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

各位前辈:

 近期我在摸索TMS570LS0714的DMA模块,想通过配置DMA完成SCI接收以节约CPU资源。但是我现在碰到了点问题,SCI我使用的是SCI/LIN,当我将DMA的source地址配置为scilinREG-》RD时,我的DMA接收数据全部为零。如果我使用SCI中的scireceivebyte功能将sci的rx存放于data1,并同时产生DMA的request请求,将data1存放进data中,这时DMA可以正常工作。恳请各位前辈指导一下,为何直接使用sciRd作为源地址不可行,或者给我一些建议,感谢各位!

  • 您好我们已收到您的问题并升级到英文论坛寻求帮助,如有答复将尽快回复您。谢谢!

  • 如果我使用SCI中的scireceivebyte功能将sci的rx存放于data1,并同时产生DMA的request请求,将data1存放进data中,这时DMA可以正常工作

    您好,能麻烦您重新描述下这句话吗?

    此外为了更好地解决您的问题,您能否提供以下信息:

    1. DMA 使用的触发源是什么?
    2. 请问您是否使用使能了 DMA 的多缓冲 SCI 模式? 如果是的话,在 SCIFORMAT 寄存器中配置的长度值是多少?
    3. 您的代码是否方便提供下?
  • 1.DMA的触发源是 SCI的RX; 2.并未使能DMA的多缓冲模式;3.部分代码如下:

    /** @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 */
    

  • 好的感谢您提供的信息。

    此外您所提到的以下信息,能否重新阐述一下工作机制?我们没太理解。

    如果我使用SCI中的scireceivebyte功能将sci的rx存放于data1,并同时产生DMA的request请求,将data1存放进data中,这时DMA可以正常工作。
  • DMA在我看来就是把地址A的东西搬到地址B去,之前我以为是我的硬件请求没有发送出来,所以我使用了SCI的接收函数获取通讯结果值并将其存放在数组data1中,在完成读取之后 我使用软件触发方式触发CH0通道转换(此时转换是从数组data1传递到data中),发现data数组能正常得到data1中的数,说明我有关DMA的配置是正确的的。之后我将软件触发方式修改为SCI硬件触发,依旧得到了正确的结果。但是如果将source address更换为scilinReg的RD寄存器,收到的数据就有问题,大部分DMA结果都为零。

  • 好的收到哈,我们反馈给工程师看下。

  • 您好,

    您给出的代码中有一个错误,

    您将"SCI_RX_ADDR"定义为"((uint32_t)(&(scilinREG->RD))",但这将仅在系统配置为小端字节序时有效。 如果系统在大端字节序中配置,那么不应是 RX 地址,而应将其添加3,因此最好按如下方式进行配置:

    #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

    系统现在应该是在以大端字节序运行,这应该就是读取出来都为零的原因。 您也可以在我们的其他器件 SCI DMA 示例中找到相同的东西。 

  • 感谢各位工程师的帮助,刚刚尝试了一下,确实是大小端的问题!