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.

Question is about continiuos operation with DMA-SCI

Other Parts Discussed in Thread: RM57L843, HALCOGEN

Hi,

I am working on RM57L843 device DMA with SCI.

I am able to transfer 260 bytes of data with DMA and also able to receive the 260 bytes of  data with DMA.

My Setup:

1.Configured DMA ch-0 to SCI3 transmit

2.Configured DMA ch-1 to SCI3 receive.

3.enabled DMA RX and DMA TX in SCI3

4.transmit control packet initialization below

 dmaReqAssign(DMA_CH0, DMAREQ_SCI3_TX);

 /*Configure control packet for Channel 0  for transmit */
 g_dmaSci3TxCTRLPKT1.SADD = ((uint32_t) (&u8_sci3TxData[1])); /* source address which is nothing but RAM location */
 g_dmaSci3TxCTRLPKT1.DADD = (uint32_t) (&(sciREG3->TD)); /* destination  address which is nothing but Buffer register */
 g_dmaSci3TxCTRLPKT1.CHCTRL = 0; /* channel control            */
 g_dmaSci3TxCTRLPKT1.FRCNT = (SIZE - 1U); /* frame count                */
 g_dmaSci3TxCTRLPKT1.ELCNT = 4U;  //SIZE; /* element count              */
 g_dmaSci3TxCTRLPKT1.ELDOFFSET = 0; /* element destination offset which is nothing but Buffer register */
 g_dmaSci3TxCTRLPKT1.ELSOFFSET = 0U; /* element Source offset which is nothing but RAM location */
 g_dmaSci3TxCTRLPKT1.FRDOFFSET = 0; /* frame destination offset   */
 g_dmaSci3TxCTRLPKT1.FRSOFFSET = 1U; /* frame Source offset   */
 g_dmaSci3TxCTRLPKT1.PORTASGN = PORTA_READ_PORTB_WRITE; //Data RAM to SCI TX register
 g_dmaSci3TxCTRLPKT1.RDSIZE = ACCESS_8_BIT; /* read size                  */
 g_dmaSci3TxCTRLPKT1.WRSIZE = ACCESS_8_BIT; /* write size                 */
 g_dmaSci3TxCTRLPKT1.TTYPE = FRAME_TRANSFER; /* transfer type              */
 g_dmaSci3TxCTRLPKT1.ADDMODERD = ADDR_OFFSET; /* address mode read          */
 g_dmaSci3TxCTRLPKT1.ADDMODEWR = ADDR_OFFSET; /* address mode write         */
 g_dmaSci3TxCTRLPKT1.AUTOINIT = AUTOINIT_OFF; /* autoinit                   */

 /*Set control packet for channel 0 */
 dmaSetCtrlPacket(DMA_CH0, g_dmaSci3TxCTRLPKT1);

 /*Set Priority for channel-0*/
 dmaSetPriority(DMA_CH0, HIGHPRIORITY);

 /*Set dma channel 0 trigger on hardware request*/
 dmaSetChEnable(DMA_CH0, DMA_HW);

5.Receive control packet initialization:

dmaReqAssign(DMA_CH1, DMAREQ_SCI3_RX);

 /*Configure control packet for Channel 1*/
 g_dmaSci3RxCTRLPKT2.SADD = ((uint32_t) (&(sciREG3->RD))); /* source address which is nothing but RAM location */
 g_dmaSci3RxCTRLPKT2.DADD = ((uint32_t) (&u8_sci3RxData[0])); /* destination  address which is nothing but RAM location*/
 g_dmaSci3RxCTRLPKT2.CHCTRL = 0; /* channel control            */
 g_dmaSci3RxCTRLPKT2.FRCNT = SIZE; /* frame count                */
 g_dmaSci3RxCTRLPKT2.ELCNT = 4U; /* element count              */
 g_dmaSci3RxCTRLPKT2.ELDOFFSET = 0U; /* element destination offset  */
 g_dmaSci3RxCTRLPKT2.ELSOFFSET = 0U; /* element Source offset */
 g_dmaSci3RxCTRLPKT2.FRDOFFSET = 1U; /* frame destination offset   */
 g_dmaSci3RxCTRLPKT2.FRSOFFSET = 0U; /* frame source offset   */
 g_dmaSci3RxCTRLPKT2.PORTASGN = PORTB_READ_PORTA_WRITE;
 g_dmaSci3RxCTRLPKT2.RDSIZE = ACCESS_8_BIT; /* read size                  */
 g_dmaSci3RxCTRLPKT2.WRSIZE = ACCESS_8_BIT; /* write size                 */
 g_dmaSci3RxCTRLPKT2.TTYPE = FRAME_TRANSFER; /* transfer type              */
 g_dmaSci3RxCTRLPKT2.ADDMODERD = ADDR_OFFSET; /* address mode read          */
 g_dmaSci3RxCTRLPKT2.ADDMODEWR = ADDR_OFFSET; //ADDR_INC1; /* address mode write         */
 g_dmaSci3RxCTRLPKT2.AUTOINIT = AUTOINIT_OFF; /* autoinit                   */

 /*Set control packet for channel 1*/
 dmaSetCtrlPacket(DMA_CH1, g_dmaSci3RxCTRLPKT2);

 /*Set Priority for channel-0*/
 dmaSetPriority(DMA_CH1, HIGHPRIORITY);

 /*Set dma channel 0 trigger on hardware request*/
 dmaSetChEnable(DMA_CH1, DMA_HW);

6.Enabled DMA

7.Sent first byte sci3TxData[0] through CPU using SCIsend(); function generated by the HALCOGEN.

