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.

TMS320F280049C: I2C not working with optimization enabled, but working with optimisation disabled

Part Number: TMS320F280049C


In reference to the previous questions:
https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/907412/tms320f28388s-i2c-read-the-wrong-data/3362401#3362401
https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/909853/compiler-tms320f28388s-unable-to-disable-the-optimization-level-for-some-function?tisearch=e2e-sitesearch&keymatch=TMS320F28388S

In my system in Repeat Mode Master Transmitter, When I run the following code:

//Flush FIFOs
I2C_disableFIFO(I2CA_BASE);
I2C_enableFIFO(I2CA_BASE);

//Setup how many bytes to send
//I2C_setDataCount(I2CA_BASE, 0x01);

//Put data to be transmitted in TX FIFO
I2C_putData(I2CA_BASE, byte);

//wait for the data to be sent
//ARDY is low when data is not yet sent. ARDY gets set when all data in FIFO has been sent or NACK is received
attemptCount = 1U;
while(attemptCount < 100U)
{
    if((I2C_getStatus(I2CA_BASE) & I2C_STR_ARDY) != 0U)
    {
        //all data in FIFO has been sent along with START, Device Address or NACK has been received
        //so break out of the loop
        break;
    }
    else
    {
        //all data in FIFO is yet to be sent
        //stay inside loop
        attemptCount++;
        DEVICE_DELAY_US(10);
    }
}

//Outside the loop, if ARDY is still low, that means data hasn't been sent yet and timeout has occurred
//Exit function and return timeout error
if((I2C_getStatus(I2CA_BASE) & I2C_STR_ARDY) == 0U)
{
    //enable write protect
    GPIO_writePin(39, 1);

    return ERROR_TIMEOUT;
}

This code works fine with optimizations disabled. But when I enable optimizations, the function returns ERROR_TIMEOUT.
As explained in the links above, I can solve this issue by adding delay before checking for the ARDY for the first time. There are 2 codes that I got working:

1. Added __asm(" RPT #12 || NOP");

//Flush FIFOs
I2C_disableFIFO(I2CA_BASE);
I2C_enableFIFO(I2CA_BASE);

//Setup how many bytes to send
//I2C_setDataCount(I2CA_BASE, 0x01);

//Put data to be transmitted in TX FIFO
I2C_putData(I2CA_BASE, byte);

//wait for the data to be sent
//ARDY is low when data is not yet sent. ARDY gets set when all data in FIFO has been sent or NACK is received
attemptCount = 1U;
while(attemptCount < 100U)
{
    __asm(" RPT #12 || NOP");

    if((I2C_getStatus(I2CA_BASE) & I2C_STR_ARDY) != 0U)
    {
        //all data in FIFO has been sent along with START, Device Address or NACK has been received
        //so break out of the loop
        break;
    }
    else
    {
        //all data in FIFO is yet to be sent
        //stay inside loop
        attemptCount++;

        DEVICE_DELAY_US(10);
    }
}

//Outside the loop, if ARDY is still low, that means data hasn't been sent yet and timeout has occurred
//Exit function and return timeout error
if((I2C_getStatus(I2CA_BASE) & I2C_STR_ARDY) == 0U)
{
    //enable write protect
    GPIO_writePin(39, 1);

    return ERROR_TIMEOUT;
}

2. Moved DEVICE_DELAY_US(10);

//Flush FIFOs
I2C_disableFIFO(I2CA_BASE);
I2C_enableFIFO(I2CA_BASE);

//Setup how many bytes to send
//I2C_setDataCount(I2CA_BASE, 0x01);

//Put data to be transmitted in TX FIFO
I2C_putData(I2CA_BASE, byte);

//wait for the data to be sent
//ARDY is low when data is not yet sent. ARDY gets set when all data in FIFO has been sent or NACK is received
attemptCount = 1U;
while(attemptCount < 100U)
{
    DEVICE_DELAY_US(10);

    if((I2C_getStatus(I2CA_BASE) & I2C_STR_ARDY) != 0U)
    {
        //all data in FIFO has been sent along with START, Device Address or NACK has been received
        //so break out of the loop
        break;
    }
    else
    {
        //all data in FIFO is yet to be sent
        //stay inside loop
        attemptCount++;
    }
}

//Outside the loop, if ARDY is still low, that means data hasn't been sent yet and timeout has occurred
//Exit function and return timeout error
if((I2C_getStatus(I2CA_BASE) & I2C_STR_ARDY) == 0U)
{
    //enable write protect
    GPIO_writePin(39, 1);

    return ERROR_TIMEOUT;
}

Why is this problem coming? Any pipeline issues? Or the I2C takes some cycles to respond?

  • When optimization is enabled, the sequence in which code is feed into pipeline changes and ARDY bit is getting checked few cycles before when compared to optimization disabled. So, it is a combination of pipeline and I2C taking some cycles to respond which is causing this issue.  I would recommend using RPT instead of delay function.

  • Hi Manoj,

    I did some experiments. RPT 12 is the minimum we need with the current optimization settings. But I am not sure about the other optimization settings. What is a safe value for repeat. If it were only pipeline, then RPT 8 should have been sufficient I feel. How many extra cycles are needed by I2C? 4? How can I calculate a sure and safe value of RPT?

  • Arpan,

    What is your optimization setting?  I need to check with design team on this topic. But, it generally takes atleast 2 weeks before I expect to hear back from them.

    It essentially boils down to how many I2C module clocks does it take for ARDY bit to be cleared from previous I2C transaction.

    Regards,

    Manoj

  • Hi Manoj,

    I am using level - 2 Global optimizations with speed vs size tradeoff level- 2

    I am still not clear about ARDY bit when it goes high (as referred in the other thread). A timing diagram is must to undertstand it fully and should be included in TRM.

    Regards,
    Arpan

  • Arpan,

    I will check with design to check the number cycles it takes for ARDY bit to be set and cleared. With respect to timing diagram, the same argument can be extended any status bit and will be overwhelming include all the timing diagram for different scenarios.

    As I said before, it will takes a minimum of 2 weeks to hear back from design. I will keep you posted.

    Regards,

    Manoj