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.

[参考译文] TDA4VH-Q1:摄像头模块板的 TDA4VH [RTOS] I2C 通信问题

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

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1620533/tda4vh-q1-tda4vh-rtos-i2c-communication-issue-with-camera-module-board

器件型号: TDA4VH-Q1

您好、

下面是我的硬件和软件设置。

硬件:J784SEVM <--> DS90UB9702 Fusion2 主板<--> DS90UB971 我们自己的主板<-->具有 MCU 的 OX08B40(8MP@30fps UYVY 格式)

软件:RTOS SDK 11.00.00.06

我们的摄像头板中有一个 MCU。 我可以使用 i2c_transaction 正确地与此 MCU 进行通信。 但在对 64 个字节执行 i2c_transaction 时、i2c 会卡住。 我们无法在 i2c_transaction 之后执行代码。

下面是我的 i2c_transaction 代码

static int32_t OX08B40_WriteReg(uint8_t    i2cInstId,
                               uint8_t    i2cAddr,
                               uint16_t   regAddr,
                               uint8_t    *regVal,
                               uint32_t   numRegs,
                               uint8_t    skip_error) {
    int32_t    status = -1;
    I2C_Handle sensorI2cHandle = NULL;
    static uint8_t sensorI2cByteOrder = 255U;
    getIssSensorI2cInfo(&sensorI2cByteOrder, &sensorI2cHandle);
    if (sensorI2cHandle == NULL)
    {
        printf("Sensor I2C Handle is NULL \n");
        return -1;
    }

    I2C_Transaction i2cTransaction;

	I2C_transactionInit(&i2cTransaction);
	i2cTransaction.slaveAddress = i2cAddr;
	i2cTransaction.writeBuf = regVal;
	i2cTransaction.writeCount = numRegs;
	i2cTransaction.readBuf = NULL;
	i2cTransaction.readCount = 0;
	status = I2C_transfer(sensorI2cHandle, &i2cTransaction);
	if(FALSE == status)
	{
		printf("\n %s (%d) I2C Data Transfer failed. \n", __func__, __LINE__);
	}

    return (status);
}

I am getting stuck in below line
status = OX08B40_WriteReg(i2cInstId, i2cAddrSensor, 0, g_bload_buf, 64, 0);

I2C_Transaction.writeCount 是否应低于 64 字节?


注意:当 I2C_Transaction.writeCount 小于 63 字节时、我不会遇到任何问题。

此致、

