PIN latch functionality for ESP32
PIN latch functionality for ESP32
Hi guys,
On `ESP32` PINs can keep their value in deep sleep with using the functions `rtc_gpio_hold_en()` and `rtc_gpio_hold_dis()`.
I had a look at the `MicroPython` code base and saw that it would be an option to add such a functionality in `modesp32.c`.
Would you guys welcome adding such a functionality?
Would that be a good spot there? What names for the two new functions could be used?
I saw that other similar functions like `wake_on_ext1()` don't exactly follow the naming in `esp-idf` but I didn't figure a rule how to convert function names in `esp-idf ` to function names in `MicroPython`.
Regards,
Pete
On `ESP32` PINs can keep their value in deep sleep with using the functions `rtc_gpio_hold_en()` and `rtc_gpio_hold_dis()`.
I had a look at the `MicroPython` code base and saw that it would be an option to add such a functionality in `modesp32.c`.
Would you guys welcome adding such a functionality?
Would that be a good spot there? What names for the two new functions could be used?
I saw that other similar functions like `wake_on_ext1()` don't exactly follow the naming in `esp-idf` but I didn't figure a rule how to convert function names in `esp-idf ` to function names in `MicroPython`.
Regards,
Pete
Re: PIN latch functionality for ESP32
In the close related Pycom dialect this method is called hold() with the argument True and False. So pin.hold(True) enables it, pin.hold(False) disables it. For consistency, this name should be used.
-
- Posts: 169
- Joined: Fri Aug 19, 2016 11:55 am
Re: PIN latch functionality for ESP32
Is this related to the Pin.PULL_HOLD flag (of which I’m not entirely sure what it does)?
Re: PIN latch functionality for ESP32
No, it is not. PULL_HOLD activates a function, which freezes the state of a PIN, such that it will not be modified any more by changing input value in input mode or by writing to the pin in output mode. I can imagine why that is useful input mode, but not for output mode.
Re: PIN latch functionality for ESP32
@Roberthh are you considering extending the generic class `machine.Pin` for this functionality? I'm unsure if other CPUs than ESP32 support it too.
The two functions are described here:
https://docs.espressif.com/projects/esp ... gpio_num_t
In output mode it's useful for deep sleep. When these functions are not called, the PIN is switched off in deep sleep.
The two functions are described here:
https://docs.espressif.com/projects/esp ... gpio_num_t
In output mode it's useful for deep sleep. When these functions are not called, the PIN is switched off in deep sleep.
Re: PIN latch functionality for ESP32
It is not a problem if only the ESP32 supports it. There are many other examples of hardware-specific functions in MicroPython, which are not supported by every port. For instance WiFi. I understand why that is useful, so there are good reasons for implementing it. Whether I will implement it ... don't know.
Re: PIN latch functionality for ESP32
So I made a test implementation of pin.hold(). Not a lot of work for coding. Testing takes longer.
It works, but I see no difference to the pull=Pin.PULL_HOLD option of Pin.init(). In both cases, the value of the output is frozen and maintained during a machine.deepsleep() or machine.reset() call. A physical reset clears the setting. And opposed to the documentation, a pin input value with Pin.hold or pull=Pin.PULL_HOLD is not frozen. Even if set, the value read back is the actual value at the input. That's different to how I understand the espressif documentation.
I did not test (yet) with a battery attached.
Core code of the pin.hold function:
Additionally needed in the include section
and in the QSTR definitions:
It works, but I see no difference to the pull=Pin.PULL_HOLD option of Pin.init(). In both cases, the value of the output is frozen and maintained during a machine.deepsleep() or machine.reset() call. A physical reset clears the setting. And opposed to the documentation, a pin input value with Pin.hold or pull=Pin.PULL_HOLD is not frozen. Even if set, the value read back is the actual value at the input. That's different to how I understand the espressif documentation.
I did not test (yet) with a battery attached.
Core code of the pin.hold function:
Code: Select all
// pin.hold(value)
STATIC mp_obj_t machine_pin_hold(mp_obj_t self_in, mp_obj_t arg) {
machine_pin_obj_t *self = MP_OBJ_TO_PTR(self_in);
esp_err_t rc;
if (mp_obj_is_true(arg)) {
rc = rtc_gpio_hold_en(self->id);
} else {
rc = rtc_gpio_hold_dis(self->id);
}
if (rc == ESP_OK) {
return mp_const_none;
} else {
mp_raise_ValueError(MP_ERROR_TEXT("invalid pin for hold"));
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(machine_pin_hold_obj, machine_pin_hold);
Code: Select all
#include "driver/rtc_io.h"
Code: Select all
{ MP_ROM_QSTR(MP_QSTR_hold), MP_ROM_PTR(&machine_pin_hold_obj) },
Re: PIN latch functionality for ESP32
@ PRosenb: Finally using the option pull=Pin.PULL_HOLD with the existing firmware will offer you the in intended function of keeping the value of an output Pin during machine.deepsleep and machine.reset. It also prevents the redefinition of a PIN to input mode until the hold is released with pull=None. Still I could not see any effect on the input mode.
pull=Pin.PULL_HOLD causes gpio_hold_en to be called for that pin, and similar
pull=None causes gpio_hold_dis to be called.
pull=Pin.PULL_HOLD causes gpio_hold_en to be called for that pin, and similar
pull=None causes gpio_hold_dis to be called.
Re: PIN latch functionality for ESP32
Many thanks @Roberthh for such a quick answer and even analysis.
For some reason it behaves differently on my ESP32. It is a "ESP32 DEVKITV1", silicon revision 1.
I tested
- self built MicroPython with current master (using ESP-IDF v3.3.2)
- esp32spiram-idf3-20191220-v1.12.bin (downloaded)
Then I execute the following code, the internal LED is not switched on. When I remove `Pin.PULL_HOLD`, the internal LED is switched on for 2 seconds and goes off afterwards while the CPU is in deep sleep.
It seams that on my chip it only works when using `rtc_gpio_hold_en()` instead of `gpio_hold_en()`.
For some reason it behaves differently on my ESP32. It is a "ESP32 DEVKITV1", silicon revision 1.
I tested
- self built MicroPython with current master (using ESP-IDF v3.3.2)
- esp32spiram-idf3-20191220-v1.12.bin (downloaded)
Then I execute the following code, the internal LED is not switched on. When I remove `Pin.PULL_HOLD`, the internal LED is switched on for 2 seconds and goes off afterwards while the CPU is in deep sleep.
It seams that on my chip it only works when using `rtc_gpio_hold_en()` instead of `gpio_hold_en()`.
Code: Select all
import utime
import machine
from machine import Pin
def test():
led_pin = Pin(2, Pin.OUT, Pin.PULL_HOLD)
# led_pin = Pin(2, Pin.OUT)
print("led on")
led_pin.on()
print("wait 2 sec")
utime.sleep(2)
print("deep sleep 2 sec")
machine.deepsleep(2 * 1000)
Re: PIN latch functionality for ESP32
Once PULL_HOLD is called, the output does not change any more. So I used the sequence:
Unfortunately, the ESP32 port does not have the single pin.pull() method.
Edit: I use a Wemos board, but the chips are expected to behave identical.
Code: Select all
led_pin = Pin(2, Pin.OUT)
led_pin.on() # or led_pin(1)
led_pin.init(Pin.OUT, pull=Pin.PULL_HOLD)
Edit: I use a Wemos board, but the chips are expected to behave identical.