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.

[参考译文] TMS320F28376S:upp 数据接收问题

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/719130/tms320f28376s-upp-data-reception-problem

器件型号:TMS320F28376S
Thread 中讨论的其他器件:controlSUITE

尊敬的社区:

通过 UPP 总线从 Xilinx FPGA 接收数据时遇到问题。 我按照  18页 www.ti.com/.../sprugj5b.pdf 中的说明对协议进行了编程。

很遗憾、我找不到任何有关时序的信息。 该文件仅指出:

-"默认情况下、其他信号在时钟的上升沿对齐"  

-"时钟的有效边沿应始终略早于其他 uPP 信号的转换。"

这是 FPGA 的仿真输出、具有时钟启动使能 (上图)和8位数据 (下图):

我正在尝试在1行和1窗口中传输8个字节的数据。 时钟频率为11MHz。

C2000上的代码基于针对 UPP 接收的 controlSUITE 示例。 如上所示实现协议后、控制器不会触发中断。 但是、在这之前、我尝试在时钟的下降沿对齐信号、从而能够生成 OOW (窗口结束)中断。  

问题是、当我分析地址"uPP_RX_MSGRAM_ADDR"(0x6E00)处的存储器时、似乎我只接收到3个字节:D0、D2和 D4。  

我现在的问题是:

  • 当我使用 UPP 文档中规定的时间时、为什么我不会收到任何信息?
  • 为什么 UPP 消息 RAM 中只有3个字节(从 byte_CNT 中指定的6个字节开始)并且它触发了 OOW 中断?
  • "UppRegs.CHIDESC0 = 0x7000;"有何影响? 我希望传入的数据存储在该地址、但该存储器始终为空。

 

如果有任何建议,我会很感激!

此致、Josh

#include "F28x_Project.h"
#include "F2837xS_upp_defines.h"

//
定义
//
#define LINE_CNT 1
#define byte_CNT 6
#define WIN_CNT 1
#define WIN_BYTE_CNT 6
#define WIN_WORD_CNT 3

//
全局
//
volatile long int 勘误表= 0;
volatile long int OOW_IN_cnt = 0;
volatile long int EOL = 0;
volatile long int Rdr = 0;
volatile Copyint RxMsgRam = 0;
volatile long Dt = 0xDt // GS0 RAM

//
函数原型
//
extern void InitUpp1Gpio (void);
extern void SoftResetUpp (void);
interrupt void local_UPPA_ISR (void);

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

//
初始化系统控制
//
InitSysCtrl ();






//禁用 eCPU 中断/中断


IER = 0x0000;
IFR = 0x0000;
EDIS;

InitPieVectTable ();

EALLOW;
PieVectTable.UPPA_INT =&LOCAL_UPPA_ISR;

//
//启用中断号8。
//
IER = M_INT8;

//
//为 UPPA 中断启用中断。
//
PieCtrlRegs.PIEIER8.bit.INTx15=1;

//
启用 PIE 和 CPU 级别中断。
//
EnableInterrupts();

//
清除用于存储传入数据包的 RAM。
//
MemCfgRegs.GSxINIT.bit.init_GS0 = 1;
while (MemCfgRegs.GSxINITDONE.bit.INITDONE_GS0 = 0){};

//
发出软复位至 uPP
//
软复位();


InitGpio (INITDONE_GS0 = 0);// GPIO
设置93
(PINU1_LED)
;//输出 UPI_Pinux (GPIO_93);GPIO_Pin) GPIO_PushPull);

//
初始化 UPP1 GPIO
//
InitUpp1Gpio ();

GPIO_WritePin (93、0);

//
为 RX 配置 uPP
//
UppRegs.ifcfg.bit.ENAA = 1; //使用使能信号
uppRegs.ifcfg.bit.STARTA = 1; //使用起始信号
//UppRegs.ifcfg.bit.waita = 1;
UppRegs.CHCTL.bit.MODE = uPP_RX_MODE;//设置 RX。
UppRegs.CHCTL.bit.DRA = uPP_SDR; // SDR 模式

//
//启用 EOL/EOW 中断
//
UppRegs.INTENSET.EOLI = 1;
UppRegs.INTENSET.EOWI = 1;
UppRegs.GINTEN.BIN.GINTEN = 1;

//
启用 uPP 模块
// UppRegs.bit.CESCR.EON.1











