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.

TMS570LS3134: DMA SCI TX loosing 2nd byte when enabling request on another chanel

Part Number: TMS570LS3134

Tool/software:

Hi,

I am working on an application where I need to communicate between 2 devices. I was currently testing message transfer using the SCI and the DMA.

I have different messages MSG1 of size 15, MSG2 of size 14 and MSG3 of size 13. I configured 3 DMA packet like so :

g_dmaCTRL g_dmaCTRLPKT1;
/*Configure control packet for Channel 0*/
g_dmaCTRLPKT1.SADD = (uint32_t)MSG1; /* source address*/
g_dmaCTRLPKT1.DADD = (uint32_t)((uint8*)&(sciREG->TD)+3); /* destination address */
g_dmaCTRLPKT1.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT1.FRCNT = 15; /* frame count */
g_dmaCTRLPKT1.ELCNT = 1; /* element count */
g_dmaCTRLPKT1.ELDOFFSET = 0; /* 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 = 4;
g_dmaCTRLPKT1.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT1.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT1.TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT1.ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT1.AUTOINIT = AUTOINIT_OFF; /* autoinit */
dmaReqAssign(DMA_CH0, 31);
dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT1);

g_dmaCTRL g_dmaCTRLPKT2;
/*Configure control packet for Channel 1*/
g_dmaCTRLPKT2.SADD = (uint32_t)MSG2; /* source address*/
g_dmaCTRLPKT2.DADD = (uint32_t)((uint8*)&(sciREG->TD)+3); /* destination address */
g_dmaCTRLPKT2.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT2.FRCNT = 14; /* frame count */
g_dmaCTRLPKT2.ELCNT = 1; /* element count */
g_dmaCTRLPKT2.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT2.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT2.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT2.FRSOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT2.PORTASGN = 4;
g_dmaCTRLPKT2.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT2.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT2.TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT2.ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT2.ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT2.AUTOINIT = AUTOINIT_OFF; /* autoinit */
dmaReqAssign(DMA_CH1, 31);
dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT2);

g_dmaCTRL g_dmaCTRLPKT3;
/*Configure control packet for Channel 1*/
g_dmaCTRLPKT3.SADD = (uint32_t)MSG3; /* source address*/
g_dmaCTRLPKT3.DADD = (uint32_t)((uint8*)&(sciREG->TD)+3); /* destination address */
g_dmaCTRLPKT3.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT3.FRCNT = 13; /* frame count */
g_dmaCTRLPKT3.ELCNT = 1; /* element count */
g_dmaCTRLPKT3.ELDOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT3.ELSOFFSET = 0; /* element destination offset */
g_dmaCTRLPKT3.FRDOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT3.FRSOFFSET = 0; /* frame destination offset */
g_dmaCTRLPKT3.PORTASGN = 4;
g_dmaCTRLPKT3.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT3.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT3.TTYPE = FRAME_TRANSFER; /* transfer type */
g_dmaCTRLPKT3.ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT3.ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT3.AUTOINIT = AUTOINIT_OFF; /* autoinit */
dmaReqAssign(DMA_CH2, 31);
dmaSetCtrlPacket(DMA_CH2, g_dmaCTRLPKT3);

In my main i do all the necessay init and then :

sciREG->SETINT = (1<<16)| (1<<8); // set tx dma and set tx int

then in my loop i use dmaSetChEnable(DMA_CH0, DMA_HW),dmaSetChEnable(DMA_CH1, DMA_HW) and dmaSetChEnable(DMA_CH2, DMA_HW) with delays but using hterm the first message received is correct i get 15 bytes out of 15, the second message is wrong i get 13 bytes out of 14 all the bytes are correct except the second byte completly missing.

For exemple for a message like 0xB7,0X56,0XAA,0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66 I get 0xB7,0XAA,0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66.

For the third message i get the same error as the second message 12 bytes out of 13 were all the bytes are correct except the second byte compltely missing. 

When i only send the 1st, 2nd or 3rd message I have no error but whenever the DMA switch between channels the first messages is correct but the rest of the messages are received by hterm without the second byte. 

Any idea why ? am I missing a configuration step ?

Thank you for your help in advance. 

  • Hi Ahmet,

    I don't see any configuration errors with the shared code.

    Can i get your complete project for verification and quick debugging at my end? If possible, zip the complete project and attach it.

    --
    Thanks & regards,
    Jagadish.

  • Unfortunately i wont be able to directly send a zip file but I can give you information about my project.

    My enabled driver are RTI,GIO, SCI and HET1. In pinmux mux option 1 is activated for N2 and W3. SCI baudrate 230400 1stop bit. My PLL is configured at 160 MHZ.

    In my source file i only do the previously gived configuration for the 3 messages that are 

    uint8 MSG1[15] = {0xD6,0x81,0x0F,0x57,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0E};
    uint8 MSG2[14] = {0xB7,0x60,0x0F,0x67,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B};
    uint8 MSG3[13] = {0xC6,0x56,0x0F,0x77,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A};

    and in my while loop i just use the dmaSetChEnable function for the 3 channels with delay between calling each function.

    Is this enough for you to replicate the project and see if you have the same problem on your side? I can try to give more information if needed.

    Thank your for your help.

  • Hi Ahmet,

    I was able to reproduce your issue at my end i could see the issue you are talking about.

    Here is the output at my end:

    And i could see the missing of second byte that you mentioned here.

    And further i did one more testing and found the root cause for the issue:

    Actually, after channel-0 completes its transfer to SCI, and after SCI also transfers the data from channel-0 out the TX register in the SCI will get empty right? So, it will immediately generate the TX empty trigger to the DMA and DMA will set the pending bit for corresponding channel that is channel-0(because the channel-1 will not get initialized yet).

    This is the problem, the channel-2 doesn't know about the trigger received from SCI.

    You can see the below pics for better understanding:

    As you can see before i enabled the DMA channel-1, all the three channels pending bits got set (3 channels got set because we assigned same triggers for all three channels in initializations but at the end whichever channel enabled "dmaSetChEnable" will transfer the data):

    And as you can see once i enabled the DMA channel-1 its pending bit cleared

    And it is no use of calling SETINT now because the DMA empty interrupt already sent by the SCI after the end of the first transfer. So, as you can see the pending bit for channel-1 still zero.

    So, to rectify this problem we should need to clear the channel pending for previously active channel:

    To do this i am changing the control packet:

    If i tried to change the control packet and then i will clear and set the DMA TX INT on SCI like below

    If i do this then pending interrupt for previously enabled channel will be cleared.

    And here is the output after this modification:

    And here is the modified code:

    SCI_DMA_TEST_LS3137.zip

    And i want to suggest you one more thing, actually for this requirement we don't need three channels, instead of we can only do with single channel like below:

    After the first transfer just try to change the source address of the first channel with MSG2 like as shown above.

    and after this again wait until the transfer complete. This method should also work. Just try to implement it and remove the code for other two channels.

    --
    Thanks & regards,
    Jagadish.