git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16377 27425a3e-05d8-49a3-a47f-9c15f0e5edd8

This commit is contained in:
Giovanni Di Sirio 2023-08-21 14:21:28 +00:00
parent aa5c0d9965
commit 18d026687f
12 changed files with 232 additions and 25 deletions

View File

@ -163,7 +163,7 @@
* @brief Enables the SPI subsystem. * @brief Enables the SPI subsystem.
*/ */
#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__)
#define HAL_USE_SPI FALSE #define HAL_USE_SPI TRUE
#endif #endif
/** /**

View File

@ -324,7 +324,7 @@
/* /*
* SPI driver system settings. * SPI driver system settings.
*/ */
#define STM32_SPI_USE_SPI1 FALSE #define STM32_SPI_USE_SPI1 TRUE
#define STM32_SPI_USE_SPI2 FALSE #define STM32_SPI_USE_SPI2 FALSE
#define STM32_SPI_USE_SPI3 FALSE #define STM32_SPI_USE_SPI3 FALSE
#define STM32_SPI_USE_SPI4 FALSE #define STM32_SPI_USE_SPI4 FALSE

View File

@ -46,17 +46,22 @@ do {
} }
} while (false)]]></implementation> } while (false)]]></implementation>
</macro> </macro>
</group></macros> </group>
</macros>
<types> <types>
<typedef name="hal_cb_t"> <typedef name="drv_status_t">
<brief>Generic HAL notification callback type.</brief> <brief>Type of driver status.</brief>
<basetype ctype="eventflags_t" />
</typedef>
<typedef name="drv_cb_t">
<brief>Driver callback type.</brief>
<basetype ctype="void (*$N)(void *ip)" /> <basetype ctype="void (*$N)(void *ip)" />
</typedef> </typedef>
<class type="abstract" name="hal_cb_driver" namespace="cbdrv" <class type="abstract" name="hal_cb_driver" namespace="cbdrv"
ancestorname="hal_base_driver" descr="callback driver"> ancestorname="hal_base_driver" descr="callback driver">
<brief>Class of a callback-based driver.</brief> <brief>Class of a callback-based driver.</brief>
<fields> <fields>
<field name="cb" ctype="hal_cb_t"> <field name="cb" ctype="drv_cb_t">
<brief>Driver callback.</brief> <brief>Driver callback.</brief>
<note>Can be @p NULL.</note> <note>Can be @p NULL.</note>
</field> </field>
@ -71,10 +76,8 @@ self->cb = NULL;]]></implementation>
</dispose> </dispose>
<virtual> <virtual>
<method name="drvSetCallbackX" ctype="void" shortname="setcb"> <method name="drvSetCallbackX" ctype="void" shortname="setcb">
<brief> <brief>Associates a callback to the driver instance.</brief>
Associates a callback to the driver instance. <param name="cb" ctype="drv_cb_t">
</brief>
<param name="cb" ctype="hal_cb_t">
Callback function to be associated. Passing @p NULL Callback function to be associated. Passing @p NULL
disables the existing callback, if any. disables the existing callback, if any.
</param> </param>
@ -83,9 +86,31 @@ self->cb = NULL;]]></implementation>
self->cb = cb;]]></implementation> self->cb = cb;]]></implementation>
</method> </method>
<method name="drvGetStatusX" ctype="drv_status_t" shortname="gsts">
<brief>Returns all driver status flags without clearing.</brief>
<iclass />
<implementation><![CDATA[
(void)self;
return (drv_status_t)0;]]></implementation>
</method>
<method name="drvGetAndClearStatusI" ctype="drv_status_t" shortname="gcsts">
<brief>Returns the specified driver status flags and clears them.</brief>
<param name="mask" ctype="drv_status_t" dir="in">Flags to
be returned and cleared.
</param>
<xclass />
<implementation><![CDATA[
(void)self;
(void)mask;
return (drv_status_t)0;]]></implementation>
</method>
</virtual> </virtual>
<inline> <inline>
<method name="drvGetCallbackX" ctype="hal_cb_t"> <method name="drvGetCallbackX" ctype="drv_cb_t">
<brief>Returns the callback associated to the driver instance.</brief> <brief>Returns the callback associated to the driver instance.</brief>
<xclass /> <xclass />
<implementation><![CDATA[ <implementation><![CDATA[

View File

@ -25,6 +25,11 @@
<brief>Selection by LLD-defined mode.</brief> <brief>Selection by LLD-defined mode.</brief>
</define> </define>
</group> </group>
<group description="SPI status flags">
<define name="SPI_STS_FAILED" value="1U">
<brief>Last transfer failed because HW error.</brief>
</define>
</group>
</definitions_early> </definitions_early>
<configs> <configs>
<config name="SPI_USE_SYNCHRONIZATION" default="TRUE"> <config name="SPI_USE_SYNCHRONIZATION" default="TRUE">
@ -879,6 +884,16 @@ spi_lld_stop(self);]]></implementation>
return (const void *)spi_lld_configure(self, (const hal_spi_config_t *)config);]]></implementation> return (const void *)spi_lld_configure(self, (const hal_spi_config_t *)config);]]></implementation>
</method> </method>
<method shortname="gsts">
<implementation><![CDATA[
return __cbdrv_gsts_impl(self);]]></implementation>
</method>
<method shortname="gcsts">
<implementation><![CDATA[
return __cbdrv_gcsts_impl(self, mask);]]></implementation>
</method>
</override> </override>
</methods> </methods>
</class> </class>

