/* GPIO 的 ESP-IDF 实现。 */ #include #include "driver/gpio.h" #include "hal_gpio.h" #define PIN_MAX 49 /* ESP32-S3 的 GPIO 编号是 0~48(**含 48**),与 sim 保持一致 */ /* 记住方向,好让「写一个输入脚」在板子上也返回 HAL_ERR_ARG —— ESP-IDF 的 gpio_set_level() 对输入脚是静默无效的,那正是最难查的一类 bug。 */ static uint8_t s_mode[PIN_MAX]; /* 0 = 没配过;否则 mode+1 */ hal_err_t hal_gpio_config(int pin, hal_gpio_mode_t mode) { if (pin < 0 || pin >= PIN_MAX) { return HAL_ERR_ARG; } gpio_config_t cfg = { .pin_bit_mask = 1ULL << pin, /* 输出也开输入缓冲:`hal_gpio_read()` 读到的是**引脚上的真电平**,不是寄存器。 「重启不断电」靠它核对锁住的 EN 脚是不是真的还是高(warm_esp.c)。 */ .mode = (mode == HAL_GPIO_OUTPUT) ? GPIO_MODE_INPUT_OUTPUT : GPIO_MODE_INPUT, .pull_up_en = (mode == HAL_GPIO_INPUT_PULLUP) ? GPIO_PULLUP_ENABLE : GPIO_PULLUP_DISABLE, .pull_down_en = GPIO_PULLDOWN_DISABLE, .intr_type = GPIO_INTR_DISABLE, }; if (gpio_config(&cfg) != ESP_OK) { return HAL_ERR_ARG; } s_mode[pin] = (uint8_t)(mode + 1); return HAL_OK; } hal_err_t hal_gpio_write(int pin, int level) { if (pin < 0 || pin >= PIN_MAX || s_mode[pin] != (uint8_t)(HAL_GPIO_OUTPUT + 1)) { return HAL_ERR_ARG; } return gpio_set_level(pin, level ? 1 : 0) == ESP_OK ? HAL_OK : HAL_ERR_ARG; } hal_err_t hal_gpio_read(int pin, int *level) { if (pin < 0 || pin >= PIN_MAX || s_mode[pin] == 0 || level == NULL) { return HAL_ERR_ARG; } *level = gpio_get_level(pin); return HAL_OK; } hal_err_t hal_gpio_hold(int pin, bool on) { if (pin < 0 || pin >= PIN_MAX) { return HAL_ERR_ARG; } return ((on ? gpio_hold_en(pin) : gpio_hold_dis(pin)) == ESP_OK) ? HAL_OK : HAL_ERR_ARG; }