Hi,
My app does most of its job in the wake stub, called when waking up from deep sleep (the reason is to be as reactive as possible, and to save as much energy as possible).
As the board it not fully initialized yet at that time, limited functionality is available from the wake stub, but ets_printf can be used.
The thing is, right after wakeup, the MacOS USB port used to power and communicate with the board has been disconnected on deep-sleep entry, and is not re-connected yet, so idf.py monitor is not able to output what is printed from the wake stub.

I guess I should use another UART, and plug a separate UART/USB device. However:

  • which other ESP32 UART should I use, and which TX pin?
  • how can I configure the system so that ets_printf uses that UART instead of the default one (#0 I believe?)?
  • do you have any other (simpler) approach to recommend?

Many thanks!

I would suggest UART0 on RX0 and TX0, since it is hard-wired as UART while the others go through GPIO MUX I think. That's TX0 and TX labeled-pins on the PowerFeather (TX0 and RX0, respectively). The reason is that I'm not sure if GPIO MUX config persists through deep sleep.

You can try other UARTs, and the relevant sdkconfig option should be: https://docs.espressif.com/projects/esp-idf/en/stable/esp32/api-reference/kconfig.html#config-esp-console-uart.

Thank you! Will try that.

Meanwhile I am a bit worried because, if I have found a way to configure GPIOs via registers* from GPIO0 to GPIO21, I could not manage to tackle GPIO22+ because I could find no registers for these higher GPIOs.

So in case you have some code working from wake stub to configure TX0/GPIO43 as digital output, I would be quite grateful (I trust it will start as input by default when resetting from deep sleep).

Thanks again!!

  • registers are the only thing that works during wake stub, because the higher level C APIs do not work as their code is in Flash, not available from wake stub.

    bfredo123 This question might be more appropriate for the ESP32 forum, as I myself have not gone into the deep end of using the wake stub.

    You might actually be better served by moving some logic into the ULP coprocessor instead, I believe you can do bitbang UART with it as per: https://github.com/espressif/esp-idf/tree/v5.2.3/examples/system/ulp/ulp_riscv/uart_print. Though again, I have not tried this myself... just spitballing 😃

    This way, you do not actually have to wake up unless you absolutely need the main core(s) to handle something...

    If it can help someone there, I have made some experiments with my oscilloscope:

    • ets_printf does output to TX0 from the wake stub without requiring any further setup
    • between the actual wake up, and the call to the wake stub, some processing is done by the ESP32 which takes 8.4ms. During that time some stuff is output to TX0 (I have no decoder so I can't say what it is, probably some diagnostic messages)
    • the output of this text goes on during the stub execution for another ~ 6-7ms (I assume that the UART flushes the output generated by the ROM)
    • the ets_printfoutput is generated at 115200 bps, the start bit is 0, the stop bit is 1, and there is no parity bit.

    Below is a working example:

    void RTC_IRAM_ATTR wake_stub_example(void) {
      ets_delay_us(7000);
      // this declaration is required to ensure that the data are in  RTC RAM, otherwise it crashes:
      static RTC_RODATA_ATTR const char fmt_str[] = "AB\n";
      ets_printf(fmt_str);
      esp_wake_stub_set_wakeup_time(1000);
      esp_wake_stub_sleep(&wake_stub_example);
    }

    I have set the logs (both bootloader and log output) to "none" in sdkconfig.

    I find it a bit disappointing that 8.4ms are spent before the wake stub is called, as it means that the battery will be used to power the chip during that time (in my case I only need 5ms in the wake stup, so it almost triple the energy required, to go from 5 to 13.4ms), but I guess this ROM initialization cannot be changed.

      bfredo123 Thanks for sharing!

      some processing is done by the ESP32 which takes 8.4ms.

      This is interesting. It may do some processing, but takes longer because it has to log it to UART.

      I have set the logs (both bootloader and log output) to "none" in sdkconfig.

      I think these options do not affect the log output done by the ROM code itself.
      Unfortunately GPIO46, the strapping pin which might be able to disable this, is assigned to the USR LED.
      You might be able to bodge a wire to pull this pin up to test if the wakeup time is reduced.

      If it does reduce it, you can set the fuses EFUSE_UART_PRINT_CONTROL and EFUSE_DIS_USB_SERIAL_JTAG_ROM_PRINT fuses. Note that this is permanent, though.

      6 days later

      Hi,
      Just FYI, I have purchased a UART/USB board, and by plugging it to TX0 and to the ground, the printf, ets_printf etc. can be seen from the Mac without any further setting.

      Regarding the 8.4ms processing, I had indeed already set the verbosity to minimum for the bootloader and the app logging, so this should be the ROM output only.
      Best regards