Hi All!
I learned how to use EDMA in Linking mode.
I want to receive 2048 bytes by SPI continuously into the ping-pong buffer by EDMA Linking mode. I investigated Technical Reference manual for L138 and now I have just one question.
In use four ParamSet: one for dummy SPI transmission, one for SPI receive and two linked Paramset for ping and pong buffers filling. For each ParamSet initialization I created function which is called once in the EDMA initialization routine.
My ParamSet init functions:
void edmaRecvReload(void) { unsigned int shadowRegionId = 1; // Shadow region used for interrupts unsigned int edmaRecvChNum = 18; // Ch18 is SPI1 Receive Event unsigned int edmaTxEvtQNum = 0; // Event Queue used unsigned short edmaRecvACnt = 1; // 2048 1-byte transmissions unsigned short edmaBCnt = 2048; // 1 time transmission unsigned short edmaCCnt = 1; // 1 time transmission unsigned short edmaRecvSrcBIdx = 0; // Don't want to change the src count offset unsigned short edmaRecvDesBIdx = 1; // Increment on destination count offset by one byte unsigned short edmaRecvSrcCIdx = 0; // Don't want to change the src count offset unsigned short edmaRecvDesCIdx = 0; // Don't want to change the destination count offset unsigned short edmaBCntReload = 0; // Don't want to reload B count unsigned int writeAddr; volatile unsigned int *ds; unsigned int *sr; unsigned int i = 0; // Set up DMA Recv channel ////////////////////////////////////////////////////////// //getWriteBufferAddr(&writeAddr); // Associate DMA Channel to Event Queue HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_DMAQNUM((edmaRecvChNum) >> 3u)) &= EDMA3CC_DMAQNUM_CLR(edmaRecvChNum); HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_DMAQNUM((edmaRecvChNum) >> 3u)) |= EDMA3CC_DMAQNUM_SET((edmaRecvChNum), edmaTxEvtQNum); // Enable the Event Interrupt HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_S_IESR(shadowRegionId)) |= (0x01u << edmaRecvChNum); HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_OPT(edmaRecvChNum)) &= EDMA3CC_OPT_TCC_CLR; HWREG(SOC_EDMA30CC_0_REGS + EDMA3CC_OPT(edmaRecvChNum)) |= EDMA3CC_OPT_TCC_SET(edmaRecvChNum); /* Fill the PaRAM Set with transfer specific information */ recvParamSet.srcAddr = (unsigned int)&HWREG(SOC_SPI_1_REGS + SPI_SPIBUF); recvParamSet.destAddr = (unsigned int)&PingBuf; recvParamSet.aCnt = edmaRecvACnt; recvParamSet.bCnt = edmaBCnt; recvParamSet.cCnt = edmaCCnt; // Setting up the SRC/DES Index recvParamSet.srcBIdx = edmaRecvSrcBIdx; recvParamSet.destBIdx = edmaRecvDesBIdx; /* A Sync Transfer Mode */ recvParamSet.srcCIdx = edmaRecvSrcCIdx; recvParamSet.destCIdx = edmaRecvDesCIdx; // 0x4000 is starting add. 8 32 bit register values per channel. Using ch32. So 8*4*32+0x4000 = 0x4400 recvParamSet.linkAddr = (unsigned short)0x4800; recvParamSet.bCntReload = edmaBCntReload; // Initialize the options register recvParamSet.opt = 0u; /* Enable Final transfer completion interrupt */ recvParamSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT); // Program the TCC recvParamSet.opt |= ((edmaRecvChNum << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC); // /* Enable Intermediate & Final transfer completion interrupt */ // paramSet.opt |= (1 << EDMA3CC_OPT_ITCINTEN_SHIFT); // recvParamSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT); // Set for A-B synchronized transfer // txParamSet.opt |= (1 << EDMA3CC_OPT_SYNCDIM_SHIFT); // End Set up DMA Recv channel ////////////////////////////////////////////////////// /* configure PaRAM Set */ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, edmaRecvChNum , &PongParamSet); /* Enable the transfer */ EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, edmaRecvChNum , EDMA3_TRIG_MODE_EVENT); } void Pong_ParamSet_init(void) { unsigned int shadowRegionId = 1; // Shadow region used for interrupts unsigned int PongSetParamNum = 64; // Set 64 linked to Set 65 unsigned int edmaTxEvtQNum = 0; // Event Queue used unsigned short edmaRecvACnt = 1; // 2048 1-byte transmissions unsigned short edmaBCnt = 2048; // 1 time transmission unsigned short edmaCCnt = 1; // 1 time transmission unsigned short edmaRecvSrcBIdx = 0; // Don't want to change the src count offset unsigned short edmaRecvDesBIdx = 1; // Increment on destination count offset by one byte unsigned short edmaRecvSrcCIdx = 0; // Don't want to change the src count offset unsigned short edmaRecvDesCIdx = 0; // Don't want to change the destination count offset unsigned short edmaBCntReload = 0; // Don't want to reload B count unsigned int writeAddr; volatile unsigned int *ds; unsigned int *sr; unsigned int i = 0; // Set up DMA Recv channel ////////////////////////////////////////////////////////// // getWriteBufferAddr(&writeAddr); /* Fill the PaRAM Set with transfer specific information */ PongParamSet.srcAddr = (unsigned int)&HWREG(SOC_SPI_1_REGS + SPI_SPIBUF); PongParamSet.destAddr = (unsigned int)&PongBuf; PongParamSet.aCnt = edmaRecvACnt; PongParamSet.bCnt = edmaBCnt; PongParamSet.cCnt = edmaCCnt; // Setting up the SRC/DES Index PongParamSet.srcBIdx = edmaRecvSrcBIdx; PongParamSet.destBIdx = edmaRecvDesBIdx; /* A Sync Transfer Mode */ PongParamSet.srcCIdx = edmaRecvSrcCIdx; PongParamSet.destCIdx = edmaRecvDesCIdx; // 0x4000 is starting add. 8 32 bit register values per channel. Using ch32. So 8*4*32+0x4000 = 0x4400 PongParamSet.linkAddr = (unsigned short)0x4820; PongParamSet.bCntReload = edmaBCntReload; // Initialize the options register PongParamSet.opt = 0u; /* Enable Final transfer completion interrupt */ // PongParamSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT); //Im NOT SURE!!! // Program the TCC PongParamSet.opt |= ((18 << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC); //interrupt from chan18 after completion Im NOT SURE!!! /* configure PaRAM Set */ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, PongSetParamNum , &PongParamSet); /* Enable the transfet */ EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, PongSetParamNum , EDMA3_TRIG_MODE_EVENT); } void Ping_ParamSet_init(void) { unsigned int shadowRegionId = 1; // Shadow region used for interrupts unsigned int PongSetParamNum = 65; // Set 65 linked to Set 64 unsigned int edmaTxEvtQNum = 0; // Event Queue used unsigned short edmaRecvACnt = 1; // 2048 1-byte transmissions unsigned short edmaBCnt = 2048; // 1 time transmission unsigned short edmaCCnt = 1; // 1 time transmission unsigned short edmaRecvSrcBIdx = 0; // Don't want to change the src count offset unsigned short edmaRecvDesBIdx = 1; // Increment on destination count offset by one byte unsigned short edmaRecvSrcCIdx = 0; // Don't want to change the src count offset unsigned short edmaRecvDesCIdx = 0; // Don't want to change the destination count offset unsigned short edmaBCntReload = 0; // Don't want to reload B count unsigned int writeAddr; volatile unsigned int *ds; unsigned int *sr; unsigned int i = 0; // Set up DMA Recv channel ////////////////////////////////////////////////////////// // getWriteBufferAddr(&writeAddr); /* Fill the PaRAM Set with transfer specific information */ PingParamSet.srcAddr = (unsigned int)&HWREG(SOC_SPI_1_REGS + SPI_SPIBUF); PingParamSet.destAddr = (unsigned int)&PingBuf; PingParamSet.aCnt = edmaRecvACnt; PingParamSet.bCnt = edmaBCnt; PongParamSet.cCnt = edmaCCnt; // Setting up the SRC/DES Index PingParamSet.srcBIdx = edmaRecvSrcBIdx; PingParamSet.destBIdx = edmaRecvDesBIdx; /* A Sync Transfer Mode */ PingParamSet.srcCIdx = edmaRecvSrcCIdx; PingParamSet.destCIdx = edmaRecvDesCIdx; // 0x4000 is starting add. 8 32 bit register values per channel. Using ch32. So 8*4*32+0x4000 = 0x4400 PingParamSet.linkAddr = (unsigned short)0x4800; PingParamSet.bCntReload = edmaBCntReload; // Initialize the options register PingParamSet.opt = 0u; /* Enable Final transfer completion interrupt */ // PingParamSet.opt |= (1 << EDMA3CC_OPT_TCINTEN_SHIFT); // Im NOT SURE!!! // Program the TCC PingParamSet.opt |= ((18 << EDMA3CC_OPT_TCC_SHIFT) & EDMA3CC_OPT_TCC); //interrupt from chan18 after completion Im NOT SURE!!! /* configure PaRAM Set */ EDMA3SetPaRAM(SOC_EDMA30CC_0_REGS, PingSetParamNum , &PongParamSet); /* Enable the transfet */ EDMA3EnableTransfer(SOC_EDMA30CC_0_REGS, PingSetParamNum , EDMA3_TRIG_MODE_EVENT); }
I market places when Im not sure in the code. So, my questiuon: can I set TCINTEN to 1 and TCC to 18 in the Ping and Pong ParamSets?
Why Im not sure: Tech. ref. manual has Ping Pong buffering example (18.4.4.4). There use ParamSet64 and ParamSet65 (Pong and Ping) with TCINTEN = 0. Only in ParamSet of channel 3 (McBSP receive) used TCINTEN=1. I want to generate interrupt after each ping/pong filling, therefore I set TCINTEN to 1 and TCC to 18 in each ParamSet for generate same interrupt for each filling of ping and pong.
Is it correct?