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.

[参考译文] TMS320F280041C:FSI - USER_DATA 和缓冲区与预期内容不匹配

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1207387/tms320f280041c-fsi---user_data-and-buffer-do-not-match-expected-content

器件型号:TMS320F280041C

您好!

我正在使用 FSI 在具有 F280041C DSP (使用 LaunchPad)的应用中同时执行两项操作:

-同步两个 F280041C 微控制器的 ePWM

-在 微控制器之间发送数据

我执行此操作的方式(在握手过程之后)如下:

-在"主"设备中,我将一个 EPWM 设置为外部触发源,以特定频率触发 ping 帧传输。 "Slave" DSP 将使用此 ping 来同步 PWM。 当应用程序想要向"保存"发送数据时、禁用外部 Ping 传输、然后启用软件传输。 Buffer 和 USER_DATA 填充自定义数据、然后开始传输。 传输完成后、再次启用外部 Ping 传输。

在"从"设备中,我将 CLB 模块设置为在收到 ping 帧时自动发回该帧(正如关于 PWM 同步的 TI 示例所解释的那样)。 与我在"主"器件中执行的操作类似、如果应用程序想要发送数据、则会禁用外部 Ping 传输、然后启用软件传输。 当软件传输完成时、外部传输再次使能。

要解释自定义 接收数据帧(在主器件或从器件中)、我要做的是检查 USER_DATA 值、然后根据此值调用不同的函数。  

现在我解释一下我所面临的问题。 通常、握手过程会顺利进行、两个电路板能够同步其 PWM。 我还能够 在它们之间成功发送数据、但是 其他方面 中,user_data 内容和缓冲区内容与我的预期不匹配。 让我举一个例子:

当 USER_DATA 为0时、我希望缓冲区内容全部为0x0000;当 USER_DATA 为1时、我希望缓冲区内容全部为0xAAAA。 但是、有时我会收到 值为1的 USER_DATA、而缓冲区内容全部为零、反之亦然。 基本上、似乎 RX 子模块正在读取 USER_DATA 或缓冲寄存器的旧信息。 但我知道(根据我的应用程序代码)不可能为这些寄存器提供错误的值。 那么、我认为这与 FSI 的 TX/RX 模块的仲裁有关。

