SAMA5: Use RDR/TDR registers for DMA, not FIFO registers; change DMA bit settings to match Atmel example. Still no DMA
This commit is contained in:
parent
53c4a1e647
commit
2b36e7e266
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user