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.

[参考译文] TMS320F28069:I2C FIFO 溢出

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1254914/tms320f28069-i2c-fifo-overflow

器件型号:TMS320F28069

您好!

 

我们将 TMS320F28069与 I2C IO 扩展器结合使用。

有时 I2C 接口有问题。 似乎 FIFO 溢出。

应发送值0x09和值(通常为0x1C)。 在代码中、始终首先发送值0x09 (IO 扩展器的寄存器)。

通过 LogicAnalyzer、我们可以看到值按错误的顺序发送(请参阅屏幕截图)。

 

 

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Config:
void InitI2C ( void )
{
I2caRegs.I2CSAR = I2C_SLAVE_ADDR; // (0x20)
I2caRegs.I2CPSC.all = 8; // Prescaler - 10MHz
I2caRegs.I2CMDR.bit.IRS = 1;
// The prescaled frequency takes effect only when IRS is changed to 1.
I2caRegs.I2CCLKL = 7; // NOTE: must be non zero
I2caRegs.I2CCLKH = 7; // NOTE: must be non zero
// --> 100.44 kHz I2C Speed
I2caRegs.I2CFFTX.all = 0x6000; // Enable FIFO mode and TXFIFO
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

致电:

WRITE_I2C_DATA (I2C_SLAVE_ADDR,2,MCP23008_GPIO,GPIO_exp.all);

可以非常快速地调用该函数。

 

 

发送 FIFO 的溢出是否已知?

我该如何进行准确的调试?

谢谢你。

马库斯

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

    您好、Markus:

    我不知道 I2C 上有任何溢出问题。 为了进行仔细检查、您是否可以在 WRITE_I2C_DATA 函数前后使用 print 语句、以确保发送正确的参数? 如果在写入之间添加延迟、是否有任何变化? 您能否分享这两种未首先发送0x09的情况的屏幕截图?

    此致、

    阿米尔·奥马尔

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

    您好、Omer:

    感谢您提供快速反馈。 在上面的屏幕截图中、可以看到这一点(黄线)。 您可以看到首先发送0x0C、这是错误的。

    第一个数据库代码中的调用是一个定义、因此实际上不能首先发送其他值(如0x09)。

    Fullscreen
    1
    2
    3
    4
    #define I2C_SLAVE_ADDR 0x20
    #define MCP23008_GPIO 0x09
    write_I2c_data ( I2C_SLAVE_ADDR, 2, MCP23008_GPIO, GPIO_exp.all );
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    在经过延迟后、我无法看到误差。 因此、我们假设 FIFO 溢出。

    此致、

    马库斯

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

    您好、Markus:

    我看了一些用于带有 EEPROM 的 I2C 的示例、看起来通过 FIFO 进行传输时确实有延迟; 有一个 while 循环以最长的时间等待10微秒(它会检查是否接收到 NACK 或发生超时、如果出现这种情况、则会中断循环)。  您是使用轮询来确定何时写入还是中断、还是您只是尽快写入?

    此致、

    阿米尔·奥马尔

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

    您好 Omar:

    我们尽快写信。 我检查 Stopbit 和 Busybit、然后下一个周期开始。

    此致、

    马库斯

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

    尊敬的 Markus:

    我将检查轮询停止位和繁忙位是否足以等待使用 I2C 进行写入、我将在明天尝试与您联系。

    此致、

    阿米尔·奥马尔

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

    您好、Markus:

    您的方法似乎没有问题、您能否在初始帖子第73行提供该函数的函数代码? (RetVal |= CHECK_STP_AND_BB_BIT (I2C_TIMEOUT);)。 此外、由于您使用 FIFO 模式、您 是否可以尝试轮询 I2caRegs.I2CFFTX.bit.TXFFST 位来查看 FIFO 何时为空?

    此致、

    阿米尔·奥马尔

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

    您好、Omer:

    谢谢你。 这是第73行的代码。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    int16 check_STP_and_BB_bit( Uint16 timeout )
    {
    int16 retval = 1;
    retval = check_STP_bit (timeout);
    retval |= check_BB_bit (timeout);
    return retval;
    }
    int16 check_BB_bit( Uint16 timeout )
    {
    int16 retval = 1;
    while ( I2caRegs.I2CSTR.bit.BB == 1 )
    {
    DELAY_US( 1 );
    timeout--;
    if ( timeout < 1 )
    {
    retval = -1; // I2C is locked up - fatal Error!
    break;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


    该超时称为"紧急退出"。 以便主电源不能挂起。

    好主意。 我是否也可以为此使用 I2caRegs.I2CFFTX.bit.TXFFINT?

    哪一种是更好的解决方案、即对位 TXFFST 或位 TXFFINT 进行极化?

    此致、

    马库斯

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

    您好、Markus:

    由于您正在对代码使用轮询、因此最好保持轮询位的状态、所以我建议尝试 TXFFST、因为它是状态。 TXFFINT 的工作方式应相同、因为您还使能 TXFFIENA 位。

    此致、

    阿米尔·奥马尔

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

    您好、Omer:

    感谢您的答复。 关于 TXFFINT:我之所以读这个、是因为如果我还想产生一个中断、我只需要设置 TXFFIENA。  但根据我的解释、我也可以在不使用中断的情况下使用位 TXFFINT。

    TXFFST 包含5位。 对于小于1的情况、我必须进行查询。 借助 TXFFINT、我可以查询等式。 这应该会更快、更高效、对吧?

    此致、

    马库斯

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

    您好、Markus:

    TXFFST 包含5位。 对于小于1的情况、我必须进行查询。 借助 TXFFINT、我可以查询等式。 这应该会更快、更高效、对吗?

    这不完全正确、逻辑检查是等效的。 这与所说的0xf 和0x0比0b1和0b0慢相同;只是因为位更多并不一定意味着它需要更长的时间(如果您比较的位数大于与汇编操作等效的位数、则可能需要更长的时间)。  我 在下面创建了一些基本伪代码:

    Fullscreen
    1
    while(I2caRegs.I2CFFTX.TXFFST & 0xF);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    这是 类似于您以前检查其他状态位的方式的简单检查。 您只需检查发送 FIFO 何时为空、就可以进行按位与运算、没有太大的开销。

    此致、

    阿米尔·奥马尔

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

    您好、Omer:

    我修改了我的代码。 到目前为止、该测试未显示任何错误。 然而,它也只是偶尔出现以前。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    int16 check_TXFFST_FIFO_status( Uint16 timeout )
    {
    int16 retval = 1;
    while ( I2caRegs.I2CFFTX.bit.TXFFST == 0 )
    {
    DELAY_US( 1 );
    timeout--;
    if ( timeout < 1 )
    {
    i2c_timeout_counter++;
    retval = -1;
    break;
    }
    }
    return retval;
    }
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    /***************Write******************/
    I2caRegs.I2CSAR = slave_addr;
    I2caRegs.I2CCNT = length;
    I2caRegs.I2CDXR = I2CRegister;
    I2caRegs.I2CDXR = Value;
    retval |= check_TXFFST_FIFO_status ( I2C_TIMEOUT);
    if (retval < 0)
    {
    I2caRegs.I2CMDR.bit.IRS = 0; // Timed out. Reset module.
    I2C_Errorrhandling();
    return retval;
    }
    // Send start as master transmitter
    I2caRegs.I2CMDR.all = 0x6E20;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    ---

    除了使用 int16 check_TXFFST_FIFO_STATUS ( uint16超时),我还使用 int16 check_TXFFINT_bit( uint16超时)对其进行了测试。 到目前为止、这里也没有出现任何错误。

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int16 check_TXFFINT_bit( Uint16 timeout )
    {
    int16 retval = 1;
    while ( I2caRegs.I2CFFTX.bit.TXFFINT == 0 )
    {
    DELAY_US( 1 );
    timeout--;
    break;
    }
    }
    I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;
    return retval;
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    您看到某个函数或另一个函数的优点了吗?

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

    您好、Markus:

    在性能方面、它们看起来与我相当。 如果您对此非常谨慎、则可以使用 CCS 周期计数器 来查看函数的运行速度是否有任何差异。

    此致、

    阿米尔·奥马尔

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

    您好、Omer:

    感谢您的评估。 我想通过此函数修复了误差。 感谢您的支持。

    此致、

    马库斯