summaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/src/sam3u
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-03-28 16:25:48 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2010-03-28 16:25:48 +0000
commit8feefeef77e0b7a420545511d8494d45b745116e (patch)
treeab259a5b6f01a6b8a8a5e45bdd773d4b2f477816 /nuttx/arch/arm/src/sam3u
parentb2b4e94276a9e54322925e95a61dd82820242725 (diff)
downloadpx4-nuttx-8feefeef77e0b7a420545511d8494d45b745116e.tar.gz
px4-nuttx-8feefeef77e0b7a420545511d8494d45b745116e.tar.bz2
px4-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
Diffstat (limited to 'nuttx/arch/arm/src/sam3u')
-rwxr-xr-xnuttx/arch/arm/src/sam3u/sam3u_dmac.c56
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;
}
/****************************************************************************