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: sci dma rx

Part Number: TMS570LC4357


王工您好:

        我们现在用SCI3做串口收发,两个570芯片使用sci3进行通信,并使用DMA功能。

        

       配置如下:

     

     初始化代码: 

void dma_init()
{
/*Assign DMA request SCI3 receive to Channel 1*/
dmaReqAssign(DMA_CH1, DMA_SCI3_RX);

sciRxData = SCI3_RX_ADDR;

/*Configure control packet for Channel 1*/
g_dmaCTRLPKT2.SADD = sciRxData; /* source address */
g_dmaCTRLPKT2.DADD = (uint32_t)RX_DATA; /* destination addr ss */
g_dmaCTRLPKT2.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT2.FRCNT = 5; /* 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 = PORTB_READ_PORTA_WRITE;
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_FIXED; /* address mode read */
g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1; /* address mode write */
g_dmaCTRLPKT2.AUTOINIT = AUTOINIT_OFF; /* autoinit */

/*Set control packet for channel 0 and 1*/
dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT2);

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

/*Enable DMA*/
dmaEnable();

/*Enable SCI3 Receive DMA Request*/
sciREG3->SETINT |= SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
}

接收函数为:

void sci_rcvData()
{
memset(pRcvData,0,size);
#if 1
while((sciREG3->FLR & 0x4U) == 0x4U)
{
}
#endif
/*- Disable所有中断*/
sciREG3->CLEARINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;

memcpy(pRcvData,RX_DATA,size);
dbgPrintf("cpu:%d dma recv:%d %d %d %d %d\r\n",cpu_id,pRcvData[0],pRcvData[1],pRcvData[2],pRcvData[3],pRcvData[4]);

/*- 清除BTC flag*/
dmaREG->BTCFLAG |= 1U << DMA_CH1;
/*- 设置通道1的控制pkt*/
dmaRAMREG->PCP[DMA_CH1].ITCOUNT = ((uint32_t)5<< 16U) | 1U;
/*- 设置通道1使能*/
dmaSetChEnable(DMA_CH1, DMA_HW);
/*- 使能SCI3接收DMA请求*/
sciREG3->SETINT |= SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
}

周期执行下列代码:

for(i=0;i<5;i++)
{
data[i]++;
if(data[i]==200)
data[i]=0;
}

sciSend(sciREG3,5,data);
sci_rcvData();

但是两个cpu接收的数据都不对,打印如下,请王工给看一下我哪里弄错了,谢谢。

  • Hi MingXi,

    Is MCU1 SCI3_RX connected to CPU2 SCI3_TX, and MCU1 SCI3_TX connected to CPU2 SCI3_RX?

    g_dmaCTRLPKT2.SADD = sciRxData; /* source address */

    What is sciRxData used in your code? For TMS570LC43x which is a big endian device, the source address should be &(sciREG3->RD) + 3 rather than &(sciREG3->RD).

    /*Enable DMA*/
    dmaEnable();

    /*Enable SCI3 Receive DMA Request*/
    sciREG3->SETINT |= SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;

    It is better to enable DMA after SCI DMA is enabled. If DMA is enabled before SCI_TX/RX_DMA is enabled, delay between sciREG3->SETINT will make the SCI get the wrong data (or just the last byte). DMA can be enabled here or before sciInit().

    What is the transmitted data from CPU2 and CPU1? Are the CPU1 received data correct, for example 109, 110, 110, 110?

    sciSend(sciREG3,5,data);
    sci_rcvData();

    If DMA is used, you don't need to call sciSend(sciREG3,5,data); and sci_rcvData(); to transmit data and receive data?

  • 王工,上面那个问题我知道哪里不对了。我还有个问题想咨询一下,如下是我们DMA的接收函数,主要步奏是1.2.3.4.5.6,您看这六步的顺序是否合适,是否还需要增加别的操作,有没有哪步可以删除,可以不用执行?谢谢。

    void sci_rcvData()
    {
    memset(pRcvData,0,size);

    while((sciREG3->FLR & 0x4U) == 0x4U)  /*- 1.串口总线是否空闲*/

    {
    }

    while(dmaGetInterruptStatus(DMA_CH1, BTC) != TRUE)  /*- 2.DMA传输是否完成*/
    {
    }


    sciREG3->CLEARINT = SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;/*- 3.Disable所有中断*/

    memcpy(pRcvData,RX_DATA,size);

    dmaREG->BTCFLAG |= 1U << DMA_CH1;/*-4.清除 BTC标识*/
    dmaSetChEnable(DMA_CH1, DMA_HW);/*- 5. 使能硬件请求*/
    sciREG3->SETINT |= SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;/*- 6. 使能SCI3接收DMA请求*/
    }

  • Hi Mingxi,

    Does the sci_rcvData() work in your test?

    I think the sequence should be:

    1 --> 3 --> 5 --> 6 --> 2 --> 4-->memcpy(pRcvData,RX_DATA,size);

    If you use DMA BTC interrupt, step can be ignored since reading interrupt offset will clear the interrupt flag.

  • 王工您好:

          1)您能给我提供一个sci使用DMA接收函数嘛?

          2)如何判断DMA接收完成?

          3)dmaSetChEnable(DMA_CH1, DMA_HW);这个函数的作用是将数据复制到用户的接收缓RX_DATA存中吗?

  • 1)您能给我提供一个sci使用DMA接收函数嘛?

    I will check if I have a working example.

        2)如何判断DMA接收完成?

    You can enable the Block transfer complete (BTC) interrupt and set a flag in the BTC ISR. The BTC is issued after the last element of the last frame has been transferred.

    3)dmaSetChEnable(DMA_CH1, DMA_HW);这个函数的作用是将数据复制到用户的接收缓RX_DATA存中吗?

    This function is to enables the selected DMA channel (DMA_CH1) for hardware triggering. There are three ways to start a DMA transfer:

    1. Hardware request: The DMA controller can handle up to 48 DMA Request lines. A hardware request can trigger either a frame or a block transfer.
    2. Software request: The transfer will be triggered by writing to SW Channel Enable Set and Status Register.
    3. Triggered by other control packet: When a control packet finishes the programmed number of transfers it can trigger another channel to initiate its transfers.
  • Hi Mingxi,

    Attached is a TXRX DMA example for SCI:

    TMS570LC43_SCI_TXRX_DMA.zip

  • 王工

           1)如何enable the Block transfer complete (BTC) interrupt and set a flag in the BTC ISR.

            2)如果没有enable the Block transfer complete (BTC) interrupt,那么是不是就不需要关心BTC状态,上面代码中步奏4就不需要。

  • 如何enable the Block transfer complete (BTC) interrupt and set a flag in the BTC ISR.

    Set bit of BTCINTENAS register, call the following API:

    dmaEnableInterrupt(DMA_CH1, BTC, DMA_INTA);

    Enable VIM channel for BTC interrupt:

    The ISR is predefined for channel 40:

    2)如果没有enable the Block transfer complete (BTC) interrupt,那么是不是就不需要关心BTC状态,上面代码中步奏4就不需要。

    If the BTC interrupt is enabled, step #4 is nor needed.