;UppCLINESCR.EN.CLINESCn.BIT.BIT.USCMT= 1;// UCCNT_RINCR.INCR.INCR.ENTREN.ENTREN.INESCNT.INTREN.EN.EN.INTREN.BIT.1;// UCLINCR.INESCR.ENTRENTREN.INESCR.EN.IN.IN.INTRENTRENTREN.INTREN.IN.INTREN.IN.INTREN.IN.IN.EN.IN.IN.INTRENTRENTREN.


if (CopyRxMsgRam = 1)
{
if (OOW_INT_cnt%2)
{
对于(i = 0;i < win_word_CNT;i+=2)
{
RdValue =*(uint32 *)(uPP_RX_MSGRAM_ADDR + WIN_WORD_CNT + I);
*(uint32 *) DstAddr = RdValue;
DstAddr = DstAddr + 2;
}
}
其他
{
对于(i = 0;i < win_word_CNT;i+=2)
{
RdValue =*(uint32 *)(uPP_RX_MSGRAM_ADDR + WIN_WORD_CNT + I);
*(uint32 *) DstAddr = RdValue;
DstAddr = DstAddr + 2;
}
}
CopyRxMsgRam = 0;
}


//
//在预期的窗口计数完成后禁用 uPP 以停止传输。
//
UppRegs.PERCTL.bit.PEREN = 0;

//
发出软复位至 uPP。 这将复位 RX 状态机、但为了实现这一点、
//输入时钟(uPP_CLK)应保持运行。
//此处发出复位。
//
SoftResetUpp ();

RdValue = 0;

asm (" ESTOP0");
for (;);
}

