diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c index 41c040b85..08a49e507 100644 --- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c +++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c @@ -48,53 +48,59 @@ * @brief Mask of the DMA2 streams in @p dma_streams_mask. */ #define STM32_DMA2_STREAMS_MASK (((1U << STM32_DMA2_NUM_CHANNELS) - \ - 1U) << STM32_DMA1_NUM_CHANNELS) + 1U) << STM32_DMA1_NUM_CHANNELS) #if STM32_DMA_SUPPORTS_CSELR == TRUE #if defined(DMA1_CSELR) -#define DMA1_VARIANT &DMA1_CSELR->CSELR +#define __DMA1_CSELR &DMA1_CSELR->CSELR #else -#define DMA1_VARIANT &DMA1->CSELR +#define __DMA1_CSELR &DMA1->CSELR #endif #if defined(DMA2_CSELR) -#define DMA2_VARIANT &DMA2_CSELR->CSELR +#define __DMA2_CSELR &DMA2_CSELR->CSELR #else -#define DMA2_VARIANT &DMA2->CSELR +#define __DMA2_CSELR &DMA2->CSELR #endif -#define DMA1_CH1_VARIANT DMA1_VARIANT -#define DMA1_CH2_VARIANT DMA1_VARIANT -#define DMA1_CH3_VARIANT DMA1_VARIANT -#define DMA1_CH4_VARIANT DMA1_VARIANT -#define DMA1_CH5_VARIANT DMA1_VARIANT -#define DMA1_CH6_VARIANT DMA1_VARIANT -#define DMA1_CH7_VARIANT DMA1_VARIANT -#define DMA2_CH1_VARIANT DMA2_VARIANT -#define DMA2_CH2_VARIANT DMA2_VARIANT -#define DMA2_CH3_VARIANT DMA2_VARIANT -#define DMA2_CH4_VARIANT DMA2_VARIANT -#define DMA2_CH5_VARIANT DMA2_VARIANT -#define DMA2_CH6_VARIANT DMA2_VARIANT -#define DMA2_CH7_VARIANT DMA2_VARIANT +#define DMA1_CH1_VARIANT __DMA1_CSELR +#define DMA1_CH2_VARIANT __DMA1_CSELR +#define DMA1_CH3_VARIANT __DMA1_CSELR +#define DMA1_CH4_VARIANT __DMA1_CSELR +#define DMA1_CH5_VARIANT __DMA1_CSELR +#define DMA1_CH6_VARIANT __DMA1_CSELR +#define DMA1_CH7_VARIANT __DMA1_CSELR +#define DMA1_CH8_VARIANT __DMA1_CSELR +#define DMA2_CH1_VARIANT __DMA2_CSELR +#define DMA2_CH2_VARIANT __DMA2_CSELR +#define DMA2_CH3_VARIANT __DMA2_CSELR +#define DMA2_CH4_VARIANT __DMA2_CSELR +#define DMA2_CH5_VARIANT __DMA2_CSELR +#define DMA2_CH6_VARIANT __DMA2_CSELR +#define DMA2_CH7_VARIANT __DMA2_CSELR +#define DMA2_CH8_VARIANT __DMA2_CSELR #elif STM32_DMA_SUPPORTS_DMAMUX == TRUE -#define DMA1_CH1_VARIANT DMAMUX1_Channel0 -#define DMA1_CH2_VARIANT DMAMUX1_Channel1 -#define DMA1_CH3_VARIANT DMAMUX1_Channel2 -#define DMA1_CH4_VARIANT DMAMUX1_Channel3 -#define DMA1_CH5_VARIANT DMAMUX1_Channel4 -#define DMA1_CH6_VARIANT DMAMUX1_Channel5 -#define DMA1_CH7_VARIANT DMAMUX1_Channel6 -#define DMA2_CH1_VARIANT DMAMUX1_Channel7 -#define DMA2_CH2_VARIANT DMAMUX1_Channel8 -#define DMA2_CH3_VARIANT DMAMUX1_Channel9 -#define DMA2_CH4_VARIANT DMAMUX1_Channel10 -#define DMA2_CH5_VARIANT DMAMUX1_Channel11 -#define DMA2_CH6_VARIANT DMAMUX1_Channel12 -#define DMA2_CH7_VARIANT DMAMUX1_Channel13 +#define DMAMUX1_CHANNEL(id) (DMAMUX1_BASE + ((id) * 4U)) + +#define DMA1_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(0)) +#define DMA1_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(1)) +#define DMA1_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(2)) +#define DMA1_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(3)) +#define DMA1_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(4)) +#define DMA1_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(5)) +#define DMA1_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(6)) +#define DMA1_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(7)) +#define DMA2_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(8)) +#define DMA2_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(9)) +#define DMA2_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(10)) +#define DMA2_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(11)) +#define DMA2_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(12)) +#define DMA2_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(13)) +#define DMA2_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(14)) +#define DMA2_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(15)) #else /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */ @@ -118,60 +124,68 @@ /* * Default ISR collision masks. */ -#if !defined(DMA1_CH1_CMASK) -#define DMA1_CH1_CMASK 0x00000001U +#if !defined(STM32_DMA1_CH1_CMASK) +#define STM32_DMA1_CH1_CMASK (1U << 0U) #endif -#if !defined(DMA1_CH2_CMASK) -#define DMA1_CH2_CMASK 0x00000002U +#if !defined(STM32_DMA1_CH2_CMASK) +#define STM32_DMA1_CH2_CMASK (1U << 1U) #endif -#if !defined(DMA1_CH3_CMASK) -#define DMA1_CH3_CMASK 0x00000004U +#if !defined(STM32_DMA1_CH3_CMASK) +#define STM32_DMA1_CH3_CMASK (1U << 2U) #endif -#if !defined(DMA1_CH4_CMASK) -#define DMA1_CH4_CMASK 0x00000008U +#if !defined(STM32_DMA1_CH4_CMASK) +#define STM32_DMA1_CH4_CMASK (1U << 3U) #endif -#if !defined(DMA1_CH5_CMASK) -#define DMA1_CH5_CMASK 0x00000010U +#if !defined(STM32_DMA1_CH5_CMASK) +#define STM32_DMA1_CH5_CMASK (1U << 4U) #endif -#if !defined(DMA1_CH6_CMASK) -#define DMA1_CH6_CMASK 0x00000020U +#if !defined(STM32_DMA1_CH6_CMASK) +#define STM32_DMA1_CH6_CMASK (1U << 5U) #endif -#if !defined(DMA1_CH7_CMASK) -#define DMA1_CH7_CMASK 0x00000040U +#if !defined(STM32_DMA1_CH7_CMASK) +#define STM32_DMA1_CH7_CMASK (1U << 6U) #endif -#if !defined(DMA2_CH1_CMASK) -#define DMA2_CH1_CMASK 0x00000080U +#if !defined(STM32_DMA1_CH8_CMASK) +#define STM32_DMA1_CH8_CMASK (1U << 7U) #endif -#if !defined(DMA2_CH2_CMASK) -#define DMA2_CH2_CMASK 0x00000100U +#if !defined(STM32_DMA2_CH1_CMASK) +#define STM32_DMA2_CH1_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 0U)) #endif -#if !defined(DMA2_CH3_CMASK) -#define DMA2_CH3_CMASK 0x00000200U +#if !defined(STM32_DMA2_CH2_CMASK) +#define STM32_DMA2_CH2_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 1U)) #endif -#if !defined(DMA2_CH4_CMASK) -#define DMA2_CH4_CMASK 0x00000400U +#if !defined(STM32_DMA2_CH3_CMASK) +#define STM32_DMA2_CH3_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 2U)) #endif -#if !defined(DMA2_CH5_CMASK) -#define DMA2_CH5_CMASK 0x00000800U +#if !defined(STM32_DMA2_CH4_CMASK) +#define STM32_DMA2_CH4_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 3U)) #endif -#if !defined(DMA2_CH6_CMASK) -#define DMA2_CH6_CMASK 0x00001000U +#if !defined(STM32_DMA2_CH5_CMASK) +#define STM32_DMA2_CH5_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 4U)) #endif -#if !defined(DMA2_CH7_CMASK) -#define DMA2_CH7_CMASK 0x00002000U +#if !defined(STM32_DMA2_CH6_CMASK) +#define STM32_DMA2_CH6_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 5U)) +#endif + +#if !defined(STM32_DMA2_CH7_CMASK) +#define STM32_DMA2_CH7_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 6U)) +#endif + +#if !defined(STM32_DMA2_CH8_CMASK) +#define STM32_DMA2_CH8_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 7U)) #endif /*===========================================================================*/ @@ -186,29 +200,53 @@ * instead: @p STM32_DMA1_STREAM1, @p STM32_DMA1_STREAM2 etc. */ const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS] = { - {DMA1, DMA1_Channel1, DMA1_CH1_CMASK, DMA1_CH1_VARIANT, 0, 0, STM32_DMA1_CH1_NUMBER}, - {DMA1, DMA1_Channel2, DMA1_CH2_CMASK, DMA1_CH2_VARIANT, 4, 1, STM32_DMA1_CH2_NUMBER}, - {DMA1, DMA1_Channel3, DMA1_CH3_CMASK, DMA1_CH3_VARIANT, 8, 2, STM32_DMA1_CH3_NUMBER}, - {DMA1, DMA1_Channel4, DMA1_CH4_CMASK, DMA1_CH4_VARIANT, 12, 3, STM32_DMA1_CH4_NUMBER}, - {DMA1, DMA1_Channel5, DMA1_CH5_CMASK, DMA1_CH5_VARIANT, 16, 4, STM32_DMA1_CH5_NUMBER}, +#if STM32_DMA1_NUM_CHANNELS > 0 + {DMA1, DMA1_Channel1, STM32_DMA1_CH1_CMASK, DMA1_CH1_VARIANT, 0, 0, STM32_DMA1_CH1_NUMBER}, +#endif +#if STM32_DMA1_NUM_CHANNELS > 1 + {DMA1, DMA1_Channel2, STM32_DMA1_CH2_CMASK, DMA1_CH2_VARIANT, 4, 1, STM32_DMA1_CH2_NUMBER}, +#endif +#if STM32_DMA1_NUM_CHANNELS > 2 + {DMA1, DMA1_Channel3, STM32_DMA1_CH3_CMASK, DMA1_CH3_VARIANT, 8, 2, STM32_DMA1_CH3_NUMBER}, +#endif +#if STM32_DMA1_NUM_CHANNELS > 3 + {DMA1, DMA1_Channel4, STM32_DMA1_CH4_CMASK, DMA1_CH4_VARIANT, 12, 3, STM32_DMA1_CH4_NUMBER}, +#endif +#if STM32_DMA1_NUM_CHANNELS > 4 + {DMA1, DMA1_Channel5, STM32_DMA1_CH5_CMASK, DMA1_CH5_VARIANT, 16, 4, STM32_DMA1_CH5_NUMBER}, +#endif #if STM32_DMA1_NUM_CHANNELS > 5 - {DMA1, DMA1_Channel6, DMA1_CH6_CMASK, DMA1_CH6_VARIANT, 20, 5, STM32_DMA1_CH6_NUMBER}, + {DMA1, DMA1_Channel6, STM32_DMA1_CH6_CMASK, DMA1_CH6_VARIANT, 20, 5, STM32_DMA1_CH6_NUMBER}, +#endif #if STM32_DMA1_NUM_CHANNELS > 6 - {DMA1, DMA1_Channel7, DMA1_CH7_CMASK, DMA1_CH7_VARIANT, 24, 6, STM32_DMA1_CH7_NUMBER}, + {DMA1, DMA1_Channel7, STM32_DMA1_CH7_CMASK, DMA1_CH7_VARIANT, 24, 6, STM32_DMA1_CH7_NUMBER}, +#endif +#if STM32_DMA1_NUM_CHANNELS > 7 + {DMA1, DMA1_Channel8, STM32_DMA1_CH8_CMASK, DMA1_CH8_VARIANT, 28, 7, STM32_DMA1_CH8_NUMBER}, +#endif #if STM32_DMA2_NUM_CHANNELS > 0 - {DMA2, DMA2_Channel1, DMA2_CH1_CMASK, DMA2_CH1_VARIANT, 0, 7, STM32_DMA2_CH1_NUMBER}, - {DMA2, DMA2_Channel2, DMA2_CH2_CMASK, DMA2_CH2_VARIANT, 4, 8, STM32_DMA2_CH2_NUMBER}, - {DMA2, DMA2_Channel3, DMA2_CH3_CMASK, DMA2_CH3_VARIANT, 8, 9, STM32_DMA2_CH3_NUMBER}, - {DMA2, DMA2_Channel4, DMA2_CH4_CMASK, DMA2_CH4_VARIANT, 12, 10, STM32_DMA2_CH4_NUMBER}, - {DMA2, DMA2_Channel5, DMA2_CH5_CMASK, DMA2_CH5_VARIANT, 16, 11, STM32_DMA2_CH5_NUMBER}, + {DMA2, DMA2_Channel1, STM32_DMA2_CH1_CMASK, DMA2_CH1_VARIANT, 0, 0 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH1_NUMBER}, +#endif +#if STM32_DMA2_NUM_CHANNELS > 1 + {DMA2, DMA2_Channel2, STM32_DMA2_CH2_CMASK, DMA2_CH2_VARIANT, 4, 1 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH2_NUMBER}, +#endif +#if STM32_DMA2_NUM_CHANNELS > 2 + {DMA2, DMA2_Channel3, STM32_DMA2_CH3_CMASK, DMA2_CH3_VARIANT, 8, 2 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH3_NUMBER}, +#endif +#if STM32_DMA2_NUM_CHANNELS > 3 + {DMA2, DMA2_Channel4, STM32_DMA2_CH4_CMASK, DMA2_CH4_VARIANT, 12, 3 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH4_NUMBER}, +#endif +#if STM32_DMA2_NUM_CHANNELS > 4 + {DMA2, DMA2_Channel5, STM32_DMA2_CH5_CMASK, DMA2_CH5_VARIANT, 16, 4 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH5_NUMBER}, +#endif #if STM32_DMA2_NUM_CHANNELS > 5 - {DMA2, DMA2_Channel6, DMA2_CH6_CMASK, DMA2_CH6_VARIANT, 20, 12, STM32_DMA2_CH6_NUMBER}, + {DMA2, DMA2_Channel6, STM32_DMA2_CH6_CMASK, DMA2_CH6_VARIANT, 20, 5 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH6_NUMBER}, +#endif #if STM32_DMA2_NUM_CHANNELS > 6 - {DMA2, DMA2_Channel7, DMA2_CH7_CMASK, DMA2_CH7_VARIANT, 24, 13, STM32_DMA2_CH7_NUMBER}, -#endif -#endif -#endif + {DMA2, DMA2_Channel7, STM32_DMA2_CH7_CMASK, DMA2_CH7_VARIANT, 24, 6 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH7_NUMBER}, #endif +#if STM32_DMA2_NUM_CHANNELS > 6 + {DMA2, DMA2_Channel8, STM32_DMA2_CH8_CMASK, DMA2_CH8_VARIANT, 28, 7 + STM32_DMA1_NUM_CHANNELS, STM32_DMA2_CH8_NUMBER}, #endif }; @@ -647,25 +685,26 @@ const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id, * @iclass */ void dmaStreamFreeI(const stm32_dma_stream_t *dmastp) { + uint32_t selfindex = (uint32_t)dmastp->selfindex; osalDbgCheck(dmastp != NULL); /* Check if the streams is not taken.*/ - osalDbgAssert((dma.allocated_mask & (1 << dmastp->selfindex)) != 0U, + osalDbgAssert((dma.allocated_mask & (1 << selfindex)) != 0U, "not allocated"); /* Marks the stream as not allocated.*/ - dma.allocated_mask &= ~(1U << dmastp->selfindex); - dma.isr_mask &= ~(1U << dmastp->selfindex); + dma.allocated_mask &= ~(1U << selfindex); + dma.isr_mask &= ~(1U << selfindex); /* Disables the associated IRQ vector if it is no more in use.*/ - if ((dma.allocated_mask & dmastp->cmask) == 0U) { + if ((dma.isr_mask & dmastp->cmask) == 0U) { nvicDisableVector(dmastp->vector); } /* Removes the DMA handler.*/ - dma.streams[dmastp->selfindex].func = NULL; - dma.streams[dmastp->selfindex].param = NULL; + dma.streams[selfindex].func = NULL; + dma.streams[selfindex].param = NULL; /* Shutting down clocks that are no more required, if any.*/ if ((dma.allocated_mask & STM32_DMA1_STREAMS_MASK) == 0U) { @@ -711,13 +750,13 @@ void dmaStreamFree(const stm32_dma_stream_t *dmastp) { */ void dmaServeInterrupt(const stm32_dma_stream_t *dmastp) { uint32_t flags; - uint32_t idx = (dmastp)->selfindex; + uint32_t selfindex = (uint32_t)dmastp->selfindex; flags = (dmastp->dma->ISR >> dmastp->shift) & STM32_DMA_ISR_MASK; if (flags & dmastp->channel->CCR) { dmastp->dma->IFCR = flags << dmastp->shift; - if (dma.streams[idx].func) { - dma.streams[idx].func(dma.streams[idx].param, flags); + if (dma.streams[selfindex].func) { + dma.streams[selfindex].func(dma.streams[selfindex].param, flags); } } } diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h index e18e55ff0..6042ebb24 100644 --- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h +++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h @@ -50,11 +50,6 @@ */ #define STM32_DMA_ISR_MASK 0x0E -/** - * @brief From stream number to shift factor in @p ISR and @p IFCR registers. - */ -#define STM32_DMA_ISR_SHIFT(stream) (((stream) - 1U) * 4U) - /** * @brief Returns the request line associated to the specified stream. * @note In some STM32 manuals the request line is named confusingly @@ -65,7 +60,8 @@ * nibble * @return Returns the request associated to the stream. */ -#define STM32_DMA_GETCHANNEL(id, c) (((c) >> (((id) % 7U) * 4U)) & 15U) +#define STM32_DMA_GETCHANNEL(id, c) \ + (((uint32_t)(c) >> (((uint32_t)(id) % (uint32_t)STM32_DMA1_NUM_CHANNELS) * 4U)) & 15U) /** * @brief Checks if a DMA priority is within the valid range. @@ -105,7 +101,9 @@ * @param[in] stream the stream number * @return An unique numeric stream identifier. */ -#define STM32_DMA_STREAM_ID(dma, stream) ((((dma) - 1U) * 7U) + ((stream) - 1U)) +#define STM32_DMA_STREAM_ID(dma, stream) \ + ((((uint32_t)(dma) - 1U) * (uint32_t)STM32_DMA1_NUM_CHANNELS) + \ + ((uint32_t)(stream) - 1U)) /** * @brief Returns a DMA stream identifier mask. @@ -156,20 +154,54 @@ */ #define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id]) +#if STM32_DMA1_NUM_CHANNELS > 0 #define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0) +#endif +#if STM32_DMA1_NUM_CHANNELS > 1 #define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1) +#endif +#if STM32_DMA1_NUM_CHANNELS > 2 #define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2) +#endif +#if STM32_DMA1_NUM_CHANNELS > 3 #define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3) +#endif +#if STM32_DMA1_NUM_CHANNELS > 4 #define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4) +#endif +#if STM32_DMA1_NUM_CHANNELS > 5 #define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5) +#endif +#if STM32_DMA1_NUM_CHANNELS > 6 #define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6) -#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(7) -#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(8) -#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(9) -#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(10) -#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(11) -#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(12) -#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(13) +#endif +#if STM32_DMA1_NUM_CHANNELS > 7 +#define STM32_DMA1_STREAM8 STM32_DMA_STREAM(7) +#endif +#if STM32_DMA2_NUM_CHANNELS > 0 +#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 0) +#endif +#if STM32_DMA2_NUM_CHANNELS > 1 +#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 1) +#endif +#if STM32_DMA2_NUM_CHANNELS > 2 +#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 2) +#endif +#if STM32_DMA2_NUM_CHANNELS > 3 +#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 3) +#endif +#if STM32_DMA2_NUM_CHANNELS > 4 +#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 4) +#endif +#if STM32_DMA2_NUM_CHANNELS > 5 +#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 5) +#endif +#if STM32_DMA2_NUM_CHANNELS > 6 +#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 6) +#endif +#if STM32_DMA2_NUM_CHANNELS > 7 +#define STM32_DMA2_STREAM8 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 7) +#endif /** @} */ /** @@ -261,7 +293,11 @@ #error "STM32_DMA2_NUM_CHANNELS not defined in registry" #endif -#if (STM32_DMA1_NUM_CHANNELS < 7) && (STM32_DMA2_NUM_CHANNELS > 0) +#if (STM32_DMA1_NUM_CHANNELS < 0) || (STM32_DMA1_NUM_CHANNELS > 8) +#error "unsupported channels configuration" +#endif + +#if (STM32_DMA2_NUM_CHANNELS < 0) || (STM32_DMA2_NUM_CHANNELS > 8) #error "unsupported channels configuration" #endif diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma_test.c b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma_test.c deleted file mode 100644 index b0c23c486..000000000 --- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma_test.c +++ /dev/null @@ -1,784 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file DMAv1/stm32_dma.c - * @brief DMA helper driver code. - * - * @addtogroup STM32_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 - * drivers to coordinate the access to the resource. - * @note The DMA ISR handlers are all declared into this module because - * sharing, the various device drivers can associate a callback to - * ISRs when allocating streams. - * @{ - */ - -#include "hal.h" - -/* The following macro is only defined if some driver requiring DMA services - has been enabled.*/ -#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/** - * @brief Mask of the DMA1 streams in @p dma_streams_mask. - */ -#define STM32_DMA1_STREAMS_MASK ((1U << STM32_DMA1_NUM_CHANNELS) - 1U) - -/** - * @brief Mask of the DMA2 streams in @p dma_streams_mask. - */ -#define STM32_DMA2_STREAMS_MASK (((1U << STM32_DMA2_NUM_CHANNELS) - \ - 1U) << STM32_DMA1_NUM_CHANNELS) - -#if STM32_DMA_SUPPORTS_CSELR == TRUE - -#if defined(DMA1_CSELR) -#define __DMA1_CSELR &DMA1_CSELR->CSELR -#else -#define __DMA1_CSELR &DMA1->CSELR -#endif - -#if defined(DMA2_CSELR) -#define __DMA2_CSELR &DMA2_CSELR->CSELR -#else -#define __DMA2_CSELR &DMA2->CSELR -#endif - -#define DMA1_CH1_VARIANT __DMA1_CSELR -#define DMA1_CH2_VARIANT __DMA1_CSELR -#define DMA1_CH3_VARIANT __DMA1_CSELR -#define DMA1_CH4_VARIANT __DMA1_CSELR -#define DMA1_CH5_VARIANT __DMA1_CSELR -#define DMA1_CH6_VARIANT __DMA1_CSELR -#define DMA1_CH7_VARIANT __DMA1_CSELR -#define DMA1_CH8_VARIANT __DMA1_CSELR -#define DMA2_CH1_VARIANT __DMA2_CSELR -#define DMA2_CH2_VARIANT __DMA2_CSELR -#define DMA2_CH3_VARIANT __DMA2_CSELR -#define DMA2_CH4_VARIANT __DMA2_CSELR -#define DMA2_CH5_VARIANT __DMA2_CSELR -#define DMA2_CH6_VARIANT __DMA2_CSELR -#define DMA2_CH7_VARIANT __DMA2_CSELR -#define DMA2_CH8_VARIANT __DMA2_CSELR - -#elif STM32_DMA_SUPPORTS_DMAMUX == TRUE - -#define DMAMUX1_CHANNEL(id) (DMAMUX1_BASE + ((id) * 4U)) - -#define DMA1_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(0)) -#define DMA1_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(1)) -#define DMA1_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(2)) -#define DMA1_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(3)) -#define DMA1_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(4)) -#define DMA1_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(5)) -#define DMA1_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(6)) -#define DMA1_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(7)) -#define DMA2_CH1_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(8)) -#define DMA2_CH2_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(9)) -#define DMA2_CH3_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(10)) -#define DMA2_CH4_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(11)) -#define DMA2_CH5_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(12)) -#define DMA2_CH6_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(13)) -#define DMA2_CH7_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(14)) -#define DMA2_CH8_VARIANT ((DMAMUX_Channel_TypeDef *)DMAMUX1_CHANNEL(15)) - -#else /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */ - -#define DMA1_CH1_VARIANT 0 -#define DMA1_CH2_VARIANT 0 -#define DMA1_CH3_VARIANT 0 -#define DMA1_CH4_VARIANT 0 -#define DMA1_CH5_VARIANT 0 -#define DMA1_CH6_VARIANT 0 -#define DMA1_CH7_VARIANT 0 -#define DMA2_CH1_VARIANT 0 -#define DMA2_CH2_VARIANT 0 -#define DMA2_CH3_VARIANT 0 -#define DMA2_CH4_VARIANT 0 -#define DMA2_CH5_VARIANT 0 -#define DMA2_CH6_VARIANT 0 -#define DMA2_CH7_VARIANT 0 - -#endif /* !(STM32_DMA_SUPPORTS_DMAMUX == TRUE) */ - -/* - * Default ISR collision masks. - */ -#if !defined(DMA1_CH1_CMASK) -#define DMA1_CH1_CMASK (1U << 0U) -#endif - -#if !defined(DMA1_CH2_CMASK) -#define DMA1_CH2_CMASK (1U << 1U) -#endif - -#if !defined(DMA1_CH3_CMASK) -#define DMA1_CH3_CMASK (1U << 2U) -#endif - -#if !defined(DMA1_CH4_CMASK) -#define DMA1_CH4_CMASK (1U << 3U) -#endif - -#if !defined(DMA1_CH5_CMASK) -#define DMA1_CH5_CMASK (1U << 4U) -#endif - -#if !defined(DMA1_CH6_CMASK) -#define DMA1_CH6_CMASK (1U << 5U) -#endif - -#if !defined(DMA1_CH7_CMASK) -#define DMA1_CH7_CMASK (1U << 6U) -#endif - -#if !defined(DMA1_CH8_CMASK) -#define DMA1_CH8_CMASK (1U << 7U) -#endif - -#if !defined(DMA2_CH1_CMASK) -#define DMA2_CH1_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 0U)) -#endif - -#if !defined(DMA2_CH2_CMASK) -#define DMA2_CH2_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 1U)) -#endif - -#if !defined(DMA2_CH3_CMASK) -#define DMA2_CH3_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 2U)) -#endif - -#if !defined(DMA2_CH4_CMASK) -#define DMA2_CH4_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 3U)) -#endif - -#if !defined(DMA2_CH5_CMASK) -#define DMA2_CH5_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 4U)) -#endif - -#if !defined(DMA2_CH6_CMASK) -#define DMA2_CH6_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 5U)) -#endif - -#if !defined(DMA2_CH7_CMASK) -#define DMA2_CH7_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 6U)) -#endif - -#if !defined(DMA2_CH7_CMASK) -#define DMA2_CH7_CMASK (1U << (STM32_DMA1_NUM_CHANNELS + 7U)) -#endif - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief DMA streams descriptors. - * @details This table keeps the association between an unique stream - * identifier and the involved physical registers. - * @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] = { -#if STM32_DMA1_NUM_CHANNELS > 0 - {DMA1, DMA1_Channel1, DMA1_CH1_CMASK, DMA1_CH1_VARIANT, 0, STM32_DMA1_CH1_NUMBER}, -#endif -#if STM32_DMA1_NUM_CHANNELS > 1 - {DMA1, DMA1_Channel2, DMA1_CH2_CMASK, DMA1_CH2_VARIANT, 4, STM32_DMA1_CH2_NUMBER}, -#endif -#if STM32_DMA1_NUM_CHANNELS > 2 - {DMA1, DMA1_Channel3, DMA1_CH3_CMASK, DMA1_CH3_VARIANT, 8, STM32_DMA1_CH3_NUMBER}, -#endif -#if STM32_DMA1_NUM_CHANNELS > 3 - {DMA1, DMA1_Channel4, DMA1_CH4_CMASK, DMA1_CH4_VARIANT, 12, STM32_DMA1_CH4_NUMBER}, -#endif -#if STM32_DMA1_NUM_CHANNELS > 4 - {DMA1, DMA1_Channel5, DMA1_CH5_CMASK, DMA1_CH5_VARIANT, 16, STM32_DMA1_CH5_NUMBER}, -#endif -#if STM32_DMA1_NUM_CHANNELS > 5 - {DMA1, DMA1_Channel6, DMA1_CH6_CMASK, DMA1_CH6_VARIANT, 20, STM32_DMA1_CH6_NUMBER}, -#endif -#if STM32_DMA1_NUM_CHANNELS > 6 - {DMA1, DMA1_Channel7, DMA1_CH7_CMASK, DMA1_CH7_VARIANT, 24, STM32_DMA1_CH7_NUMBER}, -#endif -#if STM32_DMA1_NUM_CHANNELS > 7 - {DMA1, DMA1_Channel8, DMA1_CH8_CMASK, DMA1_CH8_VARIANT, 28, STM32_DMA1_CH8_NUMBER}, -#endif -#if STM32_DMA2_NUM_CHANNELS > 0 - {DMA2, DMA2_Channel1, DMA2_CH1_CMASK, DMA2_CH1_VARIANT, 0, STM32_DMA2_CH1_NUMBER}, -#endif -#if STM32_DMA2_NUM_CHANNELS > 1 - {DMA2, DMA2_Channel2, DMA2_CH2_CMASK, DMA2_CH2_VARIANT, 4, STM32_DMA2_CH2_NUMBER}, -#endif -#if STM32_DMA2_NUM_CHANNELS > 2 - {DMA2, DMA2_Channel3, DMA2_CH3_CMASK, DMA2_CH3_VARIANT, 8, STM32_DMA2_CH3_NUMBER}, -#endif -#if STM32_DMA2_NUM_CHANNELS > 3 - {DMA2, DMA2_Channel4, DMA2_CH4_CMASK, DMA2_CH4_VARIANT, 12, STM32_DMA2_CH4_NUMBER}, -#endif -#if STM32_DMA2_NUM_CHANNELS > 4 - {DMA2, DMA2_Channel5, DMA2_CH5_CMASK, DMA2_CH5_VARIANT, 16, STM32_DMA2_CH5_NUMBER}, -#endif -#if STM32_DMA2_NUM_CHANNELS > 5 - {DMA2, DMA2_Channel6, DMA2_CH6_CMASK, DMA2_CH6_VARIANT, 20, STM32_DMA2_CH6_NUMBER}, -#endif -#if STM32_DMA2_NUM_CHANNELS > 6 - {DMA2, DMA2_Channel7, DMA2_CH7_CMASK, DMA2_CH7_VARIANT, 24, STM32_DMA2_CH7_NUMBER}, -#endif -#if STM32_DMA2_NUM_CHANNELS > 6 - {DMA2, DMA2_Channel8, DMA2_CH8_CMASK, DMA2_CH8_VARIANT, 28, STM32_DMA2_CH8_NUMBER}, -#endif -}; - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief Global DMA-related data structures. - */ -static struct { - /** - * @brief Mask of the allocated streams. - */ - uint32_t allocated_mask; - /** - * @brief Mask of the enabled streams ISRs. - */ - uint32_t isr_mask; - /** - * @brief DMA IRQ redirectors. - */ - struct { - /** - * @brief DMA callback function. - */ - stm32_dmaisr_t func; - /** - * @brief DMA callback parameter. - */ - void *param; - } streams[STM32_DMA_STREAMS]; -} dma; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if defined(STM32_DMA1_CH1_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 stream 1 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA1_STREAM1); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA1_CH2_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 stream 2 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA1_STREAM2); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA1_CH3_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 stream 3 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH3_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA1_STREAM3); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA1_CH4_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 stream 4 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH4_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA1_STREAM4); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA1_CH5_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 stream 5 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH5_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA1_STREAM5); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA1_CH6_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 stream 6 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH6_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA1_STREAM6); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA1_CH7_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA1 stream 7 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA1_CH7_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA1_STREAM7); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA2_CH1_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 1 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA2_CH1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA2_STREAM1); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA2_CH2_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 2 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA2_CH2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA2_STREAM2); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA2_CH3_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 3 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA2_CH3_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA2_STREAM3); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA2_CH4_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 4 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA2_CH4_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA2_STREAM4); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA2_CH5_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 5 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA2_CH5_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA2_STREAM5); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA2_CH6_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 6 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA2_CH6_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA2_STREAM6); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if defined(STM32_DMA2_CH7_HANDLER) || defined(__DOXYGEN__) -/** - * @brief DMA2 stream 7 shared ISR. - * - * @isr - */ -OSAL_IRQ_HANDLER(STM32_DMA2_CH7_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - dmaServeInterrupt(STM32_DMA2_STREAM7); - - OSAL_IRQ_EPILOGUE(); -} -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief STM32 DMA helper initialization. - * - * @init - */ -void dmaInit(void) { - int i; - - dma.allocated_mask = 0U; - dma.isr_mask = 0U; - for (i = 0; i < STM32_DMA_STREAMS; i++) { - _stm32_dma_streams[i].channel->CCR = STM32_DMA_CCR_RESET_VALUE; - dma.streams[i].func = NULL; - } - DMA1->IFCR = 0xFFFFFFFFU; -#if STM32_DMA2_NUM_CHANNELS > 0 - DMA2->IFCR = 0xFFFFFFFFU; -#endif -} - -/** - * @brief Allocates a DMA stream. - * @details The stream is allocated and, if required, the DMA clock enabled. - * The function also enables the IRQ vector associated to the stream - * and initializes its priority. - * - * @param[in] id numeric identifiers of a specific stream or: - * - @p STM32_DMA_STREAM_ID_ANY for any stream. - * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream - * on DMA1. - * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream - * on DMA2. - * . - * @param[in] priority IRQ priority for the DMA stream - * @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_stream_t - * structure. - * @retval NULL if a/the stream is not available. - * - * @iclass - */ -const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id, - uint32_t priority, - stm32_dmaisr_t func, - void *param) { - uint32_t i, startid, endid; - - osalDbgCheckClassI(); - - if (id < STM32_DMA_STREAMS) { - startid = id; - endid = id; - } -#if STM32_DMA_SUPPORTS_DMAMUX == TRUE - else if (id == STM32_DMA_STREAM_ID_ANY) { - startid = 0U; - endid = STM32_DMA_STREAMS - 1U; - } - else if (id == STM32_DMA_STREAM_ID_ANY_DMA1) { - startid = 0U; - endid = STM32_DMA1_NUM_CHANNELS - 1U; - } -#if STM32_DMA2_NUM_CHANNELS > 0 - else if (id == STM32_DMA_STREAM_ID_ANY_DMA2) { - startid = 7U; - endid = STM32_DMA_STREAMS - 1U; - } -#endif -#endif - else { - osalDbgCheck(false); - return NULL; - } - - for (i = startid; i <= endid; i++) { - uint32_t mask = (1U << i); - if ((dma.allocated_mask & mask) == 0U) { - const stm32_dma_stream_t *dmastp = STM32_DMA_STREAM(i); - - /* Installs the DMA handler.*/ - dma.streams[i].func = func; - dma.streams[i].param = param; - dma.allocated_mask |= mask; - - /* Enabling DMA clocks required by the current streams set.*/ - if ((STM32_DMA1_STREAMS_MASK & mask) != 0U) { - rccEnableDMA1(true); - } -#if STM32_DMA2_NUM_CHANNELS > 0 - if ((STM32_DMA2_STREAMS_MASK & mask) != 0U) { - rccEnableDMA2(true); - } -#endif - -#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccEnableDMAMUX) - /* Enabling DMAMUX if present.*/ - if (dma.allocated_mask != 0U) { - rccEnableDMAMUX(true); - } -#endif - - /* Enables the associated IRQ vector if not already enabled and if a - callback is defined.*/ - if (func != NULL) { - if ((dma.isr_mask & dmastp->cmask) == 0U) { - nvicEnableVector(dmastp->vector, priority); - } - dma.isr_mask |= mask; - } - - /* Putting the stream in a known state.*/ - dmaStreamDisable(dmastp); - dmastp->channel->CCR = STM32_DMA_CCR_RESET_VALUE; - - return dmastp; - } - } - - return NULL; -} - -/** - * @brief Allocates a DMA stream. - * @details The stream is allocated and, if required, the DMA clock enabled. - * The function also enables the IRQ vector associated to the stream - * and initializes its priority. - * - * @param[in] id numeric identifiers of a specific stream or: - * - @p STM32_DMA_STREAM_ID_ANY for any stream. - * - @p STM32_DMA_STREAM_ID_ANY_DMA1 for any stream - * on DMA1. - * - @p STM32_DMA_STREAM_ID_ANY_DMA2 for any stream - * on DMA2. - * . - * @param[in] priority IRQ priority for the DMA stream - * @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_stream_t - * structure. - * @retval NULL if a/the stream is not available. - * - * @api - */ -const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id, - uint32_t priority, - stm32_dmaisr_t func, - void *param) { - const stm32_dma_stream_t *dmastp; - - osalSysLock(); - dmastp = dmaStreamAllocI(id, priority, func, param); - osalSysUnlock(); - - return dmastp; -} - -/** - * @brief Releases a DMA stream. - * @details The stream is freed and, if required, the DMA clock disabled. - * Trying to release a unallocated stream is an illegal operation - * and is trapped if assertions are enabled. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @iclass - */ -void dmaStreamFreeI(const stm32_dma_stream_t *dmastp) { - uint32_t selfindex = (uint32_t)(dmastp - _stm32_dma_streams;) - - osalDbgCheck(dmastp != NULL); - - /* Check if the streams is not taken.*/ - osalDbgAssert((dma.allocated_mask & (1 << selfindex)) != 0U, - "not allocated"); - - /* Marks the stream as not allocated.*/ - dma.allocated_mask &= ~(1U << selfindex); - dma.isr_mask &= ~(1U << selfindex); - - /* Disables the associated IRQ vector if it is no more in use.*/ - if ((dma.allocated_mask & dmastp->cmask) == 0U) { - nvicDisableVector(dmastp->vector); - } - - /* Removes the DMA handler.*/ - dma.streams[selfindex].func = NULL; - dma.streams[selfindex].param = NULL; - - /* Shutting down clocks that are no more required, if any.*/ - if ((dma.allocated_mask & STM32_DMA1_STREAMS_MASK) == 0U) { - rccDisableDMA1(); - } -#if STM32_DMA2_NUM_CHANNELS > 0 - if ((dma.allocated_mask & STM32_DMA2_STREAMS_MASK) == 0U) { - rccDisableDMA2(); - } -#endif - -#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) && defined(rccDisableDMAMUX) - /* Shutting down DMAMUX if present.*/ - if (dma.allocated_mask == 0U) { - rccDisableDMAMUX(); - } -#endif -} - -/** - * @brief Releases a DMA stream. - * @details The stream is freed and, if required, the DMA clock disabled. - * Trying to release a unallocated stream is an illegal operation - * and is trapped if assertions are enabled. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @api - */ -void dmaStreamFree(const stm32_dma_stream_t *dmastp) { - - osalSysLock(); - dmaStreamFreeI(dmastp); - osalSysUnlock(); -} - -/** - * @brief Serves a DMA IRQ. - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -void dmaServeInterrupt(const stm32_dma_stream_t *dmastp) { - uint32_t flags; - uint32_t selfindex = (uint32_t)(dmastp - _stm32_dma_streams;) - - flags = (dmastp->dma->ISR >> dmastp->shift) & STM32_DMA_ISR_MASK; - if (flags & dmastp->channel->CCR) { - dmastp->dma->IFCR = flags << dmastp->shift; - if (dma.streams[selfindex].func) { - dma.streams[selfindex].func(dma.streams[idx].param, flags); - } - } -} - -#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__) -/** - * @brief Associates a peripheral request to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * - * @param[in] dmastp pointer to a @p stm32_dma_stream_t structure - * @param[in] per peripheral identifier - * - * @special - */ -void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per) { - - osalDbgCheck(per < 256U); - - dmastp->mux->CCR = per; -} -#endif - -#endif /* STM32_DMA_REQUIRED */ - -/** @} */ diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma_test.h b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma_test.h deleted file mode 100644 index d1e899f1a..000000000 --- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma_test.h +++ /dev/null @@ -1,554 +0,0 @@ -/* - ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/** - * @file DMAv1/stm32_dma.h - * @brief DMA helper driver header. - * @note This driver uses the new naming convention used for the STM32F2xx - * so the "DMA channels" are referred as "DMA streams". - * - * @addtogroup STM32_DMA - * @{ - */ - -#ifndef STM32_DMA_H -#define STM32_DMA_H - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/** - * @brief DMA capability. - * @details if @p TRUE then the DMA is able of burst transfers, FIFOs, - * scatter gather and other advanced features. - */ -#define STM32_DMA_ADVANCED FALSE - -/** - * @brief Total number of DMA streams. - * @details This is the total number of streams among all the DMA units. - */ -#define STM32_DMA_STREAMS (STM32_DMA1_NUM_CHANNELS + \ - STM32_DMA2_NUM_CHANNELS) - -/** - * @brief Mask of the ISR bits passed to the DMA callback functions. - */ -#define STM32_DMA_ISR_MASK 0x0E - -/** - * @brief Returns the request line associated to the specified stream. - * @note In some STM32 manuals the request line is named confusingly - * channel. - * - * @param[in] id the unique numeric stream identifier - * @param[in] c a stream/request association word, one request per - * nibble - * @return Returns the request associated to the stream. - */ -#define STM32_DMA_GETCHANNEL(id, c) \ - (((uint32_t)(c) >> (((uint32_t)(id) % (uint32_t)STM32_DMA1_NUM_CHANNELS) * 4U)) & 15U) - -/** - * @brief Checks if a DMA priority is within the valid range. - * @param[in] prio DMA priority - * - * @retval The check result. - * @retval false invalid DMA priority. - * @retval true correct DMA priority. - */ -#define STM32_DMA_IS_VALID_PRIORITY(prio) (((prio) >= 0U) && ((prio) <= 3U)) - -#if (STM32_DMA_SUPPORTS_DMAMUX == FALSE) || defined(_DOXYGEN__) -/** - * @brief Checks if a DMA stream id is within the valid range. - * - * @param[in] id DMA stream id - * @retval The check result. - * @retval false invalid DMA channel. - * @retval true correct DMA channel. - */ -#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \ - ((id) < STM32_DMA_STREAMS)) -#else /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */ -#if STM32_DMA2_NUM_CHANNELS > 0 -#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \ - ((id) <= (STM32_DMA_STREAMS + 2))) -#else -#define STM32_DMA_IS_VALID_STREAM(id) (((id) >= 0U) && \ - ((id) <= (STM32_DMA_STREAMS + 1))) -#endif -#endif /* STM32_DMA_SUPPORTS_DMAMUX == FALSE */ - -/** - * @brief Returns an unique numeric identifier for a DMA stream. - * - * @param[in] dma the DMA unit number - * @param[in] stream the stream number - * @return An unique numeric stream identifier. - */ -#define STM32_DMA_STREAM_ID(dma, stream) \ - ((((uint32_t)(dma) - 1U) * (uint32_t)STM32_DMA1_NUM_CHANNELS) + \ - ((uint32_t)(stream) - 1U)) - -/** - * @brief Returns a DMA stream identifier mask. - * - * - * @param[in] dma the DMA unit number - * @param[in] stream the stream number - * @return A DMA stream identifier mask. - */ -#define STM32_DMA_STREAM_ID_MSK(dma, stream) \ - (1U << STM32_DMA_STREAM_ID(dma, stream)) - -/** - * @brief Checks if a DMA stream unique identifier belongs to a mask. - * - * @param[in] id the stream numeric identifier - * @param[in] mask the stream numeric identifiers mask - * - * @retval The check result. - * @retval false id does not belong to the mask. - * @retval true id belongs to the mask. - */ -#define STM32_DMA_IS_VALID_ID(id, mask) (((1U << (id)) & (mask))) - -#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(_DOXYGEN__) -/** - * @name Special stream identifiers - * @{ - */ -#define STM32_DMA_STREAM_ID_ANY STM32_DMA_STREAMS -#define STM32_DMA_STREAM_ID_ANY_DMA1 (STM32_DMA_STREAM_ID_ANY + 1) -#if STM32_DMA2_NUM_CHANNELS > 0 -#define STM32_DMA_STREAM_ID_ANY_DMA2 (STM32_DMA_STREAM_ID_ANY_DMA1 + 1) -#endif -/** @} */ -#endif - -/** - * @name DMA streams identifiers - * @{ - */ -/** - * @brief Returns a pointer to a stm32_dma_stream_t structure. - * - * @param[in] id the stream numeric identifier - * @return A pointer to the stm32_dma_stream_t constant structure - * associated to the DMA stream. - */ -#define STM32_DMA_STREAM(id) (&_stm32_dma_streams[id]) - -#if STM32_DMA1_NUM_CHANNELS > 0 -#define STM32_DMA1_STREAM1 STM32_DMA_STREAM(0) -#endif -#if STM32_DMA1_NUM_CHANNELS > 1 -#define STM32_DMA1_STREAM2 STM32_DMA_STREAM(1) -#endif -#if STM32_DMA1_NUM_CHANNELS > 2 -#define STM32_DMA1_STREAM3 STM32_DMA_STREAM(2) -#endif -#if STM32_DMA1_NUM_CHANNELS > 3 -#define STM32_DMA1_STREAM4 STM32_DMA_STREAM(3) -#endif -#if STM32_DMA1_NUM_CHANNELS > 4 -#define STM32_DMA1_STREAM5 STM32_DMA_STREAM(4) -#endif -#if STM32_DMA1_NUM_CHANNELS > 5 -#define STM32_DMA1_STREAM6 STM32_DMA_STREAM(5) -#endif -#if STM32_DMA1_NUM_CHANNELS > 6 -#define STM32_DMA1_STREAM7 STM32_DMA_STREAM(6) -#endif -#if STM32_DMA1_NUM_CHANNELS > 7 -#define STM32_DMA1_STREAM8 STM32_DMA_STREAM(7) -#endif -#if STM32_DMA2_NUM_CHANNELS > 0 -#define STM32_DMA2_STREAM1 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 0) -#endif -#if STM32_DMA2_NUM_CHANNELS > 1 -#define STM32_DMA2_STREAM2 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 1) -#endif -#if STM32_DMA2_NUM_CHANNELS > 2 -#define STM32_DMA2_STREAM3 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 2) -#endif -#if STM32_DMA2_NUM_CHANNELS > 3 -#define STM32_DMA2_STREAM4 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 3) -#endif -#if STM32_DMA2_NUM_CHANNELS > 4 -#define STM32_DMA2_STREAM5 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 4) -#endif -#if STM32_DMA2_NUM_CHANNELS > 5 -#define STM32_DMA2_STREAM6 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 5) -#endif -#if STM32_DMA2_NUM_CHANNELS > 6 -#define STM32_DMA2_STREAM7 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 6) -#endif -#if STM32_DMA2_NUM_CHANNELS > 7 -#define STM32_DMA2_STREAM8 STM32_DMA_STREAM(STM32_DMA1_NUM_CHANNELS + 7) -#endif -/** @} */ - -/** - * @name CR register constants common to all DMA types - * @{ - */ -#define STM32_DMA_CCR_RESET_VALUE 0x00000000U -#define STM32_DMA_CR_EN DMA_CCR_EN -#define STM32_DMA_CR_TEIE DMA_CCR_TEIE -#define STM32_DMA_CR_HTIE DMA_CCR_HTIE -#define STM32_DMA_CR_TCIE DMA_CCR_TCIE -#define STM32_DMA_CR_DIR_MASK (DMA_CCR_DIR | DMA_CCR_MEM2MEM) -#define STM32_DMA_CR_DIR_P2M 0U -#define STM32_DMA_CR_DIR_M2P DMA_CCR_DIR -#define STM32_DMA_CR_DIR_M2M DMA_CCR_MEM2MEM -#define STM32_DMA_CR_CIRC DMA_CCR_CIRC -#define STM32_DMA_CR_PINC DMA_CCR_PINC -#define STM32_DMA_CR_MINC DMA_CCR_MINC -#define STM32_DMA_CR_PSIZE_MASK DMA_CCR_PSIZE -#define STM32_DMA_CR_PSIZE_BYTE 0U -#define STM32_DMA_CR_PSIZE_HWORD DMA_CCR_PSIZE_0 -#define STM32_DMA_CR_PSIZE_WORD DMA_CCR_PSIZE_1 -#define STM32_DMA_CR_MSIZE_MASK DMA_CCR_MSIZE -#define STM32_DMA_CR_MSIZE_BYTE 0U -#define STM32_DMA_CR_MSIZE_HWORD DMA_CCR_MSIZE_0 -#define STM32_DMA_CR_MSIZE_WORD DMA_CCR_MSIZE_1 -#define STM32_DMA_CR_SIZE_MASK (STM32_DMA_CR_PSIZE_MASK | \ - STM32_DMA_CR_MSIZE_MASK) -#define STM32_DMA_CR_PL_MASK DMA_CCR_PL -#define STM32_DMA_CR_PL(n) ((n) << 12U) -/** @} */ - -/** - * @name Request line selector macro - * @{ - */ -#if STM32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__) -#define STM32_DMA_CR_CHSEL_MASK (15U << 16U) -#define STM32_DMA_CR_CHSEL(n) ((n) << 16U) -#else -#define STM32_DMA_CR_CHSEL_MASK 0U -#define STM32_DMA_CR_CHSEL(n) 0U -#endif -/** @} */ - -/** - * @name CR register constants only found in enhanced DMA - * @{ - */ -#define STM32_DMA_CR_DMEIE 0U /**< @brief Ignored by normal DMA. */ -/** @} */ - -/** - * @name Status flags passed to the ISR callbacks - * @{ - */ -#define STM32_DMA_ISR_FEIF 0U -#define STM32_DMA_ISR_DMEIF 0U -#define STM32_DMA_ISR_TEIF DMA_ISR_TEIF1 -#define STM32_DMA_ISR_HTIF DMA_ISR_HTIF1 -#define STM32_DMA_ISR_TCIF DMA_ISR_TCIF1 -/** @} */ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if !defined(STM32_DMA_SUPPORTS_DMAMUX) -#error "STM32_DMA_SUPPORTS_DMAMUX not defined in registry" -#endif - -#if !defined(STM32_DMA_SUPPORTS_CSELR) -#error "STM32_DMA_SUPPORTS_CSELR not defined in registry" -#endif - -#if STM32_DMA_SUPPORTS_DMAMUX && STM32_DMA_SUPPORTS_CSELR -#error "STM32_DMA_SUPPORTS_DMAMUX and STM32_DMA_SUPPORTS_CSELR both TRUE" -#endif - -#if !defined(STM32_DMA1_NUM_CHANNELS) -#error "STM32_DMA1_NUM_CHANNELS not defined in registry" -#endif - -#if !defined(STM32_DMA2_NUM_CHANNELS) -#error "STM32_DMA2_NUM_CHANNELS not defined in registry" -#endif - -#if (STM32_DMA1_NUM_CHANNELS < 0) || (STM32_DMA1_NUM_CHANNELS > 8) -#error "unsupported channels configuration" -#endif - -#if (STM32_DMA2_NUM_CHANNELS < 0) || (STM32_DMA2_NUM_CHANNELS > 8) -#error "unsupported channels configuration" -#endif - -#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__) -#include "stm32_dmamux.h" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Type of a DMA callback. - * - * @param[in] p parameter for the registered function - * @param[in] flags pre-shifted content of the ISR register, the bits - * are aligned to bit zero - */ -typedef void (*stm32_dmaisr_t)(void *p, uint32_t flags); - -/** - * @brief STM32 DMA stream descriptor structure. - */ -typedef struct { - DMA_TypeDef *dma; /**< @brief Associated DMA. */ - DMA_Channel_TypeDef *channel; /**< @brief Associated DMA channel. */ - uint32_t cmask; /**< @brief Mask of streams sharing - the same ISR. */ -#if (STM32_DMA_SUPPORTS_CSELR == TRUE) || defined(__DOXYGEN__) - volatile uint32_t *cselr; /**< @brief Associated CSELR reg. */ -#elif STM32_DMA_SUPPORTS_DMAMUX == TRUE - DMAMUX_Channel_TypeDef *mux; /**< @brief Associated DMA mux. */ -#else - uint8_t dummy; /**< @brief Filler. */ -#endif - uint8_t shift; /**< @brief Bit offset in ISR, IFCR - and CSELR registers. */ - uint8_t vector; /**< @brief Associated IRQ vector. */ -} stm32_dma_stream_t; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @name Macro Functions - * @{ - */ -/** - * @brief Associates a peripheral data register to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the CPAR register - * - * @special - */ -#define dmaStreamSetPeripheral(dmastp, addr) { \ - (dmastp)->channel->CPAR = (uint32_t)(addr); \ -} - -/** - * @brief Associates a memory destination to a DMA stream. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] addr value to be written in the CMAR register - * - * @special - */ -#define dmaStreamSetMemory0(dmastp, addr) { \ - (dmastp)->channel->CMAR = (uint32_t)(addr); \ -} - -/** - * @brief Sets the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] size value to be written in the CNDTR register - * - * @special - */ -#define dmaStreamSetTransactionSize(dmastp, size) { \ - (dmastp)->channel->CNDTR = (uint32_t)(size); \ -} - -/** - * @brief Returns the number of transfers to be performed. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @return The number of transfers to be performed. - * - * @special - */ -#define dmaStreamGetTransactionSize(dmastp) ((size_t)((dmastp)->channel->CNDTR)) - -/** - * @brief Programs the stream mode settings. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode value to be written in the CCR register - * - * @special - */ -#if STM32_DMA_SUPPORTS_CSELR || defined(__DOXYGEN__) -#define dmaStreamSetMode(dmastp, mode) { \ - uint32_t cselr = *(dmastp)->cselr; \ - cselr &= ~(0x0000000FU << (dmastp)->shift); \ - cselr |= (((uint32_t)(mode) >> 16U) << (dmastp)->shift); \ - *(dmastp)->cselr = cselr; \ - (dmastp)->channel->CCR = (uint32_t)(mode); \ -} -#else -#define dmaStreamSetMode(dmastp, mode) { \ - (dmastp)->channel->CCR = (uint32_t)(mode); \ -} -#endif - -/** - * @brief DMA stream enable. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamEnable(dmastp) { \ - (dmastp)->channel->CCR |= STM32_DMA_CR_EN; \ -} - -/** - * @brief DMA stream disable. - * @details The function disables the specified stream 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 stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamDisable(dmastp) { \ - (dmastp)->channel->CCR &= ~(STM32_DMA_CR_TCIE | STM32_DMA_CR_HTIE | \ - STM32_DMA_CR_TEIE | STM32_DMA_CR_EN); \ - dmaStreamClearInterrupt(dmastp); \ -} - -/** - * @brief DMA stream interrupt sources clear. - * @note This function can be invoked in both ISR or thread context. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * - * @special - */ -#define dmaStreamClearInterrupt(dmastp) { \ - (dmastp)->dma->IFCR = STM32_DMA_ISR_MASK << (dmastp)->shift; \ -} - -/** - * @brief Starts a memory to memory operation using the specified stream. - * @note The default transfer data mode is "byte to byte" but it can be - * changed by specifying extra options in the @p mode parameter. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - * @param[in] mode value to be written in the CCR register, this value - * is implicitly ORed with: - * - @p STM32_DMA_CR_MINC - * - @p STM32_DMA_CR_PINC - * - @p STM32_DMA_CR_DIR_M2M - * - @p STM32_DMA_CR_EN - * . - * @param[in] src source address - * @param[in] dst destination address - * @param[in] n number of data units to copy - */ -#define dmaStartMemCopy(dmastp, mode, src, dst, n) { \ - dmaStreamSetPeripheral(dmastp, src); \ - dmaStreamSetMemory0(dmastp, dst); \ - dmaStreamSetTransactionSize(dmastp, n); \ - dmaStreamSetMode(dmastp, (mode) | \ - STM32_DMA_CR_MINC | STM32_DMA_CR_PINC | \ - STM32_DMA_CR_DIR_M2M | STM32_DMA_CR_EN); \ -} - -/** - * @brief Polled wait for DMA transfer end. - * @pre The stream must have been allocated using @p dmaStreamAllocate(). - * @post After use the stream can be released using @p dmaStreamRelease(). - * - * @param[in] dmastp pointer to a stm32_dma_stream_t structure - */ -#define dmaWaitCompletion(dmastp) { \ - while ((dmastp)->channel->CNDTR > 0U) \ - ; \ - dmaStreamDisable(dmastp); \ -} -/** @} */ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if !defined(__DOXYGEN__) -extern const stm32_dma_stream_t _stm32_dma_streams[STM32_DMA_STREAMS]; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void dmaInit(void); - const stm32_dma_stream_t *dmaStreamAllocI(uint32_t id, - uint32_t priority, - stm32_dmaisr_t func, - void *param); - const stm32_dma_stream_t *dmaStreamAlloc(uint32_t id, - uint32_t priority, - stm32_dmaisr_t func, - void *param); - void dmaStreamFreeI(const stm32_dma_stream_t *dmastp); - void dmaStreamFree(const stm32_dma_stream_t *dmastp); - void dmaServeInterrupt(const stm32_dma_stream_t *dmastp); -#if STM32_DMA_SUPPORTS_DMAMUX == TRUE - void dmaSetRequestSource(const stm32_dma_stream_t *dmastp, uint32_t per); -#endif -#ifdef __cplusplus -} -#endif - -#endif /* STM32_DMA_H */ - -/** @} */ diff --git a/os/hal/ports/STM32/LLD/USARTv2/stm32_lpuart1.inc b/os/hal/ports/STM32/LLD/USARTv2/stm32_lpuart1.inc index 0efffc6d2..df25eabf2 100644 --- a/os/hal/ports/STM32/LLD/USARTv2/stm32_lpuart1.inc +++ b/os/hal/ports/STM32/LLD/USARTv2/stm32_lpuart1.inc @@ -49,13 +49,7 @@ #endif /* Other checks.*/ -#if (HAL_USE_SERIAL && STM32_SERIAL_USE_LPUART1) && \ - (HAL_USE_UART && STM32_UART_USE_LPUART1) -#error "LPUART1 used by multiple drivers" -#endif - -#if (HAL_USE_SERIAL && STM32_SERIAL_USE_LPUART1) || \ - (HAL_USE_UART && STM32_UART_USE_LPUART1) +#if (HAL_USE_SERIAL && STM32_SERIAL_USE_LPUART1) #define STM32_LPUART1_IS_USED TRUE #else #define STM32_LPUART1_IS_USED FALSE diff --git a/os/hal/ports/STM32/STM32G0xx/stm32_isr.c b/os/hal/ports/STM32/STM32G0xx/stm32_isr.c index b963242a8..05ea9b784 100644 --- a/os/hal/ports/STM32/STM32G0xx/stm32_isr.c +++ b/os/hal/ports/STM32/STM32G0xx/stm32_isr.c @@ -73,6 +73,52 @@ #include "stm32_tim16.inc" #include "stm32_tim17.inc" +#if defined(STM32_DMA_REQUIRED) || defined(__DOXYGEN__) +/** + * @brief DMA1 streams 2 and 3 shared ISR. + * @note It is declared here because this device has a non-standard + * DMA shared IRQ handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA1_CH23_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 2.*/ + dmaServeInterrupt(STM32_DMA1_STREAM2); + + /* Check on channel 3.*/ + dmaServeInterrupt(STM32_DMA1_STREAM3); + + OSAL_IRQ_EPILOGUE(); +} + +/** + * @brief DMA1 streams 4, 5, 6 and 7 shared ISR. + * + * @isr + */ +OSAL_IRQ_HANDLER(STM32_DMA1_CH4567_HANDLER) { + + OSAL_IRQ_PROLOGUE(); + + /* Check on channel 4.*/ + dmaServeInterrupt(STM32_DMA1_STREAM4); + + /* Check on channel 5.*/ + dmaServeInterrupt(STM32_DMA1_STREAM5); + + /* Check on channel 6.*/ + dmaServeInterrupt(STM32_DMA1_STREAM6); + + /* Check on channel 7.*/ + dmaServeInterrupt(STM32_DMA1_STREAM7); + + OSAL_IRQ_EPILOGUE(); +} +#endif + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ diff --git a/os/hal/ports/STM32/STM32G0xx/stm32_isr.h b/os/hal/ports/STM32/STM32G0xx/stm32_isr.h index ba33cb4df..c6a7776e1 100644 --- a/os/hal/ports/STM32/STM32G0xx/stm32_isr.h +++ b/os/hal/ports/STM32/STM32G0xx/stm32_isr.h @@ -71,15 +71,21 @@ #define STM32_DMA1_CH1_NUMBER 9 #define STM32_DMA1_CH23_NUMBER 10 +#define STM32_DMA1_CH2_NUMBER STM32_DMA1_CH23_NUMBER +#define STM32_DMA1_CH3_NUMBER STM32_DMA1_CH23_NUMBER #define STM32_DMA1_CH4567_NUMBER 11 +#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 -#define DMA1_CH0_CMASK 0x00000001U -#define DMA1_CH1_CMASK 0x00000002U -#define DMA1_CH3_CMASK 0x00000006U -#define DMA1_CH4_CMASK 0x00000078U -#define DMA1_CH5_CMASK 0x00000078U -#define DMA1_CH6_CMASK 0x00000078U -#define DMA1_CH7_CMASK 0x00000078U +#define STM32_DMA1_CH1_CMASK 0x00000001U +#define STM32_DMA1_CH2_CMASK 0x00000006U +#define STM32_DMA1_CH3_CMASK 0x00000006U +#define STM32_DMA1_CH4_CMASK 0x00000078U +#define STM32_DMA1_CH5_CMASK 0x00000078U +#define STM32_DMA1_CH6_CMASK 0x00000078U +#define STM32_DMA1_CH7_CMASK 0x00000078U /* * EXTI unit. diff --git a/os/hal/ports/STM32/STM32G4xx/hal_lld.h b/os/hal/ports/STM32/STM32G4xx/hal_lld.h index cfa5821ea..328d22549 100644 --- a/os/hal/ports/STM32/STM32G4xx/hal_lld.h +++ b/os/hal/ports/STM32/STM32G4xx/hal_lld.h @@ -1802,7 +1802,7 @@ /* Various helpers.*/ #include "nvic.h" #include "stm32_isr.h" -//#include "stm32_dma.h" +#include "stm32_dma.h" #include "stm32_exti.h" #include "stm32_rcc.h" diff --git a/os/hal/ports/STM32/STM32G4xx/platform.mk b/os/hal/ports/STM32/STM32G4xx/platform.mk index 70ebd44c0..520b5ccfa 100644 --- a/os/hal/ports/STM32/STM32G4xx/platform.mk +++ b/os/hal/ports/STM32/STM32G4xx/platform.mk @@ -27,7 +27,7 @@ endif # Drivers compatible with the platform. #include $(CHIBIOS)/os/hal/ports/STM32/LLD/ADCv1/driver.mk #include $(CHIBIOS)/os/hal/ports/STM32/LLD/DACv1/driver.mk -#include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk +include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk #include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk diff --git a/readme.txt b/readme.txt index f78b203c2..b58fdd4f6 100644 --- a/readme.txt +++ b/readme.txt @@ -74,7 +74,9 @@ ***************************************************************************** *** Next *** -- NEW: Initial STM32G4xx support in HAL. +- HAL: STM32 DMAv1 driver improvements and generalization, added support + for 8 channels. +- HAL: Initial STM32G4xx support in HAL. - HAL: Added script to generate board files from command line, just run ./os/hal/boards/genboard.sh with the board directory name as parameter. @@ -90,9 +92,9 @@ - HAL: Made bus acquire/release functions in SNOR driver public. - NEW: Added mcuconf.h generator for STM32L052/L053/L062/L063. - NEW: Added mcuconf.h generator for STM32L072/L073. -- NEW: Initial STM32G0xx support in HAL. -- NEW: Added STM32L452 support in HAL. -- NEW: Implemented TIMPRE setting for STM32F7xx HAL. +- HAL: Initial STM32G0xx support in HAL. +- HAL: Added STM32L452 support in HAL. +- HAL: Implemented TIMPRE setting for STM32F7xx HAL. - NEW: Merged FatFS 0.13c. - NEW: Added a "library generator" project for RT, it allows to generate a library with a pre-configured RT. It also includes @@ -103,9 +105,9 @@ - NEW: Code style checker tool added. - NEW: Added and embedded flash driver model in HAL. Added an implementation for STM32F1xx, STM32L4xx, STM32L4xx+. -- NEW: Modified AES GCM function signatures. +- HAL: Modified AES GCM function signatures. - HAL: Added H753 to all H7 mcuconf.h files. -- NEW: Added transactional updates to MFS. Doubled data headers magic numbers +- HAL: Added transactional updates to MFS. Doubled data headers magic numbers for improved safety and to keep the final write aligned to 64 bits, it is required for STM32 ECC flash. - VAR: Modified syscalls.c to allocate memory from bottom upward, ChibiOS