libretiny-eu / libretiny

PlatformIO development platform for IoT modules
http://docs.libretiny.eu/
MIT License
383 stars 55 forks source link

[beken-72xx] Fix GPIO deep sleep wakeup edge #159

Closed Xmister closed 10 months ago

Xmister commented 10 months ago

Manufacturer docs: https://docs-bekencorp-com.translate.goog/sdk_3.0.x/bk7238/html/developer-guide/power_save/sleep_test.html?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=hu&_x_tr_pto=wapp

Discussion: https://github.com/libretiny-eu/libretiny-esphome/pull/11

kuba2k2 commented 10 months ago

I'm not sure I understand. The manufacturer docs say "rising edge" is 0: obraz This PR changes the behavior, so that on_high = true (wake up on HIGH level == wake up on RISING edge) sets 1 bit in the gpio_edge_map:

        if (on_high) {
        deep_sleep_param.gpio_edge_map |= gpio_index_map;
    } 

You've said that

And indeed, the translated manufacturer docs agree that "1" should be the rising edge

except that the docs are mixing the values. First they say "rising edge, falling edge" and then they say "falling edge, rising edge".

I think that this has to be tested properly, by attaching a button (with debouncing) to a GPIO pin, then enabling deep sleep with either on_high = true or false, and measuring the GPIO voltage when it wakes up. I'll do that test in a moment.

Xmister commented 10 months ago

Users' comments from the esphome PR confirms it worked for them when the logic was reverted. Also the level definition in wakeup_pins were wrong, that's why it was working for me so far. But sure, please test it yourself to be sure.

kuba2k2 commented 10 months ago

How do I actually test it? Something doesn't work for me.

#include <Arduino.h>

void setup() {
    pinMode(14, INPUT);
    // pinMode(14, OUTPUT);
    // while (true) {
    //  digitalWrite(14, HIGH);
    //  delay(1000);
    //  digitalWrite(14, LOW);
    //  delay(1000);
    //  yield();
    // }
}

void loop() {
    Serial.println("Waking up on HIGH...");
    lt_deep_sleep_config_gpio(1 << 14, true);
    lt_deep_sleep_enter();
    Serial.println("Wake up successful!");
    delay(2000);
    Serial.println("Waking up on LOW...");
    lt_deep_sleep_config_gpio(1 << 14, false);
    lt_deep_sleep_enter();
    Serial.println("Wake up successful!");
    delay(2000);
}

I uploaded this test program, and it gets stuck on Waking up on HIGH. I have confirmed that P14 is the right pin - you can see the commented-out code in setup(). Also tried with pinMode INPUT and without it. Tried connecting 3.3V and GND to the pin. Tried resetting while connected to GND, then lifting it and conecting to 3.3V. Sadly it doesn't go out of deep sleep. Do you know what am I doing wrong?

Xmister commented 10 months ago

Are you sure it's not coming out? Wakeup basically means a reset with some extra info in the registers, so your app will never reach Serial.println("Wake up successful!"); It might just go to sleep too early to be able to print the initial message to serial.

kuba2k2 commented 10 months ago

Oh. You're right, obviously - I haven't been too familiar with deep sleep at all. Still, I was getting no messages at all after the deep sleep.

Turns out, that deep sleep deactivates UART1 and UART2 - which are not activated back after waking up. Since LibreTiny doesn't initialize these peripherals upon reboot (and since I didn't add Serial.begin as I thought it "just works" every time without it) the UART stayed disabled.

I added uart1_init(); to the Serial class and now RTC timer deep sleep works fine. I'll test GPIO shortly.

kuba2k2 commented 10 months ago

Yeah that works... GPIO wakeup is inverted, as per this PR. Thanks!

One odd thing is that HIGH wakeup doesn't set the reset reason correctly...

I [      0.000] LibreTiny v1.2.1+sha.f387138.dirty on generic-bk7231n-qfn32-tuya, compiled at Aug 23 2023 15:33:27, GCC 10.3.1 (-O1)
I [      0.000] Reset reason: Power-On
// lt_deep_sleep_config_gpio(1 << 14, false);
Waking up on LOW...
I [      0.000] LibreTiny v1.2.1+sha.f387138.dirty on generic-bk7231n-qfn32-tuya, compiled at Aug 23 2023 15:33:27, GCC 10.3.1 (-O1)
I [      0.000] Reset reason: Sleep Wakeup
// lt_deep_sleep_config_gpio(1 << 14, true);
Waking up on HIGH...
I [      0.000] LibreTiny v1.2.1+sha.f387138.dirty on generic-bk7231n-qfn32-tuya, compiled at Aug 23 2023 15:33:27, GCC 10.3.1 (-O1)
I [      0.000] Reset reason: Power-On
// lt_deep_sleep_config_timer(1000);
Waking up in 1000 ms...
I [      0.000] LibreTiny v1.2.1+sha.f387138.dirty on generic-bk7231n-qfn32-tuya, compiled at Aug 23 2023 15:33:27, GCC 10.3.1 (-O1)
I [      0.000] Reset reason: Sleep Wakeup