From 33f53bc0dd199ae40e8af19a4116bd5dd5d654ff Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Thu, 16 Nov 2023 09:20:50 +0000 Subject: [PATCH] Small improvements and new functions. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@16412 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.c | 46 ++------------ os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h | 64 +++++++++++++++++--- 2 files changed, 61 insertions(+), 49 deletions(-) diff --git a/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.c b/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.c index 2d4d8d386..e1e6c7340 100644 --- a/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.c +++ b/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.c @@ -567,29 +567,6 @@ void gpdmaChannelFree(const stm32_gpdma_channel_t *dmachp) { osalSysUnlock(); } - -/** - * @brief GPDMA channel suspend. - * @note This function can be invoked in both ISR or thread context. - * @pre The channel must have been allocated using @p dmaChannelAlloc(). - * @post After use the channel can be released using @p dmaChannelRelease(). - * - * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure - * - * @special - */ -void gpdmaChannelSuspend(const stm32_gpdma_channel_t *dmachp) { - - osalDbgAssert((dmachp->channel->CCR & STM32_GPDMA_CCR_EN) != 0U, - "not enabled"); - - dmachp->channel->CCR |= STM32_GPDMA_CCR_SUSP; - while ((dmachp->channel->CSR & STM32_GPDMA_CSR_SUSPF) != 0U) { - /* Wait completion.*/ - } - dmachp->channel->CFCR = STM32_GPDMA_CFCR_SUSPF; -} - /** * @brief GPDMA channel disable. * @details The function disables the specified channel and then clears any @@ -606,26 +583,15 @@ void gpdmaChannelSuspend(const stm32_gpdma_channel_t *dmachp) { */ void gpdmaChannelDisable(const stm32_gpdma_channel_t *dmachp) { - /* Suspending channel, note, we don't know if it is still active at this - point because the EN bit can be reset in HW.*/ - dmachp->channel->CCR |= STM32_GPDMA_CCR_SUSP; - - /* If the channel was actually active.*/ - if ((dmachp->channel->CCR & STM32_GPDMA_CCR_EN) != 0U) { - - /* Waiting for completion if suspend operation then resetting the - completion flag.*/ - while ((dmachp->channel->CSR & STM32_GPDMA_CSR_SUSPF) != 0U) { - /* Wait completion.*/ - } - dmachp->channel->CFCR = STM32_GPDMA_CFCR_SUSPF; - } + /* Suspending the channel, it needs to be in idle.*/ + gpdmaChannelSuspend(dmachp); + gpdmaChannelWaitIdle(dmachp); /* Now resetting the channel.*/ - dmachp->channel->CCR |= STM32_GPDMA_CCR_RESET; - dmachp->channel->CCR = 0U; + gpdmaChannelReset(dmachp); - /* Clearing all interrupts.*/ + /* Resetting all sources and clearing interrupts.*/ + dmachp->channel->CCR = 0U; dmachp->channel->CFCR = STM32_GPDMA_CFCR_ALL; } diff --git a/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h b/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h index 3751ceaa8..013db29a6 100644 --- a/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h +++ b/os/hal/ports/STM32/LLD/GPDMAv1/stm32_gpdma.h @@ -569,7 +569,6 @@ extern "C" { void *param); void gpdmaChannelFreeI(const stm32_gpdma_channel_t *dmachp); void gpdmaChannelFree(const stm32_gpdma_channel_t *dmachp); - void gpdmaChannelSuspend(const stm32_gpdma_channel_t *dmachp); void gpdmaChannelDisable(const stm32_gpdma_channel_t *dmachp); void gpdmaServeInterrupt(const stm32_gpdma_channel_t *dmachp); #ifdef __cplusplus @@ -616,6 +615,7 @@ void gpdmaChannelInit(const stm32_gpdma_channel_t *dmachp, /** * @brief Prepares a GPDMA channel for transfer. + * @note This function can be invoked in both ISR or thread context. * * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure * @param[in] tr1 CTR1 register initialization value @@ -645,6 +645,7 @@ void gpdmaChannelSetupTransfer(const stm32_gpdma_channel_t *dmachp, /** * @brief Prepares a GPDMA channel for a 2D transfer. * @note The channel must have 2D capability. + * @note This function can be invoked in both ISR or thread context. * * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure * @param[in] tr1 CTR1 register initialization value @@ -677,6 +678,7 @@ void gpdmaChannelSetupTransfer2D(const stm32_gpdma_channel_t *dmachp, /** * @brief Channel enable. + * @note This function can be invoked in both ISR or thread context. * * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure * @@ -684,13 +686,57 @@ void gpdmaChannelSetupTransfer2D(const stm32_gpdma_channel_t *dmachp, */ __STATIC_FORCEINLINE void gpdmaChannelEnable(const stm32_gpdma_channel_t *dmachp) { - DMA_Channel_TypeDef *chp = dmachp->channel; - chp->CCR |= STM32_GPDMA_CCR_EN; + dmachp->channel->CCR |= STM32_GPDMA_CCR_EN; +} + +/** + * @brief GPDMA channel reset. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure + * + * @special + */ +__STATIC_FORCEINLINE +void gpdmaChannelReset(const stm32_gpdma_channel_t *dmachp) { + + dmachp->channel->CCR |= STM32_GPDMA_CCR_RESET; +} + +/** + * @brief GPDMA channel suspend. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure + * + * @special + */ +__STATIC_FORCEINLINE +void gpdmaChannelSuspend(const stm32_gpdma_channel_t *dmachp) { + + dmachp->channel->CCR |= STM32_GPDMA_CCR_SUSP; +} + +/** + * @brief GPDMA channel wait for idle state. + * @note This function can be invoked in both ISR or thread context. + * + * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure + * + * @special + */ +__STATIC_FORCEINLINE +void gpdmaChannelWaitIdle(const stm32_gpdma_channel_t *dmachp) { + + while ((dmachp->channel->CSR & STM32_GPDMA_CSR_IDLEF) == 0U) { + /* Wait completion.*/ + } } /** * @brief Set channel source pointer. + * @note This function can be invoked in both ISR or thread context. * * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure * @param[in] s source pointer @@ -700,13 +746,13 @@ void gpdmaChannelEnable(const stm32_gpdma_channel_t *dmachp) { __STATIC_FORCEINLINE void gpdmaChannelSetSource(const stm32_gpdma_channel_t *dmachp, volatile const void *s) { - DMA_Channel_TypeDef *chp = dmachp->channel; - chp->CSAR = (uint32_t)s; + dmachp->channel->CSAR = (uint32_t)s; } /** * @brief Set channel destination pointer. + * @note This function can be invoked in both ISR or thread context. * * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure * @param[in] d destination pointer @@ -716,13 +762,13 @@ void gpdmaChannelSetSource(const stm32_gpdma_channel_t *dmachp, __STATIC_FORCEINLINE void gpdmaChannelSetDestination(const stm32_gpdma_channel_t *dmachp, volatile const void *d) { - DMA_Channel_TypeDef *chp = dmachp->channel; - chp->CDAR = (uint32_t)d; + dmachp->channel->CDAR = (uint32_t)d; } /** * @brief Set channel transfer modes and triggers. + * @note This function can be invoked in both ISR or thread context. * * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure * @param[in] tr1 CTR1 register initialization value @@ -743,6 +789,7 @@ void gpdmaChannelSetMode(const stm32_gpdma_channel_t *dmachp, /** * @brief Set channel counters. + * @note This function can be invoked in both ISR or thread context. * * @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure * @param[in] n transaction size @@ -752,9 +799,8 @@ void gpdmaChannelSetMode(const stm32_gpdma_channel_t *dmachp, __STATIC_FORCEINLINE void gpdmaChannelTransactionSize(const stm32_gpdma_channel_t *dmachp, size_t n) { - DMA_Channel_TypeDef *chp = dmachp->channel; - chp->CBR1 = (uint32_t)n; + dmachp->channel->CBR1 = (uint32_t)n; } #endif /* STM32_GPDMA_H */