arduino-esp32 icon indicating copy to clipboard operation
arduino-esp32 copied to clipboard

gpio_hold_en not working as expected since 2.0.0

Open dynek opened this issue 3 years ago • 17 comments

Board

ESP-WROOM-32

Device Description

I tested both with a 30 pin and 38 pin dev modules: image image

Hardware Configuration

There is absolutely nothing attached to the ESP, only an oscilloscope on GPIO 33 and GND.

Version

v2.0.3

IDE Name

PlateformIO

Operating System

macOS 10.15.7

Flash frequency

40Mhz

PSRAM enabled

no

Upload speed

460800

Description

Below's code sets GPIO 33 HIGH, instructs the ESP to hold it in its current state, and sleep for 2 seconds. Upon wake-up I expect GPIO 33 to be held high, except if / until I call gpio_hold_dis.

When using Arduino-ESP32 version 1.0.6, it works as mentioned. Since 2.0.0, as soon as the ESP wakes up, GPIOs are reset to their default state.

Sketch

pinMode(GPIO_NUM_33, OUTPUT);
digitalWrite(GPIO_NUM_33, HIGH);
gpio_hold_en(GPIO_NUM_33);
esp_sleep_enable_timer_wakeup(2000000);
esp_deep_sleep_start();

Debug Message

M/A

Other Steps to Reproduce

N/A

I have checked existing issues, online documentation and the Troubleshooting Guide

  • [X] I confirm I have checked existing issues, online documentation and Troubleshooting guide.

dynek avatar Jun 01 '22 20:06 dynek

I think you now need to call gpio_deep_sleep_hold_en?

lbernstone avatar Jun 01 '22 21:06 lbernstone

Isn't this used to hold all rtc gpios in their current state? I want to to specify which ones, reason why I use gpio_hold_en.

dynek avatar Jun 01 '22 21:06 dynek

@dynek - This is not an Arduino Issue... but I'm surprised it works with Arduino 1.0.6, because as @lbernstone said you must call gpio_deep_sleep_hold_en() as well, for any both Arduino Cores (1.0.6 and 2.0.0+).

Check the documentation:

Arduino 1.0.6 uses IDF 3.3: https://espressif-docs.readthedocs-hosted.com/projects/esp-idf/en/v3.3.4/api-reference/peripherals/gpio.html#_CPPv412gpio_hold_en10gpio_num_t

Arduino 2.0.0+ uses IDF 4.4: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/gpio.html#_CPPv412gpio_hold_en10gpio_num_t

SuGlider avatar Jun 01 '22 21:06 SuGlider

@dynek - check out this link https://github.com/espressif/arduino-esp32/issues/2712

SuGlider avatar Jun 01 '22 21:06 SuGlider

@dynek Do you still need help?

VojtechBartoska avatar Jun 14 '22 13:06 VojtechBartoska

@VojtechBartoska I still need to give a try, I've been super busy lately. I was under the impression (when I tried it some weeks ago) that gpio_deep_sleep_hold_en() would hold all RTC GPIO in their current state, not just the ones specified with gpio_hold_en(). Also what's weird in my case is that the GPIO is actually held in the right state, it's just switching back to its default state when the ESP comes back to life, after sleeping. But I'll give it a try asap, thanks for the hints!

dynek avatar Jun 15 '22 04:06 dynek

@dynek thanks! Looking forward for your results.

VojtechBartoska avatar Jun 15 '22 09:06 VojtechBartoska

Just tried it and it doesn't work better. I tried with:

gpio_deep_sleep_hold_en();
gpio_hold_en(GPIO_NUM_33);
esp_sleep_enable_timer_wakeup(2000000);
esp_deep_sleep_start();

And:

gpio_hold_en(GPIO_NUM_33);
gpio_deep_sleep_hold_en();
esp_sleep_enable_timer_wakeup(2000000);
esp_deep_sleep_start();
image

Using gpio_deep_sleep_hold_en or not has the same effect. GPIO is held in its current state, but as soon as the ESP restarts it goes LOW again.

dynek avatar Jun 20 '22 20:06 dynek

