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:
parent
784a983de4
commit
0c12ae82a5
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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)
|
||||||
|
@ -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 */
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user