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.
工具与软件:
您好!
我们会遇到 I2C 时钟信号始终处于低电平无法恢复的问题。 在此 I2C 总线上、AM2434是主器件、有一个 MSP430FR2355 作为从器件。 当 AM2434 在 EFT 噪声干扰期间以引导模式将程序数据写入 MSP430FR2355时、I2C 时钟信号会卡在低电平。
下图显示、在 EFT 噪声发生器中断传输后、AM2434调用 I2C_FreeBus ()函数(根据 SDK 的 I2C_recoverBus ()函数进行修改)来尝试恢复 I2C 总线(在标记为"Gen 9 Clocks to Recover bus"的点上)、然后尝试重新发送数据包。 但是、如图所示、当重新发送达到长度字段第一个字节的第7位时、SDA 和 SCL 都卡在低电平状态。
随后,由于连续传输失败,程序再次调用 I2C_FreeBus()函数,但这次 SCL 不会产生预期的9个时钟并保持低电平(如下图所示)。 该情况已重试10次、结果与图中所示相同。 SDA 线转换到两次高电平状态,我们怀疑这是调用 I2C_CtrlInit ()函数的结果。
下面是 AM2434中的 I2C_FreeBus ()函数、它已从 SDK 的 I2C_recoverBus 函数进行修改。
void I2C_FreeBus( I2C_Handle handle ) { I2C_Object *pObject; Uint32 SysTest, i; pObject = ( I2C_Object* )handle->object; /* Acquire the lock for this particular I2C handle */ ( void )SemaphoreP_pend( &pObject->mutex, SystemP_WAIT_FOREVER ); /* Check if SDA or SCL is stuck low based on the SYSTEST. * If SCL is stuck low we reset the IP. * If SDA is stuck low drive 9 clock pulses on SCL and check if the * target has released the SDA. If not we reset the I2C controller. */ SysTest = I2CControllerGetSysTest( pObject->baseAddr ); I2C_CtrlInit( handle ); /* SDA output high */ /* generate 9 clk pulses on SCL */ /* switch to system test mode */ HW_SET_FIELD32( SysTest, I2C_SYSTEST_ST_EN, I2C_SYSTEST_ST_EN_ENABLE ); HW_SET_FIELD32( SysTest, I2C_SYSTEST_TMODE, I2C_SYSTEST_TMODE_LOOPBACK ); // HW_SET_FIELD32( SysTest, I2C_SYSTEST_SDA_O, I2C_SYSTEST_SDA_O_SDAOH ); I2CControllerSetSysTest( pObject->baseAddr, SysTest ); for( i = 0; i < 9; i++ ) { HW_SET_FIELD32( SysTest, I2C_SYSTEST_SCL_O, I2C_SYSTEST_SCL_O_SCLOH ); I2CControllerSetSysTest( pObject->baseAddr, SysTest ); Delay_us( 5 ); HW_SET_FIELD32( SysTest, I2C_SYSTEST_SCL_O, I2C_SYSTEST_SCL_O_SCLOL ); I2CControllerSetSysTest( pObject->baseAddr, SysTest ); Delay_us( 5 ); } /* Switch back to functional mode */ HW_SET_FIELD32( SysTest, I2C_SYSTEST_ST_EN, I2C_SYSTEST_ST_EN_DISABLE ); HW_SET_FIELD32( SysTest, I2C_SYSTEST_TMODE, I2C_SYSTEST_TMODE_FUNCTIONAL ); I2CControllerSetSysTest( pObject->baseAddr, SysTest ); /* Now check if the SDA is releases. If its still stuck low, * There is nothing that can be done. We still try to reset our IP. */ SysTest = I2CControllerGetSysTest( pObject->baseAddr ); if ((SysTest & I2C_SYSTEST_SDA_I_FUNC_MASK) == 0U) { I2C_CtrlInit( handle ); } /* Release the lock for this particular I2C handle */ ( void )SemaphoreP_post( &pObject->mutex ); }
此外、我们还 通过 SDK 修改 AM2434的 I2C_CtrlInit ()、如下所示。
void I2C_CtrlInit( I2C_Handle handle ) { I2C_HwAttrs const *pHwAttrs; I2C_Object *pObject; Uint32 Delay = 50U; Uint32 OutputClk; Uint32 InternalClk; Uint32 RegVal; /* Get the pointer to hwAttrs */ pObject = ( I2C_Object* )handle->object; pHwAttrs = ( I2C_HwAttrs const* )handle->hwAttrs; /* Put i2c in reset/disabled state */ I2CControllerDisable( pObject->baseAddr ); /* Do a software reset */ I2CSoftReset( pObject->baseAddr ); /* Enable i2c module */ I2CControllerEnable( pObject->baseAddr ); /* Wait for the reset to get complete -- timeout = 50ms */ while( ( ( HW_RD_REG32( pObject->baseAddr + I2C_SYSS ) & I2C_SYSS_RDONE_MASK ) == 0 ) && ( Delay != 0 ) ) { Delay--; Delay_us( 1000 ); } /* Put i2c in reset/disabled state */ I2CControllerDisable( pObject->baseAddr ); /* Configure i2c bus speed*/ switch( pObject->i2cParams.bitRate ) { case I2C_100KHZ: { OutputClk = 100000U; InternalClk = I2C_MODULE_INTERNAL_CLK_4MHZ; break; } case I2C_400KHZ: { OutputClk = 400000U; InternalClk = I2C_MODULE_INTERNAL_CLK_12MHZ; break; } case I2C_1P0MHZ: { OutputClk = 3400000U; InternalClk = I2C_MODULE_INTERNAL_CLK_12MHZ; break; } default: { /* Default case force it to 100 KHZ bit rate */ OutputClk = 100000U; InternalClk = I2C_MODULE_INTERNAL_CLK_4MHZ; } break; } /* Set the I2C configuration */ I2CControllerInitExpClk( pObject->baseAddr, pHwAttrs->funcClk, InternalClk, OutputClk ); /* Configure I2C_SYSC params * Disable auto idle mode * Both OCP and systen clock cut off * Wake up mechanism disabled * No idle mode selected */ RegVal = I2C_AUTOIDLE_DISABLE | I2C_CUT_OFF_BOTH_CLK | I2C_ENAWAKEUP_DISABLE | I2C_NO_IDLE_MODE; I2CSyscInit( pObject->baseAddr, RegVal ); /* Configure I2C_CON params */ RegVal = I2C_OPMODE_FAST_STAND_MODE | I2C_NORMAL_MODE; I2CConfig( pObject->baseAddr, RegVal ); /* Take the I2C module out of reset: */ I2CControllerEnable( pObject->baseAddr ); /* Enable free run mode */ I2CControllerEnableFreeRun( pObject->baseAddr ); /*Clear status register */ I2CControllerIntClearEx( pObject->baseAddr, I2C_INT_ALL ); }
在进一步测试中、当 I2C 时钟(SCL)持续处于低电平时、我们尝试 使用硬件方法对 MSP430FR2355进行复位。 此方法可手动触发硬件复位、以恢复器件并恢复正常的 I2C 通信。
在复位 MSP430FR2355后、我们观察到 SCL 引脚返回到高电平状态、如下图所示:
接下来、我们测试了 MSP430FR2355 进入 APP 模式、并且引入 EFT 噪声以强制 I2C 时钟(SCL)线路保持低电平的情况。 但是、在我们的 MSP430FR2355应用中、我们将配置UCB0CTLW1 = 0x03
为启用时钟低电平超时功能。 当UCCLTOIFG
检测到该标志时、我们将复位 I2C 模块。
因此、I2C 时钟线在大约44ms 后成功恢复到高电平状态、如下图所示。
我想问是否有配置的方法 MSP430FR2355 BSL 当检测到时钟(SCL)在一段时间内卡在低电平时、自动复位 I2C 模块。 这是为了防止在编程过程中由噪声干扰引起的编程失败。
非常感谢您提供任何指导!
此致、
Yenting
Yen Ting、
首先需要与您确认、您在使用基于 ROM 的 BSL、对吧?
如果是、您是否已将器件上的复位引脚与主机连接? 如果需要、我认为您可以只使用复位引脚对器件进行复位。
您是否已尝试启用 A 型看门狗、使超时时间为10s、足以进行正常固件更新? 如果您使用软件触发器、似乎不会重置寄存器、这意味着看门狗可能可以工作。
FR2355似乎没有 USCI30问题、所有问题都在勘误表 https://www.ti.com/lit/er/slaz695j/slaz695j.pdf 中
您好、Gary、
在对固件进行编程之前、是否可以在 MSP430FR2355上以 BSL 模式启用和使用看门狗计时器(WDT)?
如果是、您能说明一下如何在这种情况下配置 WDT、以便在 μ I²C 总线卡住或通信失败时恢复器件吗?
如果问题与 USCI30勘误表无关、那么 MSP430FR2355 BSL 模式下的哪些其他机制或条件 可能会导致 SCL 线保持低电平而无法释放?
我们正在努力确定潜在的根本原因、如果有任何深入的调查见解或建议、我们将不胜感激。
感谢您的帮助!
此致、
Yenting
在对任何固件进行编程之前、是否可以在 MSP430FR2355上以 BSL 模式启用并使用看门狗计时器(WDT)?
否、您需要在应用代码中启用它
[报价 userid="632180" url="~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1452325/msp430fr2355-handling-i2c-clock-stuck-low-in-msp430fr2355-bsl/5571312 #5571312"]如果问题与 USCI30勘误表无关、 MSP430FR2355 BSL 模式下的其它哪些机制或条件 可能导致 SCL 线卡在低电平并无法释放?[/QUOT]在封装之间添加更多延迟、以确保 MSP430能够处理预封装。
您好、Gary
在数据包之间添加更多延迟以确保 MSP430能够处理预封装。 [报价]感谢您发送编修。 您能否详细说明在数据包之间添加更多延迟的原因?
有多大的延迟被认为是合适的?
此外、MSP430文档中是否有与此相关的任何信息或指导?
此致、
Yenting
30ms 应该足够了。
另外、您是否尝试过通过示波器测量 SCL 和 SDA 信号来查看信号质量是否良好? 您现在使用的 SCL 的频率是多少? 您是否尝试过减慢它?
顺便说一下、您是说即使是空白器件也会出现此问题吗?
您好、Gary
30ms 应该足够了。
我们已尝试将每个数据包之间的间隔增加到30ms、但 MSP430 ROM BSL 仍将 SCL 线拉低。
顺便说一句、您是否尝试通过示波器测量 SCL 和 SDA 信号以查看信号质量是否合格?
目前、我们有些产品的内部电路会产生明显的噪声、我们可以观察到 I2C 线路上的噪声、如下图所示。 这些器件在首次尝试在出厂时对 MSP430进行编程时失败。
您现在使用的 SCL 频率是多少? 您是否尝试过减慢速度?
当前 I2C 频率设置为100kHz、这已经是可用的最低速度。
顺便说一句、您的意思是即使是空白设备也会发生此问题吗?
是的、此问题发生在空白器件上的第一次编程尝试期间。
(应用程序编程成功的器件也会遇到通信故障、但可以在应用模式下使用时钟超时机制来缓解该问题。)
此致、
Yenting
您好、Gary
这是使用逻辑分析仪捕获的完整波形、 封装之间有30ms 延迟。
e2e.ti.com/.../20241219_5F00_30msBetweenPackage.zip
有四个标记(A0至 A3)、指示 SCL 卡在低电平的周期。
我使用的软件是 ZP-Logic V1.02.08 (型号:Lap-C Pro (16064M))。 您可以通过以下链接下载:
https://www.zeroplus.com tw /logic-analyzer_en/download_re.php?id=7849&name=https%3A%2F%2F%2Fbd.zeroplus.com tw 2FZP-Logic_10208_all.zip
此致、
Yenting
我似乎没有硬件就无法使用软件。
当您添加 EFT 噪声时才会发生该问题? 如果没有 EFT 噪声、那么就会发生该问题的剂量?
您好、Gary
如果没有硬件、软件似乎无法使用。 [报价]选择"演示"
选择 Lap-C Pro (16ch 64M)并按 Demo、然后您可以使用软件打开波形文件。
因此、如果您正确添加了 EFT 噪声、这个问题才会发生? 如果没有 EFT 噪声、则会发生此问题的剂量?是的、如果没有噪声、SCL 线不会卡在低电平。
我们使用 EFT 引入噪声、因为要仿真电源设计不佳且会产生噪声的一批产品的工作条件。 这批产品还会因为电源噪声而在编程期间遇到 SCL 卡在低电平的情况。我们目前希望使用基于软件的解决方案来实现该批产品中的 MSP430成功编程。
此致、
Yenting
[/quote]
I2C 总线非常容易受到噪声的影响、因为(主要)是无源高电平。 噪声可能会导致协议错误、总线挂起和(未检测到)错误数据。 这可以通过屏蔽、更强的上拉电阻、更慢的总线、校验和和和多次读取(投票)来缓解。
如果 SDA 保持低电平、则9时钟技巧通常会起作用。 如果 SCL 被保持在低电平、 您需要(硬件)通过 RST/NMI/SBWTDIO 将从机复位并重新启动。 [参考 UM10204 (R6)第3.1.16]节。 RST/NMI/SBWTDIO 引脚是 BSL 协议[参考 FRAM BSL UG (SLAU550AB)第3.3.2节]的一部分、因此必须与主机建立连接。
正如 Gary 所说的、ROM BSL 不使用 WDT 和 UCCLTO 超时、因此主器件必须管理它。 虽然我怀疑这比您记忆中的要复杂、但是您可以编写自己的 BSL。
设计中切换到 UART BSL 是否太晚? UART 可驱动高电平和低电平、因此(略微)不易受噪声的影响。