SAML21 DMA: More DMA logic. Still incomplete

This commit is contained in:
Gregory Nutt
2015-06-14 11:26:52 -06:00
parent c2f2919ab0
commit fb6252aa6f
3 changed files with 52 additions and 45 deletions
+1
View File
@@ -317,6 +317,7 @@ trigger */
#define DMAC_INT_TERR (1 << 0) /* Bit 0: Transfer error interrupt */
#define DMAC_INT_TCMPL (1 << 1) /* Bit 1: Channel transfer complete interrupt */
#define DMAC_INT_SUSP (1 << 2) /* Bit 2: Channel suspend interrupt */
#define DMAC_INT_ALL (0x07)
/* Channel Status Register */
+51 -37
View File
@@ -229,11 +229,22 @@ static inline void sam_givedsem(void)
static void sam_dmaterminate(struct sam_dmach_s *dmach, int result)
{
/* Disable all channel interrupts */
#warning Missing logic
irqstate_t flags;
/* Disable the channel */
#warning Missing logic
/* Disable the DMA channel */
flags = irqsave();
putreg8(dmach->dc_chan, SAM_DMAC_CHID);
putreg8(0, SAM_DMAC_CHCTRLA);
/* Reset the DMA channel */
putreg8(DMAC_CHCTRLA_SWRST, SAM_DMAC_CHCTRLA);
/* Disable all channel interrupts */
putreg8(1 << dmach->dc_chan, SAM_DMAC_CHINTENCLR);
irqrestore(flags);
/* Free the linklist */
@@ -262,43 +273,44 @@ static int sam_dmainterrupt(int irq, void *context)
{
struct sam_dmach_s *dmach;
unsigned int chndx;
uint16_t intpend;
/* Get the DMAC status register value. Ignore all masked interrupt
* status bits.
*/
#warning Missing logic
/* Check if the any transfer has completed or any errors have occurred */
#warning Missing logic
/* Process all pending channel interrupts */
while (((intpend = getreg16(SAM_DMAC_INTPEND)) & DMAC_INTPEND_PEND) != 0)
{
/* Yes.. Check each bit to see which channel has interrupted */
#warning Missing logic
/* Get the channel that generated the interrupt */
for (chndx = 0; chndx < SAMDL_NDMACHAN; chndx++)
chndx = (intpend & DMAC_INTPEND_ID_MASK) >> DMAC_INTPEND_ID_SHIFT;
dmach = &g_dmach[chndx];
/* Clear all pending channel interrupt */
putreg8(DMAC_INT_ALL, SAM_DMAC_CHINTFLAG);
/* Check for transfer error interrupt */
if ((intpend & DMAC_INTPEND_TERR) != 0)
{
dmach = &g_dmach[chndx];
/* Yes... Terminate the transfer with an error? */
/* Are any interrupts pending for this channel? */
sam_dmaterminate(dmach, -EIO);
}
/* Check for channel transfer complete interrupt */
else if ((intpend & DMAC_INTPEND_TCMPL) != 0)
{
/* Yes.. Terminate the transfer with success */
sam_dmaterminate(dmach, OK);
}
/* Check for channel suspend interrupt */
else if ((intpend & DMAC_INTPEND_SUSP) != 0)
{
#warning Missing logic
{
/* Yes.. Did an error occur? */
{
/* Yes... Terminate the transfer with an error? */
sam_dmaterminate(dmach, -EIO);
}
/* Is the transfer complete? */
{
/* Yes.. Terminate the transfer with success */
sam_dmaterminate(dmach, OK);
}
}
}
}
@@ -782,6 +794,10 @@ DMA_HANDLE sam_dmachannel(uint32_t chflags)
/* Reset the channel */
putreg8(DMAC_CHCTRLA_SWRST, SAM_DMAC_CHCTRLA);
/* Disable all channel interrupts */
putreg8(1 << chndx, SAM_DMAC_CHINTENCLR);
irqrestore(flags);
break;
}
@@ -1127,7 +1143,7 @@ void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs,
dmadbg("%s\n", msg);
dmadbg(" DMAC Registers:\n");
dmadbg(" CTRL: %04x CRCCTRL: %04x RCDATAIN: %08x CRCCHKSUM: %08x\n",
dmadbg(" CTRL: %04x CRCCTRL: %04x CRCDATAIN: %08x CRCCHKSUM: %08x\n",
regs->ctrl, regs->crcctrl, regs->crcdatain, regs->crcchksum);
dmadbg(" CRCSTATUS: %02x DBGCTRL: %02x QOSCTRL: %02x SWTRIGCTRL: %08x\n",
regs->crcstatus, regs->dbgctrl, regs->qosctrl, regs->swtrigctrl);
@@ -1135,8 +1151,6 @@ void sam_dmadump(DMA_HANDLE handle, const struct sam_dmaregs_s *regs,
regs->prictrl0, regs->intpend, regs->intstatus, regs->busych);
dmadbg(" PENDCH: %08x ACTIVE: %08x BASEADDR: %08x WRBADDR: %08x\n",
regs->pendch, regs->active, regs->baseaddr, regs->wrbaddr);
dmadbg(" BASEADDR: %08x WRBADDR: %08x CHID: %08x CHCTRLA: %08x\n",
regs->baseaddr, regs->wrbaddr, regs->chid, regs->chctrla);
dmadbg(" CHID: %02x CHCRTRLA: %02x CHCRTRLB: %08x CHINFLAG: %02x\n",
regs->chid, regs->chctrla, regs->chctrlb, regs->chintflag,
dmadbg(" CHSTATUS: %02x\n",
-8
View File
@@ -155,14 +155,6 @@ struct sam_dmaregs_s
uint32_t baseaddr; /* Descriptor Memory Section Base Address Register */
uint32_t wrbaddr; /* Write-Back Memory Section Base Address Register */
uint32_t chctrlb; /* Channel Control B Register */
/* LPSRAM Registers Relative to BASEADDR or WRBADDR */
uint16_t btctrl; /* Block Transfer Control Register */
uint16_t btcnt; /* Block Transfer Count Register */
uint32_t srcaddr; /* Block Transfer Source Address Register */
uint32_t dstaddr; /* Block Transfer Destination Address Register */
uint32_t descaddr; /* Next Address Descriptor Register */
};
#endif