diff --git a/os/xhal/codegen/hal_sio.xml b/os/xhal/codegen/hal_sio.xml index deee7b897..5ad41c054 100644 --- a/os/xhal/codegen/hal_sio.xml +++ b/os/xhal/codegen/hal_sio.xml @@ -407,6 +407,10 @@ do { Type of SIO event flags. + + Type of structure representing a SIO driver. + + Type of structure representing a SIO configuration. diff --git a/os/xhal/codegen/hal_spi.xml b/os/xhal/codegen/hal_spi.xml index 92055e429..f71081955 100644 --- a/os/xhal/codegen/hal_spi.xml +++ b/os/xhal/codegen/hal_spi.xml @@ -64,6 +64,10 @@ + + Type of structure representing a SPI driver. + + Type of structure representing a SPI configuration. diff --git a/os/xhal/hal.mk b/os/xhal/hal.mk index e1c8c30e8..71dd552cc 100644 --- a/os/xhal/hal.mk +++ b/os/xhal/hal.mk @@ -34,7 +34,7 @@ HALSRC = $(CHIBIOS)/os/xhal/src/hal.c \ $(CHIBIOS)/os/xhal/src/hal_st.c \ $(CHIBIOS)/os/xhal/src/hal_queues.c \ $(CHIBIOS)/os/xhal/src/hal_pal.c \ - $(CHIBIOS)/os/xhal/src/hal_sio.c + $(CHIBIOS)/os/xhal/src/hal_sio.c \ $(CHIBIOS)/os/xhal/src/hal_spi.c endif diff --git a/os/xhal/include/hal_sio.h b/os/xhal/include/hal_sio.h index 145f632b3..4a8e08788 100644 --- a/os/xhal/include/hal_sio.h +++ b/os/xhal/include/hal_sio.h @@ -477,6 +477,11 @@ */ typedef chnflags_t sioevents_t; +/** + * @brief Type of structure representing a SIO driver. + */ +typedef struct hal_sio_driver hal_sio_driver_c; + /** * @brief Type of structure representing a SIO configuration. */ diff --git a/os/xhal/include/hal_spi.h b/os/xhal/include/hal_spi.h index 2507c45b0..ff2101061 100644 --- a/os/xhal/include/hal_spi.h +++ b/os/xhal/include/hal_spi.h @@ -140,6 +140,11 @@ /* Module data structures and types. */ /*===========================================================================*/ +/** + * @brief Type of structure representing a SPI driver. + */ +typedef struct hal_spi_driver hal_spi_driver_c; + /** * @brief Type of structure representing a SPI configuration. */ 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 20c0953f3..f07fcba7b 100644 --- a/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.c +++ b/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.c @@ -116,6 +116,25 @@ SPIDriver SPID6; /* Driver local variables and types. */ /*===========================================================================*/ +/* + * Default SPI configuration. + */ +static const hal_spi_config_t spi_default_config = { + .circular = false, + .slave = false, +#if (SPI_SELECT_MODE == SPI_SELECT_MODE_LINE) || defined (__DOXYGEN__) + .ssline = PAL_LINE(STM32_SPI_DEFAULT_PORT, STM32_SPI_DEFAULT_PAD); +#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PORT + .ssport = STM32_SPI_DEFAULT_PORT, + .ssport = PAL_PORT_BIT(STM32_SPI_DEFAULT_PAD), +#elif SPI_SELECT_MODE == SPI_SELECT_MODE_PAD + .ssport = STM32_SPI_DEFAULT_PORT, + .sspad = STM32_SPI_DEFAULT_PAD, +#endif + .cr1 = STM32_SPI_DEFAULT_CR1, + .cr2 = STM32_SPI_DEFAULT_CR2 +}; + /*===========================================================================*/ /* Driver local functions. */ /*===========================================================================*/ @@ -454,138 +473,224 @@ void spi_lld_init(void) { * @notapi */ msg_t spi_lld_start(SPIDriver *spip) { - uint32_t ds; msg_t msg; /* Resetting TX pattern source.*/ spip->txsource = (uint32_t)STM32_SPI_FILLER_PATTERN; - /* If in stopped state then enables the SPI and DMA clocks.*/ - if (spip->state == DRV_STATE_STOP) { - if (false) { - } + /* Activating SPI unit.*/ + if (false) { + } #if STM32_SPI_USE_SPI1 - else if (&SPID1 == spip) { - msg = spi_lld_get_dma(spip, - STM32_SPI_SPI1_RX_DMA_STREAM, - STM32_SPI_SPI1_TX_DMA_STREAM, - STM32_SPI_SPI1_IRQ_PRIORITY); - if (msg != HAL_RET_SUCCESS) { - return msg; - } - rccEnableSPI1(true); - rccResetSPI1(); -#if STM32_DMA_SUPPORTS_DMAMUX - dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI1_RX); - dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI1_TX); -#endif + else if (&SPID1 == spip) { + msg = spi_lld_get_dma(spip, + STM32_SPI_SPI1_RX_DMA_STREAM, + STM32_SPI_SPI1_TX_DMA_STREAM, + STM32_SPI_SPI1_IRQ_PRIORITY); + if (msg != HAL_RET_SUCCESS) { + return msg; } + rccEnableSPI1(true); + rccResetSPI1(); +#if STM32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI1_RX); + dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI1_TX); +#endif + } #endif #if STM32_SPI_USE_SPI2 - else if (&SPID2 == spip) { - msg = spi_lld_get_dma(spip, - STM32_SPI_SPI2_RX_DMA_STREAM, - STM32_SPI_SPI2_TX_DMA_STREAM, - STM32_SPI_SPI2_IRQ_PRIORITY); - if (msg != HAL_RET_SUCCESS) { - return msg; - } - rccEnableSPI2(true); - rccResetSPI2(); -#if STM32_DMA_SUPPORTS_DMAMUX - dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI2_RX); - dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI2_TX); -#endif + else if (&SPID2 == spip) { + msg = spi_lld_get_dma(spip, + STM32_SPI_SPI2_RX_DMA_STREAM, + STM32_SPI_SPI2_TX_DMA_STREAM, + STM32_SPI_SPI2_IRQ_PRIORITY); + if (msg != HAL_RET_SUCCESS) { + return msg; } + rccEnableSPI2(true); + rccResetSPI2(); +#if STM32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI2_RX); + dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI2_TX); +#endif + } #endif #if STM32_SPI_USE_SPI3 - else if (&SPID3 == spip) { - msg = spi_lld_get_dma(spip, - STM32_SPI_SPI3_RX_DMA_STREAM, - STM32_SPI_SPI3_TX_DMA_STREAM, - STM32_SPI_SPI3_IRQ_PRIORITY); - if (msg != HAL_RET_SUCCESS) { - return msg; - } - rccEnableSPI3(true); - rccResetSPI3(); -#if STM32_DMA_SUPPORTS_DMAMUX - dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI3_RX); - dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI3_TX); -#endif + else if (&SPID3 == spip) { + msg = spi_lld_get_dma(spip, + STM32_SPI_SPI3_RX_DMA_STREAM, + STM32_SPI_SPI3_TX_DMA_STREAM, + STM32_SPI_SPI3_IRQ_PRIORITY); + if (msg != HAL_RET_SUCCESS) { + return msg; } + rccEnableSPI3(true); + rccResetSPI3(); +#if STM32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI3_RX); + dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI3_TX); +#endif + } #endif #if STM32_SPI_USE_SPI4 - else if (&SPID4 == spip) { - msg = spi_lld_get_dma(spip, - STM32_SPI_SPI4_RX_DMA_STREAM, - STM32_SPI_SPI4_TX_DMA_STREAM, - STM32_SPI_SPI4_IRQ_PRIORITY); - if (msg != HAL_RET_SUCCESS) { - return msg; - } - rccEnableSPI4(true); - rccResetSPI4(); -#if STM32_DMA_SUPPORTS_DMAMUX - dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI4_RX); - dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI4_TX); -#endif + else if (&SPID4 == spip) { + msg = spi_lld_get_dma(spip, + STM32_SPI_SPI4_RX_DMA_STREAM, + STM32_SPI_SPI4_TX_DMA_STREAM, + STM32_SPI_SPI4_IRQ_PRIORITY); + if (msg != HAL_RET_SUCCESS) { + return msg; } + rccEnableSPI4(true); + rccResetSPI4(); +#if STM32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI4_RX); + dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI4_TX); +#endif + } #endif #if STM32_SPI_USE_SPI5 - else if (&SPID5 == spip) { - msg = spi_lld_get_dma(spip, - STM32_SPI_SPI5_RX_DMA_STREAM, - STM32_SPI_SPI5_TX_DMA_STREAM, - STM32_SPI_SPI5_IRQ_PRIORITY); - if (msg != HAL_RET_SUCCESS) { - return msg; - } - rccEnableSPI5(true); - rccResetSPI5(); -#if STM32_DMA_SUPPORTS_DMAMUX - dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI5_RX); - dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI5_TX); -#endif + else if (&SPID5 == spip) { + msg = spi_lld_get_dma(spip, + STM32_SPI_SPI5_RX_DMA_STREAM, + STM32_SPI_SPI5_TX_DMA_STREAM, + STM32_SPI_SPI5_IRQ_PRIORITY); + if (msg != HAL_RET_SUCCESS) { + return msg; } + rccEnableSPI5(true); + rccResetSPI5(); +#if STM32_DMA_SUPPORTS_DMAMUX + dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI5_RX); + dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI5_TX); +#endif + } #endif #if STM32_SPI_USE_SPI6 - else if (&SPID6 == spip) { - msg = spi_lld_get_dma(spip, - STM32_SPI_SPI6_RX_DMA_STREAM, - STM32_SPI_SPI6_TX_DMA_STREAM, - STM32_SPI_SPI6_IRQ_PRIORITY); - if (msg != HAL_RET_SUCCESS) { - return msg; - } - rccEnableSPI6(true); - rccResetSPI6(); + else if (&SPID6 == spip) { + msg = spi_lld_get_dma(spip, + STM32_SPI_SPI6_RX_DMA_STREAM, + STM32_SPI_SPI6_TX_DMA_STREAM, + STM32_SPI_SPI6_IRQ_PRIORITY); + if (msg != HAL_RET_SUCCESS) { + return msg; + } + rccEnableSPI6(true); + rccResetSPI6(); #if STM32_DMA_SUPPORTS_DMAMUX - dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI6_RX); - dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI6_TX); + dmaSetRequestSource(spip->dmarx, STM32_DMAMUX1_SPI6_RX); + dmaSetRequestSource(spip->dmatx, STM32_DMAMUX1_SPI6_TX); #endif - } -#endif - - else { - osalDbgAssert(false, "invalid SPI instance"); - } - - /* DMA setup.*/ - dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); - dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); } +#endif + else { - /* De-activation before re-configuration.*/ - spi_lld_disable(spip); + osalDbgAssert(false, "invalid SPI instance"); } + /* DMA setup.*/ + dmaStreamSetPeripheral(spip->dmarx, &spip->spi->DR); + dmaStreamSetPeripheral(spip->dmatx, &spip->spi->DR); + + /* Configures the peripheral.*/ + spi_lld_configure(spip, &spi_default_config); + + return HAL_RET_SUCCESS; +} + +/** + * @brief Deactivates the SPI peripheral. + * + * @param[in] spip pointer to the @p SPIDriver object + * + * @notapi + */ +void spi_lld_stop(SPIDriver *spip) { + + /* Just in case this has been called uncleanly.*/ + spi_lld_disable(spip); + + /* SPI cleanup.*/ + spip->spi->CR1 = 0; + spip->spi->CR2 = 0; + + /* DMA channels release.*/ + dmaStreamFreeI(spip->dmatx); + dmaStreamFreeI(spip->dmarx); + spip->dmarx = NULL; + spip->dmatx = NULL; + + /* Clock shutdown.*/ + if (false) { + } + +#if STM32_SPI_USE_SPI1 + else if (&SPID1 == spip) { + rccDisableSPI1(); + } +#endif + +#if STM32_SPI_USE_SPI2 + else if (&SPID2 == spip) { + rccDisableSPI2(); + } +#endif + +#if STM32_SPI_USE_SPI3 + else if (&SPID3 == spip) { + rccDisableSPI3(); + } +#endif + +#if STM32_SPI_USE_SPI4 + else if (&SPID4 == spip) { + rccDisableSPI4(); + } +#endif + +#if STM32_SPI_USE_SPI5 + else if (&SPID5 == spip) { + rccDisableSPI5(); + } +#endif + +#if STM32_SPI_USE_SPI6 + else if (&SPID6 == spip) { + rccDisableSPI6(); + } +#endif + + else { + osalDbgAssert(false, "invalid SPI instance"); + } +} + +/** + * @brief SPI configuration. + * + * @param[in] spip pointer to the @p hal_spi_driver_c object + * @param[in] config pointer to the @p hal_spi_config_t structure + * @return A pointer to the current configuration structure. + * + * @notapi + */ +const hal_spi_config_t *spi_lld_configure(hal_spi_driver_c *spip, + const hal_spi_config_t *config) { + uint32_t ds; + + if (config == NULL) { + config = &spi_default_config; + } + + /* De-activation before re-configuration.*/ + spi_lld_disable(spip); + /* Configuration-specific DMA setup.*/ ds = __spi_getfield(spip, cr2) & SPI_CR2_DS; if (!ds || (ds <= (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0))) { @@ -615,78 +720,7 @@ msg_t spi_lld_start(SPIDriver *spip) { /* SPI setup.*/ spi_lld_enable(spip); - return HAL_RET_SUCCESS; -} - -/** - * @brief Deactivates the SPI peripheral. - * - * @param[in] spip pointer to the @p SPIDriver object - * - * @notapi - */ -void spi_lld_stop(SPIDriver *spip) { - - /* If in ready state then disables the SPI clock.*/ - if (spip->state == SPI_READY) { - - /* Just in case this has been called uncleanly.*/ - spi_lld_disable(spip); - - /* SPI cleanup.*/ - spip->spi->CR1 = 0; - spip->spi->CR2 = 0; - - /* DMA channels release.*/ - dmaStreamFreeI(spip->dmatx); - dmaStreamFreeI(spip->dmarx); - spip->dmarx = NULL; - spip->dmatx = NULL; - - /* Clock shutdown.*/ - if (false) { - } - -#if STM32_SPI_USE_SPI1 - else if (&SPID1 == spip) { - rccDisableSPI1(); - } -#endif - -#if STM32_SPI_USE_SPI2 - else if (&SPID2 == spip) { - rccDisableSPI2(); - } -#endif - -#if STM32_SPI_USE_SPI3 - else if (&SPID3 == spip) { - rccDisableSPI3(); - } -#endif - -#if STM32_SPI_USE_SPI4 - else if (&SPID4 == spip) { - rccDisableSPI4(); - } -#endif - -#if STM32_SPI_USE_SPI5 - else if (&SPID5 == spip) { - rccDisableSPI5(); - } -#endif - -#if STM32_SPI_USE_SPI6 - else if (&SPID6 == spip) { - rccDisableSPI6(); - } -#endif - - else { - osalDbgAssert(false, "invalid SPI instance"); - } - } + return config; } #if (SPI_SELECT_MODE == SPI_SELECT_MODE_LLD) || defined(__DOXYGEN__) 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 5923f0d97..c4552ea20 100644 --- a/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.h +++ b/os/xhal/ports/STM32/LLD/SPIv2/hal_spi_lld.h @@ -218,6 +218,34 @@ #if !defined(STM32_SPI_DMA_ERROR_HOOK) || defined(__DOXYGEN__) #define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure") #endif + +/** + * @brief Default PAL port for Chip Select line. + */ +#if !defined(STM32_SPI_DEFAULT_PORT) || defined(__DOXYGEN__) +#define STM32_SPI_DEFAULT_PORT GPIOA +#endif + +/** + * @brief Default PAL pad for Chip Select line. + */ +#if !defined(STM32_SPI_DEFAULT_PAD) || defined(__DOXYGEN__) +#define STM32_SPI_DEFAULT_PAD 0U +#endif + +/** + * @brief CR1 setting for default SPI configuration. + */ +#if !defined(STM32_SPI_DEFAULT_CR1) || defined(__DOXYGEN__) +#define STM32_SPI_DEFAULT_CR1 (SPI_CR1_BR_2 | SPI_CR1_BR_1) +#endif + +/** + * @brief CR2 setting for default SPI configuration. + */ +#if !defined(STM32_SPI_DEFAULT_CR2) || defined(__DOXYGEN__) +#define STM32_SPI_DEFAULT_CR2 (SPI_CR2_DS_2 | SPI_CR2_DS_1 | SPI_CR2_DS_0) +#endif /** @} */ /*===========================================================================*/ @@ -549,6 +577,8 @@ extern "C" { void spi_lld_init(void); msg_t spi_lld_start(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 *config); #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/ports/STM32/LLD/USARTv3/hal_sio_lld.c b/os/xhal/ports/STM32/LLD/USARTv3/hal_sio_lld.c index a9904b7ae..632c80a62 100644 --- a/os/xhal/ports/STM32/LLD/USARTv3/hal_sio_lld.c +++ b/os/xhal/ports/STM32/LLD/USARTv3/hal_sio_lld.c @@ -460,6 +460,15 @@ void sio_lld_stop(SIODriver *siop) { } } +/** + * @brief SIO configuration. + * + * @param[in] siop pointer to the @p SIODriver object + * @param[in] config pointer to the @p SIOConfig structure + * @return A pointer to the current configuration structure. + * + * @notapi + */ const SIOConfig *sio_lld_configure(SIODriver *siop, const SIOConfig *config) { USART_TypeDef *u = siop->usart; uint32_t presc, brr, clock;