Skip to content

Commit 102df63

Browse files
committed
1 parent 6607247 commit 102df63

3 files changed

Lines changed: 171 additions & 2 deletions

File tree

doc/src/programmers-guide.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ Use the [`esp:deep_sleep/1`](./apidocs/erlang/eavmlib/esp.md#deep_sleep1) functi
14001400
esp:deep_sleep(60*1000).
14011401
```
14021402
1403-
Use the [`esp:sleep_get_wakeup_cause/0`](./apidocs/erlang/eavmlib/esp.md#sleep_get_wakeup_cause0) function to inspect the reason for a wakeup. Possible return values include:
1403+
For ESP-IDF 5.5 compatibility, use [`esp:sleep_get_wakeup_cause/0`](./apidocs/erlang/eavmlib/esp.md#sleep_get_wakeup_cause0) to inspect a single wakeup reason. Possible values include:
14041404
14051405
* `sleep_wakeup_ext0`
14061406
* `sleep_wakeup_ext1`
@@ -1411,7 +1411,7 @@ Use the [`esp:sleep_get_wakeup_cause/0`](./apidocs/erlang/eavmlib/esp.md#sleep_g
14111411
* `sleep_wakeup_uart`
14121412
* `sleep_wakeup_wifi`
14131413
* `sleep_wakeup_cocpu`
1414-
* `sleep_wakeup_cocpu_trag_trig`
1414+
* `sleep_wakeup_cocpu_trap_trig`
14151415
* `sleep_wakeup_bt`
14161416
* `undefined` (no sleep wakeup)
14171417
* `error` (unknown other reason)
@@ -1431,6 +1431,20 @@ case esp:sleep_get_wakeup_cause() of
14311431
end.
14321432
```
14331433
1434+
For ESP-IDF 6+, use [`esp:sleep_get_wakeup_causes/0`](./apidocs/erlang/eavmlib/esp.md#sleep_get_wakeup_causes0) to inspect all wakeup reasons. This function returns a list, since a wakeup may have multiple causes.
1435+
1436+
The values match the semantics of [`esp_sleep_get_wakeup_causes`](https://docs.espressif.com/projects/esp-idf/en/release-v6.0/esp32/api-reference/system/sleep_modes.html).
1437+
1438+
```erlang
1439+
WakeupCauses = esp:sleep_get_wakeup_causes(),
1440+
case WakeupCauses of
1441+
[] ->
1442+
io:format("No wakeup cause available~n");
1443+
_ ->
1444+
io:format("Wakeup causes: ~p~n", [WakeupCauses])
1445+
end.
1446+
```
1447+
14341448
Use the [`esp:sleep_enable_ext0_wakeup/2`](./apidocs/erlang/eavmlib/esp.md#sleep_enable_ext0_wakeup2) and [`esp:sleep_enable_ext1_wakeup/2`](./apidocs/erlang/eavmlib/esp.md#sleep_enable_ext1_wakeup2) functions to configure ext0 and ext1 wakeup mechanisms. They follow the semantics of [`esp_sleep_enable_ext0_wakeup`](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32/api-reference/system/sleep_modes.html#_CPPv428esp_sleep_enable_ext0_wakeup10gpio_num_ti) and [`esp_sleep_enable_ext1_wakeup`](https://docs.espressif.com/projects/esp-idf/en/release-v5.5/esp32/api-reference/system/sleep_modes.html#_CPPv428esp_sleep_enable_ext1_wakeup8uint64_t28esp_sleep_ext1_wakeup_mode_t).
14351449
14361450
```erlang

libs/avm_esp32/src/esp.erl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
restart/0,
3131
reset_reason/0,
3232
sleep_get_wakeup_cause/0,
33+
sleep_get_wakeup_causes/0,
3334
sleep_enable_ext0_wakeup/2,
3435
sleep_enable_ext1_wakeup/2,
3536
sleep_enable_ext1_wakeup_io/2,
@@ -174,6 +175,15 @@ reset_reason() ->
174175
sleep_get_wakeup_cause() ->
175176
erlang:nif_error(undefined).
176177

178+
%%-----------------------------------------------------------------------------
179+
%% @returns wakeup causes for the previous sleep operation
180+
%% @doc Returns all causes for the wakeup
181+
%% @end
182+
%%-----------------------------------------------------------------------------
183+
-spec sleep_get_wakeup_causes() -> [esp_wakeup_cause()].
184+
sleep_get_wakeup_causes() ->
185+
erlang:nif_error(undefined).
186+
177187
%%-----------------------------------------------------------------------------
178188
%% @doc Configure gpio wakeup from deep sleep.
179189
%% Implemented for SOCs that support it (ESP32, ESP32S2, ESP32S3)

src/platforms/esp32/components/avm_sys/platform_nifs.c

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,6 +483,61 @@ static term nif_esp_sleep_get_wakeup_cause(Context *ctx, int argc, term argv[])
483483
UNUSED(argc);
484484
UNUSED(argv);
485485

486+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
487+
uint32_t causes = esp_sleep_get_wakeup_causes();
488+
489+
if (causes == 0) {
490+
return UNDEFINED_ATOM;
491+
}
492+
#if SOC_PM_SUPPORT_EXT_WAKEUP || SOC_PM_SUPPORT_EXT0_WAKEUP
493+
if (causes & BIT(ESP_SLEEP_WAKEUP_EXT0)) {
494+
return globalcontext_make_atom(ctx->global, sleep_wakeup_ext0_atom);
495+
}
496+
#endif
497+
#if SOC_PM_SUPPORT_EXT_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
498+
if (causes & BIT(ESP_SLEEP_WAKEUP_EXT1)) {
499+
return globalcontext_make_atom(ctx->global, sleep_wakeup_ext1_atom);
500+
}
501+
#endif
502+
if (causes & BIT(ESP_SLEEP_WAKEUP_TIMER)) {
503+
return globalcontext_make_atom(ctx->global, sleep_wakeup_timer_atom);
504+
}
505+
if (causes & BIT(ESP_SLEEP_WAKEUP_TOUCHPAD)) {
506+
return globalcontext_make_atom(ctx->global, sleep_wakeup_touchpad_atom);
507+
}
508+
#if SOC_ULP_SUPPORTED
509+
if (causes & BIT(ESP_SLEEP_WAKEUP_ULP)) {
510+
return globalcontext_make_atom(ctx->global, sleep_wakeup_ulp_atom);
511+
}
512+
#endif
513+
if (causes & BIT(ESP_SLEEP_WAKEUP_GPIO)) {
514+
return globalcontext_make_atom(ctx->global, sleep_wakeup_gpio_atom);
515+
}
516+
if (causes & BIT(ESP_SLEEP_WAKEUP_UART)) {
517+
return globalcontext_make_atom(ctx->global, sleep_wakeup_uart_atom);
518+
}
519+
#ifdef ESP_SLEEP_WAKEUP_WIFI
520+
if (causes & BIT(ESP_SLEEP_WAKEUP_WIFI)) {
521+
return globalcontext_make_atom(ctx->global, sleep_wakeup_wifi_atom);
522+
}
523+
#endif
524+
#ifdef ESP_SLEEP_WAKEUP_COCPU
525+
if (causes & BIT(ESP_SLEEP_WAKEUP_COCPU)) {
526+
return globalcontext_make_atom(ctx->global, sleep_wakeup_cocpu_atom);
527+
}
528+
#endif
529+
#ifdef ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG
530+
if (causes & BIT(ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG)) {
531+
return globalcontext_make_atom(ctx->global, sleep_wakeup_cocpu_trap_trig_atom);
532+
}
533+
#endif
534+
#ifdef ESP_SLEEP_WAKEUP_BT
535+
if (causes & BIT(ESP_SLEEP_WAKEUP_BT)) {
536+
return globalcontext_make_atom(ctx->global, sleep_wakeup_bt_atom);
537+
}
538+
#endif
539+
return ERROR_ATOM;
540+
#else
486541
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
487542

488543
switch (cause) {
@@ -527,6 +582,82 @@ static term nif_esp_sleep_get_wakeup_cause(Context *ctx, int argc, term argv[])
527582
default:
528583
return ERROR_ATOM;
529584
}
585+
#endif
586+
}
587+
588+
static term nif_esp_sleep_get_wakeup_causes(Context *ctx, int argc, term argv[])
589+
{
590+
UNUSED(argc);
591+
UNUSED(argv);
592+
593+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
594+
uint32_t causes = esp_sleep_get_wakeup_causes();
595+
#else
596+
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
597+
if (cause == ESP_SLEEP_WAKEUP_UNDEFINED) {
598+
return term_nil();
599+
}
600+
uint32_t causes = BIT(cause);
601+
#endif
602+
603+
if (causes == 0) {
604+
return term_nil();
605+
}
606+
607+
if (UNLIKELY(memory_ensure_free(ctx, CONS_SIZE * 11) != MEMORY_GC_OK)) {
608+
RAISE_ERROR(OUT_OF_MEMORY_ATOM);
609+
}
610+
611+
term causes_list = term_nil();
612+
#ifdef ESP_SLEEP_WAKEUP_BT
613+
if (causes & BIT(ESP_SLEEP_WAKEUP_BT)) {
614+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_bt_atom), causes_list, &ctx->heap);
615+
}
616+
#endif
617+
#ifdef ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG
618+
if (causes & BIT(ESP_SLEEP_WAKEUP_COCPU_TRAP_TRIG)) {
619+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_cocpu_trap_trig_atom), causes_list, &ctx->heap);
620+
}
621+
#endif
622+
#ifdef ESP_SLEEP_WAKEUP_COCPU
623+
if (causes & BIT(ESP_SLEEP_WAKEUP_COCPU)) {
624+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_cocpu_atom), causes_list, &ctx->heap);
625+
}
626+
#endif
627+
#ifdef ESP_SLEEP_WAKEUP_WIFI
628+
if (causes & BIT(ESP_SLEEP_WAKEUP_WIFI)) {
629+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_wifi_atom), causes_list, &ctx->heap);
630+
}
631+
#endif
632+
if (causes & BIT(ESP_SLEEP_WAKEUP_UART)) {
633+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_uart_atom), causes_list, &ctx->heap);
634+
}
635+
if (causes & BIT(ESP_SLEEP_WAKEUP_GPIO)) {
636+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_gpio_atom), causes_list, &ctx->heap);
637+
}
638+
#if SOC_ULP_SUPPORTED
639+
if (causes & BIT(ESP_SLEEP_WAKEUP_ULP)) {
640+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_ulp_atom), causes_list, &ctx->heap);
641+
}
642+
#endif
643+
if (causes & BIT(ESP_SLEEP_WAKEUP_TOUCHPAD)) {
644+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_touchpad_atom), causes_list, &ctx->heap);
645+
}
646+
if (causes & BIT(ESP_SLEEP_WAKEUP_TIMER)) {
647+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_timer_atom), causes_list, &ctx->heap);
648+
}
649+
#if SOC_PM_SUPPORT_EXT_WAKEUP || SOC_PM_SUPPORT_EXT1_WAKEUP
650+
if (causes & BIT(ESP_SLEEP_WAKEUP_EXT1)) {
651+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_ext1_atom), causes_list, &ctx->heap);
652+
}
653+
#endif
654+
#if SOC_PM_SUPPORT_EXT_WAKEUP || SOC_PM_SUPPORT_EXT0_WAKEUP
655+
if (causes & BIT(ESP_SLEEP_WAKEUP_EXT0)) {
656+
causes_list = term_list_prepend(globalcontext_make_atom(ctx->global, sleep_wakeup_ext0_atom), causes_list, &ctx->heap);
657+
}
658+
#endif
659+
660+
return causes_list;
530661
}
531662

532663
#if SOC_PM_SUPPORT_EXT_WAKEUP || SOC_PM_SUPPORT_EXT0_WAKEUP
@@ -613,8 +744,13 @@ static term nif_esp_deep_sleep_enable_gpio_wakeup(Context *ctx, int argc, term a
613744
VALIDATE_VALUE(argv[0], term_is_any_integer);
614745
VALIDATE_VALUE(argv[1], term_is_integer);
615746
avm_int64_t mask = term_maybe_unbox_int64(argv[0]);
747+
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(6, 0, 0)
748+
esp_sleep_gpio_wake_up_mode_t mode = term_to_int(argv[1]);
749+
esp_err_t err = esp_sleep_enable_gpio_wakeup_on_hp_periph_powerdown(mask, mode);
750+
#else
616751
esp_deepsleep_gpio_wake_up_mode_t mode = term_to_int(argv[1]);
617752
esp_err_t err = esp_deep_sleep_enable_gpio_wakeup(mask, mode);
753+
#endif
618754
if (UNLIKELY(err == ESP_ERR_INVALID_ARG)) {
619755
RAISE_ERROR(BADARG_ATOM);
620756
}
@@ -1014,6 +1150,11 @@ static const struct Nif esp_sleep_get_wakeup_cause_nif =
10141150
.base.type = NIFFunctionType,
10151151
.nif_ptr = nif_esp_sleep_get_wakeup_cause
10161152
};
1153+
static const struct Nif esp_sleep_get_wakeup_causes_nif =
1154+
{
1155+
.base.type = NIFFunctionType,
1156+
.nif_ptr = nif_esp_sleep_get_wakeup_causes
1157+
};
10171158
#if SOC_PM_SUPPORT_EXT_WAKEUP || SOC_PM_SUPPORT_EXT0_WAKEUP
10181159
static const struct Nif esp_sleep_enable_ext0_wakeup_nif =
10191160
{
@@ -1180,6 +1321,10 @@ const struct Nif *platform_nifs_get_nif(const char *nifname)
11801321
TRACE("Resolved platform nif %s ...\n", nifname);
11811322
return &esp_sleep_get_wakeup_cause_nif;
11821323
}
1324+
if (strcmp("esp:sleep_get_wakeup_causes/0", nifname) == 0) {
1325+
TRACE("Resolved platform nif %s ...\n", nifname);
1326+
return &esp_sleep_get_wakeup_causes_nif;
1327+
}
11831328
#if SOC_PM_SUPPORT_EXT_WAKEUP || SOC_PM_SUPPORT_EXT0_WAKEUP
11841329
if (strcmp("esp:sleep_enable_ext0_wakeup/2", nifname) == 0) {
11851330
TRACE("Resolved platform nif %s ...\n", nifname);

0 commit comments

Comments
 (0)