Skip to content

Fix for deadlock conditions after i2c bus errors #23

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

Merged
merged 1 commit into from
Aug 13, 2015

Conversation

pixelpixi
Copy link
Contributor

Hello. I'm working on getting my project, Modulo (www.modulo.co) working with the Arduino Zero. Modulo uses hot plugging of i2c devices, so it tends to stress test handling of i2c bus errors. I found two places in SERCOM.cpp where incorrect handling of error conditions can cause a deadlock to occur. This pull request includes simple fixes for both of them.

The first occurs when an addressed device simply doesn't respond. This can be easily reproduced by doing a Wire.requestFrom() to an address that doesn't exist. Without the fix the arduino will completely lock up. With the fix, requestFrom returns an error. The bug is that it waits until the SB (slave on bus) bit is set in the INTFLAGS register, but when a nack occurs that never happens so we're stuck in an infinite loop. The fix is to also look for the MB flag to be set. If it is, issue a stop condition and return.

The second happens when a bus error (ie, an illegal stop condition) occurs while sending data as a master. This can be reproduced by connecting/disconnecting the SDA and SCL lines while i2c communication is in progress. In that case we are waiting for the MB (master on bus) flag to be set. When a bus error occurs that never happens, so again we end up in an infinite loop. The fix here is to also look for the BUSERR flag to be set. If it is, return an error condition.

Please let me know if there's any additional information I can provide on the problems or the fixes. Thanks.

…ccur.

The first occurs when starting a read transaction from a slave that doesn't respond. The code would wait until the SB (slave on bus) bit is set in the INTFLAGS register, but when a nack occurs that never happens so we're stuck in an infinite loop. The fix is to also look for the MB flag to be set. If it is, issue a stop condition and return.

The second happens when a bus error (ie, an illegal stop condition) occurs while sending data as a master. In that case we are waiting for the MB (master on bus) flag to be set. When a bus error occurs that never happens, so again we end up in an infinite loop. The fix here is to also look for the BUSERR flag to be set. If it is, return an error condition.
@facchinm
Copy link
Member

Hi @pixelpixi, thank you for the patch! I've tested on a Zero and it works great.
I believe it will be merged as soon as @cmaglie is back.

@pixelpixi
Copy link
Contributor Author

Thank you for testing, @facchinm!

@pixelpixi
Copy link
Contributor Author

Hello @cmaglie and @facchinm. I was just wondering if you have an estimate for when this might get pulled in? If there are any concerns about it or anything else you need, please let me know what I can do. Of course if you are just busy and haven't gotten to it I completely understand.

Thanks a lot!

cmaglie added a commit that referenced this pull request Aug 13, 2015
Fix for deadlock conditions after i2c bus errors
@cmaglie cmaglie merged commit b69bead into arduino:master Aug 13, 2015
@cmaglie
Copy link
Member

cmaglie commented Aug 13, 2015

Thank you!

@cmaglie cmaglie added this to the Release 1.6.2 milestone Aug 13, 2015
@pixelpixi
Copy link
Contributor Author

Thrilled to see this get pulled in! Thanks!

bxparks pushed a commit to bxparks/ArduinoCore-samd that referenced this pull request Jun 1, 2023
Accurate PWM frequency for SAMD21
Thanks for you PR!
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants