Skip to content
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

Change I2C Bus Reset to handle interrupted READ sequences. #2496

Closed
wants to merge 3 commits into from
Closed

Change I2C Bus Reset to handle interrupted READ sequences. #2496

wants to merge 3 commits into from

Conversation

stickbreaker
Copy link
Contributor

The current bus reset code does not handle interrupted READ cycles.

If a SLAVE device was in a READ operation when the bus was interrupted, the SLAVE device is controlling SDA.

The only bit during the 9 clock cycles of a byte READ the MASTER(ESP32) is guaranteed control over, is during the ACK bit period.

If the SLAVE is sending a stream of ZERO bytes, it will only release SDA during the ACK bit period. The master(ESP32) cannot generate a STOP unless SDA is HIGH.

So, this reset code synchronizes the bit stream with, Either, the ACK bit, Or a 1 bit.

The current code does not handle interrupted READ cycles.

 If a SLAVE device was in a read operation when the bus was interrupted, the SLAVE device is controlling SDA.

The only bit during the 9 clock cycles of a byte READ the MASTER(ESP32) is guaranteed control over, is during the ACK bit period. 

If the SLAVE is sending a stream of ZERO bytes, it will only release SDA during the ACK bit period. The master(ESP32) cannot generate a STOP unless SDA is HIGH.

So, this reset code synchronizes the bit stream with, Either, the ACK bit, Or a 1 bit.
I am stealing this delay coding from @jeremyherbert #2493 pr.
@stickbreaker stickbreaker changed the title Change Bus Reset to handle interrupted READ sequences. Change I2C Bus Reset to handle interrupted READ sequences. Sep 30, 2018
Copy link

@ryan-ma ryan-ma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A typo, please check. Except this, It works fine for me.

gpio_set_level(scl_io, 0);
ets_delay_us(scl_half_period);
int i=0;
while( !gpio_get_level(sda_id) && (i<9)){ // cycle SCL until SDA is HIGH
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
while( !gpio_get_level(sda_id) && (i<9)){ // cycle SCL until SDA is HIGH
while( !gpio_get_level(sda_io) && (i<9)){ // cycle SCL until SDA is HIGH

@stickbreaker
Copy link
Contributor Author

Yea, i my fault.

I'll fix it.

Chuck.

correct `sda_id` to `sda_io` in `i2c_master_clear_bus()` @ryan-ma found it.  This typo was generated when I manually edited this patch on GitHub, I should have done a Copy/Paste operation!
@koobest
Copy link
Contributor

koobest commented Nov 23, 2018

hi,
Thanks for you contributing code :), it helps us improve the I2C driver. We will update the I2C driver soon.
thansk!!

@projectgus projectgus added the Status: Pending blocked by some other factor label Nov 30, 2018
@projectgus
Copy link
Contributor

Thanks for contributing this fix, @stickbreaker . These commits have been cherry-picked with some other I2C fixes and should be merged to master shortly.

@igrr igrr closed this in 924daf7 Nov 30, 2018
igrr pushed a commit that referenced this pull request Jan 24, 2019
… SDA

closes #2494
closes #2493
closes #2496

1. Change bus reset to handle interrupted READ sequences.
2. Slow down I2C to 100khz during reset
3. If a SLAVE device was in a read operation when the bus was interrupted, the SLAVE device is controlling SDA.The only bit during the 9 clock cycles of a byte READ the MASTER(ESP32) is guaranteed control over, is during the ACK bit period.
If the SLAVE is sending a stream of ZERO bytes, it will only release SDA during the ACK bit period. The master(ESP32) cannot generate a STOP unless SDA is HIGH. So, this reset code synchronizes the bit stream with, Either, the ACK bit, Or a 1 bit.
igrr pushed a commit that referenced this pull request Jan 29, 2019
… SDA

closes #2494
closes #2493
closes #2496

1. Change bus reset to handle interrupted READ sequences.
2. Slow down I2C to 100khz during reset
3. If a SLAVE device was in a read operation when the bus was interrupted, the SLAVE device is controlling SDA.The only bit during the 9 clock cycles of a byte READ the MASTER(ESP32) is guaranteed control over, is during the ACK bit period.
If the SLAVE is sending a stream of ZERO bytes, it will only release SDA during the ACK bit period. The master(ESP32) cannot generate a STOP unless SDA is HIGH. So, this reset code synchronizes the bit stream with, Either, the ACK bit, Or a 1 bit.
catalinio pushed a commit to catalinio/pycom-esp-idf that referenced this pull request Jun 28, 2019
… SDA

closes espressif/esp-idf#2494
closes espressif/esp-idf#2493
closes espressif/esp-idf#2496

1. Change bus reset to handle interrupted READ sequences.
2. Slow down I2C to 100khz during reset
3. If a SLAVE device was in a read operation when the bus was interrupted, the SLAVE device is controlling SDA.The only bit during the 9 clock cycles of a byte READ the MASTER(ESP32) is guaranteed control over, is during the ACK bit period.
If the SLAVE is sending a stream of ZERO bytes, it will only release SDA during the ACK bit period. The master(ESP32) cannot generate a STOP unless SDA is HIGH. So, this reset code synchronizes the bit stream with, Either, the ACK bit, Or a 1 bit.
catalinio pushed a commit to catalinio/pycom-esp-idf that referenced this pull request Jun 28, 2019
… SDA

closes espressif/esp-idf#2494
closes espressif/esp-idf#2493
closes espressif/esp-idf#2496

1. Change bus reset to handle interrupted READ sequences.
2. Slow down I2C to 100khz during reset
3. If a SLAVE device was in a read operation when the bus was interrupted, the SLAVE device is controlling SDA.The only bit during the 9 clock cycles of a byte READ the MASTER(ESP32) is guaranteed control over, is during the ACK bit period.
If the SLAVE is sending a stream of ZERO bytes, it will only release SDA during the ACK bit period. The master(ESP32) cannot generate a STOP unless SDA is HIGH. So, this reset code synchronizes the bit stream with, Either, the ACK bit, Or a 1 bit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Pending blocked by some other factor
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants