Skip to content

Commit

Permalink
Allow using Pico-W WL_GPIO pins with gpio nifs
Browse files Browse the repository at this point in the history
Modifies the Pico gpio dirver to accept atoms for the special wl_gpio pins
present in the Pico-W.
- Adds support for `wl0` and `wl1` as output pins in `gpio:digital_write/2`.
- Adds support for `wl2` as an input pin in `gpio:digital_read/1`.

Signed-off-by: Winford <[email protected]>
  • Loading branch information
UncleGrumpy committed Oct 23, 2023
1 parent 68ba03a commit 5f16e3d
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 7 deletions.
2 changes: 1 addition & 1 deletion libs/eavmlib/src/gpio.erl
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
]).

-type gpio() :: pid().
-type pin() :: non_neg_integer() | {atom(), non_neg_integer()}.
-type pin() :: non_neg_integer() | {atom(), non_neg_integer()} | atom().
-type direction() :: input | output | output_od.
-type pull() :: up | down | up_down | floating.
-type low_level() :: low | 0.
Expand Down
50 changes: 44 additions & 6 deletions src/platforms/rp2040/src/lib/gpiodriver.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}
Expand All @@ -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"));
}
Expand Down

0 comments on commit 5f16e3d

Please sign in to comment.