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.

[参考译文] TMS320F28388D:关于28388D CPU2中的 SCI 通信

Guru**** 2562340 points
Other Parts Discussed in Thread: C2000WARE, SYSCONFIG

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1222788/tms320f28388d-about-sci-communications-in-28388d-cpu2

器件型号:TMS320F28388D
主题中讨论的其他器件:C2000WARESysConfig

工程师、您好、我最近从事的是28388D 内核间的通信、我实现的函数是通过 IPC 从 CPU1向 CPU2发送一组数据、然后 CPU2将使用 SCIB 将这组数据发送出去、 但目前、当通过 SCIB 发送数据时、存在一个问题、 而且无法成功发送、我将代码发布到了 CPU1和 CPU2中、我希望您可以将代码发布到 CPU1和 CPU2中、并希望您可以帮助我发现问题。

CPU1中的加载程序代码

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Defines
//
#define IPC_CMD_READ_MEM   0x1001
#define IPC_CMD_RESP       0x2001

#define TEST_PASS          0x5555
#define TEST_FAIL          0xAAAA


#pragma DATA_SECTION(readData, "MSGRAM_CPU1_TO_CPU2")
char sdData[10]={1,2,3,4,5,6,7,8,9,'\n'};
uint32_t readData[10]={0};
uint32_t pass;

