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:
patacongo 2009-10-16 18:17:13 +00:00
parent f04860aa46
commit 0132b1ed6d
3 changed files with 115 additions and 62 deletions

View File

@ -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;
}

View File

@ -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
************************************************************************************/

View File

@ -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