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.

[参考译文] F28M36P63C2:M3 I2C 模块即使只有一个主器件存在、也会获得 I2C_MASTER_ERR_ARB_Lost 错误

Guru**** 2609955 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/680188/f28m36p63c2-m3-i2c-module-gets-i2c_master_err_arb_lost-errors-even-though-only-one-master-exists

器件型号:F28M36P63C2

 使用 Mware/driverlib 库中的 I2C 模块时、我们偶尔会遇到 I2C_MASTER_ERR_ARB_Lost 错误(v207)。 但是、我们在该总线上只有一个主器件。

MCU 和外设之间有一个 I2C 驱动器(请参阅下面的原理图)、我们添加了该驱动器、因为它们之间存在~1米的长物理距离。 I2C 驱动器的存在是否会导致 MCU 认为在启动事务时仲裁失败? 当我检查 SCL 和 SDA 线路时、它们都保持高电平、这意味着总线是空闲的。 因此、我想知道为什么 MCU 无法获得对总线的控制。

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

    您是否可以尝试移除驱动程序芯片并再次测试? 您可能还需要缩短电缆长度作为第二次测试。
    您在哪里对信号进行范围界定? 您能否将示波器放置在线路的远端、并查看从端的时钟和数据线路之间是否存在任何偏差?
    您能否共享丢失仲裁的帧起始的范围捕获?
    错误是随每次传输而发生还是随机发生?

    我假设驱动器芯片使数据线路保持低电平的时间可能长于 M3_I2C 模块所需的时间、这可能会强制 I2C 失去仲裁。 我将继续看这个。

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

    Mark、

    在短期内不能拆除驱动器芯片、也不能缩短电缆、但下面是我可以收集到的有关现有硬件的一些其他详细信息。

    首先是代码。 这是 I2C 读取函数和

    tf_uint16 I2C:::读取(tf_uint8 addr、tf_uint8 * regptr、tf_uint8 ptrLen、tf_uint8 * data、tf_uint16 dataLen)
    {
    unsigned long i2cerr = I2C_MASTER_ERR_NONE;
    
    mutex.Lock();
    
    i2cerr =等待();
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    错误计数器++;
    转至 EXIT;
    }
    
    I2CMasterSlaveAddrSet (base、addr、false);
    wait();
    
    if (ptrLen=1)
    {
    I2CMasterDataPut (base、* regptr);
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_SEND_START);
    i2cerr = I2CMasterErr (base);
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
    错误计数器++;
    转至 EXIT;
    }
    wait();
    }
    其他
    {
    I2CMasterDataPut (base、regptr[1]);
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_SEND_START);
    i2cerr = I2CMasterErr (base);
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
    错误计数器++;
    转至 EXIT;
    }
    wait();
    
    I2CMasterDataPut (base、regptr[0]);
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_SEND_CONT);
    i2cerr = I2CMasterErr (base);
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_SEND_ERROR_STOP);
    错误计数器++;
    转至 EXIT;
    }
    wait();
    }
    
    I2CMasterSlaveAddrSet (base、addr、true);
    
    wait();
    
    if (dataLen>1)
    {
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_Receive_start);
    wait();
    
    对于(size_t i = 0;i < dataLen-2;+i)
    {
    DATA[i]= I2CMasterDataGet (base);
    
    i2cerr = I2CMasterErr (base);
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_receive_error_stop);
    错误计数器++;
    转至 EXIT;
    }
    
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_Receive_CONT);
    wait();
    }
    
    DATA[dataLen-2]= I2CMasterDataGet (base);
    
    i2cerr = I2CMasterErr (base);
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_receive_error_stop);
    错误计数器++;
    转至 EXIT;
    }
    
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_Receive_finish);
    wait();
    
    DATA[dataLen-1]= I2CMasterDataGet (base);
    i2cerr = I2CMasterErr (base);
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    I2CMasterControl (base、I2C_MASTER_CMD_BURST_receive_error_stop);
    错误计数器++;
    转至 EXIT;
    }
    }
    其他
    {
    I2CMasterControl (base、I2C_MASTER_CMD_SINGLE_Receive);
    wait();
    *data = I2CMasterDataGet (base);
    i2cerr = I2CMasterErr (base);
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    错误计数器++;
    转至 EXIT;
    }
    }
    
    退出:
    mutex.Unlock();
    
    if (i2cr!= I2C_MASTER_ERR_NONE)
    {
    //if (((i2cr 和 I2C_MASTER_ERR_ARB_Lost)!= 1)
    //{
    ResetBus();
    //}
    
    GPIOPinWrite (GPIO_PORTN_BASE、gpioPin、0xFF);
    SysCtlDelay (i2cr);
    GPIOPinWrite (GPIO_PORTN_BASE、gpioPin、0);
    }
    
    返回 i2certr;
    } 

    当我检测到错误时、即以下示波器截图中的紫色轨迹、我将 GPIO 置为有效。 我们正在触发此断言的范围、并尝试在断言发生之前捕获 SCL (蓝色线迹)和 SDA (黄色线迹)线。 我确实在单独的逻辑块中打印 i2cerr 代码、对于以下情况、错误始终为 I2C_MASTER_ERR_ARB_Lost (0x10)。

    我每~250ms 尝试从温度传感器读取一次、每次尝试都会导致相同的 ARB_Lost 错误。

    下面是示波器捕获、其中在上述原理图中的 R119和 R131上测量了 SCL 和 SDA、位于 I2C 驱动器之后。 clk 和数据线都连续保持高电平。

    这是 I2C 驱动器与 MCU、R120和 R132之间的示波器捕获。 非常相似、只是噪声小一点。

    由于缺少测试点和严格限制、在测量温度外围器件本身附近的信号时会遇到一些困难。 目前、我们正在尝试获取一些捕获数据。 但是、我认为我们可以共享这些第一个示波器捕获、因为 clk/数据持续较高。 温度外设器件附近也会出现这种情况。

    此外、当遇到此错误或任何其他错误时、如何正确地重置 M3中的 I2C 模块? 我的当前逻辑仅用于禁用和启用主模块。 但这似乎无法解决问题。

    空 I2C::ResetBus()

      I2CMasterDisable (base);
      SysCtlDelay (10);
      I2CMasterEnable (base);

    也许我在文档中错过了它、但我没有看到明确的复位命令。

    感谢你的帮助。

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

    我应该在工作时附上一份示波器快照。 与我上次答复中的相同的波形、在 R119和 R131处测得。 我在数据线上触发、并捕获来自该温度传感器的完整"读取"事务。

    我遇到的问题似乎非常间歇性、有时在重新启动后、I2C 会立即进入 ARB_Lost 错误状态、永远。 在其他情况下、例如当前的重新启动、系统是"可"的、我没有在该总线上看到任何错误。

    我们有多个相同的硬件运行相同的软件、它仅发生在少数这些器件上。 我们正在尝试对硬件进行故障排除、但如果我们有一种在软件中重置 M3 I2C 模块的好方法、如果出现错误、这也是有益的。

    谢谢。

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

    下面是一个快速回复、可帮助您继续调试。

    查看软件复位控制1寄存器(SRCR1)。 您可以使用此寄存器中的某个位来复位 M3_I2C 寄存器。 您将需要重新配置模块、因为所有寄存器都会重置为默认状态。

    很奇怪、您很少看到误差、而且只有少数器件出现误差。 这是一个板级或系统级问题、但我还不能肯定。 如果今天下午我再也不能得到更深入的答复,我一定会在星期二晚上,因为我在星期一不在办公室。 我将邀请另一位专家、他们可能也能回复。

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

    Mark、

    感谢您的快速响应。 在查看该寄存器时,我看到内部处理复位逻辑的 SysCtrlPeripheralReset()函数,因此我将 ResetBus 逻辑更改为:

    空 I2C::ResetBus()
    {
    if (base == I2C0_master_base)
    {
    SysCtlPeripheralReset (SYSCTL_Periph_I2C0);
    }
    其他
    {
    SysCtlPeripheralReset (SYSCTL_Periph_I2C1);
    }
    
    //必须重新创新
    init (base、gpioPin);
    } 

    在同一硬件上、我仍然看到 I2C 错误、但总线复位逻辑似乎可以解决问题、因为我现在只看到偶尔出现的错误。 在我每250ms 对温度读数进行一次轮询之前、我会先对它们进行一次轮询:

    02:03:39 PM 0038 M3 I2C 读取错误:0x1c 总线:0x40021000地址:0x4b
    02:03:39 PM 0039 M3 I2C 读取错误:0x8总线:0x40021000地址:0x4b
    02:04:11 PM 0040 M3 I2C 读取错误:0x8总线:0x40021000地址:0x4b
    02:04:14 PM 0041 M3 I2C 读取错误:0x18总线:0x40021000地址:0x4b

    有趣的是、上面的每种情况下的错误编号都不同。

    Derek

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

    很抱歉耽误您的回答。 您是否能够解决此问题? 如果是、请发布您的解决方案。 如果没有、请提供您认为对对话有用的任何其他信息。

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

    Mark、

    我们还没有解决这个问题。 由于软件中的总线复位现在工作得更好、所以它的优先级不如以前那么高。 我们仍在计划绕过 I2C 驱动器、看看这是否有用。 我将在我们进行这些测量时发布更多更新。

    Derek

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

    也许作为一个额外的调试练习、您可以尝试在错误事件期间触发总线的范围捕获。 在未使用(或不必要)引脚上添加 GPIO 引脚切换以进行调试、从而触发示波器。 尝试捕获检测错误之前的时间。 我建议在驱动器芯片的 MCU 侧和总线侧都放置示波器。 它可能会显示其他内容。

    我重新读取了该线程、再次发现您曾提到、有时即使在初始启动后、也会发生 ARB_Lost 错误。 也许您可以在 I2C 复位后添加所有 I2C 中断的明确清除?

    您是否有进行这些测量的预计时间? 就像 FYI 一样、该主题在30天后将锁定、因此定期发布将很好地保持打开状态。

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

    自上次更新以来已经过了几周。 我现在要关闭此帖子。 如果您从今天起30天内回来、您将能够回复、否则请使用此帖子顶部的"提出相关问题"按钮继续对话。

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

    Mark、您好!

    我只是想更新这个线程、因为我还在尝试通过 Derek 解决这个 I2C 问题。 我们发现、我们以前使用示波器进行测量的方式实际上掩盖了问题。 这次我们进行了不同的新测量、下面是在与之前相同的布线上测量的示波器捕获、在 R119和 R131处测量。

    未报告错误时的 SDA:

    报告错误时的 SDA:

    报告错误时的 SCL:

    报告错误时的 SCL、当时钟似乎缩短时放大。

    前一个示波器捕获中的噪声级别足够高、足以触发错误的时钟周期。 这是我认为在最后一个脉冲发生的情况。 总线复位有助于在发生这种情况时恢复、但很明显、我们现在需要重点关注此问题的硬件方面。

    谢谢、
    Thi Le

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

    您共享的图像没有通过。 您可以编辑您的帖子并尝试重新上传。

    好的、我很高兴您现在认为软件很好。 恢复 I2C 的最佳方法是通过模块复位、因此、如果它变得无响应或运行不良、这是一件有效的事情。

    在 SW 侧、您可能会尝试处理的一件事是使用 I2CCLKL 和 I2CCLKH 寄存器来操控 I2CCLK 的占空比。 如果您的其中一个脉冲被截断、这可能有助于缓解一些问题。 只是一个想法。

    祝您顺利进行硬件调试。 您可以搜索 e2e 以查找类似问题、或者如果您认为我们可以提供帮助、则提出新问题、但通常与噪声相关的问题很难远程调试、尤其是在定制硬件上。 我们随时为您提供帮助。

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

    奇怪的是、照片在发布时没有显示。 下面是示波器捕获以及包含捕获的文档、以防万一。

    未报告错误时的 SDA:

    报告错误时的 SDA:

    报告错误时的 SCL:

    报告错误时的 SCL、当时钟似乎缩短时放大。


    链接到 PDF、并提供示波器截图、以防捕获再次显示在帖子中。


    www.dropbox.com/.../Scope 上 SDA 和 SCL.pdf 的截图