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.

[参考译文] MSP432E401Y:在 UDMA 控制下、I2C 向 TMP117发送数据

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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1027378/msp432e401y-i2c-transmit-to-tmp117-under-udma-control

器件型号:MSP432E401Y
主题中讨论的其他器件: TMP117

这 是九个月前在后火炉上放置的前一个线程的延续、我最终将再次查看。  我的系统使用 MSP432E401Y 通过 SPI 和 UART 接口控制和读取多个不同器件的数据。  我当前在 CPU 控制下从 SPI 器件读取数据、但 UART 速度很慢、在传输过程中无法承受 CPU 延迟、因此我使用 uDMA 将数据从传感器移动到内部存储器。

我需要在系统中添加一个温度传感器、我正在考虑使用具有 I2C 接口的 TMP117。  我购买了 TMP117 EVM、并将其用蓝色线连接到我的 MSP432板上以进行测试和代码开发。  I2C 总线也太慢、无法通过 CPU 执行传输、因此我也想使用 uDMA。  我创建了一个非常简单的项目、目标是采取婴儿措施、以获得功能齐全的解决方案。  以下是 main()例程的代码:

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <ti/devices/msp432e4/driverlib/driverlib.h>
#include "common.h"
void main(void)
{
uint32_t g_ui32SysClock; // The system clock frequency
int32_t status;
tempReady = false;
g_ui32SysClock = init_CLK(); // configure system clock
init_GPIO(); // configure the device pins
int_disable();
status = init_temp_I2C(g_ui32SysClock); // configure temperature sensor I2C interface
status = init_temperature(); // initialize temperature driver parameters
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

我的第一步 是使用 CPU 写入配置和读取/写入函数。  首先,init_temp_I2C()函数启用 I2C 外设,然后 init_temperatures ()配置 TMP117并开始数据采集。  当 TEMP_DRDY 中断触发 tempReadyFxn() ISR 读取数据时。  最后, 当 I2C 传输完成时,tempCallBack()回调会设置 tempReady 信标。  使用此代码、我可以成功地从 TMP117捕获数据。

下一步是在 I2C、TMP117和 UDMA 由 CPU 初始化后使用 UDMA 来捕获数据。 我使用   了 Resource Explorer 中的 i2c_master_dma_fifo 和 i2c_mastermode_fifodma_transfer 示例作为指南。

下面的图表解释了 TMP117的数据传输协议:

当主器件(MSP432)驱动 SDA 线路时、灰色框显示;当 TMP117驱动线路时、白色框显示。

我的数据传输比显示的要简单、因为我始终从相同的寄存器地址读取数据、每次传输都不需要发送寄存器地址。  相反、MSP432只需要通过 SDA 发送一个字节、然后 TMP117将使用两个字节进行回复。  因为传输的数据太少、我认为我不需要使用 FIFO。  TMP117以500ms 的速率进行采样、但 MSP432仅以1S 的速率记录温度数据、因此我不介意我是否覆盖尚未记录的数据。

随附的项目文件显示了我的测试的当前状态。  在这个非常简单的代码中、我使用  init_temp_I2C()和 init_temperated() 来初始化 I2C 外设和 TMP117。  接下来、我将尝试启用和配置 UDMA 外设、并从 I2C 总线发送一个字节。  函数 ConfigureuDMATX()的目的是将 uDMA 通道23映射 到 I2C5,并将 单个字节的转码器从 sendMasterTxData 指向的内存初始化为 I2C5主数据寄存器,然后我希望该数据寄存器在 I2C5SDA 上传输。

Fullscreen
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void ConfigureuDMATX(void)
{
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
while(!(MAP_SysCtlPeripheralReady(SYSCTL_PERIPH_UDMA))){}
MAP_uDMAEnable();
MAP_uDMAControlBaseSet(pui8ControlTable);
MAP_uDMAChannelAssign(UDMA_CH23_I2C5TX);
MAP_uDMAChannelAttributeDisable(UDMA_CH23_I2C5TX, UDMA_ATTR_USEBURST |
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
MAP_uDMAChannelControlSet(UDMA_CH23_I2C5TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_NONE |
UDMA_ARB_1);
MAP_uDMAChannelTransferSet(UDMA_CH23_I2C5TX | UDMA_PRI_SELECT,
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

最后、我调用 map_uDMAChannelRequest (UDMA_CH23_I2C5TX)来执行传输。

很遗憾, 在执行 MAP_uDMAChannelRequest()后,我看不到 I2C 总线上的传输。

如果能帮助您解决这个问题、我将不胜感激。  我不知道我是否错误地配置了 UDMA、或者错过了一些关键的初始化 Conde。

谢谢、

-Phil

e2e.ti.com/.../i2c_5F00_dma_5F00_test.zip

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

    请参阅 MSP432E4 TRM 中的以下部分

    • 19.3.5
    • 19.3.5.2
    • 19.3.6.2

    我还建议您查看 MSP432E4 SDK 中的"i2c_mastermode_fifodma_transfer"示例。

     关于" map_I2CTxFIFOConfigSet()函数" map_I2CMasterIntEnableEx()函数"的内容

    我的建议是、首先让示例代码 I2C1在您的器件上工作。 然后更改 I2C 通道和 DMA 通道。

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

    伊斯天

    正如我在问题中所述、 i2c_mastermode_fifodma_transfer 是我参考的两个示例之一、请参阅我在上面第四段中的说明。  正如我还说过的、我不使用 FIFO。  我的 I2C 接口已经在工作、正如我在上面所描述的那样。  我的板没有可用的 I2C1引脚、我只有一个板、因此无法运行示例代码。

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

    是的、我知道。 我使用示例代码检查您的代码设置。 我能观察到的唯一区别是 FIFO 设置。

    因为您已经使其适用于 I2C、并且无法启用 I2C1。  您能否先根据 I2C5在代码上添加 FIFO 设置以查看它是否有帮助? 与我们的示例代码相比、您对代码所做的更改很少。

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

    谢谢、我将尝试使用 Xmit FIFO 并返回报告。

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

    等待您的好消息

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

    我从 i2c_mastermode_fifodma_transfer  示例开始、而不是尝试创建我自己的自定义例程。  它看起来很有希望、但只有在我运行 DMA RX 函数时设置断点时、它才有效。  如果我让它在没有断点的情况下运行、那么 I2C RX 传输会被截断。

    我正在尝试简化和清理代码、然后我将在这里报告。

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

    伊斯天

    我取得了一些有希望的进展。  我从  i2c_mastermode_fifodma_transfer.c 文件开始、并对其进行了修改以满足我的需求。  最大的更改是删除 FSM、以便更轻松地遵循代码流。

    要从 TMP117捕获数据、首先必须向寄存器地址0x01发送配置命令。  然后我从地址0x00读取数据。  最后、当 TMP117生成数据就绪中断时、我需要从地址0x00进行截断的 I2C 读取-其中一个仅发送读取从地址、然后 TMP117以两个字节进行响应。

    在我的修改后的代码(已连接)中、我首先设置 I2C 和 UDMA 用于主机传输。 接下来是一个函数 SEND_CONFIG(),它使用 I2C 主 FIFO 突发发送将配置字写入地址0x01 (配置)。 接下来、它使用 I2C 主 FIFO 单次接收到地址0x00 (TEMP_RESULT)来读回第一个温度数据字。  该数据字 按预期存储在 getMasterRxData[]中。

    SEND_CONFIG()完成后,我启用 GPIO P3中断,即 TMP117数据就绪输入。  在 GPIOP3_IRQHandler() ISR 中,我执行一 个简单的 I2C 主 FIFO 单次接收来从 TMP117读取数据。

    使用逻辑分析仪、我可以看到 I2C 总线上的预期活动。  下图显示了发生的情况。  T=0之前 SCL 和 SDA 上的活动是 SEND_CONFIG()期间的活动。  随后的 SCL 和 SDA 活动来自  GPIOP3_IRQHandler()的执行。  GPIO P3中断按预期以500ms 的间隔发生、MSP432按预期处理前四个中断。

    第五个 GPIO P3中断没有完全执行。  原因是 I2C RX FIFO 在第四个中断后填满、因此当 I2C 读取第九个数据字节时、它没有空间放入、执行开始。

    以下是 SEND_CONFIG()活动的捕捉,数据0x0BE7存储在 getMasterRxData[]中:

    这是第一个 P3中断活动:

    下面是截断的第五个 P3中断活动:

    我的问题是、DMA 为什么停止将数据从 I2C RX FIFO 移动到 getMasterRxData[]?  我认为这是我完成这项工作所需的最后一项工作。

     e2e.ti.com/.../i2c_5F00_mastermode_5F00_fifodma_5F00_transfer.c

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

    我已经回答了我自己的问题。  我没有意识到每次传输后都需要重写 UDMA 通道控制字。  该操作的开销是意外的。  我需要最大程度地减小 CPU 上的 I2C 传输负载、在可以处理 I2C 接收 FIFO 被告知保持数据之前、我似乎可以使用它。  FIFO 服务代码比重写 UDMA 控制字所需的时间更短、因此我决定停止使用 UDMA 来取代 FIFO。

     因此、我将关闭此 TT。  

x 出现错误。请重试或与管理员联系。