描述
在主模式下配置时,I2C控制器会生成无效的读取事务。
解
描述:
当I2C控制器作为主器件运行并发出读取事务(即它是主接收器)时,会出现此问题。
设置时 HOLD位 (i2c.Control_reg0 [HOLD]),防止控制器在传输结束时发出STOP条件。
相反,当transfer_size(i2c.Transfer_size_reg0)为0时,SCL将保持低电平,直到软件决定下一步做什么。
如果控制器超时(请参阅i2c.Time_out_reg0 [TO]),而控制器保持SCL为低电平,则它会错误地从从器件传输16字节的附加读取数据。
transfer_size寄存器被破坏并转换为0xFF。
如果FIFO中有空间,则这些附加字节将保存在FIFO中。
即使禁用超时中断,也会发生此问题。
影响: HOLD位主要用于两种情况:
- 在做重复START时。
要在读取之后进行第二次传输而不放弃I2C接口,则使用HOLD位并在没有首先发出STOP条件的情况下启动第二次传输。 - 进行大量读取传输时。
读取大于255B需要对transfer_size寄存器进行重新编程。
执行此操作的方法是允许transfer_size递减为0,然后将其重新编程为更高的值。
应该注意,只有当软件无法及时为I2C控制器提供服务时才会出现问题。 (即在超时之前)。
但是,如果问题确实发生,则会发生意外的数据传输。
根据系统和特定的转移,这可能是无害的或严重的。
解决方法:
将i2c.Time_out_reg0设置为较大的值将使软件有更多时间响应I2C事件,从而降低问题的可能性。
但是,这并不能完全避免这个问题。
为避免此问题,当HOLD位置1时,软件不允许transfer_size递减为0。
此规则可防止使用上面“影响”部分(a)中描述的重复START功能。
软件可以通过将大型读取传输分成多个单独的传输来避免上述情况(b)。
但是,这可能需要上层协议支持才能将事务重新组合为完整和原始大小。
如果采取特殊预防措施以避免在transfer_size为0时设置HOLD位,则可以支持大量读取传输。
如上所述,必须停顿I2C接口以重新编程transfer_size。
解决方法使用FIFO填满时总线将停顿的事实。
因此,使用的方法是:
- 驱动程序必须跟踪当前传输块中从FIFO读取的数据量。
- 当剩余17B数据时,它应该停止从FIFO读取。
- 然后,它必须等到transfer_size = 1。由于剩余17B数据,这表明FIFO已满16B数据。
- 此时,I2C接口将处于静默状态(仍有一个数据的最后一个字节需要传输),驱动程序可以重新编程transfer_size。
- 然后,驱动程序可以照常从FIFO读取数据,并从步骤(2)继续。
受影响的配置:利用I2C作为主器件的系统。
解决方案 :没有修复计划。
请参阅(Xilinx答复47916) – Zynq-7000 SoC芯片版本差异
没有回复内容