Page 1 of 1

toggle rtc_gpio pullup in wake_stub cause immediate WDT reboot

Posted: Wed Oct 25, 2023 3:12 pm
by PeteDD
I am trying to use as little power as possible so I want to turn off the pull-up on one port except when I am reading that port in a wake_stub. However, as soon as I add rtc_gpio_pullup_en(GPIO_NUM_27) to the code in the wake_stub, I get an immediate WDT reboot.

If I enable the pullup before going to sleep, then everything works fine however if my switch (rain tipping bucket) remains closed during the sleep, which it has a 50% chance of doing, then I am using power through the pull-up continuously which I am trying to avoid.

So, the question is, is it not allowed to toggle the rtc_gpio_pullup (that is, do a rtc_gpio_pullup_en, read the port, then do a rtc_gpio_pullup_dis) while in a wake_stub and then return to sleeping?

Here is a code example.
THANKS!
  1.  
  2.  
  3. // this is an example
  4. // GPIO-17 has a switch to ground
  5.  
  6. #define RAIN_CNT_RTC_GPIO_NUM 17
  7. #define RAIN_CNT_GPIO_NUM GPIO_NUM_27
  8.  
  9. static void RTC_IRAM_ATTR wake_stub(void)
  10. {
  11. #define PULSE_CNT_IS_LOW() \
  12.   ((REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & BIT(RAIN_CNT_RTC_GPIO_NUM)) == 0)
  13. /
  14.   rtc_gpio_pullup_en(RAIN_CNT_GPIO_NUM); // start using power
  15.   if (PULSE_CNT_IS_LOW())
  16.   {
  17.     // do something
  18.   }
  19.   else
  20.   {
  21.     // do something else
  22.   }
  23.   rtc_gpio_pullup_dis(RAIN_CNT_GPIO_NUM); // stop using power
  24.  
  25.  
  26.  // Set wakeup time in stub
  27.   uint64_t time_in_us = WAKE_EVERY_X_SECONDS * uS_TO_S_FACTOR;
  28.   deepsleep_for_us(time_in_us);
  29.  
  30.   // Print status.
  31.   ESP_RTC_LOGI("wake stub: going to deep sleep");
  32.  
  33.   // clear out the UART buffer before going to sleep
  34.   while (REG_GET_FIELD(UART_STATUS_REG(0), UART_ST_UTX_OUT))
  35.   {
  36.   }
  37.  
  38.   // Set the pointer of the wake stub function.
  39.   REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)&wake_stub);
  40.  
  41.   // Go to sleep again
  42.   CLEAR_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
  43.   SET_PERI_REG_MASK(RTC_CNTL_STATE0_REG, RTC_CNTL_SLEEP_EN);
  44. } // end of wake_stub example
  45.  

Re: toggle rtc_gpio pullup in wake_stub cause immediate WDT reboot

Posted: Wed Oct 25, 2023 3:50 pm
by PeteDD
I found another discussion about this here:
https://www.esp32.com/viewtopic.php?f= ... lup#p72193

and this page helps a lot:
https://github.com/espressif/esp-idf/b ... .c#L60-L81

Yes, using RTC_GPIO_PULLUP_EN in a wake stub WILL cause an immediate WDT reboot.

Yes, there is a way to do this using bit flipping and yes, like most ESP32 bit flipping, it is cryptic.

  1.  
  2. //First, in the main code, set up the port:
  3. #define RAIN_CNT_GPIO_NUM GPIO_NUM_27
  4. #define RAIN_CNT_RTC_GPIO_NUM 17
  5.  
  6.     rtc_gpio_init(RAIN_CNT_GPIO_NUM);
  7.     rtc_gpio_set_direction(RAIN_CNT_GPIO_NUM, RTC_GPIO_MODE_INPUT_ONLY);
  8.     rtc_gpio_pulldown_dis(RAIN_CNT_GPIO_NUM);
  9.     rtc_gpio_pullup_dis(RAIN_CNT_GPIO_NUM);  // start with pullup turned off
  10.  
  11. // then in the wake stub you can do this
  12. #define RAIN_CNT_IS_LOW() \
  13.   ((REG_GET_FIELD(RTC_GPIO_IN_REG, RTC_GPIO_IN_NEXT) & BIT(RAIN_CNT_RTC_GPIO_NUM)) == 0)
  14.  
  15.  REG_SET_BIT(RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_RUE_M);  // enable pull-up on GPIO-27
  16.  
  17.  if (RAIN_CNT_IS_LOW())
  18.   {
  19.     // do something
  20.   }
  21.   else
  22.   {
  23.     // do something else
  24.   }
  25.  
  26.  REG_CLR_BIT(RTC_IO_TOUCH_PAD7_REG, RTC_IO_TOUCH_PAD7_RUE_M); // disable pull-up  on GPIO-27
  27.  
  28. // then do the other stuff to prepare and re-enter deep sleep  or fully wake up.
  29.