您好!
我正在 LP-AM2434上使用 I2C0在 延迟环路中读取 I2C 外设(AD9542)的状态。
I2C 传输定期超时:看似会检查 I2C Busy 位的 I2CControllerBusBusBusy 函数始终返回 BUSY 状态。
如何清除此位和/或复位总线? 我不在乎之前的交易-我只是想进行一笔新的交易。
仅供参考、我将调用 I2C_RecoverBus、然后在循环开始时执行100us 的延迟、但这没有帮助。
谢谢、Steve
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.
您好!
我正在 LP-AM2434上使用 I2C0在 延迟环路中读取 I2C 外设(AD9542)的状态。
I2C 传输定期超时:看似会检查 I2C Busy 位的 I2CControllerBusBusBusy 函数始终返回 BUSY 状态。
如何清除此位和/或复位总线? 我不在乎之前的交易-我只是想进行一笔新的交易。
仅供参考、我将调用 I2C_RecoverBus、然后在循环开始时执行100us 的延迟、但这没有帮助。
谢谢、Steve
Steve、您好!
此 I2C 句柄卡在忙模式下的行为不是预期行为。 如果操作不正确、可能会导致 I2C 配置出现一些问题。
您能否通过共享您所处的示例和 MCU_PLUS_SDK 版本来帮助我在最终重现问题。
I2C_IRQSTATUS_RAW 的第12位提供总线忙状态、但它是只读类型、对其进行写入将不产生影响、因此该位不能直接清零
此外、您是否可以尝试将延迟时间增加到250-500us 之类。
此致。
~Shaunak
尊敬的 Shaunak:
我使用的是 SDK 8.06和 clang 3.0.0 (尽管 SDK 8.04和8.05中存在该问题)。
(简化的)伪代码为:
device.I2cHandle = I2cHandle;
I2C_Transaction_init (&device.i2cTransaction);
device.i2cTransaction.targetAddress = targetAddress;
device.i2cTransaction.TIMEOUT = 10000U;
while (1)
{
I2C_RecoverBus (I2cHandle、I2C_DELAY_SMALL);
ClockP_usleep (500);
pdocity->i2cTransaction.writeBuf =&txBytes[0U];
pdocity->i2cTransaction.writeCount = 2u;
pdocity->i2cTransaction.readBuf = pValue;
pdocity->i2cTransaction.ReadCount = 1U;
I2C_TRANSMIT (PDevice->I2cHandle、&PDevice->i2cTransaction);
ClockP_usleep (10000);
}
我已经增加了睡眠后恢复到500 us。
仅供参考、 因为我们知道 AM 的 I2C 边沿与 I2C 不兼容("太快")、所以我已经在 AM2434 I2C0和 AD9542之间添加了一个 PCA9517A I2C 缓冲器。 下面是 模拟和数字信号完整性的典型 I2C 事务跟踪(PCA9517A 的任一端)。


谢谢、Steve
Steve、您好!
根据伪代码、我尝试 在最终重现此问题、但无法观察到相同的行为、您能否共享 debug.out 文件?
同时、您可以尝试执行 I2C 软件复位吗?
此致、
Shaunak
Steve、您好!
不再现问题很难得出可靠结论、我尝试根据伪代码进行再现、但找不到总线忙位卡住。
如果您只关心接下来的交易、您可以采用更安全的方法。
if(I2CControllerBusBusy(baseAddr) == 1) /* check if bus is busy */
{
/* If busy, Wait for the transaction to complete */
status = I2C_waitForBb(baseAddr, timeout);
}
else
{
/* If timeout, then reset the I2C IP */
status = I2C_resetCtrl(I2C_Handle)
}
我仍在研究可能导致该位卡在繁忙模式的原因。 如果有任何更新、我会回复给您。
此致、
Shaunak
Steve、您好!
1.当发生故障条件时、您可以分享 I2C 总线的示波器屏幕截图吗?
2.您能 将该电路板和 AD9542引脚相连吗?这能帮助我们更好地理解设置吗?
3.您使用的是什么版本的 AM243x LP、比如 E3A 或者 E3B?
4.如果您可以删除代码的专有部分、并仅将其减少为有助于我重现问题的 I2C 代码、我将能够为您提供更好的支持。
此致、
Shaunak
尊敬的 Shaunak:
哦、我的代码基于 SDK 文档:

但是、我现在已将其分解、并将重试:
int32_t AD9542_ReadRegister(AD9542_Device *pDevice, uint16_t registerAddress, uint8_t *pValue)
{
int32_t status = SystemP_SUCCESS;
int32_t count = 5; // If there is an I2C Transfer error then retry 5 times
uint8_t txBytes[sizeof(registerAddress)];
// address is high byte, low byte order
txBytes[1U] = registerAddress & 0xFF;
txBytes[0U] = registerAddress >> 8;
// prepare to write
pDevice->i2cTransaction.writeBuf = &txBytes[0U];
pDevice->i2cTransaction.writeCount = sizeof(registerAddress);
pDevice->i2cTransaction.readCount = 0U;
// write
status = I2C_transfer(pDevice->I2cHandle, &pDevice->i2cTransaction);
if (SystemP_SUCCESS == status)
{
// prepare to read
pDevice->i2cTransaction.writeCount = 0U;
pDevice->i2cTransaction.readBuf = pValue;
pDevice->i2cTransaction.readCount = sizeof(*pValue);
// read
status = I2C_transfer(pDevice->I2cHandle, &pDevice->i2cTransaction);
}
if (SystemP_SUCCESS != status)
{
// I2C not successful, print error
AD9542_DebugPrintI2CStatus("AD9542_ReadRegister", registerAddress, status);
}
return status;
}
史蒂夫