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.

[参考译文] RTOS/CC2640:I2C 批量写入:字节间隙、时钟丢失

Guru**** 2589275 points
Other Parts Discussed in Thread: CC2640, MSP430F5438A

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/703829/rtos-cc2640-i2c-bulk-write-gaps-between-bytes-clock-loss

器件型号:CC2640
主题中讨论的其他器件: MSP430F5438A

工具/软件:TI-RTOS

HY、

向 I2C 写入大容量数据(258字节)时、我看到两个奇怪的影响:

1)

有时(大约2/3的情况)、两个字节之间存在38us 的间隙

2)

在某些字节(即24)之后、一个时钟周期似乎比平常短(仅155ns)。 I2C (EEPROM)无法理解该字节、因此不会进行应答。

之后、SDA 线路保持低电平、直到出现一个新的 I2C 命令。 这似乎只发生在我的一个器件上、其他器件工作正常

1)是否有可能的改进、以及2)的根本原因是什么

此致

Harald

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Harald、
    您是否正在使用 TI-RTOS 驱动程序?
    哪个版本?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    HY Erik、

    是的、我使用 TI-RTOS 驱动程序。 我修改了现有的 bsp_i2c 文件、以便能够发送超过256字节的数据。 然后我使用

    bool bspI2cWrite (uint8_t *数据、uint32_t len)
    {
    I2C_Transaction masterTransaction;
    
    masterTransaction.writeCount = len;
    masterTransaction.writeBuf =数据;
    masterTransaction.ReadCount = 0;
    masterTransaction.readBuf =空;
    masterTransaction.slaveAddress = slaveAddr;
    
    返回 I2C_transfer (i2cHandle、&masterTransaction)= true;
    } 

    至于版本:I2C.c 文件位于文件夹中

    TI\tirtos_simplelink_2_13_00_06\packages/ti\drivers

    这是否包括驱动程序的版本? 或者在哪里可以找到有关该驱动程序的更多信息?

    此致

    Harald

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

    您好 Harald、
    自 tirtos_simplelink_2_13_00_06以来、I2C 驱动程序已进行了大量更新。 CC2640的当前版本为 tirtos_cc13xx_cc26xx_2_21_01_08。 我在发行说明中找不到任何看起来相关的项目。 我将测试更高/最新版本以验证此问题是否仍然存在。

    software-dl.ti.com/.../index.html

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

    HY Erik、

    感谢您的回答

    >我将测试最新版本以验证此问题是否仍然存在。

    是否有建议的方法? 分步移植指南?

    我对开发环境的松紧程度有点担心。 我需要支持固件的多个旧分支、每个分支都是使用我当前的工具链构建的。 此外、我可能不需要更新固件的堆栈部分。 我在现场有许多电池供电的设备、无法更新所有这些设备的堆栈和应用程序。 我是否确定在安装较新版本的 tirtos 后可以返回到原始版本? 我是否可以尝试仅更改 tirtos 的 I2C 驱动程序部分?

    此致

    Harald

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我已经看到了这种确切的症状。 当一个较高优先级的任务中断了 I2C 任务并接管了 CPU 时、发生了这个较高优先级的任务有一些工作要做。 我很确定 I2C_Transfer()没有设置中断驱动传输,而是在该过程中运行。

    在我的应用中、我通过 SPI 完成了所有繁重的数据移动(比 I2C 快100倍)。 准备就绪并需要 SPI 的器件可以发送一个 SWI (来自 HWI_Task、又名称为 ISR)、并且 SPI 总线工作可以作为一个任务开始。 只有当您尝试从 ISR 执行过多操作(可能超过20微秒的工作)时、您才会遇到问题。

    此外、我们无法控制 TI-RTOS 运行的1ms 计时器中断(作为最高中断优先级)。
    嗯、实际上、我们有一些控制。 我发现、计时器中断的中断延迟太大、以至于115 KB 的 UART 中断无法始终得到服务。 我通过对工程 cfg 文件进行一些仔细的更改来修复了这一问题。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Harald、

    您能否分享一下 I2C 驱动程序本身的设置方式、它是处于回调模式还是阻塞模式?

    @ Allan

    我不希望将这种行为引入 I2C 驱动器中会有一个高优先级任务。 但是、较高优先级的 Hwi 可能会延迟数据输出、因为这是从 Hwi 上下文处理的(简而言之、所有 I2C 传输都应视为中断驱动)。

    我想知道您从哪里获取了1ms 计时器中断? 据我所知、非 CC26xx 和 CC13xx TI-RTOS 示例通过周期性系统节拍交付、但使用动态系统节拍方法(仅在需要时节拍)。 此外、典型时钟周期设置为10us。 我知道 SimpleLink 系列中还有其他器件利用1ms 系统时钟周期、您当时在哪个器件上工作?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、M-W、

    我成功保存并找到了一个图像... 这是四个月前开发的 MSP430F5438A 产品、该产品在其内部8MHz 时钟上运行。  

    在上图中、我捕获了一个 I2C 传输、其持续时间显然为12.5ms (根据时序标记 A1和 A2)。  在此期间、SCL 时钟恰好每1ms 延长一次、持续时间约为100us。   我检测了 ISR 中的每一个、(备用 GPIO 引脚上有时序信号)、并确定它不是 ISR、而是 TI-RTOS 的1ms 计时器中断。   我找到了该代码、并且看到它每1ms 作为 NMI (不可屏蔽中断)运行一次。

    我知道系统节拍可以以不同的间隔运行、并且可以是动态的。  这是一个项目 cfg 文件设置。  是的,我本来可以改变它,但是,这不能解决我的问题--只能减少它的频率。

    I2C 器件运行状况良好、我不会丢失数据(我认为)。  在本例中、问题是中断延迟太差、我在115kB 器件上丢失了 UCS_A2接收器中断。   来自另一个器件的此字符流至关重要、因为协议没有错误检测或重试。

    我必须降低周期性系统节拍的中断延迟。  我最终以两种方式解决了该问题。  首先、我对项目 cfg 文件进行了填入、并使周期性系统 tick 函数减少了。  (通过关闭代码计时选项以及我不记得确切细节的另一个选项)。   其次、我们进行了 PCB 修复、并安装了连接到 XT2IN 和 XT2OUT 的外部晶体、现在以12MHz 的 SMCLK 运行 MSP430。

    我们减少了中断延迟、运行周期系统节拍函数的时间减少到大约60us。 (或者现在更少--我没有在几个月内计时)。  我还检查了所有自有 ISR 的中断延迟、并验证它们通常在10us 至20us 内运行。

    很抱歉 Harold、这对您来说有点偏离主题。  在您的案例中、SCL 信号被严重改编、在我的案例中、它被扩展。

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

    HY M-W、

    >您能否分享 I2C 驱动程序本身的设置方式,它是处于回调模式还是阻塞模式?

    基本上、我使用来自传感器标签示例 I2C 的所有标准调用、处于阻塞模式:

    /*默认 I2C 参数结构*/
    const I2C_Params I2C_defaultParams ={
    I2C_MODE_BLOCKING、/* TransferMode */
    null、 /* transferCallbackFxn */
    I2C_400kHz、 /*比特率*/
    null /*定制*/
    };
    void I2C_init (void)
    {
    if (I2C_count =-1){
    /*调用每个驱动程序的初始化函数*/
    对于(I2C_COUNT = 0;I2C_CONFIG[I2C_COUNT].fxnTablePtr!= NULL;I2C_COUNT++){
    I2C_CONFIG[I2C_COUNT].fxnTablePtr->initFxn ((I2C_Handle)&(I2C_CONFIG[I2C_COUNT]);
    }
    }
    
    void I2C_Params_init (I2C_Params *参数)
    {
    *参数= I2C_defaultParams;
    }
    I2C_Handle I2C_open (unsigned int index、I2C_Params *参数)
    {
    I2C_Handle 句柄;
    
    /*获取此驱动程序实例的句柄*/
    句柄=(I2C_Handle)&(I2C_CONFIG[index]);
    
    return (handle->fxnTablePtr->openFxn (handle、params));
    }
    
    void bspI2cInit(void)
    {
    semaphore_Params semParametersMutex;
    
    //创建保护 Semaphore
    Semaphore_Params_init (&semsMutex);
    semParametersMutex.mode = semMutote_mode_1
    ;semSemaphore (semmutex);paramsemmutex (1)
    
    //重置 I2C 控制
    器 HapiResetPeripheral (PRCM_Periph_I2C0);
    
    I2C_init ();
    I2C_Params_init (&i2cParams);
    i2cParams.bitrate = I2C_400kHz;
    i2cHandle = I2C_open (Board_I2C、 &i2cParams);
    
    //初始化局部变量
    slaveAddr = 0xFF;
    接口= BSP_I2C_interface_0;
    
    if (i2cHandle = NULL)
    {
    Task_exit();
    }
    

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

    这说明了您在谈论的计时器。 但是、对于 CC13xx 和 CC26xx、情况并非如此、因为系统节拍默认设置为10us/节拍、且具有动态设置(仅当应用实际需要时才会获得中断)。 我对 MSP430系列完全不熟悉、我将记住您在未来学到的知识、感谢您的分享!

    要返回到您的主题 Harald、您现在看到的两个字节之间的延迟可以连接到执行其他操作的系统。 传输是中断驱动程序、但此时可能会有另一个 Hwi 运行、这会延迟 I2C 驱动程序。

    我必须更仔细地查看奇怪的时钟周期。 我将尝试进行测试并查看是否可以重现测试。 由于它仅发生在您的一个器件上、因此很可能与硬件相关、并且是特定电路板的问题。