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.

TMS570LC4357: HAL Code Generator example_mibspiDMA extended to 2 transfer groups (DMA transfer for second group does not work)

Part Number: TMS570LC4357


HAL Code Generator Version 04.07.01

CCS Version 10.4.0.00006

I extended the given example example_mibspiDMA.c with 2 transfer groups. Unfortunately the transfer of the received data for the second group from mibSPI1 to RAM location via DMA does not work. I defined 2 transfer groups in the HAL Code Generator, each having 64 buffers. After that I generated the code with HAL Code Generator and modified the example module example_mspiDMA.c. Please find below the content of the modified example_mibspiDMA.c. Do you have an idea what is wrong in this code. The transfer of transfer group 0 works fine.

/* USER CODE BEGIN (0) */
/* USER CODE END */

/* Include Files */

#include "HL_sys_common.h"

/* USER CODE BEGIN (1) */
#include "HL_mibspi.h"
#include "HL_sys_dma.h"

/* example data Pattern configuration */
#define D_SIZE 64

void loadDataPattern(uint32 psize, uint16* pptr);
void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi);
void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize);
void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel);

#pragma SET_DATA_SECTION(".sharedRAM")
uint16 TG0_TXDATA[D_SIZE];         /* transmit buffer in sys ram */
uint16 TG0_RXDATA[D_SIZE]= {0};    /* receive  buffer in sys ram */
uint16 TG1_TXDATA[D_SIZE];         /* transmit buffer in sys ram */
uint16 TG1_RXDATA[D_SIZE]= {0};    /* receive  buffer in sys ram */
#pragma SET_DATA_SECTION()

g_dmaCTRL g_dmaCTRLPKT1, g_dmaCTRLPKT2;    /* dma control packet configuration stack */
/* USER CODE END */

/** @fn void main(void)
*   @brief Application main function
*   @note This function is empty by default.
*
*   This function is called after startup.
*   The user can use this function to implement the application.
*/

/* USER CODE BEGIN (2) */
/* USER CODE END */

