This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

OMAP-L138 : when EDMA is set to service the SPI module it write 0 in the next 3 bytes after the last byte of the destination memory range

Hello,

I'm trying to read data from a SPI Flash memory and write it in the DDR memory attached to the OMAP.

And I've seen via the Memory Browser (of Code Composer Studio) that after the legitimate data, I always have 3 bytes at 0 (instead of the pattern I wrote before setting the SPI and EDMA).

I've also seen via an oscilloscope that the correct number of Bytes have been transferred.

Here is the EDMA setup function :

UINT32 EDMAB_setPaRamForEvent(UINT32 eventNumber, void * srcAddr, void * dstAddr, UINT32 sizeOfArray,
        UINT32 numberOfArrays, INT16 offsetBetweenArraysSrcAddr, INT16 offsetBetweenArraysDstAddr)
{
    UINT32 res = EDMAB_RETURN_VALUE_NO_ERROR;
    if (eventNumber < EDMAB_MAX_EVENT_NUMBER)
    {
        switch (eventNumber)
        {
            case CSL_EDMA3CC_DRAE_E19_SHIFT:
                //Enable Access to channel 19 for DMA Region 0
                CSL_FINST(edma3ccRegs->DRA[0].DRAE, EDMA3CC_DRAE_E19, ENABLE);
                //Set the event 19 in the Event Enable Register
                CSL_FINST(edma3ccRegs->EESR, EDMA3CC_EESR_E19, SET);
                //Set the channel 19 in the Interrupt Enable Register
                CSL_FINST(edma3ccRegs->IESR, EDMA3CC_IESR_I19, SET);
                break;
            case CSL_EDMA3CC_DRAE_E18_SHIFT:
                //Enable Access to channel 18 for DMA Region 0
                CSL_FINST(edma3ccRegs->DRA[0].DRAE, EDMA3CC_DRAE_E18, ENABLE);
                //Set the event 18 in the Event Enable Register
                CSL_FINST(edma3ccRegs->EESR, EDMA3CC_EESR_E18, SET);
                //Set the channel 18 in the Interrupt Enable Register
                CSL_FINST(edma3ccRegs->IESR, EDMA3CC_IESR_I18, SET);
                break;
        }

        //Set the Source and destination addresses
        edma3ccRegs->PARAMSET[eventNumber].SRC = (UINT32) srcAddr;
        edma3ccRegs->PARAMSET[eventNumber].DST = (UINT32) dstAddr;

        UINT32 tmpABcnt = edma3ccRegs->PARAMSET[eventNumber].A_B_CNT;
        //Set the size of each transfert triggered by an event
        CSL_FINS(tmpABcnt, EDMA3CC_A_B_CNT_ACNT, sizeOfArray);
        //Set the number of transfert to perform before trigerring a Transfert Complete Code
        CSL_FINS(tmpABcnt, EDMA3CC_A_B_CNT_BCNT, numberOfArrays);
        edma3ccRegs->PARAMSET[eventNumber].A_B_CNT = tmpABcnt;

        UINT32 tmpSrcDstBIDX = edma3ccRegs->PARAMSET[eventNumber].SRC_DST_BIDX;
        //Set the increment on the source and destination addresses between each array
        CSL_FINS(tmpSrcDstBIDX, EDMA3CC_SRC_DST_BIDX_SRCBIDX, offsetBetweenArraysSrcAddr);
        CSL_FINS(tmpSrcDstBIDX, EDMA3CC_SRC_DST_BIDX_DSTBIDX, offsetBetweenArraysDstAddr);
        edma3ccRegs->PARAMSET[eventNumber].SRC_DST_BIDX = tmpSrcDstBIDX;

        UINT32 tmpLinkBCNTRLD = edma3ccRegs->PARAMSET[eventNumber].LINK_BCNTRLD;
        //Set the BCNT Reload register to 0 (only BCNT words of size ACNT to be transfered)
        CSL_FINS(tmpLinkBCNTRLD, EDMA3CC_LINK_BCNTRLD_BCNTRLD, 0);
        //Set Link register to 0xFFFF since no link is desired
        CSL_FINS(tmpLinkBCNTRLD, EDMA3CC_LINK_BCNTRLD_LINK, 0xFFFF);
        edma3ccRegs->PARAMSET[eventNumber].LINK_BCNTRLD = tmpLinkBCNTRLD;

        UINT32 tmpSrcDstCIDX = edma3ccRegs->PARAMSET[eventNumber].SRC_DST_CIDX;
        //Set the increment to 0 on the source and destination addresses between each group of BCNT arrays
        //(only BCNT words of size ACNT to be transfered)
        CSL_FINS(tmpSrcDstCIDX, EDMA3CC_SRC_DST_CIDX_SRCCIDX, 0);
        CSL_FINS(tmpSrcDstCIDX, EDMA3CC_SRC_DST_CIDX_DSTCIDX, 0);
        edma3ccRegs->PARAMSET[eventNumber].SRC_DST_CIDX = tmpSrcDstCIDX;

        //Set the CCNT register to 1 (only BCNT words of size ACNT to be transfered)
        CSL_FINS(edma3ccRegs->PARAMSET[eventNumber].CCNT, EDMA3CC_CCNT_CCNT, 1);

        UINT32 tmpOPT = edma3ccRegs->PARAMSET[eventNumber].OPT;
        //Set source and destination addresses mode to increment
        CSL_FINST(tmpOPT, EDMA3CC_OPT_SAM, INCR);
        CSL_FINST(tmpOPT, EDMA3CC_OPT_DAM, INCR);
        //Set the SYNCDIM to A Synchronized transfert
        CSL_FINST(tmpOPT, EDMA3CC_OPT_SYNCDIM, ASYNC);
        //Set the PaRam as non static since it is desired that the source and destination addresses are incremented
        CSL_FINST(tmpOPT, EDMA3CC_OPT_STATIC, NORMAL);
        //FIFO width is let to the default value since it is not applicable
        CSL_FINST(tmpOPT, EDMA3CC_OPT_FWID, 8BIT);
        //Set the TCC mode to normal completion
        CSL_FINST(tmpOPT, EDMA3CC_OPT_TCCMOD, NORMAL);
        //Set the Transfert Complete Code to the same number as the event number
        CSL_FINS(tmpOPT, EDMA3CC_OPT_TCC, eventNumber);
        //Enable the Transfer Complete Interrupt and disable the others interrupts
        CSL_FINST(tmpOPT, EDMA3CC_OPT_TCINTEN, ENABLE);
        CSL_FINST(tmpOPT, EDMA3CC_OPT_ITCINTEN, DISABLE);
        CSL_FINST(tmpOPT, EDMA3CC_OPT_TCCHEN, DISABLE);
        CSL_FINST(tmpOPT, EDMA3CC_OPT_ITCCHEN, DISABLE);
        edma3ccRegs->PARAMSET[eventNumber].OPT = tmpOPT;

    }
    else
    {
        res = EDMAB_RETURN_VALUE_UNIMPLEMENTED_EVENT;
    }
    return res;
}

