-
Notifications
You must be signed in to change notification settings - Fork 7.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
i2c_master handle NACK (IDFGH-12083) #13142
i2c_master handle NACK (IDFGH-12083) #13142
Conversation
Now, when device address NACK is encountered using i2c_master_receive, the transaction will be aborted with a stop signal. See https://www.github.com/espressif/esp-idf/issues/13134.
Aborts transaction if device address or write byte is NACK'ed on i2c_master_transmit and i2c_master_transmit_receive. See https://www.github.com/espressif/esp-idf/issues/13134.
When a transaction error occurred, the bus would be blocked indefinitely.
👋 Hello MatthiasKunnen, we appreciate your contribution to this project! 📘 Please review the project's Contributions Guide for key guidelines on code, documentation, testing, and more. 🖊️ Please also make sure you have read and signed the Contributor License Agreement for this project. Click to see more instructions ...
Review and merge process you can expect ...
|
Hi @MatthiasKunnen, thanks for writing up this PR! I just tested this PR with the i2c async callback as follows, and it doesn't seem to work as expected. First, this is how we tested without the PR applied: Without the PR
With the PR This is the same procedure with this PR applied:
TL;DR Do you know what may have caused the hang, and how might the NACK detection be fixed for asynchronous requests? This is our callback: bool esp32_i2c_dev_callback(i2c_master_dev_handle_t i2c_dev, const i2c_master_event_data_t *evt_data, void *arg)
{
// i2c_req_t is our own i2c request tracking structure. For the purpose of this example,
// its just a way of passing `evt_data->event` outside of the ISR:
i2c_req_t *req = arg;
req->esp_callback_event = evt_data->event;
if (evt_data->event == I2C_EVENT_DONE)
req->status = i2cTransferDone;
else if (evt_data->event == I2C_EVENT_NACK) // <- never happens
req->status = i2cTransferError;
else
req->status = -evt_data->event;
return false;
} |
Since I read that the async API was still experimental, I hadn't tested it before pausing development. I'll have a look and see what can be done. |
Thanks, I appreciate it. Here is a simple test routine that implements both sync and async side-by-side if it helps you with testing: |
I merged 016877b, so this is gonna fixed. Thanks for your contribution, I will close this one. |
Closes #13134
In summary, this PR:
s_i2c_synchronous_transaction
failurei2c_master_receive
i2c_master_transmit
andi2c_master_transmit_receive
TODO
i2c_master_probe
reports incorrect NOT FOUND if previous transaction failedI noticed that after dealing with an unexpected NACK (on slave address or write byte) on
i2c_master_transmit
, thei2c_master_probe
function will report NOT_FOUND on an existing address. This is seems to be due to some missing cleanup or resetting of initial state when startingi2c_master_probe
.I was planning on continuing to develop this PR until the probe issue was resolved and was looking into writing tests. Since then, @mythbuster5 has voiced that they would add NACK checking in #13136 (comment). Wanting to prevent duplication of effort, I'm not sure if I should continue further development on this PR.
I look forward to feedback, both on the current approach and if/how to continue.