The documentation is a bit confusing here, but when looking at the gpio_hold_dis function, it looks like what you're seeing is intended behavior.

Not sure when the gpio_hold_dis is called, but maybe you can set the pin to the desired state in the setup() function and call gpio_hold_dis yourself right after?

What does seem contradicting in the documentation is that the gpio_hold_en is apparently not active during deep sleep, but should be activated right after deep sleep. However the documentation of gpio_deep_sleep_hold_en does contradict this. So it seems as if gpio_hold_dis is somehow called anyway when waking from deep sleep.

TD-er avatar Jun 30 '22 11:06 TD-er

I am having the same problem. I have tried for days to figure out why I my LED was flashing off when it was supposed to remain on after resume from deep sleep.

  • LED is set to be on using toggle switch.
  • ESP32 goes into Deep Sleep
  • Button is pressed which wakes ESP32 to wake up
  • When resuming from deep sleep, LED flashes off for a few milliseconds (noticeably blinks)

When sketch is compiled on a Mac 12.5, Arduino IDE 1.8.19, ESP32 Board 2.0.4, issue IS present. When sketch is compiled on a Windows 10 21H1, Arduino IDE 1.8.13, ESP32 Board 1.0.5, issue is NOT present.

#define BUTTON_PIN_BITMASK 0x200000000 // 2^33 in hex
RTC_DATA_ATTR int bootCount = 0;
RTC_DATA_ATTR int bootCountRefresh = 100;
#define uS_TO_S_FACTOR 1000000ULL  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  60        /* Time ESP32 will go to sleep (in seconds)   = Seconds per Cycles */
#define sleep_duration 5
uint64_t GPIO_reason;
uint64_t GPIO_wake_number;

#define pinButton1           33
#define pinButton2           14
char pinLED1              = 2;
char pinTEST            = 35;
/////////////////////////////////////////////////////////  Setup  /////////////////////////////////////////////////////////
void setup() {
  Serial.begin(115200);
  Serial.println("\n");
  Serial.println("-- Starting Setup -- ");
  pinMode(pinButton1, INPUT_PULLDOWN);
  //pinMode(pinButton1, INPUT_PULLUP);
  pinMode(pinLED1, OUTPUT);
  pinMode(pinTEST, INPUT);

  print_wakeup_reason();
  print_GPIO_wake_up();
  //esp_sleep_enable_ext0_wakeup(GPIO_NUM_34, 0); //1 = High, 0 = Low
  //esp_sleep_enable_ext0_wakeup(GPIO_NUM_39, 0); //1 = High, 0 = Low

  //---esp_sleep_enable_ext0_wakeup(GPIO_NUM_33, 0); //1 = High, 0 = Low
  esp_sleep_enable_ext1_wakeup(0x200004000, ESP_EXT1_WAKEUP_ANY_HIGH); //14 , 33

  //esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  //esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_OFF);
  //Serial.println("Configured all RTC Peripherals to be powered down in sleep");
}
/////////////////////////////////////////////////////////  LOOP  /////////////////////////////////////////////////////////
void loop() {
  // put your main code here, to run repeatedly:
  gpio_hold_dis((gpio_num_t) pinLED1);
  bool buttonstate = digitalRead(pinTEST);
  digitalWrite(pinLED1, buttonstate);
  esp_sleep_enable_timer_wakeup(sleep_duration * uS_TO_S_FACTOR);
  goToSleep();
}

/////////////////////////////////////////////////////////  print_GPIO_wake_up  /////////////////////////////////////////////////////////
void print_GPIO_wake_up() {
  GPIO_reason = esp_sleep_get_ext1_wakeup_status();
  Serial.print("GPIO that triggered the wake up: GPIO ");
  GPIO_wake_number = (log(GPIO_reason)) / log(2);
  Serial.println(GPIO_reason);
  Serial.print("GPIO that triggered the wake up: GPIO ");
  Serial.println(GPIO_wake_number);
}

///////////////////////////////////////////////////////// print_wakeup_reason  /////////////////////////////////////////////////////////
void print_wakeup_reason() {
  esp_sleep_wakeup_cause_t wakeup_reason;
  wakeup_reason = esp_sleep_get_wakeup_cause();
  switch (wakeup_reason)
  {
    case ESP_SLEEP_WAKEUP_EXT0 : Serial.println("Wakeup caused by external signal using RTC_IO"); break;
    case ESP_SLEEP_WAKEUP_EXT1 : Serial.println("Wakeup caused by external signal using RTC_CNTL");
    case ESP_SLEEP_WAKEUP_TIMER : Serial.println("Wakeup caused by timer"); break;
    case ESP_SLEEP_WAKEUP_TOUCHPAD : Serial.println("Wakeup caused by touchpad"); break;
    case ESP_SLEEP_WAKEUP_ULP : Serial.println("Wakeup caused by ULP program"); break;
    default : Serial.printf("Wakeup was not caused by deep sleep: %d\n", wakeup_reason); break;
  }
}
//////////////////////////////////////////////////////  goToSleep ///////////////////////////////////////////////////////////////
void goToSleep() {
  gpio_hold_en((gpio_num_t)pinLED1);
  esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
  //gpio_pullup_dis(gpio_num);
  //rtc_gpio_pulldown_en(GPIO_NUM_39);
  gpio_pulldown_en(GPIO_NUM_14);
  Serial.println("Going to sleep now");
  Serial.println("============================================================================");
  Serial.flush();
  delay(200);
  gpio_deep_sleep_hold_en();
  esp_deep_sleep_start();
}

EdHayes3 avatar Aug 02 '22 02:08 EdHayes3

@VojtechBartoska not sure if you are still following this, but curious on your thoughts of my testing.

EdHayes3 avatar Aug 12 '22 21:08 EdHayes3

Hi @EdHayes3, thanks for your feedback!

We will investigate this for next major release 2.1.0 :)

VojtechBartoska avatar Aug 12 '22 23:08 VojtechBartoska

@EdHayes3 Hi and thanks for great test sketch. There is a bug in ESP-IDF for a long time. I have created MR in ESP-IDF with fix. Once its merged and the fix gets to Arduino-esp32 I will inform you and close the issue.

P-R-O-C-H-Y avatar Aug 24 '22 13:08 P-R-O-C-H-Y

Hi @EdHayes3, @dynek the fix is already merged in ESP-IDF. It isn't in Arduino-core master branch merged yet, but if you wanna give it a try, you can checkout branch idf-release/v4.4 and test that.

P-R-O-C-H-Y avatar Sep 15 '22 11:09 P-R-O-C-H-Y

@dynek Are you able to test this under 2.0.5 Arduino version please?

VojtechBartoska avatar Sep 21 '22 12:09 VojtechBartoska

@VojtechBartoska Its not fixed in 2.0.5 yet. Will be in IDF 4.4.3. 2.0.5 is based on 4.4.2.

P-R-O-C-H-Y avatar Sep 21 '22 12:09 P-R-O-C-H-Y

@P-R-O-C-H-Y Perfect, so it will be part of bugfixes release. Thanks for answer and please don't reply during driving. 😄

VojtechBartoska avatar Sep 21 '22 14:09 VojtechBartoska

I'll try asap

dynek avatar Sep 28 '22 12:09 dynek

Missed @P-R-O-C-H-Y's comment in between, so I just tested with Plateform IO Espressif 32 version 5.2.0:

to find out that it still the same. Waiting next iteration :-)

dynek avatar Nov 14 '22 20:11 dynek

@dynek if you manually check current master branch, it's already using ESP-IDF 4.4.3. Or just wait for 2.0.6 release.

VojtechBartoska avatar Nov 16 '22 11:11 VojtechBartoska

@VojtechBartoska I just tested it on VSCode PlateformIO by adding the following to the project's plateformio.ini file:

platform_packages =
    platformio/framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#master

And I can confirm the problem is solved.

dynek avatar Nov 29 '22 20:11 dynek

@dynek Great, thanks for testing, closing as solved.

VojtechBartoska avatar Nov 30 '22 12:11 VojtechBartoska