I2C从使用适配器:待定交易和SCLK保持低电平

了解更多常见问题解答教程

4个帖子/ 0新
最后一篇
rajames
离线
最后一次露面:2年9个月前
加入:2017年12月7日11:04
I2C从使用适配器:待定交易和SCLK保持低电平

嗨对话框,

我试图使用DA1468x设备使用I2C适配器(AD_I2C_START_SLAVE)作为I2C从设备。在大多数情况下它有效,但有时它没有。

的通信协议是(或多或少)如下:
- 等待消息报头
ad_i2c_start_slave(ACK,ACK的sizeof,msgHeader,的sizeof msgHeader,回调,OS_EVENT_FOREVER);
...等待data_sent和data_received回调
- 等待有效载荷
ad_i2c_start_slave(ack,sizeof ack,msgpayload,msgpayload,回调,超时的sizeof;
- 处理并获得结果就绪
ad_i2c_start_slave(ACK,ACK的sizeof,waiting_for_result,的sizeof waiting_for_result,回调,TIMEOUT);
- 发送结果
ad_i2c_start_slave(ACK,ACK的sizeof,结果,结果的sizeof,回调,TIMEOUT);

所述ad_i2c_start_slave()可以根据是否设置有读和/或写缓冲器产生4个不同的回调。从我的经验,我不能够正确处理读取请求的回调,所以我选择了总是ad_i2c_start_slave提供WBUF和RBUF()。这样,我只关心data_sent和DATA_RECEIVED回调。
因此,在每一个阶段(上图),预计在I2C主站发送数据和读取数据(说的确认)。所以基本上我在等待data_sent和DATA_RECEIVED事件,以便触发提前到协议的下一阶段(见上文)。

但有时他们I2C总线挂起(SCLK保持低)。我猜这是因为被请求的数据(或数据发送到),这是不是由软件处理。这怎么可能发生吗?我认为这可以在各阶段之间的缓冲区的开关期间,当发生。但是应该不老的缓冲区来代替?或者这些缓冲器只使用一次?

可能发生,我想另一个问题是,有未决的事务,我不知道如何在timesouts删除的情况下。见我的其他张贴在这里:https://support.dialog-semicondiondiondum/forums/post/dialog-smartbond-bl ...

所以我的问题是如何使用超时使用上面提到的协议中所描述的方式使用的ad_i2c_start_slave()方式,或者您对如何实现此操作的任何建议。

PS。我之前具有read_request回调的问题是,从缓冲区中读取数据并没有真正阻止不断被触发中断(RX_FULL)。或许,如果您有任何建议如何可以组合做与协议,我会多于欢迎,听到这个消息。

设备:
mt_dialog.
离线
最后一次露面:1周4天前
职员
加入:2015-06-08 11:34
嗨rajames,

嗨rajames,

不幸的是,使用68x作为从设备没有示例演示。关于I2C的一些事情以及驾驶员如何运行。当68x处于I2C从模式时,如果存在读取或写入取决于从主站发送的命令,则从主服务器与从属地址读取或写入,而不是从可用缓冲区读取或写入。根据来自主设备的命令,设备将公开正确的缓冲区读取或写入。关于从站持有的时钟线,当从站没有数据在其FIFO中没有数据时,可能会发生这种情况,在此情况下,在这种情况下,直到向从站提供读取数据,直到该线将保持低电平I2C控制器。关于您所提供给AD_I2C_START_SLAVE()的函数,我看到在您提供了一个超时的最后一个参数上,没有参数设置超时,您可以执行的是实现自己的超时调用ad_i2c_stop_slave()以中止交互,如果没有设备将等到交互完成。同时与掌握互动时
应该首先在您的事务中设置缓冲区才能从主站读取数据,然后启动新事务以便在上面的代码上依赖于updeneeneted时的新事务。

谢谢mt_dialog.

rajames
离线
最后一次露面:2年9个月前
加入:2017年12月7日11:04
嗨对话框,

嗨对话框,

让我澄清,确实是AD_I2C_Start_slave没有超时参数我将在下面解释我的意思。

//准备ACK缓冲器用于响应

//消息报头
ad_i2c_start_slave(ACK,ACK的sizeof,msgHeader,的sizeof msgHeader,回调);
...等待data_sent和data_received回调
OS_EVENT_GROUP_WAIT(事件,(DATA_RECEIVED | DATA_SENT),OS_EVENT_GROUP_FOREVER);

//有效载荷
ad_i2c_start_slave(ack,sizeof ack,msgpayload,sizeof msgpayload,回调);
...等待data_sent和data_received回调
OS_EVENT_GROUP_WAIT(事件,(DATA_RECEIVED | DATA_SENT),TIMEOUT);

//等待结果
ad_i2c_start_slave(ack,sizeof ack,severing_for_result,sizeof seeve_for_result,回调);
...等待data_sent和data_received回调
OS_EVENT_GROUP_WAIT(事件,(DATA_RECEIVED | DATA_SENT),TIMEOUT);

//过程并准备结果缓冲器(可能需要一些时间)

//发送结果
ad_i2c_start_slave(ACK,ACK的sizeof,结果,结果的sizeof,回调);
...等待data_sent和data_received回调
OS_EVENT_GROUP_WAIT(事件,(DATA_RECEIVED | DATA_SENT),TIMEOUT);

其次所有WBUF.在ad_i2c_start_slave用于调用ad_i2c_start_slave前准备。

我想到的是设置WBUF.RBUF.并呼吁ad_i2c_start_slave将能够同时处理的写入和读出异步。

我如何与主设备同步(如果只是查看data_received和data_sent事件)?

示例方案。
1.如果奴隶期待一个但主人做了一个反而。

  • 仅有的RBUF.假如。
  • 奴隶等待Data_sent事件
  • DATA_READY事件触发的,而不是

2.如果从属期待一个但主人做了一个反而。

  • 仅有的WBUF.假如。
  • 奴隶等待Data_Received活动
  • read_request触发的事件

我应该处理所有4个事件DATA_RECEIVED,DATA_READY,DATA_SENT,READ_REQUEST事件?我不喜欢,因为这真的是复杂的状态机的视角看
我可能会等待可能不会发生,而我可能要处理一些逻辑的回调(ISR上下文)事件。如果我还记得它可能不是一个好主意,打电话ad_i2c例程ISR上下文。

劳尔

mt_dialog.
离线
最后一次露面:1周4天前
职员
加入:2015-06-08 11:34
嗨rajames,

嗨rajames,

关于这样的事实,你看到的设备保持SCK线低,这是为了宣布一个忙状态给主设备,这将线路保持为低是当设备接受来自主设备的读请求时,当发生(以便当READ_REQ已发生)的SW将检查是否有有效的回调和缓冲区,如果有,将开始填写硬件缓冲,以使I2C硬件发送出的数据,因此这个过程正在执行像是时钟保持低。

我想,你可以为了执行一个标准读命令(因为I2C执行写,然后读)提供写和读缓冲。还提到,如果没有缓冲器可在主站发送读取或写入请求(read_request和DATA_READY)的时候,你可以管理设备会从这些回调做。什么活动,你应该处理,你会如何处理它们取决于具体的实现,如果你想一个系统,将处理的,其中主机和从机可以访问总线,那么你应该处理所有的事件同步的情况了。

谢谢mt_dialog.