void main(void)
{
/* USER CODE BEGIN (3) */

   /* - creating a data chunk in system ram to start with ... */
   loadDataPattern(D_SIZE, &TG0_TXDATA[0]);
   loadDataPattern(D_SIZE, &TG1_TXDATA[0]);

   /* - initializing mibspi - enabling tg 0 , length 127 (halcogen file)*/
   mibspiInit();

   /* - enabling loopback ( this is to emulate data transfer without external wires */
   mibspiEnableInternalLoopback(mibspiREG1);

   /* - configuring dma control packets TG0 */
   g_dmaCTRLPKT1.SADD      = (uint32)TG0_TXDATA;    /* source address             */
   g_dmaCTRLPKT1.DADD      = (uint32)&(mibspiRAM1->tx[0].data);    /* destination  address       */
   g_dmaCTRLPKT1.CHCTRL    = 3+1;               /* channel control            */
   g_dmaCTRLPKT1.FRCNT	   = 1;                 /* frame count                */
   g_dmaCTRLPKT1.ELCNT     = D_SIZE;            /* element count              */
   g_dmaCTRLPKT1.ELDOFFSET = 4;                 /* element destination offset */
   g_dmaCTRLPKT1.ELSOFFSET = 0;		            /* element destination offset */
   g_dmaCTRLPKT1.FRDOFFSET = 0;		            /* frame destination offset   */
   g_dmaCTRLPKT1.FRSOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT1.PORTASGN  = PORTA_READ_PORTB_WRITE;
   g_dmaCTRLPKT1.RDSIZE    = ACCESS_16_BIT;	    /* read size                  */
   g_dmaCTRLPKT1.WRSIZE    = ACCESS_16_BIT; 	/* write size                 */
   g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
   g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1;         /* address mode read          */
   g_dmaCTRLPKT1.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
   g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

   g_dmaCTRLPKT2.SADD      = (uint32)&(mibspiRAM1->rx[0].data);    /* source address             */
   g_dmaCTRLPKT2.DADD      = (uint32)TG0_RXDATA;    /* destination  address       */
   g_dmaCTRLPKT2.CHCTRL    = 2+1;               /* channel control            */
   g_dmaCTRLPKT2.FRCNT	   = 1;                 /* frame count                */
   g_dmaCTRLPKT2.ELCNT     = D_SIZE;             /* element count              */
   g_dmaCTRLPKT2.ELDOFFSET = 0;                 /* element destination offset */
   g_dmaCTRLPKT2.ELSOFFSET = 4;		            /* element destination offset */
   g_dmaCTRLPKT2.FRDOFFSET = 0;		            /* frame destination offset   */
   g_dmaCTRLPKT2.FRSOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT2.PORTASGN  = PORTB_READ_PORTA_WRITE;
   g_dmaCTRLPKT2.RDSIZE    = ACCESS_16_BIT;	    /* read size                  */
   g_dmaCTRLPKT2.WRSIZE    = ACCESS_16_BIT; 	/* write size                 */
   g_dmaCTRLPKT2.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
   g_dmaCTRLPKT2.ADDMODERD = ADDR_OFFSET;         /* address mode read          */
   g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1;       /* address mode write         */
   g_dmaCTRLPKT2.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

   /* upto 32 control packets are supported. */

   /* - setting dma control packets */
   dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT2);
   dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT1);

   /* - setting the dma channel to trigger on h/w request */
   dmaSetChEnable(DMA_CH0, DMA_HW);
   dmaSetChEnable(DMA_CH1, DMA_HW);

   /* - configuring dma control packets TG1 */
   g_dmaCTRLPKT1.SADD      = (uint32)TG1_TXDATA;    /* source address             */
   g_dmaCTRLPKT1.DADD      = (uint32)&(mibspiRAM1->tx[64].data);    /* destination  address       */
   g_dmaCTRLPKT1.CHCTRL    = 0;                 /* channel control            */
   g_dmaCTRLPKT1.FRCNT     = 1;                 /* frame count                */
   g_dmaCTRLPKT1.ELCNT     = D_SIZE;            /* element count              */
   g_dmaCTRLPKT1.ELDOFFSET = 4;                 /* element destination offset */
   g_dmaCTRLPKT1.ELSOFFSET = 0;                 /* element destination offset */
   g_dmaCTRLPKT1.FRDOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT1.FRSOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT1.PORTASGN  = PORTA_READ_PORTB_WRITE;
   g_dmaCTRLPKT1.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
   g_dmaCTRLPKT1.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
   g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
   g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1;         /* address mode read          */
   g_dmaCTRLPKT1.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
   g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

   g_dmaCTRLPKT2.SADD      = (uint32)&(mibspiRAM1->rx[64].data);    /* source address             */
   g_dmaCTRLPKT2.DADD      = (uint32)TG1_RXDATA;    /* destination  address       */
   g_dmaCTRLPKT2.CHCTRL    = 0;                 /* channel control            */
   g_dmaCTRLPKT2.FRCNT     = 1;                 /* frame count                */
   g_dmaCTRLPKT2.ELCNT     = D_SIZE;             /* element count              */
   g_dmaCTRLPKT2.ELDOFFSET = 0;                 /* element destination offset */
   g_dmaCTRLPKT2.ELSOFFSET = 4;                 /* element destination offset */
   g_dmaCTRLPKT2.FRDOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT2.FRSOFFSET = 0;                 /* frame destination offset   */
   g_dmaCTRLPKT2.PORTASGN  = PORTB_READ_PORTA_WRITE;
   g_dmaCTRLPKT2.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
   g_dmaCTRLPKT2.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
   g_dmaCTRLPKT2.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
   g_dmaCTRLPKT2.ADDMODERD = ADDR_OFFSET;         /* address mode read          */
   g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1;       /* address mode write         */
   g_dmaCTRLPKT2.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

   /* upto 32 control packets are supported. */

   /* - setting dma control packets */
   dmaSetCtrlPacket(DMA_CH2,g_dmaCTRLPKT2);
   dmaSetCtrlPacket(DMA_CH3,g_dmaCTRLPKT1);

   /* - setting the dma channel to trigger on h/w request */
   dmaSetChEnable(DMA_CH2, DMA_HW);
   dmaSetChEnable(DMA_CH3, DMA_HW);

   dmaReqAssign(DMA_CH0, DMA_REQ0); //TG0 RX
   dmaReqAssign(DMA_CH1, DMA_REQ1); //TG0 TX
   dmaReqAssign(DMA_CH2, DMA_REQ5); //TG1 RX
   dmaReqAssign(DMA_CH3, DMA_REQ4); //TG1 TX

   /* - configuring the mibspi dma , channel 0 , tx line - 0 , rxline - 1     */
   /* - refer to the device data sheet dma request source for mibspi tx/rx  */
   mibspiDmaConfig(mibspiREG1,0,0,1);
   /* - configuring the mibspi dma , channel 1 , tx line - 3 , rxline - 2     */
   mibspiDmaConfig(mibspiREG1,1,3,2);

   dmaEnable();

   /* - start the mibspi transfer tg 0 and tg 1 */
   mibspiTransfer(mibspiREG1, 0);
   mibspiTransfer(mibspiREG1, 1);

   while(1); /* loop forever */

/* USER CODE END */
}

