交易支持
需要使用 DMA 在 I2C 上传输/接收一些数据、是否有类似 UART ONE 的示例要遵循?
谢谢
Ping
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.
交易支持
需要使用 DMA 在 I2C 上传输/接收一些数据、是否有类似 UART ONE 的示例要遵循?
谢谢
Ping
尊敬的 Ping:
我们没有 uDMA 模块的特定于 I2C 的示例。 不过、您应该能够参考 UART 示例并相应地修改 I2C 的通道分配。 例如,如果您要在 uDMA 通道0上使用 I2C0RX,那么您将使用 uDMAChannelAssign () API 为 I2C0RX 配置通道0。 请参见以下示例。
uDMAChannelAssign(UDMA_CH0_I2C0RX);
uDMAChannelAttributeDisable(UDMA_CH0_I2C0RX,
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
您好、Charles
感谢您的回复!
我草拟了代码、但是它不起作用、下面是只将几个字节向下发送到 Trigger_Tx 的代码、我在需要发送一些数据时调用 I2C_I2C、这有什么问题吗? DMA 模块和 I2C 在调用 I2C_DMA_Init ()之前已经初始化。
void I2C_DMA_init(void) { // Configure the DMA channel for I2C2_BASE only uDMAChannelAssign(UDMA_CH5_I2C2TX); uDMAChannelAttributeDisable(UDMA_CH5_I2C2TX , UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK); // uDMAChannelAttributeEnable(UDMA_CH5_I2C2TX, UDMA_ATTR_USEBURST); uDMAChannelControlSet(UDMA_CH5_I2C2TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_8); uDMAChannelEnable(UDMA_CH5_I2C2TX); } void I2C_Trigger_Tx(uint8_t *TxData, uint8_t size) { while(uDMAChannelIsEnabled(UDMA_CH5_I2C2TX)) {} //wait for last Tx complete // Set the DMA source address to the transmit data buffer uDMAChannelTransferSet(UDMA_CH5_I2C2TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, TxData, (void *)(QP_I2C_BASE + I2C_O_MDR), size); uDMAChannelEnable(UDMA_CH5_I2C2TX); // Start the I2C write transmission I2CMasterSlaveAddrSet(QP_I2C_BASE,I2C_Status[I2C_CHANNEL_QP].SlaveAddr, false); // Read operation I2CMasterControl(QP_I2C_BASE, I2C_MASTER_CMD_BURST_SEND_START); }
在触发发送时、需要初始启用 DMA 通道还是延迟启用 DMA 通道? 它是否在像 UART 1那样传输后禁用? 关于 uDMAChannelControlSet 中的 uDMA_ARB_4、我打算发送至少2个字节或更多字节。
谢谢!
Ping
您好、Charles
"你是我的女人,我是你的女人,我是你的女人,我是你的女人。"
当我触发多个字节发送时、我需要调用 I2CMasterControl (QP_I2C_base、I2C_MASTER_CMD_BURST_SEND_START);之后是否仍需要调用 I2CMasterControl (QP_I2C_base、I2C_MASTER_CMD_BURST_SEND_CONT)以及 I2CMasterControl (QP_I2C_BASE_SEND_STATE、I2C_MASTER_CMD_BURST_ST_CMD_BURST_ST_STEURE_SCURE_END)? 具体取决于剩余的字节数?
顺便说一下、使用上述代码、我看到从器件地址写入总线上、然后是数据0、而不是更多。
是否在传输后禁用 DMA 通道? 我应该始终启用它、还是仅在传输触发之前启用它?
感谢您的回复!
Ping
当我触发多字节发送时、我需要调用 I2CMasterControl (QP_I2C_base、I2C_MASTER_CMD_BURST_SEND_START);之后是否仍需要调用 I2CMasterControl (QP_I2C_BASE、I2C_MASTER_SETT_SEND_MASTER_SEND_BST_ST_SCURE_START)? 根据剩余的字节数?
假设您将写入8个字节。 您需要致电:
将一个数据写入 I2C TXFIFO。
调用 I2C_MASTER_CMD_BURST_SEND_START
将六个数据写入 I2C TXFIFO
调用 I2C_MASTER_CMD_BURST_SEND_CONT
将最后一个数据写入 I2C TXFIFO
调用 I2C_MASTER_CMD_BURST_SEND_FINISH
不过、以上序列用于 CPU 操作。
我认为将 uDMA 用于 I2C 会更加复杂。 您需要以某种方式衡量使用 uDMA 的优势。 我想您会混合 CPU 操作、例如发送从器件地址、使用 I2CMasterControl 设置控件以及调用 uDMA 以将数据传输到 FIFO。 如果您要传输两个字节的数据、我认为 uDMA 不能提供您所寻求的优势。 不过、我没有基准来量化它。 您可能希望尝试仅使用 CPU、而不是混合使用 CPU 和 uDMA、并查看是否获得正确的吞吐量。
顺便说一下、使用上述代码、我看到从器件地址写入总线上、然后是数据0、而不是更多。
[/报价]您打算写入数据0还是 TXFIFO 中没有数据? 我建议您从简单的 uDMA 设置开始、例如只发送一个字节、并使其首先工作、然后将其扩展。 正如我说过的、进行诸如一个或两个字节的传输之类的几个字节可能无法显著提高吞吐量、因为 CPU 仍需要进入以控制 I2C 状态机。
感谢您的讲解和耐心、Charles
CPU 操作目前已在产品中实现、我最近的任务是使用 DMA 重写它们、正如您所说的那样更加复杂、目前、我 还没有达到可以比较其优势的程度、直到 它开始工作为止。
那么关于如何触发 DMA 传输的序列、似乎这就是它不起作用的原因、正如您建议的、我们现在只会进行1字节传输-对于我的前一个触发代码、我想知道什么是正确的序列、 哪个代码行准确地触发 DMA 的传输? 我还需要调用 I2CMasterDataPut ()吗? 或者它应该被 DMA 传输触发器取代?
谈论 TXFIFO 寄存器、我应该将 DMA 放在 TXFIFO 而不是 MDR 上吗?
此致!
Ping
我想知道正确的顺序是什么,以及哪个代码行准确地触发 DMA 的传输? 我还需要调用 I2CMasterDataPut ()吗? 或者它是否应替换为 DMA 传输触发器?
尊敬的 Ping:
是的,您需要 用 DMA 触发器替换 I2CMasterDataPut(),以便 UDMA 可以在调用 I2CMasterControl 之前加载 TXFIFO。 这就是为什么我说过它是 CPU 和 DMA 的混合、在我看来、要让 I2C 正常工作很麻烦。 我还没有见过任何人将 uDMA 用于 I2C、我也没有这方面的示例。 您需要自己研究一下。
谈论 TXFIFO 寄存器、我应该将 DMA 放在 TXFIFO 而不是 MDR 上吗?
[/报价]从 DMA 或 CPU 的角度来看、您需要写入的就是 MDR。 MDR 是 FIFO 的前门。 当您写入 MDR 时、数据会被推至 FIFO。