请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号: TDA4VH-Q1
这是 TI j784s4 PSDK 版本 11.2 中 i2c 驱动程序的错误报告、不过这个问题可能在使用该驱动程序的所有 PSDK 版本中都是相同的。
当通过 i2c 与一些芯片通信时、重要的是 不仅要知道芯片已否定了操作、而且还要知道 事务中 NACK 的确切位置、因为根据 NACK 的位置、可能需要不同的处理。
TI i2c 驱动程序尝试通过在完成事务对象之前调整事务对象中的 writeCount(和 ReadCount)来支持这一点、位于 I2C_v1_complete_CURR_transfer() 中:
object->currentTransaction->readCount -= object->readCountIdx;
object->currentTransaction->writeCount -= object->writeCountIdx;
但是、当驱动程序处于中断模式时、object->writeCountIdx 此时不表示 NACK 之前传输的数据量。 相反、它表示驱动程序已写入 TX FIFO 的字节数。
要正确报告错误位置、必须更新 object->writeCountIdx。 DataCount 寄存器的当前值可用于了解实际错误位置。
下面的补丁使 NACK 位置报告准确。
From 80d9d6d99cb1e095c9fa45ad0fde92aa46dc0b2e Mon Sep 17 00:00:00 2001
From: Nikita Yushchenko <nikita.yoush@cogentembedded.com>
Date: Mon, 8 Jun 2026 23:12:46 +0200
Subject: [PATCH] pdk: i2c: fix NACK position reporting in interrupt mode
When communicating with some chips over i2c, it is important to know
not only the fact that the chip has NACKed the operation, but also the
exact position of NACK within the transaction - because different
handling can be required depending on the position of NACK.
TI i2c driver tries to support that, by adjusting writeCount (and
readCount) inside transaction object before completing it. This is done
in I2C_v1_complete_curr_transfer():
object->currentTransaction->readCount -= object->readCountIdx;
object->currentTransaction->writeCount -= object->writeCountIdx;
However, when the driver is in interrupt mode, object->writeCountIdx
contains not the hardware transmit position, but the tx fifo write
position, which is always several bytes forward compared to the
transmit position (and for a typical short transaction that fits into
tx fifo completely, object->writeCountIdx just points to the end).
This results into wrong NACK position report.
Fix that by adjusting object->writeCountIdx at the error path, using
the current value of DataCount hardware register, that points to the
current hardware transmit position.
Change-Id: Ibaf217217bea1334c4bf290969d14b5ec13ae71d
---
.../packages/ti/drv/i2c/src/i2c_api.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/pdk_j784s4_11_02_00_15/packages/ti/drv/i2c/src/i2c_api.c b/pdk_j784s4_11_02_00_15/packages/ti/drv/i2c/src/i2c_api.c
index 4e41598e7..6ef3de306 100644
--- a/pdk_j784s4_11_02_00_15/packages/ti/drv/i2c/src/i2c_api.c
+++ b/pdk_j784s4_11_02_00_15/packages/ti/drv/i2c/src/i2c_api.c
@@ -288,6 +288,18 @@ static void I2C_v1_hwiFxnMaster(I2C_Handle handle)
if(UFALSE != fatalError)
{
+ if (object->mode == I2C_WRITE_MODE)
+ {
+ /* At this point object->writeCountIdx shows how many bytes are not
+ * written to fifo, this does not help the caller to understand
+ * the position of NACK.
+ *
+ * Replace it with number of bytes not sent, available in DataCount
+ * register.
+ */
+ object->writeCountIdx = I2CDataCountGet(hwAttrs->baseAddr);
+ }
+ object->mode = I2C_IDLE_MODE;
/* ISsue the stop condition*/
I2CMasterStop(hwAttrs->baseAddr);
I2CMasterIntDisableEx(hwAttrs->baseAddr, CSL_I2C_INT_ALL);
@@ -335,10 +347,12 @@ static void I2C_v1_hwiFxnMaster(I2C_Handle handle)
I2CMasterIntEnableEx(hwAttrs->baseAddr, CSL_I2C_INT_RECV_READY);
/* Start I2C peripheral in RX mode */
+ object->mode = I2C_READ_MODE;
I2CMasterStart(hwAttrs->baseAddr);
}
else
{
+ object->mode = I2C_IDLE_MODE;
if (0U != (rawStat & CSL_I2C_INT_BUS_BUSY))
{
I2CMasterStop(hwAttrs->baseAddr);
@@ -980,6 +994,7 @@ static int16_t I2C_primeTransfer_v1(I2C_Handle handle,
I2CMasterIntEnableEx(hwAttrs->baseAddr, regVal);
/* Start the I2C transfer in master transmit mode */
+ object->mode = I2C_WRITE_MODE;
I2CMasterStart(hwAttrs->baseAddr);
I2C_drv_log1("\n I2C:(0x%x) I2C_IDLE_MODE: -> I2C_WRITE_MODE; Writing w/ START \n",
@@ -1006,6 +1021,7 @@ static int16_t I2C_primeTransfer_v1(I2C_Handle handle,
CSL_I2C_INT_RECV_READY | CSL_I2C_INT_ADRR_READY_ACESS | CSL_I2C_INT_NO_ACK | CSL_I2C_INT_ARBITRATION_LOST);
/* Send start bit */
+ object->mode = I2C_READ_MODE;
I2CMasterStart(hwAttrs->baseAddr);
I2C_drv_log1("\n I2C:(0x%x) I2C_IDLE_MODE: -> I2C_READ_MODE; Reading w/ NACK \n",
--
2.47.3