Why can MicroPython not use the ULP WAKE instruction
Re: Why can MicroPython not use the ULP WAKE instruction
@mattyt
Oh dear, I've looked at the code you referred to and it's fairly much mumbo-jumbo to me
I guess we need to add another bool called wake to the typedef for machine_rtc_config and also another static object similar to esp32_wake_on_touch called esp32_wake but I don't see where these connect to the "real world" which for the ulp timer wakeup API is here and for our new ULP wakeup for the WAKE instruction would be this.
I so want this to work but I fear that I am going to need so much help that my input will be negligible. However, I can see that the code required is small and so maybe I can stumble through it with some help After all, I did used to write machine code for Z80 before assemblers were available to joe public, but that was (sigh) a long time ago and had the benefit of being essentially simple even if a lot of care was required
Anyway, still waiting to find non-V0/V1 chip dev boards, so there's no rush I guess...
Oh dear, I've looked at the code you referred to and it's fairly much mumbo-jumbo to me
I guess we need to add another bool called wake to the typedef for machine_rtc_config and also another static object similar to esp32_wake_on_touch called esp32_wake but I don't see where these connect to the "real world" which for the ulp timer wakeup API is here and for our new ULP wakeup for the WAKE instruction would be this.
I so want this to work but I fear that I am going to need so much help that my input will be negligible. However, I can see that the code required is small and so maybe I can stumble through it with some help After all, I did used to write machine code for Z80 before assemblers were available to joe public, but that was (sigh) a long time ago and had the benefit of being essentially simple even if a lot of care was required
Anyway, still waiting to find non-V0/V1 chip dev boards, so there's no rush I guess...
John Ellis
What cannot go wrong, will. What definitely cannot go wrong absolutely will...
What cannot go wrong, will. What definitely cannot go wrong absolutely will...
Re: Why can MicroPython not use the ULP WAKE instruction
Re-reading the ESP-IDF, I've definitely over-stated this:
The IDF says this:mattyt wrote: ↑Mon Nov 30, 2020 12:59 am...wasn't implemented because it didn't work on rev 0 and 1 versions of the ESP32
Those are fairly specific conditions so I think v0 and v1 chips should work ok.ESP-IDF wrote: In revisions 0 and 1 of the ESP32, ULP wakeup source cannot be used when RTC_PERIPH power domain is forced to be powered on (ESP_PD_OPTION_ON) or when ext0 wakeup source is used.
Re: Why can MicroPython not use the ULP WAKE instruction
Some of that code was a bit...hairy.
Having briefly read a little more I think all we need to do is enable the ULP to wake up the CPU and then put the CPU into a deep sleep (after running code on the ULP that will trigger a WAKE).
I think this means that the only missing link is to enable the ULP to wake the CPU. That's just an IDF call that can be exposed like this:
Code: Select all
diff --git a/ports/esp32/modesp32.c b/ports/esp32/modesp32.c
index 28d1762d2..8d304d4a3 100644
--- a/ports/esp32/modesp32.c
+++ b/ports/esp32/modesp32.c
@@ -45,6 +45,13 @@
#include "modmachine.h"
#include "machine_rtc.h"
#include "modesp32.h"
+#include "esp_sleep.h"
+
+STATIC mp_obj_t esp32_enable_ulp_wakeup(void) {
+ return mp_obj_new_int(esp_sleep_enable_ulp_wakeup())
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp32_raw_temperature_obj, esp32_raw_temperature);
STATIC mp_obj_t esp32_wake_on_touch(const mp_obj_t wake) {
@@ -173,6 +180,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp32_idf_heap_info_obj, esp32_idf_heap_info);
STATIC const mp_rom_map_elem_t esp32_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp32) },
+ { MP_ROM_QSTR(MP_QSTR_enable_ulp_wakeup), MP_ROM_PTR(&esp32_enable_ulp_wakeup_obj) },
{ MP_ROM_QSTR(MP_QSTR_wake_on_touch), MP_ROM_PTR(&esp32_wake_on_touch_obj) },
{ MP_ROM_QSTR(MP_QSTR_wake_on_ext0), MP_ROM_PTR(&esp32_wake_on_ext0_obj) },
{ MP_ROM_QSTR(MP_QSTR_wake_on_ext1), MP_ROM_PTR(&esp32_wake_on_ext1_obj) },
Code: Select all
import machine
import esp32
# Allow ESP32 to be woken by ULP WAKE opcode
esp32.enable_ulp_wakeup()
# Load and run pre-compiled ULP binary
ulp = esp32.ULP()
f = open('ulp_main.bin')
binary = f.read()
load_addr, entry_addr = 0, 4
ulp.load_binary(load_addr, binary)
ulp.run(entry_addr)
# Put ESP32 to sleep, relying on the ULP to wake
machine.deepsleep()
# Note that machine.wake_reason() == machine.ULP_WAKE
Re: Why can MicroPython not use the ULP WAKE instruction
Yes, I think I just got there yesterday, empirically, when I bit the bullet and installed the whole ESP-IDF thing and worked through an example to use the WAKE instruction (with the ADC as it happens) and it all works just fine, so the revision 1 chips clearly work. I now have enough dev boards, all revision 1 from different suppliers, to wallpaper my officeThose are fairly specific conditions so I think v0 and v1 chips should work ok.
So, now knowing I have h/w that will allow me to test, I will look at your (no doubt excellent) code and see what I can do with it! Thank you!
Just an interesting titbit: When I run that ULP ADC program and I power the ESP32 from an Anker USB battery pack, after 1 minute, the battery pack switches off the juice. I assume that the current is so low that it thinks nothing is connected!? Cases with battery holders have been ordered for the next phase of testing
The light at the end of the tunnel has reappeared...
John Ellis
What cannot go wrong, will. What definitely cannot go wrong absolutely will...
What cannot go wrong, will. What definitely cannot go wrong absolutely will...
-
- Posts: 969
- Joined: Sat Feb 03, 2018 7:02 pm
Re: Why can MicroPython not use the ULP WAKE instruction
yeah that happens with most battery packs sadly. Had that problem with my esp8266 too Apparently you can force them to stay on if you make consumption peaks in a certain interval. But didn't quite work with my battery pack.. Ultimately I gave up on thatellisjr wrote: ↑Tue Dec 15, 2020 2:26 pmJust an interesting titbit: When I run that ULP ADC program and I power the ESP32 from an Anker USB battery pack, after 1 minute, the battery pack switches off the juice. I assume that the current is so low that it thinks nothing is connected!? Cases with battery holders have been ordered for the next phase of testing
Kevin Köck
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
Micropython Smarthome Firmware (with Home-Assistant integration): https://github.com/kevinkk525/pysmartnode
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Why can MicroPython not use the ULP WAKE instruction
Yup, me too. Fixed (or rather bodged) with a resistor between the 5V supply and gnd. ISTR 47Ω 0.5W did the trick with mine.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Why can MicroPython not use the ULP WAKE instruction
Thanks, there is one mistake in the patch, it should be:
Code: Select all
+STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp32_enable_ulp_wakeup_obj, esp32_enable_ulp_wakeup);
To test if the system is ready for wake up and avoid unnecessary interrupts the
Code: Select all
READ_RTC_FIELD(RTC_CNTL_LOW_POWER_ST_REG, RTC_CNTL_RDY_FOR_WAKEUP)
Code: Select all
reg_rd 0x3ff480c0, 19, 19
Where 0x3ff480c0 = DR_REG_RTCCNTL_BASE + 0xc0:
Code: Select all
> hex(0x3ff48000 + 0xc0)
'0x3ff480c0'
It would be nice if this change could be added to the official micropython source code among adc1_ulp_enable() (and other ULP related calls if there is any)
Re: Why can MicroPython not use the ULP WAKE instruction
@clone
Welcome to the party! Or should I say, thank goodness, the cavalry have arrived! I have spent three days getting to the point where I can build Micropython, so that I could test Mattyt's code, but I have finally just done it. Many traps for the unwary/uninitiated...
So, I will also test the change and add to the calls for it to be added to the official release.
Also, I am impressed that you could work out the raw reg_rd instruction instead of the macros; I tried it with no success, but somehow that doesn't surprise me That IS very useful though so that we can use py-esp32-ulp with ease.
Welcome to the party! Or should I say, thank goodness, the cavalry have arrived! I have spent three days getting to the point where I can build Micropython, so that I could test Mattyt's code, but I have finally just done it. Many traps for the unwary/uninitiated...
So, I will also test the change and add to the calls for it to be added to the official release.
Also, I am impressed that you could work out the raw reg_rd instruction instead of the macros; I tried it with no success, but somehow that doesn't surprise me That IS very useful though so that we can use py-esp32-ulp with ease.
John Ellis
What cannot go wrong, will. What definitely cannot go wrong absolutely will...
What cannot go wrong, will. What definitely cannot go wrong absolutely will...
Re: Why can MicroPython not use the ULP WAKE instruction
@mattyt
So, I built MP with the changes as debugged by @clone and of course, it works perfectly. Thank you both!
I'm guessing that this is a silly question, but why can't esp32.enable_ulp_wakeup() take a Boolean to enable and disable the use of the ULP WAKE instruction? It would seem good to be able to turn it off as well as on, but I guess maybe when I start building real applications I might see why one would not need to turn it off (though on that basis, why is it not always on? )
Anyway, if we ignore my NOOB question this all seems good and I would welcome it in the standard build asap.
So, I built MP with the changes as debugged by @clone and of course, it works perfectly. Thank you both!
I'm guessing that this is a silly question, but why can't esp32.enable_ulp_wakeup() take a Boolean to enable and disable the use of the ULP WAKE instruction? It would seem good to be able to turn it off as well as on, but I guess maybe when I start building real applications I might see why one would not need to turn it off (though on that basis, why is it not always on? )
Anyway, if we ignore my NOOB question this all seems good and I would welcome it in the standard build asap.
John Ellis
What cannot go wrong, will. What definitely cannot go wrong absolutely will...
What cannot go wrong, will. What definitely cannot go wrong absolutely will...
Re: Why can MicroPython not use the ULP WAKE instruction
There is no disable_ulp_wakeup in official API, because you have to call enable_ulp_wakeup() every time before you go to deep sleep if you want to enable ULP wake.ellisjr wrote: ↑Wed Dec 23, 2020 4:27 pmI'm guessing that this is a silly question, but why can't esp32.enable_ulp_wakeup() take a Boolean to enable and disable the use of the ULP WAKE instruction? It would seem good to be able to turn it off as well as on, but I guess maybe when I start building real applications I might see why one would not need to turn it off (though on that basis, why is it not always on? )
Probably esp32.wake_from_ulp(wake: bool) would be the closest to current micropython function names: there is already a esp32.wake_on_touch(wake: bool) function to call esp_sleep_enable_touchpad_wakeup(void).
Probably it will require more modification based on current esp32.wake_on_touch that stores the enable/disable status in rtc memory to preserve it between restarts.