@@ -415,6 +415,32 @@ static bool gpiodriver_is_gpio_attached(struct GPIOData *gpio_data, int gpio_num
415
415
return false;
416
416
}
417
417
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
+
418
444
static term gpiodriver_set_int (Context * ctx , int32_t target_pid , term cmd )
419
445
{
420
446
GlobalContext * glb = ctx -> global ;
@@ -456,9 +482,6 @@ static term gpiodriver_set_int(Context *ctx, int32_t target_pid, term cmd)
456
482
target_local_pid = target_pid ;
457
483
}
458
484
459
- if (gpiodriver_is_gpio_attached (gpio_data , gpio_num )) {
460
- return ERROR_ATOM ;
461
- }
462
485
463
486
/* TODO: GPIO specific atoms should be removed from platform_defaultatoms and constructed within this driver */
464
487
gpio_int_type_t interrupt_type ;
@@ -491,40 +514,50 @@ static term gpiodriver_set_int(Context *ctx, int32_t target_pid, term cmd)
491
514
return ERROR_ATOM ;
492
515
}
493
516
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
+ }
500
521
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 );
512
523
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
+ }
515
528
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 );
519
554
}
520
555
521
556
return OK_ATOM ;
522
557
}
523
558
524
559
static term gpiodriver_remove_int (Context * ctx , term cmd )
525
560
{
526
- struct GPIOData * gpio_data = ctx -> platform_data ;
527
-
528
561
term gpio_num_term = term_get_tuple_element (cmd , 1 );
529
562
gpio_num_t gpio_num ;
530
563
if (LIKELY (term_is_integer (gpio_num_term ))) {
@@ -537,27 +570,7 @@ static term gpiodriver_remove_int(Context *ctx, term cmd)
537
570
return ERROR_ATOM ;
538
571
}
539
572
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 );
561
574
}
562
575
563
576
static term create_pair (Context * ctx , term term1 , term term2 )
0 commit comments