More DMA logic

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2567 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2010-03-30 01:39:30 +00:00
parent 784a983de4
commit 0c12ae82a5
4 changed files with 152 additions and 24 deletions

View File

@ -207,70 +207,185 @@ static inline boolean sam3u_flowcontrol(uint8_t dmach_flags)
} }
/************************************************************************************ /************************************************************************************
* Name: sam3u_settxctrla * Name: sam3u_txctrlabits
* *
* Description: * Description:
* Decode the the flags to get the correct CTRLA register bit settings for a transmit * Decode the the flags to get the correct CTRLA register bit settings for a transmit
* (memory to peripheral) transfer. * (memory to peripheral) transfer. These are only the "fixed" CTRLA values and
* need to be updated with the actual transfer size before being written to CTRLA
* sam3u_txctrla).
* *
************************************************************************************/ ************************************************************************************/
static inline void static inline uint32_t
sam3u_settxctrla(struct sam3u_dma_s *dmach, uint32_t dmasize, uint32_t otherbits) sam3u_txctrlabits(struct sam3u_dma_s *dmach, uint32_t otherbits)
{ {
uint32_t regval; uint32_t regval;
unsigned int ndx; unsigned int ndx;
DEBUGASSERT(dmach && dmasize <= DMACHAN_CTRLA_BTSIZE_MAX); DEBUGASSERT(dmach);
regval = (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT) | otherbits; regval = otherbits;
/* Since this is a transmit, the source is described by the memeory selections */ /* Since this is a transmit, the source is described by the memory selections.
* Set the source width (memory width).
*/
ndx = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) >> DMACH_FLAG_MEMWIDTH_SHIFT; ndx = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) >> DMACH_FLAG_MEMWIDTH_SHIFT;
DEBUGASSERT(ndx < 3); DEBUGASSERT(ndx < 3);
regval |= g_srcwidth[ndx]; regval |= g_srcwidth[ndx];
return regval;
/* Since this is a transmit, the destination is described by the peripheral selections */ /* Set the source chuck size (memory chunk size) */
if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
{
regval |= DMACHAN_CTRLA_SCSIZE_4;
}
#if 0 /* DMACHAN_CTRLA_SCSIZE_1 is zero */
else
{
regval |= DMACHAN_CTRLA_SCSIZE_1;
}
#endif
/* Since this is a transmit, the destination is described by the peripheral selections.
* Set the destination width (peripheral width).
*/
ndx = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> DMACH_FLAG_PERIPHWIDTH_SHIFT; ndx = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> DMACH_FLAG_PERIPHWIDTH_SHIFT;
DEBUGASSERT(ndx < 3); DEBUGASSERT(ndx < 3);
regval |= g_destwidth[ndx]; regval |= g_destwidth[ndx];
/* Set the destination chuck size (peripheral chunk size) */
if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4)
{
regval |= DMACHAN_CTRLA_DCSIZE_4;
}
#if 0 /* DMACHAN_CTRLA_DCSIZE_1 is zero */
else
{
regval |= DMACHAN_CTRLA_DCSIZE_1;
}
#endif
return regval; return regval;
} }
/************************************************************************************
* Name: sam3u_txctrla
*
* Description:
* Or in the variable CTRLA bits
*
************************************************************************************/
static inline uint32_t sam3u_txctrla(uint32_t dmasize, uint32_t txctrlabits)
{
/* Set the buffer transfer size field. This is the number of transfers to be
* performed, that is, the number of source width transfers to perform.
*/
/* Adjust the the source transfer size for the source chunk size (memory chunk size) */
if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
{
dmasize >>= 2;
}
DEBUGASSERT(dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
return (txctrlabits & ~DMACHAN_CTRLA_BTSIZE_MASK) | (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT);
}
/************************************************************************************ /************************************************************************************
* Name: sam3u_setrxctrla * Name: sam3u_setrxctrla
* *
* Description: * Description:
* Decode the the flags to get the correct CTRLA register bit settings for a read * Decode the the flags to get the correct CTRLA register bit settings for a read
* (peripheral to memory) transfer. * (peripheral to memory) transfer. These are only the "fixed" CTRLA values and
* need to be updated with the actual transfer size before being written to CTRLA
* sam3u_rxctrla).
* *
************************************************************************************/ ************************************************************************************/
static inline void static inline uint32_t
sam3u_setrxctrla(struct sam3u_dma_s *dmach, uint32_t dmasize, uint32_t otherbits) sam3u_setrxctrla(struct sam3u_dma_s *dmach, uint32_t otherbits)
{ {
uint32_t regval; uint32_t regval;
unsigned int ndx; unsigned int ndx;
DEBUGASSERT(dmach && dmasize <= DMACHAN_CTRLA_BTSIZE_MAX); DEBUGASSERT(dmach && dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
regval = (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT) | otherbits; regval = otherbits;
/* Since this is a receive, the source is described by the peripheral selections */ /* Since this is a receive, the source is described by the peripheral selections.
* Set the source width (peripheral width).
*/
ndx = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> DMACH_FLAG_PERIPHWIDTH_SHIFT; ndx = (dmach->flags & DMACH_FLAG_PERIPHWIDTH_MASK) >> DMACH_FLAG_PERIPHWIDTH_SHIFT;
DEBUGASSERT(ndx < 3); DEBUGASSERT(ndx < 3);
regval |= g_srcwidth[ndx]; regval |= g_srcwidth[ndx];
/* Since this is a receive, the destination is described by the memory selections */ /* Set the source chuck size (peripheral chunk size) */
if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4)
{
regval |= DMACHAN_CTRLA_SCSIZE_4;
}
#if 0 /* DMACHAN_CTRLA_SCSIZE_1 is zero */
else
{
regval |= DMACHAN_CTRLA_SCSIZE_1;
}
#endif
/* Since this is a receive, the destination is described by the memory selections.
* Set the destination width (memory width).
*/
ndx = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) >> DMACH_FLAG_MEMWIDTH_SHIFT; ndx = (dmach->flags & DMACH_FLAG_MEMWIDTH_MASK) >> DMACH_FLAG_MEMWIDTH_SHIFT;
DEBUGASSERT(ndx < 3); DEBUGASSERT(ndx < 3);
regval |= g_destwidth[ndx]; regval |= g_destwidth[ndx];
/* Set the destination chuck size (memory chunk size) */
if ((dmach->flags & DMACH_FLAG_MEMCHUNKSIZE) == DMACH_FLAG_MEMCHUNKSIZE_4)
{
regval |= DMACHAN_CTRLA_DCSIZE_4;
}
#if 0 /* DMACHAN_CTRLA_DCSIZE_1 is zero */
else
{
regval |= DMACHAN_CTRLA_DCSIZE_1;
}
#endif
return regval; return regval;
} }
/************************************************************************************
* Name: sam3u_rxctrla
*
* Description:
* Or in the variable CTRLA bits
*
************************************************************************************/
static inline uint32_t sam3u_rxctrla(uint32_t dmasize, uint32_t txctrlabits)
{
/* Set the buffer transfer size field. This is the number of transfers to be
* performed, that is, the number of source width transfers to perform.
*/
/* Adjust the the source transfer size for the source chunk size (peripheral chunk size) */
if ((dmach->flags & DMACH_FLAG_PERIPHCHUNKSIZE) == DMACH_FLAG_PERIPHCHUNKSIZE_4)
{
dmasize >>= 2;
}
DEBUGASSERT(dmasize <= DMACHAN_CTRLA_BTSIZE_MAX);
return (txctrlabits & ~DMACHAN_CTRLA_BTSIZE_MASK) | (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT);
}
/************************************************************************************ /************************************************************************************
* Name: sam3u_srcctrlb * Name: sam3u_srcctrlb
* *

View File

@ -345,7 +345,11 @@
#define DMACHAN_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-11: Buffer Transfer Size */ #define DMACHAN_CTRLA_BTSIZE_SHIFT (0) /* Bits 0-11: Buffer Transfer Size */
#define DMACHAN_CTRLA_BTSIZE_MASK (DMACHAN_CTRLA_BTSIZE_MAX << 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_SCSIZE (1 << 16) /* Bit 16: Source Chunk Transfer Size */
# define DMACHAN_CTRLA_SCSIZE_1 (0)
# define DMACHAN_CTRLA_SCSIZE_4 DMACHAN_CTRLA_SCSIZE
#define DMACHAN_CTRLA_DCSIZE (1 << 20) /* Bit 20: Destination Chunk Transfer size */ #define DMACHAN_CTRLA_DCSIZE (1 << 20) /* Bit 20: Destination Chunk Transfer size */
# define DMACHAN_CTRLA_DCSIZE_1 (0)
# define DMACHAN_CTRLA_DCSIZE_4 DMACHAN_CTRLA_DCSIZE
#define DMACHAN_CTRLA_SRCWIDTH_SHIFT (24) /* Bits 24-25 */ #define DMACHAN_CTRLA_SRCWIDTH_SHIFT (24) /* Bits 24-25 */
#define DMACHAN_CTRLA_SRCWIDTH_MASK (3 << DMACHAN_CTRLA_SRCWIDTH_SHIFT) #define DMACHAN_CTRLA_SRCWIDTH_MASK (3 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
# define DMACHAN_CTRLA_SRCWIDTH_BYTE (0 << DMACHAN_CTRLA_SRCWIDTH_SHIFT) # define DMACHAN_CTRLA_SRCWIDTH_BYTE (0 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)

