Skip to content

Commit 3d71182

Browse files
committed
Forward port changes from v0.6 release branch
Merge release-0.6 into main branch.
2 parents 1ca523c + 65f644a commit 3d71182

File tree

4 files changed

+68
-54
lines changed

4 files changed

+68
-54
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ might lead to a crash in certain situations.
2929
- Fixed destruction of ssl-related resources
3030
- Fix corruption when dealing with specific situations that involve more than 16 x registers when
3131
certain VM instructions are used.
32+
- Fixed ESP32 GPIO interrupt trigger `none`
3233

3334
## [0.6.5] - 2024-10-15
3435

src/platforms/esp32/components/avm_builtins/gpio_driver.c

+61-48
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,32 @@ static bool gpiodriver_is_gpio_attached(struct GPIOData *gpio_data, int gpio_num
415415
return false;
416416
}
417417

418+
static term unregister_interrupt_listener(Context *ctx, gpio_num_t gpio_num)
419+
{
420+
struct GPIOData *gpio_data = ctx->platform_data;
421+
struct ListHead *item;
422+
struct ListHead *tmp;
423+
MUTABLE_LIST_FOR_EACH (item, tmp, &gpio_data->gpio_listeners) {
424+
struct GPIOListenerData *gpio_listener = GET_LIST_ENTRY(item, struct GPIOListenerData, gpio_listener_list_head);
425+
if (gpio_listener->gpio == gpio_num) {
426+
sys_unregister_listener(ctx->global, &gpio_listener->listener);
427+
list_remove(&gpio_listener->gpio_listener_list_head);
428+
free(gpio_listener);
429+
430+
gpio_set_intr_type(gpio_num, GPIO_INTR_DISABLE);
431+
gpio_isr_handler_remove(gpio_num);
432+
433+
if (list_is_empty(&gpio_data->gpio_listeners)) {
434+
gpio_uninstall_isr_service();
435+
}
436+
437+
return OK_ATOM;
438+
}
439+
}
440+
441+
return ERROR_ATOM;
442+
}
443+
418444
static term gpiodriver_set_int(Context *ctx, int32_t target_pid, term cmd)
419445
{
420446
GlobalContext *glb = ctx->global;
@@ -456,9 +482,6 @@ static term gpiodriver_set_int(Context *ctx, int32_t target_pid, term cmd)
456482
target_local_pid = target_pid;
457483
}
458484

459-
if (gpiodriver_is_gpio_attached(gpio_data, gpio_num)) {
460-
return ERROR_ATOM;
461-
}
462485

463486
/* TODO: GPIO specific atoms should be removed from platform_defaultatoms and constructed within this driver */
464487
gpio_int_type_t interrupt_type;
@@ -491,40 +514,50 @@ static term gpiodriver_set_int(Context *ctx, int32_t target_pid, term cmd)
491514
return ERROR_ATOM;
492515
}
493516

494-
TRACE("going to install interrupt for %i.\n", gpio_num);
495-
496-
if (list_is_empty(&gpio_data->gpio_listeners)) {
497-
gpio_install_isr_service(0);
498-
TRACE("installed ISR service 0.\n");
499-
}
517+
if (trigger != NONE_ATOM) {
518+
if (UNLIKELY(gpiodriver_is_gpio_attached(gpio_data, gpio_num))) {
519+
return ERROR_ATOM;
520+
}
500521

501-
struct GPIOListenerData *data = malloc(sizeof(struct GPIOListenerData));
502-
if (IS_NULL_PTR(data)) {
503-
ESP_LOGE(TAG, "gpiodriver_set_int: Failed to ensure free heap space.");
504-
AVM_ABORT();
505-
}
506-
list_append(&gpio_data->gpio_listeners, &data->gpio_listener_list_head);
507-
data->gpio = gpio_num;
508-
data->target_local_pid = target_local_pid;
509-
sys_register_listener(glb, &data->listener);
510-
data->listener.sender = data;
511-
data->listener.handler = gpio_interrupt_callback;
522+
TRACE("going to install interrupt for %i.\n", gpio_num);
512523

513-
gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
514-
gpio_set_intr_type(gpio_num, interrupt_type);
524+
if (list_is_empty(&gpio_data->gpio_listeners)) {
525+
gpio_install_isr_service(0);
526+
TRACE("installed ISR service 0.\n");
527+
}
515528

516-
esp_err_t ret = gpio_isr_handler_add(gpio_num, gpio_isr_handler, data);
517-
if (UNLIKELY(ret != ESP_OK)) {
518-
return ERROR_ATOM;
529+
struct GPIOListenerData *data = malloc(sizeof(struct GPIOListenerData));
530+
if (IS_NULL_PTR(data)) {
531+
ESP_LOGE(TAG, "gpiodriver_set_int: Failed to ensure free heap space.");
532+
AVM_ABORT();
533+
}
534+
list_append(&gpio_data->gpio_listeners, &data->gpio_listener_list_head);
535+
data->gpio = gpio_num;
536+
data->target_local_pid = target_local_pid;
537+
sys_register_listener(glb, &data->listener);
538+
data->listener.sender = data;
539+
data->listener.handler = gpio_interrupt_callback;
540+
541+
gpio_set_direction(gpio_num, GPIO_MODE_INPUT);
542+
gpio_set_intr_type(gpio_num, interrupt_type);
543+
544+
esp_err_t ret = gpio_isr_handler_add(gpio_num, gpio_isr_handler, data);
545+
if (UNLIKELY(ret != ESP_OK)) {
546+
return ERROR_ATOM;
547+
}
548+
} else {
549+
if (UNLIKELY(!gpiodriver_is_gpio_attached(gpio_data, gpio_num))) {
550+
return ERROR_ATOM;
551+
}
552+
gpio_set_intr_type(gpio_num, interrupt_type);
553+
return unregister_interrupt_listener(ctx, gpio_num);
519554
}
520555

521556
return OK_ATOM;
522557
}
523558

