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:DMA 同时发送和接收

Guru**** 2458720 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1124712/tms570lc4357-dma-send-and-receive-simultaneously

器件型号:TMS570LC4357

您好!

我想使用 SCI 和 DMA 与外部 IC 通信、即写入 IC 和从 IC 读取。

当我 启用 SCI 回送时、我能够写入数据并读回相同的数据。

下面是代码

/** @file HL_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 "HL_sys_common.h"

/* USER CODE BEGIN (1) */
#include "HL_system.h"
#include "HL_sci.h"
#include "HL_sys_pmu.h"
#include "HL_sys_dma.h"
#include "HL_sys_vim.h"
/* 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) */
#define size                20U

#define SCI2_TX_ADDR        ((uint32_t)(&(sciREG2->TD)) + 3)
#define SCI2_RX_ADDR        ((uint32_t)(&(sciREG2->RD)) + 3)

#define DMA_SCI2_TX_CH      DMA_REQ41
#define DMA_SCI2_RX_CH      DMA_REQ40

#define SCI_SET_TX_DMA      (1<<16)
#define SCI_SET_RX_DMA      (1<<17)
#define SCI_SET_RX_DMA_ALL  (1<<18)

/* dma control packet configuration stack */
uint32 DMA_Comp_Flag;

uint32 DMA_TX_Counter;
uint32 DMA_RX_Counter;

#pragma SET_DATA_SECTION(".sharedRAM")
uint8 TX_Data[size] = {0};
uint8 RX_Data[size] = {0};
#pragma SET_DATA_SECTION()

int main(void);
void DMA_Init(void);
void scidmaInit();
void scidmaSend();
void scidmaReceive();
void Update_DMA_Comp_Flag(uint32 channel);

/* USER CODE END */

int main(void)
{
/* USER CODE BEGIN (3) */
    uint32 IDLECOUNT = 0;

    _enable_IRQ_interrupt_();

    sciInit();

    sciEnableLoopback(sciREG2, Digital_Lbk);

    /* Enable DMA */
    dmaEnable();

    /* Init SCI2 for DMA transfers */
    DMA_Init();

    /* Enable Interrupt after reception of data */
    dmaEnableInterrupt(DMA_CH0, BTC, DMA_INTA);
    scidmaSend();

    dmaEnableInterrupt(DMA_CH1, BTC, DMA_INTA);
    scidmaReceive();

    /* Wait for the DMA interrupt ISR to set the Flag   */
    while(DMA_Comp_Flag != 0x55AAD09E){
        IDLECOUNT++;
    }

    while (1);       
/* USER CODE END */

    //return 0;
}


/* USER CODE BEGIN (4) */
void DMA_Init(void)
{
    /* Init SCI3 for DMA transfers */
    scidmaInit();
}

/** @fn void scidmaInit(short mode)
*   @brief Initialize the SCI and DMA to tranfer SCI data via DMA
*   @note This function configures the SCI to trigger a DMA request when the SCI TX is complete.
*/
void scidmaInit()
{
    dmaReqAssign(DMA_CH0, DMA_SCI2_TX_CH);
    dmaReqAssign(DMA_CH1, DMA_SCI2_RX_CH);

    /* Reset the Flag */
    DMA_Comp_Flag = 0x55AAD09E;

    /* Channel 40 - Enable the VIM channel in HalCoGen to include dmaBTCAInterrupt function */
    vimChannelMap(40, 40, &dmaBTCAInterrupt);

    /* Enable VIM DMA BTCA interrupt to CPU on SCI2 transfer complete */
    vimEnableInterrupt(40, SYS_IRQ);

} /* scidmaInit */


/** @fn void scidmaSend(char *source_address, short mode)
*   @brief Initialize the SCI and DMA to tranfer SCI data via DMA
*   @note This function configures the SCI to trigger a DMA request when the SCI TX is complete.
*
*   This function configures the DMA in single buffer or multibuffer mode.
*   In single buffer mode (0) the DMA moves each Byte to the SCI tranmit register when request is set.
*   In multi buffer mode (1)  the DMA moves 4 Bytes to the SCI transmit buffer when the request is set.
*/
void scidmaSend()
{
    g_dmaCTRL g_dmaCTRLPKT;
    int i;

    for(i=0; i<size; i++)
    {
        TX_Data[i] = i + 1;
    }

    /* Wait for the DMA to complete any existing transfers */
    while(DMA_Comp_Flag != 0x55AAD09E);

    /* Reset the Flag to not Done*/
    DMA_Comp_Flag = ~0x55AAD09E;

    /* - Populate dma control packets structure */
    g_dmaCTRLPKT.CHCTRL    = 0;                 /* channel control            */
    g_dmaCTRLPKT.ELCNT     = 1;                 /* element count              */
    g_dmaCTRLPKT.ELDOFFSET = 0;                 /* element destination offset */
    g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element source offset      */
    g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
    g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame source offset        */
    g_dmaCTRLPKT.PORTASGN  = PORTA_READ_PORTB_WRITE;    /* PORTA_READ_PORTB_WRITE */
    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.ADDMODEWR = ADDR_FIXED;        /* address mode write         */
    g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_OFF;      /* autoinit                   */
    g_dmaCTRLPKT.SADD      = (uint32)TX_Data;
    g_dmaCTRLPKT.DADD      = SCI2_TX_ADDR;
    g_dmaCTRLPKT.FRCNT     = size;

    /* - setting dma control packets for transmit */
    dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT);

    /* - setting the dma channel to trigger on h/w request */
    dmaSetChEnable(DMA_CH0, DMA_HW);

    /* Enable TX DMA */
    sciREG2->SETINT = SCI_SET_TX_DMA;

} /* scidmaSend */