View File

@ -120,9 +120,12 @@
/* DMA configuration flags */ /* DMA configuration flags */
#define DMA_FLAGS \ #define DMA_FLAGS \
(DMACH_FLAG_FIFO_8BYTES | DMACH_FLAG_FIFOCFG_LARGEST | (DMACHAN_PID_MCI0 << DMACH_FLAG_PERIPHPID_SHIFT) | \ (DMACH_FLAG_FIFO_8BYTES | DMACH_FLAG_FIFOCFG_LARGEST | \
DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHLLIMODE | DMACH_FLAG_PERIPHWIDTH_32BITS | \ (DMACHAN_PID_MCI0 << DMACH_FLAG_PERIPHPID_SHIFT) | \
DMACH_FLAG_MEMLLIMODE | DMACH_FLAG_MEMWIDTH_32BITS | DMACH_FLAG_MEMINCREMENT) DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHLLIMODE | \
DMACH_FLAG_PERIPHWIDTH_32BITS | DMACH_FLAG_PERIPHCHUNKSIZE_1 | \
DMACH_FLAG_MEMLLIMODE | DMACH_FLAG_MEMWIDTH_32BITS | \
DMACH_FLAG_MEMINCREMENT | DMACH_FLAG_MEMCHUNKSIZE_4)
/* FIFO sizes */ /* FIFO sizes */

