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.

TMS570LS0714: DMA-SCI

Part Number: TMS570LS0714

Hi team,

Here's an issue from the customer may need your help:

The customer wants to save CPU resources by configuring DMA for SCI receive and SCI/LIN is uesd.

When the DMA source address is configured to scilinREG- RD, the DMA receive data is all zeros. While if using the scireceivebyte feature in SCI to store Rx of sci in data1 and also generate a request request from DMA, place data1 in data, the DMA is able to working properly.

The customer would like to know why can't use sciRd as the source address directly. Could you help check this case? Thanks.

Best Regards,

Cherry

  • Hi Cherry,

    I don't understand the working method mentioned by the customer

    While if using the scireceivebyte feature in SCI to store Rx of sci in data1 and also generate a request request from DMA, place data1 in data, the DMA is able to working properly.

    Can you please ask him to clarify the above thing?

    And also i have the following doubts 

    What is the trigger source using for DMA?

    Is customer using Multibuffered SCI mode with DMA enabled? If yes then what is the LENGTH value he configured in SCIFORMAT register?

    Is customer code is disclosable? If yes can you please ask him to share his code?

    --

    Thanks,

    Jagadish.

  • Hi Jagadish,

    Thanks for your support and I've got some updates from the customer:

    What is the trigger source using for DMA?

    The trigger source for DMA is the RX of SCI.

    Is customer using Multibuffered SCI mode with DMA enabled? If yes then what is the LENGTH value he configured in SCIFORMAT register?

    No, they didn't enable DMA multibuffered mode.

    Is customer code is disclosable? If yes can you please ask him to share his code?

    Part of codes are as follows:

    /** @file sys_main.c 
    *   @brief Application main file
    *   @date 11-Dec-2018
    *   @version 04.07.01
    *
    *   This file contains an empty main function,
    *   which can be used for the application.
    */
    
    /* 
    * Copyright (C) 2009-2018 Texas Instruments Incorporated - www.ti.com 
    * 
    * 
    *  Redistribution and use in source and binary forms, with or without 
    *  modification, are permitted provided that the following conditions 
    *  are met:
    *
    *    Redistributions of source code must retain the above copyright 
    *    notice, this list of conditions and the following disclaimer.
    *
    *    Redistributions in binary form must reproduce the above copyright
    *    notice, this list of conditions and the following disclaimer in the 
    *    documentation and/or other materials provided with the   
    *    distribution.
    *
    *    Neither the name of Texas Instruments Incorporated nor the names of
    *    its contributors may be used to endorse or promote products derived
    *    from this software without specific prior written permission.
    *
    *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
    *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
    *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
    *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
    *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
    *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
    *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
    *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    *
    */
    
    
    /* USER CODE BEGIN (0) */
    /* USER CODE END */
    
    /* Include Files */
    
    #include "sys_common.h"
    
    /* USER CODE BEGIN (1) */
    #include "system.h"
    #include "rti.h"
    #include "het.h"
    #include "gio.h"
    #include "can.h"
    #include "esm.h"
    #include "sys_core.h"
    #include "structdef.h"
    #include "sci.h"
    #include "spi.h"
    #include "sys_dma.h"
    
    #define DMA_SCI_RX  28
    #define SCI_SET_RX_DMA      (1<<17)
    #define SCI_SET_RX_DMA_ALL  (1<<18)
    #define SCI_RX_ADDR ((uint32_t)(&(scilinREG->RD)))
    g_dmaCTRL g_dmaCTRLPKT;
    /* 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) */
    union unOBCTXDATA1{
        struct stBYTETEMP       ObcTxByte1;
        struct unOBCTXWORD1     ObcTxWord1;
    };
    union unOBCTXDATA2{
        struct sciBYTETEMP      ObcTxByte2;
        struct unOBCTXWORDSCI   ObcTxWord2;
    };
    spiDAT1_t dataconfig1_t;
    uint8 tx_data1[8];
    uint8 tx_data2[8];
    uint8 tx_data3[8];
    uint8 tx_data4[8];
    uint8 tx_data5[8];
    uint8 tx_data6[8];
    uint8 tx_data7[8];
    uint8 tx_data8[8];
    uint8 sci_tx_data[3];
    uint8 rx_data[100] = {0};
    uint8 rx_data1[100] = {0};
    uint16 spi_txdata[8];
    uint16 spi_rxdata[8];
    uint16 length;
    uint32 sciRxData;
    //int delay_flag;
    void Can_ObcData1_Send(void);
    void spi_HVLV_SendandRecieve(void);
    void dma_init(void);
    void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize);
    /* USER CODE END */
    
    int main(void)
    {
    /* USER CODE BEGIN (3) */
        sciRxData = SCI_RX_ADDR;
        uint16_t i;
        spiInit();
        gioInit();
        rtiInit();
        hetInit();
        canInit();
        sciInit();
        dma_init();
        rtiEnableNotification(rtiNOTIFICATION_COMPARE0);
        _enable_IRQ();
        dmaEnable();
        scilinREG->SETINT |= SCI_SET_RX_DMA | SCI_SET_RX_DMA_ALL;
        gioSetBit(hetPORT1, 14, 0); //将CAN设置为normal
        rtiStartCounter(rtiCOUNTER_BLOCK0);
        length = 0;
        for(i=0;i<8;i++)
        {
        spi_txdata[i] = 0;
        spi_rxdata[i] = 0;
        }
        dataconfig1_t.CSNR = 0;
        dataconfig1_t.CS_HOLD = 0;
        dataconfig1_t.DFSEL = SPI_FMT_0;
        dataconfig1_t.WDEL = 1;
        while(1)
        {
            if(sciReceiveByte(scilinREG) == 0xFF)
            {
            for(length=0;length<16;length++)
            {
                rx_data[length]  = sciReceiveByte(scilinREG);
    //            rx_data1[length]  = sciReceiveByte(scilinREG);
            }
            }
        }
    /* USER CODE END */
    
        return 0;
    }
    
    
    /* USER CODE BEGIN (4) */
    void dma_init(void)
    {
        dmaReqAssign(DMA_CH0, DMA_SCI_RX);
        dmaConfigCtrlPacket((uint32)(sciRxData),(uint32)(rx_data),16);
    //    dmaConfigCtrlPacket((uint32)(rx_data1),(uint32)(rx_data),16);
        dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT);
        dmaSetChEnable(DMA_CH0, DMA_HW);
    
    }
    void rtiNotification(uint32 notification)
    {
    /*  enter user code between the USER CODE BEGIN and USER CODE END. */
        /* Toggle HET pin 0 */
        gioSetBit(hetPORT1, 22, gioGetBit(hetPORT1, 22) ^ 1);
        spi_HVLV_SendandRecieve();
        Can_ObcData1_Send();
        Sci_ObcData1_Send();
    
    }
    //void Can_ObcData1_Send(void)
    //{
    //    union unOBCTXDATA1  ObcTxData1 = {0};
    //        int j;
    ////        Get_Obc_Message();
    //
    //        ObcTxData1.ObcTxWord1.OBC_Status = 0x001;
    //        ObcTxData1.ObcTxWord1.PFC_Error_State = 0x001;
    //        ObcTxData1.ObcTxWord1.OBC_Output_Vol_H = 3000/256;
    //        ObcTxData1.ObcTxWord1.OBC_Output_Vol_L = 3000%256;
    //        ObcTxData1.ObcTxWord1.OBC_Input_Cur_H = 3000/256;
    //        ObcTxData1.ObcTxWord1.OBC_Input_Cur_L = 3000%256;
    //        ObcTxData1.ObcTxWord1.OBC_Input_Vol_H = 3000/256;
    //        ObcTxData1.ObcTxWord1.OBC_Input_Vol_L = 3000%256;
    //
    //        for(j = 0; j < 8; j++)
    //        {
    //            tx_data[j] = ObcTxData1.ObcTxByte1.ByteTemp[j];
    //        }
    //
    //        canTransmit(canREG2, canMESSAGE_BOX1, tx_data);
    ////        while(!canIsRxMessageArrived(canREG1, canMESSAGE_BOX2));
    ////            canGetData(canREG1, canMESSAGE_BOX2, rx_data);  /* receive on can2  */
    //
    //}
    void spi_HVLV_SendandRecieve(void)
    {
        spiTransmitAndReceiveData(spiREG2,&dataconfig1_t,4,spi_txdata,spi_rxdata);
        spi_txdata[0] ++;
    }
    void Can_ObcData1_Send(void)
    {
        int j;
        for(j = 0; j < 8;j++)
        {
            tx_data1[j] = rx_data[j];
        }
        for(j = 0; j < 8;j++)
        {
            tx_data2[j] = rx_data[j+8];
        }
        for(j = 0; j < 8;j++)
        {
            tx_data3[j] = rx_data[j+16];
        }
        for(j = 0; j < 8;j++)
        {
            tx_data4[j] = rx_data[j+24];
        }
        for(j = 0; j < 8;j++)
        {
            tx_data5[j] = rx_data[j+32];
        }
        for(j = 0; j < 8;j++)
        {
            tx_data6[j] = rx_data[j+40];
        }
        for(j = 0; j < 8;j++)
        {
            tx_data7[j] = rx_data[j+48];
        }
        canTransmit(canREG2, canMESSAGE_BOX1, tx_data1);
        canTransmit(canREG2, canMESSAGE_BOX2, tx_data2);
        canTransmit(canREG2, canMESSAGE_BOX3, tx_data3);
        canTransmit(canREG2, canMESSAGE_BOX4, tx_data4);
        canTransmit(canREG2, canMESSAGE_BOX5, tx_data5);
        canTransmit(canREG2, canMESSAGE_BOX6, tx_data6);
        canTransmit(canREG2, canMESSAGE_BOX7, tx_data7);
    //    canTransmit(canREG2, canMESSAGE_BOX2, tx_data8);
    }
    Sci_ObcData1_Send()
    {
        union unOBCTXDATA2  ObcTxData2 = {0};
            int j1;
        ObcTxData2.ObcTxWord2.OBC_CONTROL = 0x001;
        ObcTxData2.ObcTxWord2.OBC_REF_V_H = 3000/256;
        ObcTxData2.ObcTxWord2.OBC_REF_V_L = 3000%256;
        for(j1 = 0; j1 < 3; j1++)
        {
            sci_tx_data[j1] = ObcTxData2.ObcTxByte2.SCIByteTemp[j1];
        }
        sciSend(scilinREG,3,sci_tx_data);
    }
    
    void dmaConfigCtrlPacket(uint32 sadd,uint32 dadd,uint32 dsize)
    {
      g_dmaCTRLPKT.SADD      = sadd;              /* source address             */
      g_dmaCTRLPKT.DADD      = dadd;              /* destination  address       */
      g_dmaCTRLPKT.CHCTRL    = 0;                 /* channel control            */
      g_dmaCTRLPKT.FRCNT     = dsize;                 /* frame count                */
      g_dmaCTRLPKT.ELCNT     = 1;             /* element count              */
      g_dmaCTRLPKT.ELDOFFSET = 0;                 /* element destination offset */
      g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element destination offset */
      g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
      g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame destination offset   */
      g_dmaCTRLPKT.PORTASGN  = 4;                 /* port b                     */
      g_dmaCTRLPKT.RDSIZE    = ACCESS_8_BIT;     /* read size                  */
      g_dmaCTRLPKT.WRSIZE    = ACCESS_8_BIT;     /* write size                 */
      g_dmaCTRLPKT.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
    //  g_dmaCTRLPKT.ADDMODERD = ADDR_INC1;         /* address mode read          */
      g_dmaCTRLPKT.ADDMODERD = ADDR_FIXED;         /* address mode read          */
      g_dmaCTRLPKT.ADDMODEWR = ADDR_INC1;       /* address mode write         */
      g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
    }
    
    
    /* USER CODE END */

    Thanks and regards,

    Cherry

  • Hi Jagadish,


    I don't understand the working method mentioned by the customer

    While if using the scireceivebyte feature in SCI to store Rx of sci in data1 and also generate a request request from DMA, place data1 in data, the DMA is able to working properly.

    Please let me clarify:

    The DMA mechanism is to move the contents of address A to address B, is this correct?

    The customer had previously mistakenly thought that the hardware request had not been sent, so they used the receiving function of SCI to get the communication result value and store it in array data1. The CH0 channel conversion is triggered by software trigger after the read is complete (when the conversion is passed from array data1 to data) and the data array is found to be getting the number in data1 correctly, which indicates that the DMA is configured correctly. The software trigger was then modified to the SCI hardware trigger and the correct result was also obtained.

    However, if the source address is changed to the RD register of scilinReg, most of the DMA results received are zero.

    Thanks and regards,

    Cherry

  • Hi Cherry,

    I noticed the one mistakes in customer code,

    The customer defined "SCI_RX_ADDR" as "((uint32_t)(&(scilinREG->RD)))", this will work only when system is configured as little endian. If system configured in Big endian then it should not be the RX Address and it should be added by 3, so better to configure as below

    #if ((__little_endian__ == 1) || (__LITTLE_ENDIAN__ == 1))

    #define SCI_RX_ADDR ((uint32_t)(&(sciREG->RD)))

    #else

    #define SCI_RX_ADDR ((uint32_t)(&(sciREG->RD)) + 3)

    #endif

    I guess now the system is operating in big endian, that is why the customer is reading all zeros. You can find the same thing in our other devices SCI DMA examples as well. This is the primary reason i am suspecting as root cause.


    --

    Thanks,
    Jagadish.