diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2010-03-28 16:25:48 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2010-03-28 16:25:48 +0000 |
commit | 8feefeef77e0b7a420545511d8494d45b745116e (patch) | |
tree | ab259a5b6f01a6b8a8a5e45bdd773d4b2f477816 | |
parent | b2b4e94276a9e54322925e95a61dd82820242725 (diff) | |
download | nuttx-8feefeef77e0b7a420545511d8494d45b745116e.tar.gz nuttx-8feefeef77e0b7a420545511d8494d45b745116e.tar.bz2 nuttx-8feefeef77e0b7a420545511d8494d45b745116e.zip |
A little more DMA logic
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@2559 42af7a65-404d-4744-a932-0658087f49c3
-rwxr-xr-x | nuttx/arch/arm/src/sam3u/sam3u_dmac.c | 56 |
1 files changed, 55 insertions, 1 deletions
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_dmac.c b/nuttx/arch/arm/src/sam3u/sam3u_dmac.c index 7a686ca15..e97d4d0a5 100755 --- a/nuttx/arch/arm/src/sam3u/sam3u_dmac.c +++ b/nuttx/arch/arm/src/sam3u/sam3u_dmac.c @@ -76,6 +76,7 @@ struct sam3u_dma_s void *arg; /* Argument passed to callback function */ uint16_t bufsize; /* Transfer buffer size in bytes */ volatile uint16_t remaining; /* Total number of bytes remaining to be transferred */ + int result; /* Transfer result (OK or negated errno) */ }; /**************************************************************************** @@ -364,7 +365,60 @@ static inline void sam3u_flowcontrol(struct sam3u_dma_s *dmach, uint32_t setting static int sam3u_dmainterrupt(int irq, void *context) { -# warning "Missing logic" + struct sam3u_dma_s *dmach; + unsigned int chndx; + uint32_t regval; + + /* Get the DMAC status register value */ + + regval = getreg32(SAM3U_DMAC_EBCISR); + + /* Check if the any buffer transfer has completed */ + + if (regval & DMAC_EBC_BTC_MASK) + { + /* Check each channel status */ + + for (chndx = 0; chndx < DMA_CHANNEL_NUM; chndx++) + { + /* Are interrupts enabled for this channel? */ + + if ((regval & DMAC_EBC_BTC(chndx)) != 0) + { + /* Subtract the number of bytes transferred so far */ + + dmach->remaining -= dmach->bufsize; + + /* Is the transfer finished? */ + + if (dmach->remaining == 0) + { + /* Disable Buffer Transfer Complete interrupts */ + + dmach = &g_dma[chndx]; + putreg32(DMAC_EBC_BTC(dmach->chan), SAM3U_DMAC_EBCIDR); + + /* Disable the DMA channel */ + + putreg32(DMAC_CHDR_DIS(dmach->chan), SAM3U_DMAC_CHDR); + + /* Perform the DMA complete callback */ + + if (dmach->callback) + { + dmach->callback(dmach->arg); + } + } + else + { + /* Write the KEEPON field to clear the STALL states */ + + putreg32(DMAC_CHER_KEEP(dmach->chan), SAM3U_DMAC_CHER); + } + } + } + } + return OK; } /**************************************************************************** |