And here is how I  Initiate a transfer (At this point the instruction code and address has already been transferred to the SPI Flash memory) :

        //incommingData
        //Set the PaRam 18 (SPI1 Receive) to write received data from the SPI register to the memory
        //Source address will not be incremented (we will always read from the same register)
        //Destination address will be incremented by 1 on each event (each new byte received by the SPI will be written after the previous one in the memory)
        EDMAB_setPaRamForEvent(18, (void *) &(spi1Regs->SPIBUF), (void *) incommingData, 1,
                maxDataSize - minDataSize, 0, 1);

        //outgoingData
        //Set the PaRam 19 (SPI1 Transmit) to write dummy data from the memory to the SPI register
        //Source address will not be incremented (we will always read the same dummy byte)
        //Destination address will be not incremented (we will always write to the same SPI register)
        EDMAB_setPaRamForEvent(19, (void *) &dataToReject, (void *) &(spi1Regs->SPIDAT1), 1,
                maxDataSize - minDataSize, 0, 0);

        //Enabling the DMA event generation in the SPI registers
        CSL_FINST(spi1Regs->SPIINT0, SPI_SPIINT0_DMAREQEN, ENABLE);

        //Trigger the first SPI1 transmit event
        CSL_FINST(edma3ccRegs->ESR, EDMA3CC_ESR_E19, SET);

        //Wait for both SPI1 Transmit and receive DEMA channel to trigger a Transfert complete (interrupt)
        while ((CSL_FEXT(edma3ccRegs->IPR,EDMA3CC_IPR_I19) != CSL_EDMA3CC_IPR_I19_YES)
                && (CSL_FEXT(edma3ccRegs->IPR,EDMA3CC_IPR_I18) != CSL_EDMA3CC_IPR_I18_YES))
            ;


        //Disabling the DMA event generation in the SPI registers
        CSL_FINST(spi1Regs->SPIINT0, SPI_SPIINT0_DMAREQEN, DISABLE);

        //Clearing the Event register
        CSL_FINST(edma3ccRegs->ECR, EDMA3CC_ECR_E19, CLEAR);
        CSL_FINST(edma3ccRegs->ECR, EDMA3CC_ECR_E18, CLEAR);

        //Clearing the Interrupt Pending register
        CSL_FINST(edma3ccRegs->ICR, EDMA3CC_ICR_I19, CLEAR);
        CSL_FINST(edma3ccRegs->ICR, EDMA3CC_ICR_I18, CLEAR);

        //Clearing the Event Missed register
        CSL_FINST(edma3ccRegs->EMCR, EDMA3CC_EMCR_E19, CLEAR);
        CSL_FINST(edma3ccRegs->EMCR, EDMA3CC_EMCR_E18, CLEAR);

        //Clearing the Secondary Event register
        CSL_FINST(edma3ccRegs->SECR, EDMA3CC_SECR_E19, CLEAR);
        CSL_FINST(edma3ccRegs->SECR, EDMA3CC_SECR_E18, CLEAR);

Can you help me find the error I made in the configuration of the EDMA.

Best regards

Arthur