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个月2周前
职员
加入:2015-06-08 11:34
嗨rajames,

嗨rajames,

如果您使用SDK的异步函数启动异步事务,API将为您提供一个回调参数,该回调应该在事务完成时执行。如果因为任何原因设备得到了纳当试图访问一个I2C设备的交互将终止与适当的错误,对于纳从设备的HW_I2C_ABORT_7B_ADDR_NO_ACK,你将能够知道当出现回调。而不是wait_for_event(事件)(我假设这是你的意思)你可以ommit为了不阻止任务,但你不能取消交易,已经开始,也不能使用另一个事务中在前一个返回之前,在ad_i2c_asynch_read和write函数的描述中,doxygen清楚地说明了这一点。

谢谢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个月2周前
职员
加入:2015-06-08 11:34
嗨rajames,

嗨rajames,

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

Static 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.