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.

TMS320C6678: I2C transfer blocks on a semaphore pend

Part Number: TMS320C6678

Hi all,

I started to integrate in my project i2c functionality Based on the PDK 2.0.6 example projects. The example projects are correctly working and they pass correctly.

moving the code to my project I found difficulties in performing the I2C_transfer function. in particular I debugged until i found the core going in idle when pending on a semaphore even though there was a timeout set (1000U).

In particular the point where it stuck is in the I2C_transfer_v0 function at this instruction:

if (object->operMode == I2C_OPER_MODE_BLOCKING) {
                I2C_drv_log1("\n I2C:(0x%x) Pending on transferComplete semaphore \n",
                    hwAttrs->baseAddr);

                /*
                 * Wait for the transfer to complete here.
                 * It's OK to block from here because the I2C's Hwi will unblock
                 * upon errors
                 */
                semStatus = I2C_osalPendLock(object->transferComplete, transaction->timeout);
				/* If interrupt is enabled and no specific call back routine is supplied by
				   the application, the error status is stored in object->intStatusErr.
				   Read it and return the error status accordingly */

........

I'm pretty sure there must be some compatibility/setting issue but i can't find it so far.

I merged the example .cfg with the one i'm using in my project and reproducing the example with a dedicated main file but with my project .cfg

any idea of what this issue might be?

Thank you in advance,

Best regards

Fabrizio

  • Hi Fabrizio,

    The team is notified. They will post their feedback directly here.

    BR
    Tsvetolin Shulev
  • Fabrizio,

    Your problem seems to be similar to this issue reported in MArch 2017:
    e2e.ti.com/.../585284

    Can you check if the fix discussed in that E2E thread resolves your issue.

    Regards,
    Rahul
  • Hi,

    It seems that the code in pdk_2_0_6 is already fixed and different from the 2.0.3 version.

    in this, it looks like the timeout fix is already present:

               if (object->operMode == I2C_OPER_MODE_BLOCKING) {
                    I2C_drv_log1("\n I2C:(0x%x) Pending on transferComplete semaphore \n",
                        hwAttrs->baseAddr);
    
                    /*
                     * Wait for the transfer to complete here.
                     * It's OK to block from here because the I2C's Hwi will unblock
                     * upon errors
                     */
                    semStatus = I2C_osalPendLock(object->transferComplete, transaction->timeout);
    				/* If interrupt is enabled and no specific call back routine is supplied by
    				   the application, the error status is stored in object->intStatusErr.
    				   Read it and return the error status accordingly */
    		        if (object->intStatusErr & I2C_INT_NO_ACK)
                    {
                       retVal = I2C_STS_ERR_NO_ACK;
    		        } else if (object->intStatusErr & I2C_INT_ARBITRATION_LOST)
                    { 
                       retVal = I2C_STS_ERR_ARBITRATION_LOST;
                    } else {
                       retVal = I2C_STS_SUCCESS;
    		        }
    				
    				if (semStatus == SemaphoreP_TIMEOUT) {
                     retVal = (int16_t)I2C_STS_ERR;
    				}
    				else{
    					I2C_drv_log1("\n I2C:(0x%x) Transaction completed \n", hwAttrs->baseAddr);
    
    					/* Hwi handle has posted a 'transferComplete' check for Errors */
    					if (object->mode == I2C_IDLE_MODE) {
    						I2C_drv_log1("\n I2C:(0x%x) Transfer OK \n", hwAttrs->baseAddr);
    					}
    				}
                }

    From what I can understand, in the link you kindly shared the error was generated when giving an incorrect slave address.

    In my case the address should be correct (0x50) and taken straight from the I2C example define for the I2C EEPROM address:

        I2C_init();
    
        I2C_Params_init(&i2cParams);
    //    i2cParams.transferMode = I2C_MODE_CALLBACK;
    
        handle = I2C_open(I2C_EEPROM_INSTANCE, &i2cParams);
    
        I2C_transactionInit(&i2cTransaction);
        i2cTransaction.slaveAddress = I2C_EEPROM_ADDR; //0x50
        i2cTransaction.writeBuf = (uint8_t *)&txBuf[0];
        i2cTransaction.writeCount = I2C_EEPROM_ADDR_SIZE; // 2 bytes
        i2cTransaction.readBuf = (uint8_t *)&rxBuf[0];
        i2cTransaction.readCount = I2C_EEPROM_TEST_LENGTH; // 10 bytes
        i2cTransaction.timeout   = I2C_TRANSACTION_TIMEOUT; // 1000U
        transferStatus = I2C_transfer(handle, &i2cTransaction);

    do you think is it the same issue?

    Thank you very much for your answer.

    Best Regards,

    Fabrizio

  • Here is a snapshot of the I2C registers

    any idea of what it can be happened?

    Thanks,

    Fabrizio

  • Hi,

    any news on this? It would be pretty urgent, please.

    Thank you in advance,
    Best regards

    Fabrizio