summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Nutt <gnutt@nuttx.org>2013-08-08 15:51:16 -0600
committerGregory Nutt <gnutt@nuttx.org>2013-08-08 15:51:16 -0600
commitc140d27900b95ceed867ef36102fcdeaa91a5cc8 (patch)
treede6c84a3aad7ad582d72a1bb108a1d82bd8d18d8
parent051a567290d9bc9834ade25ff2b5465aa01e5f35 (diff)
downloadnuttx-c140d27900b95ceed867ef36102fcdeaa91a5cc8.tar.gz
nuttx-c140d27900b95ceed867ef36102fcdeaa91a5cc8.tar.bz2
nuttx-c140d27900b95ceed867ef36102fcdeaa91a5cc8.zip
SAMA5: Use RDR/TDR registers for DMA, not FIFO registers; change DMA bit settings to match Atmel example. Still no DMA
-rw-r--r--nuttx/arch/arm/src/sam34/sam3u_dmac.c10
-rw-r--r--nuttx/arch/arm/src/sam34/sam_hsmci.c4
-rwxr-xr-xnuttx/arch/arm/src/sama5/chip/sam_dmac.h9
-rw-r--r--nuttx/arch/arm/src/sama5/sam_dmac.c18
-rw-r--r--nuttx/arch/arm/src/sama5/sam_hsmci.c30
5 files changed, 48 insertions, 23 deletions
diff --git a/nuttx/arch/arm/src/sam34/sam3u_dmac.c b/nuttx/arch/arm/src/sam34/sam3u_dmac.c
index ef598d01b..43d725b0d 100644
--- a/nuttx/arch/arm/src/sam34/sam3u_dmac.c
+++ b/nuttx/arch/arm/src/sam34/sam3u_dmac.c
@@ -308,7 +308,8 @@ static inline uint32_t sam_txcfg(struct sam_dma_s *dmach)
/* Set transfer (memory to peripheral) DMA channel configuration register */
- regval = (((dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT) << DMACHAN_CFG_SRCPER_SHIFT);
+ regval = DMACHAN_CFG_SOD;
+ regval |= (((dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT) << DMACHAN_CFG_SRCPER_SHIFT);
regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMACHAN_CFG_SRCH2SEL : 0;
regval |= (((dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT) << DMACHAN_CFG_DSTPER_SHIFT);
regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMACHAN_CFG_DSTH2SEL : 0;
@@ -331,7 +332,8 @@ static inline uint32_t sam_rxcfg(struct sam_dma_s *dmach)
/* Set received (peripheral to memory) DMA channel config */
- regval = (((dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT) << DMACHAN_CFG_SRCPER_SHIFT);
+ regval = DMACHAN_CFG_SOD;
+ regval |= (((dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT) << DMACHAN_CFG_SRCPER_SHIFT);
regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMACHAN_CFG_SRCH2SEL : 0;
regval |= (((dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT) << DMACHAN_CFG_DSTPER_SHIFT);
regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMACHAN_CFG_DSTH2SEL : 0;
@@ -949,6 +951,10 @@ static inline int sam_single(struct sam_dma_s *dmach)
putreg32(llhead->dest, dmach->base + SAM_DMACHAN_DADDR_OFFSET);
+ /* Clear the next descriptor address register */
+
+ putreg32(0, dmach->base + SAM_DMACHAN_DSCR_OFFSET);
+
/* Set up the CTRLA register */
putreg32(llhead->ctrla, dmach->base + SAM_DMACHAN_CTRLA_OFFSET);
diff --git a/nuttx/arch/arm/src/sam34/sam_hsmci.c b/nuttx/arch/arm/src/sam34/sam_hsmci.c
index ee252e578..e5fca7f0d 100644
--- a/nuttx/arch/arm/src/sam34/sam_hsmci.c
+++ b/nuttx/arch/arm/src/sam34/sam_hsmci.c
@@ -2217,7 +2217,7 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Configure the RX DMA */
sam_enablexfrints(priv, HSMCI_DMARECV_INTS);
- sam_dmarxsetup(priv->dma, SAM_HSMCI_FIFO, (uint32_t)buffer, buflen);
+ sam_dmarxsetup(priv->dma, SAM_HSMCI_RDR, (uint32_t)buffer, buflen);
/* Enable DMA handshaking */
@@ -2265,7 +2265,7 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev,
/* Configure the TX DMA */
- sam_dmatxsetup(priv->dma, SAM_HSMCI_FIFO, (uint32_t)buffer, buflen);
+ sam_dmatxsetup(priv->dma, SAM_HSMCI_TDR, (uint32_t)buffer, buflen);
/* Enable DMA handshaking */
diff --git a/nuttx/arch/arm/src/sama5/chip/sam_dmac.h b/nuttx/arch/arm/src/sama5/chip/sam_dmac.h
index fbcd6b651..6e4cf51a2 100755
--- a/nuttx/arch/arm/src/sama5/chip/sam_dmac.h
+++ b/nuttx/arch/arm/src/sama5/chip/sam_dmac.h
@@ -507,11 +507,12 @@
# define DMAC_EBC_DICERR4 (1 << (DMAC_EBC_DICERR_SHIFT+4))
# define DMAC_EBC_DICERR5 (1 << (DMAC_EBC_DICERR_SHIFT+5))
# define DMAC_EBC_DICERR6 (1 << (DMAC_EBC_DICERR_SHIFT+6))
-# define DMAC_EBC_DICERR7 (1 << (DMAC_EBC_DICERR_SHIFT+7))
+# define DMAC_EBC_DICERR7 (1 << (DMAC_EBC_DICERR_SHIFT+7))
-#define DMAC_EBC_BTCINTS(n) (0x01010001 << (n)) /* BTC + ERR interrupts */
-#define DMAC_EBC_CBTCINTS(n) (0x01010100 << (n)) /* CBT + ERR interrupts */
-#define DMAC_EBC_CHANINTS(n) (0x01010101 << (n)) /* All channel interrupts */
+#define DMAC_EBC_BTCINTS(n) (0x00010001 << (n)) /* BTC+ERR interrupts */
+#define DMAC_EBC_CBTCINTS(n) (0x00010100 << (n)) /* CBT+ERR interrupts */
+#define DMAC_EBC_CHANINTS(n) (0x00010101 << (n)) /* BTC+CBT+ERR interrupts */
+#define DMAC_EBC_ALLCHANINTS(n) (0x01010101 << (n)) /* All channel interrupts */
#define DMAC_EBC_ALLINTS (0xffffffff) /* All interrupts */
/* DMAC Channel Handler Enable Register */
diff --git a/nuttx/arch/arm/src/sama5/sam_dmac.c b/nuttx/arch/arm/src/sama5/sam_dmac.c
index 90b6fee6f..e595afde5 100644
--- a/nuttx/arch/arm/src/sama5/sam_dmac.c
+++ b/nuttx/arch/arm/src/sama5/sam_dmac.c
@@ -759,11 +759,13 @@ static inline uint32_t sam_txcfg(struct sam_dmach_s *dmach)
/* Set transfer (memory to peripheral) DMA channel configuration register */
+ regval = DMAC_CH_CFG_SOD;
+
pid = (dmach->flags & DMACH_FLAG_MEMPID_MASK) >> DMACH_FLAG_MEMPID_SHIFT;
isperiph = ((dmach->flags & DMACH_FLAG_MEMISPERIPH) != 0);
pchan = sam_source_channel(dmach, pid, isperiph);
- regval = ((pchan & 0x0f) << DMAC_CH_CFG_SRCPER_SHIFT);
+ regval |= ((pchan & 0x0f) << DMAC_CH_CFG_SRCPER_SHIFT);
regval |= ((pchan & 0x30) << (DMAC_CH_CFG_SRCPERMSB_SHIFT-4));
regval |= (dmach->flags & DMACH_FLAG_MEMH2SEL) != 0 ? DMAC_CH_CFG_SRCH2SEL : 0;
@@ -797,11 +799,13 @@ static inline uint32_t sam_rxcfg(struct sam_dmach_s *dmach)
/* Set received (peripheral to memory) DMA channel config */
+ regval = DMAC_CH_CFG_SOD;
+
pid = (dmach->flags & DMACH_FLAG_PERIPHPID_MASK) >> DMACH_FLAG_PERIPHPID_SHIFT;
isperiph = ((dmach->flags & DMACH_FLAG_PERIPHISPERIPH) != 0);
pchan = sam_source_channel(dmach, pid, isperiph);
- regval = ((pchan & 0x0f) << DMAC_CH_CFG_SRCPER_SHIFT);
+ regval |= ((pchan & 0x0f) << DMAC_CH_CFG_SRCPER_SHIFT);
regval |= ((pchan & 0x30) << (DMAC_CH_CFG_SRCPERMSB_SHIFT-4));
regval |= (dmach->flags & DMACH_FLAG_PERIPHH2SEL) != 0 ? DMAC_CH_CFG_SRCH2SEL : 0;
@@ -1167,7 +1171,7 @@ static inline uint32_t sam_txctrlb(struct sam_dmach_s *dmach)
* and destination descriptors. The default will be single transfer mode.
*/
- regval = DMAC_CH_CTRLB_BOTHDSCR;
+ regval = DMAC_CH_CTRLB_BOTHDSCR | DMAC_CH_CTRLB_IEN;
/* Select flow control (even if the channel doesn't support it). The
* naming convention from TX is memory to peripheral, but that is really
@@ -1258,7 +1262,7 @@ static inline uint32_t sam_rxctrlb(struct sam_dmach_s *dmach)
* and destination descriptors. The default will be single transfer mode.
*/
- regval = DMAC_CH_CTRLB_BOTHDSCR;
+ regval = DMAC_CH_CTRLB_BOTHDSCR | DMAC_CH_CTRLB_IEN;
/* Select flow control (even if the channel doesn't support it). The
* naming convention from RX is peripheral to memory, but that is really
@@ -1605,6 +1609,10 @@ static inline int sam_single(struct sam_dmach_s *dmach)
sam_putdmach(dmach, llhead->daddr, SAM_DMAC_CH_DADDR_OFFSET);
+ /* Clear the next descriptor address */
+
+ sam_putdmach(dmach, 0, SAM_DMAC_CH_DSCR_OFFSET);
+
/* Set up the CTRLA register */
sam_putdmach(dmach, llhead->ctrla, SAM_DMAC_CH_CTRLA_OFFSET);
@@ -1628,7 +1636,7 @@ static inline int sam_single(struct sam_dmach_s *dmach)
/* The DMA has been started. Once the transfer completes, hardware sets
* the interrupts and disables the channel. We will received buffer
- * complete and* transfer complete interrupts.
+ * complete and transfer complete interrupts.
*
* Enable error, buffer complete and transfer complete interrupts.
* (Since there is only a single buffer, we don't need the buffer
diff --git a/nuttx/arch/arm/src/sama5/sam_hsmci.c b/nuttx/arch/arm/src/sama5/sam_hsmci.c
index 42558048a..7d5fe09e5 100644
--- a/nuttx/arch/arm/src/sama5/sam_hsmci.c
+++ b/nuttx/arch/arm/src/sama5/sam_hsmci.c
@@ -420,7 +420,7 @@ static void sam_cmddump(struct sam_dev_s *priv);
/* DMA Helpers **************************************************************/
static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result);
-static uint32_t sam_pfifo(struct sam_dev_s *priv);
+static uint32_t sam_dmaregister(struct sam_dev_s *priv, unsigned int offset);
/* Data Transfer Helpers ****************************************************/
@@ -1074,21 +1074,21 @@ static void sam_dmacallback(DMA_HANDLE handle, void *arg, int result)
}
/****************************************************************************
- * Name: sam_pfifo
+ * Name: sam_dmaregister
*
* Description:
- * Return the physical address of a FIFO
+ * Return the physical address of an HSMCI register
*
****************************************************************************/
-static uint32_t sam_pfifo(struct sam_dev_s *priv)
+static uint32_t sam_dmaregister(struct sam_dev_s *priv, unsigned int offset)
{
/* Get the offset into the 1MB section containing the HSMCI registers */
uint32_t pbase = priv->base & 0xfff00000;
#ifdef CONFIG_HSMCI_HSMCI0
- /* Add in the physcal base for HSMCI0
+ /* Add in the physical base for HSMCI0
*
* We only have to check if this is HSMCI0 if either HSMCI1 or HSMCI2 are
* enabled.
@@ -1106,7 +1106,7 @@ static uint32_t sam_pfifo(struct sam_dev_s *priv)
#endif
#ifdef CONFIG_HSMCI_HSMCI1
- /* Add in the physcal base for HSMCI1
+ /* Add in the physical base for HSMCI1
*
* We only have to check if this is HSCMCi1 if HSMCI2 is enabled.
*/
@@ -1122,7 +1122,7 @@ static uint32_t sam_pfifo(struct sam_dev_s *priv)
#endif
#endif
- /* Add in the physcal base for HSMCI2.
+ /* Add in the physical base for HSMCI2.
*
* If we get here, we con't have to check.
*/
@@ -1133,7 +1133,7 @@ static uint32_t sam_pfifo(struct sam_dev_s *priv)
}
#endif
- return pbase + SAM_HSMCI_FIFO_OFFSET;
+ return pbase + offset;
}
/****************************************************************************
@@ -2505,10 +2505,15 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
size_t buflen)
{
struct sam_dev_s *priv = (struct sam_dev_s *)dev;
+ uint32_t rdr;
DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+ /* Physical address of the HSCMI RDR registr */
+
+ rdr = sam_dmaregister(priv, SAM_HSMCI_RDR_OFFSET);
+
/* Setup register sampling */
sam_xfrsampleinit(priv);
@@ -2517,7 +2522,7 @@ static int sam_dmarecvsetup(FAR struct sdio_dev_s *dev, FAR uint8_t *buffer,
/* Configure the RX DMA */
sam_enablexfrints(priv, HSMCI_DMARECV_INTS);
- sam_dmarxsetup(priv->dma, sam_pfifo(priv), (uint32_t)buffer, buflen);
+ sam_dmarxsetup(priv->dma, rdr, (uint32_t)buffer, buflen);
/* Enable DMA handshaking */
@@ -2554,10 +2559,15 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev,
FAR const uint8_t *buffer, size_t buflen)
{
struct sam_dev_s *priv = (struct sam_dev_s *)dev;
+ uint32_t tdr;
DEBUGASSERT(priv != NULL && buffer != NULL && buflen > 0);
DEBUGASSERT(((uint32_t)buffer & 3) == 0);
+ /* Physical address of the HSCMI TDR registr */
+
+ tdr = sam_dmaregister(priv, SAM_HSMCI_TDR_OFFSET);
+
/* Setup register sampling */
sam_xfrsampleinit(priv);
@@ -2565,7 +2575,7 @@ static int sam_dmasendsetup(FAR struct sdio_dev_s *dev,
/* Configure the TX DMA */
- sam_dmatxsetup(priv->dma, sam_pfifo(priv), (uint32_t)buffer, buflen);
+ sam_dmatxsetup(priv->dma, tdr, (uint32_t)buffer, buflen);
/* Enable DMA handshaking */