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.

[参考译文] TDA4VE-Q1:TDA4VE-Q1:Greely_Smart I2C 无 ACK 问题

Guru**** 2474200 points


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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1460967/tda4ve-q1-tda4ve-q1-greely_smart-i2c-no-ack-issue

器件型号:TDA4VE-Q1

工具与软件:

尊敬的 TI 专家:

我们将 TDA4->UB962->UB935->OVX3F 用于我们的视频线。

目前、我们发现了一个发生在 小概率事件中的问题。

我们正在尝试写入 IQ 寄存器、有时 I2C 波形会写入第一个数据。

这是我们的摄像头地址之一,但之后没有 ACK   

253ms 后、soc 发送 NACK 和 STOP 信号

输入、然后  

摄像机再次成功通信

我想知道为什么超时为253ms、因为当我查看 PDK 的 I2C 驱动程序时  

           if(object->writeCountIdx != 0U)
            {
                /* set number of bytes to write */
                I2CSetDataCount(hwAttrs->baseAddr, object->writeCountIdx);

                /* set to master transmitter mode */
                regVal = I2C_CFG_MST_TX | xsa;
                if ((object->i2cParams.bitRate == I2C_1P0Mhz) || (object->i2cParams.bitRate == I2C_3P4Mhz))
                {
                    regVal |= I2C_CFG_HS_MOD;
                }

                /* wait for bus busy */
                while ((I2CMasterBusBusy(hwAttrs->baseAddr) == 1) && (timeout != 0U))
                {
                    I2C_v1_udelay(I2C_DELAY_USEC);
                    if (I2C_checkTimeout(&uSecTimeout))
                    {
                        timeout--;
                    }
                }

                I2CMasterControl(hwAttrs->baseAddr, regVal);

                /* generate start */
                I2CMasterStart(hwAttrs->baseAddr);

                while ((object->writeCountIdx != 0U) && (timeout != 0U))
                {
                    /* wait for transmit ready or error */
                    while(((I2CMasterIntRawStatusEx(hwAttrs->baseAddr, I2C_INT_TRANSMIT_READY) == 0U) && \
                           (I2CMasterIntRawStatusEx(hwAttrs->baseAddr, I2C_INT_ARBITRATION_LOST | \
                                                                       I2C_INT_NO_ACK | \
                                                                       I2C_INT_ACCESS_ERROR | \
                                                                       I2C_INT_STOP_CONDITION ) == 0U)) && \
                          (timeout != 0U))
                    {
                        I2C_v1_udelay(I2C_DELAY_USEC);
                        if (I2C_checkTimeout(&uSecTimeout))
                        {
                            timeout--;
                        }
                    }

自动填充  

它将在这里等待 ACK

 /* wait for transmit ready or error */
                    while(((I2CMasterIntRawStatusEx(hwAttrs->baseAddr, I2C_INT_TRANSMIT_READY) == 0U) && \
                           (I2CMasterIntRawStatusEx(hwAttrs->baseAddr, I2C_INT_ARBITRATION_LOST | \
                                                                       I2C_INT_NO_ACK | \
                                                                       I2C_INT_ACCESS_ERROR | \
                                                                       I2C_INT_STOP_CONDITION ) == 0U)) && \
                          (timeout != 0U))
                    {
                        I2C_v1_udelay(I2C_DELAY_USEC);
                        if (I2C_checkTimeout(&uSecTimeout))
                        {
                            timeout--;
                        }
                    }

超时应约为1ms*timeout*1000、我们给出 timeout=50000

这应该是一个很长的时间。

#define I2C_DELAY_USEC  ((uint32_t) 250u)

static void I2C_v1_udelay(uint32_t delay)
{
    volatile uint32_t del = delay;

    while (del != 0U)
    {
        del = del - 1U;
    }
}

static bool I2C_checkTimeout(uint32_t *pUsecCnt)
{
    bool timeout = (bool)false;

    *pUsecCnt = *pUsecCnt + 1U;
    if (*pUsecCnt == 1000U)
    {
        *pUsecCnt = 0U;
        timeout = (bool)true;
    }

    return (timeout);
}

通过这种方式 ,我们也想知道为什么这种偶尔否定的原因,你能帮助我们分析一下吗?

但是  

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

    您好、Han、

    但是、一旦从器件收到完整数据、就应由从器件发送 ACK 或 NACK。 SoC 只是等待 ACK/NACK、如果未收到它、 驱动程序会尝试通过发送 STOP 来恢复。  

    现在关于250ms 的延迟、我们可以看到、它是 在 繁忙等待中实现的、因此超时可能会有轻微的变化、250ms 与253ms。

    此致、

    Brijesh