View File

@ -98,9 +98,14 @@
/*===========================================================================*/ /*===========================================================================*/
/** /**
* @brief Generic HAL notification callback type. * @brief Type of driver status.
*/ */
typedef void (*hal_cb_t)(void *ip); typedef eventflags_t drv_status_t;
/**
* @brief Driver callback type.
*/
typedef void (*drv_cb_t)(void *ip);
/** /**
* @class hal_cb_driver_c * @class hal_cb_driver_c
@ -128,7 +133,9 @@ struct hal_cb_driver_vmt {
void (*stop)(void *ip); void (*stop)(void *ip);
const void * (*doconf)(void *ip, const void *config); const void * (*doconf)(void *ip, const void *config);
/* From hal_cb_driver_c.*/ /* From hal_cb_driver_c.*/
void (*setcb)(void *ip, hal_cb_t cb); void (*setcb)(void *ip, drv_cb_t cb);
drv_status_t (*gsts)(void *ip);
drv_status_t (*gcsts)(void *ip, drv_status_t mask);
}; };
/** /**
@ -175,7 +182,7 @@ struct hal_cb_driver {
* @brief Driver callback. * @brief Driver callback.
* @note Can be @p NULL. * @note Can be @p NULL.
*/ */
hal_cb_t cb; drv_cb_t cb;
}; };
/** @} */ /** @} */
@ -189,7 +196,9 @@ extern "C" {
/* Methods of hal_cb_driver_c.*/ /* Methods of hal_cb_driver_c.*/
void *__cbdrv_objinit_impl(void *ip, const void *vmt); void *__cbdrv_objinit_impl(void *ip, const void *vmt);
void __cbdrv_dispose_impl(void *ip); void __cbdrv_dispose_impl(void *ip);
void __cbdrv_setcb_impl(void *ip, hal_cb_t cb); void __cbdrv_setcb_impl(void *ip, drv_cb_t cb);
drv_status_t __cbdrv_gsts_impl(void *ip);
drv_status_t __cbdrv_gcsts_impl(void *ip, drv_status_t mask);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
@ -215,11 +224,46 @@ extern "C" {
* @xclass * @xclass
*/ */
CC_FORCE_INLINE CC_FORCE_INLINE
static inline void drvSetCallbackX(void *ip, hal_cb_t cb) { static inline void drvSetCallbackX(void *ip, drv_cb_t cb) {
hal_cb_driver_c *self = (hal_cb_driver_c *)ip; hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
self->vmt->setcb(ip, cb); self->vmt->setcb(ip, cb);
} }
/**
* @memberof hal_cb_driver_c
* @public
*
* @brief Returns all driver status flags without clearing.
*
* @param[in,out] ip Pointer to a @p hal_cb_driver_c instance.
*
* @iclass
*/
CC_FORCE_INLINE
static inline drv_status_t drvGetStatusX(void *ip) {
hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
return self->vmt->gsts(ip);
}
/**
* @memberof hal_cb_driver_c
* @public
*
* @brief Returns the specified driver status flags and clears them.
*
* @param[in,out] ip Pointer to a @p hal_cb_driver_c instance.
* @param[in] mask Flags to be returned and cleared.
*
* @xclass
*/
CC_FORCE_INLINE
static inline drv_status_t drvGetAndClearStatusI(void *ip, drv_status_t mask) {
hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
return self->vmt->gcsts(ip, mask);
}
/** @} */ /** @} */
/** /**
@ -237,7 +281,7 @@ static inline void drvSetCallbackX(void *ip, hal_cb_t cb) {
* @xclass * @xclass
*/ */
CC_FORCE_INLINE CC_FORCE_INLINE
static inline hal_cb_t drvGetCallbackX(void *ip) { static inline drv_cb_t drvGetCallbackX(void *ip) {
hal_cb_driver_c *self = (hal_cb_driver_c *)ip; hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
return self->cb; return self->cb;

View File

@ -540,7 +540,9 @@ struct hal_sio_driver_vmt {
void (*stop)(void *ip); void (*stop)(void *ip);
const void * (*doconf)(void *ip, const void *config); const void * (*doconf)(void *ip, const void *config);
/* From hal_cb_driver_c.*/ /* From hal_cb_driver_c.*/
void (*setcb)(void *ip, hal_cb_t cb); void (*setcb)(void *ip, drv_cb_t cb);
drv_status_t (*gsts)(void *ip);
drv_status_t (*gcsts)(void *ip, drv_status_t mask);
/* From hal_sio_driver_c.*/ /* From hal_sio_driver_c.*/
}; };
@ -588,7 +590,7 @@ struct hal_sio_driver {
* @brief Driver callback. * @brief Driver callback.
* @note Can be @p NULL. * @note Can be @p NULL.
*/ */
hal_cb_t cb; drv_cb_t cb;
#if (SIO_USE_STREAMS_INTERFACE == TRUE) || defined (__DOXYGEN__) #if (SIO_USE_STREAMS_INTERFACE == TRUE) || defined (__DOXYGEN__)
/** /**
* @brief Implemented interface @p asynchronous_channel_i. * @brief Implemented interface @p asynchronous_channel_i.

View File

@ -63,6 +63,16 @@
#define SPI_SELECT_MODE_LLD 4 #define SPI_SELECT_MODE_LLD 4
/** @} */ /** @} */
/**
* @name SPI status flags
* @{
*/
/**
* @brief Last transfer failed because HW error.
*/
#define SPI_STS_FAILED 1U
/** @} */
/*===========================================================================*/ /*===========================================================================*/
/* Module pre-compile time settings. */ /* Module pre-compile time settings. */
/*===========================================================================*/ /*===========================================================================*/
@ -253,7 +263,9 @@ struct hal_spi_driver_vmt {
void (*stop)(void *ip); void (*stop)(void *ip);
const void * (*doconf)(void *ip, const void *config); const void * (*doconf)(void *ip, const void *config);
/* From hal_cb_driver_c.*/ /* From hal_cb_driver_c.*/
void (*setcb)(void *ip, hal_cb_t cb); void (*setcb)(void *ip, drv_cb_t cb);
drv_status_t (*gsts)(void *ip);
drv_status_t (*gcsts)(void *ip, drv_status_t mask);
/* From hal_spi_driver_c.*/ /* From hal_spi_driver_c.*/
}; };
@ -301,7 +313,7 @@ struct hal_spi_driver {
* @brief Driver callback. * @brief Driver callback.
* @note Can be @p NULL. * @note Can be @p NULL.
*/ */
hal_cb_t cb; drv_cb_t cb;
#if (SPI_USE_SYNCHRONIZATION == TRUE) || defined (__DOXYGEN__) #if (SPI_USE_SYNCHRONIZATION == TRUE) || defined (__DOXYGEN__)
/** /**
* @brief Synchronization point for transfer. * @brief Synchronization point for transfer.
@ -329,6 +341,8 @@ extern "C" {
msg_t __spi_start_impl(void *ip); msg_t __spi_start_impl(void *ip);
void __spi_stop_impl(void *ip); void __spi_stop_impl(void *ip);
const void *__spi_doconf_impl(void *ip, const void *config); const void *__spi_doconf_impl(void *ip, const void *config);
drv_status_t __spi_gsts_impl(void *ip);
drv_status_t __spi_gcsts_impl(void *ip, drv_status_t mask);
msg_t spiStartIgnoreI(void *ip, size_t n); msg_t spiStartIgnoreI(void *ip, size_t n);
msg_t spiStartIgnore(void *ip, size_t n); msg_t spiStartIgnore(void *ip, size_t n);
msg_t spiStartExchangeI(void *ip, size_t n, const void *txbuf, void *rxbuf); msg_t spiStartExchangeI(void *ip, size_t n, const void *txbuf, void *rxbuf);

View File

@ -594,6 +594,9 @@ msg_t spi_lld_start(SPIDriver *spip) {
osalDbgAssert(false, "invalid SPI instance"); osalDbgAssert(false, "invalid SPI instance");
} }
/* Status cleared.*/
spip->sts = (drv_status_t)0;
/* DMA setup.*/ /* DMA setup.*/
dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR);
dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR);
@ -723,6 +726,36 @@ const hal_spi_config_t *spi_lld_configure(hal_spi_driver_c *spip,
return config; return config;
} }
/**
* @brief Implementation of method @p drvGetStatusX().
*
* @param[in] spip pointer to the @p hal_spi_driver_c object
*
* @notapi
*/
drv_status_t spi_lld_get_status(hal_spi_driver_c *spip) {
return spip->sts;
}
/**
* @brief Implementation of method @p drvGetAndClearStatusI().
*
* @param[in] spip pointer to the @p hal_spi_driver_c object
* @param[in] mask flags to be returned and cleared
*
* @notapi
*/
drv_status_t spi_lld_get_clear_status(hal_spi_driver_c *spip,
drv_status_t mask) {
drv_status_t sts;
sts = spip->sts;
spip->sts &= ~mask;
return sts;
}
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) #if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
/** /**
* @brief Asserts the slave select signal and prepares for transfers. * @brief Asserts the slave select signal and prepares for transfers.

View File

@ -521,6 +521,8 @@
#define spi_lld_driver_fields \ #define spi_lld_driver_fields \
/* Pointer to the SPIx registers block.*/ \ /* Pointer to the SPIx registers block.*/ \
SPI_TypeDef *spi; \ SPI_TypeDef *spi; \
/* Driver status.*/ \
drv_status_t sts; \
/* Receive DMA stream.*/ \ /* Receive DMA stream.*/ \
const stm32_dma_stream_t *dmarx; \ const stm32_dma_stream_t *dmarx; \
/* Transmit DMA stream.*/ \ /* Transmit DMA stream.*/ \
@ -579,6 +581,9 @@ extern "C" {
void spi_lld_stop(SPIDriver *spip); void spi_lld_stop(SPIDriver *spip);
const hal_spi_config_t *spi_lld_configure(hal_spi_driver_c *spip, const hal_spi_config_t *spi_lld_configure(hal_spi_driver_c *spip,
const hal_spi_config_t *config); const hal_spi_config_t *config);
drv_status_t spi_lld_get_status(hal_spi_driver_c *spip);
drv_status_t spi_lld_get_clear_status(hal_spi_driver_c *spip,
drv_status_t mask);
#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) #if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__)
void spi_lld_select(SPIDriver *spip); void spi_lld_select(SPIDriver *spip);
void spi_lld_unselect(SPIDriver *spip); void spi_lld_unselect(SPIDriver *spip);

View File

@ -116,11 +116,47 @@ void __cbdrv_dispose_impl(void *ip) {
* @param cb Callback function to be associated. Passing @p * @param cb Callback function to be associated. Passing @p
* NULL disables the existing callback, if any. * NULL disables the existing callback, if any.
*/ */
void __cbdrv_setcb_impl(void *ip, hal_cb_t cb) { void __cbdrv_setcb_impl(void *ip, drv_cb_t cb) {
hal_cb_driver_c *self = (hal_cb_driver_c *)ip; hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
self->cb = cb; self->cb = cb;
} }
/**
* @memberof hal_cb_driver_c
* @protected
*
* @brief Implementation of method @p drvGetStatusX().
* @note This function is meant to be used by derived classes.
*
* @param[in,out] ip Pointer to a @p hal_cb_driver_c instance.
*/
drv_status_t __cbdrv_gsts_impl(void *ip) {
hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
(void)self;
return (drv_status_t)0;
}
/**
* @memberof hal_cb_driver_c
* @protected
*
* @brief Implementation of method @p drvGetAndClearStatusI().
* @note This function is meant to be used by derived classes.
*
* @param[in,out] ip Pointer to a @p hal_cb_driver_c instance.
* @param[in] mask Flags to be returned and cleared.
*/
drv_status_t __cbdrv_gcsts_impl(void *ip, drv_status_t mask) {
hal_cb_driver_c *self = (hal_cb_driver_c *)ip;
(void)self;
(void)mask;
return (drv_status_t)0;
}
/** @} */ /** @} */
/** @} */ /** @} */

View File

@ -596,7 +596,9 @@ const struct hal_sio_driver_vmt __hal_sio_driver_vmt = {
.start = __sio_start_impl, .start = __sio_start_impl,
.stop = __sio_stop_impl, .stop = __sio_stop_impl,
.doconf = __sio_doconf_impl, .doconf = __sio_doconf_impl,
.setcb = __cbdrv_setcb_impl .setcb = __cbdrv_setcb_impl,
.gsts = __cbdrv_gsts_impl,
.gcsts = __cbdrv_gcsts_impl
}; };
/** /**

View File

@ -167,6 +167,35 @@ const void *__spi_doconf_impl(void *ip, const void *config) {
return (const void *)spi_lld_configure(self, (const hal_spi_config_t *)config); return (const void *)spi_lld_configure(self, (const hal_spi_config_t *)config);
} }
/**
* @memberof hal_spi_driver_c
* @protected
*
* @brief Override of method @p drvGetStatusX().
*
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
*/
drv_status_t __spi_gsts_impl(void *ip) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
return __cbdrv_gsts_impl(self);
}
/**
* @memberof hal_spi_driver_c
* @protected
*
* @brief Override of method @p drvGetAndClearStatusI().
*
* @param[in,out] ip Pointer to a @p hal_spi_driver_c instance.
* @param[in] mask Flags to be returned and cleared.
*/
drv_status_t __spi_gcsts_impl(void *ip, drv_status_t mask) {
hal_spi_driver_c *self = (hal_spi_driver_c *)ip;
return __cbdrv_gcsts_impl(self, mask);
}
/** @} */ /** @} */
/** /**
@ -178,7 +207,9 @@ const struct hal_spi_driver_vmt __hal_spi_driver_vmt = {
.start = __spi_start_impl, .start = __spi_start_impl,
.stop = __spi_stop_impl, .stop = __spi_stop_impl,
.doconf = __spi_doconf_impl, .doconf = __spi_doconf_impl,
.setcb = __cbdrv_setcb_impl .setcb = __cbdrv_setcb_impl,
.gsts = __spi_gsts_impl,
.gcsts = __spi_gcsts_impl
}; };
/** /**