Skip to content

Commit 1f06efc

Browse files
committed
Merge pull request #1234 from pguyot/w29/gpio-init-esp32
Implement `gpio:init/1` on esp32 Some GPIO pins require initialization as gpio pins to work, for example GPIO 4 on ESP32C3. This is achieved by calling esp-idf `gpio_config`. Implement this within `gpio:init/1` which is used on rp2040. These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 3b6f36c + 855460c commit 1f06efc

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
66

77
## [0.6.4] - Unreleased
88

9+
### Added
10+
11+
- Implement `gpio:init/1` on esp32 to initialize pins for GPIO usage, which some pins
12+
require depending on default function and bootloader code
13+
914
## [0.6.3] - 20-07-2024
1015

1116
### Added

libs/eavmlib/src/gpio.erl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ remove_int(GPIO, Pin) ->
296296
%% @param Pin number to initialize
297297
%% @returns ok
298298
%% @doc Initialize a pin to be used as GPIO.
299-
%% Currently only implemented (and required) for RP2040 (Pico).
299+
%% This is required on RP2040 and for some pins on ESP32.
300300
%% @end
301301
%%-----------------------------------------------------------------------------
302302
-spec init(Pin :: pin()) -> ok.

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

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -644,10 +644,43 @@ REGISTER_PORT_DRIVER(gpio, gpio_driver_init, NULL, gpio_driver_create_port)
644644

645645
#ifdef CONFIG_AVM_ENABLE_GPIO_NIFS
646646

647+
static term nif_gpio_init(Context *ctx, int argc, term argv[])
648+
{
649+
UNUSED(argc);
650+
651+
gpio_num_t gpio_num;
652+
if (LIKELY(term_is_integer(argv[0]))) {
653+
avm_int_t pin_int = term_to_int32(argv[0]);
654+
if (UNLIKELY((pin_int < 0) || (pin_int >= GPIO_NUM_MAX))) {
655+
RAISE_ERROR(BADARG_ATOM);
656+
}
657+
gpio_num = (gpio_num_t) pin_int;
658+
} else {
659+
RAISE_ERROR(BADARG_ATOM);
660+
}
661+
662+
gpio_config_t config = {};
663+
config.pin_bit_mask = 1 << gpio_num;
664+
config.mode = GPIO_MODE_DISABLE;
665+
config.pull_up_en = GPIO_PULLUP_DISABLE;
666+
config.pull_down_en = GPIO_PULLDOWN_DISABLE;
667+
config.intr_type = GPIO_INTR_DISABLE;
668+
669+
esp_err_t result = gpio_config(&config);
670+
671+
if (UNLIKELY(result != ESP_OK)) {
672+
RAISE_ERROR(BADARG_ATOM);
673+
}
674+
675+
return OK_ATOM;
676+
}
677+
647678
/* TODO: in the case of {error, Return} we should RAISE_ERROR(Reason) */
648679

649680
static term nif_gpio_set_pin_mode(Context *ctx, int argc, term argv[])
650681
{
682+
UNUSED(argc);
683+
651684
return gpio_set_pin_mode(ctx, argv[0], argv[1]);
652685
}
653686

@@ -706,6 +739,12 @@ static term nif_gpio_digital_read(Context *ctx, int argc, term argv[])
706739
return gpio_digital_read(argv[0]);
707740
}
708741

742+
static const struct Nif gpio_init_nif =
743+
{
744+
.base.type = NIFFunctionType,
745+
.nif_ptr = nif_gpio_init
746+
};
747+
709748
static const struct Nif gpio_set_pin_mode_nif =
710749
{
711750
.base.type = NIFFunctionType,
@@ -757,6 +796,15 @@ static const struct Nif gpio_digital_read_nif = {
757796

758797
const struct Nif *gpio_nif_get_nif(const char *nifname)
759798
{
799+
if (strcmp("gpio:init/1", nifname) == 0) {
800+
TRACE("Resolved platform nif %s ...\n", nifname);
801+
return &gpio_init_nif;
802+
}
803+
if (strcmp("Elixir.GPIO:init/1", nifname) == 0) {
804+
TRACE("Resolved platform nif %s ...\n", nifname);
805+
return &gpio_init_nif;
806+
}
807+
760808
if (strcmp("gpio:set_pin_mode/2", nifname) == 0) {
761809
TRACE("Resolved platform nif %s ...\n", nifname);
762810
return &gpio_set_pin_mode_nif;

0 commit comments

Comments
 (0)