嗨对话框,
我试图使用DA1468x设备使用I2C适配器(AD_I2C_START_SLAVE)作为I2C从设备。在大多数情况下它有效,但有时它没有。
通信协议(或多或少)如下:
- 等待消息标题
AD_I2C_START_SLAVE(ACK,SIZEOF ACK,MSGHEADER,SIZEOF MSGHeader,Callbacks,OS_Event_Forever);
...等待data_sent和data_received回调
- 等待有效载荷
ad_i2c_start_slave(ack,sizeof ack,msgpayload,msgpayload,回调,超时的sizeof;
- 进程准备好结果
ad_i2c_start_slave(ack,sizeof ack,severing_for_result,sizeof seevent_for_result,回调,超时);
- 发送结果
AD_I2C_START_SLAVE(ACK,SIZEOF ACK,结果,尺寸结果,回调,超时);
ad_i2c_start_slave()可以根据提供读取和/或写入缓冲区生成4个不同的回调。从我的经验来看,我无法正确处理读取请求回调,因此我始终为ad_i2c_start_slave()始终提供wbuf和rbuf,以便我仅关注data_sent和data_received回调。
因此,在每个阶段(上图)预期I2C主站都会发送数据并读取数据(例如确认)。所以基本上我在等待触发的data_sent和data_received事件,以便前进到协议的下一个阶段(见上文)。
然而,有时它们I2C总线悬挂(SCLK保持低电平)。我猜这是因为请求数据(或发送到的数据),其未被软件处理。这怎么可能发生吗?我认为在每个阶段之间缓冲区的交换机之间时可能会发生这种情况。但是不应该使用旧缓冲区吗?或者这些缓冲区只使用一次吗?
我猜到的另一个问题是,我不知道如何在超时的情况下取消的交易。在这里查看我的其他帖子: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()的函数,我看到在您提供了一个超时的最后一个参数上,没有参数设置超时,您可以执行的是实现自己的超时调用ad_i2c_stop_slave()以中止交互,如果没有设备将等到交互完成。同时与掌握互动时
应该首先在您的事务中设置缓冲区才能从主站读取数据,然后启动新事务以便在上面的代码上依赖于updeneeneted时的新事务。
谢谢mt_dialog.
嗨对话框,
让我澄清,确实是AD_I2C_Start_slave没有超时参数我将在下面解释我的意思。
//准备ACK缓冲区进行响应
//消息标题
AD_I2C_START_SLAVE(ACK,SIZEOF ACK,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),超时);
//等待结果
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),超时);
//进程和准备结果缓冲区(可能需要一些时间)
//发送结果
ad_i2c_start_slave(ack,sizeof ack,结果,sizef结果,回调);
...等待data_sent和data_received回调
os_event_group_wait(事件,(data_received | data_sent),超时);
其次是所有的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 Context)。如果我记得在ISR上下文中调用AD_I2C例程可能不是一个好主意。
劳尔
嗨rajames,
关于你看到持有SCK线路的设备的事实,这是为了向主设备声明忙碌状态,这保持低电平是当设备接受来自主机的读取请求,发生这种情况(所以当READ_REQ发生时)SW将检查是否有有效的回调和缓冲区,并且如果存在它将开始填充HW缓冲区,以便I2C HW发送数据,因此此过程执行时钟时保持低位。
我想你可以提供写入和读缓冲区,以便执行标准读取命令(因为I2C执行写入,然后读取)。同样如上所述,如果主机发送读取或写入请求时没有可用缓冲区(READ_REQUEST和DATA_READY),则可以管理设备将从这些回调中执行的内容。您应该处理哪些事件以及如何处理它们取决于您的实现,如果您想要一个将处理Master和Slave可以访问所述总线的同步情况,那么您应该处理所有事件。
谢谢mt_dialog.