First cut at DMA code
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2142 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
1d90504a84
commit
f04860aa46
@ -39,10 +39,15 @@
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <semaphore.h>
|
||||
#include <debug.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
|
||||
#include "up_arch.h"
|
||||
#include "os_internal.h"
|
||||
#include "chip.h"
|
||||
#include "stm32_dma.h"
|
||||
#include "stm32_internal.h"
|
||||
@ -50,23 +55,262 @@
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define DMA1_NCHANNELS 7
|
||||
#if STM32_NDMA > 1
|
||||
# define DMA2_NCHANNELS 5
|
||||
# define DMA_NCHANNELS (DMA1_NCHANNELS+DMA2_NCHANNELS)
|
||||
#else
|
||||
# define DMA_NCHANNELS DMA1_NCHANNELS
|
||||
#endif
|
||||
|
||||
/* Convert the DMA channel base address to the DMA register block address */
|
||||
|
||||
#define DMA_BASE(ch) (ch & 0xfffffc00)
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
/* Pinch a byte if is possible if there are not very many DMA channels */
|
||||
|
||||
#if DMA_NCHANNELS > 8
|
||||
typedef uint16 dma_bitset_t;
|
||||
#else
|
||||
typedef uint8 dma_bitset_t;
|
||||
#endif
|
||||
|
||||
/* This structure descibes one DMA channel */
|
||||
|
||||
struct stm32_dma_s
|
||||
{
|
||||
ubyte chan; /* DMA channel number */
|
||||
ubyte irq; /* DMA channel IRQ number */
|
||||
uint32 base; /* DMA register channel base address */
|
||||
dma_callback_t callback; /* Callback invoked when the DMA completes */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* This bitset indicates which DMA channels have been allocated */
|
||||
|
||||
static dma_bitset_t g_dmaallocated;
|
||||
static sem_t g_allocsem;
|
||||
|
||||
/* This array describes the state of each DMA */
|
||||
|
||||
static struct stm32_dma_s g_dma[DMA_NCHANNELS] =
|
||||
{
|
||||
{
|
||||
.chan = 0,
|
||||
.irq = STM32_IRQ_DMA1CH1,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(0),
|
||||
},
|
||||
{
|
||||
.chan = 1,
|
||||
.irq = STM32_IRQ_DMA1CH2,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(1),
|
||||
},
|
||||
{
|
||||
.chan = 2,
|
||||
.irq = STM32_IRQ_DMA1CH3,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(2),
|
||||
},
|
||||
{
|
||||
.chan = 3,
|
||||
.irq = STM32_IRQ_DMA1CH4,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(3),
|
||||
},
|
||||
{
|
||||
.chan = 4,
|
||||
.irq = STM32_IRQ_DMA1CH5,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(4),
|
||||
},
|
||||
{
|
||||
.chan = 5,
|
||||
.irq = STM32_IRQ_DMA1CH6,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(5),
|
||||
},
|
||||
{
|
||||
.chan = 6,
|
||||
.irq = STM32_IRQ_DMA1CH7,
|
||||
.base = STM32_DMA1_BASE + STM32_DMACHAN_OFFSET(6),
|
||||
},
|
||||
#if STM32_NDMA > 1
|
||||
{
|
||||
.chan = 7,
|
||||
.irq = STM32_IRQ_DMA2CH1,
|
||||
.base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(0),
|
||||
},
|
||||
{
|
||||
.chan = 8,
|
||||
.irq = STM32_IRQ_DMA2CH2,
|
||||
.base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(1),
|
||||
},
|
||||
{
|
||||
.chan = 9,
|
||||
.irq = STM32_IRQ_DMA2CH3,
|
||||
.base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(2),
|
||||
},
|
||||
{
|
||||
.chan = 10,
|
||||
.irq = STM32_IRQ_DMA2CH4,
|
||||
.base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(3),
|
||||
},
|
||||
{
|
||||
.chan = 11,
|
||||
.irq = STM32_IRQ_DMA2CH5,
|
||||
.base = STM32_DMA2_BASE + STM32_DMACHAN_OFFSET(4),
|
||||
},
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Global Functions
|
||||
* DMA register access functions
|
||||
****************************************************************************/
|
||||
|
||||
/* Get non-channel register from DMA1 or DMA2 */
|
||||
|
||||
static inline uint32 dmabase_getreg(struct stm32_dma_s *dmach, uint32 offset)
|
||||
{
|
||||
return getreg32(DMA_BASE(dmach->base) + offset);
|
||||
}
|
||||
|
||||
/* Write to non-channel register in DMA1 or DMA2 */
|
||||
|
||||
static inline void dmabase_putreg(struct stm32_dma_s *dmach, uint32 offset, uint32 value)
|
||||
{
|
||||
putreg32(value, DMA_BASE(dmach->base) + offset);
|
||||
}
|
||||
|
||||
/* Get channel register from DMA1 or DMA2 */
|
||||
|
||||
static inline uint32 dmachan_getreg(struct stm32_dma_s *dmach, uint32 offset)
|
||||
{
|
||||
return getreg32(dmach->base + offset);
|
||||
}
|
||||
|
||||
/* Write to channel register in DMA1 or DMA2 */
|
||||
|
||||
static inline void dmachan_putreg(struct stm32_dma_s *dmach, uint32 offset, uint32 value)
|
||||
{
|
||||
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
|
||||
*
|
||||
* Description:
|
||||
* DMA interrupt handler
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static int stm32_dmainterrupt(int irq, void *context)
|
||||
{
|
||||
struct stm32_dma_s *dmach;
|
||||
uint32 isr;
|
||||
int chan;
|
||||
|
||||
/* Get the channel structure from the interrupt number */
|
||||
|
||||
if (irq >= STM32_IRQ_DMA1CH1 && irq <= STM32_IRQ_DMA1CH7)
|
||||
{
|
||||
chan = irq - STM32_IRQ_DMA1CH1;
|
||||
}
|
||||
else
|
||||
#if STM32_NDMA > 1
|
||||
if (irq >= STM32_IRQ_DMA2CH1 && irq <= STM32_IRQ_DMA2CH5)
|
||||
{
|
||||
chan = irq - STM32_IRQ_DMA2CH1 + DMA1_NCHANNELS;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
PANIC(OSERR_INTERNAL);
|
||||
}
|
||||
dmach = &g_dma[chan];
|
||||
|
||||
/* Get the interrupt status (for this channel only) */
|
||||
|
||||
isr = dmabase_getreg(dmach, STM32_DMA_ISR_OFFSET) & ~DMA_ISR_CHAN_MASK(chan);
|
||||
|
||||
/* Clear pending interrupts (for this channel only) */
|
||||
|
||||
dmabase_putreg(dmach, STM32_DMA_IFCR_OFFSET, isr);
|
||||
|
||||
/* Invoke the callback */
|
||||
|
||||
if (dmach->callback)
|
||||
{
|
||||
dmach->callback(dmach, isr >> DMA_ISR_CHAN_SHIFT(chan));
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmainitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the DMA subsystem
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
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++)
|
||||
{
|
||||
irq_attach(g_dma[chan].irq, stm32_dmainterrupt);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmachannel
|
||||
*
|
||||
@ -80,5 +324,116 @@
|
||||
|
||||
DMA_HANDLE stm32_dmachannel(void)
|
||||
{
|
||||
return NULL;
|
||||
struct stm32_dma_s *dmach = NULL;
|
||||
int chan;
|
||||
int bit;
|
||||
|
||||
/* Make sure that we exclusive access to the DMA bitset */
|
||||
|
||||
stm32_dmatake();
|
||||
|
||||
/* Try each possible channel */
|
||||
|
||||
for (chan = 0, bit = 1; chan < DMA_NCHANNELS; chan++, bit <<= 1)
|
||||
{
|
||||
/* Has this channel been allocated? */
|
||||
|
||||
if ((g_dmaallocated & bit) == 0)
|
||||
{
|
||||
/* No.. grab it and return */
|
||||
|
||||
g_dmaallocated |= bit;
|
||||
dmach = &g_dma[chan];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
stm32_dmagive();
|
||||
return (DMA_HANDLE)dmach;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmasetup
|
||||
*
|
||||
* Description:
|
||||
* Configure DMA before using
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_dmasetup(DMA_HANDLE handle, uint32 paddr, uint32 maddr, size_t ntransfers, uint32 ccr)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
uint32 regval;
|
||||
|
||||
/* Set the peripheral register address in the DMA_CPARx register. The data
|
||||
* will be moved from/to this address to/from the memory after the
|
||||
* peripheral event.
|
||||
*/
|
||||
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CPAR_OFFSET, paddr);
|
||||
|
||||
/* Set the memory address in the DMA_CMARx register. The data will be
|
||||
* written to or read from this memory after the peripheral event.
|
||||
*/
|
||||
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CMAR_OFFSET, maddr);
|
||||
|
||||
/* Configure the total number of data to be transferred in the DMA_CNDTRx
|
||||
* register. After each peripheral event, this value will be decremented.
|
||||
*/
|
||||
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CNDTR_OFFSET, ntransfers);
|
||||
|
||||
/* Configure the channel priority using the PL[1:0] bits in the DMA_CCRx
|
||||
* register. Configure data transfer direction, circular mode, peripheral & memory
|
||||
* incremented mode, peripheral & memory data size, and interrupt after
|
||||
* half and/or full transfer in the DMA_CCRx register.
|
||||
*/
|
||||
|
||||
regval = dmachan_gettreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
regval &= ~(DMA_CCR_MEM2MEM|DMA_CCR_PL_MASK|DMA_CCR_MSIZE_MASK|DMA_CCR_PSIZE_MASK|
|
||||
DMA_CCR_MINC|DMA_CCR_PINC|DMA_CCR_CIRC|DMA_CCR_DIR);
|
||||
ccr &= (DMA_CCR_MEM2MEM|DMA_CCR_PL_MASK|DMA_CCR_MSIZE_MASK|DMA_CCR_PSIZE_MASK|
|
||||
DMA_CCR_MINC|DMA_CCR_PINC|DMA_CCR_CIRC|DMA_CCR_DIR);
|
||||
regval |= ccr;
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, regval);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmastart
|
||||
*
|
||||
* Description:
|
||||
* Start the DMA transfer
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, boolean half)
|
||||
{
|
||||
struct stm32_dma_s *dmach = (struct stm32_dma_s *)handle;
|
||||
int irq;
|
||||
uint32 ccr;
|
||||
|
||||
DEBUGASSERT(handle != NULL);
|
||||
|
||||
/* Save the callback. This will be invoked whent the DMA commpletes */
|
||||
|
||||
dmach->callback = callback;
|
||||
|
||||
/* Activate the channel by setting the ENABLE bit in the DMA_CCRx register.
|
||||
* As soon as the channel is enabled, it can serve any DMA request from the
|
||||
* peripheral connected on the channel.
|
||||
*/
|
||||
|
||||
ccr = dmachan_gettreg(dmach, STM32_DMACHAN_CCR_OFFSET);
|
||||
ccr |= DMA_CCR_EN;
|
||||
|
||||
/* Once half of the bytes are transferred, the half-transfer flag (HTIF) is
|
||||
* set and an interrupt is generated if the Half-Transfer Interrupt Enable
|
||||
* bit (HTIE) is set. At the end of the transfer, the Transfer Complete Flag
|
||||
* (TCIF) is set and an interrupt is generated if the Transfer Complete
|
||||
* Interrupt Enable bit (TCIE) is set.
|
||||
*/
|
||||
|
||||
ccr |= (half ? (DMA_CCR_HTIE|DMA_CCR_TEIE) : (DMA_CCR_TCIE|DMA_CCR_TEIE));
|
||||
dmachan_putreg(dmach, STM32_DMACHAN_CCR_OFFSET, ccr);
|
||||
}
|
||||
|
@ -60,10 +60,20 @@
|
||||
|
||||
/* Register Offsets *****************************************************************/
|
||||
|
||||
#define STM32_DMA_ISR_OFFSET 0x0000 /* DMA interrupt status register */
|
||||
#define STM32_DMA_IFCR_OFFSET 0x0004 /* DMA interrupt flag clear register */
|
||||
#define STM32_DMA_ISR_OFFSET 0x0000 /* DMA interrupt status register */
|
||||
#define STM32_DMA_IFCR_OFFSET 0x0004 /* DMA interrupt flag clear register */
|
||||
|
||||
#define STM32_DMACHAN_OFFSET(n) (0x0014*(n))
|
||||
#define STM32_DMACHAN_CCR_OFFSET 0x0008
|
||||
#define STM32_DMACHAN_CNDTR_OFFSET 0x000c
|
||||
#define STM32_DMACHAN_CPAR_OFFSET 0x0010
|
||||
#define STM32_DMACHAN_CMAR_OFFSET 0x0014
|
||||
|
||||
#define STM32_DMA_CCR_OFFSET(n) (STM32_DMACHAN_CCR_OFFSET+STM32_DMACHAN_OFFSET(n))
|
||||
#define STM32_DMA_CNDTR_OFFSET(n) (STM32_DMACHAN_CNDTR_OFFSET+STM32_DMACHAN_OFFSET(n))
|
||||
#define STM32_DMA_CPAR_OFFSET(n) (STM32_DMACHAN_CPAR_OFFSET+STM32_DMACHAN_OFFSET(n))
|
||||
#define STM32_DMA_CMAR_OFFSET(n) (STM32_DMACHAN_CMAR_OFFSET+STM32_DMACHAN_OFFSET(n))
|
||||
|
||||
#define STM32_DMA_CCR_OFFSET(n) (0x0008+0x0014*(n))
|
||||
#define STM32_DMA_CCR1_OFFSET 0x0008 /* DMA channel 1 configuration register */
|
||||
#define STM32_DMA_CCR2_OFFSET 0x001c /* DMA channel 2 configuration register */
|
||||
#define STM32_DMA_CCR3_OFFSET 0x0030 /* DMA channel 3 configuration register */
|
||||
@ -72,7 +82,6 @@
|
||||
#define STM32_DMA_CCR6_OFFSET 0x006c /* DMA channel 6 configuration register */
|
||||
#define STM32_DMA_CCR7_OFFSET 0x0080 /* DMA channel 7 configuration register */
|
||||
|
||||
#define STM32_DMA_CNDTR_OFFSET(n) (0x000c+0x0014*(n))
|
||||
#define STM32_DMA_CNDTR1_OFFSET 0x000c /* DMA channel 1 number of data register */
|
||||
#define STM32_DMA_CNDTR2_OFFSET 0x0020 /* DMA channel 2 number of data register */
|
||||
#define STM32_DMA_CNDTR3_OFFSET 0x0034 /* DMA channel 3 number of data register */
|
||||
@ -81,7 +90,6 @@
|
||||
#define STM32_DMA_CNDTR6_OFFSET 0x0070 /* DMA channel 6 number of data register */
|
||||
#define STM32_DMA_CNDTR7_OFFSET 0x0084 /* DMA channel 7 number of data register */
|
||||
|
||||
#define STM32_DMA_CPAR_OFFSET(n) (0x0010+0x0014*(n))
|
||||
#define STM32_DMA_CPAR1_OFFSET 0x0010 /* DMA channel 1 peripheral address register */
|
||||
#define STM32_DMA_CPAR2_OFFSET 0x0024 /* DMA channel 2 peripheral address register */
|
||||
#define STM32_DMA_CPAR3_OFFSET 0x0038 /* DMA channel 3 peripheral address register */
|
||||
@ -90,7 +98,6 @@
|
||||
#define STM32_DMA_CPAR6_OFFSET 0x0074 /* DMA channel 6 peripheral address register */
|
||||
#define STM32_DMA_CPAR7_OFFSET 0x0088 /* DMA channel 7 peripheral address register */
|
||||
|
||||
#define STM32_DMA_CMAR_OFFSET(n) (0x0014+0x0014*(n))
|
||||
#define STM32_DMA_CMAR1_OFFSET 0x0014 /* DMA channel 1 memory address register */
|
||||
#define STM32_DMA_CMAR2_OFFSET 0x0028 /* DMA channel 2 memory address register */
|
||||
#define STM32_DMA_CMAR3_OFFSET 0x003c /* DMA channel 3 memory address register */
|
||||
@ -101,102 +108,132 @@
|
||||
|
||||
/* Register Addresses ***************************************************************/
|
||||
|
||||
#define STM32_DMA_ISRC (STM32_DMA_BASE+STM32_DMA_ISRC_OFFSET)
|
||||
#define STM32_DMA_IFCR (STM32_DMA_BASE+STM32_DMA_IFCR_OFFSET)
|
||||
#define STM32_DMA1_ISRC (STM32_DMA1_BASE+STM32_DMA_ISR_OFFSET)
|
||||
#define STM32_DMA1_IFCR (STM32_DMA1_BASE+STM32_DMA_IFCR_OFFSET)
|
||||
|
||||
#define STM32_DMA_CCR(n) (STM32_DMA_BASE+STM32_DMA_CCR_OFFSET(n))
|
||||
#define STM32_DMA_CCR1 (STM32_DMA_BASE+STM32_DMA_CCR1_OFFSET)
|
||||
#define STM32_DMA_CCR2 (STM32_DMA_BASE+STM32_DMA_CCR2_OFFSET)
|
||||
#define STM32_DMA_CCR3 (STM32_DMA_BASE+STM32_DMA_CCR3_OFFSET)
|
||||
#define STM32_DMA_CCR4 (STM32_DMA_BASE+STM32_DMA_CCR4_OFFSET)
|
||||
#define STM32_DMA_CCR5 (STM32_DMA_BASE+STM32_DMA_CCR5_OFFSET)
|
||||
#define STM32_DMA_CCR6 (STM32_DMA_BASE+STM32_DMA_CCR6_OFFSET)
|
||||
#define STM32_DMA_CCR7 (STM32_DMA_BASE+STM32_DMA_CCR7_OFFSET)
|
||||
#define STM32_DMA1_CCR(n) (STM32_DMA1_BASE+STM32_DMA_CCR_OFFSET(n))
|
||||
#define STM32_DMA1_CCR1 (STM32_DMA1_BASE+STM32_DMA_CCR1_OFFSET)
|
||||
#define STM32_DMA1_CCR2 (STM32_DMA1_BASE+STM32_DMA_CCR2_OFFSET)
|
||||
#define STM32_DMA1_CCR3 (STM32_DMA1_BASE+STM32_DMA_CCR3_OFFSET)
|
||||
#define STM32_DMA1_CCR4 (STM32_DMA1_BASE+STM32_DMA_CCR4_OFFSET)
|
||||
#define STM32_DMA1_CCR5 (STM32_DMA1_BASE+STM32_DMA_CCR5_OFFSET)
|
||||
#define STM32_DMA1_CCR6 (STM32_DMA1_BASE+STM32_DMA_CCR6_OFFSET)
|
||||
#define STM32_DMA1_CCR7 (STM32_DMA1_BASE+STM32_DMA_CCR7_OFFSET)
|
||||
|
||||
#define STM32_DMA_CNDTR(n) (STM32_DMA_BASE+STM32_DMA_CNDTR_OFFSET(n))
|
||||
#define STM32_DMA_CNDTR1 (STM32_DMA_BASE+STM32_DMA_CNDTR1_OFFSET)
|
||||
#define STM32_DMA_CNDTR2 (STM32_DMA_BASE+STM32_DMA_CNDTR2_OFFSET)
|
||||
#define STM32_DMA_CNDTR3 (STM32_DMA_BASE+STM32_DMA_CNDTR3_OFFSET)
|
||||
#define STM32_DMA_CNDTR4 (STM32_DMA_BASE+STM32_DMA_CNDTR4_OFFSET)
|
||||
#define STM32_DMA_CNDTR5 (STM32_DMA_BASE+STM32_DMA_CNDTR5_OFFSET)
|
||||
#define STM32_DMA_CNDTR6 (STM32_DMA_BASE+STM32_DMA_CNDTR6_OFFSET)
|
||||
#define STM32_DMA_CNDTR7 (STM32_DMA_BASE+STM32_DMA_CNDTR7_OFFSET)
|
||||
#define STM32_DMA1_CNDTR(n) (STM32_DMA1_BASE+STM32_DMA_CNDTR_OFFSET(n))
|
||||
#define STM32_DMA1_CNDTR1 (STM32_DMA1_BASE+STM32_DMA_CNDTR1_OFFSET)
|
||||
#define STM32_DMA1_CNDTR2 (STM32_DMA1_BASE+STM32_DMA_CNDTR2_OFFSET)
|
||||
#define STM32_DMA1_CNDTR3 (STM32_DMA1_BASE+STM32_DMA_CNDTR3_OFFSET)
|
||||
#define STM32_DMA1_CNDTR4 (STM32_DMA1_BASE+STM32_DMA_CNDTR4_OFFSET)
|
||||
#define STM32_DMA1_CNDTR5 (STM32_DMA1_BASE+STM32_DMA_CNDTR5_OFFSET)
|
||||
#define STM32_DMA1_CNDTR6 (STM32_DMA1_BASE+STM32_DMA_CNDTR6_OFFSET)
|
||||
#define STM32_DMA1_CNDTR7 (STM32_DMA1_BASE+STM32_DMA_CNDTR7_OFFSET)
|
||||
|
||||
#define STM32_DMA_CPAR(n) (STM32_DMA_BASE+STM32_DMA_CPAR_OFFSET(n))
|
||||
#define STM32_DMA_CPAR1 (STM32_DMA_BASE+STM32_DMA_CPAR1_OFFSET)
|
||||
#define STM32_DMA_CPAR2 (STM32_DMA_BASE+STM32_DMA_CPAR2_OFFSET)
|
||||
#define STM32_DMA_CPAR3 (STM32_DMA_BASE+STM32_DMA_CPAR3_OFFSET)
|
||||
#define STM32_DMA_CPAR4 (STM32_DMA_BASE+STM32_DMA_CPAR4_OFFSET)
|
||||
#define STM32_DMA_CPAR5 (STM32_DMA_BASE+STM32_DMA_CPAR5_OFFSET)
|
||||
#define STM32_DMA_CPAR6 (STM32_DMA_BASE+STM32_DMA_CPAR6_OFFSET)
|
||||
#define STM32_DMA_CPAR7 (STM32_DMA_BASE+STM32_DMA_CPAR7_OFFSET)
|
||||
#define STM32_DMA1_CPAR(n) (STM32_DMA1_BASE+STM32_DMA_CPAR_OFFSET(n))
|
||||
#define STM32_DMA1_CPAR1 (STM32_DMA1_BASE+STM32_DMA_CPAR1_OFFSET)
|
||||
#define STM32_DMA1_CPAR2 (STM32_DMA1_BASE+STM32_DMA_CPAR2_OFFSET)
|
||||
#define STM32_DMA1_CPAR3 (STM32_DMA1_BASE+STM32_DMA_CPAR3_OFFSET)
|
||||
#define STM32_DMA1_CPAR4 (STM32_DMA1_BASE+STM32_DMA_CPAR4_OFFSET)
|
||||
#define STM32_DMA1_CPAR5 (STM32_DMA1_BASE+STM32_DMA_CPAR5_OFFSET)
|
||||
#define STM32_DMA1_CPAR6 (STM32_DMA1_BASE+STM32_DMA_CPAR6_OFFSET)
|
||||
#define STM32_DMA1_CPAR7 (STM32_DMA1_BASE+STM32_DMA_CPAR7_OFFSET)
|
||||
|
||||
#define STM32_DMA_CMAR(n) (STM32_DMA_BASE+STM32_DMA_CMAR_OFFSET(n))
|
||||
#define STM32_DMA_CMAR1 (STM32_DMA_BASE+STM32_DMA_CMAR1_OFFSET)
|
||||
#define STM32_DMA_CMAR2 (STM32_DMA_BASE+STM32_DMA_CMAR2_OFFSET)
|
||||
#define STM32_DMA_CMAR3 (STM32_DMA_BASE+STM32_DMA_CMAR3_OFFSET)
|
||||
#define STM32_DMA_CMAR4 (STM32_DMA_BASE+STM32_DMA_CMAR4_OFFSET)
|
||||
#define STM32_DMA_CMAR5 (STM32_DMA_BASE+STM32_DMA_CMAR5_OFFSET)
|
||||
#define STM32_DMA_CMAR6 (STM32_DMA_BASE+STM32_DMA_CMAR6_OFFSET)
|
||||
#define STM32_DMA_CMAR7 (STM32_DMA_BASE+STM32_DMA_CMAR7_OFFSET)
|
||||
#define STM32_DMA1_CMAR(n) (STM32_DMA1_BASE+STM32_DMA_CMAR_OFFSET(n))
|
||||
#define STM32_DMA1_CMAR1 (STM32_DMA1_BASE+STM32_DMA_CMAR1_OFFSET)
|
||||
#define STM32_DMA1_CMAR2 (STM32_DMA1_BASE+STM32_DMA_CMAR2_OFFSET)
|
||||
#define STM32_DMA1_CMAR3 (STM32_DMA1_BASE+STM32_DMA_CMAR3_OFFSET)
|
||||
#define STM32_DMA1_CMAR4 (STM32_DMA1_BASE+STM32_DMA_CMAR4_OFFSET)
|
||||
#define STM32_DMA1_CMAR5 (STM32_DMA1_BASE+STM32_DMA_CMAR5_OFFSET)
|
||||
#define STM32_DMA1_CMAR6 (STM32_DMA1_BASE+STM32_DMA_CMAR6_OFFSET)
|
||||
#define STM32_DMA1_CMAR7 (STM32_DMA1_BASE+STM32_DMA_CMAR7_OFFSET)
|
||||
|
||||
#define STM32_DMA2_ISRC (STM32_DMA2_BASE+STM32_DMA_ISR_OFFSET)
|
||||
#define STM32_DMA2_IFCR (STM32_DMA2_BASE+STM32_DMA_IFCR_OFFSET)
|
||||
|
||||
#define STM32_DMA2_CCR(n) (STM32_DMA2_BASE+STM32_DMA_CCR_OFFSET(n))
|
||||
#define STM32_DMA2_CCR1 (STM32_DMA2_BASE+STM32_DMA_CCR1_OFFSET)
|
||||
#define STM32_DMA2_CCR2 (STM32_DMA2_BASE+STM32_DMA_CCR2_OFFSET)
|
||||
#define STM32_DMA2_CCR3 (STM32_DMA2_BASE+STM32_DMA_CCR3_OFFSET)
|
||||
#define STM32_DMA2_CCR4 (STM32_DMA2_BASE+STM32_DMA_CCR4_OFFSET)
|
||||
#define STM32_DMA2_CCR5 (STM32_DMA2_BASE+STM32_DMA_CCR5_OFFSET)
|
||||
|
||||
#define STM32_DMA2_CNDTR(n) (STM32_DMA2_BASE+STM32_DMA_CNDTR_OFFSET(n))
|
||||
#define STM32_DMA2_CNDTR1 (STM32_DMA2_BASE+STM32_DMA_CNDTR1_OFFSET)
|
||||
#define STM32_DMA2_CNDTR2 (STM32_DMA2_BASE+STM32_DMA_CNDTR2_OFFSET)
|
||||
#define STM32_DMA2_CNDTR3 (STM32_DMA2_BASE+STM32_DMA_CNDTR3_OFFSET)
|
||||
#define STM32_DMA2_CNDTR4 (STM32_DMA2_BASE+STM32_DMA_CNDTR4_OFFSET)
|
||||
#define STM32_DMA2_CNDTR5 (STM32_DMA2_BASE+STM32_DMA_CNDTR5_OFFSET)
|
||||
|
||||
#define STM32_DMA2_CPAR(n) (STM32_DMA2_BASE+STM32_DMA_CPAR_OFFSET(n))
|
||||
#define STM32_DMA2_CPAR1 (STM32_DMA2_BASE+STM32_DMA_CPAR1_OFFSET)
|
||||
#define STM32_DMA2_CPAR2 (STM32_DMA2_BASE+STM32_DMA_CPAR2_OFFSET)
|
||||
#define STM32_DMA2_CPAR3 (STM32_DMA2_BASE+STM32_DMA_CPAR3_OFFSET)
|
||||
#define STM32_DMA2_CPAR4 (STM32_DMA2_BASE+STM32_DMA_CPAR4_OFFSET)
|
||||
#define STM32_DMA2_CPAR5 (STM32_DMA2_BASE+STM32_DMA_CPAR5_OFFSET)
|
||||
|
||||
#define STM32_DMA2_CMAR(n) (STM32_DMA2_BASE+STM32_DMA_CMAR_OFFSET(n))
|
||||
#define STM32_DMA2_CMAR1 (STM32_DMA2_BASE+STM32_DMA_CMAR1_OFFSET)
|
||||
#define STM32_DMA2_CMAR2 (STM32_DMA2_BASE+STM32_DMA_CMAR2_OFFSET)
|
||||
#define STM32_DMA2_CMAR3 (STM32_DMA2_BASE+STM32_DMA_CMAR3_OFFSET)
|
||||
#define STM32_DMA2_CMAR4 (STM32_DMA2_BASE+STM32_DMA_CMAR4_OFFSET)
|
||||
#define STM32_DMA2_CMAR5 (STM32_DMA2_BASE+STM32_DMA_CMAR5_OFFSET)
|
||||
|
||||
/* Register Bitfield Definitions ****************************************************/
|
||||
|
||||
#define DMA_CHAN_SHIFT(n) ((n) << 2)
|
||||
#define DMA_CHAN_MASK 0x0f
|
||||
#define DMA_CHAN_GIF_BIT (1 << 0) /* Bit 0: Channel Global interrupt flag */
|
||||
#define DMA_CHAN_TCIF_BIT (1 << 1) /* Bit 1: Channel Transfer Complete flag */
|
||||
#define DMA_CHAN_HTIF_BIT (1 << 2) /* Bit 2: Channel Half Transfer flag */
|
||||
#define DMA_CHAN_TEIF_BIT (1 << 3) /* Bit 3: Channel Transfer Error flag */
|
||||
|
||||
/* DMA interrupt status register */
|
||||
|
||||
#define DMA_ISRC_CHAN_SHIFT(n) (4*(n))
|
||||
#define DMA_ISRC_CHAN_MASK(n) (0x0f << DMA_ISRC_CHAN_SHIFT(n))
|
||||
#define DMA_ISRC_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt status */
|
||||
#define DMA_ISRC_CHAN1_MASK (0x0f << DMA_ISRC_CHAN1_SHIFT)
|
||||
#define DMA_ISRC_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt status */
|
||||
#define DMA_ISRC_CHAN2_MASK (0x0f << DMA_ISRC_CHAN2_SHIFT)
|
||||
#define DMA_ISRC_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt status */
|
||||
#define DMA_ISRC_CHAN3_MASK (0x0f << DMA_ISRC_CHAN3_SHIFT)
|
||||
#define DMA_ISRC_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt status */
|
||||
#define DMA_ISRC_CHAN4_MASK (0x0f << DMA_ISRC_CHAN4_SHIFT)
|
||||
#define DMA_ISRC_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt status */
|
||||
#define DMA_ISRC_CHAN5_MASK (0x0f << DMA_ISRC_CHAN5_SHIFT)
|
||||
#define DMA_ISRC_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt status */
|
||||
#define DMA_ISRC_CHAN6_MASK (0x0f << DMA_ISRC_CHAN6_SHIFT)
|
||||
#define DMA_ISRC_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt status */
|
||||
#define DMA_ISRC_CHAN7_MASK (0x0f << DMA_ISRC_CHAN7_SHIFT)
|
||||
#define DMA_ISR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n)
|
||||
#define DMA_ISR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_ISR_CHAN_SHIFT(n))
|
||||
#define DMA_ISR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt status */
|
||||
#define DMA_ISR_CHAN1_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN1_SHIFT)
|
||||
#define DMA_ISR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt status */
|
||||
#define DMA_ISR_CHAN2_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN2_SHIFT)
|
||||
#define DMA_ISR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt status */
|
||||
#define DMA_ISR_CHAN3_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN3_SHIFT)
|
||||
#define DMA_ISR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt status */
|
||||
#define DMA_ISR_CHAN4_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN4_SHIFT)
|
||||
#define DMA_ISR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt status */
|
||||
#define DMA_ISR_CHAN5_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN5_SHIFT)
|
||||
#define DMA_ISR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt status */
|
||||
#define DMA_ISR_CHAN6_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN6_SHIFT)
|
||||
#define DMA_ISR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt status */
|
||||
#define DMA_ISR_CHAN7_MASK (DMA_CHAN_MASK << DMA_ISR_CHAN7_SHIFT)
|
||||
|
||||
#define DMA_ISRC_GIF_BIT (1 << 0) /* Bit 0: Channel Global interrupt flag */
|
||||
#define DMA_ISRC_GIF(n) (DMA_ISRC_GIF_BIT << DMA_ISRC_CHAN_SHIFT(n))
|
||||
#define DMA_ISRC_TCIF_BIT (1 << 1) /* Bit 1: Channel Transfer Complete flag */
|
||||
#define DMA_ISRC_TCIF(n) (DMA_ISRC_TCIF_BIT << DMA_ISRC_CHAN_SHIFT(n))
|
||||
#define DMA_ISRC_HTIF_BIT (1 << 2) /* Bit 2: Channel Half Transfer flag */
|
||||
#define DMA_ISRC_HTIF(n) (DMA_ISRC_HTIF_BIT << DMA_ISRC_CHAN_SHIFT(n))
|
||||
#define DMA_ISRC_TEIF_BIT (1 << 3) /* Bit 3: Channel Transfer Error flag */
|
||||
#define DMA_ISRC_TEIF(n) (DMA_ISRC_TEIF_BIT << DMA_ISRC_CHAN_SHIFT(n))
|
||||
#define DMA_ISR_GIF(n) (DMA_CHAN_GIF_BIT << DMA_ISR_CHAN_SHIFT(n))
|
||||
#define DMA_ISR_TCIF(n) (DMA_CHAN_TCIF_BIT << DMA_ISR_CHAN_SHIFT(n))
|
||||
#define DMA_ISR_HTIF(n) (DMA_CHAN_HTIF_BIT << DMA_ISR_CHAN_SHIFT(n))
|
||||
#define DMA_ISR_TEIF(n) (DMA_CHAN_TEIF_BIT << DMA_ISR_CHAN_SHIFT(n))
|
||||
|
||||
/* DMA interrupt flag clear register */
|
||||
|
||||
#define DMA_IFCR_CHAN_SHIFT(n) (4*(n))
|
||||
#define DMA_IFCR_CHAN_MASK(n) (0x0f << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CHAN_SHIFT(n) DMA_CHAN_SHIFT(n)
|
||||
#define DMA_IFCR_CHAN_MASK(n) (DMA_CHAN_MASK << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CHAN1_SHIFT (0) /* Bits 3-0: DMA Channel 1 interrupt flag clear */
|
||||
#define DMA_IFCR_CHAN1_MASK (0x0f << DMA_IFCR_CHAN1_SHIFT)
|
||||
#define DMA_IFCR_CHAN1_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN1_SHIFT)
|
||||
#define DMA_IFCR_CHAN2_SHIFT (4) /* Bits 7-4: DMA Channel 2 interrupt flag clear */
|
||||
#define DMA_IFCR_CHAN2_MASK (0x0f << DMA_IFCR_CHAN2_SHIFT)
|
||||
#define DMA_IFCR_CHAN2_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN2_SHIFT)
|
||||
#define DMA_IFCR_CHAN3_SHIFT (8) /* Bits 11-8: DMA Channel 3 interrupt flag clear */
|
||||
#define DMA_IFCR_CHAN3_MASK (0x0f << DMA_IFCR_CHAN3_SHIFT)
|
||||
#define DMA_IFCR_CHAN3_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN3_SHIFT)
|
||||
#define DMA_IFCR_CHAN4_SHIFT (12) /* Bits 15-12: DMA Channel 4 interrupt flag clear */
|
||||
#define DMA_IFCR_CHAN4_MASK (0x0f << DMA_IFCR_CHAN4_SHIFT)
|
||||
#define DMA_IFCR_CHAN4_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN4_SHIFT)
|
||||
#define DMA_IFCR_CHAN5_SHIFT (16) /* Bits 19-16: DMA Channel 5 interrupt flag clear */
|
||||
#define DMA_IFCR_CHAN5_MASK (0x0f << DMA_IFCR_CHAN5_SHIFT)
|
||||
#define DMA_IFCR_CHAN5_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN5_SHIFT)
|
||||
#define DMA_IFCR_CHAN6_SHIFT (20) /* Bits 23-20: DMA Channel 6 interrupt flag clear */
|
||||
#define DMA_IFCR_CHAN6_MASK (0x0f << DMA_IFCR_CHAN6_SHIFT)
|
||||
#define DMA_IFCR_CHAN6_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN6_SHIFT)
|
||||
#define DMA_IFCR_CHAN7_SHIFT (24) /* Bits 27-24: DMA Channel 7 interrupt flag clear */
|
||||
#define DMA_IFCR_CHAN7_MASK (0x0f << DMA_IFCR_CHAN7_SHIFT)
|
||||
#define DMA_IFCR_CHAN7_MASK (DMA_CHAN_MASK << DMA_IFCR_CHAN7_SHIFT)
|
||||
|
||||
#define DMA_IFCR_CGIF_BIT (1 << 0) /* Bit 0: Channel Global interrupt clear */
|
||||
#define DMA_IFCR_CGIF(n) (DMA_IFCR_CGIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CTCIF_BIT (1 << 1) /* Bit 1: Channel Transfer Complete clear */
|
||||
#define DMA_IFCR_CTCIF(n) (DMA_IFCR_CTCIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CHTIF_BIT (1 << 2) /* Bit 2: Channel Half Transfer clear */
|
||||
#define DMA_IFCR_CHTIF(n) (DMA_IFCR_CHTIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CTEIF_BIT (1 << 3) /* Bit 3: Channel Transfer Error clear */
|
||||
#define DMA_IFCR_CTEIF(n) (DMA_IFCR_CTEIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CGIF(n) (DMA_CHAN_GIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CTCIF(n) (DMA_CHAN_TCIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CHTIF(n) (DMA_CHAN_HTIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
|
||||
#define DMA_IFCR_CTEIF(n) (DMA_CHAN_TEIF_BIT << DMA_IFCR_CHAN_SHIFT(n))
|
||||
|
||||
/* DMA channel configuration register */
|
||||
|
||||
|
@ -380,6 +380,7 @@
|
||||
************************************************************************************/
|
||||
|
||||
typedef FAR void *DMA_HANDLE;
|
||||
typedef void (*dma_callback_t)(DMA_HANDLE handle, ubyte isr);
|
||||
|
||||
/************************************************************************************
|
||||
* Inline Functions
|
||||
@ -476,6 +477,19 @@ EXTERN int stm32_dumpgpio(uint32 pinset, const char *msg);
|
||||
# define stm32_dumpgpio(p,m)
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmainitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize the DMA subsystem
|
||||
*
|
||||
* Returned Value:
|
||||
* None
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void weak_function stm32_dmainitialize(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmachannel
|
||||
*
|
||||
@ -489,6 +503,27 @@ EXTERN int stm32_dumpgpio(uint32 pinset, const char *msg);
|
||||
|
||||
EXTERN DMA_HANDLE stm32_dmachannel(void);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmasetup
|
||||
*
|
||||
* Description:
|
||||
* Configure DMA before using
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void stm32_dmasetup(DMA_HANDLE handle, uint32 paddr, uint32 maddr,
|
||||
size_t ntransfers, uint32 ccr);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: stm32_dmastart
|
||||
*
|
||||
* Description:
|
||||
* Start the DMA transfer
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void stm32_dmastart(DMA_HANDLE handle, dma_callback_t callback, boolean half);
|
||||
|
||||
/************************************************************************************
|
||||
* Function: stm32_ethinitialize
|
||||
*
|
||||
|
@ -869,7 +869,7 @@ void stm32_spitake(FAR struct spi_dev_s *dev)
|
||||
* by a signal.
|
||||
*/
|
||||
|
||||
ASSERT(*get_errno_ptr() == EINTR);
|
||||
ASSERT(errno == EINTR);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,15 @@
|
||||
|
||||
void stm32_boardinitialize(void)
|
||||
{
|
||||
/* Initialize the DMA subsystem if the weak function stm32_dmainitialize has been
|
||||
* brought into the build
|
||||
*/
|
||||
|
||||
if (stm32_dmainitialize)
|
||||
{
|
||||
stm32_dmainitialize();
|
||||
}
|
||||
|
||||
/* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak function
|
||||
* stm32_spiinitialize() has been brought into the link.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user