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.

RDK3.2 VPS i2c driver issue

Now I have trouble r/w to MT9P031 image sensor.
Hardware is verified. Linux application can r/w to the sensor without any issue.

When the iss driver tries to write a word to the sensor, after the slave address is sent, there is huge delay, the SCL is streched low in that priod, which lasts about 5 seconds, before the payload is eventually put on the i2c bus.

  

I finally traced it down to Vps_i2cTransferMsgInt() function, it's stuck at Semaphore_pend(instObj->completionSem, i2cXferParams->timeout). however if I read i2c interrupt registers from Linux, the interrupt bits appear set(0x1410).
I tried polling mode, it has its own issue. 

The only thing I changed from stock rdk3.2 is that MT9P031 sensor uses 8 bit register address,compared to AR0331's 16bit, so I changed Iss_deviceRead16/Iss_deviceWrite16 to reflect that.

How did you guys get the i2c to work? I have wasted two days on this stupid issue.

  • It's not 5 seconds, it's 115 seconds! very consistent.

    And eventually the read routine did return expected result, so the isr was called, but what's causing the delay?

  • I finally made some change to the i2c driver and got it to work. I still have no idea why the interrupt mode didn't work.

    hdvpss -> vpsdrv_deviceI2c.c

    -        i2cInitParams[i2cId].opMode = I2C_OPMODE_INTERRUPT;
    +        i2cInitParams[i2cId].opMode = I2C_OPMODE_POLLED;//I2C_OPMODE_INTERRUPT;

    hdvpss -> psp_i2cdrv.c

     /* Enable interrupts, if required */
    -    if (instObj->opMode == I2C_OPMODE_INTERRUPT)
    +    //if (instObj->opMode == I2C_OPMODE_INTERRUPT)
         {
    -        I2C_WRITE_REG_WORD(I2C_IE_XRDY | I2C_IE_RRDY |I2C_IE_ARDY |
    +        I2C_WRITE_REG_WORD(I2C_IE_XRDY | I2C_IE_XUDF | I2C_IE_RRDY |I2C_IE_ARDY |
                         I2C_IE_NACK | I2C_IE_AL, &instObj->i2cRegs->I2C_IRQENABLE_SET);
         }