/* USER CODE BEGIN (4) */
/** void mibspiEnableLoopback(mibspiBASE_t *mibspi )
*
*   enabling internal loopback on mibspix
*/
void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi )
{
	/* enabling internal loopback */
    mibspi->GCR1 |= 1U << 16U;
}

/** void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel)
*
*   configuring mibspi dma with
*
*       channel   > mibspi dma channel number
*       txchannel > transmit channel dedicated for mibspi
*       rxchannel > receive  channel dedicated for mibspi
*/
void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel)
{
	uint32 bufid  = D_SIZE - 1;
	uint32 icount = 0;

	/* setting transmit and receive channels */
	mibspi->DMACTRL[channel] |= (((rxchannel<<4)|txchannel) << 16);

	/* enabling transmit and receive dma */
	mibspi->DMACTRL[channel] |=  0x8000C000;

	/* setting Initial Count of DMA transfers and the buffer utilized for DMA transfer */
	mibspi->DMACTRL[channel] |=  (icount << 8) |(bufid<<24);

}


/** void loadDataPattern(uint32 psize, uint16* pptr)
*
*   loading a randam data chunk into system ram
*
*     pptr  > sys ram address
*     psize > chunkl size
*
*/
void loadDataPattern(uint32 psize, uint16 * pptr)
{
	int i;

	for(i = 0; i < psize; i++)
	{
		TG0_TXDATA[i] = i;
		TG1_TXDATA[i] = i+64;
	}
 }
/* USER CODE END */

  • Hello,

    Do you use DMA chain feature for Group1 transfer? From your packet configuration, the Group1 TX and RX are triggered by the completion of Group 0 TX/RX.

    /* - configuring the mibspi dma , channel 1 , tx line - 3 , rxline - 2 */
    mibspiDmaConfig(mibspiREG1,1,3,2);

    should be:

    /* - configuring the mibspi dma , channel 1 , tx line - 2 , rxline - 3 */
    mibspiDmaConfig(mibspiREG1,1,2,3);

  • Hello Mr. Wang,

    thanks for your response and your help. I corrected the code regarding the parameters of function mibspiDmaConfig(...). Also I cleared the trigger by the completion of Group 0 TX/RX for Group 1 TX/RX in the packet configuration.

    Debugging shows, that the content of TG1_RXDATA RAM location for Group 1 still remains 0. Memory View of the mibSpi transmit buffers show that the content of Group 0 and Group 1 are correct. This means that the content of TG0_TXDATA and TG1_TXDATA in RAM loction for both Groups have been correctly transfered by DMA to mibSpi buffers. Viewing the receive buffers of mibSPI also show the correct content. But only the content of Group 0 is transfered by DMA to RAM location TG0_RXDATA.  

    Actually I dont want to use DMA chain feature in the packet configuration, but I donot know what I have to do in order to get the TG1 transmitted from mibSpi buffers to TG1_RXDATA via DMA.

    Thanks a lot for your help.

    Supplement: I just found out, that DMA ist tranfering TG1 to TG1_RXDATA to early. DMA accesses the receive buffers of TG1 before mibSPI writes received data to the receive buffers of TG1. In this situation the content of all receive buffers of TG1 are still 0 and therefore DMA transmitts 0 to TG1_RXDATA. How to solve this problem?

  • Please enable the DMA BTC interrupt, and start Group1 transfer after Group0 transfer has completed

    /* Enable Block Transfer Complete interrupt for the Group0 receive after transfer complete */
    dmaEnableInterrupt(DMA_CH0, BTC, DMA_INTA);

    Group0_DMA_Completion_Flg = 0;

    /* - start the mibspi transfer tg 0 */
    mibspiTransfer(mibspiREG1, 0);

    while(Group0_DMA_Completion_Flg == 0);

    mibspiTransfer(mibspiREG1, 1);

      while(1); /* loop forever */

    }

    //notification for DMA BTC interrupt

    void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel)
    {
        Group0_DMA_Completion_Flg = 1;
    }

  • Thanks for your reply. Unfortunately this did not solve the Problem. The DMA transfer from TG1 to TG1_RXDATA is allready done before mibspiTransfer(mibspiREG1, 1) is executed. Executing mibspiTransfer(mibspiREG1, 1) dose still lead to an empty (filled with 0) TG1_RXDATA (no DMA transfer).

  • Hi Raheem,

    Just re-checked your code, I think the bufid for group1 should be 127 rather than 63.

  • Hi QJ,

    thanks for your help. After changing the bufid for group1 my example code works perfectly. I read the technical reference manual regarding the description of the register DMAxCTRL. I am not sure if I understood the meaning of bufid. Does it mean, that bufid has to be set to the last buffer ID of a transfer group? For group 0 it is 63 and group 1 it is 127?

    Regards,

    Raheem

  • Yes, your understanding is correct.