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 在启用优化的情况下无法工作、但在禁用优化的情况下工作

Guru**** 2539500 points


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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1056922/tms320f280049c-i2c-not-working-with-optimization-enabled-but-working-with-optimisation-disabled

器件型号:TMS320F280049C

关于前面的问题:
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

在我的系统中、当我运行以下代码时、在重复模式主发送器中:

//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;
}

此代码在禁用优化的情况下工作正常。 但是、当我启用优化时、该函数返回 ERROR_TIMEOUT。
如上面的链接中所述、我可以通过在首次检查 ARDY 之前添加延迟来解决此问题。 我可以使用2个代码:

1.添加 了__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.移动 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;
}

为什么会出现此问题? 是否存在流水线问题? 或者 I2C 需要一些周期来响应?

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

    启用优化后、代码馈入流水线的顺序会发生变化、并且在禁用优化与优化相比、ARDY 位会在几个周期前被检查。 因此、它是流水线和 I2C 的组合、需要花费一些周期来响应、这会导致此问题。  我建议使用 RPT 而不是延迟函数。

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

    您好、Manoj、

    我做了一些实验。 RPT 12是当前优化设置所需的最小值。 但我不确定其他优化设置。 什么是重复的安全值。 如果它只是管道、那么 RPT 8应该已经足够了。 I2C 需要多少个额外周期? 4? 如何计算 RPT 的确定和安全值?

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

    Arpan、

    您的优化设置是什么?  我需要向设计团队核实此主题。 但是、我通常至少需要2周时间才能听到他们的声音。

    它基本上归结为从之前的 I2C 事务中清除 ARDY 位需要多少个 I2C 模块时钟。

    此致、

    曼诺伊

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

    您好、Manoj、

    我使用级别-2全局优化、速度与大小之间进行权衡级别-2

    当 ARDY 位变为高电平时、我仍然不清楚该位(如另一个线程中所述)。 必须在 TRM 中提供完整的时序图。

    此致、
    Arpan

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

    Arpan、

    我将使用设计检查 ARDY 位的置位和清零所需的周期数。 对于时序图、同一参数可以扩展到任何状态位、并且将包含不同情形下的所有时序图、这是压倒性的。

    正如我之前所说的、至少需要2周的时间才能听到设计的声音。 我会随时向您发布。

    此致、

    曼诺伊