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