A little more DMA logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2557 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
parent
785ce264d9
commit
7b75132de2
@ -69,7 +69,7 @@
|
||||
struct sam3u_dma_s
|
||||
{
|
||||
uint8_t chan; /* DMA channel number (0-6) */
|
||||
uint8_t fifosize; /* Size of DMA FIFO in btyes */
|
||||
uint8_t flags; /* DMA channel flags */
|
||||
bool inuse; /* TRUE: The DMA channel is in use */
|
||||
uint32_t base; /* DMA register channel base address */
|
||||
dma_callback_t callback; /* Callback invoked when the DMA completes */
|
||||
@ -100,24 +100,27 @@ static struct sam3u_dma_s g_dma[CONFIG_SAM3U_NDMACHAN] =
|
||||
|
||||
{
|
||||
.chan = 0,
|
||||
.fifosize = 8,
|
||||
.flags = DMACH_FLAG_FIFO_8BYTES;
|
||||
.base = SAM3U_DMACHAN0_BASE,
|
||||
},
|
||||
{
|
||||
.chan = 1,
|
||||
.fifosize = 8,
|
||||
.flags = DMACH_FLAG_FIFO_8BYTES;
|
||||
.base = SAM3U_DMACHAN1_BASE,
|
||||
},
|
||||
{
|
||||
.chan = 2,
|
||||
.fifosize = 8,
|
||||
.flags = DMACH_FLAG_FIFO_8BYTES;
|
||||
.base = SAM3U_DMACHAN2_BASE,
|
||||
},
|
||||
{
|
||||
.chan = 3,
|
||||
.fifosize = 32,
|
||||
.flags = (DMACH_FLAG_FIFO_32BYTES | DMACH_FLAG_FLOWCONTROL),
|
||||
.base = SAM3U_DMACHAN3_BASE,
|
||||
}
|
||||
#else
|
||||
# error "Nothing is known about the DMA channels for this device"
|
||||
#endif
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -151,6 +154,144 @@ static inline void sam3u_dmagive(void)
|
||||
(void)sem_post(&g_dmasem);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: sam3u_fifosize
|
||||
*
|
||||
* Description:
|
||||
* Decode the FIFO size from the flags
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static unsigned int sam3u_fifosize(uint8_t dmach_flags)
|
||||
{
|
||||
dmach_flags &= DMACH_FLAG_FIFOSIZE_MASK;
|
||||
if (dmach_flags == DMACH_FLAG_FIFO_8BYTES)
|
||||
{
|
||||
return 8;
|
||||
}
|
||||
else /* if (dmach_flags == DMACH_FLAG_FIFO_32BYTES) */
|
||||
{
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: sam3u_flowcontrol
|
||||
*
|
||||
* Description:
|
||||
* Decode the FIFO flow control from the flags
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static inline boolean sam3u_flowcontrol(uint8_t dmach_flags)
|
||||
{
|
||||
return ((dmach_flags & DMACH_FLAG_FLOWCONTROL) != 0);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: sam3u_settxctrla
|
||||
*
|
||||
* Description:
|
||||
* Decode the the flags to get the correct CTRLA register bit settings for a transmit
|
||||
* (memory to peripheral) transfer.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static inline void
|
||||
sam3u_settxctrla(struct sam3u_dma_s *dmach, uint32_t dmasize, uint32_t otherbits)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t flags;
|
||||
|
||||
DEBUGASSERT(dmach && dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
|
||||
regval = (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT) | otherbits;
|
||||
|
||||
/* Since this is a transmit, the source is described by the memeory selections */
|
||||
|
||||
flags = dmach->flags & DMACH_FLAG_MEMWIDTH_MASK;
|
||||
if (flags == DMACH_FLAG_MEMWIDTH_8BITS)
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_SRCWIDTH_BYTE;
|
||||
}
|
||||
else if (flags == DMACH_FLAG_MEMWIDTH_16BITS)
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_SRCWIDTH_HWORD;
|
||||
}
|
||||
else /* if (flags == DMACH_FLAG_MEMWIDTH_32BITS) */
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_SRCWIDTH_WORD;
|
||||
}
|
||||
|
||||
/* Since this is a transmit, the destination is described by the peripheral selections */
|
||||
|
||||
flags = dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK;
|
||||
if (flags == DMACH_FLAG_PERIPHWIDTH_8BITS)
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_DSTWIDTH_BYTE;
|
||||
}
|
||||
else if (flags == DMACH_FLAG_PERIPHWIDTH_16BITS)
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_DSTWIDTH_HWORD;
|
||||
}
|
||||
else /* if (flags == DMACH_FLAG_PERIPHWIDTH_32BITS) */
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_DSTWIDTH_WORD;
|
||||
}
|
||||
return regval;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: sam3u_setrxctrla
|
||||
*
|
||||
* Description:
|
||||
* Decode the the flags to get the correct CTRLA register bit settings for a read
|
||||
* (peripheral to memory) transfer.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
static inline void
|
||||
sam3u_setrxctrla(struct sam3u_dma_s *dmach, uint32_t dmasize, uint32_t otherbits)
|
||||
{
|
||||
uint32_t regval;
|
||||
uint32_t flags;
|
||||
|
||||
DEBUGASSERT(dmach && dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
|
||||
regval = (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT) | otherbits;
|
||||
|
||||
/* Since this is a receive, the source is described by the peripheral selections */
|
||||
|
||||
flags = dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK;
|
||||
if (flags == DMACH_FLAG_PERIPHWIDTH_8BITS)
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_SRCWIDTH_BYTE;
|
||||
}
|
||||
else if (flags == DMACH_FLAG_PERIPHWIDTH_16BITS)
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_SRCWIDTH_HWORD;
|
||||
}
|
||||
else /* if (flags == DMACH_FLAG_PERIPHWIDTH_32BITS) */
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_SRCWIDTH_WORD;
|
||||
}
|
||||
|
||||
/* Since this is a receive, the destination is described by the memory selections */
|
||||
|
||||
flags = dmach->flags & DMACH_FLAG_MEMWIDTH_MASK;
|
||||
if (flags == DMACH_FLAG_MEMWIDTH_8BITS)
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_DSTWIDTH_BYTE;
|
||||
}
|
||||
else if (flags == DMACH_FLAG_MEMWIDTH_16BITS)
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_DSTWIDTH_HWORD;
|
||||
}
|
||||
else /* if (flags == DMACH_FLAG_MEMWIDTH_32BITS) */
|
||||
{
|
||||
regval |= DMACHAN_CTRLA_DSTWIDTH_WORD;
|
||||
}
|
||||
return regval;
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: sam3u_dmainterrupt
|
||||
*
|
||||
@ -181,8 +322,6 @@ static int sam3u_dmainterrupt(int irq, void *context)
|
||||
|
||||
void weak_function up_dmainitialize(void)
|
||||
{
|
||||
struct sam3u_dma_s *dmach;
|
||||
|
||||
/* Enable peripheral clock */
|
||||
|
||||
putreg32((1 << SAM3U_PID_DMAC), SAM3U_PMC_PCER);
|
||||
@ -212,9 +351,9 @@ void weak_function up_dmainitialize(void)
|
||||
* Name: sam3u_dmachannel
|
||||
*
|
||||
* Description:
|
||||
* Allocate a DMA channel. This function gives the caller mutually
|
||||
* sets aside a DMA channel with the required FIFO size and gives the
|
||||
* caller exclusive access to the DMA channelt.
|
||||
* Allocate a DMA channel. This function sets aside a DMA channel with
|
||||
* the required FIFO size and flow control capabilities (determined by
|
||||
* dma_flags) then gives the caller exclusive access to the DMA channel.
|
||||
*
|
||||
* Returned Value:
|
||||
* If a DMA channel if the required FIFO size is available, this function
|
||||
@ -223,12 +362,17 @@ void weak_function up_dmainitialize(void)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
DMA_HANDLE sam3u_dmachannel(unsigned int fifosize)
|
||||
DMA_HANDLE sam3u_dmachannel(uint8_t dmach_flags)
|
||||
{
|
||||
struct sam3u_dma_s *dmach;
|
||||
unsigned int chndx;
|
||||
uint32_t regval;
|
||||
|
||||
/* Get the search parameters */
|
||||
|
||||
bool flowcontrol = sam3u_flowcontrol(dmach_flags);
|
||||
unsigned int fifosize = sam3u_fifosize(dmach_flags);
|
||||
|
||||
/* Search for an available DMA channel with at least the requested FIFO
|
||||
* size.
|
||||
*/
|
||||
@ -238,32 +382,35 @@ DMA_HANDLE sam3u_dmachannel(unsigned int fifosize)
|
||||
for (chndx = 0; chndx < CONFIG_SAM3U_NDMACHAN; chndx++)
|
||||
{
|
||||
struct sam3u_dma_s *candidate = &g_dma[chndx];
|
||||
if (!candidate->inuse && candidate->fifosize >= fifosize)
|
||||
if (!candidate->inuse &&
|
||||
(sam3u_fifosize(candidate->flags) >= fifosize) &&
|
||||
(!flowcontrol || sam3u_flowcontrol(dmach_flags)))
|
||||
{
|
||||
dmach = candidate;
|
||||
dmach->inuse = true;
|
||||
dmach = candidate;
|
||||
dmach->inuse = true;
|
||||
|
||||
/* Read the status register to clear any pending interrupts on the channel */
|
||||
|
||||
(void)getreg32(SAM3U_DMAC_EBCISR);
|
||||
|
||||
/* Disable the channel by writing one to the write-only channel disable register */
|
||||
|
||||
putreg32(DMAC_CHDR_DIS(chndx), SAM3U_DMAC_CHDR);
|
||||
|
||||
/* See the DMA channel flags, retaining the fifo size and flow control
|
||||
* settings which are inherent properties of the FIFO and cannot be changed.
|
||||
*/
|
||||
|
||||
dmach->flags &= (DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK);
|
||||
dmach->flags |= (dma_flags & ~((DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK)));
|
||||
|
||||
/* Initialize the transfer state */
|
||||
|
||||
dmach->xfrsize = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
sam3u_dmagive();
|
||||
|
||||
/* Did we get one? */
|
||||
|
||||
if (dmach)
|
||||
{
|
||||
/* Read the status register to clear any pending interrupts on the channel */
|
||||
|
||||
(void)getreg32(SAM3U_DMAC_EBCISR);
|
||||
|
||||
/* Disable the channel by writing one to the write-only channel disable register */
|
||||
|
||||
putreg32(DMAC_CHDR_DIS(chndx), SAM3U_DMAC_CHDR);
|
||||
|
||||
/* Initilize the transfer size */
|
||||
|
||||
dmach->xfrsize = 0;
|
||||
}
|
||||
|
||||
return (DMA_HANDLE)dmach;
|
||||
}
|
||||
|
||||
@ -284,12 +431,13 @@ void sam3u_dmafree(DMA_HANDLE handle)
|
||||
{
|
||||
struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
|
||||
|
||||
/* Mark the channel no longer in use. This is an atomic operation and so
|
||||
* should be safe.
|
||||
/* Mark the channel no longer in use. Clearing the inuse flag is an atomic
|
||||
* operation and so should be safe.
|
||||
*/
|
||||
|
||||
DEBUGASSERT(dmach != NULL);
|
||||
dmach->inuse = true;
|
||||
DEBUGASSERT((dmach != NULL) && (dmach->inuse));
|
||||
dmach->flags &= (DMACH_FLAG_FLOWCONTROL | DMACH_FLAG_FIFOSIZE_MASK);
|
||||
dmach->inuse = false; /* No longer in use */
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -300,7 +448,7 @@ void sam3u_dmafree(DMA_HANDLE handle)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t ntransfers, uint32_t ccr)
|
||||
void sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
|
||||
{
|
||||
struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
|
||||
uint32_t regval;
|
||||
@ -315,7 +463,7 @@ void sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
void sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t ntransfers, uint32_t ccr)
|
||||
void sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr, size_t nbytes)
|
||||
{
|
||||
struct sam3u_dma_s *dmach = (struct sam3u_dma_s *)handle;
|
||||
uint32_t regval;
|
||||
|
@ -341,8 +341,9 @@
|
||||
/* DMA channel registers */
|
||||
/* DMAC Channel n [n = 0..3] Control A Register */
|
||||
|
||||
#define DMACHAN_CTRLA_BTSIZE_MAX (0xfff)
|
||||
#define DMACHAN_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-11: Buffer Transfer Size */
|
||||
#define DMACHAN_CTRLA_BTSIZE_MASK (0xfff << DMACHAN_CTRLA_BTSIZE_SHIFT)
|
||||
#define DMACHAN_CTRLA_BTSIZE_MASK (DMACHAN_CTRLA_BTSIZE_MAX << DMACHAN_CTRLA_BTSIZE_SHIFT)
|
||||
#define DMACHAN_CTRLA_SCSIZE (1 << 16) /* Bit 16: Source Chunk Transfer Size */
|
||||
#define DMACHAN_CTRLA_DCSIZE (1 << 20) /* Bit 20: Destination Chunk Transfer size */
|
||||
#define DMACHAN_CTRLA_SRCWIDTH_SHIFT (24) /* Bits 24-25 */
|
||||
@ -351,11 +352,11 @@
|
||||
# define DMACHAN_CTRLA_SRCWIDTH_HWORD (1 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
|
||||
# define DMACHAN_CTRLA_SRCWIDTH_WORD (2 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
|
||||
#define DMACHAN_CTRLA_DSTWIDTH_SHIFT (28) /* Bits 28-29 */
|
||||
#define DMACHAN_CTRLA_DSTWIDTH__MASK (3 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
|
||||
#define DMACHAN_CTRLA_DSTWIDTH_MASK (3 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
|
||||
# define DMACHAN_CTRLA_DSTWIDTH_BYTE (0 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
|
||||
# define DMACHAN_CTRLA_DSTWIDTH_HWORD (1 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
|
||||
# define DMACHAN_CTRLA_DSTWIDTH_WORD (2 << DMACHAN_CTRLA_DSTWIDTH_SHIFT)
|
||||
#define DMACHAN_CTRLA_DONE (1 << 31)
|
||||
#define DMACHAN_CTRLA_DONE (1 << 31) /* Bit 31: Auto disable DMAC */
|
||||
|
||||
/* DMAC Channel n [n = 0..3] Control B Register */
|
||||
|
||||
@ -404,6 +405,17 @@
|
||||
* Public Types
|
||||
****************************************************************************************/
|
||||
|
||||
/* DMA multi buffer transfer link list entry structure */
|
||||
|
||||
struct dma_linklist_s
|
||||
{
|
||||
uint32_t src; /* Source address */
|
||||
uint32_t dest; /* Destination address */
|
||||
uint32_t ctrla; /* Control A value */
|
||||
uint32_t ctrlb; /* Congtrol B value */
|
||||
uint32_t desc; /* Descriptor address */
|
||||
};
|
||||
|
||||
/****************************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************************/
|
||||
|
@ -117,12 +117,10 @@
|
||||
|
||||
#define HSMCI_DTIMER_DATATIMEOUT (0x000fffff)
|
||||
|
||||
/* DMA CCR register settings */
|
||||
/* DMA configuration flags */
|
||||
|
||||
#define HSMCI_RXDMA32_CONFIG \
|
||||
( CONFIG_HSMCI_DMAPRIO | DMA_CCR_MSIZE_32BITS | DMA_CCR_PSIZE_32BITS | DMA_CCR_MINC)
|
||||
#define HSMCI_TXDMA32_CONFIG \
|
||||
( CONFIG_HSMCI_DMAPRIO | DMA_CCR_MSIZE_32BITS | DMA_CCR_PSIZE_32BITS | DMA_CCR_MINC | DMA_CCR_DIR)
|
||||
#define DMA_FLAGS \
|
||||
(DMACH_FLAG_FIFO_8BYTES|DMACH_FLAG_SRCWIDTH_32BITS|DMACH_FLAG_DESTWIDTH_32BITS|DMACH_FLAG_MEMINCREMENT)
|
||||
|
||||
/* FIFO sizes */
|
||||
|
||||
@ -2346,8 +2344,7 @@ static int sam3u_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
|
||||
sam3u_enablexfrints(priv, HSMCI_DMARECV_INTS);
|
||||
|
||||
putreg32(1, HSMCI_DCTRL_DMAEN_BB);
|
||||
sam3u_dmarxsetup(priv->dma, SAM3U_HSMCI_FIFO, (uint32_t)buffer,
|
||||
(buflen + 3) >> 2, HSMCI_RXDMA32_CONFIG);
|
||||
sam3u_dmarxsetup(priv->dma, SAM3U_HSMCI_FIFO, (uint32_t)buffer, buflen);
|
||||
|
||||
/* Start the DMA */
|
||||
|
||||
@ -2412,8 +2409,7 @@ static int sam3u_dmasendsetup(FAR struct sdio_dev_s *dev,
|
||||
|
||||
/* Configure the TX DMA */
|
||||
|
||||
sam3u_dmatxsetup(priv->dma, SAM3U_HSMCI_FIFO, (uint32_t)buffer,
|
||||
(buflen + 3) >> 2, HSMCI_TXDMA32_CONFIG);
|
||||
sam3u_dmatxsetup(priv->dma, SAM3U_HSMCI_FIFO, (uint32_t)buffer, buflen);
|
||||
|
||||
sam3u_sample(priv, SAMPLENDX_BEFORE_ENABLE);
|
||||
putreg32(1, HSMCI_DCTRL_DMAEN_BB);
|
||||
@ -2545,7 +2541,7 @@ FAR struct sdio_dev_s *sdio_initialize(int slotno)
|
||||
|
||||
/* Allocate a DMA channel. A FIFO size of 8 is sufficient. */
|
||||
|
||||
priv->dma = sam3u_dmachannel(8);
|
||||
priv->dma = sam3u_dmachannel(DMA_FLAGS);
|
||||
DEBUGASSERT(priv->dma);
|
||||
|
||||
/* Configure GPIOs for 4-bit, wide-bus operation. NOTE: (1) the chip is capable of
|
||||
|
@ -290,6 +290,31 @@
|
||||
|
||||
#define GPIO_USB_VBUS (GPIO_INPUT|GPIO_CFG_DEFAULT|GPIO_PORT_PIOA|GPIO_PIN0)
|
||||
|
||||
/* DMA ******************************************************************************/
|
||||
|
||||
/* Flags used to characterize the desired DMA channel. The naming convention is that
|
||||
* one side is the peripheral and the other is memory (however, the interface could still
|
||||
* be used if, for example, both sides were memory although the naming would be awkward)
|
||||
*/
|
||||
|
||||
#define DMACH_FLAG_FLOWCONTROL (1 << 0) /* Bit 0: Channel supports flow control */
|
||||
#define DMACH_FLAG_FIFOSIZE_SHIFT (1) /* Bit 1: Size of DMA FIFO */
|
||||
#define DMACH_FLAG_FIFOSIZE_MASK (1 << DMACH_FLAG_FIFOSIZE_SHIFT)
|
||||
# define DMACH_FLAG_FIFO_8BYTES (0 << DMACH_FLAG_FIFOSIZE_SHIFT) /* 8 bytes */
|
||||
# define DMACH_FLAG_FIFO_32BYTES (1 << DMACH_FLAG_FIFOSIZE_SHIFT) /* 32 bytes */
|
||||
#define DMACH_FLAG_PERIPHWIDTH_SHIFT (2) /* Bits 2-3: Peripheral width */
|
||||
#define DMACH_FLAG_PERIPHWIDTH_MASK (3 << DMACH_FLAG_PERIPHWIDTH_SHIFT)
|
||||
# define DMACH_FLAG_PERIPHWIDTH_8BITS (0 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 8 bits */
|
||||
# define DMACH_FLAG_PERIPHWIDTH_16BITS (1 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 16 bits */
|
||||
# define DMACH_FLAG_PERIPHWIDTH_32BITS (2 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 16 bits */
|
||||
#define DMACH_FLAG_PERIPHINCREMENT (1 << 4) /* Bit 4: Autoincrement peripheral address */
|
||||
#define DMACH_FLAG_MEMWIDTH_SHIFT (5) /* Bits 5-6: Memory width */
|
||||
#define DMACH_FLAG_MEMWIDTH_MASK (3 << DMACH_FLAG_MEMWIDTH_SHIFT)
|
||||
# define DMACH_FLAG_MEMWIDTH_8BITS (0 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 8 bits */
|
||||
# define DMACH_FLAG_MEMWIDTH_16BITS (1 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */
|
||||
# define DMACH_FLAG_MEMWIDTH_32BITS (2 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */
|
||||
#define DMACH_FLAG_MEMINCREMENT (1 << 7) /* Bit 7: Autoincrement memory address */
|
||||
|
||||
/************************************************************************************
|
||||
* Public Types
|
||||
************************************************************************************/
|
||||
@ -297,6 +322,8 @@
|
||||
typedef FAR void *DMA_HANDLE;
|
||||
typedef void (*dma_callback_t)(DMA_HANDLE handle, uint8_t isr, void *arg);
|
||||
|
||||
/* The following is used for sampling DMA registers when CONFIG DEBUG_DMA is selected */
|
||||
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
struct sam3u_dmaregs_s
|
||||
{
|
||||
@ -461,9 +488,9 @@ EXTERN void sam3u_gpioirqdisable(int irq);
|
||||
* Name: sam3u_dmachannel
|
||||
*
|
||||
* Description:
|
||||
* Allocate a DMA channel. This function gives the caller mutually
|
||||
* sets aside a DMA channel with the required FIFO size and gives the
|
||||
* caller exclusive access to the DMA channelt.
|
||||
* Allocate a DMA channel. This function sets aside a DMA channel with
|
||||
* the required FIFO size and flow control capabilities (determined by
|
||||
* dma_flags) then gives the caller exclusive access to the DMA channel.
|
||||
*
|
||||
* Returned Value:
|
||||
* If a DMA channel if the required FIFO size is available, this function
|
||||
@ -472,7 +499,7 @@ EXTERN void sam3u_gpioirqdisable(int irq);
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN DMA_HANDLE sam3u_dmachannel(unsigned int fifosize);
|
||||
EXTERN DMA_HANDLE sam3u_dmachannel(uint8_t dmach_flags);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam3u_dmafree
|
||||
@ -495,14 +522,10 @@ EXTERN void sam3u_dmafree(DMA_HANDLE handle);
|
||||
* Description:
|
||||
* Configure DMA for transmit (memory to periphal) before using
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by sam3u_dmachannel()
|
||||
* - No DMA in progress
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void sam3u_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
|
||||
size_t ntransfers, uint32_t ccr);
|
||||
size_t nbytes);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam3u_dmarxsetup
|
||||
@ -510,14 +533,10 @@ EXTERN void sam3u_dmatxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
|
||||
* Description:
|
||||
* Configure DMA for receive (peripheral to memory) before using
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by sam3u_dmachannel()
|
||||
* - No DMA in progress
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
|
||||
size_t ntransfers, uint32_t ccr);
|
||||
size_t nbytes);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: sam3u_dmastart
|
||||
@ -525,10 +544,6 @@ EXTERN void sam3u_dmarxsetup(DMA_HANDLE handle, uint32_t paddr, uint32_t maddr,
|
||||
* Description:
|
||||
* Start the DMA transfer
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by sam3u_dmachannel()
|
||||
* - No DMA in progress
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void sam3u_dmastart(DMA_HANDLE handle, dma_callback_t callback,
|
||||
@ -542,9 +557,6 @@ EXTERN void sam3u_dmastart(DMA_HANDLE handle, dma_callback_t callback,
|
||||
* reset and sam3u_dmasetup() must be called before sam3u_dmastart() can be
|
||||
* called again
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by sam3u_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
EXTERN void sam3u_dmastop(DMA_HANDLE handle);
|
||||
@ -555,9 +567,6 @@ EXTERN void sam3u_dmastop(DMA_HANDLE handle);
|
||||
* Description:
|
||||
* Sample DMA register contents
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by sam3u_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
@ -572,9 +581,6 @@ EXTERN void sam3u_dmasample(DMA_HANDLE handle, struct sam3u_dmaregs_s *regs);
|
||||
* Description:
|
||||
* Dump previously sampled DMA register contents
|
||||
*
|
||||
* Assumptions:
|
||||
* - DMA handle allocated by sam3u_dmachannel()
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_DEBUG_DMA
|
||||
|
Loading…
Reference in New Issue
Block a user