Quantcast
Channel: Processors forum - Recent Threads
Viewing all articles
Browse latest Browse all 17527

EDMA Linking mode for ping-pong buffering

$
0
0

 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?

 


Viewing all articles
Browse latest Browse all 17527

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>