I2C适配器Async Write:挂起事务问题

⚠️
嗨,...感谢您来论坛。令人兴奋的消息!我们现在正在迁至我们的新论坛平台,将提供更好的功能,并包含在主对话框网站中。所有帖子和帐户都已迁移。我们现在只接受新论坛上的流量 - 请发布任何新线程https://www.dialog-seminile.com/support.。我们将在未来几天修复错误/优化搜索和标记。
4个帖子/ 0新
最后一篇
拉杰姆斯
离线
最后一次露面:3年2周前
加入:2017-12-07 11:04
I2C适配器Async Write:挂起事务问题

我正在使用i2c适配器(在主模式下)进行异步写入,或者读取从回调中发出的OS_EVENT等待的读取。
然而,而不是永远等待我希望能够设置超时值,以便如果在总线上没有设备,则不会被卡住。
但是,如果我尝试启动另一个异步读取或写入适配器的超时,因为存在未完成的待处理事务,所以读取或写入适配器挂起。我如何取消这些待处理的交易或更好,尚更良好,是正确的方式,以便我可以使用带有AD_I2C_ASYNC_READ或AD_I2C_ASYNC_WRITE的超时。

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

嗨rajames,

如果您使用SDK的ASYNCH函数启动异步事务,则API为您提供回调参数,应在完成事务时执行此回调。如果由于任何原因在尝试访问I2C设备时设备获取NACK,则交互将终止适当的错误,在设备侧HW_I2C_ABORT_7B_ADDR_NO_ACK中的NACK的情况下,您将能够知道在回调时。而不是拥有wait_for_event(事件)(我想这就是你的意思)你可以ommit是为了不阻止任务,但你不能取消已经开始的事务,并且你不能在之前使用第二个ASYNCH事务前一个返回,这在doxygen中清楚地说明了ad_i2c_asynch_read和写入函数的描述中。

谢谢mt_dialog.

拉杰姆斯
离线
最后一次露面:3年2周前
加入:2017-12-07 11:04
嗨Dalog,

嗨Dalog,

感谢您的答复。

如果我正确理解,即使发生错误,应始终应始终执行回调。

我正在使用回调来发出任务,请参阅下面的伪代码:

回调(Params){
//处理参数
os_signal(事件)
}


任务() {
async_write(数据,回调)
OS_EVENT_WAIT(事件,超时)
//更多异步写入或以相同的方式读取
}

我面临的问题是,如果在超时过期之前未执行回调,则无法取消任何挂起的事务。这就是为什么要使用OS_Event_forever。
但并不总是执行回调。回调会在以下错误期间执行吗?例如,SCLK线在异步写入或读取开始之前由从设备保持低电平。回调仍然会用hw_i2c_abort_ *执行吗?在未触发回调时是否有其他情况?

如何防止以下序列阻止

master:ad_i2c_async_read.
Master:启动读取请求
奴隶:承认并保持SCLK线路
奴隶:永远不会发送回复
master:os_event_wait超时到期
Master:启动另一个ad_i2c_async_read请求
Master:块因为有待待处理的事务。

谢谢您的帮助

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

嗨rajames,

那么,你说有时操作永远不会完成,所以设备摊位并等待?从那以后,如果I2C HW看到的是时钟线路低电平,它不会传输任何数据,并且它不会返回错误(因为没有错误)它只等到时钟线释放并传出数据缓冲区。所以在这种情况下,不应该任何完成交易完成。但是你不能拥有一个奴隶,它会一直将CLK线保持低。如果发生这种情况并且线路保持低电平,则应更好地由从设备而不是主机处理,因为保持时钟线低电平将阻止对该总线上附加的所有设备的通信,即使存在取消程序以停止异步事务,如果从站继续保持低电平,则必须符合后续交易。在任何情况下,您可以尝试的是有类似以下代码段的东西,以取消程序(请注意,这没有测试,而不是官方SDK代码,我无法预测这可能对I2C交易的行为的任何副作用):

静态void i2c_release_uncomp_transact(i2c_device dev)
{
i2c_device_config * device =(i2c_device_config *)dev;
i2c_bus_dynamic_data * data = device-> bus_data;
if(数据 - > transaction_ix!= 0)
{
data-> transaction_ix = 0;
/ *只发布总线和设备* /
AD_I2C_BUS_RELEASE(DEV);
ad_i2c_device_release(dev);
}
}

因此,使用上面可以使用超时而不是使用WAIT_FOR_EVENT()函数中的OS_EVENT_FOREVER,并且一旦超时结束,您可以调用上述功能以取消先前的事务并继续使用另一个事务。

谢谢mt_dialog.