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.

[参考译文] MSPM0G3507:具有 DMA 高电流的 I2C

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1308960/mspm0g3507-i2c-with-dma-high-current

器件型号:MSPM0G3507
主题中讨论的其他器件:SysConfig

您好!

我们之前在具有 FIFO 的控制器模式下使用 I2C 与电路板上的另一个芯片定期通信、并在不需要通信的情况下在 STANDBY1模式下使用 I2C。 典型 I2C 交换的大致格式如下、交换的周期性100ms 和交换持续时间、包括软件开销小于1ms。 MCU 在剩余的99ms 内处于休眠状态。 整个板的平均电流消耗~250uA。

发送写地址+发送我们要访问的2字节寄存器 ID +重启+发送读取地址+读取8字节数据。

但现在、我们希望切换到一次接收10个字节的数据。 I2C FIFO 最多只能有8个字节、因此我们切换到 DMA 以便仅进行接收。  按如下所示配置了 I2C+DMA 并且其工作正常、我们得到预期的10字节数据:

  • DMA 事件2上的 I2C 中断
  • I2C RX FIFO 级别>= 1字节
  • DMA 事件2触发=控制器 RX FIFO 触发
  • 修正了地址到块地址。 源为 I2C1.MASTER.MRXDATA、目标地址为 RAM 中的某个缓冲区。
  • 源和目的长度=字节
  • 待传输数目= 10
  • DMA 传输模式单路

正如我说过的、I2C 通信按预期运行。 但电流消耗从250uA 跃升至~μ A 1.8mA。 我通过围绕 WFI 指令切换引脚来确认、MCU 在~99ms 内确实处于睡眠状态、此时它不进行任何 I2C 交换。 通常我只是  在睡眠前调用 DL_I2C_disableController (),而不是使用 DL_I2C_disablePower ()完全禁用 I2C 外设,但我也尝试过这样做,而且功耗没有变化。

我将在每次10字节传输之前设置一次 DMAEN。 当 DMA 传输完成时、我已经确认:

  • DMAEN 被自动设回0
  • 使用 DL_I2C_IIDX_CONTROL_EVENT2_DMA_DONE 命中 I2C 中断
  • 未命中其他 I2C 中断

我怀疑 DMA 中的某些内容会使 CPU 的某些部分保持唤醒状态、从而导致高电流消耗。 已确认我是否仅在 DL_DMA_enableChannel ()调用中添加功耗降至~0.2mA。 但我找不到直接禁用/复位 DMA 的方法、所以我很困。

