Fix DMA channel mapping
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2143 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
f04860aa46
commit
0132b1ed6d
@ -40,7 +40,6 @@
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
************************************************************************************/
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user