From c96f0b2bbf7c911a5d23d6c9920f1c6f4d766c8c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 26 Jul 2015 06:17:10 +0000 Subject: More STM32L0xx support files. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@8104 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c | 224 ++++++++++++++++++++++--------- 1 file changed, 160 insertions(+), 64 deletions(-) (limited to 'os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c') diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c index 9fd59bbff..4f0d29eb1 100644 --- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c +++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c @@ -15,10 +15,10 @@ */ /** - * @file DMAv1/stm32_dma.c + * @file STM32F3xx/stm32_dma.c * @brief DMA helper driver code. * - * @addtogroup STM32_DMA_V1 + * @addtogroup STM32F3xx_DMA * @details DMA sharing helper driver. In the STM32 the DMA streams are a * shared resource, this driver allows to allocate and free DMA * streams at runtime in order to allow all the other device @@ -54,6 +54,29 @@ */ #define STM32_DMA_CCR_RESET_VALUE 0x00000000U +/* + * Handling devices with shared DMA IRQ handlers. + */ +#if defined(STM32_DMA1_CH23_NUMBER) +#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER +#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER +#endif + +#if defined(STM32_DMA1_CH4567_NUMBER) +#define STM32_DMA1_CH4_NUMBER STM32_DMA1_CH4567_NUMBER +#define STM32_DMA1_CH5_NUMBER STM32_DMA1_CH4567_NUMBER +#define STM32_DMA1_CH6_NUMBER STM32_DMA1_CH4567_NUMBER +#define STM32_DMA1_CH7_NUMBER STM32_DMA1_CH4567_NUMBER +#endif + +#if STM32_ADVANCED_DMA == TRUE +#define ADDR_DMA1_CSELR &DMA1_CSELR->CSELR +#define ADDR_DMA2_CSELR &DMA2_CSELR->CSELR +#else +#define ADDR_DMA1_CSELR NULL +#define ADDR_DMA2_CSELR NULL +#endif + /*===========================================================================*/ /* Driver exported variables. */ /*===========================================================================*/ @@ -65,22 +88,28 @@ * @note Don't use this array directly, use the appropriate wrapper macros * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. */ -const stm32_dma_stream_t __stm32_dma_streams[STM32_DMA_STREAMS] = { - {DMA1_Channel1, &DMA1->IFCR, 0, 0, STM32_DMA1_STREAM1_EVENT_NUMBER}, - {DMA1_Channel2, &DMA1->IFCR, 4, 1, STM32_DMA1_STREAM2_EVENT_NUMBER}, - {DMA1_Channel3, &DMA1->IFCR, 8, 2, STM32_DMA1_STREAM3_EVENT_NUMBER}, - {DMA1_Channel4, &DMA1->IFCR, 12, 3, STM32_DMA1_STREAM4_EVENT_NUMBER}, - {DMA1_Channel5, &DMA1->IFCR, 16, 4, STM32_DMA1_STREAM5_EVENT_NUMBER}, -#if STM32_DMA_STREAMS > 5 - {DMA1_Channel6, &DMA1->IFCR, 20, 5, STM32_DMA1_STREAM6_EVENT_NUMBER}, - {DMA1_Channel7, &DMA1->IFCR, 24, 6, STM32_DMA1_STREAM7_EVENT_NUMBER}, +const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { + {DMA1_Channel1, &DMA1->IFCR, ADDR_DMA1_CSELR, 0, 0, STM32_DMA1_CH1_NUMBER}, + {DMA1_Channel2, &DMA1->IFCR, ADDR_DMA1_CSELR, 4, 1, STM32_DMA1_CH2_NUMBER}, + {DMA1_Channel3, &DMA1->IFCR, ADDR_DMA1_CSELR, 8, 2, STM32_DMA1_CH3_NUMBER}, + {DMA1_Channel4, &DMA1->IFCR, ADDR_DMA1_CSELR, 12, 3, STM32_DMA1_CH4_NUMBER}, + {DMA1_Channel5, &DMA1->IFCR, ADDR_DMA1_CSELR, 16, 4, STM32_DMA1_CH5_NUMBER}, +#if STM32_DMA1_NUM_CHANNELS > 5 + {DMA1_Channel6, &DMA1->IFCR, ADDR_DMA1_CSELR, 20, 5, STM32_DMA1_CH6_NUMBER}, +#else + {NULL, NULL, NULL, 0, 5, 0}, #endif -#if STM32_DMA_STREAMS > 7 - {DMA2_Channel1, &DMA2->IFCR, 0, 7, STM32_DMA2_STREAM1_EVENT_NUMBER}, - {DMA2_Channel2, &DMA2->IFCR, 4, 8, STM32_DMA2_STREAM2_EVENT_NUMBER}, - {DMA2_Channel3, &DMA2->IFCR, 8, 9, STM32_DMA2_STREAM3_EVENT_NUMBER}, - {DMA2_Channel4, &DMA2->IFCR, 12, 10, STM32_DMA2_STREAM4_EVENT_NUMBER}, - {DMA2_Channel5, &DMA2->IFCR, 16, 11, STM32_DMA2_STREAM5_EVENT_NUMBER}, +#if STM32_DMA1_NUM_CHANNELS > 6 + {DMA1_Channel7, &DMA1->IFCR, ADDR_DMA1_CSELR, 24, 6, STM32_DMA1_CH7_NUMBER}, +#else + {NULL, NULL, NULL, 0, 6, 0}, +#endif +#if STM32_DMA2_NUM_CHANNELS > 0 + {DMA2_Channel1, &DMA2->IFCR, ADDR_DMA2_CSELR, 0, 8, STM32_DMA2_CH1_NUMBER}, + {DMA2_Channel2, &DMA2->IFCR, ADDR_DMA2_CSELR, 4, 9, STM32_DMA2_CH2_NUMBER}, + {DMA2_Channel3, &DMA2->IFCR, ADDR_DMA2_CSELR, 8, 10, STM32_DMA2_CH3_NUMBER}, + {DMA2_Channel4, &DMA2->IFCR, ADDR_DMA2_CSELR, 12, 11, STM32_DMA2_CH4_NUMBER}, + {DMA2_Channel5, &DMA2->IFCR, ADDR_DMA2_CSELR, 16, 13, STM32_DMA2_CH5_NUMBER}, #endif }; @@ -114,13 +143,12 @@ static dma_isr_redir_t dma_isr_redir[STM32_DMA_STREAMS]; /* Driver interrupt handlers. */ /*===========================================================================*/ -#if defined(STM32_DMA1_STREAM1_EVENT_HANDLER) || defined(__DOXYGEN__) /** * @brief DMA1 stream 1 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA1_STREAM1_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -132,15 +160,44 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM1_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif -#if defined(STM32_DMA1_STREAM2_EVENT_HANDLER) || defined(__DOXYGEN__) +/* Channels 2 and 3 are shared on some devices.*/ +#if defined(STM32_DMA1_CH23_HANDLER) +/** + * @brief DMA1 streams 2 and 3 shared interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA1_CH23_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 2.*/ + flags = (DMA1->ISR >> 4) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA1->IFCR = flags << 4; + if (dma_isr_redir[1].dma_func) + dma_isr_redir[1].dma_func(dma_isr_redir[1].dma_param, flags); + } + + /* Check on channel 3.*/ + flags = (DMA1->ISR >> 8) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA1->IFCR = flags << 8; + if (dma_isr_redir[2].dma_func) + dma_isr_redir[2].dma_func(dma_isr_redir[2].dma_param, flags); + } + + OSAL_IRQ_EPILOGUE(); +} +#else /*!defined(STM32_DMA1_CH23_HANDLER) */ /** * @brief DMA1 stream 2 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA1_STREAM2_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -152,15 +209,13 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM2_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif -#if defined(STM32_DMA1_STREAM3_EVENT_HANDLER) || defined(__DOXYGEN__) /** * @brief DMA1 stream 3 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA1_STREAM3_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -172,15 +227,66 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM3_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } +#endif /*!defined(STM32_DMA1_CH23_HANDLER) */ + + +/* Channels 4, 5, 6 and 7 are shared on some devices.*/ +#if defined(STM32_DMA1_CH4567_HANDLER) +/** + * @brief DMA1 streams 4 and 5 shared interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA1_CH4567_HANDLER) { + uint32_t flags; + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 4.*/ + flags = (DMA1->ISR >> 12) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA1->IFCR = flags << 12; + if (dma_isr_redir[3].dma_func) + dma_isr_redir[3].dma_func(dma_isr_redir[3].dma_param, flags); + } + + /* Check on channel 5.*/ + flags = (DMA1->ISR >> 16) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA1->IFCR = flags << 16; + if (dma_isr_redir[4].dma_func) + dma_isr_redir[4].dma_func(dma_isr_redir[4].dma_param, flags); + } + +#if STM32_DMA1_NUM_CHANNELS > 5 + /* Check on channel 6.*/ + flags = (DMA1->ISR >> 20) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA1->IFCR = flags << 20; + if (dma_isr_redir[5].dma_func) + dma_isr_redir[5].dma_func(dma_isr_redir[5].dma_param, flags); + } #endif -#if defined(STM32_DMA1_STREAM4_EVENT_HANDLER) || defined(__DOXYGEN__) +#if STM32_DMA1_NUM_CHANNELS > 6 + /* Check on channel 7.*/ + flags = (DMA1->ISR >> 24) & STM32_DMA_ISR_MASK; + if (flags & STM32_DMA_ISR_MASK) { + DMA1->IFCR = flags << 24; + if (dma_isr_redir[6].dma_func) + dma_isr_redir[6].dma_func(dma_isr_redir[6].dma_param, flags); + } +#endif + + OSAL_IRQ_EPILOGUE(); +} +#else /* !defined(STM32_DMA1_CH4567_HANDLER) */ /** * @brief DMA1 stream 4 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA1_STREAM4_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -192,15 +298,13 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM4_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif -#if defined(STM32_DMA1_STREAM5_EVENT_HANDLER) || defined(__DOXYGEN__) /** * @brief DMA1 stream 5 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA1_STREAM5_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -212,15 +316,14 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM5_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif -#if defined(STM32_DMA1_STREAM6_EVENT_HANDLER) || defined(__DOXYGEN__) +#if (STM32_DMA1_NUM_CHANNELS > 5) || defined(__DOXYGEN__) /** * @brief DMA1 stream 6 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA1_STREAM6_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -232,15 +335,15 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM6_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif +#endif /* STM32_DMA1_NUM_CHANNELS > 5 */ -#if defined(STM32_DMA1_STREAM7_EVENT_HANDLER) || defined(__DOXYGEN__) +#if (STM32_DMA1_NUM_CHANNELS > 6) || defined(__DOXYGEN__) /** * @brief DMA1 stream 7 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA1_STREAM7_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -252,15 +355,16 @@ OSAL_IRQ_HANDLER(STM32_DMA1_STREAM7_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif +#endif /* STM32_DMA1_NUM_CHANNELS > 6 */ +#endif /* !defined(STM32_DMA1_CH4567_HANDLER) */ -#if defined(STM32_DMA2_STREAM1_EVENT_HANDLER) || defined(__DOXYGEN__) +#if (STM32_DMA2_NUM_CHANNELS > 0) || defined(__DOXYGEN__) /** * @brief DMA2 stream 1 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA2_STREAM1_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -272,15 +376,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM1_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif -#if defined(STM32_DMA2_STREAM2_EVENT_HANDLER) || defined(__DOXYGEN__) /** * @brief DMA2 stream 2 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA2_STREAM2_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -292,15 +394,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM2_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif -#if defined(STM32_DMA2_STREAM3_EVENT_HANDLER) || defined(__DOXYGEN__) /** * @brief DMA2 stream 3 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA2_STREAM3_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -312,15 +412,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM3_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif -#if defined(STM32_DMA2_STREAM4_EVENT_HANDLER) || defined(__DOXYGEN__) /** * @brief DMA2 stream 4 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA2_STREAM4_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -332,15 +430,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM4_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif -#if defined(STM32_DMA2_STREAM5_EVENT_HANDLER) || defined(__DOXYGEN__) /** * @brief DMA2 stream 5 shared interrupt handler. * * @isr */ -OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) { +OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) { uint32_t flags; OSAL_IRQ_PROLOGUE(); @@ -352,7 +448,7 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) { OSAL_IRQ_EPILOGUE(); } -#endif +#endif /* STM32_DMA2_NUM_CHANNELS > 0 */ /*===========================================================================*/ /* Driver exported functions. */ @@ -366,13 +462,13 @@ OSAL_IRQ_HANDLER(STM32_DMA2_STREAM5_EVENT_HANDLER) { void dmaInit(void) { int i; - dma_streams_mask = 0; + dma_streams_mask = 0U; for (i = 0; i < STM32_DMA_STREAMS; i++) { - __stm32_dma_streams[i].channel->CCR = STM32_DMA_CCR_RESET_VALUE; + _stm32_dma_streams[i].channel->CCR = 0U; dma_isr_redir[i].dma_func = NULL; } DMA1->IFCR = 0xFFFFFFFFU; -#if STM32_HAS_DMA2 +#if STM32_DMA2_NUM_CHANNELS > 0 DMA2->IFCR = 0xFFFFFFFFU; #endif } @@ -409,19 +505,19 @@ bool dmaStreamAllocate(const stm32_dma_stream_t *dmastp, osalDbgCheck(dmastp != NULL); /* Checks if the stream is already taken.*/ - if ((dma_streams_mask & (1 << dmastp->selfindex)) != 0) + if ((dma_streams_mask & (1U << dmastp->selfindex)) != 0U) return true; /* Marks the stream as allocated.*/ dma_isr_redir[dmastp->selfindex].dma_func = func; dma_isr_redir[dmastp->selfindex].dma_param = param; - dma_streams_mask |= (1 << dmastp->selfindex); + dma_streams_mask |= (1U << dmastp->selfindex); /* Enabling DMA clocks required by the current streams set.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0) + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) != 0U) rccEnableDMA1(false); -#if STM32_HAS_DMA2 - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0) +#if STM32_DMA2_NUM_CHANNELS > 0 + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) != 0U) rccEnableDMA2(false); #endif @@ -454,7 +550,7 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { osalDbgCheck(dmastp != NULL); /* Check if the streams is not taken.*/ - osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0, + osalDbgAssert((dma_streams_mask & (1 << dmastp->selfindex)) != 0U, "not allocated"); /* Disables the associated IRQ vector.*/ @@ -464,10 +560,10 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { dma_streams_mask &= ~(1 << dmastp->selfindex); /* Shutting down clocks that are no more required, if any.*/ - if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0) + if ((dma_streams_mask & STM32_DMA1_STREAMS_MASK) == 0U) rccDisableDMA1(false); -#if STM32_HAS_DMA2 - if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0) +#if STM32_DMA2_NUM_CHANNELS > 0 + if ((dma_streams_mask & STM32_DMA2_STREAMS_MASK) == 0U) rccDisableDMA2(false); #endif } -- cgit v1.2.3