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

This commit is contained in:
Giovanni Di Sirio 2023-10-26 15:00:36 +00:00
parent a593b93b19
commit 353daeaa12
3 changed files with 146 additions and 53 deletions

View File

@ -19,11 +19,11 @@
* @brief GPDMA helper driver code.
*
* @addtogroup STM32_GPDMA
* @details GPDMA sharing helper driver. In the STM32 the DMA channels are a
* shared resource, this driver allows to allocate and free DMA
* @details GPDMA sharing helper driver. In the STM32 the GPDMA channels are a
* shared resource, this driver allows to allocate and free GPDMA
* channels at runtime in order to allow all the other device
* drivers to coordinate the access to the resource.
* @note The DMA ISR handlers are all declared into this module because
* @note The GPDMA ISR handlers are all declared into this module because
* sharing, the various device drivers can associate a callback to
* ISRs when allocating channels.
* @{
@ -106,7 +106,7 @@ const stm32_gpdma_channel_t __stm32_gpdma_channels[STM32_GPDMA_CHANNELS] = {
/*===========================================================================*/
/**
* @brief Global DMA-related data structures.
* @brief Global GPDMA-related data structures.
*/
static struct {
/**
@ -114,15 +114,15 @@ static struct {
*/
uint32_t allocated_mask;
/**
* @brief DMA IRQ redirectors.
* @brief GPDMA IRQ redirectors.
*/
struct {
/**
* @brief DMA callback function.
* @brief GPDMA callback function.
*/
stm32_gpdmaisr_t func;
/**
* @brief DMA callback parameter.
* @brief GPDMA callback parameter.
*/
void *param;
} channels[STM32_GPDMA_CHANNELS];
@ -141,7 +141,7 @@ static struct {
/*===========================================================================*/
/**
* @brief STM32 DMA helper initialization.
* @brief STM32 GPDMA helper initialization.
*
* @init
*/
@ -158,13 +158,13 @@ void dmaInit(void) {
}
/**
* @brief Allocates a DMA channel.
* @details The channel is allocated and, if required, the DMA clock enabled.
* @brief Allocates a GPDMA channel.
* @details The channel is allocated and, if required, the GPDMA clock enabled.
* The function also enables the IRQ vector associated to the channel
* and initializes its priority.
*
* @param[in] cmask channels mask where to search for an available chennel
* @param[in] irqprio IRQ priority for the DMA channel
* @param[in] irqprio IRQ priority for the GPDMA channel
* @param[in] func handling function pointer, can be @p NULL
* @param[in] param a parameter to be passed to the handling function
* @return Pointer to the allocated @p stm32_dma_channel_t
@ -192,12 +192,12 @@ const stm32_gpdma_channel_t *gpdmaChannelAllocI(uint32_t cmask,
/* Channel found.*/
const stm32_gpdma_channel_t *dmachp = STM32_GPDMA_CHANNEL(i);
/* Installs the DMA handler.*/
/* Installs the GPDMA handler.*/
gpdma.channels[i].func = func;
gpdma.channels[i].param = param;
gpdma.allocated_mask |= mask;
/* Enabling DMA clocks required by the current channels set.*/
/* Enabling GPDMA clocks required by the current channels set.*/
if ((STM32_GPDMA1_MASK_ANY & mask) != 0U) {
rccEnableGPDMA1(true);
}
@ -215,7 +215,7 @@ const stm32_gpdma_channel_t *gpdmaChannelAllocI(uint32_t cmask,
}
/* Putting the channel in a known state.*/
gpdmaStreamDisable(dmachp);
gpdmaChannelDisable(dmachp);
dmachp->channel->CCR = 0U;
return dmachp;
@ -226,13 +226,13 @@ const stm32_gpdma_channel_t *gpdmaChannelAllocI(uint32_t cmask,
}
/**
* @brief Allocates a DMA channel.
* @details The channel is allocated and, if required, the DMA clock enabled.
* @brief Allocates a GPDMA channel.
* @details The channel is allocated and, if required, the GPDMA clock enabled.
* The function also enables the IRQ vector associated to the channel
* and initializes its priority.
*
* @param[in] cmask channels mask where to search for an available chennel
* @param[in] irqprio IRQ priority for the DMA channel
* @param[in] irqprio IRQ priority for the GPDMA channel
* @param[in] func handling function pointer, can be @p NULL
* @param[in] param a parameter to be passed to the handling function
* @return Pointer to the allocated @p stm32_dma_channel_t
@ -255,8 +255,8 @@ const stm32_gpdma_channel_t *gpdmaChannelAlloc(uint32_t cmask,
}
/**
* @brief Releases a DMA channel.
* @details The channel is freed and, if required, the DMA clock disabled.
* @brief Releases a GPDMA channel.
* @details The channel is freed and, if required, the GPDMA clock disabled.
* Trying to release a unallocated channel is an illegal operation
* and is trapped if assertions are enabled.
*
@ -279,7 +279,7 @@ void gpdmaChannelFreeI(const stm32_gpdma_channel_t *dmachp) {
/* Disables the associated IRQ vector if it is no more in use.*/
nvicDisableVector(dmachp->vector);
/* Removes the DMA handler.*/
/* Removes the GPDMA handler.*/
gpdma.channels[selfindex].func = NULL;
gpdma.channels[selfindex].param = NULL;
@ -295,8 +295,8 @@ void gpdmaChannelFreeI(const stm32_gpdma_channel_t *dmachp) {
}
/**
* @brief Releases a DMA channel.
* @details The channel is freed and, if required, the DMA clock disabled.
* @brief Releases a GPDMA channel.
* @details The channel is freed and, if required, the GPDMA clock disabled.
* Trying to release a unallocated channel is an illegal operation
* and is trapped if assertions are enabled.
*
@ -307,12 +307,74 @@ void gpdmaChannelFreeI(const stm32_gpdma_channel_t *dmachp) {
void gpdmaChannelFree(const stm32_gpdma_channel_t *dmachp) {
osalSysLock();
gpdmaStreamFreeI(dmachp);
gpdmaChannelFreeI(dmachp);
osalSysUnlock();
}
/**
* @brief Serves a DMA IRQ.
* @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] dmastp pointer to a @p stm32_gpdma_channel_t structure
*
* @special
*/
void gpdmaChannelSuspend(const stm32_gpdma_channel_t *dmastp) {
osalDbgAssert((dmastp->channel->CCR & STM32_GPDMA_CCR_EN) != 0U,
"not enabled");
dmastp->channel->CCR |= STM32_GPDMA_CCR_SUSP;
while ((dmastp->channel->CSR & STM32_GPDMA_CSR_SUSPF) != 0U) {
/* Wait completion.*/
}
dmastp->channel->CFCR = STM32_GPDMA_CFCR_SUSPF;
}
/**
* @brief GPDMA channel disable.
* @details The function disables the specified channel and then clears any
* pending interrupt.
* @note This function can be invoked in both ISR or thread context.
* @note Interrupts enabling flags are set to zero after this call, see
* bug 3607518.
* @pre The channel must have been allocated using @p dmaChannelAlloc().
* @post After use the channel can be released using @p dmaChannelRelease().
*
* @param[in] dmastp pointer to a @p stm32_gpdma_channel_t structure
*
* @special
*/
void gpdmaChannelDisable(const stm32_gpdma_channel_t *dmastp) {
/* Suspending channel, note, we don't know if it is still active at this
point because the EN bit can be reset in HW.*/
dmastp->channel->CCR |= STM32_GPDMA_CCR_SUSP;
/* If the channel was actually active.*/
if ((dmastp->channel->CCR & STM32_GPDMA_CCR_EN) != 0U) {
/* Waiting for completion if suspend operation then resetting the
completion flag.*/
while ((dmastp->channel->CSR & STM32_GPDMA_CSR_SUSPF) != 0U) {
/* Wait completion.*/
}
dmastp->channel->CFCR = STM32_GPDMA_CFCR_SUSPF;
}
/* Now resetting the channel.*/
dmastp->channel->CCR |= STM32_GPDMA_CCR_RESET;
dmastp->channel->CCR = 0U;
/* Clearing all interrupts.*/
dmastp->channel->CFCR = STM32_GPDMA_CFCR_ALL;
}
/**
* @brief Serves a GPDMA IRQ.
*
* @param[in] dmachp pointer to a @p stm32_gpdma_channel_t structure
*

View File

@ -15,7 +15,7 @@
*/
/**
* @file GPDMAv1/stm32_gpdma.h
* @file DMAv1/stm32_gpdma.h
* @brief GPDMA helper driver header.
*
* @addtogroup STM32_GPDMA
@ -32,7 +32,7 @@
/*===========================================================================*/
/**
* @name GPDMA registers helpers
* @name DMA registers helpers
* @{
*/
#define STM32_GPDMA_CLBAR_LBA_POS DMA_CLBAR_LBA_Pos
@ -46,6 +46,10 @@
#define STM32_GPDMA_CFCR_DTEF DMA_CFCR_DTEF
#define STM32_GPDMA_CFCR_HTF DMA_CFCR_HTF
#define STM32_GPDMA_CFCR_TCF DMA_CFCR_TCF
#define STM32_GPDMA_CFCR_ALL (DMA_CFCR_TOF | DMA_CFCR_SUSPF | \
DMA_CFCR_USEF | DMA_CFCR_ULEF | \
DMA_CFCR_DTEF | DMA_CFCR_HTF | \
DMA_CFCR_TCF)
#define STM32_GPDMA_CSR_FIFOL_POS DMA_CSR_FIFOL_Pos
#define STM32_GPDMA_CSR_FIFOL_MASK (0x7FU << STM32_GPDMA_CSR_FIFOL_POS)
@ -63,21 +67,21 @@
DMA_CSR_DTEF | DMA_CSR_HTF | \
DMA_CSR_TCF)
#define STM32_GPDMA_CR_PRIO_POS DMA_CCR_PRIO_Pos
#define STM32_GPDMA_CR_PRIO_MASK (3U << STM32_GPDMA_CR_PRIO_POS)
#define STM32_GPDMA_CR_PRIO(n) ((n) << STM32_GPDMA_CR_PRIO_POS)
#define STM32_GPDMA_CR_LAP DMA_CCR_LAP
#define STM32_GPDMA_CR_LSM DMA_CCR_LSM
#define STM32_GPDMA_CR_TOIE DMA_CCR_TOIE
#define STM32_GPDMA_CR_SUSPIE DMA_CCR_SUSPIE
#define STM32_GPDMA_CR_USEIE DMA_CCR_USEIE
#define STM32_GPDMA_CR_ULEIE DMA_CCR_ULEIE
#define STM32_GPDMA_CR_DTEIE DMA_CCR_DTEIE
#define STM32_GPDMA_CR_HTIE DMA_CCR_HTIE
#define STM32_GPDMA_CR_TCIE DMA_CCR_TCIE
#define STM32_GPDMA_CR_SUSP DMA_CCR_SUSP
#define STM32_GPDMA_CR_RESET DMA_CCR_RESET
#define STM32_GPDMA_CR_EN DMA_CCR_EN
#define STM32_GPDMA_CCR_PRIO_POS DMA_CCR_PRIO_Pos
#define STM32_GPDMA_CCR_PRIO_MASK (3U << STM32_GPDMA_CR_PRIO_POS)
#define STM32_GPDMA_CCR_PRIO(n) ((n) << STM32_GPDMA_CR_PRIO_POS)
#define STM32_GPDMA_CCR_LAP DMA_CCR_LAP
#define STM32_GPDMA_CCR_LSM DMA_CCR_LSM
#define STM32_GPDMA_CCR_TOIE DMA_CCR_TOIE
#define STM32_GPDMA_CCR_SUSPIE DMA_CCR_SUSPIE
#define STM32_GPDMA_CCR_USEIE DMA_CCR_USEIE
#define STM32_GPDMA_CCR_ULEIE DMA_CCR_ULEIE
#define STM32_GPDMA_CCR_DTEIE DMA_CCR_DTEIE
#define STM32_GPDMA_CCR_HTIE DMA_CCR_HTIE
#define STM32_GPDMA_CCR_TCIE DMA_CCR_TCIE
#define STM32_GPDMA_CCR_SUSP DMA_CCR_SUSP
#define STM32_GPDMA_CCR_RESET DMA_CCR_RESET
#define STM32_GPDMA_CCR_EN DMA_CCR_EN
#define STM32_GPDMA_CTR1_DSEC DMA_CTR1_DSEC
#define STM32_GPDMA_CTR1_DAP DMA_CTR1_DAP
@ -143,6 +147,31 @@
#define STM32_GPDMA_CBR1_BNDT_MASK (3U << STM32_GPDMA_CBR1_BNDT_POS)
#define STM32_GPDMA_CBR1_BNDT(n) ((n) << STM32_GPDMA_CBR1_BNDT_POS)
#define STM32_GPDMA_CTR3_DAO_POS DMA_CTR3_DAO_Pos
#define STM32_GPDMA_CTR3_DAO_MASK (0x1FFFU << STM32_GPDMA_CTR3_DAO_POS)
#define STM32_GPDMA_CTR3_DAO(n) ((n) << STM32_GPDMA_CTR3_DAO_POS)
#define STM32_GPDMA_CTR3_SAO_POS DMA_CTR3_SAO_Pos
#define STM32_GPDMA_CTR3_SAO_MASK (0x1FFFU << STM32_GPDMA_CTR3_SAO_POS)
#define STM32_GPDMA_CTR3_SAO(n) ((n) << STM32_GPDMA_CTR3_SAO_POS)
#define STM32_GPDMA_CBR2_BRDAO_POS DMA_CBR2_BRDAO_Pos
#define STM32_GPDMA_CBR2_BRDAO_MASK (0xFFFFU << STM32_GPDMA_CBR2_BRDAO_POS)
#define STM32_GPDMA_CBR2_BRDAO(n) ((n) << STM32_GPDMA_CBR2_BRDAO_POS)
#define STM32_GPDMA_CBR2_BRSAO_POS DMA_CBR2_BRSAO_Pos
#define STM32_GPDMA_CBR2_BRSAO_MASK (0xFFFFU << STM32_GPDMA_CBR2_BRSAO_POS)
#define STM32_GPDMA_CBR2_BRSAO(n) ((n) << STM32_GPDMA_CBR2_BRSAO_POS)
#define STM32_GPDMA_CLLR_UT1 DMA_CLLR_UT1
#define STM32_GPDMA_CLLR_UT2 DMA_CLLR_UT2
#define STM32_GPDMA_CLLR_UB1 DMA_CLLR_UB1
#define STM32_GPDMA_CLLR_USA DMA_CLLR_USA
#define STM32_GPDMA_CLLR_UDA DMA_CLLR_UDA
#define STM32_GPDMA_CLLR_UT3 DMA_CLLR_UT3
#define STM32_GPDMA_CLLR_UB2 DMA_CLLR_UB2
#define STM32_GPDMA_CLLR_ULL DMA_CLLR_ULL
#define STM32_GPDMA_CLLR_LA_POS DMA_CLLR_LA_Pos
#define STM32_GPDMA_CLLR_LA_MASK (0xFFFCU << STM32_GPDMA_CLLR_LA_POS)
#define STM32_GPDMA_CLLR_LA(n) ((n) << STM32_GPDMA_CLLR_LA_POS)
/** @< */
/**
@ -156,7 +185,7 @@
/**
* @brief Checks if a GPDMA priority is within the valid range.
* @param[in] prio GPDMA priority
* @param[in] prio DMA priority
*
* @retval The check result.
* @retval false invalid GPDMA priority.
@ -187,7 +216,7 @@
(1U << STM32_GPDMA_CHANNEL_ID(dma, ch))
/**
* @name GPDMA channels identifiers
* @name DMA channels identifiers
* @{
*/
/**
@ -315,12 +344,12 @@
* @brief Type of a GPDMA callback.
*
* @param[in] p parameter for the registered function
* @param[in] v content of the CxSR register
* @param[in] csr content of the CxSR register
*/
typedef void (*stm32_gpdmaisr_t)(void *p, uint32_t csr);
/**
* @brief STM32 DMA channel descriptor structure.
* @brief STM32 GPDMA channel descriptor structure.
*/
typedef struct {
DMA_Channel_TypeDef *channel; /**< @brief Associated channel. */
@ -336,7 +365,7 @@ typedef struct {
* @{
*/
/**
* @brief Associates a peripheral data register to a DMA channel.
* @brief Associates a peripheral data register to a GPDMA channel.
* @note This function can be invoked in both ISR or thread context.
* @pre The channel must have been allocated using @p dmaStreamAlloc().
* @post After use the channel can be released using @p dmaStreamRelease().
@ -351,7 +380,7 @@ typedef struct {
}
/**
* @brief Associates a memory destination to a DMA channel.
* @brief Associates a memory destination to a GPDMA channel.
* @note This function can be invoked in both ISR or thread context.
* @pre The channel must have been allocated using @p dmaStreamAlloc().
* @post After use the channel can be released using @p dmaStreamRelease().
@ -409,7 +438,7 @@ typedef struct {
}
/**
* @brief DMA channel enable.
* @brief GPDMA channel enable.
* @note This function can be invoked in both ISR or thread context.
* @pre The channel must have been allocated using @p dmaStreamAlloc().
* @post After use the channel can be released using @p dmaStreamRelease().
@ -423,7 +452,7 @@ typedef struct {
}
/**
* @brief DMA channel disable.
* @brief GPDMA channel disable.
* @details The function disables the specified channel and then clears any
* pending interrupt.
* @note This function can be invoked in both ISR or thread context.
@ -436,14 +465,14 @@ typedef struct {
*
* @special
*/
#define gpdmaStreamDisable(dmastp) { \
#define ______gpdmaStreamDisable(dmastp) { \
(dmastp)->channel->CCR &= ~(STM32_GPDMA_CR_TCIE | STM32_GPDMA_CR_HTIE | \
STM32_GPDMA_CR_TEIE | STM32_GPDMA_CR_EN); \
dmaStreamClearInterrupt(dmastp); \
}
/**
* @brief DMA channel interrupt sources clear.
* @brief GPDMA channel interrupt sources clear.
* @note This function can be invoked in both ISR or thread context.
* @pre The channel must have been allocated using @p dmaStreamAlloc().
* @post After use the channel can be released using @p dmaStreamRelease().
@ -485,7 +514,7 @@ typedef struct {
}
/**
* @brief Polled wait for DMA transfer end.
* @brief Polled wait for GPDMA transfer end.
* @pre The channel must have been allocated using @p dmaStreamAlloc().
* @post After use the channel can be released using @p dmaStreamRelease().
*
@ -520,6 +549,8 @@ 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 *dmastp);
void gpdmaChannelDisable(const stm32_gpdma_channel_t *dmastp);
void gpdmaServeInterrupt(const stm32_gpdma_channel_t *dmachp);
#ifdef __cplusplus
}

View File

@ -518,7 +518,7 @@
*
* @api
*/
#define rccDisableGPDMA1() rccDisableGPAHB1(RCC_AHB1ENR_GPDMA1EN)
#define rccDisableGPDMA1() rccDisableAHB1(RCC_AHB1ENR_GPDMA1EN)
/**
* @brief Resets the GPDMA1 peripheral.