/** @fn void scidmaReceive(char *source_address)
*/
void scidmaReceive()
{
    g_dmaCTRL g_dmaCTRLPKT;

    /* Wait for the DMA to complete any existing transfers */
    while(DMA_Comp_Flag != 0x55AAD09E);

    /* Reset the Flag to not Done*/
    DMA_Comp_Flag = ~0x55AAD09E;

    /* - Populate dma control packets structure */
    g_dmaCTRLPKT.CHCTRL    = 0;                 /* channel control            */
    g_dmaCTRLPKT.ELCNT     = 1;                 /* element count              */
    g_dmaCTRLPKT.ELDOFFSET = 0;                 /* element destination offset */
    g_dmaCTRLPKT.ELSOFFSET = 0;                 /* element source offset      */
    g_dmaCTRLPKT.FRDOFFSET = 0;                 /* frame destination offset   */
    g_dmaCTRLPKT.FRSOFFSET = 0;                 /* frame source offset        */
    g_dmaCTRLPKT.PORTASGN  = PORTB_READ_PORTA_WRITE;    /* PORTB_READ_PORTA_WRITE */
    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_FIXED;         /* address mode read   */
    g_dmaCTRLPKT.ADDMODEWR = ADDR_INC1;        /* address mode write    */
    g_dmaCTRLPKT.AUTOINIT  = AUTOINIT_OFF;      /* autoinit */
    g_dmaCTRLPKT.SADD      = SCI2_RX_ADDR;
    g_dmaCTRLPKT.DADD      = (uint32)RX_Data;
    g_dmaCTRLPKT.FRCNT     = size;

    /* - setting dma control packets for transmit */
    dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT);

    /* - setting the dma channel to trigger on h/w request */
    dmaSetChEnable(DMA_CH1, DMA_HW);

    sciEnableNotification(sciREG2, SCI_RX_INT);
    /* Enable RX DMA */
    sciREG2->SETINT |= SCI_SET_RX_DMA;

} /* scidmaReceive */

/** @fn void Update_DMA_Comp_Flag()
*   @brief Switch the DMA complete flag to done and disable the SCI2 TX DMA interrupt
*   @note This function needs to be called by dmaGroupANotification in notification.c
*/
void Update_DMA_Comp_Flag(uint32 channel)
{
    /* Set the Flag to Done*/
    DMA_Comp_Flag = 0x55AAD09E;

    if(channel == DMA_CH0)
    {
        /* Disable TX DMA Interrupt */
        sciREG2->CLEARINT = SCI_SET_TX_DMA;
        DMA_TX_Counter++;
    }
    else if(channel == DMA_CH1)
    {
        /* Disable RX DMA Interrupt */
        sciREG2->CLEARINT = SCI_SET_RX_DMA;
        DMA_RX_Counter++;
    }
}

/* USER CODE END */

但是、当我在没有回送的情况下回读时、这种情况不起作用。

在示例中、我也可以看到"SCI 回送被使用"或"Tx 和 Rx 在不同的硬件 SCI 单元上完成"。

无法同时使用相同的硬件进行发送和接收??  

此致

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    [引用 userid="505316" URL"~/support/microcontrollers/arm-based microcontrollers-group/arm-based microcontrollers/f/arm-based microcontrollers-forume/1124712/tms570lc4357-dma-send-and-receive-simulty"]但如果我读回时没有回送,也不起作用。

    如果启用了环回、SCIRX 引脚将在内部连接到 SCITX 引脚。 如果未启用回送、SCI TXed 数据不会路由到 SCI RX 引脚。 禁用环回时、您是否向 SCI2 RX 端口发送了任何数据? 您可以使用蓝色线从外部连接 SCI2 TX 引脚和 SCI2 RX 引脚来执行测试。  

    SCI RX 和 TX 是双缓冲的。 接收器和发送器可在全双工模式下独立且同步运行。  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    [~ userid="45190" url="支持/微控制器/基于 ARM 的微控制器组/基于 ARM 的微控制器/f/基于 ARM 的微控制器论坛/1124712/tms570lc4357-dma-send-and-receive-simult/4171083#4171083]\n 如果启用了环回、SCIRX 引脚内部连接至 ITX 引脚。 如果未启用回送、SCI TXed 数据不会路由到 SCI RX 引脚。 禁用环回时、您是否向 SCI2 RX 端口发送了任何数据? 您可以使用蓝色线从外部连接 SCI2 TX 引脚和 SCI2 RX 引脚来执行测试。  [/报价]

    是的、我使用跳线从外部连接了 TX 引脚和 RX 引脚。 下面随附了软件。

    e2e.ti.com/.../01_5F00_DMA_5F00_Test.rar

    1、在回送启用的情况下、软件运行正常(仅在启用此线路的情况下)(如下面的 PIC 所示)、否则回送不起作用。

    2.如果 sciEnableLoopback 被禁用并且 SCI2 TX 和 RX 被外部连接。 软件不工作。

    您能不能告诉我实施可能会出现什么问题。 提前感谢。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果使用 TI HDK、SCI2信号不会路由到 J10连接器。 HDK 最初是为 TMS570LS31x 而不是 TMS570LC43x 设计的、因此 SCI 信号不会路由到连接器。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢你的答复。 我不使用 HDK、而是使用我们的定制板并从外部连接 SCI2 TX 和 RX。

    您能否从您的角度检查硬件上的代码?

    此致

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Sakti、

    除函数调用顺序外,代码看起来正常: scidmaReceive()和 scidmaSend();

    scidmaReceive();应首先调用,然后调用 scidmaSend();

    如果 首先调用 scidmaSend(),则可能无法正确接收第一个字符。

    我稍后将找到一个硬件来测试您的代码。