View File

@ -313,7 +313,7 @@
#define DMACH_FLAG_FIFOCFG_SHIFT (2) /* Bits 2-3: FIFO configuration */ #define DMACH_FLAG_FIFOCFG_SHIFT (2) /* Bits 2-3: FIFO configuration */
#define DMACH_FLAG_FIFOCFG_MASK (3 << DMACH_FLAG_FIFOCFG_SHIFT) #define DMACH_FLAG_FIFOCFG_MASK (3 << DMACH_FLAG_FIFOCFG_SHIFT)
# define DMACH_FLAG_FIFOCFG_LARGEST (DMACH_FLAG_BURST_LARGEST << DMACH_FLAG_FIFOCFG_SHIFT # define DMACH_FLAG_FIFOCFG_LARGEST (DMACH_FLAG_BURST_LARGEST << DMACH_FLAG_FIFOCFG_SHIFT)
# define DMACH_FLAG_FIFOCFG_HALF (DMACH_FLAG_BURST_HALF << DMACH_FLAG_FIFOCFG_SHIFT) # define DMACH_FLAG_FIFOCFG_HALF (DMACH_FLAG_BURST_HALF << DMACH_FLAG_FIFOCFG_SHIFT)
# define DMACH_FLAG_FIFOCFG_SINGLE (DMACH_FLAG_BURST_SINGLE << DMACH_FLAG_FIFOCFG_SHIFT) # define DMACH_FLAG_FIFOCFG_SINGLE (DMACH_FLAG_BURST_SINGLE << DMACH_FLAG_FIFOCFG_SHIFT)
@ -329,19 +329,25 @@
# define DMACH_FLAG_PERIPHWIDTH_32BITS (2 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 32 bits */ # define DMACH_FLAG_PERIPHWIDTH_32BITS (2 << DMACH_FLAG_PERIPHWIDTH_SHIFT) /* 32 bits */
#define DMACH_FLAG_PERIPHINCREMENT (1 << 11) /* Bit 11: Autoincrement peripheral address */ #define DMACH_FLAG_PERIPHINCREMENT (1 << 11) /* Bit 11: Autoincrement peripheral address */
#define DMACH_FLAG_PERIPHLLIMODE (1 << 12) /* Bit 12: Use link list descriptors */ #define DMACH_FLAG_PERIPHLLIMODE (1 << 12) /* Bit 12: Use link list descriptors */
#define DMACH_FLAG_PERIPHCHUNKSIZE (1 << 13) /* Bit 13: Peripheral chunk size */
# define DMACH_FLAG_PERIPHCHUNKSIZE_1 (0) /* Peripheral chunksize = 1 */
# define DMACH_FLAG_PERIPHCHUNKSIZE_4 DMACH_FLAG_PERIPHCHUNKSIZE /* Peripheral chunksize = 4 */
/* Memory endpoint characteristics */ /* Memory endpoint characteristics */
#define DMACH_FLAG_MEMPID_SHIFT (13) /* Bits 13-16: Memory PID */ #define DMACH_FLAG_MEMPID_SHIFT (14) /* Bits 14-17: Memory PID */
#define DMACH_FLAG_MEMPID_MASK (15 << DMACH_FLAG_PERIPHPID_SHIFT) #define DMACH_FLAG_MEMPID_MASK (15 << DMACH_FLAG_PERIPHPID_SHIFT)
#define DMACH_FLAG_MEMH2SEL (1 << 17) /* Bits 17: HW handshaking */ #define DMACH_FLAG_MEMH2SEL (1 << 18) /* Bits 18: HW handshaking */
#define DMACH_FLAG_MEMWIDTH_SHIFT (18) /* Bits 18-19: Memory width */ #define DMACH_FLAG_MEMWIDTH_SHIFT (19) /* Bits 19-20: Memory width */
#define DMACH_FLAG_MEMWIDTH_MASK (3 << DMACH_FLAG_MEMWIDTH_SHIFT) #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_8BITS (0 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 8 bits */
# define DMACH_FLAG_MEMWIDTH_16BITS (1 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */ # define DMACH_FLAG_MEMWIDTH_16BITS (1 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 16 bits */
# define DMACH_FLAG_MEMWIDTH_32BITS (2 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 32 bits */ # define DMACH_FLAG_MEMWIDTH_32BITS (2 << DMACH_FLAG_MEMWIDTH_SHIFT) /* 32 bits */
#define DMACH_FLAG_MEMINCREMENT (1 << 20) /* Bit 20: Autoincrement memory address */ #define DMACH_FLAG_MEMINCREMENT (1 << 21) /* Bit 21: Autoincrement memory address */
#define DMACH_FLAG_MEMLLIMODE (1 << 21) /* Bit 21: Use link list descriptors */ #define DMACH_FLAG_MEMLLIMODE (1 << 22) /* Bit 22: Use link list descriptors */
#define DMACH_FLAG_MEMCHUNKSIZE (1 << 23) /* Bit 23: Memory chunk size */
# define DMACH_FLAG_MEMCHUNKSIZE_1 (0) /* Memory chunksize = 1 */
# define DMACH_FLAG_MEMCHUNKSIZE_4 DMACH_FLAG_MEMCHUNKSIZE /* Memory chunksize = 4 */
/************************************************************************************ /************************************************************************************
* Public Types * Public Types