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

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

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

设备:
mt_dialog.
离线
最后一次露面:5个月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年3个月前
加入: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.
离线
最后一次露面:5个月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.