524559
static term gpiodriver_remove_int(Context *ctx, term cmd)
525560
{
526-
struct GPIOData *gpio_data = ctx->platform_data;
527-
528561
term gpio_num_term = term_get_tuple_element(cmd, 1);
529562
gpio_num_t gpio_num;
530563
if (LIKELY(term_is_integer(gpio_num_term))) {
@@ -537,27 +570,7 @@ static term gpiodriver_remove_int(Context *ctx, term cmd)
537570
return ERROR_ATOM;
538571
}
539572

540-
struct ListHead *item;
541-
struct ListHead *tmp;
542-
MUTABLE_LIST_FOR_EACH (item, tmp, &gpio_data->gpio_listeners) {
543-
struct GPIOListenerData *gpio_listener = GET_LIST_ENTRY(item, struct GPIOListenerData, gpio_listener_list_head);
544-
if (gpio_listener->gpio == gpio_num) {
545-
list_remove(&gpio_listener->gpio_listener_list_head);
546-
sys_unregister_listener(ctx->global, &gpio_listener->listener);
547-
free(gpio_listener);
548-
549-
gpio_set_intr_type(gpio_num, GPIO_INTR_DISABLE);
550-
gpio_isr_handler_remove(gpio_num);
551-
552-
if (list_is_empty(&gpio_data->gpio_listeners)) {
553-
gpio_uninstall_isr_service();
554-
}
555-
556-
return OK_ATOM;
557-
}
558-
}
559-
560-
return ERROR_ATOM;
573+
return unregister_interrupt_listener(ctx, gpio_num);
561574
}
562575

563576
static term create_pair(Context *ctx, term term1, term term2)

src/platforms/esp32/test/main/test_erl_sources/test_esp_partition.erl

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ start() ->
2525
[
2626
{<<"nvs">>, 1, 2, 16#9000, 16#6000, []},
2727
{<<"phy_init">>, 1, 1, 16#f000, 16#1000, []},
28-
{<<"factory">>, 0, 0, 16#10000, 16#200000, []},
29-
{<<"lib.avm">>, 1, 1, 16#210000, 16#40000, []},
30-
{<<"main.avm">>, 1, 1, 16#250000, 16#100000, []}
28+
{<<"factory">>, 0, 0, 16#10000, 16#2C0000, []},
29+
{<<"lib.avm">>, 1, 1, 16#2D0000, 16#40000, []},
30+
{<<"main.avm">>, 1, 1, 16#310000, 16#40000, []}
3131
] = esp:partition_list(),
3232
0.

src/platforms/esp32/test/partitions.csv

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,6 @@
1010
# Note: if you change the phy_init or app partition offset, make sure to change the offset in Kconfig.projbuild
1111
nvs, data, nvs, 0x9000, 0x6000,
1212
phy_init, data, phy, 0xf000, 0x1000,
13-
factory, app, factory, 0x10000, 0x200000,
14-
lib.avm, data, phy, 0x210000, 0x40000,
15-
main.avm, data, phy, 0x250000, 0x100000
13+
factory, app, factory, 0x10000, 0x2C0000,
14+
lib.avm, data, phy, 0x2D0000, 0x40000,
15+
main.avm, data, phy, 0x310000, 0x40000

0 commit comments

Comments
 (0)