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 communication issue with camera module board

Part Number: TDA4VH-Q1

Hello ,

Below is my hardware and software setup.

Hardware : J784SEVM <--> DS90UB9702 Fusion2 board <--> DS90UB971 Our own board <--> OX08B40 with MCU(8MP@30fps UYVY format)

Software : RTOS SDK 11.00.00.06

Our camera board have one MCU in it. I can able to communicate with this MCU properly using i2c_transaction. But while performing i2c_transaction for 64 bytes, i2c gets stuck. We could not executes codes after i2c_transaction.

Below is my i2c_transaction code

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);

Is there any limit that I2C_Transaction.writeCount should be below 64bytes?


Note: I am not facing any issue when I2C_Transaction.writeCount is less than 63bytes.

With regards,

Jeyaprakash C K.

  • Hello,

    One more point to add here.

    I have enabled CIO_DRV_CONSOLE in ti-processor-sdk-rtos-j784s4-evm-11_00_00_06/pdk_j784s4_11_00_00_21/packages/ti/drv/i2c/src/i2c_drv_log.h file.

    After that also I am not getting error message during i2c stuck. Below is the last print from this log

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

  • Hello,

    One more point observed.

    I2C transaction is stuck in while loop present in this file ti-processor-sdk-rtos-j784s4-evm-11_00_00_06/pdk_j784s4_11_00_00_21/packages/ti/drv/i2c/src/i2c_api.c

    /*
     *  ======== 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);
    
                    }
                    
    /////////////////////////////////////////
    }
                    

    If I did not check I2CBufferStatus API and continue with if(1), I could able to send more than 64 bytes.

    Please let us know the importance of I2CBufferStatus API and how this will impact when we remove this API?

    With regards,

    Jeyarpakash C K.

  • Hi Jayprakash,

    I have gone through all the points you described. I am on it.

    As i have some system issue on my side, allow me time till monday.

    I will get back to you ASAP.

    in the meantime, i would suggest you to replace that if-condition with if(1) and let me know what happens.

    Apart from this, are you using polling mode or interrupt mode in i2c?

    Thanks for being patient.

    Regards,

    Vinit

  • Hello Vinit,

    1. I have proceeded with if-condition with if(1), Some time I could complete the transaction, but some time i could not complete after few transactions. it is falling randomly.

    2. I have not configured i2c mode any where but seems this while loop where I am stuck is present in polling mode block of code.

    3. Could you please explain, how can i configure i2c mode?

  • Hi jeyaprakash,

    I have not configured i2c mode any where but seems this while loop where I am stuck is present in polling mode block of code.

    yes, seems like that.

    TI suggests using interrupt mode instead of Polling mode.

    For that, you need to configure i2c into interrupt mode like below,

    There are two changes you need to do,

    1. While configuring i2c, make interrupts enabled. 

    2. While initializing params, make transfermode as blocking mode

     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);

    Regards,

    Vinit

  • Hi Vinit,

    1. Could you please confirm impact of not checking I2CBufferStatus API and continue with if(1).

    2. How to send more than 63bytes of data without modifying low level i2c driver?

    3.  Regarding Interrupt method

    /* 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. Here what value we should give for i2cInstance? Is this same as struct IssSensor_CreateParams.i2cInstId?

    b. We applied this in I2C_transfer of our RTOS driver. Is this correct or we should apply this code in low level driver (i,e i2c_api.c)?

    Thanks 

    jeyaprakash C K

  • Could you please confirm impact of not checking I2CBufferStatus API and continue with if(1).

    As you saw earlier, 

    Random Failures: Works sometimes, fails randomly based on timing

    also, Buffer overflow, Lost data etc...

    Here what value we should give for i2cInstance? Is this same as struct IssSensor_CreateParams.i2cInstId?

    yes, the one you use.

    We applied this in I2C_transfer of our RTOS driver. Is this correct or we should apply this code in low level driver (i,e i2c_api.c)?

    apply to the application level during initialization.

    If issue still persists then i would like you to mention the mode you decide to proceed with (polling or interrupt) and provide the register dump of the moments before issue and when issue occurs,for debugging the issue.

    Regards,

    Vinit.

  • Hi Vinit,

    We have recently modified the logic in the code. We are now sending 32 bytes per I²C transaction. In addition, we reverted the if(1) change in the RTOS i2c_api.c driver and are now checking the buffer status within the RTOS I²C driver.

    Our module contains an MCU along with a sensor. To flash the MCU firmware, we send the firmware data over I²C. With the current modification, we are able to send 32 bytes per I²C transaction. Previously, the transaction size was much larger.

    We validated the MCU firmware flashing process in Linux with this modification, and it consistently succeeds. However, when running on RTOS, the flashing process fails about 95% of the time. Only 1–2 attempts out of 10 succeed.

    Since we are sending less than the 64-byte limit, we are unsure why this issue occurs. At the moment, we prefer not to modify the RTOS I²C driver.

    Could you please guide us on:

    • How we can resolve this issue ?

    • What could be the possible reasons for the high failure rate in RTOS compared to 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

       

    We would appreciate your guidance.

    Thank you, and we look forward to your response.

  • Hi jeyaprakash,

    This issue is now different than we started with initially.

    I would appreciate you to create different thread for this query.

    Thanks

    Vinit