diff --git a/CHANGELOG.md b/CHANGELOG.md index 750101e7c5..f94e5eec20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added cmake configuration option `AVM_CONFIG_REBOOT_ON_NOT_OK` for STM32 - New gpio driver for STM32 with nif and port support for read and write functions. - Added support for interrupts to STM32 GPIO port driver. +- Added suppoprt for PicoW extra gpio pins (led) to the gpio driver. ## [0.6.0-alpha.1] - 2023-10-09 diff --git a/libs/eavmlib/src/gpio.erl b/libs/eavmlib/src/gpio.erl index f91ac90d1d..0b5063d76b 100644 --- a/libs/eavmlib/src/gpio.erl +++ b/libs/eavmlib/src/gpio.erl @@ -58,7 +58,7 @@ -type gpio() :: pid(). %% This is the pid returned by `gpio:start/0'. --type pin() :: non_neg_integer() | pin_tuple(). +-type pin() :: non_neg_integer() | pin_tuple() | atom(). %% The pin definition for ESP32 and PR2040 is a non-negative integer, on the STM32 platform it is a tuple. -type pin_tuple() :: {gpio_bank(), 0..15}. %% A pin parameter on STM32 is a tuple consisting of a GPIO bank and pin number. diff --git a/src/platforms/rp2040/src/lib/gpiodriver.c b/src/platforms/rp2040/src/lib/gpiodriver.c index 30b56f7a06..2462a12a1c 100644 --- a/src/platforms/rp2040/src/lib/gpiodriver.c +++ b/src/platforms/rp2040/src/lib/gpiodriver.c @@ -66,6 +66,15 @@ static const AtomStringIntPair pin_level_table[] = { SELECT_INT_DEFAULT(AtomVMRP2040GPIOInvalid) }; +#ifdef LIB_PICO_CYW43_ARCH +static const AtomStringIntPair wl_pin_table[] = { + { ATOM_STR("\x3", "wl0"), 0 }, + { ATOM_STR("\x3", "wl1"), 1 }, + { ATOM_STR("\x3", "wl2"), 2 }, + SELECT_INT_DEFAULT(-1) +}; +#endif + static term nif_gpio_init(Context *ctx, int argc, term argv[]) { UNUSED(ctx); @@ -117,8 +126,7 @@ static term nif_gpio_digital_write(Context *ctx, int argc, term argv[]) { UNUSED(argc); - VALIDATE_VALUE(argv[0], term_is_integer); - int gpio_num = term_to_int(argv[0]); + term gpio_pin = argv[0]; term level_term = argv[1]; int level; @@ -133,7 +141,22 @@ static term nif_gpio_digital_write(Context *ctx, int argc, term argv[]) return ERROR_ATOM; } } - gpio_put(gpio_num, level); + + int gpio_num; + if (term_is_integer(gpio_pin)) { + gpio_num = gpio_pin; + gpio_put(gpio_num, level); +#ifdef LIB_PICO_CYW43_ARCH + } else if (term_is_atom(gpio_pin)) { + gpio_num = interop_atom_term_select_int(wl_pin_table, gpio_pin, ctx->global); + if (UNLIKELY((gpio_num == -1) || (gpio_num > 1))) { + return ERROR_ATOM; + } + cyw43_arch_gpio_put(gpio_num, level); +#endif + } else { + return ERROR_ATOM; + } return OK_ATOM; } @@ -142,9 +165,24 @@ static term nif_gpio_digital_read(Context *ctx, int argc, term argv[]) { UNUSED(argc); - VALIDATE_VALUE(argv[0], term_is_integer); - int gpio_num = term_to_int(argv[0]); - bool level = gpio_get(gpio_num); + term gpio_pin = argv[0]; + int gpio_num; + bool level; + + if (term_is_integer(gpio_pin)) { + gpio_num = gpio_pin; + level = gpio_get(gpio_num); +#ifdef LIB_PICO_CYW43_ARCH + } else if (term_is_atom(gpio_pin)) { + gpio_num = interop_atom_term_select_int(wl_pin_table, gpio_pin, ctx->global); + if (UNLIKELY((gpio_num != 2))) { + return ERROR_ATOM; + } + level = cyw43_arch_gpio_get(gpio_num); +#endif + } else { + return ERROR_ATOM; + } return level ? globalcontext_make_atom(ctx->global, ATOM_STR("\x4", "high")) : globalcontext_make_atom(ctx->global, ATOM_STR("\x3", "low")); }