summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/sam3u/sam3u_dmac.c
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-03-30 01:39:30 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-03-30 01:39:30 +0000
commite7c943a501d80d81c967815466f286285443353d (patch)
treee03d746c0f223d5586242cb52e311097a1182f6b /nuttx/arch/arm/src/sam3u/sam3u_dmac.c
parent7c9a23c32a61ce6276afb2c42777e7dc3023eacc (diff)
downloadpx4-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/arch/arm/src/sam3u/sam3u_dmac.c')
-rwxr-xr-xnuttx/arch/arm/src/sam3u/sam3u_dmac.c145
1 files changed, 130 insertions, 15 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: