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

After ESP32 wakes up from deep sleep, i2c bus unusable #3363

Open
stickbreaker opened this issue Oct 15, 2019 · 7 comments

Comments

@stickbreaker
Copy link
Collaborator

@stickbreaker stickbreaker commented Oct 15, 2019

Originally posted by @cyberman54 in #3079 (comment)

@stickbreaker sorry for hitchhiking this thread. I have a similar poblem. After ESP32 wakes up from deep sleep i find the i2c bus unusable:
[W][esp32-hal-i2c.c:1411] i2cCheckLineState(): invalid state sda(21)=0, scl(22)=0
[E][esp32-hal-i2c.c:1426] i2cCheckLineState(): Bus Invalid State, TwoWire() Can't init sda=0, scl=0

Thus i can't re-init the i2c slaves. Is there any special treatment for the SDA/SCL GPIOs required after ESP32 wakes up from deep sleep? I am stuck here and did not find help at Google for this issue, so any hint would be appreciated.

@cyberman54 Questions:

  • What pins are you using for SDA,SCL?
  • When you come out of deep sleep, how are you re-initializing Wire()?
  • What devices are connected to the I2C bus?
  • What value are your pullup resistors?
  • How are your I2C sensors powered during deep sleep?

Based on SDA=0 and SCL=0 something is holding the bus down. Simplest explanation is your I2C sensors are powered off and pulling SDA/SCL low via their input clamp diodes.

Chuck.

@cyberman54

This comment has been minimized.

Copy link
Contributor

@cyberman54 cyberman54 commented Oct 15, 2019

@stickbreaker Chuck, thanks for looking at this.

What pins are you using for SDA,SCL?

SDA=21, SCL=22

When you come out of deep sleep, how are you re-initializing Wire()?

Wire.begin(SDA, SCL, 400000);

What devices are connected to the I2C bus?

OLED display (SSD1306) and AXP192 power management chip.

What value are your pullup resistors?

According to schematic - see page 2 - of the board there should be 10 kohm pullups on SDA and SCL line.

How are your I2C sensors powered during deep sleep?

Power of the OLED is cut off by AXP192 pmu while ESP32 is in deep sleep (thus the OLED needs to be re-initialized after wakup, but can't do that without working i2cbus.)

@cyberman54

This comment has been minimized.

Copy link
Contributor

@cyberman54 cyberman54 commented Oct 15, 2019

@stickbreaker just a moment. While i wrote above reply i realized that i missed to power on the display after wake up, so perhaps the unpowered display pulls down the bus. Will add this to the code and test again.

What is a proper re-init of i2c bus after wake up? Wire.begin() ? Wire.~TwoWire() before?

@stickbreaker

This comment has been minimized.

Copy link
Collaborator Author

@stickbreaker stickbreaker commented Oct 15, 2019

@cyberman54 deep sleep is a hardware reset, so, the boot code is executed(setup()). Somewhere in setup() you need Wire.begin().
Before you enter deep sleep I would call:

Wire.end(); // shutdown/power off I2C hardware, 
pinMode(SDA,INPUT); // needed because Wire.end() enables pullups, power Saving
pinMode(SCL,INPUT);

Chuck.

@cyberman54

This comment has been minimized.

Copy link
Contributor

@cyberman54 cyberman54 commented Oct 15, 2019

@stickbreaker

"'class TwoWire' has no member named 'end'"

@cyberman54

This comment has been minimized.

Copy link
Contributor

@cyberman54 cyberman54 commented Oct 15, 2019

@stickbreaker anyway, looks like i ran in funny chicken-egg-problem: powering the display off seems to block the i2c bus. But the i2c bus is needed to control the AXP192 power management chip to turn the display on again, after wake up.

Looks like a hardware design flaw.

@stickbreaker

This comment has been minimized.

Copy link
Collaborator Author

@stickbreaker stickbreaker commented Oct 15, 2019

@cyberman54 I guess I need to add the end() for consistency. directly call the destructor.

Do you have a schematic of the AXP192 and the OLED? If you can separate them into different branches you can use an i2c hub(PCA9548), or even just a few of BSS138 Mosfets to create an isolated level converter.

Chuck.

@stickbreaker

This comment has been minimized.

Copy link
Collaborator Author

@stickbreaker stickbreaker commented Oct 15, 2019

@cyberman54 if you can insert a BSS138 between then OLED and the rest of the I2C bus, wire the BSS138 with the "low" side connected to the OLED. With the "LV" side connected to your OLED power, when the OLED power is off, the N-Channel Mosfet should be off (open circuit)

BSS138 level shifter

image

Chuck.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.