This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

DMA SSP problem

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