下面是我在"编写"函数中执行的操作的代码片段:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static int fsi__write(struct fsi_f *f)
{
/* Set software trigger mode */
FSI_setTxStartMode(FSITXA_BASE, FSI_TX_START_FRAME_CTRL);
FSI_disableRxPingWatchdog(FSIRXA_BASE);
FSI_disableTxExtPingTrigger(FSITXA_BASE);
FSI_setTxFrameType(FSITXA_BASE, FSI_FRAME_TYPE_NWORD_DATA);
/* Fill USER_DATA and BUFFER */
FSI_setTxUserDefinedData(FSITXA_BASE,f->id);
FSI_writeTxBuffer(FSITXA_BASE,f->data,16U,0U);
/* Start transmission */
FSI_clearTxEvents(FSITXA_BASE, FSI_TX_EVT_FRAME_DONE); // Clear previous FRAME_DONE flags
FSI_startTxTransmit(FSITXA_BASE);
/* Wait until the data frame is sent */
fsi__wait(FSI_TX_EVT_FRAME_DONE);
/* Enable Ping Watchdog with 1.5 seconds of timeout, assuming 100 MHz SYSCLK*/
FSI_setRxPingTimeoutMode(FSIRXA_BASE,FSI_PINGTIMEOUT_ON_HWINIT_PING_FRAME);
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

下面是我在 "读取"函数中执行的操作的代码片段

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
static int fsi__read(struct fsi_f *f)
{
uint16_t rxFlags;
uint16_t receivedWords;
/* Read RX Event flags */
rxFlags = FSI_getRxEventStatus(FSIRXA_BASE);
/* Return in case of CRC error */
if(rxFlags & (FSI_RX_EVT_CRC_ERR)){
FSI_clearRxEvents(FSITXA_BASE, FSI_RX_EVT_CRC_ERR);
return 0;
}
/* If received data frame, and there are 16 words, read its content */
if(rxFlags & (FSI_RX_EVT_DATA_FRAME | FSI_RX_EVT_FRAME_DONE) ){
receivedWords = FSI_getRxWordCount(FSIRXA_BASE);
if(receivedWords == 16){
FSI_clearRxEvents(FSITXA_BASE, (FSI_RX_EVT_DATA_FRAME | FSI_RX_EVT_FRAME_DONE));
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

 

有什么可能是我做错的事情吗? 我认为某处可能存在某种竞争条件、因为我正在外部触发器与软件触发器或类似的东西之间切换...

此代码不会在任何中断内运行、仅供参考。

如果您需要对我的问题进行更好的解释、我们将非常感谢您提供任何帮助、并告诉我。

此致。

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

    尊敬的 Jorge:

    我想这个问题是在事情的传输方面,与如何/何时填充您的'f->data'有关。 旧数据可能正在被使用。

    您能否检查代码'f->data'的定义位置? 在开始 FSI 传输之前、您需要确保已对其进行设置。

    此致!

    Kevin 老师

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

    Kevin 老师好!

    感谢您的回答。 在调用 FSI_WRITE 函数之前填充/设置 f->data 缓冲区、包括任何中断之外的所有内容。 因此,一定要正确地更新 f->data。  

    实际上、我做了一个实验、并没有在 user_data 寄存器中发送 f->id、而是将该值作为标准数据缓冲区的一部分发送(我在最后一个字中输入 f->id)。 如果我这样做,接收到的 f->id 和 f->data 之间永远不会有差异。 这种方法的唯一问题是缓冲区的一个字显然是"浪费"。

    我不知道这是否给你任何提示,我可能会做错什么。

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

    尊敬的 Jorge:

    感谢您的回答。 在调用 FSI_WRITE 函数之前填充/设置 f->data 缓冲区、包括任何中断之外的所有内容。 因此,一定要正确地更新 f->data。  [/报价]

    没关系。 f->id 是同时设置的?

    实际上,我做了一个实验,我没有在 user_data 寄存器中发送 f->id,而是将该值作为标准数据缓冲区的一部分发送(我在最后一个字中输入 f->id)。 如果我这样做,接收到的 f->id 和 f->data 之间永远不会有差异。 这种方法的唯一问题是缓冲区的一个字显然是"浪费"。

    这很奇怪。 在这种情况下、您是否曾收到过错误的数据? 可能会连续两次读取同一接收到的数据?

    您在项目属性中设置了什么优化? 我想如果在 TX 和 RX 端都关闭优化、如果仍然看到原始问题、会不会有问题。

    此致!

    Kevin 老师

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

    尊敬的 Kevin、再次感谢您的支持。

    应该可以。 F->id 同时设置?

    正确,f->id 和 f->data 都是在调用我的 FSI_WRITE ()函数之前设置的。

    [报价 userid="315587" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1207387/tms320f280041c-fsi---user_data-and-buffer-do-not-match-expected-content/4556284 #4556284"]在这种情况下,您是否曾收到错误的数据? 可能连续两次读取同一接收到的数据?

    通过将 f->id 发送为缓冲区的最后一个字这一解决方法,到目前为止,f->id 和预期的 f->data 之间从未有过差异。 实际上、此测试已经运行了3天24小时、没有任何问题。 我没有检查是否连续两次收到相同的数据(但 f->id 仍与 f->data 保持一致)。 我将再次检查是否发生了这种情况。

    您在项目属性中设置了什么优化?

    对于两侧、我一直在使用优化级别0 (-O0)和--opt_for_speed=2运行代码

    此致、

    豪尔赫。

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

    尊敬的 Jorge:

    我没有检查的是,我连续两次收到相同的数据(但 f->id 仍然与 f->data 一致)。 我将再次检查是否发生这种情况。

    谢谢、这可以检查在某个时刻是否传输/接收了旧数据。

    对于两端,我一直在运行优化级别为0的代码(-O0)和--opt_for_speed=2

    好的、这就排除了优化不会导致任何类似的潜在怪异行为。

    我认为某处可能存在某种比赛条件,因为我正在切换外部触发器和软件触发器或类似的东西...

    您能否进一步说明您是如何利用触发器启动 FSI 传输的? 您提到了 SW 和 ext 触发器之间的切换。

    此致!

    Kevin 老师

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

    Kevin 老师好!

    您能否进一步解释您是如何利用触发器启动 FSI 传输的? 您提到在 SW 和外部触发器之间切换[/报价]

    当然可以。

    在器件 A (假设主器件)中、我将 PWM 设置为约4.8KHz 的频率、这是 ping 消息的外部触发信号。 主机还希望从从机处接收 ping 消息、因此我设置了 ping 看门狗。 就像这样、主器件和从器件都可以知道通信是否中断。

    在器件 B (从端)中、我已经按照中的说明对 CLB 进行了编程  将快速串行接口(FSI)用于应用中的多个器件(修订版 E)(第7.1.3节)。 这意味着每当从器件收到 ping 消息时、它都会将该消息转发回主器件。 从器件也激活了 Ping 看门狗。 因此、 CLB 配置为在接收到 Ping 帧时跳闸 EPWM XBAR TRIP_5、而此 TRIP_5用作 FSI 模块中的外部触发器。

    通常、主设备和从设备只能相互发送和接收这些 ping 帧。 但是、当应用程序需要发送一些数据(主机或从机)时、必须停止自动 Ping 发送过程、通过软件触发器发送数据、然后恢复自动 Ping 发送过程。

    在这段代码(在我的 FSI_WRITE ()函数的开头调用)中,我停止自动 ping 传输,停止 ping 看门狗,并启用软件传输:

    Fullscreen
    1
    2
    3
    4
    FSI_setTxStartMode(FSITXA_BASE, FSI_TX_START_FRAME_CTRL);
    FSI_disableRxPingWatchdog(FSIRXA_BASE);
    FSI_disableTxExtPingTrigger(FSITXA_BASE);
    FSI_setTxFrameType(FSITXA_BASE, FSI_FRAME_TYPE_NWORD_DATA);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    然后、填充缓冲区和用户数据字段、触发软件传输。 当软件传输完成时(通过检查 TX_EVT_FRAME_DONE 标志)、然后我重新启用自动 ping 传输:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    /* Enable Ping Watchdog with 1.5 seconds of timeout, assuming 100 MHz SYSCLK*/
    FSI_setRxPingTimeoutMode(FSIRXA_BASE,FSI_PINGTIMEOUT_ON_HWINIT_PING_FRAME);
    FSI_enableRxPingWatchdog(FSIRXA_BASE,TIMEOUT_WATCHDOG);
    /* Enable ping trigger*/
    FSI_setTxPingTag(FSITXA_BASE, FSI_FRAME_TAG1);
    FSI_setTxFrameType(FSITXA_BASE, FSI_FRAME_TYPE_PING);
    FSI_enableTxExtPingTrigger(FSITXA_BASE, priv->trg_src);
    FSI_setTxStartMode(FSITXA_BASE, FSI_TX_START_EXT_TRIG);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    这些代码块在两个器件(主器件和从器件)中是相同的。 唯一的区别是外部触发源。

    我希望这能进一步澄清这一过程

    此致、

    豪尔赫。

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

    尊敬的 Jorge:

    感谢您的讲解。 我觉得您实施的流程很合理。

    我曾想、如果您完全禁用 ping 帧触发/看门狗、而只是继续进行数据帧通信、是否会发生该数据字/ USER_DATA 不匹配? 您之前提到过、如果"外部触发器和软件触发器之间的切换"以某种方式导致这一点、这可能是一个需要检查的测试。

    如果您对此进行了测试、但没有看到问题、我想知道启用/禁用触发的 ping 帧的软件序列是否有一定的效果。

    此致!

    Kevin 老师

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

    尊敬的 Kevin:

    再次感谢您的回答。  

    我已经运行了一个测试、其中我禁用了自动 Ping 传输。 基本上、两个器件在握手之后执行的唯一操作是使用软件触发器发送数据帧。 这是禁用自动 ping 传输后的 FSI_WRITE ()函数:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    static int fsi__write(struct fsi_f *f)
    {
    /* Fill USER_DATA and BUFFER */
    FSI_setTxUserDefinedData(FSITXA_BASE,f->id);
    FSI_writeTxBuffer(FSITXA_BASE,f->data,16U,0U);
    /* Start transmission */
    FSI_clearTxEvents(FSITXA_BASE, FSI_TX_EVT_FRAME_DONE); // Clear previous FRAME_DONE flags
    FSI_startTxTransmit(FSITXA_BASE);
    /* Wait until the data frame is sent */
    fsi__wait(FSI_TX_EVT_FRAME_DONE);
    return 1;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    不过、即使在执行此操作之后、在 USER_DATA 和缓冲区之间仍然会出现不相应的数据。 所以、看起来这个测试会排除这是通过从自动 ping 传输切换到软件触发的数据传输而产生的。

    您是否有任何其他想法可能会导致出现这种情况? 或者向我指出我可以尝试的方向或测试?

    再次感谢大家、此致、

    豪尔赫。

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

    尊敬的 Jorge:

    好的、我只能认为它与发送或接收端的软件定序有关。 您是否愿意与我共享您的 FSI 代码以尝试重新生成它? 如果您愿意、可以通过添加我作为朋友(即首先请求友谊)在论坛之外与我分享。

    此致!

    Kevin 老师

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

    感谢 Kevin:

    我添加了您作为朋友、并将相关代码片段发送给了您。 如果您有任何其他需要、请告诉我。

    此致、

    豪尔赫。

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

    尊敬的 Jorge:

    很抱歉耽误了时间,上周出差。

    我收到了您的消息和代码 OK。 我将在本周向您介绍最新情况、并告诉您我是否有任何问题/结论。 对于任何特定于您的代码的内容、让讨论保持脱机状态。

    此致!

    Kevin 老师

x 出现错误。请重试或与管理员联系。