//
// Main
//
void main(void)
{
    int i;

    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Boot CPU2 core
    //
#ifdef _FLASH
    Device_bootCPU2(BOOTMODE_BOOT_TO_FLASH_SECTOR0);
#else
    Device_bootCPU2(BOOTMODE_BOOT_TO_M0RAM);
#endif

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();
    //
    //set SCIB TX
    //
    GPIO_setPinConfig(DEVICE_GPIO_CFG_SCITXDB);
    GPIO_setDirectionMode(DEVICE_GPIO_PIN_SCITXDB, GPIO_DIR_MODE_OUT);
    GPIO_setPadConfig(DEVICE_GPIO_PIN_SCITXDB, GPIO_PIN_TYPE_STD | GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(DEVICE_GPIO_PIN_SCITXDB, GPIO_QUAL_ASYNC);

    GPIO_setMasterCore(DEVICE_GPIO_PIN_SCITXDB, GPIO_CORE_CPU2);
    GPIO_setMasterCore(DEVICE_GPIO_CFG_SCITXDB, GPIO_CORE_CPU2);
    //
    // Clear any IPC flags if set already
    //
    IPC_clearFlagLtoR(IPC_CPU1_L_CPU2_R, IPC_FLAG_ALL);

    //
    // Synchronize both the cores.
    //
    IPC_sync(IPC_CPU1_L_CPU2_R, IPC_FLAG31);

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // Fill in the data to be sent
    //
    for(i=0; i<10; i++)
    {
        readData[i] = sdData[i];
    }

    //
    // Send a message without message queue
    // Length of the data to be read is passed as data.
    //
    IPC_sendCommand(IPC_CPU1_L_CPU2_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
                    IPC_CMD_READ_MEM, (uint32_t)readData, 10);

    //
    // Wait for acknowledgment
    //
    IPC_waitForAck(IPC_CPU1_L_CPU2_R, IPC_FLAG0);

    //
    // Read response
    //
    if(IPC_getResponse(IPC_CPU1_L_CPU2_R) == TEST_PASS)
    {
        pass = 1;
    }
    else
    {
        pass = 0;
    }

    //
    // End of example. Loop forever
    //
    while(1);
}


//
// End of File
//

放入 CPU2

//
// Included Files
//
#include "driverlib.h"
#include "device.h"

//
// Defines
//
#define IPC_CMD_READ_MEM   0x1001
#define IPC_CMD_RESP       0x2001

#define TEST_PASS          0x5555
#define TEST_FAIL          0xAAAA
//
//Define variables
//
uint32_t recbuf[10]={0};
char recbuf1[10]={0};
//
// Function prototypes
//
__interrupt void IPC_ISR0();

//
// Main
//
void main(void)
{
    int t=0;
    //
    // Initialize device clock and peripherals
    //
    Device_init();

    //
    // Initialize PIE and clear PIE registers. Disables CPU interrupts.
    //
    Interrupt_initModule();

    //
    // Initialize the PIE vector table with pointers to the shell Interrupt
    // Service Routines (ISR).
    //
    Interrupt_initVectorTable();

    //
    // Clear any IPC flags if set already
    //
    IPC_clearFlagLtoR(IPC_CPU2_L_CPU1_R, IPC_FLAG_ALL);

    //
    // Enable IPC interrupts
    //
    IPC_registerInterrupt(IPC_CPU2_L_CPU1_R, IPC_INT0, IPC_ISR0);

    //
    // Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
    //
    EINT;
    ERTM;

    //
    // Synchronize both the cores.
    //
    IPC_sync(IPC_CPU2_L_CPU1_R, IPC_FLAG31);
    //
    //Set SCIB
    //
    SCI_setConfig(SCIB_BASE, DEVICE_LSPCLK_FREQ, 256000, (SCI_CONFIG_WLEN_8 | SCI_CONFIG_STOP_ONE | SCI_CONFIG_PAR_NONE));
    SCI_resetChannels(SCIB_BASE);
    SCI_enableModule(SCIB_BASE);
    SCI_performSoftwareReset(SCIB_BASE);
    //
    // Loop forever. Wait for IPC interrupt
    //

    while(1)
    {
        for(t=0;t<10;t++)
        {
            recbuf1[t]=recbuf[t];
        }
        for(t=0;t<10;t++)
        {
            if(recbuf1[t] == 0)
            {
                continue;
            }
            SCI_writeCharBlockingNonFIFO(SCIB_BASE, recbuf1[t]);
              if(recbuf1[t] == '\n')
            {
                  recbuf1[t] = 0;
                break;
            }
              recbuf1[t] = 0;
        }
    }
}

//
// IPC ISR for Flag 0.
// C28x core sends data without message queue using Flag 0
//
__interrupt void IPC_ISR0()
{
    int i;
    uint32_t command, addr, data;
    bool status = false;

    //
    // Read the command
    //
    IPC_readCommand(IPC_CPU2_L_CPU1_R, IPC_FLAG0, IPC_ADDR_CORRECTION_ENABLE,
                    &command, &addr, &data);

    if(command == IPC_CMD_READ_MEM)
    {
        status = true;

        //
        // Read and compare data
        //
        for(i=0; i<data; i++)
        {
            recbuf[i]=*((uint32_t *)addr + i);
            //if(*((uint32_t *)addr + i) != i)
                //status = false;
        }
    }

    //
    // Send response to C28x core
    //
    if(status)
    {
        IPC_sendResponse(IPC_CPU2_L_CPU1_R, TEST_PASS);
    }
    else
    {
        IPC_sendResponse(IPC_CPU2_L_CPU1_R, TEST_FAIL);
    }

    //
    // Acknowledge the flag
    //
    IPC_ackFlagRtoL(IPC_CPU2_L_CPU1_R, IPC_FLAG0);

    //
    // Acknowledge the PIE interrupt.
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
//
// End of File
//

我已经在器件中定义了以下引脚

#define DEVICE_GPIO_PIN_SCIRXDB 11u // SCIB RX 的 GPIO 编号
#define DEVICE_GPIO_PIN_SCITXDB 10u // SCIB TX 的 GPIO 编号
#define DEVICE_GPIO_CFG_SCIRXDB GPIO_11_SCIB_RX // SCIB RX 的"pinConfig"
#define DEVICE_GPIO_CFG_SCITXDB GPIO_10_SCIB_TX // SCIB TX 的"pinConfig"

非常感谢!

期待您的答复!

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

    您好!

    我没有看到在 CPU1代码中的任何地方将 SCI 模块移交给 CPU2。 您必须将所需模块的所有权移交给 CPU2、以确保正确运行-  

    SYSCTL_selectCPUForPeripheral (SYSCTL_CPUSEL5_SCI、2、SYSCTL_CPUSEL_CPU2);

    此外、我们还提供了一个 C2000Ware 的参考示例和类似的用例。 请您检查一下、以加快开发速度。

    位置: C2000Ware_4_03_00_00\driverlib\f2838x\examples\C28x_dual\sci

    谢谢。

    Aditya.

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

    非常感谢您的答复。
    我的代码确实将相应的 GPIO 发送到 CPU2内核进行控制、如下所示

    GPIO_setMasterCore (DEVICE_GPIO_PIN_SCITXDB、GPIO_CORE_CPU2);
    GPIO_setMasterCore (DEVICE_GPIO_CFG_SCITXDB、GPIO_CORE_CPU2);

    但它不起作用,所以我想问什么原因是缺乏成功

    我还在调试您提到的示例、导入后、会显示三个工程 CCI_ex1_sysconfig _CPU1、CCI_ex1_sysconfig _CPU2和 CCI_ex1_sysconfig _multi。 sci_ex1_sysconfig_multiple 的作用是什么?在烧录程序时是否需要烧录此项目?
    非常感谢!

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

    您好!

    您完成的 GPIO 配置仅针对 GPIO 引脚输出。 SCI 模块本身需要传输到 CPU2内核。 为此、你将必须使用上一次回复中提到的函数。

    我也正在调试您提到的示例,导入后将显示三个项目:ci_ex1_sysgm_cpu1、ci_ex1_sysgm_cpu2和 ci_ex1_sysgm_multi。 sci_ex1_sysconfig _multi 的作用是什么?在刻录程序时我需要刻录此项目吗?

    这个多示例基本上是一个使用 ex1和 ex2作为基础示例的常见示例。 如果您构建 sci_ex1_sysconfig _multiple  示例、它会从根本上构建 ex1和 ex2本身。  SCI_ex1_SysConfig_multi 依赖于 CCI_ex1_SysConfig_CPU1和 CCI_ex1_SysConfig_CPU2  。

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

    非常感谢您的回复、我在我的代码中添加了 SYSCTL_selectCPUForPeripheral (SYSCTL_CPUSEL5_SCI、2、SYSCTL_CPUSEL_CPU2);语句、以启用 CPU2的 SCIB 通信功能

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

    我相信可以解决您的问题。 您能确认吗?

    Aditya.