Jeyaprakash C K.

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

    您好:

    这里还需要补充一点。

    我已 在 ti-processor-sdk-rtos-j784s4-evm-11_00_00_06/pdk_j784s4_11_00_00_21/packages/ti/drv/i2c/文件 中启用了 CIO_DRV_console src i2c_drv_log.h。

    之后 ,我在 i2c 卡滞期间没有收到错误消息。 下面是此日志的最后一页

    I2C:(0x2050000) Starting transaction to slave: 0x40

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

    您好:

    还观察到一个点。

    在此文件 ti-processor-sdk-rtos-j784s4-evm-11_00_00_06/pdk_j784s4_11_00_00_21/packages/ti/drv/i2c/i2c/i2c_api.c 中存在循环时、I2C 事务卡住 src

    /*
     *  ======== I2C_primeTransfer_v1 =======
     */
    static int16_t I2C_primeTransfer_v1(I2C_Handle handle,
                                     I2C_Transaction *transaction)
    {
    
    ////////////////////////
                   while ((0U != object->writeCountIdx) && (0U != timeout))
                    {
                        /* wait for transmit ready or error */
                        while(((0U == I2CMasterIntRawStatusEx(hwAttrs->baseAddr, CSL_I2C_INT_TRANSMIT_READY)) && \
                               (0U == I2CMasterIntRawStatusEx(hwAttrs->baseAddr, CSL_I2C_INT_ARBITRATION_LOST | \
                            		                                             CSL_I2C_INT_NO_ACK | \
    																	         CSL_I2C_INT_ACCESS_ERROR | \
    																			 CSL_I2C_INT_STOP_CONDITION ))) && \
                              (0U != timeout))
                        {
                            I2C_v1_udelay(I2C_DELAY_USEC);
                            if (I2C_checkTimeout(&uSecTimeout))
                            {
                                timeout--;
                            }
                        }
    
                        errStat = I2CMasterIntRawStatusEx(hwAttrs->baseAddr, CSL_I2C_INT_ARBITRATION_LOST | \
                        		                                             CSL_I2C_INT_NO_ACK | \
    																		 CSL_I2C_INT_ACCESS_ERROR);
                        /* if we get an error, do a stop and return failure */
                        if (UFALSE != errStat)
                        /* if we get an error, do a stop and return failure */
                        {
                           fatalError = UTRUE;
                           break;
                        }
                        /* write byte and increase data pointer to next byte */
                        
    /////// Below if condition is not satified, hence object->writeCountIdx is not decrementing to 0, while loop continues forever///////////////////////////                   
                        
                        if(0U < I2CBufferStatus(hwAttrs->baseAddr,CSL_I2C_TX_BUFFER_STATUS))
                        {
                            I2CMasterDataPut(hwAttrs->baseAddr, *(object->writeBufIdx));
                            (object->writeBufIdx)++;
    
                            /* clear transmit ready interrupt */
                            I2CMasterIntClearEx(hwAttrs->baseAddr, CSL_I2C_INT_TRANSMIT_READY);
    
                            /* update number of bytes written */
                            object->writeCountIdx--;
                        }
                        printf("%s(%d)object->writeCountIdx = %d, timeout = %d\n",__func__,__LINE__,object->writeCountIdx,timeout);
    
                    }
                    
    /////////////////////////////////////////
    }
                    

    如果我没有检查 I2CBufferStatus API 并继续使用 if (1)、则能够发送超过 64 个字节。

    请告知我们  I2CBufferStatus API 的重要性、以及在我们删除此 API 时这会如何影响?

    此致、

    Jeyarpakash C K.

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

    尊敬的 Jayprakash:

    我已经了解了您描述的所有要点。 我在这里。

    由于我有一些系统问题、请允许我等到星期一。

    我会尽快回到您的身边。

    同时,我建议你用 if(1) 替换 if-condition ,让我知道发生了什么。

    除此之外、您是否在 i2c 中使用轮询模式或中断模式?

    感谢您耐心等待。

    此致、

    Vinit

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

    尊敬的 Vinit:

    1.我已经 用 if-condition 处理了 if(1)、有一段时间我可以完成交易、但有一段时间我不能在几次交易后完成。 它是随机下降的。

    2.我没有在任何地方配置 i2c 模式,但似乎这当循环我被卡住在轮询模式代码块中存在。

    3.你可以解释一下,如何配置 i2c 模式?

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

    尊敬的 jeyaprakash:

    我没有在任何地方配置 i2c 模式、但似乎这是在轮询模式代码块中存在的循环。

    是的、似乎是这样。

    TI 建议使用中断模式而不是轮询模式。

    为此、您需要将 i2c 配置为如下所示的中断模式、

    您需要进行两项更改、

    1.配置 i2c 时,启用中断。  

    2.初始化参数时, 将 transfermode 作为阻塞模式

     I2C_HwAttrs i2c_cfg;
    
          /* Get current I2C configuration */
          I2C_socGetInitCfg(i2cInstance, &i2c_cfg);
    
          /* Enable interrupt mode */
          i2c_cfg.enableIntr = true;              // KEY CHANGE: Enable interrupts
    
          /* Apply the configuration */
          I2C_socSetInitCfg(i2cInstance, &i2c_cfg);
    

    /* Set parameters for interrupt mode */
          I2C_Params_init(&i2cParams);
          i2cParams.transferMode = I2C_MODE_BLOCKING;     // Blocking with interrupts
    
          /* Open handle */
          handle = I2C_open(i2cInstance, &i2cParams);

    此致、

    Vinit

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

    尊敬的 Vinit:

    1.您能否确认 未 检查 I2CBufferStatus API 所产生的影响并继续执行 if (1)。

    2.如何在不修改低级 i2c 驱动程序的情况下发送超过 63 字节的数据?

    3. 关于中断方法

    /* Set parameters for interrupt mode */
          I2C_Params_init(&i2cParams);
          i2cParams.transferMode = I2C_MODE_BLOCKING;     // Blocking with interrupts
    
          /* Open handle */
          handle = I2C_open(i2cInstance, &i2cParams);
          
    //////////////////////////////////////
    Here what value we should give for i2cInstance. Is this same as IssSensor_CreateParams.i2cInstId?

    a.这里我们应该为 i2cInstance 提供什么价值? 这是否与结构 Isis.Params.i2cInstId 相同 Sensor_Create?

    B.我们在   RTOS 驱动程序的 I2C_transfer 中应用了此函数。 这是正确的还是我们应该在低级驱动程序 (i、e i2c_api.c) 中应用此代码?

    谢谢  

    jeyaprakash C K

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您能否确认 未 检查 I2CBufferStatus API 所产生的影响并继续执行 if (1)。

    正如您之前所看到的、  

    随机失效: 有时有效、根据时序随机失败

    此外、缓冲区溢出、数据丢失等...

    在这里我们应该为 i2cInstance 提供什么值? 这是否与结构 Isis.Params.i2cInstId 相同 Sensor_Create?

    是的、您使用的就是这个。

    我们在   RTOS 驱动程序的 I2C_transfer 中应用了此函数。 这是正确的还是我们应该在低级驱动程序中应用此代码 (i、e i2c_api.c)?

    在初始化期间应用于应用程序级别。

    如果问题仍然存在、那么我想您提到您决定继续(轮询或中断)的模式、并提供问题发生前和问题发生时的寄存器转储、以便调试问题。

    此致、

    Vinit。

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

    尊敬的 Vinit:

    我们最近修改了代码中的逻辑。 我们现在正在发送 每个 I²C μ s 事务 32 字节 。 此外、我们恢复了if(1) RTOSi2c_api.c 驱动程序中的更改、现在正在检查 RTOS I²C 驱动程序中的缓冲器状态

    我们的模块包含 一起使用的 MCU 。 I²C 刷写 MCU 固件、我们通过 μ s 发送固件数据。 通过当前修改、我们可以发送 每个 I²C μ s 事务 32 字节 。 以前、事务规模要大得多。

    我们通过此修改验证了 Linux 中的 MCU 固件刷写过程、然后进行了验证 始终成功 。 但是、在 RTOS 上运行时、刷写过程会完成 大约 95%的时间发生故障 。 系统 10 次中 1–2 次尝试 成功。

    我们正在发送数据 64 字节限制 、我们不确定为什么会出现此问题。 现在、我们更喜欢 请勿修改 RTOS I²C 驱动程序

    请您指导我们:

    • 如何解决此问题?

    • 可能是什么 RTOS 中高故障率的可能原因 与 Linux 相比?

      [MCU2_0]   2797.707673 s: size: 51 (i=19) ERASE Sector 20 success !! 
      [MCU2_0]   2797.707706 s: mcu_bload_erase_flash(999) 
      [MCU2_0]   2797.707732 s: mcu_bload_erase_flash(884) 
      [MCU2_0]   2797.732008 s: size: 3 (i=20) ERASE Sector 21 success !! 
      [MCU2_0]   2797.732041 s: mcu_bload_erase_flash(999) 
      [MCU2_0]   2797.732064 s: Erase Flash Success !! 
      [MCU2_0]   2797.750962 s: Updated Flash Addr = 0x08000000 
      [MCU2_0]   3023.134113 s: Updated Flash Addr = 0x08010000 
      [MCU2_0]   3248.413112 s: Updated Flash Addr = 0x08020000 
      [MCU2_0]   3473.693115 s: Updated Flash Addr = 0x08030000 
      [MCU2_0]   3698.970125 s: Updated Flash Addr = 0x08040000 
        3913.996261 s: ISS: ERROR: Initializing sensor [OX08B40_UB971_ECON] failed !!!
        3913.996297 s: ISS: Initializing sensor [OX08B40_UB971_ECON] ... Done !!!
      Error initializing sensor OX08B40_UB971_ECON 
      [MCU2_0]   3913.995946 s: mcu_bload_parse_send_cmd(1158) : OX08B40_WriteReg/OX08B40_ReadReg failed with status = -5
      [MCU2_0]   3913.995997 s: Error in Processing Commands 
      [MCU2_0]   3913.996030 s: Program FLASH Success !! - CRC = 0x0088 
      [MCU2_0]   3913.996064 s:  Write Flash FAIL !! 
      [MCU2_0]   3913.996083 s: Error updating firmware 
      [MCU2_0]   3913.996112 s: OX08B40_Config(1652) mcu_firmware_check failed
      [MCU2_0]   3913.996135 s: IM_SENSOR_CMD_CONFIG returning status = -1
        3914.158498 s: ISS: Starting sensor [OX08B40_UB971_ECON] ... !!!
      [MCU2_0]   3914.158602 s: ImageSensor_RemoteServiceHandler: IM_SENSOR_CMD_STREAM_ON 
      [MCU2_0]   3914.158670 s: IM_SENSOR_CMD_STREAM_ON:  channel_mask = 0x01
      x
      ^C
      Clean up and exit while handling signal 2
      Application did not close some rpmsg_char devices
      REMOTE_SERVICE: RX: mcu2_0 -> mpu1_0 (port 21) cmd = 0x00000004, prm_size = 384 bytes ... Failed !!!
        3925.171003 s: ISS: Starting sensor [OX08B40_UB971_ECON] failed !!!
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_0 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_1 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_0 (port 21) cmd = 0x00000006, prm_size = 416 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_1 (port 21) cmd = 0x00000006, prm_size = 416 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu4_0 (port 21) cmd = 0x00000006, prm_size = 416 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_1 (port 21) cmd = 0x00000007, prm_size = 36 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_0 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_1 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu3_0 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu3_1 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu4_0 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu4_1 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> c7x_1 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> c7x_2 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> c7x_3 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> c7x_4 (port 21) cmd = 0x00000002, prm_size = 12 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_0 (port 21) cmd = 0x00000006, prm_size = 416 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu2_1 (port 21) cmd = 0x00000006, prm_size = 416 bytes
      REMOTE_SERVICE: TX: FAILED: mpu1_0 -> mcu4_0 (port 21) cmd = 0x00000006, prm_size = 416 bytes
      root@j784s4-evm:/opt/vision_apps# ^C
      root@j784s4-evm:/opt/vision_apps# [MCU2_0]   3929.796777 s: Error writing 0x01 to de-serializer(0x3d) register 0x4c!
      [MCU2_0]   3929.796849 s:  Deserializer Error: Reg Write Failed for regAddr 0x4c, cnt = 0
      [MCU2_0]   3929.796876 s: End of deserializer config 
      root@j784s4-evm:/opt/vision_apps# [MCU2_0]   3945.438664 s: Error writing 0x01 to de-serializer(0x30) register 0x4c!
      [MCU2_0]   3945.438709 s:  Deserializer Error: Reg Write Failed for regAddr 0x4c, cnt = 0
      [MCU2_0]   3945.438736 s: End of deserializer config

       

    我们感谢您的指导。

    感谢您、我们期待您的答复。

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

    尊敬的 jeyaprakash:

    这个问题现在与我们最初开始时的问题不同。

     希望您为此查询创建不同的线程。

    谢谢

    Vinit