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

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

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

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

嗨rajames,

如果你开始一个异步事务使用asynch functions of the SDK, the API provides you with a callback parameter, this callback should be executes upon completing the transaction. If for any reason the the device gets a NACK when trying to access an I2C device then the interaction will terminate with the appropriate error, in the case of NACK from the device's side HW_I2C_ABORT_7B_ADDR_NO_ACK, and you will able to know that when the callback occurs. Instead of having the wait_for_event(event) (i suppose that this is what you mean) you can ommit that in order not to block the task but you cannot cancel the transaction that has allready began, and also you cannot use a second asynch transaction before the previous one returns, this clearly stated in the doxygen in the description of the ad_i2c_asynch_read and write functions.

谢谢mt_dialog.

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

嗨Dalog,

Thanks for your response.

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

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

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


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

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

如何防止以下序列阻止

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

谢谢您的帮助

mt_dialog.
离线
最后一次露面:1个月3周前
职员
加入: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);
}
}

So, using the above you can have a timeout instead of using the OS_EVENT_FOREVER in your wait_for_event() function and as soon as the timeout ends you can invoke the above function in order to cancel the previous transaction and continue with another one.

谢谢mt_dialog.