For the first time I am able to send data from sci3TxData[] to sci3RxData thru DMA.I mean DMA is able to read data from RAM sci3TxData and placed the data in SCI->TD register and DMA is able to read data from SCI->RD and write into sci3RxData RAM location.

But if I run the same in continuous loop say while(1) it is not working.

here is action I am doing in while(1)

while(1)

{

/* Filling data in TX buffer */
 for (u16_cnt = 0; u16_cnt < SIZE; u16_cnt++) {
  u8_sci3TxData[u16_cnt] = u16_cnt + 1;
 }

 /*Clear RX buffer*/
 for (u16_cnt = 0; u16_cnt < SIZE; u16_cnt++) {
  u8_sci4RxData[u16_cnt] = 0;
 }

v_sciSendData(UART3, &u8_sci3TxData[0], 1); /* send first byte to start the dma transaction */


  while (dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE)
  {

  }

   dmaREG->BTCFLAG = (uint32)((uint32)1U << 1U);  //Clearing dma BTC flag

  /*Set dma channel 0 trigger on hardware request*/
  dmaSetChEnable(DMA_CH0, DMA_HW);
  /*Set dma channel 1 trigger on hardware request*/
  dmaSetChEnable(DMA_CH1, DMA_HW);


  for (u16_cnt = 0; u16_cnt < SIZE; u16_cnt++)
  {
   if (u8_sci3TxData[u16_cnt] != u8_sci3RxData[u16_cnt])
   {
    break;
   }
  }
  if (u16_cnt < SIZE)
  {
   v_sciDebugPrint(u16_cnt,"Fail u16_cnt");
  }
  else
  {
   v_sciDebugPrint(u16_cnt,"PASS");

  }
 }

For the first time I am able to see PASS but when I run continuously FAIL is showing.

To run dma continoulsy what other settings need to be done?

After first transmission and receiption in DMA what will happen to SOurce addresss ,destination address,frame index pointer,element index pointer?

After first transmission and reception done successfully,If I have to start dma with the same RAM location where sci3TxData,sci3RxData buffer what else need to be taken care.

Can anyone please guide me.

With regards,

Praveen

  • Praveen,


    Well this line:

    g_dmaSci3TxCTRLPKT1.AUTOINIT = AUTOINIT_OFF

    means that after the control packet is consumed, it must be re-initialized by the CPU again.

    I don't see your listing showing that this step is done, so I would say that is a place to start.

  • Hi Anthony,

    Thank you for your response.

    I tried enabling AUTOINIT ON for both channel-0(DMA operation from RAM to SCI TX register) and channel-1(DMA operation SCI-RX to RAM) but no success still I am getting FAIL when I  compare TX data buffer and RX data buffer.

    And also please help me how will DMA channel-1((DMA operation SCI-RX to RAM)) know transfer complete. For Channel-0 I am polling BTC flag similarly if I poll BTC flag for channel-1 time taken to transfer and time taken to receive are not same.

  • Praveen,

    I don't know enough about your setup. Are you attempting to run a loopback test from SCI3 TX to SCI3 RX or is there another host involved.

    Also, from a standpoint of diagnosing the issue, this is very difficult to do from code snippets.

    The hardware has status flags in the SCI, DMA to tell you the state of the IPs and these are the things to check while the silicon is running in order to determine where the breakdown is occurring.
  • Anthony,

    Yeah I working on SCI3 loop back test hardware loop back externally I shorted SCI3RX and SCI3TX pins. I am working on RM57L development kit.

    Instead of enabling auto init, if I reinitialize the control packets for DMA SCI RX and DMA SCI TX it worked. Even I enabled hardware trigger for DMA SCI transfer and DMA SCI receive still it didn't worked, it is waiting for the channel-1 BTC flag to clear.

    while (dmaGetInterruptStatus(DMA_CH1, BTC) != TRUE)
     {

     }

    I have one more doubt to be clarified. As from the DMA SCI transmit control packet initilization you can see in my first query that frame size is 260 bytes and element count is 1

    g_dmaSci3TxCTRLPKT1.FRCNT = (SIZE - 1U); /* frame count                */

     g_dmaSci3TxCTRLPKT1.ELCNT = 1U;  //SIZE; /* element count              */

    to check whether all 260 bytes are transferred or not I am polling channel-0 BTC flag(sciTX[260] buffer to sciREG3->TD)

    while (dmaGetInterruptStatus(DMA_CH0, BTC) != TRUE)
     {

     }

    in the same way for DMA SCI receive control packet initialized as shown below

    g_dmaSci3RxCTRLPKT2.FRCNT = SIZE; /* frame count                */

    g_dmaSci3RxCTRLPKT2.ELCNT = 1U; /* element count              */

    To check whether all 260 bytes are transferred to sciRxbuffer[260] from sciREG3->RD register which flag I have to poll BTC or FTC

    If I poll channel-1 BTC flag it continuously staying in while loop and sometimes it comes out of the loop.

    while (dmaGetInterruptStatus(DMA_CH1, BTC) != TRUE)
     {

     }

    Can you please help me in this regard.

    With regards,

    Praveen

  • Great!

    Pretty sure you need the BTC to know that 260 bytes are transferred. Your element count is 1 so a 'frame' transfer consists of 1 word or byte... But your Frame count consists of SIZE - 1 elements .. So assuming SIZE=260 then it's going to be the BTC that you want.

    I'd make sure that your code can handle transfer and receive independently because even if they are synchronized now it's due to the loopback, you transmit and receive equally and with a fixed timing relationship. But this synchronization will break once you leave loopback mode and do something useful. So it's good if you are writing your DMA ISRs to be independent of each other (which it seems you are... )

    -Anthony