I2c从机使用适配器:挂起的事务和SCLK保持低

⚠️
你好。。谢谢你来参加论坛。令人兴奋的消息!我们现在正在移动到我们的新论坛平台,将提供更好的功能,并包含在主对话网站的过程。所有帖子和账号都已迁移。我们现在只接受新论坛上的流量-请在//www.wsdof.com/support. 我们将在未来几天内修复bug/优化搜索和标记。
4个职位/0个新职位
最后一篇文章
拉贾姆斯
离线
最后一次见到:3年3周前
已加入:2017-12-07 11:04
I2c从机使用适配器:挂起的事务和SCLK保持低

嗨,对话,

我试图使用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;
-过程和结果准备
从站(ack,sizeof ack,waiting for result,sizeof waiting for result,callbacks,TIMEOUT);
-发送结果
从站(ack,sizeof ack,result,sizeof result,callbacks,TIMEOUT);

根据提供的是读缓冲区还是写缓冲区,ad\u i2c\u start\u slave()可以生成4个不同的回调。根据我的经验,我无法正确处理读取请求回调,因此我选择始终为ad_i2c_start_slave()提供wbuf和rbuf,这样我只关心发送的数据和接收的数据回调。
因此,在每个阶段(如上所述),预计i2c主机发送数据和读取数据(如确认)。所以基本上我在等待数据发送和数据接收事件被触发,以便进入协议的下一阶段(见上文)。

但有时i2c总线挂起(SCLK保持低位)。我猜这是因为数据是被请求的(或发送到的),而不是由软件处理的。怎么会这样?我认为在每个阶段之间切换缓冲区时会发生这种情况。但是,不应该使用旧的缓冲区来代替吗?或者这些缓冲区只使用了一次?

我猜到的另一个问题是,我不知道如何在超时的情况下取消的交易。在这里查看我的其他帖子:https://support.dialog-semicondiondiondum/forums/post/dialog-smartbond-bl ...

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

另外,我之前在read\u request回调中遇到的问题是,从缓冲区读取数据并不能真正阻止中断(RX\u FULL)被连续触发。也许如果你有建议如何结合协议来实现这一点,我会非常乐意听到。

设备:
MT\u对话框
离线
最后一次见到:2个月1周前
工作人员
已加入:2015-06-08 11:34
嗨rajames,

嗨rajames,

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

谢谢你的对话

拉贾姆斯
离线
最后一次见到:3年3周前
已加入:2017-12-07 11:04
嗨,对话,

嗨,对话,

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

//准备应答缓冲区

//消息头
从站(ack,sizeof ack,msgHeader,sizeof msgHeader,callbacks);
...等待data_sent和data_received回调
OS|u EVENT|u GROUP|u WAIT(EVENT,(DATA|RECEIVED | DATA|SENT),OS|u EVENT|u GROUP|FOREVER);

//有效载荷
ad_i2c_start_slave(ack,sizeof ack,msgpayload,sizeof msgpayload,回调);
...等待data_sent和data_received回调
OS|EVENT|GROUP|WAIT(事件,(数据|接收|数据|发送),超时);

//等待结果
ad_i2c_start_slave(ack,sizeof ack,severing_for_result,sizeof seeve_for_result,回调);
...等待data_sent和data_received回调
OS|EVENT|GROUP|WAIT(事件,(数据|接收|数据|发送),超时);

//处理并准备结果缓冲区(可能需要一些时间)

//发送结果
从站(ack,sizeof ack,result,sizeof result,callbacks);
...等待data_sent和data_received回调
OS|EVENT|GROUP|WAIT(事件,(数据|接收|数据|发送),超时);

其次,所有WBUF.用在adïi2cïstartïslave之前都准备好调用adïi2cïstartïslave。

我希望是这样WBUF.RBUF.而调用adui2c\u start\u slave将能够异步处理写和读。

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

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

  • 仅有的RBUF.假如。
  • 奴隶等待Data_sent事件
  • 改为触发数据就绪事件

2如果slave正在等待但主人做了一个相反。

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

我应该处理所有4个事件数据接收,数据准备,数据发送,读取请求事件吗??我宁愿不这样做,因为这真的使状态机看到它变得复杂
我可能在等待可能不会发生的事件,并且可能需要处理回调(isr上下文)中的一些逻辑。如果我记得的话,在isr上下文中调用adui2c例程可能不是一个好主意。

劳尔

MT\u对话框
离线
最后一次见到:2个月1周前
工作人员
已加入:2015-06-08 11:34
嗨rajames,

嗨rajames,

关于你看到持有SCK线路的设备的事实,这是为了向主设备声明忙碌状态,这保持低电平是当设备接受来自主机的读取请求,发生这种情况(所以当READ_REQ发生时)SW将检查是否有有效的回调和缓冲区,并且如果存在它将开始填充HW缓冲区,以便I2C HW发送数据,因此此过程执行时钟时保持低位。

我假设您可以提供写缓冲区和读缓冲区,以便执行标准的读命令(因为i2c先执行写,然后执行读)。另外,如前所述,如果在主机发送读或写请求(read\u request和data\u ready)时没有可用的缓冲区,您可以管理设备将从这些回调中执行的操作。您应该处理什么事件以及如何处理它们取决于您的实现,如果您希望一个系统能够处理不同步的情况,其中主设备和从设备可以访问总线,那么您应该处理所有事件。

谢谢你的对话