由于此电流消耗超出了我们的应用预算、请帮助我们。

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

    您好、 Florin:

    这有点奇怪、如果有任何反馈、请告知我、也许您可以尝试一下。

    您是否可以在进入低功耗模式之前尝试手动禁用 DMA 通道:

    void DL_DMA_disableChannel (DMA_Regs * DMA、uint8_t channelNum)。

    如果不起作用、请 在进入低功耗模式之前尝试此操作、手动复位 DMA 配置、包括:

    以及源和目标地址;transferSize。

    B.R.

    萨尔

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

    大家好、Sal、

    我在休眠前添加了以下代码:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    static const DL_DMA_Config gDMA_I2cConfig = {
    .transferMode = DL_DMA_SINGLE_TRANSFER_MODE,
    .extendedMode = DL_DMA_NORMAL_MODE,
    .destIncrement = DL_DMA_ADDR_INCREMENT,
    .srcIncrement = DL_DMA_ADDR_UNCHANGED,
    .destWidth = DL_DMA_WIDTH_BYTE,
    .srcWidth = DL_DMA_WIDTH_BYTE,
    .trigger = DMA_I2C1_RX_TRIG,
    .triggerType = DL_DMA_TRIGGER_TYPE_EXTERNAL,
    };
    DL_DMA_disableChannel(DMA, DMA_I2c_CHAN_ID);
    DL_DMA_initChannel(DMA, DMA_I2c_CHAN_ID , (DL_DMA_Config *) &gDMA_I2cConfig);
    DL_DMA_setDestAddr(DMA, DMA_I2c_CHAN_ID, 0);
    DL_DMA_setSrcAddr(DMA, DMA_I2c_CHAN_ID, 0);
    DL_DMA_setTransferSize(DMA, DMA_I2c_CHAN_ID, 0);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    行为没有变化。 不清楚的是、您是希望我使用我针对 I2C 的配置还是您针对 ADC 的配置来尝试重新创建 DMA。 我尝试了两种方法、它们都以相同的方式工作。 我已经尝试调用 DL_DMA_disableChannel ()在上面的代码块的开头和结尾。 我也尝试过调整源/目标地址/传输大小、将它们逐个转换为非0。

    我的任何尝试都没有变化。

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

    您好、 Florin:

    很抱歉描述的细节有误导性。

    请在进入低功耗模式之前尝试以下方法:

    Fullscreen
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    static const DL_DMA_Config gDMA_I2cConfig = {
    .transferMode = DL_DMA_SINGLE_TRANSFER_MODE,
    .extendedMode = DL_DMA_NORMAL_MODE,
    .destIncrement = DL_DMA_ADDR_UNCHANGED,
    .srcIncrement = DL_DMA_ADDR_UNCHANGED,
    .destWidth = DL_DMA_WIDTH_BYTE,
    .srcWidth = DL_DMA_WIDTH_BYTE,
    .trigger = DMA_SOFTWARE_TRIG,
    .triggerType = DL_DMA_TRIGGER_TYPE_EXTERNAL,
    };
    DL_DMA_initChannel(DMA, DMA_I2c_CHAN_ID , (DL_DMA_Config *) &gDMA_I2cConfig);
    DL_DMA_setDestAddr(DMA, DMA_I2c_CHAN_ID, 0);
    DL_DMA_setSrcAddr(DMA, DMA_I2c_CHAN_ID, 0);
    DL_DMA_setTransferSize(DMA, DMA_I2c_CHAN_ID, 0);
    DL_DMA_disableChannel(DMA, DMA_I2c_CHAN_ID);
    /* Here I want to test whether set the DMA register as default reset value and then the power consumption will be lower */
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    在此、我要测试是否将 DMA 寄存器设置为默认复位值、然后功耗会更低。

    我还有其他一些建议-请在进入低功耗模式之前重置 I2C、看看它是否有用。

    Fullscreen
    1
    2
    /* reset I2C and then enter low power mode */
    DL_I2C_reset(I2C_0_INST);
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    期待您的反馈。

    B.R.

    萨尔

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

    大家好、Sal、

    我已经尝试了您的建议、没有任何变化。 即使使用 DL_I2C_RESET ()也不例外。 通过调用  DL_I2C_disablePower ()尝试了更多操作,没有变化。

    过去、我们遇到了 UART 的 DMA 相关问题、但在遇到此 I2C 问题时该 UART 未运行。 当 MCU 处于睡眠状态时、DMA 将保持开启状态、增加的电流消耗与此问题非常相似。 我发现对 UART 有效的是 在睡眠前调用 DL_UART_disableDMATransmitEvent ()。 不同之处在于对于 UART,我们使用 DL_UART_Main_disablePower ()完全禁用外设,而对于 I2C,我们仅使用  DL_I2C_disableController ()禁用控制器。

    但是对于 I2C 调用类似的接口 DL_I2C_clearDMAEvent ()没有帮助,就像对 UART 一样。

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

    您好、 Florin:

    感谢您的反馈。

    我会按照您的描述进行测试。 反馈可能需要一些时间。 感谢您的耐心等待。

    如果有任何进展、请与我同步。

    B.R.

    萨尔

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

    您好、Florin:

    为了 帮助确认此问题、您是否可以将您的 SysConfig 文件上传到 TI Drive 的以下链接? 如果可能、还上传与 I2C+DMA 相关的 C 代码。

    tidrive.ext.ti.com/.../df6adfdc-9a81-42bb-8917-568be50a1ad9  访问代码:v5Fk3i=Y

    请在您完成此操作后告诉我。 谢谢!

    此致、

    皮克尔

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

    e2e.ti.com/.../i2c_5F00_controller_5F00_DMA_5F00_rw_5F00_multibyte_5F00_fifo_5F00_interrupts_5F00_LP_5F00_MSPM0G3507_5F00_nortos_5F00_ticlang.7z

    您好、 Florin:

    请查看随附的 I2C+DMA 示例项目、在我看来、总电流大约为40uA、请参考这个与您项目一起的演示。

    此致、

    皮克尔

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

    你好,pickle,

    感谢您再次来到我这里介绍您的演示项目。 我无法更早提供请求的代码。 我刚刚对它进行了测试、它的确如预期的那样工作、但是当把同样的线路输入我的应用时、它不再工作、这意味着它仍然处于~μ A 的1.8mA 消耗。 我尝试逐步将应用程序的一部分添加到您的演示项目中来查看损坏情况、最终我得以跟踪我的问题。

    事实证明、我已经为 UART 配置了另一个仅用于某些测试模式的 DMA 通道。 因此、UART 外设本身已禁用、在我将 I2C 切换到 DMA 之前、这种方式对电流消耗没有问题。 发生的情况是、当 I2C 触发 DMA 时、即使 UART 外设被禁用、由于连接到 UART 的其他 DMA 通道、DMA 随后也会保持"唤醒"。

    因此,为了解决我的问题,我需要做的是调用 UART 外设上的 DL_UART_disableDMATransmitEvent ()以"禁用"其 DMA 通道(当 UART 启用时,否则它将不起作用),然后调用 DL_I2C_disableController ()就足够了。 甚至不需要 DL_I2C_disableDMAEvent ()。 结果是具有 DMA 的 I2C 正常工作、我返回到通常的~200uA 功耗。

    综上所述、当您触发 DMA 通道时、DMA 实际上会保持开启、即使您使用的通道的触发已被禁用、直到其他 DMA 通道的所有其他触发也被禁用。 这实际上不是 DMA 的问题(因为我不需要调用 DL_I2C_disableDMAEvent ()))、而是 UART 或 UART 连接到 DMA 的问题吗?  

    无论如何、这会在什么地方记录下来吗? 如果没有、是否可以向 TRM/errata 中添加有关这一点的提示? 因为对我来说,这真的不是我所期望的,其他人可能也会陷入这个陷阱。

    谢谢!

    弗洛林

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

    您好、Florin:

    我明白了、正如您所说、我会检查更多信息、然后我会将此问题报告给我们的相关团队。

    感谢您的深入研究和建议!

    此致、

    皮克尔