TI中文支持网
TI专业的中文技术问题咨询交流网站

I2C DMA FIFO burst 问题请教

使用I2C  FIFO  DMA  方式:

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

以下为 I2C 设置

I2CRxFIFOConfigSet(i2c_udma_setting[i].I2C_BASE, I2C_FIFO_CFG_RX_MASTER_DMA | I2C_FIFO_CFG_RX_TRIG_3);   设置 tiger 为3 bytes

I2CMasterBurstLengthSet(i2c_udma_setting[i].I2C_BASE, 3);  设置   ui8MasterBytesLength  = 3 ,  3 个bytes  burst 一次

uDMAChannelControlSet(ui32ChannelNum | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);                                                                                               4 byte arbitration   (应该没关系,我只有3 个 bytes burst , 已经 不需要 arbite 了)

 

uDMAChannelTransferSet(ui32ChannelNum | UDMA_PRI_SELECT,
UDMA_MODE, (void *)(i2c_udma_setting[index].I2C_BASE + I2C_O_FIFODATA),
(void *)g_ui8I2CMasterRxDataA[index],
3);                                                                                                                            3 bytes 

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

以下为   FIFO burst receive  开始

    I2CMasterSlaveAddrSet(ui32Base, i2c_addr, true);
    I2CMasterControl(ui32Base, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

以下为 I2C  中断

 ui32Mode = uDMAChannelModeGet(i2c_udma_setting[index].DMA_Channel | UDMA_PRI_SELECT);

   if (ui32Mode == UDMA_MODE_STOP)
   {
       ui32Mode = I2CMasterBurstCountGet(i2c_udma_setting[index].I2C_BASE);
      I2CMasterControl(i2c_udma_setting[index].I2C_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH);    这里设置硬件中断
    ……………………………….
}

                                                                                                             

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

在 INT 的  

I2CMasterControl(i2c_udma_setting[index].I2C_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH);

 处设置硬件中断

问题出在此处:

当执行 I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START 后

I2CMasterControl(ui32Base, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START);
用示波器看波形,可以看到 正常的 读取 3 bytes 的 I2C 波形
这时停止在I2C 中断的 
      I2CMasterControl(i2c_udma_setting[index].I2C_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH); 
这时单步执行, 会看到 又有 3 bytes 数据读出,并且有了一个 I2C  STOP 波形。
按照我的理解, 应该只有一个 I2C STOP 波形, 不应该再有 3 bytes  数据。
如果我把前面的 burst size 设置为4, 就有 8 个 bytes 数据读出, 设置为 8 , 就有16个数据读出。
似乎读出数据是 设置  burst 的 2倍, 这个应该是有问题。
  
Susan Yang:

我会在确认后给您回复,谢谢

user5228509:

回复 Susan Yang:

Susan, 多谢!

上述表现和DMA 工作在PINGPONG 模式极象,所以现在怀疑DMA 全部是工作在 pingpong模式,不管有没有设置 PINGPONG模式

Susan Yang:

回复 user5228509:

仅查看您提供的代码片段无法看到该问题。您是否已查看应用笔记?

在本说明中有一个示例项目,它执行i2c FIFO uDMA。我已经将该项目更新为使用CCS v10.1,代码生成工具版本20.2.3和TivaWare 2.2.0.205,并将其包括在以下位置:

ektm4c129_i2c_master_udma_fifo.zip

 

user5228509:

回复 Susan Yang:

hi,Susan

你可以看出我贴的代码和你给的示例高度相似,我就是参考示例的。

但是示例里的 receive 方式是 I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE, 而我的接收开始是 

I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START,所以这2个不具备可比性。

如有可能,你可以测试一下  burst recieve 方式,我想就会出现我的问题,谢谢!

Susan Yang:

回复 user5228509:

谢谢您的反馈,我会在测试后给您回复。

Susan Yang:

回复 Susan Yang:

我使用的是DK-TM4C129X进行测试,该套件通过I2C连接到TMP100温度传感器。尽管从温度传感器读取burst 信号并没有多大意义,但它足以显示I2C的功能。我使用FIFO和uDMA读取了8个字节。前两个字节是温度,后六个字节是0xFF。当我使用I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE时,所有8个字节将以burst 方式读取,并且主机将在不确认最后一个字节(NACK)的情况下释放总线,并发送停止条件。

当我使用I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START时,结果是相同的,但是burst 读取在8个字节之后没有结束。

尽管这不能解释您的代码中发生的情况,但显示了如何使用FIFO和uDMA正确进行burst 读取。我已附上我的项目以供参考。

dktm4c129_i2c6_master_udma_fifo.zip

user5228509:

回复 Susan Yang:

HI , susan

  你在  int  合适位置  检测   I2CMasterIntStatusEx    当状态为 I2C_MASTER_INT_RX_FIFO_REQ 时, 调用 I2CMasterControl   

I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH, 就会看到 I2C STOP , 并且又 burst 了 8 个字节,请测试下。

另, 你这个示波器是什么型号啊? 

Susan Yang:

回复 user5228509:

我是请一个美国同事测试的。因为我手边没有这个套件.

我会将您的问题转述给他,谢谢
“你在int合适位置检测I2CMasterIntStatusEx” 能否详细说一下?

user5228509:

回复 Susan Yang:

在中断合适位置加

uint32_t ui32I2CMasterInterruptStatus = I2CMasterIntStatusEx(i2c_udma_setting[8].I2C_BASE, true);
if(ui32I2CMasterInterruptStatus & I2C_MASTER_INT_RX_FIFO_REQ){I2CMasterControl(i2c_udma_setting[8].I2C_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH);

。。。。。。。。

另: 我发现 如果不用I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH,而用 I2C_MASTER_CMD_FIFO_BURST_RECEIVE_ERROR_STOP

也可以看到 I2C stop,而且不会 burst,检查了下,这2个差别就是是否有burstbit,可能有 burstbit , 就会进行一次 burst. 但是这样跑起来会莫名出错

Susan Yang:

回复 user5228509:

谢谢您的反馈,我会在之后回复给您

赞(0)
未经允许不得转载:TI中文支持网 » I2C DMA FIFO burst 问题请教
分享到: 更多 (0)