39
39
#include "mailbox.h"
40
40
#include "module.h"
41
41
#include "nifs.h"
42
- #include "platform_defaultatoms.h"
43
42
#include "port.h"
44
43
#include "scheduler.h"
45
44
#include "term.h"
49
48
50
49
#include "esp32_sys.h"
51
50
#include "esp_log.h"
51
+ #include "platform_defaultatoms.h"
52
52
#include "sys.h"
53
53
54
54
#define TAG "gpio_driver"
@@ -68,11 +68,6 @@ static void gpio_isr_handler(void *arg);
68
68
static Context * gpio_driver_create_port (GlobalContext * global , term opts );
69
69
#endif
70
70
71
- #ifdef CONFIG_AVM_ENABLE_GPIO_PORT_DRIVER
72
- static const char * const gpio_atom = "\x4" "gpio" ;
73
- static const char * const gpio_driver_atom = "\xB" "gpio_driver" ;
74
- #endif
75
-
76
71
static const AtomStringIntPair pin_mode_table [] = {
77
72
{ ATOM_STR ("\x5" , "input" ), GPIO_MODE_INPUT },
78
73
{ ATOM_STR ("\x6" , "output" ), GPIO_MODE_OUTPUT },
@@ -101,6 +96,16 @@ static const AtomStringIntPair pin_level_table[] = {
101
96
SELECT_INT_DEFAULT (GPIOPinInvalid )
102
97
};
103
98
99
+ static const AtomStringIntPair int_trigger_table [] = {
100
+ { ATOM_STR ("\x4" , "none" ), GPIO_INTR_DISABLE },
101
+ { ATOM_STR ("\x6" , "rising" ), GPIO_INTR_POSEDGE },
102
+ { ATOM_STR ("\x7" , "falling" ), GPIO_INTR_NEGEDGE },
103
+ { ATOM_STR ("\x4" , "both" ), GPIO_INTR_ANYEDGE },
104
+ { ATOM_STR ("\x3" , "low" ), GPIO_INTR_LOW_LEVEL },
105
+ { ATOM_STR ("\x4" , "high" ), GPIO_INTR_HIGH_LEVEL },
106
+ SELECT_INT_DEFAULT (GPIO_INTR_MAX )
107
+ };
108
+
104
109
enum gpio_cmd
105
110
{
106
111
GPIOInvalidCmd = 0 ,
@@ -286,15 +291,19 @@ static inline term gpio_digital_read(term gpio_num_term)
286
291
287
292
avm_int_t level = gpio_get_level (gpio_num );
288
293
289
- return level ? HIGH_ATOM : LOW_ATOM ;
294
+ return level ? globalcontext_make_atom ( glb , high_atom ) : globalcontext_make_atom ( glb , low_atom ) ;
290
295
}
291
296
292
297
#ifdef CONFIG_AVM_ENABLE_GPIO_PORT_DRIVER
293
298
294
299
void gpio_driver_init (GlobalContext * global )
295
300
{
296
- int index = globalcontext_insert_atom (global , gpio_driver_atom );
297
- gpio_driver = term_from_atom_index (index );
301
+ int index = globalcontext_insert_atom (global , ATOM_STR ("\xB" , "gpio_driver" ));
302
+ if (UNLIKELY (index < 0 )){
303
+ ESP_LOGE (TAG , "Failed to initialize gpio_driver" );
304
+ } else {
305
+ gpio_driver = term_from_atom_index (index );
306
+ }
298
307
}
299
308
300
309
Context * gpio_driver_create_port (GlobalContext * global , term opts )
@@ -312,12 +321,18 @@ Context *gpio_driver_create_port(GlobalContext *global, term opts)
312
321
ctx -> native_handler = consume_gpio_mailbox ;
313
322
ctx -> platform_data = gpio_data ;
314
323
315
- term reg_name_term = globalcontext_make_atom (global , gpio_atom );
316
- int atom_index = term_to_atom_index ( reg_name_term );
317
-
318
- if ( UNLIKELY (! globalcontext_register_process ( ctx -> global , atom_index , ctx -> process_id ))) {
324
+ int gpio_atom_index = globalcontext_insert_atom (global , ATOM_STR ( "\x4" , "gpio" ) );
325
+ if ( UNLIKELY ( gpio_atom_index < 0 )) {
326
+ ESP_LOGE ( TAG , "Failed to create 'gpio' atom to register the driver!" );
327
+ free ( gpio_data );
319
328
scheduler_terminate (ctx );
329
+ return NULL ;
330
+ }
331
+
332
+ if (UNLIKELY (!globalcontext_register_process (ctx -> global , gpio_atom_index , ctx -> process_id ))) {
320
333
ESP_LOGE (TAG , "Only a single GPIO driver can be opened." );
334
+ free (gpio_data );
335
+ scheduler_terminate (ctx );
321
336
return NULL ;
322
337
}
323
338
@@ -327,7 +342,7 @@ Context *gpio_driver_create_port(GlobalContext *global, term opts)
327
342
static term gpiodriver_close (Context * ctx )
328
343
{
329
344
GlobalContext * glb = ctx -> global ;
330
- int gpio_atom_index = atom_table_ensure_atom (glb -> atom_table , gpio_atom , AtomTableNoOpts );
345
+ int gpio_atom_index = atom_table_ensure_atom (glb -> atom_table , ATOM_STR ( "\x4" , "gpio" ) , AtomTableNoOpts );
331
346
if (UNLIKELY (!globalcontext_get_registered_process (glb , gpio_atom_index ))) {
332
347
return ERROR_ATOM ;
333
348
}
@@ -482,36 +497,9 @@ static term gpiodriver_set_int(Context *ctx, int32_t target_pid, term cmd)
482
497
target_local_pid = target_pid ;
483
498
}
484
499
485
-
486
- /* TODO: GPIO specific atoms should be removed from platform_defaultatoms and constructed within this driver */
487
- gpio_int_type_t interrupt_type ;
488
- switch (trigger ) {
489
- case NONE_ATOM :
490
- interrupt_type = GPIO_INTR_DISABLE ;
491
- break ;
492
-
493
- case RISING_ATOM :
494
- interrupt_type = GPIO_INTR_POSEDGE ;
495
- break ;
496
-
497
- case FALLING_ATOM :
498
- interrupt_type = GPIO_INTR_NEGEDGE ;
499
- break ;
500
-
501
- case BOTH_ATOM :
502
- interrupt_type = GPIO_INTR_ANYEDGE ;
503
- break ;
504
-
505
- case LOW_ATOM :
506
- interrupt_type = GPIO_INTR_LOW_LEVEL ;
507
- break ;
508
-
509
- case HIGH_ATOM :
510
- interrupt_type = GPIO_INTR_HIGH_LEVEL ;
511
- break ;
512
-
513
- default :
514
- return ERROR_ATOM ;
500
+ gpio_int_type_t interrupt_type = interop_atom_term_select_int (int_trigger_table , trigger , ctx -> global );
501
+ if (UNLIKELY (interrupt_type == GPIO_INTR_MAX )) {
502
+ return BADARG_ATOM ;
515
503
}
516
504
517
505
if (trigger != NONE_ATOM ) {
@@ -570,6 +558,7 @@ static term gpiodriver_remove_int(Context *ctx, term cmd)
570
558
return ERROR_ATOM ;
571
559
}
572
560
561
+
573
562
return unregister_interrupt_listener (ctx , gpio_num );
574
563
}
575
564
@@ -749,7 +738,7 @@ static term nif_gpio_digital_write(Context *ctx, int argc, term argv[])
749
738
750
739
static term nif_gpio_digital_read (Context * ctx , int argc , term argv [])
751
740
{
752
- return gpio_digital_read (argv [0 ]);
741
+ return gpio_digital_read (ctx , argv [0 ]);
753
742
}
754
743
755
744
static const struct Nif gpio_init_nif =
0 commit comments