diff --git a/demos/STM32/RT-XHAL-STM32G474RE-NUCLEO64/cfg/halconf.h b/demos/STM32/RT-XHAL-STM32G474RE-NUCLEO64/cfg/halconf.h index 29c7a5d20..f902b2211 100644 --- a/demos/STM32/RT-XHAL-STM32G474RE-NUCLEO64/cfg/halconf.h +++ b/demos/STM32/RT-XHAL-STM32G474RE-NUCLEO64/cfg/halconf.h @@ -163,7 +163,7 @@ * @brief Enables the SPI subsystem. */ #if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) -#define HAL_USE_SPI FALSE +#define HAL_USE_SPI TRUE #endif /** diff --git a/demos/STM32/RT-XHAL-STM32G474RE-NUCLEO64/cfg/mcuconf.h b/demos/STM32/RT-XHAL-STM32G474RE-NUCLEO64/cfg/mcuconf.h index c8685b81e..2238be2f3 100644 --- a/demos/STM32/RT-XHAL-STM32G474RE-NUCLEO64/cfg/mcuconf.h +++ b/demos/STM32/RT-XHAL-STM32G474RE-NUCLEO64/cfg/mcuconf.h @@ -324,7 +324,7 @@ /* * 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_SPI3 FALSE #define STM32_SPI_USE_SPI4 FALSE diff --git a/os/xhal/codegen/hal_cb_driver.xml b/os/xhal/codegen/hal_cb_driver.xml index ab6fccdcf..b2db3ae60 100644 --- a/os/xhal/codegen/hal_cb_driver.xml +++ b/os/xhal/codegen/hal_cb_driver.xml @@ -46,17 +46,22 @@ do { } } while (false)]]> - + + - - Generic HAL notification callback type. + + Type of driver status. + + + + Driver callback type. Class of a callback-based driver. - + Driver callback. Can be @p NULL. @@ -71,10 +76,8 @@ self->cb = NULL;]]> - - Associates a callback to the driver instance. - - + Associates a callback to the driver instance. + Callback function to be associated. Passing @p NULL disables the existing callback, if any. @@ -83,9 +86,31 @@ self->cb = NULL;]]> self->cb = cb;]]> + + Returns all driver status flags without clearing. + + + + + Returns the specified driver status flags and clears them. + Flags to + be returned and cleared. + + + + - + Returns the callback associated to the driver instance. Selection by LLD-defined mode. + + + Last transfer failed because HW error. + + @@ -879,6 +884,16 @@ spi_lld_stop(self);]]> return (const void *)spi_lld_configure(self, (const hal_spi_config_t *)config);]]> + + + + + + diff --git a/os/xhal/include/hal_cb_driver.h b/os/xhal/include/hal_cb_driver.h index ad759d7d5..d633eae4f 100644 --- a/os/xhal/include/hal_cb_driver.h +++ b/os/xhal/include/hal_cb_driver.h @@ -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 @@ -128,7 +133,9 @@ struct hal_cb_driver_vmt { void (*stop)(void *ip); const void * (*doconf)(void *ip, const void *config); /* 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. * @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.*/ void *__cbdrv_objinit_impl(void *ip, const void *vmt); 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 } #endif @@ -215,11 +224,46 @@ extern "C" { * @xclass */ 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; 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 */ 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; return self->cb; diff --git a/os/xhal/include/hal_sio.h b/os/xhal/include/hal_sio.h index 4a8e08788..71e98417b 100644 --- a/os/xhal/include/hal_sio.h +++ b/os/xhal/include/hal_sio.h @@ -540,7 +540,9 @@ struct hal_sio_driver_vmt { void (*stop)(void *ip); const void * (*doconf)(void *ip, const void *config); /* 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.*/ }; @@ -588,7 +590,7 @@ struct hal_sio_driver { * @brief Driver callback. * @note Can be @p NULL. */ - hal_cb_t cb; + drv_cb_t cb; #if (SIO_USE_STREAMS_INTERFACE == TRUE) || defined (__DOXYGEN__) /** * @brief Implemented interface @p asynchronous_channel_i. diff --git a/os/xhal/include/hal_spi.h b/os/xhal/include/hal_spi.h index ff2101061..ab6659b28 100644 --- a/os/xhal/include/hal_spi.h +++ b/os/xhal/include/hal_spi.h @@ -63,6 +63,16 @@ #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. */ /*===========================================================================*/ @@ -253,7 +263,9 @@ struct hal_spi_driver_vmt { void (*stop)(void *ip); const void * (*doconf)(void *ip, const void *config); /* 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.*/ }; @@ -301,7 +313,7 @@ struct hal_spi_driver { * @brief Driver callback. * @note Can be @p NULL. */ - hal_cb_t cb; + drv_cb_t cb; #if (SPI_USE_SYNCHRONIZATION == TRUE) || defined (__DOXYGEN__) /** * @brief Synchronization point for transfer. @@ -329,6 +341,8 @@ extern "C" { msg_t __spi_start_impl(void *ip); void __spi_stop_impl(void *ip); 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 spiStartIgnore(void *ip, size_t n); msg_t spiStartExchangeI(void *ip, size_t n, const void *txbuf, void *rxbuf); diff --git a/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.c b/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.c index f07fcba7b..5417ae8fa 100644 --- a/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.c +++ b/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.c @@ -594,6 +594,9 @@ msg_t spi_lld_start(SPIDriver *spip) { osalDbgAssert(false, "invalid SPI instance"); } + /* Status cleared.*/ + spip->sts = (drv_status_t)0; + /* DMA setup.*/ dmaStreamSetPeripheral(spip->dmarx, &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; } +/** + * @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__) /** * @brief Asserts the slave select signal and prepares for transfers. diff --git a/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.h b/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.h index c4552ea20..1a4d18cde 100644 --- a/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.h +++ b/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.h @@ -521,6 +521,8 @@ #define spi_lld_driver_fields \ /* Pointer to the SPIx registers block.*/ \ SPI_TypeDef *spi; \ + /* Driver status.*/ \ + drv_status_t sts; \ /* Receive DMA stream.*/ \ const stm32_dma_stream_t *dmarx; \ /* Transmit DMA stream.*/ \ @@ -579,6 +581,9 @@ extern "C" { void spi_lld_stop(SPIDriver *spip); const hal_spi_config_t *spi_lld_configure(hal_spi_driver_c *spip, 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__) void spi_lld_select(SPIDriver *spip); void spi_lld_unselect(SPIDriver *spip); diff --git a/os/xhal/src/hal_cb_driver.c b/os/xhal/src/hal_cb_driver.c index 30dc9443c..382a577a6 100644 --- a/os/xhal/src/hal_cb_driver.c +++ b/os/xhal/src/hal_cb_driver.c @@ -116,11 +116,47 @@ void __cbdrv_dispose_impl(void *ip) { * @param cb Callback function to be associated. Passing @p * 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; 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; +} /** @} */ /** @} */ diff --git a/os/xhal/src/hal_sio.c b/os/xhal/src/hal_sio.c index 629b9f9f8..75b05874d 100644 --- a/os/xhal/src/hal_sio.c +++ b/os/xhal/src/hal_sio.c @@ -596,7 +596,9 @@ const struct hal_sio_driver_vmt __hal_sio_driver_vmt = { .start = __sio_start_impl, .stop = __sio_stop_impl, .doconf = __sio_doconf_impl, - .setcb = __cbdrv_setcb_impl + .setcb = __cbdrv_setcb_impl, + .gsts = __cbdrv_gsts_impl, + .gcsts = __cbdrv_gcsts_impl }; /** diff --git a/os/xhal/src/hal_spi.c b/os/xhal/src/hal_spi.c index 2eb528c99..d62752e80 100644 --- a/os/xhal/src/hal_spi.c +++ b/os/xhal/src/hal_spi.c @@ -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); } + +/** + * @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, .stop = __spi_stop_impl, .doconf = __spi_doconf_impl, - .setcb = __cbdrv_setcb_impl + .setcb = __cbdrv_setcb_impl, + .gsts = __spi_gsts_impl, + .gcsts = __spi_gcsts_impl }; /**