diff --git a/arch/arm/src/stm32/stm32_dma.c b/arch/arm/src/stm32/stm32_dma.c index 9824be7e83..f456d458e3 100755 --- a/arch/arm/src/stm32/stm32_dma.c +++ b/arch/arm/src/stm32/stm32_dma.c @@ -40,7 +40,6 @@ #include #include -#include #include #include @@ -104,63 +103,63 @@ static sem_t g_allocsem; static struct stm32_dma_s g_dma[DMA_NCHANNELS] = { { - .chan = 0, + .chan = STM32_DMA1_CHAN1, .irq = STM32_IRQ_DMA1CH1, .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(0), }, { - .chan = 1, + .chan = STM32_DMA1_CHAN2, .irq = STM32_IRQ_DMA1CH2, .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(1), }, { - .chan = 2, + .chan = STM32_DMA1_CHAN3, .irq = STM32_IRQ_DMA1CH3, .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(2), }, { - .chan = 3, + .chan = STM32_DMA1_CHAN4, .irq = STM32_IRQ_DMA1CH4, .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(3), }, { - .chan = 4, + .chan = STM32_DMA1_CHAN5, .irq = STM32_IRQ_DMA1CH5, .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(4), }, { - .chan = 5, + .chan = STM32_DMA1_CHAN6, .irq = STM32_IRQ_DMA1CH6, .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(5), }, { - .chan = 6, + .chan = STM32_DMA1_CHAN7, .irq = STM32_IRQ_DMA1CH7, .base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(6), }, #if STM32_NDMA > 1 { - .chan = 7, + .chan = STM32_DMA2_CHAN1, .irq = STM32_IRQ_DMA2CH1, .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(0), }, { - .chan = 8, + .chan = STM32_DMA2_CHAN2, .irq = STM32_IRQ_DMA2CH2, .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(1), }, { - .chan = 9, + .chan = STM32_DMA2_CHAN3, .irq = STM32_IRQ_DMA2CH3, .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(2), }, { - .chan = 10, + .chan = STM32_DMA2_CHAN4, .irq = STM32_IRQ_DMA2CH4, .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(3), }, { - .chan = 11, + .chan = STM32_DMA2_CHAN5, .irq = STM32_IRQ_DMA2CH5, .base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(4), }, @@ -203,33 +202,6 @@ static inline void dmachan_putreg(struct stm32_dma_s *dmach, uint32 offset, uint putreg32(value, dmach->base + offset); } -/************************************************************************************ - * Name: stm32_dmatake() and stm32_dmagive() - * - * Description: - * Take/give semaphore that protects the channel allocation bitset - * - ************************************************************************************/ - -static void stm32_dmatake(void) -{ - /* Take the semaphore (perhaps waiting) */ - - while (sem_wait(&g_allocsem) != 0) - { - /* The only case that an error should occur here is if the wait was awakened - * by a signal. - */ - - ASSERT(errno == EINTR); - } -} - -static inline void stm32_dmagive(void) -{ - (void)sem_post(&g_allocsem); -} - /************************************************************************************ * Name: stm32_dmainterrupt * @@ -299,10 +271,6 @@ void weak_function stm32_dmainitialize(void) { int chan; - /* Initialize the semaphore used to protect the allocation bitset */ - - sem_init(&g_allocsem, 0, 1); - /* Attach DMA interrupt vectors */ for (chan = 0; chan < DMA_NCHANNELS; chan++) @@ -322,33 +290,34 @@ void weak_function stm32_dmainitialize(void) * ****************************************************************************/ -DMA_HANDLE stm32_dmachannel(void) +DMA_HANDLE stm32_dmachannel(int chan) { struct stm32_dma_s *dmach = NULL; - int chan; - int bit; + irqstate_t flags; + dma_bitset_t before; + int bit = (1 << chan); - /* Make sure that we exclusive access to the DMA bitset */ + DEBUGASSERT(chan < DMA_NCHANNELS); - stm32_dmatake(); + /* This is essentially a test and set. We simply disable interrupts to + * create the critical section. This is brutal (but very quich) and assures + * that we have exclusive access to the allocation bitset + */ - /* Try each possible channel */ + flags = irqsave(); + before = g_dmaallocated; + g_dmaallocated |= bit; + irq_restore(flags); - for (chan = 0, bit = 1; chan < DMA_NCHANNELS; chan++, bit <<= 1) + /* Was this channel been available? */ + + if ((before & bit) == 0) { - /* Has this channel been allocated? */ + /* Yes.. then the caller has it, return it */ - if ((g_dmaallocated & bit) == 0) - { - /* No.. grab it and return */ - - g_dmaallocated |= bit; - dmach = &g_dma[chan]; - break; - } + dmach = &g_dma[chan]; } - stm32_dmagive(); return (DMA_HANDLE)dmach; } diff --git a/arch/arm/src/stm32/stm32_dma.h b/arch/arm/src/stm32/stm32_dma.h index 8c44674aa4..f5409d7f6d 100644 --- a/arch/arm/src/stm32/stm32_dma.h +++ b/arch/arm/src/stm32/stm32_dma.h @@ -268,6 +268,90 @@ #define DMA_CNDTR_NDT_SHIFT (0) /* Bits 15-0: Number of data to Transfer */ #define DMA_CNDTR_NDT_MASK (0xffff << DMA_CNDTR_NDT_SHIFT) +/* DMA Channel mapping. Each DMA channel has a mapping to several possible + * sources/sinks of data. The requests from peripherals assigned to a channel + * are simply OR'ed together before entering the DMA block. This means that only + * one request on a given channel can be enabled at once. + */ + +#define STM32_DMA1_CHAN1 (0) +#define STM32_DMA1_CHAN2 (1) +#define STM32_DMA1_CHAN3 (2) +#define STM32_DMA1_CHAN4 (3) +#define STM32_DMA1_CHAN5 (4) +#define STM32_DMA1_CHAN6 (5) +#define STM32_DMA1_CHAN7 (6) + +#define STM32_DMA2_CHAN1 (7) +#define STM32_DMA2_CHAN2 (8) +#define STM32_DMA2_CHAN3 (1) +#define STM32_DMA2_CHAN4 (10) +#define STM32_DMA2_CHAN5 (11) + +#define DMACHAN_ADC1 STM32_DMA1_CHAN1 +#define DMACHAN_TIM2_CH3 STM32_DMA1_CHAN1 +#define DMACHAN_TIM4_CH1 STM32_DMA1_CHAN1 +#define DMACHAN_SPI1_RX STM32_DMA1_CHAN2 +#define DMACHAN_USART3_TX STM32_DMA1_CHAN2 +#define DMACHAN_TIM1_CH1 STM32_DMA1_CHAN2 +#define DMACHAN_TIM2_UP STM32_DMA1_CHAN2 +#define DMACHAN_TIM3_CH3 STM32_DMA1_CHAN2 +#define DMACHAN_SPI1_TX STM32_DMA1_CHAN3 +#define DMACHAN_USART3_RX STM32_DMA1_CHAN3 +#define DMACHAN_TIM1_CH2 STM32_DMA1_CHAN3 +#define DMACHAN_TIM3_CH4 STM32_DMA1_CHAN3 +#define DMACHAN_TIM3_UP STM32_DMA1_CHAN3 +#define DMACHAN_SPI2_RX STM32_DMA1_CHAN4 +#define DMACHAN_I2S2_RX STM32_DMA1_CHAN4 +#define DMACHAN_USART1_TX STM32_DMA1_CHAN4 +#define DMACHAN_I2C2_TX STM32_DMA1_CHAN4 +#define DMACHAN_TIM1_CH4 STM32_DMA1_CHAN4 +#define DMACHAN_TIM1_TRIG STM32_DMA1_CHAN4 +#define DMACHAN_TIM1_COM STM32_DMA1_CHAN4 +#define DMACHAN_TIM4_CH2 STM32_DMA1_CHAN4 +#define DMACHAN_SPI2_TX STM32_DMA1_CHAN5 +#define DMACHAN_I2S2_TX STM32_DMA1_CHAN5 +#define DMACHAN_USART1_RX STM32_DMA1_CHAN5 +#define DMACHAN_I2C2_RX STM32_DMA1_CHAN5 +#define DMACHAN_TIM1_UP STM32_DMA1_CHAN5 +#define DMACHAN_TIM2_CH1 STM32_DMA1_CHAN5 +#define DMACHAN_TIM4_CH3 STM32_DMA1_CHAN5 +#define DMACHAN_USART2_RX STM32_DMA1_CHAN6 +#define DMACHAN_I2C1_TX STM32_DMA1_CHAN6 +#define DMACHAN_TIM1_CH3 STM32_DMA1_CHAN6 +#define DMACHAN_TIM3_CH1 STM32_DMA1_CHAN6 +#define DMACHAN_TIM3_TRIG STM32_DMA1_CHAN6 +#define DMACHAN_USART2_TX STM32_DMA1_CHAN7 +#define DMACHAN_I2C1_RX STM32_DMA1_CHAN7 +#define DMACHAN_TIM2_CH2 STM32_DMA1_CHAN7 +#define DMACHAN_TIM2_CH4 STM32_DMA1_CHAN7 +#define DMACHAN_TIM4_UP STM32_DMA1_CHAN7 +#define DMACHAN_SPI3_RX STM32_DMA2_CHAN1 +#define DMACHAN_I2S3_RX STM32_DMA2_CHAN1 +#define DMACHAN_TIM5_CH4 STM32_DMA2_CHAN1 +#define DMACHAN_TIM5_TRIG STM32_DMA2_CHAN1 +#define DMACHAN_TIM8_CH3 STM32_DMA2_CHAN1 +#define DMACHAN_TIM8_UP STM32_DMA2_CHAN1 +#define DMACHAN_SPI3_TX STM32_DMA2_CHAN2 +#define DMACHAN_I2S3_TX STM32_DMA2_CHAN2 +#define DMACHAN_TIM5_CH3 STM32_DMA2_CHAN2 +#define DMACHAN_TIM5_UP STM32_DMA2_CHAN2 +#define DMACHAN_TIM5_UP STM32_DMA2_CHAN2 +#define DMACHAN_TIM8_TRIG STM32_DMA2_CHAN2 +#define DMACHAN_TIM8_COM STM32_DMA2_CHAN2 +#define DMACHAN_UART4_RX STM32_DMA2_CHAN3 +#define DMACHAN_TIM6_UP STM32_DMA2_CHAN3 +#define DMACHAN_DAC_CHAN1 STM32_DMA2_CHAN3 +#define DMACHAN_TIM8_CH1 STM32_DMA2_CHAN3 +#define DMACHAN_SDIO STM32_DMA2_CHAN4 +#define DMACHAN_TIM5_CH2 STM32_DMA2_CHAN4 +#define DMACHAN_TIM7_UP STM32_DMA2_CHAN4 +#define DMACHAN_DAC_CHAN2 STM32_DMA2_CHAN4 +#define DMACHAN_ADC3 STM32_DMA2_CHAN5 +#define DMACHAN_UART4_TX STM32_DMA2_CHAN5 +#define DMACHAN_TIM5_CH1 STM32_DMA2_CHAN5 +#define DMACHAN_TIM8_CH2 STM32_DMA2_CHAN5 + /************************************************************************************ * Public Types ************************************************************************************/ diff --git a/arch/arm/src/stm32/stm32_internal.h b/arch/arm/src/stm32/stm32_internal.h index ee0c639bf8..61169e7b52 100755 --- a/arch/arm/src/stm32/stm32_internal.h +++ b/arch/arm/src/stm32/stm32_internal.h @@ -501,7 +501,7 @@ EXTERN void weak_function stm32_dmainitialize(void); * ****************************************************************************/ -EXTERN DMA_HANDLE stm32_dmachannel(void); +EXTERN DMA_HANDLE stm32_dmachannel(int chan); /**************************************************************************** * Name: stm32_dmasetup