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.

[参考译文] TMS320F28034:I2C 总线挂起的可能原因

Guru**** 2552590 points
Other Parts Discussed in Thread: TMS320F28034

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/707596/tms320f28034-possible-cause-s-of-i2c-bus-hang-up

器件型号:TMS320F28034

我们在使用 TMS320F28034的生产单元中看到了一个问题、其中症状是 I2C 总线挂起(从器件将 SDA 保持在低电平)。  复位 TMS320F28034不能清除这个问题、但是关闭整个电路板的电源、然后再为其备份供电。  这个应用中的 I2C 总线只有3个部分- TMS320F28034 (主器件)和2个从器件(I2C EEPROM 和一个 I2C 加速计)。  I2C 总线的所有相关参数均为标称值(上拉电阻器(6.8k)、总线电容(30-40pF) SCL 时钟速度(161kHz)、主器件、从器件和 I2C 的电源电压(3.3V)、SCL 和 SDA 上的上升时间、I2C 高电平(~3.3V)、I2C 低电平(~0V)等  我们可以找到一些 TI 文档(I2C 提示 http:/processors.wiki.ti.com/index.php/I2C_Tips),这些文档指明了 I2C 主设备是否在从 I2C 上的从设备发送数据的过程中被复位,然后它可能会挂起总线。  TMS320F28034复位引脚(/XRS)有一个1k 上拉至3.3V 和一个0.1uF 电容至 GND。  我们能够通过在 I2C 通信过程中触发复位来手动使 I2C 总线挂起、串行 I2C EEPROM 在其中读取其整个存储器。  (如果在从器件读出"0"且时钟消失时发生复位、则从器件保持 SDA 线为低电平。)  TMS320F28034预计电源电压为3.3V +/- 10%、而 I2C 从器件将在低至1.9V 的5.5V 电源电压下运行。  3.3V 电源上的毛刺脉冲可能会导致 TMS320F28034执行 POR/BOR 复位、但 I2C 从器件会继续正常运行。  电路板布局不能为主器件提供一种对 I2C 从器件进行上电复位的方法。

在尝试调试和/或重现此问题时、我们设法在读取 I2C EEPROM 存储器转储的过程中手动触发 TMS320F28034的复位、并且我们在发送"0"的过程中捕获了 EEPROM。  结果是 I2C 总线挂起、从器件将 SDA 线保持在低电平。

我们可以考虑"正常"发生此问题的唯一方法是 POR/BOR 复位、看门狗复位、NMI 复位(尝试写入受保护的存储器等)、或者通过 I2C 控制寄存器写入存储器泄漏或错误指针  

是否有任何方法可以从病理上操作 I2C 主设备、使其挂起 I2C 总线?  如果 I2C 外设在 I2C 读取过程中被禁用、这是否可以模仿微控制器被复位并挂起总线?  (I2CMDR (I2C 模式寄存器)中的 IRS 位在 I2C 外设正在从从器件读取数据时写入"0"。)  I2C 寄存器不受写保护、因此错误软件可能会覆盖它们。

POR/BOR 复位将涉及电源电压输入上的毛刺脉冲。  这似乎不太可能、因为电源看起来很干净、干扰需要使3.3V 稳压器的压降足以使 TMS320F28034执行 POR/BOR、但压降不足以执行从器件的上电复位、这必须发生在的中间 从器件发送"0"时的 I2C 读取。  我们无法通过 EMI 触发复位(我们使用变速直流电钻、您可以观察电刷)。  看门狗复位或 NMI 类型的复位似乎是错误软件的症状--内存泄漏或错误指针。  所有这些似乎并不经常发生、不足以有很好的机会在悬挂 I2C 总线所需的神奇点实际发生。  如果错误指针或内存泄漏被设法写入 I2C 模式寄存器并先挂起 I2C 总线、最终导致看门狗复位或 NMI 类型的复位、 复位本身可能不是我们所看到问题的实际原因、而只是巧合。

欢迎提出任何意见和建议。  请告诉我这些猜测是否是不是很专业。  我们正在尝试确定问题的根源是硬件还是软件、以便集中精力。

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

    根据您的描述、当可以从 EEPROM 读取数据时、它听起来像是一个 POR。 一些问题可帮助我更好地理解以下情况:

    您的所有器件都在同一电路板上(F28034主器件和两个从器件)、因此都是由同一电源供电吗? 是否可以在 I2C 总线上仅使用一个从器件进行测试、以查看它是否特定于 EEPROM/Accelerometer?

    2.您是否从闪存运行应用程序代码、如果是、您是否可以访问 JTAG 以在 CCS 中调试程序? 在不同的时间检查 I2C 相关寄存器的状态会有所帮助、前提是未发生 POR 并且调试器实际上可以保持连接。

    3.您是否能够使用示波器捕获 I2C 总线或探针上的逻辑波形? 这些波形有助于查看 SDA 线被保持之前/之后在总线上发生的情况。

    如果一个 POR 确实定期发生并且保持了 I2C 总线(SDA 线)、那么也许最好缩小原因并修复它、而不是在软件内进行反击。 但是、如您链接的 I2C 提示中所述、有一些在软件内恢复的方法。

    对于将 SCL/SDA 引脚与 GPIO 复用的主器件、最简单的方法是为 GPIO 操作配置引脚并切换 SCL、直到从器件释放 SDA。 此时、您应该能够恢复正常操作。

    2、许多主器件不会将 SCL/SDA 与 GPIO 复用、因为 I2C I/O 单元通常是特殊的开漏单元。 据报告、即使在这些器件上、也会有权变措施。 通过将 I2C 配置为"自由数据格式"、然后读取一个字节、I2C 将立即开始发送时钟以输入数据(而不是尝试发送地址)。 这可用于释放总线。

    3.一些从器件可以在总线挂起时复位其 I2C 接口(例如、在33ms 后 LTC4151)。 如果这不是默认行为、请将其打开。

    选项(3)可能是一个好的做法、首先尝试、看看设置 IRS 位是否可以释放 I2C 总线。 否则、选项(1)可在 POR 后在您的应用程序中实现。

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

    Kevin

    感谢您的回答。

    I2C 总线的长度仅为2-3英寸、全部位于同一 PCB 上。  I2C 总线上的所有器件均由同一个3.3V LDO 稳压器供电。  该板已投入生产、因此 PCB 上未引出 JTAG 引脚、因此遗憾的是无法连接到 JTAG。  电路板通常封闭在金属盒中。  我们具有定制设计的 CAN 总线引导加载程序、允许在通过 CAN 进行测试后对生产单元进行编程。  我们可以通过此 CAN 连接读取寄存器并监控电路板上的某些点、但它与使用 UART 连接进行调试类似、因为它不是实时的。  应用程序在片上闪存之外运行、并对后台的 CAN 查询做出响应。  我们打开了几个装置上的金属外壳并探测了各种测试点。

    我们尚未在3.3V LDO 稳压器的输入端看到任何电噪声或在3.3V 信号上看到任何电噪声、因此我们认为 POR/BOR 复位不太可能(尽管可能)。

    在 I2C 通信过程中重置微控制器会使 I2C 总线挂起

    (SCL 底部为黄色、SDA 顶部为红色)

    微控制器复位发生在右侧、SCL 正常(高电平)、但 SDA 保持有效(低电平)

    此示波器照片展示了我们如何在串行 EEPROM 的 I2C 读取期间挂起 I2C 总线、并手动复位 TMS320F28034。

    我们无法创建一个自由格式的数据包来使用 I2C 外设发出和复位 I2C 总线。  I2C 外设会将 I2C 总线视为忙而不发送复位数据包。  我们最后不得不禁用 I2C 外设、将 SCL 和 SDA 引脚转至 GPIO、将它们设置为输入以确认 SDA 为低电平、然后将它们转换为 GPIO 输出并对数据包进行位拆裂:[start][1][1][1][1][1][1][1][1] [1][1][1][1][1][1][NACK][STOP]。  发现这是为了复位 I2C 总线。  只是发送时钟脉冲并不是这样。  以下示波器图片显示了挂起的 I2C 总线、位拆裂的 I2C 复位、I2C 总线解除挂起、以及 I2C 通信再次启动。

    I2C 复位例程清除挂起的 I2C 总线(SDA 低电平(红色)和 SCL 高电平(黄色))

    注意:I2C 例程使用 GPIO 引脚进行位转换,因此 SCL 位转换频率比微控制器的 SCL (~160kHz)慢一点(~100kHz)。 I2C 复位例程将 SDA 和 SCL 引脚从 I2C 功能更改为 GPIO 并发出例程。 GPIO 输出不是漏极开路(例如 I2C)、您可以看到主器件在从器件保持 SDA 线路为低电平时驱动 SDA 线路的位置(请参阅小脉冲)。 最终、从器件释放 SDA 线路、并使其变为高电平。 最后,它将 GPIO 更改为输入并读取总线(两个信号均为高电平)。 然后、它将 GPIO 引脚改回 I2C 外设功能 SCL 和 SDA、并再次启用 I2C 外设。

    此时、我们看不到此问题的可能硬件原因。  假设我们确实看到、如果在由"0"组成的 I2C 从器件发送数据的魔法点发生 POR/BOR 运行时会导致该问题、 但是、我们无法 在其设计参数范围内运行的电路板上看到或导致此类问题。   

    I2C 控制寄存器不受写保护、可能会被错误的软件覆盖、因此是否可以以导致此类问题的方式操作 I2C 外设?

    如果您正在读取 I2C 总线上的数据、并且通过向 I2CMDR (I2C 模式寄存器)中的 IRS 位写入"0"来禁用 I2C 外设 这是否会导致 I2C 外设在 I2C 发送/接收过程中停止、或者 I2C 外设是否会在禁用之前完成它正在执行的操作?

    我们正在尝试确定在伪不规则基础上发生的 SW 问题/问题/错误(例如内存泄漏或错误指针)是否可能通过写入 I2C 控制寄存器而导致与复位相同的问题。  事实证明、每次调用例程(而不是在初始化时仅设置一次)时、SW 中使用的 I2C 软件模块都会设置 I2C 控制寄存器。  除非 I2C 总线在禁用 I2C 外设时从从从从器件读取"0"、否则它不会挂起总线。  如果 SW 进一步进入工作模式、微控制器可能会通过 NMI 类型复位或内部看门狗(预计每隔6-12ms 触摸一次)进行复位。  这样、微控制器本身的复位实际上不会导致总线挂起、而在右侧通过 I2C 控制寄存器进行写入可能导致总线挂起。  由于这是一个生产单元、系统不会监控发生的复位类型和复位的频率等情况。  除非检测和监视应用程序、否则有可能不会注意到看门狗的周期性复位。  但是、悬挂 I2C 总线会导致系统故障、这一点很明显。

    Murdock

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

    如果不访问寄存器值、就很难真正知道器件的 I2C 模块中正在发生什么情况。 如果您可以定期检索某些寄存器值(如 I2CSTR 和 I2CMDR)、则通过 CAN 连接进行调试可能会很有用。

    您提供的示波器截图来自您的强制 POR 测试、对吧? 您实际应用中的 I2C 挂起情况是否与所示相同、SCL 保持高电平并且不再由主器件驱动? 可能是 I2C 模块在通信期间被复位(I2CMDR.IRS 被设置为0)、因为您说在每次调用例程时寄存器都被触摸。

    1.您能否分享 I2C 例程中发生的一切以及在应用中何时调用它? 每次运行例程时要设置哪些 I2C 寄存器、并设置为什么值? 它们是否设置为中间通信? 如果您可以提供初始 I2C 初始化、也会有所帮助。

    2.在应用程序运行时探测 XRS 引脚可以深入了解是否发生看门狗复位(或其他因素是否将其驱动为低电平)。

    当通过自身打开/关闭来切换 SCL 时、您看到 SDA 保持低电平并且它没有释放? 仅当您同时切换 SDA/SCL 时、它才起作用? 看起来很奇怪。

    3.您能分享您使用的加速器和 EEPROM 吗? 它们至少可以处理到快速模式?

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

    我想添加一些更多信息。

    在两次传输之间将 I2C 外设(I2CMDR.IRS 设置为0、然后设置为1)复位将清零 BB 位、模块将不知道总线的状态(即、是否处于繁忙状态)、直到检测到启动或停止条件。 我想可以看到这种相同的响应、尽管我必须进行测试才能确定、当 I2C 模块在接收一个字节的过程中被复位时。 您接收的字节也可能丢失、情况更糟。

    F2803x I2C 指南第5.4节" I2C 状态寄存器(I2CSTR)"末尾列出了一些步骤、用于重新发现总线状态并正确设置 BB 位、前提是在传输之间发生 I2C 外设复位。 但是、在较新的修订版本中需要进行轻微的更正、在之前的 E2E 帖子 e2e.ti.com/.../696954中对此进行了讨论

    http://www.ti.com/lit/sprufz9

    话虽如此、除非有必要、否则最好不要重置 I2C 模块。 如果您执行此操作、则应在传输之间执行、并执行文档中的步骤。

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

    Kevin:

    感谢您提供信息。

    从 I2C 器件是一个 Microchip 24LC16BT-E/OT 串行 EEPROM 和一个 Freescale MMA8452Q 串行加速计。  两个从器件都可以在高达400kHz 的 SCL 下工作、我们不认为可以或不进行时钟扩展。

    I2C 总线挂起的问题只有在工厂的自动化测试设备测试已完成的产品时才会出现。  测试电路板本身时未发现问题。  在最终设备中,电路板密封在金属盒中,有几根电缆从外面出来,因此无法访问电路板上的任何测试点。

    使用的 I2C 例程由第三方开发并进行轮询(不是由中断驱动)、并在后台运行。  优先级更高的前台任务可以在需要时随时运行、这样就不能检查各种 I2C 控制位来判断通信是否有问题 (即、如果 NACK 位被置位是由主器件或从器件引起的、除非你跟踪正在执行的操作的上下文(这显然没有完成)、否则很难分辨。)  I2C 例程发现、在每次启动 I2C 通信时只清除所有控制位比清除特定控制位更容易、并查看其他控制位以及上下文以查看是否发生问题。  I2C 例程看起来不是很可靠、也不会执行太多错误检查或错误处理。   

    我们已经能够确认将 I2CMDR (I2C 模式寄存器)中的 IRS 位更改为"0"以在从器件读取时禁用 I2C 外设、其中被读取的位为"0"将挂起 I2C 总线- 从器件将保持 SDA 线路为低电平。  重新启用 I2C 外设后、I2C 总线将显示为"忙"。

    该软件包含一部分从 LabView 自动生成的"C"代码以及一些"C"语言的低级驱动程序(其中许多是由第三方编写的)、这些驱动程序实际上可以与 TMS320F28034外设和特定的外部器件配合使用。  所有这些都是使用 CCS 合并在一起的。  没有 RTOS、而是具有由中断驱动的更高优先级任务的调度程序。  由于与一个完整系统通信的唯一方法是通过 CAN 总线、并且由于电路板的生产版本没有 JTAG、所以此时的调试很复杂。  看门狗已启用、将在13ms 内跳闸、除非它被触摸。 软件在发布之前已经过测试、但在进行重大的软件研究之前、我们需要确保它与硬件无关。   

    我们通过强制在魔术点上进行复位(同时从发送"0"的 I2C 从器件读取数据)、能够以病理学的方式重现症状(挂起 I2C 总线)、但在设计参数范围内的运行期间无法触发复位。  目前、我们未将问题视为与硬件相关的问题。

    让一个有效的软件例程复位挂起的 I2C 总线至少是第一步。

    谢谢。

    Murdock