//
// local_UPPA_ISR - UPPA 中断服务例程(ISR)
//
中断 void local_UPPA_ISR (void)
{
int i;

GPIO_WritePin (93、1);

//
要接收来自此 PIE 组的更多中断,请确认
//此中断
// PieReg_WritePin (93、1);// PeglInpReg


= 0xPegrg0=u.eRegs!
(0xPegrgi+p0=u.u.eRegs)
if (UppRegs.ENINTST.bit.EOWI = 0x1)//检查 OOW 中断标志
{
OOW_INT_cnt++;
CopyRxMsgRam = 1;

//
//启用 EOL 中断
//
UppRegs.INTENSET.bit.EOLI = 1;

//
//清除 OOW 中断的状态
//
UppRegs.ENINTST.ALL = uPP_INT_EOWI;

IF (UppRegs.ENINTST.bit.EOWI!= 0)
{
ErrCount++;
ASM (" ESTOP0");
}
}
if (UppRegs.ENINTST.bit.EOLI = 0x1)//检查 EOL 中断标志
{
EOL _int_cnt++;

//
//清除状态和禁用 EOL 中断
//
UppRegs.ENINTST.ALL = uPP_INT_EOLI;
IF (UppRegs.ENINTST.bit.EOLI!= 0)
{
ErrCount++;
ASM (" ESTOP0");
}
UppRegs.INTENCLR.ALL = uPP_INT_EOLI;
IF (UppRegs.INTENSET.bit.EOLI!= 0)
{
ErrCount++;
ASM (" ESTOP0");
}

//
//初始化下一个窗口传输的通道描述符。
//


if (OOW_INT_cnt < WIN_CNT)
{
if (OOW_INT_cnt%2)
{
if (CopyRxMsgRam = 1)
{
对于(i = 0;i < win_word_CNT;i+=2)
{
RdValue =*(uint32 *)(uPP_RX_MSGRAM_ADDR + I);
*(uint32 *) DstAddr = RdValue;
DstAddr = DstAddr + 2;
}
CopyRxMsgRam = 0;
}
UppRegs.CHIDESC0 = 0x7000;
UppRegs.CHIDESC1.bit.LCNT = LINE_CNT;
UppRegs.CHIDESC1.bit.BCNT = BYTE_CNT;
UppRegs.CHIDESC2.all = byte_CNT;
}
其他
{
if (CopyRxMsgRam = 1)
{
对于(i = 0;i < win_word_CNT;i+=2)
{
RdValue =*(UINT32 *)(uPP_RX_MSGRAM_ADDR +
win_word_CNT + i);
*(uint32 *) DstAddr = RdValue;
DstAddr = DstAddr + 2;
}
CopyRxMsgRam = 0;
}
UppRegs.CHIDESC0 = 0x7000 +(LINE_CNT * BYTE_CNT);
UppRegs.CHIDESC1.bit.LCNT = LINE_CNT;
UppRegs.CHIDESC1.bit.BCNT = BYTE_CNT;
UppRegs.CHIDESC2.all = byte_CNT;
}
}



//
//清除全局中断。
//
RdValue = UppRegs.ENINTST.ALL;
UppRegs.GINTCLR.bit.GINTCLR = 1;
if (UppRegs.GINTFlG.all!= 0x0)
{
ErrCount++;
ASM (" ESTOP0");
}
}

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

    更新:它现在正在运行、即使我不知道为什么... 也许有人有个想法!?

    我将 UPP 配置更改为:

    #define LINE_CNT 1 //每个传输1条线路
    #define BYTE_CNT 每个传输12 // 12字节-> 6字节
    #define WIN_CNT 1 //每次传输1个窗口 

    当 BYTE_CNT 设置为12时、我看到6个字节在"uPP_RX_MSGRAM_ADDR"(0x6E00)处发生变化。  

    我还更改了发送器(FPGA)、以便信号与下降时钟沿对齐、并且有2 (!)个 每个数据字节的时钟相位。

    问: 为什么我必须加倍"一切"才能使它发挥作用?

    此致、Josh

    时钟、 启动、 使能  (上图)和8位 数据  (下图)

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

    Josh、

    我们将对此进行研究。

    此致、

    Vivek Singh

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

    您好、Vivek、  

    如果您能帮助我解决问题、我将不胜感激。 我现在的位置是:

    我终于找到了 UPP (对于我的控制器)的时序图: http://www.ti.com/lit/ds/symlink/tms320f28376s.pdf  第174页、图5-83:

    我仍在通过以下时序从 FPGA 传输6个数据字节:

    从上升时钟沿到其他信号上升沿的延迟为10ns (1个 FPGA 时钟周期)。 此参数和其他参数应符合数据表中的规格(第172页)。

    问题:它始终需要2个传输来触发 OOW/EOL 中断。 UPP 设置现在应正确:

    #define LINE_CNT 1
    #define byte_CNT 6
    #define WIN_CNT 1 

    UppRegs.ifcfg.bit.ENAA = 1; //使用使能信号
    uppRegs.ifcfg.bit.STARTA = 1; //使用启动信号
    uppRegs.CHCTL.bit.mode = uPP_RX_MODE;//设置 RX。
    UppRegs.CHCTL.bit.DRA = uPP_SDR; // SDR 模式 

    如何解决此问题?

    此致、Josh

    完整 C 代码:

    #include "F28x_Project.h"
    #include "F2837xS_upp_defines.h"
    
    //
    定义
    //
    #define LINE_CNT 1
    #define byte_CNT 6
    #define WIN_CNT 1
    
    //
    Globals
    //
    volatile long int ErrCount = 0;
    volatile long int OOW_INT_cnt = 0;
    volatile long int EOL _int_cnt = 0;
    volatile int CopyRxMsgRam = 0;
    volatile long int DstAddr = 0xC000;// GS0 RAM
    
    //
    函数原型//
    
    Softuppin (void)
    ;void 1 (void)
    中断 void local_UPPA_ISR (void);
    
    //
    // Main
    //
    void main (void)
    {
    
    //
    初始化系统控制
    //
    InitSysCtrl ();
    
    DINT;
    
    //
    //初始化 PIE 控制寄存器到其默认状态。
    //默认状态是禁用所有 PIE 中断并
    清除 flaLS //。
    //此函数位于 F2837xS_PIECTRL.c 文件中。
    //
    InitPieCtrl();
    
    //
    禁用 CPU 中断并清除所有 CPU 中断标志:
    //
    EALLOW;
    IER = 0x0000;
    IFR = 0x0000;
    EDIS;
    
    //
    使用指向 shell 中断
    // LService 例程(ISR)的指针初始化 PIE 矢量表。
    //这将填充整个表,即使在
    本示例中未使用中断//也是如此。 这对于调试很有用。
    //可以在 F2837xS_DefaultIsr.c 中找到 shell ISR 例程
    //此函数可在 F2837xS_PieVect.c 中找到
    //
    InitPieVectTable ();
    
    EALLOW;
    PieVectTable.UPPA_INT =&LOCAL_UPPA_ISR;
    
    //
    启用中断号8。
    //
    IER = M_INT8;
    
    //
    //为 UPPA 中断启用中断。
    //
    PieCtrlRegs.PIEIER8.bit.INTx15=1;
    
    //
    启用 PIE 和 CPU 级别中断。
    //
    EnableInterrupts();
    
    //
    清除用于存储传入数据包的 RAM。
    //
    MemCfgRegs.GSxINIT.bit.init_GS0 = 1;
    while (MemCfgRegs.GSxINITDONE.bit.INITDONE_GS0 = 0){};
    
    //
    发出软复位至 uPP
    //
    软复位();
    
    //
    //初始化 GPIO_P93 (
    
    
    PINU1_UPI_0
    );//初始化 GPIO_SetupP93 (GPIO_Pin) GPIO_OUTPUT、GPIO_PushPull);
    
    InitUpp1Gpio ();
    
    GPIO_WritePin (93、0);
    
    
    //
    //为 RX 配置 uPP
    //
    uppRegs.ifcfg.bit.ENAA = 1; //使用使能信号
    uppRegs.ifcfg.bit.STARTA = 1; //使用启动信号
    uppRegs.CHCTL.bit.mode = uPP_RX_MODE;//设置 RX。
    UppRegs.CHCTL.bit.DRA = uPP_SDR; // SDR 模式
    
    //
    //启用 EOL/EOW 中断
    //
    UppRegs.INTENSET.EOLI = 1;
    UppRegs.INTENSET.EOWI = 1;
    UppRegs.GINTEN.BIN.GINTEN = 1;
    
    //
    启用 uPP 模块
    // UppRegs.bit.CESCR.EON.1
    
    
    
    
    
    
    
    
    
    
    
    ;UppCLINESCR.EN.CLINESCn.BIT.BIT.USCMT= 1;// UCCNT_RINCR.INCR.INCR.ENTREN.ENTREN.INESCNT.INTREN.EN.EN.INTREN.BIT.1;// UCLINCR.INESCR.ENTRENTREN.INESCR.EN.IN.IN.INTRENTRENTREN.INTREN.IN.INTREN.IN.INTREN.IN.IN.EN.IN.IN.INTRENTRENTREN.
    
    
    //
    ////在完成预期窗口计数后禁用 uPP 停止传输。
    //
    //UppRegs.PERCTL.bit.PEREN = 0;
    
    //
    //发出软复位至 uPP。 这将复位 RX 状态机、但为了实现这一点、
    //输入时钟(uPP_CLK)应保持运行。
    //此处发出复位。
    //
    // softResetUpp ();
    
    }
    
    //
    // local_UPPA_ISR - UPPA 中断服务例程(ISR)
    //
    中断 void local_UPPA_ISR (void)
    {
    
    GPIO_WritePin (93、!GPIO_ReadPin (93));
    
    //
    要接收来自此 PIE 组的更多中断,请确认
    //此中断
    = 0xPGR_0=pInpegrup
    
    
    (0xPGR0=0xPIE8)
    
    if (UppRegs.ENINTST.bit.EOWI = 0x1)//检查 OOW 中断标志
    {
    OOW_INT_cnt++;
    CopyRxMsgRam = 1;
    
    //
    //启用 EOL 中断
    //
    UppRegs.INTENSET.bit.EOLI = 1;
    
    //
    //清除 OOW 中断的状态
    //
    UppRegs.ENINTST.ALL = uPP_INT_EOWI;
    
    IF (UppRegs.ENINTST.bit.EOWI!= 0)
    {
    ErrCount++;
    ASM (" ESTOP0");
    }
    }
    if (UppRegs.ENINTST.bit.EOLI = 0x1)//检查 EOL 中断标志
    {
    EOL _int_cnt++;
    
    //
    //清除状态和禁用 EOL 中断
    //
    UppRegs.ENINTST.ALL = uPP_INT_EOLI;
    IF (UppRegs.ENINTST.bit.EOLI!= 0)
    {
    ErrCount++;
    ASM (" ESTOP0");
    }
    UppRegs.INTENCLR.ALL = uPP_INT_EOLI;
    IF (UppRegs.INTENSET.bit.EOLI!= 0)
    {
    ErrCount++;
    ASM (" ESTOP0");
    }
    
    //
    //初始化下一个窗口传输的通道描述符。
    //
    
    UppRegs.CHIDESC0 = 0x7000;
    UppRegs.CHIDESC1.bit.LCNT = LINE_CNT;
    UppRegs.CHIDESC1.bit.BCNT = BYTE_CNT;
    UppRegs.CHIDESC2.all = byte_CNT;
    
    
    }
    //
    //清除全局中断。
    //
    UppRegs.GINTCLR.bit.GINTCLR = 1;
    if (UppRegs.GINTFlG.all!= 0x0)
    {
    ErrCount++;
    ASM (" ESTOP0");
    }
    }
    

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

    我能够通过在有效传输周期(EN=1)前后添加几个时钟周期以及将要传输的字节数从6更改为8来解决这个问题。 UPP 文件只规定了偶数字节号、但有6个字节不适合我。

    此致、Josh