嗨,对话框中,
我试图使用DA1468x设备作为使用I2C适配器(ad_i2c_start_slave)的I2C从设备。在大多数情况下它的工作原理,但有时并非如此。
通信协议大致如下:
-等待消息头
ad_i2c_start_slave(ack, sizeof ack, msgHeader, sizeof msgHeader, callback, OS_EVENT_FOREVER);
...等待data_sent和DATA_RECEIVED回调
-等待有效载荷
ad_i2c_start_slave(ACK,ACK的sizeof,msgPayload,的sizeof msgPayload,回调,TIMEOUT);
-处理并准备结果
ad_i2c_start_slave(ack, sizeof ack, waiting_for_result, sizeof waiting_for_result, callback, TIMEOUT);
——发送结果
ad_i2c_start_slave(ack, sizeof ack, result, sizeof result, callback, 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)的持续触发。也许如果你有关于如何结合协议来做这件事的建议,我将非常欢迎你的建议。
嗨rajames,
可惜的是有使用68X作为从设备没有实例演示。有几件事情有关I2C以及如何驾驶者操作。当68X在I2C从模式下,如果有一个读或写依赖于来自主读或写连同从机地址,而不是从现有的缓冲器发送的命令。根据来自主命令设备将暴露适当的缓冲器读或写。关于由从保持低的时钟线,这可能会发生当从属好好尝试在其FIFO中的数据并且存在来自主设备的读请求,在这种情况下,该线将保持为低,直到读出的数据被提供给从I2C控制器。至于您所提供给ad_i2c_start_slave()函数,我看到的最后一个参数,你提供了一个超时的somekind的,没有将设置一个超时参数,你能做的就是实现自己的超时,然后调用,以便在ad_i2c_stop_slave()来中止的相互作用,如果没有设备将等待,直到交互完成。此外,当与主机交互您
应先设定交易中的缓冲区,以便在同一时间读取来自主的数据,然后才能启动新的事务写的,而不是你implemeneted在上面的代码。
由于MT_dialog
嗨,对话框中,
让我澄清一下,确实是ad_i2c_start_slave没有超时参数我会在下面我的意思解释。
//为响应准备ack缓冲区
/ /消息头
ad_i2c_start_slave(ack, sizeof ack, msgHeader, sizeof msgHeader, callback);
...等待data_sent和DATA_RECEIVED回调
OS_EVENT_GROUP_WAIT(event, (DATA_RECEIVED | DATA_SENT), OS_EVENT_GROUP_FOREVER);
/ /负载
ad_i2c_start_slave(ACK,ACK的sizeof,msgPayload,的sizeof msgPayload,回调);
...等待data_sent和DATA_RECEIVED回调
OS_EVENT_GROUP_WAIT(event, (DATA_RECEIVED | DATA_SENT), TIMEOUT);
//等待结果
ad_i2c_start_slave(ACK,ACK的sizeof,waiting_for_result,的sizeof waiting_for_result,回调);
...等待data_sent和DATA_RECEIVED回调
OS_EVENT_GROUP_WAIT(event, (DATA_RECEIVED | DATA_SENT), TIMEOUT);
//处理并准备结果缓冲区(可能需要一些时间)
/ /发送结果
Ad_i2c_start_slave (ack, sizeof ack, result, sizeof result, callback);
...等待data_sent和DATA_RECEIVED回调
OS_EVENT_GROUP_WAIT(event, (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.如果从期待一个读但主做了写代替。
2.如果奴隶期待一个写但主做了读代替。
我应该处理所有4个事件DATA_RECEIVED, DATA_READY, DATA_SENT, READ_REQUEST事件吗?我不喜欢这样,因为这真的会使状态机更复杂
我可能在等待可能不会发生的事件,我可能必须在回调(isr上下文)中处理一些逻辑。如果我还记得的话,在isr上下文中调用ad_i2c例程可能不是一个好主意。
劳尔
嗨rajames,
关于这样的事实,你看到的设备保持SCK线低,这是为了宣布一个忙状态给主设备,这将线路保持为低是当设备接受来自主设备的读请求时,当发生(以便当READ_REQ已发生)的SW将检查是否有有效的回调和缓冲区,如果有,将开始填写硬件缓冲,以使I2C硬件发送出的数据,因此这个过程正在执行像是时钟保持低。
我假设您可以同时提供写和读缓冲区,以便执行标准的读命令(因为i2c先执行写,然后执行读)。正如前面提到的,如果在主程序发送读或写请求(read_request和data_ready)时没有可用的缓冲区,您可以管理设备将从这些回调中做什么。你应该处理什么事件以及你将如何处理它们取决于你的实现,如果你想要一个系统将处理不同步的情况,其中主和从可以访问总线,然后你应该处理所有的事件。
由于MT_dialog