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**** 2337880 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、我们可以看到值按错误的顺序发送(请参阅屏幕截图)。

 

 

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

    I2caRegs.I2CFFRX.all = 0x2040;   // Enable RXFIFO, clear RXFFINT

}

 

Function:

int16 write_I2c_data ( unsigned int slave_addr, unsigned int length, unsigned char I2CRegister, unsigned char Value )

{

    int16 retval = 1;

    retval = check_BB_bit (I2C_TIMEOUT);

    if (retval < 0)

    {

        I2caRegs.I2CMDR.bit.IRS = 0;   // Timed out. Reset module.

        I2C_ Errorhandling ();

        return retval; // Abbrechen

    }

 

    /***************Write******************/

    I2caRegs.I2CSAR = slave_addr; // Setup slave address

    I2caRegs.I2CCNT = length; // Setup number of bytes to send MsgBuffer + Address

    I2caRegs.I2CDXR = I2CRegister; 

    I2caRegs.I2CDXR = Value;       

 

    // Send start as master transmitter

    I2caRegs.I2CMDR.all = 0x6E20; //gesetzt werden FREE, STT, STP, MST, TRX, IRS

 

    // -->> -- I2CMaster_Wait

    retval |= check_STP_and_BB_bit ( I2C_TIMEOUT);

    if (retval < 0)

    {

        I2caRegs.I2CMDR.bit.IRS = 0;   // Timed out. Reset module.

        I2C_Errorhandling();

        return retval; // Abbrechen

    }

    //--<<---

    return retval;

}

致电:

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

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

 

 

发送 FIFO 的溢出是否已知?

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

谢谢你。

马库斯

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

    您好、Markus:

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

    此致、

    阿米尔·奥马尔

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

    您好、Omer:

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

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

    #define I2C_SLAVE_ADDR      0x20
    #define MCP23008_GPIO       0x09
    
    write_I2c_data ( I2C_SLAVE_ADDR, 2, MCP23008_GPIO, GPIO_exp.all );


    在经过延迟后、我无法看到误差。 因此、我们假设 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行的代码。

    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;
            }
        }
        return retval;
    }
    
    int16 check_STP_bit( Uint16 timeout )
    {
        int16 retval = 1;
        while ( I2caRegs.I2CMDR.bit.STP == 1 )
        {
            DELAY_US( 1 );
            timeout--;
            if ( timeout < 1 )
            {
                retval = -1; // I2C is locked up - fatal Error!
                break;
            }
        }
        return retval;
    }


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

    好主意。 我是否也可以为此使用 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慢相同;只是因为位更多并不一定意味着它需要更长的时间(如果您比较的位数大于与汇编操作等效的位数、则可能需要更长的时间)。  我 在下面创建了一些基本伪代码:

    while(I2caRegs.I2CFFTX.TXFFST & 0xF);

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

    此致、

    阿米尔·奥马尔

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

    您好、Omer:

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

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

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

    ---

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

    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;
    

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

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

    您好、Markus:

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

    此致、

    阿米尔·奥马尔

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

    您好、Omer:

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

    此致、

    马库斯