From fae09ba29e15b27016bc8b3cf097f5baee27fd60 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 15 Sep 2023 18:43:02 -0700 Subject: [PATCH 1/9] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f4ffbccee..935b866ce 100644 --- a/README.md +++ b/README.md @@ -508,7 +508,7 @@ NB: Set parameter to empty to disable battery reading. For named configurations ### Sleeping The esp32 can be put in deep sleep mode to save some power. How much really depends on the connected periperals, so best is to do your own measures. Waking-up from deep sleep is the equivalent of a reboot, but as the chip takes a few seconds to connect, it's still an efficient process. -The esp32 can enter deep sleep after an audio inactivity timeout, after a button has been pressed or after a GPIO is set to a given level. It wakes up only on GPIO events +The esp32 can enter deep sleep after an audio inactivity timeout, after a button has been pressed or after a GPIO is set to a given level. It wakes up only on GPIO events. Note that *all* GPIO are isolated when sleeping, so you can not assume anything about their value, except that they will not drain current. The NVS parameter `sleep_config` is mostly used for setting sleep conditions ``` @@ -528,6 +528,8 @@ The option to use multiple GPIOs is very limited on esp32 and the esp-idf 4.3.x - ESP32: 0, 2, 4, 12-15, 25-27, 32-39; - ESP32-S3: 0-21. +Some has asked for a soft power on/off option. Although this is not built-in, it's easy to create yours as long as the regulator/power supply of the board can be controlled by Vcc or GND. Depending on how it is active, add a pull-up/down resistor to the regulator's control and connect it also to one GPIO of the esp32. Then using set_GPIO, set that GPIO to Vcc or GND. Use a hardware button that forces the regulator on with a pull- up/down and once the esp32 has booted, it will force the GPIO to the desired value maintaining the board on by software. To power it off by software, just use the deep sleep option which will suspend all GPIO hence switching off the regulator. + # Configuration ## Setup WiFi From c4df0c93f98e2599fb1f1ec4964c842415cb255c Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 15 Sep 2023 18:47:23 -0700 Subject: [PATCH 2/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 935b866ce..ce6563f2f 100644 --- a/README.md +++ b/README.md @@ -69,7 +69,7 @@ Please note that when sending to a Bluetooth speaker (source), only 44.1 kHz can Most DAC will work out-of-the-box with simply an I2S connection, but some require specific commands to be sent using I2C. See DAC option below to understand how to send these dedicated commands. There is build-in support for TAS575x, TAS5780, TAS5713 and AC101 DAC. ### Raw WROOM esp32-s3 module -The esp32-s3 based modules like [this]@(https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf) are also supported but requires esp-idf 4.4. It is not yet part of official releases, but it compiles & runs. The s3 does not have bluetooth audio. Note that CPU performances are greatly enhanced. +The esp32-s3 based modules like [this](https://www.espressif.com/sites/default/files/documentation/esp32-s3-wroom-1_wroom-1u_datasheet_en.pdf) are also supported but requires esp-idf 4.4. It is not yet part of official releases, but it compiles & runs. The s3 does not have bluetooth audio. Note that CPU performances are greatly enhanced. ### SqueezeAMP This is the main hardware companion of Squeezelite-esp32 and has been developped together. Details on capabilities can be found [here](https://forums.slimdevices.com/showthread.php?110926-pre-ANNOUNCE-SqueezeAMP-and-SqueezeliteESP32) and [here](https://github.com/philippe44/SqueezeAMP). From c61ff05081959d8d897798dd5d032855e0d9ef31 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 15 Sep 2023 18:50:26 -0700 Subject: [PATCH 3/9] take into account case with no wake option --- components/services/services.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/services/services.c b/components/services/services.c index 6ace648b6..fd469b6c0 100644 --- a/components/services/services.c +++ b/components/services/services.c @@ -176,11 +176,13 @@ void services_sleep_activate(sleep_cause_e cause) { if (sleep_config.wake_gpio & (sleep_config.wake_gpio - 1)) { ESP_LOGI(TAG, "going to sleep cause %d, wake-up on multiple GPIO, any '1' wakes up 0x%llx", cause, sleep_config.wake_gpio); esp_sleep_enable_ext1_wakeup(sleep_config.wake_gpio, ESP_EXT1_WAKEUP_ANY_HIGH); - } else { + } else if (sleep_config.wake_gpio) { int gpio = __builtin_ctz(sleep_config.wake_gpio); int level = (sleep_config.wake_level >> gpio) & 0x01; ESP_LOGI(TAG, "going to sleep cause %d, wake-up on GPIO %d level %d", cause, gpio, level); esp_sleep_enable_ext0_wakeup(gpio, level); + } else { + ESP_LOGW(TAG, "going to sleep cause %d, no wake-up option", cause); } // we need to use a timer in case the same button is used for sleep and wake-up and it's "pressed" vs "released" selected From f4e899fc60d561c06379babed52114cb6680d31c Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 15 Sep 2023 20:38:47 -0700 Subject: [PATCH 4/9] add option to maintain some RTC GPIO pull-up/down --- components/services/services.c | 42 +++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/components/services/services.c b/components/services/services.c index fd469b6c0..b301d8d3f 100644 --- a/components/services/services.c +++ b/components/services/services.c @@ -45,6 +45,7 @@ pwm_system_t pwm_system = { static EXT_RAM_ATTR struct { uint64_t wake_gpio, wake_level; + uint64_t rtc_gpio, rtc_level; uint32_t delay; } sleep_config; @@ -136,6 +137,28 @@ static void sleep_init(void) { ESP_LOGI(TAG, "Sleep wake-up gpio bitmap 0x%llx (active 0x%llx)", sleep_config.wake_gpio, sleep_config.wake_level); } } + + // get the rtc-pull criteria + if ((p = strcasestr(config, "rtc"))) { + char list[32] = "", item[8]; + sscanf(p, "%*[^=]=%31[^,]", list); + p = list - 1; + while (p++ && sscanf(p, "%7[^|]", item)) { + int level = 0, gpio = atoi(item); + if (!rtc_gpio_is_valid_gpio(gpio)) { + ESP_LOGE(TAG, "invalid rtc GPIO %d", gpio); + } else { + sleep_config.rtc_gpio |= 1LL << gpio; + } + if (sscanf(item, "%*[^:]:%d", &level)) sleep_config.rtc_level |= level << gpio; + p = strchr(p, '|'); + } + + // when moving to esp-idf more recent than 4.4.x, multiple gpio wake-up with level specific can be done + if (sleep_config.rtc_gpio) { + ESP_LOGI(TAG, "RTC forced gpio bitmap 0x%llx (active 0x%llx)", sleep_config.rtc_gpio, sleep_config.rtc_level); + } + } // then get the gpio that activate sleep (we could check that we have a valid wake) if ((p = strcasestr(config, "sleep"))) { @@ -165,11 +188,24 @@ void services_sleep_activate(sleep_cause_e cause) { // call all sleep hooks that might want to do something for (void (**hook)(void) = sleep_hooks; *hook; hook++) (*hook)(); - // isolate all possible GPIOs, except the wake-up ones + // isolate all possible GPIOs, except the wake-up and RTC-maintaines ones esp_sleep_config_gpio_isolate(); + + // keep RTC domain up if we need to maintain pull-up/down of some GPIO from RTC + if (sleep_config.rtc_gpio) esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON); + for (int i = 0; i < GPIO_NUM_MAX; i++) { - if (!rtc_gpio_is_valid_gpio(i) || ((1LL << i) & sleep_config.wake_gpio)) continue; - rtc_gpio_isolate(i); + // must be a RTC GPIO + if (!rtc_gpio_is_valid_gpio(i)) continue; + + // do we need to maintain a pull-up or down of that GPIO + if ((1LL << i) & sleep_config.rtc_gpio) { + if ((sleep_config.rtc_level >> i) & 0x01) rtc_gpio_pullup_en(i); + else rtc_gpio_pulldown_en(i); + // or is this not wake-up GPIO, just isolate it + } else if (!((1LL << i) & sleep_config.wake_gpio)) { + rtc_gpio_isolate(i); + } } // is there just one GPIO From ddd6bddde7caee52db2c47e4afac7d3fbb1f4657 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 15 Sep 2023 20:46:41 -0700 Subject: [PATCH 5/9] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ce6563f2f..d5f9744ac 100644 --- a/README.md +++ b/README.md @@ -508,11 +508,11 @@ NB: Set parameter to empty to disable battery reading. For named configurations ### Sleeping The esp32 can be put in deep sleep mode to save some power. How much really depends on the connected periperals, so best is to do your own measures. Waking-up from deep sleep is the equivalent of a reboot, but as the chip takes a few seconds to connect, it's still an efficient process. -The esp32 can enter deep sleep after an audio inactivity timeout, after a button has been pressed or after a GPIO is set to a given level. It wakes up only on GPIO events. Note that *all* GPIO are isolated when sleeping, so you can not assume anything about their value, except that they will not drain current. +The esp32 can enter deep sleep after an audio inactivity timeout, after a button has been pressed or after a GPIO is set to a given level. It wakes up only on some GPIO events. Note that *all* GPIO are isolated when sleeping (unless they are set with the `rtc`option) so you can not assume anything about their value, except that they will not drain current. The `rtc` option allows to keep some GPIO (from the RTC domain only) either pulled up or down. This can be useful if you want to keep some periperal active, for example a GPIO expander whose interrupt will be used to wake-up the system. The NVS parameter `sleep_config` is mostly used for setting sleep conditions ``` -[delay=][,sleep=[:0|1]][,wake=[:0|1][|[:0|1]...] +[delay=][,sleep=[:0|1]][,wake=[:0|1][|[:0|1]...][,rtc=[:0|1][|[:0|1]...] ``` - delay is in **minutes** - sleep is the GPIO that will put the system into sleep and it can be a level 0 or 1 From 28ecad46524c675a633ba81479b93190bbafb92f Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 15 Sep 2023 21:26:33 -0700 Subject: [PATCH 6/9] ACTRLS_SLEEP should be last (indexed array) and red led is not default for parsing --- components/services/audio_controls.c | 4 ++-- components/services/audio_controls.h | 4 ++-- components/services/led.c | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/components/services/audio_controls.c b/components/services/audio_controls.c index 60792ccf2..b071bc082 100644 --- a/components/services/audio_controls.c +++ b/components/services/audio_controls.c @@ -58,11 +58,11 @@ static const actrls_config_map_t actrls_config_map[] = // BEWARE: the actions below need to stay aligned with the corresponding enum to properly support json parsing // along with the actrls_t controls in LMS_controls, bt_sink and raop_sink #define EP(x) [x] = #x /* ENUM PRINT */ -static const char * actrls_action_s[ ] = { EP(ACTRLS_SLEEP),EP(ACTRLS_POWER),EP(ACTRLS_VOLUP),EP(ACTRLS_VOLDOWN),EP(ACTRLS_TOGGLE),EP(ACTRLS_PLAY), +static const char * actrls_action_s[ ] = { EP(ACTRLS_POWER),EP(ACTRLS_VOLUP),EP(ACTRLS_VOLDOWN),EP(ACTRLS_TOGGLE),EP(ACTRLS_PLAY), EP(ACTRLS_PAUSE),EP(ACTRLS_STOP),EP(ACTRLS_REW),EP(ACTRLS_FWD),EP(ACTRLS_PREV),EP(ACTRLS_NEXT), EP(BCTRLS_UP),EP(BCTRLS_DOWN),EP(BCTRLS_LEFT),EP(BCTRLS_RIGHT), EP(BCTRLS_PS0),EP(BCTRLS_PS1),EP(BCTRLS_PS2),EP(BCTRLS_PS3),EP(BCTRLS_PS4),EP(BCTRLS_PS5),EP(BCTRLS_PS6),EP(BCTRLS_PS7),EP(BCTRLS_PS8),EP(BCTRLS_PS9), - EP(KNOB_LEFT),EP(KNOB_RIGHT),EP(KNOB_PUSH), + EP(KNOB_LEFT),EP(KNOB_RIGHT),EP(KNOB_PUSH), EP(ACTRLS_SLEEP), ""} ; static const char * TAG = "audio controls"; diff --git a/components/services/audio_controls.h b/components/services/audio_controls.h index 137bda7e6..0c5f5fd26 100644 --- a/components/services/audio_controls.h +++ b/components/services/audio_controls.h @@ -11,12 +11,12 @@ #include "buttons.h" // BEWARE: this is the index of the array of action below (change actrls_action_s as well!) -typedef enum { ACTRLS_NONE = -1, ACTRLS_SLEEP, ACTRLS_POWER, ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY, +typedef enum { ACTRLS_NONE = -1, ACTRLS_POWER, ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY, ACTRLS_PAUSE, ACTRLS_STOP, ACTRLS_REW, ACTRLS_FWD, ACTRLS_PREV, ACTRLS_NEXT, BCTRLS_UP, BCTRLS_DOWN, BCTRLS_LEFT, BCTRLS_RIGHT, BCTRLS_PS0,BCTRLS_PS1,BCTRLS_PS2,BCTRLS_PS3,BCTRLS_PS4,BCTRLS_PS5,BCTRLS_PS6,BCTRLS_PS7,BCTRLS_PS8,BCTRLS_PS9, KNOB_LEFT, KNOB_RIGHT, KNOB_PUSH, - ACTRLS_REMAP, ACTRLS_MAX + ACTRLS_REMAP, ACTRLS_SLEEP, ACTRLS_MAX } actrls_action_e; typedef void (*actrls_handler)(bool pressed); diff --git a/components/services/led.c b/components/services/led.c index decf2f8f4..0c9d42a6f 100644 --- a/components/services/led.c +++ b/components/services/led.c @@ -283,7 +283,8 @@ void set_led_gpio(int gpio, char *value) { struct led_config_s *config; if (strcasestr(value, "green")) config = &green; - else config = &red; + else if (strcasestr(value, "red"))config = &red; + else return; config->gpio = gpio; char *p = value; From 822de92df1e163bce733f5bdcf698e6793d8ef08 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 15 Sep 2023 21:31:54 -0700 Subject: [PATCH 7/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d5f9744ac..56f59f098 100644 --- a/README.md +++ b/README.md @@ -528,7 +528,7 @@ The option to use multiple GPIOs is very limited on esp32 and the esp-idf 4.3.x - ESP32: 0, 2, 4, 12-15, 25-27, 32-39; - ESP32-S3: 0-21. -Some has asked for a soft power on/off option. Although this is not built-in, it's easy to create yours as long as the regulator/power supply of the board can be controlled by Vcc or GND. Depending on how it is active, add a pull-up/down resistor to the regulator's control and connect it also to one GPIO of the esp32. Then using set_GPIO, set that GPIO to Vcc or GND. Use a hardware button that forces the regulator on with a pull- up/down and once the esp32 has booted, it will force the GPIO to the desired value maintaining the board on by software. To power it off by software, just use the deep sleep option which will suspend all GPIO hence switching off the regulator. +Some have asked for a soft power on/off option. Although this is not built-in, it's easy to create yours as long as the regulator/power supply of the board can be controlled by Vcc or GND. Depending on how it is active, add a pull-up/down resistor to the regulator's control and connect it also to one GPIO of the esp32. Then using set_GPIO, set that GPIO to Vcc or GND. Use a hardware button that forces the regulator on with a pull- up/down and once the esp32 has booted, it will force the GPIO to the desired value maintaining the board on by software. To power it off by software, just use the deep sleep option which will suspend all GPIO hence switching off the regulator. # Configuration From b47074e6687efd11db1ceda8a950fb7bb7227099 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Fri, 15 Sep 2023 21:32:46 -0700 Subject: [PATCH 8/9] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 56f59f098..2572e06e2 100644 --- a/README.md +++ b/README.md @@ -389,11 +389,12 @@ Where (all parameters are optionals except gpio) Where `` is either the name of another configuration to load (remap) or one amongst ``` -ACTRLS_NONE, ACTRLS_SLEEP, ACTRLS_POWER, ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY, +ACTRLS_NONE, ACTRLS_POWER, ACTRLS_VOLUP, ACTRLS_VOLDOWN, ACTRLS_TOGGLE, ACTRLS_PLAY, ACTRLS_PAUSE, ACTRLS_STOP, ACTRLS_REW, ACTRLS_FWD, ACTRLS_PREV, ACTRLS_NEXT, BCTRLS_UP, BCTRLS_DOWN, BCTRLS_LEFT, BCTRLS_RIGHT, BCTRLS_PS1, BCTRLS_PS2, BCTRLS_PS3, BCTRLS_PS4, BCTRLS_PS5, BCTRLS_PS6, BCTRLS_PS7, BCTRLS_PS8, BCTRLS_PS9, BCTRLS_PS10, -KNOB_LEFT, KNOB_RIGHT, KNOB_PUSH, +KNOB_LEFT, KNOB_RIGHT, KNOB_PUSH, +ACTRLS_SLEEP, ``` Note that ACTRLS_SLEEP is not an actual button that can be sent to LMS, but it's a hook to activate deep sleep mode (see [Sleeping](#sleeping)). From effc574e50721d31e47c91cad8c98ffe04de7ea6 Mon Sep 17 00:00:00 2001 From: philippe44 Date: Sat, 16 Sep 2023 00:35:09 -0700 Subject: [PATCH 9/9] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2572e06e2..150ebaaa1 100644 --- a/README.md +++ b/README.md @@ -525,7 +525,7 @@ Please see [buttons](#buttons) for detailed syntax. The option to use multiple GPIOs is very limited on esp32 and the esp-idf 4.3.x we are using: it is only possible to wake-up when **any** of the defined GPIO is set to 1. The fact that you can specify different levels in the wake list is irrelevant for now, it's just a provision for future upgrades to more recent versions of esp-idf. -**Note that not all GPIOs can be used to wake-up the esp32** +**Only the following GPIOs can be used to wake-up the esp32** - ESP32: 0, 2, 4, 12-15, 25-27, 32-39; - ESP32-S3: 0-21.