I am trying DMA via SSP0 with LPC2378 ARM (development board). Transfers are initiated by calling the function below (write to SD card). While testing I decided to make 2 DMA transfers, one after the other (slave is SD card). The first one (transfer) resulted in interrupt routine- code passing through both channels- inside it - which means completely successful. The other transfer didn't result in interrupt and what is more interesting the states of all the SSP and DMA related registers before second pass start, are exactly the same as those before starting first DMA (at points noted as "***" in code below). This is excerpt from code (channel1 related to SSPRxFIFO, 0 to SSPTxFIFO):
char gg __attribute__((at(0x7FD00000+ 0x1FFC))); // end of USB FIFO void InitDMA(void){ PCONP |= (1UL << 29); GPDMA_CONFIG= 0; // enable CH0 GPDMA_INT_TCCLR= 3; GPDMA_INT_ERR_CLR= 3; GPDMA_CH0_SRC= (unsigned int)0x7FD00000; //USB RAM GPDMA_CH0_DEST= 0xE0068008; //(unsigned int)SSP0DR; GPDMA_CH0_LLI= 0; GPDMA_CH0_CTRL= 0x84000000 | 0x00000030; // source increment GPDMA_CH0_CFG= 0xC800; // disabled GPDMA_CH1_SRC= 0xE0068008; GPDMA_CH1_DEST= (unsigned int)0x7FD00000; //(unsigned int)SSP0DR; GPDMA_CH1_LLI= 0; GPDMA_CH1_CTRL= 0x88000000 | 0x00000030; // source increment GPDMA_CH1_CFG= 0xD002; // disabled VICVectAddr25 = (unsigned)DMAInt; VICIntEnable |= 0x2000000; VICVectPriority6= 10; GPDMA_CONFIG= 1; // enable } void StartDMAW(int length){ // called with length =512 GPDMA_INT_TCCLR= 3; GPDMA_INT_ERR_CLR= 3; GPDMA_CH0_SRC= (unsigned int)0x7FD00000; GPDMA_CH0_DEST= 0xE0068008; GPDMA_CH0_CTRL= 0x84000000 | length; // source increment GPDMA_CH0_CFG= 0xC800; // enable- later GPDMA_CH1_SRC= 0xE0068008; GPDMA_CH1_DEST=(unsigned int)» GPDMA_CH1_CTRL= 0x80000000 | length; // no increment GPDMA_CH1_CFG= 0xD002; // enable- later GPDMA_CH0_CFG |= 1; //fire Tx *** GPDMA_CH1_CFG |= 1; //fire Rx } void DMAInt(void) __irq{ if (GPDMA_INT_STAT & 1){ if (GPDMA_INT_TCSTAT & 1){ GPDMA_INT_TCCLR |= 1; GPDMA_CH0_CFG &= ~1; if (!dmaend){dmaend= 1;} } if (GPDMA_INT_ERR_STAT & 1){ GPDMA_INT_ERR_CLR|= 1; } } if (GPDMA_INT_STAT & 2){ if (GPDMA_INT_TCSTAT & 2){ GPDMA_INT_TCCLR |= 2; GPDMA_CH1_CFG &= ~1; if (!dmaend){dmaend= 1;} } if (GPDMA_INT_ERR_STAT & 2){ GPDMA_INT_ERR_CLR|= 2; } } }
Maybe someone can find why second transfer didn't result in interrupt.
Thanks
I think I found an error myself. What I missed was VICVectAddr = 0; at the very end of DMA interrupt routine. I am going to check it and inform if it is the reason for unexpected behaviour.
Regards