如果你开始一个异步事务使用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.
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.
嗨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.
嗨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:块因为有待待处理的事务。
谢谢您的帮助
嗨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.