diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2010-03-30 01:39:30 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2010-03-30 01:39:30 +0000 |
commit | e7c943a501d80d81c967815466f286285443353d (patch) | |
tree | e03d746c0f223d5586242cb52e311097a1182f6b /nuttx | |
parent | 7c9a23c32a61ce6276afb2c42777e7dc3023eacc (diff) | |
download | px4-nuttx-e7c943a501d80d81c967815466f286285443353d.tar.gz px4-nuttx-e7c943a501d80d81c967815466f286285443353d.tar.bz2 px4-nuttx-e7c943a501d80d81c967815466f286285443353d.zip |
More DMA logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2567 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx')
-rwxr-xr-x | nuttx/arch/arm/src/sam3u/sam3u_dmac.c | 145 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/sam3u/sam3u_dmac.h | 4 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/sam3u/sam3u_hsmci.c | 9 | ||||
-rwxr-xr-x | nuttx/arch/arm/src/sam3u/sam3u_internal.h | 18 |
4 files changed, 152 insertions, 24 deletions
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_dmac.c b/nuttx/arch/arm/src/sam3u/sam3u_dmac.c index 7680f93db..b5ed3e887 100755 --- a/nuttx/arch/arm/src/sam3u/sam3u_dmac.c +++ b/nuttx/arch/arm/src/sam3u/sam3u_dmac.c @@ -207,71 +207,186 @@ static inline boolean sam3u_flowcontrol(uint8_t dmach_flags) } /************************************************************************************ - * Name: sam3u_settxctrla + * Name: sam3u_txctrlabits * * Description: * 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 -sam3u_settxctrla(struct sam3u_dma_s *dmach, uint32_t dmasize, uint32_t otherbits) +static inline uint32_t +sam3u_txctrlabits(struct sam3u_dma_s *dmach, uint32_t otherbits) { uint32_t regval; unsigned int ndx; - DEBUGASSERT(dmach && dmasize <= DMACHAN_CTRLA_BTSIZE_MAX); - regval = (dmasize << DMACHAN_CTRLA_BTSIZE_SHIFT) | otherbits; + DEBUGASSERT(dmach); + 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; DEBUGASSERT(ndx < 3); 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; DEBUGASSERT(ndx < 3); 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; } /************************************************************************************ + * 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 * * Description: * 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 -sam3u_setrxctrla(struct sam3u_dma_s *dmach, uint32_t dmasize, uint32_t otherbits) +static inline uint32_t +sam3u_setrxctrla(struct sam3u_dma_s *dmach, uint32_t otherbits) { uint32_t regval; unsigned int ndx; 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; DEBUGASSERT(ndx < 3); 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; DEBUGASSERT(ndx < 3); 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; } /************************************************************************************ + * 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 * * Description: diff --git a/nuttx/arch/arm/src/sam3u/sam3u_dmac.h b/nuttx/arch/arm/src/sam3u/sam3u_dmac.h index c92c45edf..736e689b0 100755 --- a/nuttx/arch/arm/src/sam3u/sam3u_dmac.h +++ b/nuttx/arch/arm/src/sam3u/sam3u_dmac.h @@ -345,7 +345,11 @@ #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_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 (0)
+# define DMACHAN_CTRLA_DCSIZE_4 DMACHAN_CTRLA_DCSIZE
#define DMACHAN_CTRLA_SRCWIDTH_SHIFT (24) /* Bits 24-25 */
#define DMACHAN_CTRLA_SRCWIDTH_MASK (3 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
# define DMACHAN_CTRLA_SRCWIDTH_BYTE (0 << DMACHAN_CTRLA_SRCWIDTH_SHIFT)
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c b/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c index 795cac954..552d554c7 100755 --- a/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c +++ b/nuttx/arch/arm/src/sam3u/sam3u_hsmci.c @@ -120,9 +120,12 @@ /* DMA configuration flags */ #define DMA_FLAGS \ - (DMACH_FLAG_FIFO_8BYTES | DMACH_FLAG_FIFOCFG_LARGEST | (DMACHAN_PID_MCI0 << DMACH_FLAG_PERIPHPID_SHIFT) | \ - DMACH_FLAG_PERIPHH2SEL | DMACH_FLAG_PERIPHLLIMODE | DMACH_FLAG_PERIPHWIDTH_32BITS | \ - DMACH_FLAG_MEMLLIMODE | DMACH_FLAG_MEMWIDTH_32BITS | DMACH_FLAG_MEMINCREMENT) + (DMACH_FLAG_FIFO_8BYTES | DMACH_FLAG_FIFOCFG_LARGEST | \ + (DMACHAN_PID_MCI0 << DMACH_FLAG_PERIPHPID_SHIFT) | \ + 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 */ diff --git a/nuttx/arch/arm/src/sam3u/sam3u_internal.h b/nuttx/arch/arm/src/sam3u/sam3u_internal.h index a6ff75ba6..91cfc7fa1 100755 --- a/nuttx/arch/arm/src/sam3u/sam3u_internal.h +++ b/nuttx/arch/arm/src/sam3u/sam3u_internal.h @@ -313,7 +313,7 @@ #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_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_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_PERIPHINCREMENT (1 << 11) /* Bit 11: Autoincrement peripheral address */ #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 */ -#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_MEMH2SEL (1 << 17) /* Bits 17: HW handshaking */ -#define DMACH_FLAG_MEMWIDTH_SHIFT (18) /* Bits 18-19: Memory width */ +#define DMACH_FLAG_MEMH2SEL (1 << 18) /* Bits 18: HW handshaking */ +#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_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) /* 32 bits */ -#define DMACH_FLAG_MEMINCREMENT (1 << 20) /* Bit 20: Autoincrement memory address */ -#define DMACH_FLAG_MEMLLIMODE (1 << 21) /* Bit 21: Use link list descriptors */ +#define DMACH_FLAG_MEMINCREMENT (1 << 21) /* Bit 21: Autoincrement memory address */ +#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 |