From a230feaedf04c1768ec3f2791dfc32749176bb30 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Sun, 29 Jul 2018 14:45:07 +0000 Subject: DMAMUX support for DMAv1. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12211 110e8d01-0319-4d1e-a829-52ad28d1bb01 --- os/hal/ports/STM32/LLD/DMAv1/notes.txt | 1 + os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c | 110 ++++++++++++++++++++++++------- os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h | 21 ++++++ 3 files changed, 108 insertions(+), 24 deletions(-) (limited to 'os/hal/ports/STM32/LLD/DMAv1') diff --git a/os/hal/ports/STM32/LLD/DMAv1/notes.txt b/os/hal/ports/STM32/LLD/DMAv1/notes.txt index 1b684aa2c..dc4663890 100644 --- a/os/hal/ports/STM32/LLD/DMAv1/notes.txt +++ b/os/hal/ports/STM32/LLD/DMAv1/notes.txt @@ -19,6 +19,7 @@ STM32_ADVANCED_DMA - TRUE not used by the DMA drivers but other channels. Probably will be removed in the future. STM32_DMA_SUPPORTS_CSELR - TRUE if the DMA have a CSELR register. +STM32_DMA_SUPPORTS_DMAMUX - TRUE if the DMA is riven by a DMAMUX. STM32_DMAn_NUM_CHANNELS - Number of channels in DMAs "n" (1..2). STM32_DMAn_CHx_HANDLER - Vector name for IRQ "x" (1..7). If the macro is not exported then the ISR is not declared. diff --git a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c index 636969caf..03ab81d08 100644 --- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c +++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.c @@ -58,21 +58,65 @@ #if STM32_DMA_SUPPORTS_CSELR == TRUE #if defined(DMA1_CSELR) -#define ADDR_DMA1_CSELR &DMA1_CSELR->CSELR +#define DMA1_VARIANT &DMA1_CSELR->CSELR #else -#define ADDR_DMA1_CSELR &DMA1->CSELR +#define DMA1_VARIANT &DMA1->CSELR #endif #if defined(DMA2_CSELR) -#define ADDR_DMA2_CSELR &DMA2_CSELR->CSELR +#define DMA2_VARIANT &DMA2_CSELR->CSELR #else -#define ADDR_DMA2_CSELR &DMA2->CSELR -#endif - -#else /* !defined(DMA1_CSELR) */ - -#define ADDR_DMA1_CSELR NULL -#define ADDR_DMA2_CSELR NULL +#define DMA2_VARIANT &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 + +#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 + +#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 /* !defined(DMA1_CSELR) */ @@ -147,25 +191,25 @@ * 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, ADDR_DMA1_CSELR, 0, 0, STM32_DMA1_CH1_NUMBER}, - {DMA1, DMA1_Channel2, DMA1_CH2_CMASK, ADDR_DMA1_CSELR, 4, 1, STM32_DMA1_CH2_NUMBER}, - {DMA1, DMA1_Channel3, DMA1_CH3_CMASK, ADDR_DMA1_CSELR, 8, 2, STM32_DMA1_CH3_NUMBER}, - {DMA1, DMA1_Channel4, DMA1_CH4_CMASK, ADDR_DMA1_CSELR, 12, 3, STM32_DMA1_CH4_NUMBER}, - {DMA1, DMA1_Channel5, DMA1_CH5_CMASK, ADDR_DMA1_CSELR, 16, 4, STM32_DMA1_CH5_NUMBER}, + {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 > 5 - {DMA1, DMA1_Channel6, DMA1_CH6_CMASK, ADDR_DMA1_CSELR, 20, 5, STM32_DMA1_CH6_NUMBER}, + {DMA1, DMA1_Channel6, DMA1_CH6_CMASK, DMA1_CH6_VARIANT, 20, 5, STM32_DMA1_CH6_NUMBER}, #if STM32_DMA1_NUM_CHANNELS > 6 - {DMA1, DMA1_Channel7, DMA1_CH7_CMASK, ADDR_DMA1_CSELR, 24, 6, STM32_DMA1_CH7_NUMBER}, + {DMA1, DMA1_Channel7, DMA1_CH7_CMASK, DMA1_CH7_VARIANT, 24, 6, STM32_DMA1_CH7_NUMBER}, #if STM32_DMA2_NUM_CHANNELS > 0 - {DMA2, DMA2_Channel1, DMA2_CH1_CMASK, ADDR_DMA2_CSELR, 0, 7, STM32_DMA2_CH1_NUMBER}, - {DMA2, DMA2_Channel2, DMA2_CH2_CMASK, ADDR_DMA2_CSELR, 4, 8, STM32_DMA2_CH2_NUMBER}, - {DMA2, DMA2_Channel3, DMA2_CH3_CMASK, ADDR_DMA2_CSELR, 8, 9, STM32_DMA2_CH3_NUMBER}, - {DMA2, DMA2_Channel4, DMA2_CH4_CMASK, ADDR_DMA2_CSELR, 12, 10, STM32_DMA2_CH4_NUMBER}, - {DMA2, DMA2_Channel5, DMA2_CH5_CMASK, ADDR_DMA2_CSELR, 16, 11, STM32_DMA2_CH5_NUMBER}, + {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}, #if STM32_DMA2_NUM_CHANNELS > 5 - {DMA2, DMA2_Channel6, DMA2_CH6_CMASK, ADDR_DMA2_CSELR, 20, 12, STM32_DMA2_CH6_NUMBER}, + {DMA2, DMA2_Channel6, DMA2_CH6_CMASK, DMA2_CH6_VARIANT, 20, 12, STM32_DMA2_CH6_NUMBER}, #if STM32_DMA2_NUM_CHANNELS > 6 - {DMA2, DMA2_Channel7, DMA2_CH7_CMASK, ADDR_DMA2_CSELR, 24, 13, STM32_DMA2_CH7_NUMBER}, + {DMA2, DMA2_Channel7, DMA2_CH7_CMASK, DMA2_CH7_VARIANT, 24, 13, STM32_DMA2_CH7_NUMBER}, #endif #endif #endif @@ -565,6 +609,24 @@ void dmaStreamRelease(const stm32_dma_stream_t *dmastp) { #endif } +#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.h b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h index b0cd7d8f7..fdec76bfe 100644 --- a/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h +++ b/os/hal/ports/STM32/LLD/DMAv1/stm32_dma.h @@ -206,10 +206,18 @@ /* 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 @@ -218,6 +226,10 @@ #error "STM32_DMA2_NUM_CHANNELS not defined in registry" #endif +#if (STM32_DMA_SUPPORTS_DMAMUX == TRUE) || defined(__DOXYGEN__) +#include "stm32_dmamux.h" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -230,7 +242,13 @@ typedef struct { 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 selfindex; /**< @brief Index to self in array. */ @@ -471,6 +489,9 @@ extern "C" { stm32_dmaisr_t func, void *param); void dmaStreamRelease(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 -- cgit v1.2.3