From 8b92aa8e5a54f443111cef2e99ecf959c7e081c8 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Wed, 22 Jul 2026 22:43:34 +0200 Subject: [PATCH] GPIO descriptor fixes (#578) --- .../elecrow,crowpanel-advance-50.dts | 4 +- .../elecrow,crowpanel-basic-50.dts | 4 +- Devices/m5stack-cores3/m5stack,cores3.dts | 1 - .../source/drivers/papers3_power.cpp | 26 +++-------- .../m5stack-stackchan/m5stack,stackchan.dts | 6 +-- .../Source/devices/devices_v1.cpp | 7 +-- .../Source/devices/devices_v2.cpp | 3 -- .../Source/devices/display_detect.cpp | 12 ++--- .../Source/devices/tab5_headphone_detect.cpp | 5 +- .../Source/devices/tab5_power_control.cpp | 20 +++----- Devices/m5stack-tab5/Source/module.cpp | 10 ++-- Devices/unphone/source/BatteryManager.cpp | 4 +- .../source/drivers/unphone_nav_buttons.cpp | 14 +++--- .../source/drivers/unphone_power_switch.cpp | 8 +--- .../waveshare,s3-touch-lcd-43.dts | 5 +- Documentation/ideas.md | 2 + .../source/audio_codec_gpio_if.c | 23 ++++++---- Drivers/aw88298-module/source/aw88298.cpp | 7 ++- Drivers/aw9523b-module/source/aw9523b.cpp | 9 +++- .../axs5106-module/bindings/axs,axs5106.yaml | 8 ---- .../axs5106-module/include/drivers/axs5106.h | 2 - Drivers/axs5106-module/source/axs5106.cpp | 19 +++----- .../source/button_control.cpp | 10 ++-- .../bindings/hynitron,cst328.yaml | 4 -- .../cst328-module/include/drivers/cst328.h | 1 - Drivers/cst328-module/source/cst328.cpp | 9 ++-- .../bindings/hynitron,cst66xx.yaml | 4 -- .../cst66xx-module/include/drivers/cst66xx.h | 1 - Drivers/cst66xx-module/source/cst66xx.cpp | 14 ++++-- .../bindings/hynitron,cst816s.yaml | 8 ---- .../cst816s-module/include/drivers/cst816s.h | 2 - Drivers/cst816s-module/source/cst816s.cpp | 5 +- .../bindings/hynitron,cst816t.yaml | 8 ---- .../cst816t-module/include/drivers/cst816t.h | 2 - Drivers/cst816t-module/source/cst816t.cpp | 18 ++++---- .../bindings/focaltech,ft5x06.yaml | 8 ---- .../ft5x06-module/include/drivers/ft5x06.h | 2 - Drivers/ft5x06-module/source/ft5x06.cpp | 28 ++++------- .../bindings/focaltech,ft6x36.yaml | 8 ---- .../ft6x36-module/include/drivers/ft6x36.h | 2 - Drivers/ft6x36-module/source/ft6x36.cpp | 32 +++++-------- .../bindings/galaxycore,gc9a01.yaml | 4 -- .../gc9a01-module/include/drivers/gc9a01.h | 1 - Drivers/gc9a01-module/source/gc9a01.cpp | 3 +- .../gt911-module/bindings/goodix,gt911.yaml | 8 ---- Drivers/gt911-module/include/drivers/gt911.h | 2 - Drivers/gt911-module/source/gt911.cpp | 5 +- .../hx8357-module/bindings/himax,hx8357.yaml | 4 -- .../hx8357-module/include/drivers/hx8357.h | 1 - Drivers/hx8357-module/source/hx8357.cpp | 5 +- Drivers/ili9341-module/source/ili9341.cpp | 19 +++----- .../bindings/ilitek,ili9488.yaml | 4 -- .../ili9488-module/include/drivers/ili9488.h | 1 - Drivers/ili9488-module/source/ili9488.cpp | 3 +- .../bindings/ilitek,ili9881c.yaml | 4 -- .../include/drivers/ili9881c.h | 1 - Drivers/ili9881c-module/source/ili9881c.cpp | 3 +- .../jd9165-module/bindings/jdi,jd9165.yaml | 4 -- .../jd9165-module/include/drivers/jd9165.h | 1 - Drivers/jd9165-module/source/jd9165.cpp | 3 +- .../jd9853-module/bindings/jadard,jd9853.yaml | 4 -- .../jd9853-module/include/drivers/jd9853.h | 1 - Drivers/jd9853-module/source/jd9853.cpp | 3 +- .../lilygo-module/source/tdeck_trackball.cpp | 13 ++---- .../lilygo-module/source/tpager_encoder.cpp | 21 ++------- .../source/cardputer_keyboard.cpp | 13 +++--- .../source/pi4ioe5v6408.cpp | 10 +++- .../rgb-display-module/source/rgb_display.cpp | 9 ++-- .../bindings/solomon,ssd1306.yaml | 4 -- .../ssd1306-module/include/drivers/ssd1306.h | 1 - Drivers/ssd1306-module/source/ssd1306.cpp | 5 +- .../bindings/sitronix,st7123-touch.yaml | 8 ---- .../bindings/sitronix,st7123.yaml | 4 -- .../st7123-module/include/drivers/st7123.h | 1 - .../include/drivers/st7123_touch.h | 2 - Drivers/st7123-module/source/st7123.cpp | 3 +- Drivers/st7123-module/source/st7123_touch.cpp | 5 +- .../bindings/sitronix,st7701.yaml | 4 -- .../st7701-module/include/drivers/st7701.h | 1 - Drivers/st7701-module/source/st7701.cpp | 3 +- .../bindings/sitronix,st7735.yaml | 4 -- .../st7735-module/include/drivers/st7735.h | 1 - Drivers/st7735-module/source/st7735.cpp | 3 +- .../bindings/sitronix,st7789-i8080.yaml | 4 -- .../include/drivers/st7789_i8080.h | 1 - .../source/st7789_i8080.cpp | 3 +- .../bindings/sitronix,st7789.yaml | 4 -- .../st7789-module/include/drivers/st7789.h | 1 - Drivers/st7789-module/source/st7789.cpp | 3 +- .../bindings/sitronix,st7796-i8080.yaml | 4 -- .../include/drivers/st7796_i8080.h | 1 - .../source/st7796_i8080.cpp | 3 +- .../bindings/sitronix,st7796.yaml | 4 -- .../st7796-module/include/drivers/st7796.h | 1 - Drivers/st7796-module/source/st7796.cpp | 3 +- .../tca8418-module/bindings/ti,tca8418.yaml | 4 -- .../tca8418-module/include/drivers/tca8418.h | 1 - Drivers/tca8418-module/source/tca8418.cpp | 13 ++++-- .../source/xpt2046_softspi.cpp | 25 ++++------ .../tactility/drivers/esp32_gpio_helpers.h | 2 +- .../source/drivers/esp32_gpio.cpp | 16 +++++-- .../source/drivers/esp32_gpio_helpers.cpp | 7 +-- .../source/drivers/esp32_i2c.cpp | 6 +-- .../source/drivers/esp32_i2c_master.cpp | 6 +-- .../source/drivers/esp32_i2s.cpp | 10 ++-- .../source/drivers/esp32_i8080.cpp | 30 ++++++------ .../source/drivers/esp32_sdmmc.cpp | 26 +++++------ .../source/drivers/esp32_sdspi.cpp | 6 +-- .../source/drivers/esp32_spi.cpp | 20 ++++---- .../source/drivers/esp32_uart.cpp | 8 ++-- .../tactility/drivers/gpio_controller.h | 21 +++++++-- .../tactility/drivers/gpio_descriptor.h | 2 + .../source/drivers/gpio_backlight.cpp | 8 +--- .../source/drivers/gpio_controller.cpp | 46 +++++++++++++++++-- TactilityKernel/source/drivers/gpio_hog.cpp | 41 ++++++++--------- .../source/drivers/rgb_led_gpio.cpp | 23 +++------- 116 files changed, 376 insertions(+), 541 deletions(-) diff --git a/Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts b/Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts index 4cffd604..734640d0 100644 --- a/Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts +++ b/Devices/elecrow-crowpanel-advance-50/elecrow,crowpanel-advance-50.dts @@ -86,9 +86,7 @@ vsync-back-porch = <8>; vsync-front-porch = <8>; pclk-active-neg; - num-fbs = <2>; - double-fb; - bounce-buffer-size-px = <8000>; + bounce-buffer-size-px = <4000>; pin-hsync = <&gpio0 40 GPIO_FLAG_NONE>; pin-vsync = <&gpio0 41 GPIO_FLAG_NONE>; pin-de = <&gpio0 42 GPIO_FLAG_NONE>; diff --git a/Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts b/Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts index 1bf9d0bf..c9726bb1 100644 --- a/Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts +++ b/Devices/elecrow-crowpanel-basic-50/elecrow,crowpanel-basic-50.dts @@ -89,9 +89,7 @@ vsync-back-porch = <12>; vsync-front-porch = <8>; pclk-active-neg; - num-fbs = <2>; - double-fb; - bounce-buffer-size-px = <8000>; + bounce-buffer-size-px = <4000>; pin-hsync = <&gpio0 39 GPIO_FLAG_NONE>; pin-vsync = <&gpio0 41 GPIO_FLAG_NONE>; pin-de = <&gpio0 40 GPIO_FLAG_NONE>; diff --git a/Devices/m5stack-cores3/m5stack,cores3.dts b/Devices/m5stack-cores3/m5stack,cores3.dts index 6177b771..bd0ecd00 100644 --- a/Devices/m5stack-cores3/m5stack,cores3.dts +++ b/Devices/m5stack-cores3/m5stack,cores3.dts @@ -205,5 +205,4 @@ backlight = <&display_backlight>; }; }; - }; diff --git a/Devices/m5stack-papers3/source/drivers/papers3_power.cpp b/Devices/m5stack-papers3/source/drivers/papers3_power.cpp index 8722795f..83faf20d 100644 --- a/Devices/m5stack-papers3/source/drivers/papers3_power.cpp +++ b/Devices/m5stack-papers3/source/drivers/papers3_power.cpp @@ -1,8 +1,10 @@ // SPDX-License-Identifier: Apache-2.0 #include "papers3_power.h" + #include #include +#include #include #include #include @@ -13,7 +15,7 @@ #include -#define TAG "Papers3Power" +constexpr auto* TAG = "Papers3Power"; #define GET_CONFIG(device) (static_cast((device)->config)) // Power-off signal timing, ported from the old deprecated-HAL PaperS3Power::powerOff(). @@ -192,17 +194,8 @@ static void destroy_power_supply_child(Device* child) { // region Driver lifecycle static error_t acquire_input(const GpioPinSpec& pin, GpioDescriptor** out_descriptor) { - auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, GPIO_OWNER_GPIO); - if (descriptor == nullptr) { - return ERROR_RESOURCE; - } - error_t error = gpio_descriptor_set_flags(descriptor, pin.flags | GPIO_FLAG_DIRECTION_INPUT); - if (error != ERROR_NONE) { - gpio_descriptor_release(descriptor); - return error; - } - *out_descriptor = descriptor; - return ERROR_NONE; + *out_descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, pin.flags | GPIO_FLAG_DIRECTION_INPUT, GPIO_OWNER_GPIO); + return (*out_descriptor != nullptr) ? ERROR_NONE : ERROR_RESOURCE; } static error_t start(Device* device) { @@ -226,13 +219,8 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } - internal->power_off_descriptor = gpio_descriptor_acquire(config->pin_power_off.gpio_controller, config->pin_power_off.pin, GPIO_OWNER_GPIO); - if (internal->power_off_descriptor == nullptr || - gpio_descriptor_set_flags(internal->power_off_descriptor, config->pin_power_off.flags | GPIO_FLAG_DIRECTION_OUTPUT) != ERROR_NONE) { - LOG_E(TAG, "Failed to configure power-off pin"); - if (internal->power_off_descriptor != nullptr) { - gpio_descriptor_release(internal->power_off_descriptor); - } + internal->power_off_descriptor = gpio_descriptor_acquire(config->pin_power_off.gpio_controller, config->pin_power_off.pin, config->pin_power_off.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); + if (internal->power_off_descriptor == nullptr) { gpio_descriptor_release(internal->usb_detect_descriptor); gpio_descriptor_release(internal->charge_status_descriptor); delete internal; diff --git a/Devices/m5stack-stackchan/m5stack,stackchan.dts b/Devices/m5stack-stackchan/m5stack,stackchan.dts index b04d7528..9772e8b2 100644 --- a/Devices/m5stack-stackchan/m5stack,stackchan.dts +++ b/Devices/m5stack-stackchan/m5stack,stackchan.dts @@ -7,8 +7,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -20,8 +22,6 @@ #include #include #include -#include -#include // Reference: https://docs.m5stack.com/en/StackChan / { @@ -101,7 +101,7 @@ aw9523_sdcard_switch { compatible = "gpio-hog"; pin = <&aw9523b 4 GPIO_FLAG_NONE>; - mode = ; + mode = ; }; aw9523_boost_enable { diff --git a/Devices/m5stack-tab5/Source/devices/devices_v1.cpp b/Devices/m5stack-tab5/Source/devices/devices_v1.cpp index 07df7c80..68a773db 100644 --- a/Devices/m5stack-tab5/Source/devices/devices_v1.cpp +++ b/Devices/m5stack-tab5/Source/devices/devices_v1.cpp @@ -36,14 +36,14 @@ static void apply_gt911_int_workaround() { LOG_W(TAG, "display_detect: gpio0 not found, GT911 INT workaround not applied"); return; } - auto* int_pin = gpio_descriptor_acquire(gpio0, 23, GPIO_OWNER_GPIO); + auto* int_pin = gpio_descriptor_acquire(gpio0, 23, GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); device_put(gpio0); if (int_pin == nullptr) { LOG_W(TAG, "display_detect: failed to acquire GPIO23 for GT911 INT workaround"); return; } gpio_descriptor_set_flags(int_pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_PULL_UP); - gpio_descriptor_set_level(int_pin, false); + gpio_descriptor_set_level(int_pin, true); gpio_descriptor_release(int_pin); } @@ -67,8 +67,6 @@ static void create_gt911_touch(Device* i2c0) { // Reset is pulsed via io_expander0 (detect.cpp's pulse_display_reset_pins), not a direct SoC GPIO. .pin_reset = GPIO_PIN_SPEC_NONE, .pin_interrupt = GPIO_PIN_SPEC_NONE, - .reset_active_high = false, - .interrupt_active_high = false, }; gt911_device.config = >911_config; @@ -103,7 +101,6 @@ void tab5_create_devices_v1(Device* i2c0) { // LCD reset is pulsed via io_expander0 (detect.cpp's pulse_display_reset_pins), not a // direct SoC GPIO. .pin_reset = GPIO_PIN_SPEC_NONE, - .reset_active_high = false, .ldo_channel = 3, .ldo_voltage_mv = 2500, .dsi_bus_id = 0, diff --git a/Devices/m5stack-tab5/Source/devices/devices_v2.cpp b/Devices/m5stack-tab5/Source/devices/devices_v2.cpp index 980bc81a..4621d969 100644 --- a/Devices/m5stack-tab5/Source/devices/devices_v2.cpp +++ b/Devices/m5stack-tab5/Source/devices/devices_v2.cpp @@ -50,8 +50,6 @@ static void create_st7123_touch(Device* i2c0) { // Reset is pulsed via io_expander0 (detect.cpp's pulse_display_reset_pins), not a direct SoC GPIO. .pin_reset = GPIO_PIN_SPEC_NONE, .pin_interrupt = pin_interrupt, - .reset_active_high = false, - .interrupt_active_high = false, }; st7123_touch_device.config = &st7123_touch_config; @@ -82,7 +80,6 @@ void tab5_create_devices_v2(Device* i2c0) { .mirror_x = false, .mirror_y = false, .pin_reset = GPIO_PIN_SPEC_NONE, - .reset_active_high = false, .ldo_channel = 3, .ldo_voltage_mv = 2500, .dsi_bus_id = 0, diff --git a/Devices/m5stack-tab5/Source/devices/display_detect.cpp b/Devices/m5stack-tab5/Source/devices/display_detect.cpp index 644f0442..5c7fb500 100644 --- a/Devices/m5stack-tab5/Source/devices/display_detect.cpp +++ b/Devices/m5stack-tab5/Source/devices/display_detect.cpp @@ -1,6 +1,5 @@ #include "detect.h" -#include "../../../../TactilityKernel/include/tactility/log.h" #include "devices_common.h" #include "devices_v1.h" #include "devices_v2.h" @@ -8,6 +7,7 @@ #include #include +#include #include #include @@ -36,8 +36,8 @@ constexpr auto GPIO_EXP0_PIN_LCD_RESET = 4; constexpr auto GPIO_EXP0_PIN_TOUCH_RESET = 5; bool pulse_display_reset_pins(Device* io_expander0) { - auto* lcd_reset_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_LCD_RESET, GPIO_OWNER_GPIO); - auto* touch_reset_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_TOUCH_RESET, GPIO_OWNER_GPIO); + auto* lcd_reset_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_LCD_RESET, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); + auto* touch_reset_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_TOUCH_RESET, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (lcd_reset_pin == nullptr || touch_reset_pin == nullptr) { LOG_E(TAG, "display_detect: failed to acquire LCD/touch reset pins on io_expander0"); if (lcd_reset_pin != nullptr) { @@ -51,11 +51,11 @@ bool pulse_display_reset_pins(Device* io_expander0) { gpio_descriptor_set_flags(lcd_reset_pin, GPIO_FLAG_DIRECTION_OUTPUT); gpio_descriptor_set_flags(touch_reset_pin, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_level(lcd_reset_pin, false); - gpio_descriptor_set_level(touch_reset_pin, false); - vTaskDelay(pdMS_TO_TICKS(10)); gpio_descriptor_set_level(lcd_reset_pin, true); gpio_descriptor_set_level(touch_reset_pin, true); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_descriptor_set_level(lcd_reset_pin, false); + gpio_descriptor_set_level(touch_reset_pin, false); gpio_descriptor_release(lcd_reset_pin); gpio_descriptor_release(touch_reset_pin); diff --git a/Devices/m5stack-tab5/Source/devices/tab5_headphone_detect.cpp b/Devices/m5stack-tab5/Source/devices/tab5_headphone_detect.cpp index 99a82550..a9355d4d 100644 --- a/Devices/m5stack-tab5/Source/devices/tab5_headphone_detect.cpp +++ b/Devices/m5stack-tab5/Source/devices/tab5_headphone_detect.cpp @@ -1,6 +1,7 @@ #include "tab5_headphone_detect.h" #include +#include #include #include @@ -35,7 +36,7 @@ static void headphone_detect_callback(TimerHandle_t /*timer*/) { return; // Not ready yet, will retry on next tick } - auto* hp_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_HEADPHONE_DETECT, GPIO_OWNER_GPIO); + auto* hp_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_HEADPHONE_DETECT, GPIO_FLAG_DIRECTION_INPUT, GPIO_OWNER_GPIO); if (!hp_pin) { LOG_W(TAG, "hp_detect: HP_DET pin busy"); return; @@ -53,7 +54,7 @@ static void headphone_detect_callback(TimerHandle_t /*timer*/) { LOG_D(TAG, "hp_detect: HP_DET=%d", (int)hp); if (!hp_detect_initialized || hp != hp_detect_last) { - auto* spk_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_OWNER_GPIO); + auto* spk_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (!spk_pin) { LOG_W(TAG, "hp_detect: SPK_EN pin busy, will retry"); return; diff --git a/Devices/m5stack-tab5/Source/devices/tab5_power_control.cpp b/Devices/m5stack-tab5/Source/devices/tab5_power_control.cpp index 306e598c..8788b7bb 100644 --- a/Devices/m5stack-tab5/Source/devices/tab5_power_control.cpp +++ b/Devices/m5stack-tab5/Source/devices/tab5_power_control.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -51,15 +52,12 @@ static error_t ps_set_allowed_to_charge(Device* device, bool allowed) { auto* internal = static_cast(device_get_driver_data(device)); auto* io_expander1 = device_get_parent(device); - auto* pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_IP2326_CHG_EN, GPIO_OWNER_GPIO); + auto* pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_IP2326_CHG_EN, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (pin == nullptr) { LOG_W(TAG, "Failed to acquire CHG_EN pin"); return ERROR_RESOURCE; } - error_t error = gpio_descriptor_set_flags(pin, GPIO_FLAG_DIRECTION_OUTPUT); - if (error == ERROR_NONE) { - error = gpio_descriptor_set_level(pin, allowed); - } + auto error = gpio_descriptor_set_level(pin, allowed); gpio_descriptor_release(pin); if (error != ERROR_NONE) { LOG_W(TAG, "Failed to set CHG_EN pin"); @@ -83,15 +81,12 @@ static error_t ps_set_quick_charge_enabled(Device* device, bool enabled) { auto* internal = static_cast(device_get_driver_data(device)); auto* io_expander1 = device_get_parent(device); - auto* pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_IP2326_NCHG_QC_EN, GPIO_OWNER_GPIO); + auto* pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_IP2326_NCHG_QC_EN, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (pin == nullptr) { LOG_W(TAG, "Failed to acquire nCHG_QC_EN pin"); return ERROR_RESOURCE; } - error_t error = gpio_descriptor_set_flags(pin, GPIO_FLAG_DIRECTION_OUTPUT); - if (error == ERROR_NONE) { - error = gpio_descriptor_set_level(pin, !enabled); // active-low - } + auto error = gpio_descriptor_set_level(pin, !enabled); // active-low gpio_descriptor_release(pin); if (error != ERROR_NONE) { LOG_W(TAG, "Failed to set nCHG_QC_EN pin"); @@ -108,7 +103,7 @@ static bool ps_supports_power_off(Device*) { static error_t ps_power_off(Device* device) { auto* io_expander1 = device_get_parent(device); - auto* pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_DEVICE_POWER, GPIO_OWNER_GPIO); + auto* pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_DEVICE_POWER, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (pin == nullptr) { LOG_E(TAG, "Failed to acquire DEVICE_POWER pin"); return ERROR_RESOURCE; @@ -153,9 +148,8 @@ static error_t start(Device* device) { // as an idle-low output up front so it's in a known state (previously done by Configuration.cpp's // initExpander1(), now owned here - see that function's comment for why it no longer touches it). auto* io_expander1 = device_get_parent(device); - auto* device_power_pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_DEVICE_POWER, GPIO_OWNER_GPIO); + auto* device_power_pin = gpio_descriptor_acquire(io_expander1, GPIO_EXP1_PIN_DEVICE_POWER, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (device_power_pin != nullptr) { - gpio_descriptor_set_flags(device_power_pin, GPIO_FLAG_DIRECTION_OUTPUT); gpio_descriptor_set_level(device_power_pin, false); gpio_descriptor_release(device_power_pin); } else { diff --git a/Devices/m5stack-tab5/Source/module.cpp b/Devices/m5stack-tab5/Source/module.cpp index db2c7948..5c498d0e 100644 --- a/Devices/m5stack-tab5/Source/module.cpp +++ b/Devices/m5stack-tab5/Source/module.cpp @@ -1,4 +1,5 @@ #include + #include #include #include @@ -25,14 +26,11 @@ constexpr auto GPIO_EXP0_PIN_HEADPHONE_DETECT = 7; static void tab5_init_expander0(Device* io_expander0) { // Speaker and heapdhone pins are managed at runtime, so we can't have them as a hog in the dts file // We have to init them manually. - auto* speaker_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_OWNER_GPIO); + auto* speaker_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); check(speaker_enable_pin); - auto* headphone_detect_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_HEADPHONE_DETECT, GPIO_OWNER_GPIO); + auto* headphone_detect_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_HEADPHONE_DETECT, GPIO_FLAG_DIRECTION_INPUT, GPIO_OWNER_GPIO); check(headphone_detect_pin); - gpio_descriptor_set_flags(speaker_enable_pin, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_flags(headphone_detect_pin, GPIO_FLAG_DIRECTION_INPUT); - gpio_descriptor_set_level(speaker_enable_pin, false); gpio_descriptor_release(speaker_enable_pin); @@ -40,7 +38,7 @@ static void tab5_init_expander0(Device* io_expander0) { } static void tab5_enable_speaker_amp(Device* io_expander0) { - auto* speaker_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_OWNER_GPIO); + auto* speaker_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); check(speaker_enable_pin, "Failed to acquire speaker enable pin"); error_t error = gpio_descriptor_set_level(speaker_enable_pin, true); gpio_descriptor_release(speaker_enable_pin); diff --git a/Devices/unphone/source/BatteryManager.cpp b/Devices/unphone/source/BatteryManager.cpp index 9804afc3..b7e40700 100644 --- a/Devices/unphone/source/BatteryManager.cpp +++ b/Devices/unphone/source/BatteryManager.cpp @@ -21,10 +21,8 @@ bool BatteryManager::initGpioExpander() { return false; } - expanderPowerPin = gpio_descriptor_acquire(expander, expanderpin::EXPANDER_POWER, GPIO_OWNER_GPIO); + expanderPowerPin = gpio_descriptor_acquire(expander, expanderpin::EXPANDER_POWER, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); check(expanderPowerPin != nullptr); - gpio_descriptor_set_flags(expanderPowerPin, GPIO_FLAG_DIRECTION_OUTPUT); - device_put(expander); return true; diff --git a/Devices/unphone/source/drivers/unphone_nav_buttons.cpp b/Devices/unphone/source/drivers/unphone_nav_buttons.cpp index 3b28f212..7e3eefea 100644 --- a/Devices/unphone/source/drivers/unphone_nav_buttons.cpp +++ b/Devices/unphone/source/drivers/unphone_nav_buttons.cpp @@ -90,21 +90,19 @@ static int32_t nav_buttons_thread_main(UnphoneNavButtonsInternal* internal) { // region Pin acquisition static error_t acquire_button(const GpioPinSpec& pin, void (*callback)(void*), void* arg, GpioDescriptor** out_descriptor) { - auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, GPIO_OWNER_GPIO); - if (descriptor == nullptr) { - return ERROR_RESOURCE; - } - // Digital pull-up; the buttons pull the pin low while pressed. Listen for the release // (positive edge) rather than the press - if we listen to the press, these buttons can // generate more than one signal when held down (mirrors the original unPhone init). gpio_flags_t flags = GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP; flags = GPIO_FLAG_INTERRUPT_TO_OPTIONS(flags, GPIO_INTERRUPT_POS_EDGE); - error_t error = gpio_descriptor_set_flags(descriptor, flags); - if (error == ERROR_NONE) { - error = gpio_descriptor_add_callback(descriptor, callback, arg); + auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, flags, GPIO_OWNER_GPIO); + if (descriptor == nullptr) { + return ERROR_RESOURCE; } + + auto error = gpio_descriptor_add_callback(descriptor, callback, arg); + if (error == ERROR_NONE) { error = gpio_descriptor_enable_interrupt(descriptor); } diff --git a/Devices/unphone/source/drivers/unphone_power_switch.cpp b/Devices/unphone/source/drivers/unphone_power_switch.cpp index e676fbc8..e6108aa6 100644 --- a/Devices/unphone/source/drivers/unphone_power_switch.cpp +++ b/Devices/unphone/source/drivers/unphone_power_switch.cpp @@ -25,18 +25,12 @@ extern Module unphone_module; static error_t start(Device* device) { const auto* config = GET_CONFIG(device); - auto* descriptor = gpio_descriptor_acquire(config->pin.gpio_controller, config->pin.pin, GPIO_OWNER_GPIO); + auto* descriptor = gpio_descriptor_acquire(config->pin.gpio_controller, config->pin.pin, config->pin.flags | GPIO_FLAG_DIRECTION_INPUT, GPIO_OWNER_GPIO); if (descriptor == nullptr) { LOG_E(TAG, "Failed to acquire GPIO descriptor"); return ERROR_RESOURCE; } - if (gpio_descriptor_set_flags(descriptor, config->pin.flags | GPIO_FLAG_DIRECTION_INPUT) != ERROR_NONE) { - LOG_E(TAG, "Failed to configure power switch pin as input"); - gpio_descriptor_release(descriptor); - return ERROR_RESOURCE; - } - gpio_num_t native_pin; if (gpio_descriptor_get_native_pin_number(descriptor, &native_pin) != ERROR_NONE) { LOG_E(TAG, "Power switch pin has no native pin number"); diff --git a/Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts b/Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts index 48d10e0e..406b6364 100644 --- a/Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts +++ b/Devices/waveshare-s3-touch-lcd-43/waveshare,s3-touch-lcd-43.dts @@ -96,9 +96,8 @@ vsync-back-porch = <8>; vsync-front-porch = <8>; pclk-active-neg; - num-fbs = <2>; - double-fb; - bounce-buffer-size-px = <8000>; + num-fbs = <1>; + bounce-buffer-size-px = <4000>; pin-hsync = <&gpio0 46 GPIO_FLAG_NONE>; pin-vsync = <&gpio0 3 GPIO_FLAG_NONE>; pin-de = <&gpio0 5 GPIO_FLAG_NONE>; diff --git a/Documentation/ideas.md b/Documentation/ideas.md index c31a001d..95bd34e2 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -13,6 +13,8 @@ ## Higher Priority +- LilyGO T-Dongle S3: 1 button control, stop auto-launching web server +- Core2: support power off via software - Create `#define` for empty module (for modules that fully rely on device.properties and don't define drivers or have start/stop logic) - Get rid of TactilityC in favour of TactilityKernel and kernel modules - Improve SPI kernel driver (implement read, write, transactions) diff --git a/Drivers/audio-codec-module/source/audio_codec_gpio_if.c b/Drivers/audio-codec-module/source/audio_codec_gpio_if.c index 6b9a0b43..05a7531b 100644 --- a/Drivers/audio-codec-module/source/audio_codec_gpio_if.c +++ b/Drivers/audio-codec-module/source/audio_codec_gpio_if.c @@ -17,7 +17,7 @@ struct GpioAdapterContext { static struct GpioAdapterContext* g_context = NULL; -static struct GpioDescriptor* acquire_descriptor(int16_t gpio) { +static struct GpioDescriptor* acquire_descriptor(int16_t gpio, gpio_flags_t flags) { if (g_context == NULL || gpio < 0 || (size_t) gpio >= g_context->pin_count) { return NULL; } @@ -31,24 +31,31 @@ static struct GpioDescriptor* acquire_descriptor(int16_t gpio) { return NULL; } - struct GpioDescriptor* descriptor = gpio_descriptor_acquire(spec->gpio_controller, spec->pin, GPIO_OWNER_GPIO); + struct GpioDescriptor* descriptor = gpio_descriptor_acquire( + spec->gpio_controller, spec->pin, spec->flags | flags, GPIO_OWNER_GPIO + ); if (descriptor != NULL) { - gpio_descriptor_set_flags(descriptor, spec->flags); g_context->descriptors[gpio] = descriptor; } return descriptor; } static int gpio_setup(int16_t gpio, audio_gpio_dir_t dir, audio_gpio_mode_t mode) { - struct GpioDescriptor* descriptor = acquire_descriptor(gpio); + gpio_flags_t flags = (dir == AUDIO_GPIO_DIR_OUT) ? GPIO_FLAG_DIRECTION_OUTPUT : GPIO_FLAG_DIRECTION_INPUT; + if ((mode & AUDIO_GPIO_MODE_PULL_UP) != 0) { + flags |= GPIO_FLAG_PULL_UP; + } + if ((mode & AUDIO_GPIO_MODE_PULL_DOWN) != 0) { + flags |= GPIO_FLAG_PULL_DOWN; + } + + struct GpioDescriptor* descriptor = acquire_descriptor(gpio, flags); if (descriptor == NULL) { return ESP_CODEC_DEV_NOT_FOUND; } - gpio_flags_t flags = GPIO_FLAG_NONE; gpio_descriptor_get_flags(descriptor, &flags); flags &= ~(GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_PULL_UP | GPIO_FLAG_PULL_DOWN); - flags |= (dir == AUDIO_GPIO_DIR_OUT) ? GPIO_FLAG_DIRECTION_OUTPUT : GPIO_FLAG_DIRECTION_INPUT; if ((mode & AUDIO_GPIO_MODE_PULL_UP) != 0) { flags |= GPIO_FLAG_PULL_UP; @@ -61,7 +68,7 @@ static int gpio_setup(int16_t gpio, audio_gpio_dir_t dir, audio_gpio_mode_t mode } static int gpio_set(int16_t gpio, bool high) { - struct GpioDescriptor* descriptor = acquire_descriptor(gpio); + struct GpioDescriptor* descriptor = acquire_descriptor(gpio, GPIO_FLAG_DIRECTION_OUTPUT); if (descriptor == NULL) { return ESP_CODEC_DEV_NOT_FOUND; } @@ -72,7 +79,7 @@ static int gpio_set(int16_t gpio, bool high) { // acquire and a legitimate low reading are indistinguishable to the caller; log so the // failure is at least visible. static bool gpio_get(int16_t gpio) { - struct GpioDescriptor* descriptor = acquire_descriptor(gpio); + struct GpioDescriptor* descriptor = acquire_descriptor(gpio, GPIO_FLAG_DIRECTION_INPUT); if (descriptor == NULL) { LOG_E(TAG, "gpio_get: failed to acquire descriptor for pin %d", gpio); return false; diff --git a/Drivers/aw88298-module/source/aw88298.cpp b/Drivers/aw88298-module/source/aw88298.cpp index c4ccf005..8175d5b2 100644 --- a/Drivers/aw88298-module/source/aw88298.cpp +++ b/Drivers/aw88298-module/source/aw88298.cpp @@ -253,15 +253,14 @@ error_t start_device(Device* device) { // (unlike a board Configuration.cpp initBoot() callback, which only runs after ALL // devicetree devices, including this one, have already started). if (config->reset_pin.gpio_controller != nullptr) { - auto* reset_descriptor = gpio_descriptor_acquire(config->reset_pin.gpio_controller, config->reset_pin.pin, GPIO_OWNER_GPIO); + auto* reset_descriptor = gpio_descriptor_acquire(config->reset_pin.gpio_controller, config->reset_pin.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (reset_descriptor == nullptr) { LOG_E(TAG, "Failed to acquire reset pin descriptor"); goto cleanup; } - gpio_descriptor_set_flags(reset_descriptor, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_level(reset_descriptor, false); - vTaskDelay(pdMS_TO_TICKS(10)); gpio_descriptor_set_level(reset_descriptor, true); + vTaskDelay(pdMS_TO_TICKS(10)); + gpio_descriptor_set_level(reset_descriptor, false); vTaskDelay(pdMS_TO_TICKS(50)); gpio_descriptor_release(reset_descriptor); } diff --git a/Drivers/aw9523b-module/source/aw9523b.cpp b/Drivers/aw9523b-module/source/aw9523b.cpp index a27a106d..b04ec927 100644 --- a/Drivers/aw9523b-module/source/aw9523b.cpp +++ b/Drivers/aw9523b-module/source/aw9523b.cpp @@ -69,7 +69,10 @@ static error_t set_level(GpioDescriptor* descriptor, bool high) { uint8_t bit = 1U << (descriptor->pin % 8U); uint8_t reg = portRegister(isPort1, AW9523B_REG_OUTPUT_P0, AW9523B_REG_OUTPUT_P1); - if (high) { + // This chip has no output polarity register: active-low must be inverted in software. + bool physical_high = (descriptor->flags & GPIO_FLAG_ACTIVE_LOW) != 0 ? !high : high; + + if (physical_high) { return i2c_controller_register8_set_bits(parent, address, reg, bit, portMAX_DELAY); } else { return i2c_controller_register8_reset_bits(parent, address, reg, bit, portMAX_DELAY); @@ -90,7 +93,8 @@ static error_t get_level(GpioDescriptor* descriptor, bool* high) { return err; } - *high = (bits & bit) != 0; + bool physical_high = (bits & bit) != 0; + *high = (descriptor->flags & GPIO_FLAG_ACTIVE_LOW) != 0 ? !physical_high : physical_high; return ERROR_NONE; } @@ -126,6 +130,7 @@ static error_t get_flags(GpioDescriptor* descriptor, gpio_flags_t* flags) { // Config register is inverted: 0 = output, 1 = input. *flags = (val & bit) ? GPIO_FLAG_DIRECTION_INPUT : GPIO_FLAG_DIRECTION_OUTPUT; + *flags |= (descriptor->flags & GPIO_FLAG_ACTIVE_LOW); return ERROR_NONE; } diff --git a/Drivers/axs5106-module/bindings/axs,axs5106.yaml b/Drivers/axs5106-module/bindings/axs,axs5106.yaml index 4fe9910e..1b3993ea 100644 --- a/Drivers/axs5106-module/bindings/axs,axs5106.yaml +++ b/Drivers/axs5106-module/bindings/axs,axs5106.yaml @@ -35,14 +35,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Interrupt GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high - interrupt-active-high: - type: boolean - default: false - description: Whether the interrupt pin is active high transmit-timeout: type: int default: 100 diff --git a/Drivers/axs5106-module/include/drivers/axs5106.h b/Drivers/axs5106-module/include/drivers/axs5106.h index ac2988fe..1b2141ee 100644 --- a/Drivers/axs5106-module/include/drivers/axs5106.h +++ b/Drivers/axs5106-module/include/drivers/axs5106.h @@ -19,8 +19,6 @@ struct Axs5106Config { bool mirror_y; struct GpioPinSpec pin_reset; struct GpioPinSpec pin_interrupt; - bool reset_active_high; - bool interrupt_active_high; // Timeout (ms) for the register-address write half of a read, and for the data-read half, // done as two separate I2C transactions - matches the vendor factory demo's // i2c_master_transmit()/i2c_master_receive() split (each with its own 100ms timeout), diff --git a/Drivers/axs5106-module/source/axs5106.cpp b/Drivers/axs5106-module/source/axs5106.cpp index ff368739..f01b03fa 100644 --- a/Drivers/axs5106-module/source/axs5106.cpp +++ b/Drivers/axs5106-module/source/axs5106.cpp @@ -1,12 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 #include + #include #include #include #include +#include #include -#include #include #include #include @@ -41,16 +42,10 @@ struct Axs5106Internal { // region Driver lifecycle -// Matches the vendor demo's touch_axs5106_reset(): pulse the reset pin active for 10ms, then -// release it for 10ms before any I2C traffic. No separate init step follows - the vendor demo's -// touch_axs5106_init() is a no-op too. -static error_t reset_pulse(GpioDescriptor* descriptor, bool active_high) { - bool idle_level = !active_high; - - bool ok = gpio_descriptor_set_flags(descriptor, GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE; - ok = ok && gpio_descriptor_set_level(descriptor, active_high) == ERROR_NONE; +static error_t reset_pulse(GpioDescriptor* descriptor) { + bool ok = gpio_descriptor_set_level(descriptor, true) == ERROR_NONE; vTaskDelay(pdMS_TO_TICKS(10)); - ok = ok && gpio_descriptor_set_level(descriptor, idle_level) == ERROR_NONE; + ok = ok && gpio_descriptor_set_level(descriptor, false) == ERROR_NONE; vTaskDelay(pdMS_TO_TICKS(10)); return ok ? ERROR_NONE : ERROR_RESOURCE; @@ -73,14 +68,14 @@ static error_t start(Device* device) { internal->point_count = 0; if (config->pin_reset.gpio_controller != nullptr) { - internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (internal->reset_descriptor == nullptr) { LOG_E(TAG, "Failed to acquire reset pin"); free(internal); return ERROR_RESOURCE; } - if (reset_pulse(internal->reset_descriptor, config->reset_active_high) != ERROR_NONE) { + if (reset_pulse(internal->reset_descriptor) != ERROR_NONE) { LOG_E(TAG, "Failed to pulse reset pin"); gpio_descriptor_release(internal->reset_descriptor); free(internal); diff --git a/Drivers/button-control-module/source/button_control.cpp b/Drivers/button-control-module/source/button_control.cpp index 97500746..9facf5e6 100644 --- a/Drivers/button-control-module/source/button_control.cpp +++ b/Drivers/button-control-module/source/button_control.cpp @@ -1,9 +1,11 @@ // SPDX-License-Identifier: Apache-2.0 #include + #include #include #include +#include #include #include #include @@ -72,18 +74,12 @@ static error_t acquire_button(const GpioPinSpec& pin, uint32_t short_press_key, return ERROR_NONE; } - auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, GPIO_OWNER_GPIO); + auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, pin.flags | GPIO_FLAG_DIRECTION_INPUT, GPIO_OWNER_GPIO); if (descriptor == nullptr) { LOG_E(TAG, "Failed to acquire GPIO descriptor"); return ERROR_RESOURCE; } - if (gpio_descriptor_set_flags(descriptor, pin.flags | GPIO_FLAG_DIRECTION_INPUT) != ERROR_NONE) { - LOG_E(TAG, "Failed to configure GPIO as input"); - gpio_descriptor_release(descriptor); - return ERROR_RESOURCE; - } - *out_state = { .descriptor = descriptor, .in_use = true, diff --git a/Drivers/cst328-module/bindings/hynitron,cst328.yaml b/Drivers/cst328-module/bindings/hynitron,cst328.yaml index 907d125d..116384bf 100644 --- a/Drivers/cst328-module/bindings/hynitron,cst328.yaml +++ b/Drivers/cst328-module/bindings/hynitron,cst328.yaml @@ -26,7 +26,3 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Optional reset GPIO pin. Falls back to a software reset command if not set. - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high diff --git a/Drivers/cst328-module/include/drivers/cst328.h b/Drivers/cst328-module/include/drivers/cst328.h index ec010170..ba2b58e2 100644 --- a/Drivers/cst328-module/include/drivers/cst328.h +++ b/Drivers/cst328-module/include/drivers/cst328.h @@ -17,7 +17,6 @@ struct Cst328Config { bool mirror_x; bool mirror_y; struct GpioPinSpec pin_reset; - bool reset_active_high; }; #ifdef __cplusplus diff --git a/Drivers/cst328-module/source/cst328.cpp b/Drivers/cst328-module/source/cst328.cpp index be93eb6c..9cd0563c 100644 --- a/Drivers/cst328-module/source/cst328.cpp +++ b/Drivers/cst328-module/source/cst328.cpp @@ -1,11 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 #include + #include #include #include #include #include +#include #include #include #include @@ -55,12 +57,11 @@ static bool query(Device* i2c, uint8_t address, uint8_t b0, uint8_t b1, uint8_t* // chip's own software reset command instead. static void perform_reset(Device* i2c, uint8_t address, const Cst328Config* config) { if (config->pin_reset.gpio_controller != nullptr) { - auto* rst = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + auto* rst = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (rst != nullptr) { - gpio_descriptor_set_flags(rst, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_level(rst, config->reset_active_high); + gpio_descriptor_set_level(rst, true); delay_millis(100); - gpio_descriptor_set_level(rst, !config->reset_active_high); + gpio_descriptor_set_level(rst, false); gpio_descriptor_release(rst); delay_millis(100); return; diff --git a/Drivers/cst66xx-module/bindings/hynitron,cst66xx.yaml b/Drivers/cst66xx-module/bindings/hynitron,cst66xx.yaml index e5963217..067bae07 100644 --- a/Drivers/cst66xx-module/bindings/hynitron,cst66xx.yaml +++ b/Drivers/cst66xx-module/bindings/hynitron,cst66xx.yaml @@ -35,7 +35,3 @@ properties: type: phandles required: true description: Reset GPIO pin. The chip only re-initializes into normal reporting mode after a clean reset pulse. - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high diff --git a/Drivers/cst66xx-module/include/drivers/cst66xx.h b/Drivers/cst66xx-module/include/drivers/cst66xx.h index 2f35b1bc..9bf9f064 100644 --- a/Drivers/cst66xx-module/include/drivers/cst66xx.h +++ b/Drivers/cst66xx-module/include/drivers/cst66xx.h @@ -19,7 +19,6 @@ struct Cst66xxConfig { bool mirror_x; bool mirror_y; struct GpioPinSpec pin_reset; - bool reset_active_high; }; #ifdef __cplusplus diff --git a/Drivers/cst66xx-module/source/cst66xx.cpp b/Drivers/cst66xx-module/source/cst66xx.cpp index 56ae7620..736be7d4 100644 --- a/Drivers/cst66xx-module/source/cst66xx.cpp +++ b/Drivers/cst66xx-module/source/cst66xx.cpp @@ -1,13 +1,14 @@ // SPDX-License-Identifier: Apache-2.0 #include + #include #include #include #include #include +#include #include -#include #include #include #include @@ -61,15 +62,18 @@ static void perform_hardware_reset(const Cst66xxConfig* config) { return; } - auto* rst = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + // Not requesting GPIO_FLAG_ACTIVE_LOW here: some GPIO expanders (e.g. xl9555/tca95xx/ + // tca9534) can only invert what's read back from an input, not what's driven on an + // output, so they reject ACTIVE_LOW combined with OUTPUT. Drive the raw physical level + // instead: this pin's reset line is active-low, so low asserts and high releases. + auto* rst = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (rst == nullptr) { return; } - gpio_descriptor_set_flags(rst, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_level(rst, config->reset_active_high); + gpio_descriptor_set_level(rst, false); delay_millis(10); - gpio_descriptor_set_level(rst, !config->reset_active_high); + gpio_descriptor_set_level(rst, true); gpio_descriptor_release(rst); // The reset pulse exits boot mode; give the controller time to re-init. delay_millis(80); diff --git a/Drivers/cst816s-module/bindings/hynitron,cst816s.yaml b/Drivers/cst816s-module/bindings/hynitron,cst816s.yaml index 948ee1d2..a4fd6916 100644 --- a/Drivers/cst816s-module/bindings/hynitron,cst816s.yaml +++ b/Drivers/cst816s-module/bindings/hynitron,cst816s.yaml @@ -35,11 +35,3 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Interrupt GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high - interrupt-active-high: - type: boolean - default: false - description: Whether the interrupt pin is active high diff --git a/Drivers/cst816s-module/include/drivers/cst816s.h b/Drivers/cst816s-module/include/drivers/cst816s.h index bf36dbfa..6c6c5639 100644 --- a/Drivers/cst816s-module/include/drivers/cst816s.h +++ b/Drivers/cst816s-module/include/drivers/cst816s.h @@ -22,8 +22,6 @@ struct Cst816sConfig { bool mirror_y; struct GpioPinSpec pin_reset; struct GpioPinSpec pin_interrupt; - bool reset_active_high; - bool interrupt_active_high; }; #ifdef __cplusplus diff --git a/Drivers/cst816s-module/source/cst816s.cpp b/Drivers/cst816s-module/source/cst816s.cpp index b1cb713b..04a44ff1 100644 --- a/Drivers/cst816s-module/source/cst816s.cpp +++ b/Drivers/cst816s-module/source/cst816s.cpp @@ -75,9 +75,10 @@ static error_t start(Device* device) { .y_max = config->y_max, .rst_gpio_num = pin_or_nc(config->pin_reset), .int_gpio_num = pin_or_nc(config->pin_interrupt), + // CST816S's reset and interrupt lines are both fixed active-low in hardware. .levels = { - .reset = config->reset_active_high ? 1u : 0u, - .interrupt = config->interrupt_active_high ? 1u : 0u, + .reset = 0u, + .interrupt = 0u, }, .flags = { .swap_xy = config->swap_xy ? 1u : 0u, diff --git a/Drivers/cst816t-module/bindings/hynitron,cst816t.yaml b/Drivers/cst816t-module/bindings/hynitron,cst816t.yaml index 21796823..696ddfdf 100644 --- a/Drivers/cst816t-module/bindings/hynitron,cst816t.yaml +++ b/Drivers/cst816t-module/bindings/hynitron,cst816t.yaml @@ -35,11 +35,3 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Interrupt GPIO pin (currently unused - reads are polled via read_data()) - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high - interrupt-active-high: - type: boolean - default: false - description: Whether the interrupt pin is active high diff --git a/Drivers/cst816t-module/include/drivers/cst816t.h b/Drivers/cst816t-module/include/drivers/cst816t.h index b85480bf..f59da473 100644 --- a/Drivers/cst816t-module/include/drivers/cst816t.h +++ b/Drivers/cst816t-module/include/drivers/cst816t.h @@ -19,8 +19,6 @@ struct Cst816tConfig { bool mirror_y; struct GpioPinSpec pin_reset; struct GpioPinSpec pin_interrupt; - bool reset_active_high; - bool interrupt_active_high; }; #ifdef __cplusplus diff --git a/Drivers/cst816t-module/source/cst816t.cpp b/Drivers/cst816t-module/source/cst816t.cpp index d9f29dda..c66ed825 100644 --- a/Drivers/cst816t-module/source/cst816t.cpp +++ b/Drivers/cst816t-module/source/cst816t.cpp @@ -1,12 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 #include + #include #include #include #include +#include #include -#include #include #include #include @@ -44,15 +45,12 @@ struct Cst816tInternal { // Timings match the reference driver linked above: it holds RST high for 100ms (well past the // datasheet's Tpor/Tron minimum of 100ms), pulses it low for 10ms (Trst minimum is 0.1ms), then // waits another 100ms (Tron) for the chip to finish reinitializing before any I2C traffic. -static error_t reset_pulse(GpioDescriptor* descriptor, bool active_high) { - bool idle_level = !active_high; - - bool ok = gpio_descriptor_set_flags(descriptor, GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE; - ok = ok && gpio_descriptor_set_level(descriptor, idle_level) == ERROR_NONE; +static error_t reset_pulse(GpioDescriptor* descriptor) { + bool ok = gpio_descriptor_set_level(descriptor, false) == ERROR_NONE; vTaskDelay(pdMS_TO_TICKS(100)); - ok = ok && gpio_descriptor_set_level(descriptor, active_high) == ERROR_NONE; + ok = ok && gpio_descriptor_set_level(descriptor, true) == ERROR_NONE; vTaskDelay(pdMS_TO_TICKS(10)); - ok = ok && gpio_descriptor_set_level(descriptor, idle_level) == ERROR_NONE; + ok = ok && gpio_descriptor_set_level(descriptor, false) == ERROR_NONE; vTaskDelay(pdMS_TO_TICKS(100)); return ok ? ERROR_NONE : ERROR_RESOURCE; @@ -77,14 +75,14 @@ static error_t start(Device* device) { internal->y = 0; if (config->pin_reset.gpio_controller != nullptr) { - internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (internal->reset_descriptor == nullptr) { LOG_E(TAG, "Failed to acquire reset pin"); free(internal); return ERROR_RESOURCE; } - if (reset_pulse(internal->reset_descriptor, config->reset_active_high) != ERROR_NONE) { + if (reset_pulse(internal->reset_descriptor) != ERROR_NONE) { LOG_E(TAG, "Failed to pulse reset pin"); gpio_descriptor_release(internal->reset_descriptor); free(internal); diff --git a/Drivers/ft5x06-module/bindings/focaltech,ft5x06.yaml b/Drivers/ft5x06-module/bindings/focaltech,ft5x06.yaml index 557f2a40..d9410cd8 100644 --- a/Drivers/ft5x06-module/bindings/focaltech,ft5x06.yaml +++ b/Drivers/ft5x06-module/bindings/focaltech,ft5x06.yaml @@ -35,11 +35,3 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Interrupt GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high - interrupt-active-high: - type: boolean - default: false - description: Whether the interrupt pin is active high diff --git a/Drivers/ft5x06-module/include/drivers/ft5x06.h b/Drivers/ft5x06-module/include/drivers/ft5x06.h index 7a7aba57..2ce771c6 100644 --- a/Drivers/ft5x06-module/include/drivers/ft5x06.h +++ b/Drivers/ft5x06-module/include/drivers/ft5x06.h @@ -21,8 +21,6 @@ struct Ft5x06Config { bool mirror_y; struct GpioPinSpec pin_reset; struct GpioPinSpec pin_interrupt; - bool reset_active_high; - bool interrupt_active_high; }; #ifdef __cplusplus diff --git a/Drivers/ft5x06-module/source/ft5x06.cpp b/Drivers/ft5x06-module/source/ft5x06.cpp index 8725fc30..37fb078a 100644 --- a/Drivers/ft5x06-module/source/ft5x06.cpp +++ b/Drivers/ft5x06-module/source/ft5x06.cpp @@ -36,30 +36,26 @@ struct Ft5x06Internal { // over as if it were one (the previous pin_or_nc() behavior below) silently toggles the wrong, // unrelated physical pin whenever pin_reset actually points at an I2C expander. GpioDescriptor* reset_descriptor; - bool reset_active_high; }; // Only valid for pin_interrupt: esp_lcd_touch only ever reads this pin's level / attaches an ISR // to it, both of which esp_lcd_touch performs via ESP-IDF's native gpio_* calls, so - like // ili9341-module's cs/dc pins - it must be a real ESP32 GPIO. pin_reset has no such requirement and // must never go through this helper; see pulse_reset() instead. -static inline gpio_num_t pin_or_nc(const struct GpioPinSpec& pin) { +static inline gpio_num_t pin_or_nc(const GpioPinSpec& pin) { return pin.gpio_controller == nullptr ? GPIO_NUM_NC : static_cast(pin.pin); } -// See esp_lcd_ili9341-module's pulse_reset() for the full rationale; same idea, same 10ms/10ms -// timing (matches esp_lcd_touch_ft5x06's own touch_ft5x06_reset()). esp_lcd_touch's rst_gpio_num is -// always left at GPIO_NUM_NC (see start()), under which it just skips its own reset step entirely. -static error_t pulse_reset(GpioDescriptor* descriptor, bool active_high) { +static error_t pulse_reset(GpioDescriptor* descriptor) { if (descriptor == nullptr) { return ERROR_NONE; } - error_t error = gpio_descriptor_set_level(descriptor, active_high); + error_t error = gpio_descriptor_set_level(descriptor, true); if (error != ERROR_NONE) { return error; } vTaskDelay(pdMS_TO_TICKS(10)); - error = gpio_descriptor_set_level(descriptor, !active_high); + error = gpio_descriptor_set_level(descriptor, false); if (error != ERROR_NONE) { return error; } @@ -101,20 +97,13 @@ static error_t start(Device* device) { } internal->reset_descriptor = nullptr; - internal->reset_active_high = config->reset_active_high; if (config->pin_reset.gpio_controller != nullptr) { - internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (internal->reset_descriptor == nullptr) { LOG_E(TAG, "Failed to acquire reset GPIO descriptor"); free(internal); return ERROR_RESOURCE; } - if (gpio_descriptor_set_flags(internal->reset_descriptor, config->pin_reset.flags | GPIO_FLAG_DIRECTION_OUTPUT) != ERROR_NONE) { - LOG_E(TAG, "Failed to configure reset pin as output"); - gpio_descriptor_release(internal->reset_descriptor); - free(internal); - return ERROR_RESOURCE; - } } esp_err_t ret = create_io_handle(parent, &internal->io_handle); @@ -126,7 +115,7 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } - if (pulse_reset(internal->reset_descriptor, internal->reset_active_high) != ERROR_NONE) { + if (pulse_reset(internal->reset_descriptor) != ERROR_NONE) { LOG_E(TAG, "Failed to pulse reset pin"); esp_lcd_panel_io_del(internal->io_handle); if (internal->reset_descriptor != nullptr) { @@ -143,9 +132,10 @@ static error_t start(Device* device) { // why); esp_lcd_touch just skips its own no-op reset step when this is NC. .rst_gpio_num = GPIO_NUM_NC, .int_gpio_num = pin_or_nc(config->pin_interrupt), + // FT5x06's reset and interrupt lines are both fixed active-low in hardware. .levels = { - .reset = config->reset_active_high ? 1u : 0u, - .interrupt = config->interrupt_active_high ? 1u : 0u, + .reset = 0u, + .interrupt = 0u, }, .flags = { .swap_xy = config->swap_xy ? 1u : 0u, diff --git a/Drivers/ft6x36-module/bindings/focaltech,ft6x36.yaml b/Drivers/ft6x36-module/bindings/focaltech,ft6x36.yaml index cede0fbd..c26bde64 100644 --- a/Drivers/ft6x36-module/bindings/focaltech,ft6x36.yaml +++ b/Drivers/ft6x36-module/bindings/focaltech,ft6x36.yaml @@ -35,11 +35,3 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Interrupt GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high - interrupt-active-high: - type: boolean - default: false - description: Whether the interrupt pin is active high diff --git a/Drivers/ft6x36-module/include/drivers/ft6x36.h b/Drivers/ft6x36-module/include/drivers/ft6x36.h index abedfa23..7e0ecdc2 100644 --- a/Drivers/ft6x36-module/include/drivers/ft6x36.h +++ b/Drivers/ft6x36-module/include/drivers/ft6x36.h @@ -21,8 +21,6 @@ struct Ft6x36Config { bool mirror_y; struct GpioPinSpec pin_reset; struct GpioPinSpec pin_interrupt; - bool reset_active_high; - bool interrupt_active_high; }; #ifdef __cplusplus diff --git a/Drivers/ft6x36-module/source/ft6x36.cpp b/Drivers/ft6x36-module/source/ft6x36.cpp index 8043955d..12ad5894 100644 --- a/Drivers/ft6x36-module/source/ft6x36.cpp +++ b/Drivers/ft6x36-module/source/ft6x36.cpp @@ -1,5 +1,6 @@ // SPDX-License-Identifier: Apache-2.0 #include + #include #include @@ -7,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -30,13 +32,7 @@ struct Ft6x36Internal { esp_lcd_panel_io_handle_t io_handle; esp_lcd_touch_handle_t touch_handle; // Non-null when pin_reset is configured. Owned/pulsed by this driver instead of esp_lcd_touch - // (see pulse_reset() below) so the reset pin can live on any GPIO_CONTROLLER, not just native - // gpio0 - esp_lcd_touch's rst_gpio_num only accepts a native ESP32 GPIO number (it calls - // gpio_set_level() directly), and just reading a GpioPinSpec's raw pin index and handing it - // over as if it were one (the previous pin_or_nc() behavior below) silently toggles the wrong, - // unrelated physical pin whenever pin_reset actually points at an I2C expander. GpioDescriptor* reset_descriptor; - bool reset_active_high; }; // Only valid for pin_interrupt: esp_lcd_touch only ever reads this pin's level / attaches an ISR @@ -50,16 +46,18 @@ static inline gpio_num_t pin_or_nc(const struct GpioPinSpec& pin) { // See ili9341-module's pulse_reset() for the full rationale; same idea, same 10ms/10ms timing. // esp_lcd_touch's rst_gpio_num is always left at GPIO_NUM_NC (see start()), under which it just // skips its own reset step entirely. -static error_t pulse_reset(GpioDescriptor* descriptor, bool active_high) { +static error_t pulse_reset(GpioDescriptor* descriptor) { if (descriptor == nullptr) { return ERROR_NONE; } - error_t error = gpio_descriptor_set_level(descriptor, active_high); + // Logical high (physical low, because of earlier GPIO_FLAG_ACTIVE_LOW) + error_t error = gpio_descriptor_set_level(descriptor, true); if (error != ERROR_NONE) { return error; } vTaskDelay(pdMS_TO_TICKS(50)); - error = gpio_descriptor_set_level(descriptor, !active_high); + // Logical low (physical high, because of earlier GPIO_FLAG_ACTIVE_LOW) + error = gpio_descriptor_set_level(descriptor, false); if (error != ERROR_NONE) { return error; } @@ -101,20 +99,13 @@ static error_t start(Device* device) { } internal->reset_descriptor = nullptr; - internal->reset_active_high = config->reset_active_high; if (config->pin_reset.gpio_controller != nullptr) { - internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (internal->reset_descriptor == nullptr) { LOG_E(TAG, "Failed to acquire reset GPIO descriptor"); free(internal); return ERROR_RESOURCE; } - if (gpio_descriptor_set_flags(internal->reset_descriptor, config->pin_reset.flags | GPIO_FLAG_DIRECTION_OUTPUT) != ERROR_NONE) { - LOG_E(TAG, "Failed to configure reset pin as output"); - gpio_descriptor_release(internal->reset_descriptor); - free(internal); - return ERROR_RESOURCE; - } } esp_err_t ret = create_io_handle(parent, &internal->io_handle); @@ -126,7 +117,7 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } - if (pulse_reset(internal->reset_descriptor, internal->reset_active_high) != ERROR_NONE) { + if (pulse_reset(internal->reset_descriptor) != ERROR_NONE) { LOG_E(TAG, "Failed to pulse reset pin"); esp_lcd_panel_io_del(internal->io_handle); if (internal->reset_descriptor != nullptr) { @@ -143,9 +134,10 @@ static error_t start(Device* device) { // why); esp_lcd_touch just skips its own no-op reset step when this is NC. .rst_gpio_num = GPIO_NUM_NC, .int_gpio_num = pin_or_nc(config->pin_interrupt), + // FT6x36's reset and interrupt lines are both fixed active-low in hardware. .levels = { - .reset = config->reset_active_high ? 1u : 0u, - .interrupt = config->interrupt_active_high ? 1u : 0u, + .reset = 0u, + .interrupt = 0u, }, .flags = { .swap_xy = config->swap_xy ? 1u : 0u, diff --git a/Drivers/gc9a01-module/bindings/galaxycore,gc9a01.yaml b/Drivers/gc9a01-module/bindings/galaxycore,gc9a01.yaml index 27576d1a..9fa38deb 100644 --- a/Drivers/gc9a01-module/bindings/galaxycore,gc9a01.yaml +++ b/Drivers/gc9a01-module/bindings/galaxycore,gc9a01.yaml @@ -57,10 +57,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/gc9a01-module/include/drivers/gc9a01.h b/Drivers/gc9a01-module/include/drivers/gc9a01.h index 2df79c3f..233811fa 100644 --- a/Drivers/gc9a01-module/include/drivers/gc9a01.h +++ b/Drivers/gc9a01-module/include/drivers/gc9a01.h @@ -25,7 +25,6 @@ struct Gc9a01Config { uint8_t transaction_queue_depth; struct GpioPinSpec pin_dc; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/gc9a01-module/source/gc9a01.cpp b/Drivers/gc9a01-module/source/gc9a01.cpp index 86406404..bd1b1632 100644 --- a/Drivers/gc9a01-module/source/gc9a01.cpp +++ b/Drivers/gc9a01-module/source/gc9a01.cpp @@ -106,7 +106,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = 16, - .flags = { .reset_active_high = config->reset_active_high }, + // GC9A01's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = nullptr, }; diff --git a/Drivers/gt911-module/bindings/goodix,gt911.yaml b/Drivers/gt911-module/bindings/goodix,gt911.yaml index f938d349..9ec8341d 100644 --- a/Drivers/gt911-module/bindings/goodix,gt911.yaml +++ b/Drivers/gt911-module/bindings/goodix,gt911.yaml @@ -35,11 +35,3 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Interrupt GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high - interrupt-active-high: - type: boolean - default: false - description: Whether the interrupt pin is active high diff --git a/Drivers/gt911-module/include/drivers/gt911.h b/Drivers/gt911-module/include/drivers/gt911.h index e1f7a551..14b3e4d0 100644 --- a/Drivers/gt911-module/include/drivers/gt911.h +++ b/Drivers/gt911-module/include/drivers/gt911.h @@ -22,8 +22,6 @@ struct Gt911Config { bool mirror_y; struct GpioPinSpec pin_reset; struct GpioPinSpec pin_interrupt; - bool reset_active_high; - bool interrupt_active_high; }; #ifdef __cplusplus diff --git a/Drivers/gt911-module/source/gt911.cpp b/Drivers/gt911-module/source/gt911.cpp index 217e9b62..b8aaed5d 100644 --- a/Drivers/gt911-module/source/gt911.cpp +++ b/Drivers/gt911-module/source/gt911.cpp @@ -84,9 +84,10 @@ static error_t start(Device* device) { .y_max = config->y_max, .rst_gpio_num = pin_or_nc(config->pin_reset), .int_gpio_num = pin_or_nc(config->pin_interrupt), + // GT911's reset and interrupt lines are both fixed active-low in hardware. .levels = { - .reset = config->reset_active_high ? 1u : 0u, - .interrupt = config->interrupt_active_high ? 1u : 0u, + .reset = 0u, + .interrupt = 0u, }, .flags = { .swap_xy = config->swap_xy ? 1u : 0u, diff --git a/Drivers/hx8357-module/bindings/himax,hx8357.yaml b/Drivers/hx8357-module/bindings/himax,hx8357.yaml index 77929766..13627a9e 100644 --- a/Drivers/hx8357-module/bindings/himax,hx8357.yaml +++ b/Drivers/hx8357-module/bindings/himax,hx8357.yaml @@ -54,10 +54,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/hx8357-module/include/drivers/hx8357.h b/Drivers/hx8357-module/include/drivers/hx8357.h index ec2f8a13..7bc01993 100644 --- a/Drivers/hx8357-module/include/drivers/hx8357.h +++ b/Drivers/hx8357-module/include/drivers/hx8357.h @@ -23,7 +23,6 @@ struct Hx8357Config { uint32_t pixel_clock_hz; struct GpioPinSpec pin_dc; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/hx8357-module/source/hx8357.cpp b/Drivers/hx8357-module/source/hx8357.cpp index 65ab3aac..a89fe0a3 100644 --- a/Drivers/hx8357-module/source/hx8357.cpp +++ b/Drivers/hx8357-module/source/hx8357.cpp @@ -264,9 +264,10 @@ static error_t start(Device* device) { free(internal); return ERROR_RESOURCE; } - gpio_set_level(static_cast(reset_pin), config->reset_active_high ? 1 : 0); + // HX8357's reset line is fixed active-low in hardware. + gpio_set_level(static_cast(reset_pin), 0); vTaskDelay(pdMS_TO_TICKS(10)); - gpio_set_level(static_cast(reset_pin), config->reset_active_high ? 0 : 1); + gpio_set_level(static_cast(reset_pin), 1); vTaskDelay(pdMS_TO_TICKS(120)); } diff --git a/Drivers/ili9341-module/source/ili9341.cpp b/Drivers/ili9341-module/source/ili9341.cpp index c9ef6d98..d8de08a2 100644 --- a/Drivers/ili9341-module/source/ili9341.cpp +++ b/Drivers/ili9341-module/source/ili9341.cpp @@ -71,16 +71,16 @@ static int pin_or_unused(const struct GpioPinSpec& pin) { // start()), which makes it fall back to sending a SWRESET command instead - itself a valid and // commonly-recommended reset path, so this pulse plus that fallback is redundant-safe, not harmful. // Timing (10ms low, 10ms recovery) matches esp_lcd_ili9341's own hardware-reset path exactly. -static error_t pulse_reset(GpioDescriptor* descriptor, bool active_high) { +static error_t pulse_reset(GpioDescriptor* descriptor) { if (descriptor == nullptr) { return ERROR_NONE; } - error_t error = gpio_descriptor_set_level(descriptor, active_high); + error_t error = gpio_descriptor_set_level(descriptor, true); if (error != ERROR_NONE) { return error; } vTaskDelay(pdMS_TO_TICKS(10)); - error = gpio_descriptor_set_level(descriptor, !active_high); + error = gpio_descriptor_set_level(descriptor, false); if (error != ERROR_NONE) { return error; } @@ -117,20 +117,13 @@ static error_t start(Device* device) { internal->reset_descriptor = nullptr; internal->reset_active_high = config->reset_active_high; if (config->pin_reset.gpio_controller != nullptr) { - internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + internal->reset_descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (internal->reset_descriptor == nullptr) { LOG_E(TAG, "Failed to acquire reset GPIO descriptor"); vSemaphoreDelete(internal->draw_done_semaphore); free(internal); return ERROR_RESOURCE; } - if (gpio_descriptor_set_flags(internal->reset_descriptor, config->pin_reset.flags | GPIO_FLAG_DIRECTION_OUTPUT) != ERROR_NONE) { - LOG_E(TAG, "Failed to configure reset pin as output"); - gpio_descriptor_release(internal->reset_descriptor); - vSemaphoreDelete(internal->draw_done_semaphore); - free(internal); - return ERROR_RESOURCE; - } } esp_lcd_panel_io_spi_config_t io_config = { @@ -195,7 +188,7 @@ static error_t start(Device* device) { // Every failure path below must clean up fully: unlike stop_device, this is never retried by the kernel // if start_device fails (see device_start() in TactilityKernel), so a partial failure here would leak. bool ok = - pulse_reset(internal->reset_descriptor, internal->reset_active_high) == ERROR_NONE && + pulse_reset(internal->reset_descriptor) == ERROR_NONE && esp_lcd_panel_reset(internal->panel_handle) == ESP_OK && esp_lcd_panel_init(internal->panel_handle) == ESP_OK && (!config->invert_color || esp_lcd_panel_invert_color(internal->panel_handle, true) == ESP_OK); @@ -263,7 +256,7 @@ static error_t stop(Device* device) { static error_t ili9341_reset(Device* device) { auto* internal = static_cast(device_get_driver_data(device)); - error_t error = pulse_reset(internal->reset_descriptor, internal->reset_active_high); + error_t error = pulse_reset(internal->reset_descriptor); if (error != ERROR_NONE) { return error; } diff --git a/Drivers/ili9488-module/bindings/ilitek,ili9488.yaml b/Drivers/ili9488-module/bindings/ilitek,ili9488.yaml index cba33f32..bda15722 100644 --- a/Drivers/ili9488-module/bindings/ilitek,ili9488.yaml +++ b/Drivers/ili9488-module/bindings/ilitek,ili9488.yaml @@ -65,10 +65,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/ili9488-module/include/drivers/ili9488.h b/Drivers/ili9488-module/include/drivers/ili9488.h index 6eceecb5..1f060078 100644 --- a/Drivers/ili9488-module/include/drivers/ili9488.h +++ b/Drivers/ili9488-module/include/drivers/ili9488.h @@ -29,7 +29,6 @@ struct Ili9488Config { uint8_t transaction_queue_depth; struct GpioPinSpec pin_dc; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/ili9488-module/source/ili9488.cpp b/Drivers/ili9488-module/source/ili9488.cpp index 7af09378..a23731ac 100644 --- a/Drivers/ili9488-module/source/ili9488.cpp +++ b/Drivers/ili9488-module/source/ili9488.cpp @@ -111,7 +111,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = config->bits_per_pixel, - .flags = { .reset_active_high = config->reset_active_high }, + // ILI9488's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = nullptr, }; diff --git a/Drivers/ili9881c-module/bindings/ilitek,ili9881c.yaml b/Drivers/ili9881c-module/bindings/ilitek,ili9881c.yaml index 794032db..b2e8b3e3 100644 --- a/Drivers/ili9881c-module/bindings/ilitek,ili9881c.yaml +++ b/Drivers/ili9881c-module/bindings/ilitek,ili9881c.yaml @@ -40,10 +40,6 @@ properties: default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin. Falls back to a software reset (sent over the DBI command interface) if not set. - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high ldo-channel: type: int required: true diff --git a/Drivers/ili9881c-module/include/drivers/ili9881c.h b/Drivers/ili9881c-module/include/drivers/ili9881c.h index ca01a2cc..d7bae83f 100644 --- a/Drivers/ili9881c-module/include/drivers/ili9881c.h +++ b/Drivers/ili9881c-module/include/drivers/ili9881c.h @@ -23,7 +23,6 @@ struct Ili9881cConfig { // Reset pin for the panel. GPIO_PIN_SPEC_NONE falls back to a software reset sent over the // DBI command interface (see esp_lcd_ili9881c's panel_ili9881c_reset()). struct GpioPinSpec pin_reset; - bool reset_active_high; // LDO channel powering the MIPI DSI PHY - the PHY has no power of its own until this is // acquired, so it must happen before the DSI bus is created. Both fields are int32_t (not diff --git a/Drivers/ili9881c-module/source/ili9881c.cpp b/Drivers/ili9881c-module/source/ili9881c.cpp index 660249e1..fd3e2ac2 100644 --- a/Drivers/ili9881c-module/source/ili9881c.cpp +++ b/Drivers/ili9881c-module/source/ili9881c.cpp @@ -226,7 +226,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = config->bits_per_pixel, - .flags = { .reset_active_high = config->reset_active_high }, + // ILI9881C's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = &vendor_config, }; diff --git a/Drivers/jd9165-module/bindings/jdi,jd9165.yaml b/Drivers/jd9165-module/bindings/jdi,jd9165.yaml index 4ed0900b..0270fdce 100644 --- a/Drivers/jd9165-module/bindings/jdi,jd9165.yaml +++ b/Drivers/jd9165-module/bindings/jdi,jd9165.yaml @@ -39,10 +39,6 @@ properties: default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin. Falls back to a software reset (sent over the DBI command interface) if not set. - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high ldo-channel: type: int required: true diff --git a/Drivers/jd9165-module/include/drivers/jd9165.h b/Drivers/jd9165-module/include/drivers/jd9165.h index beb975eb..d3489745 100644 --- a/Drivers/jd9165-module/include/drivers/jd9165.h +++ b/Drivers/jd9165-module/include/drivers/jd9165.h @@ -23,7 +23,6 @@ struct Jd9165Config { // Reset pin for the panel. GPIO_PIN_SPEC_NONE falls back to a software reset sent over the // DBI command interface (see esp_lcd_jd9165's panel_jd9165_reset()). struct GpioPinSpec pin_reset; - bool reset_active_high; // LDO channel powering the MIPI DSI PHY - the PHY has no power of its own until this is // acquired, so it must happen before the DSI bus is created. Both fields are int32_t (not diff --git a/Drivers/jd9165-module/source/jd9165.cpp b/Drivers/jd9165-module/source/jd9165.cpp index 1352a74e..ca8e6ba4 100644 --- a/Drivers/jd9165-module/source/jd9165.cpp +++ b/Drivers/jd9165-module/source/jd9165.cpp @@ -225,7 +225,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = config->bits_per_pixel, - .flags = { .reset_active_high = config->reset_active_high }, + // JD9165's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = &vendor_config, }; diff --git a/Drivers/jd9853-module/bindings/jadard,jd9853.yaml b/Drivers/jd9853-module/bindings/jadard,jd9853.yaml index 03743ff8..c7ae3987 100644 --- a/Drivers/jd9853-module/bindings/jadard,jd9853.yaml +++ b/Drivers/jd9853-module/bindings/jadard,jd9853.yaml @@ -63,10 +63,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/jd9853-module/include/drivers/jd9853.h b/Drivers/jd9853-module/include/drivers/jd9853.h index ff4fde4c..435b77d4 100644 --- a/Drivers/jd9853-module/include/drivers/jd9853.h +++ b/Drivers/jd9853-module/include/drivers/jd9853.h @@ -27,7 +27,6 @@ struct Jd9853Config { uint8_t gamma_curve; struct GpioPinSpec pin_dc; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/jd9853-module/source/jd9853.cpp b/Drivers/jd9853-module/source/jd9853.cpp index c34e3314..28a364cb 100644 --- a/Drivers/jd9853-module/source/jd9853.cpp +++ b/Drivers/jd9853-module/source/jd9853.cpp @@ -117,7 +117,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = 16, - .flags = { .reset_active_high = config->reset_active_high }, + // JD9853's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = &vendor_config, }; diff --git a/Drivers/lilygo-module/source/tdeck_trackball.cpp b/Drivers/lilygo-module/source/tdeck_trackball.cpp index 092f3852..9ec7881e 100644 --- a/Drivers/lilygo-module/source/tdeck_trackball.cpp +++ b/Drivers/lilygo-module/source/tdeck_trackball.cpp @@ -57,18 +57,15 @@ static void on_click(void* arg) { // region Pin acquisition static error_t acquire_pin(const GpioPinSpec& spec, GpioInterruptType interrupt_type, void (*callback)(void*), void* arg, GpioDescriptor** out_descriptor) { - auto* descriptor = gpio_descriptor_acquire(spec.gpio_controller, spec.pin, GPIO_OWNER_GPIO); + gpio_flags_t flags = GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP; + flags = GPIO_FLAG_INTERRUPT_TO_OPTIONS(flags, interrupt_type); + + auto* descriptor = gpio_descriptor_acquire(spec.gpio_controller, spec.pin, flags, GPIO_OWNER_GPIO); if (descriptor == nullptr) { return ERROR_RESOURCE; } - gpio_flags_t flags = GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP; - flags = GPIO_FLAG_INTERRUPT_TO_OPTIONS(flags, interrupt_type); - - error_t error = gpio_descriptor_set_flags(descriptor, flags); - if (error == ERROR_NONE) { - error = gpio_descriptor_add_callback(descriptor, callback, arg); - } + error_t error = gpio_descriptor_add_callback(descriptor, callback, arg); if (error == ERROR_NONE) { error = gpio_descriptor_enable_interrupt(descriptor); } diff --git a/Drivers/lilygo-module/source/tpager_encoder.cpp b/Drivers/lilygo-module/source/tpager_encoder.cpp index 099427f2..c5f92680 100644 --- a/Drivers/lilygo-module/source/tpager_encoder.cpp +++ b/Drivers/lilygo-module/source/tpager_encoder.cpp @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -33,14 +34,7 @@ static error_t read_delta(Device* device, int32_t* out_pulses) { static error_t get_button_pressed(Device* device, bool* out_pressed) { auto* internal = GET_INTERNAL(device); - bool high = true; - error_t error = gpio_descriptor_get_level(internal->pin_enter, &high); - if (error != ERROR_NONE) { - return error; - } - // Active low: pressed when level is low. - *out_pressed = !high; - return ERROR_NONE; + return gpio_descriptor_get_level(internal->pin_enter, out_pressed); } error_t tpager_encoder_read_delta(Device* device, int32_t* out_pulses) { @@ -148,7 +142,7 @@ static error_t start(Device* device) { return error; } - internal->pin_enter = gpio_descriptor_acquire(config->pin_enter.gpio_controller, config->pin_enter.pin, GPIO_OWNER_GPIO); + internal->pin_enter = gpio_descriptor_acquire(config->pin_enter.gpio_controller, config->pin_enter.pin, GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (internal->pin_enter == nullptr) { pcnt_unit_stop(internal->pcnt_unit); pcnt_del_unit(internal->pcnt_unit); @@ -156,15 +150,6 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } - error = gpio_descriptor_set_flags(internal->pin_enter, GPIO_FLAG_DIRECTION_INPUT); - if (error != ERROR_NONE) { - gpio_descriptor_release(internal->pin_enter); - pcnt_unit_stop(internal->pcnt_unit); - pcnt_del_unit(internal->pcnt_unit); - delete internal; - return error; - } - device_set_driver_data(device, internal); return ERROR_NONE; } diff --git a/Drivers/m5stack-module/source/cardputer_keyboard.cpp b/Drivers/m5stack-module/source/cardputer_keyboard.cpp index c8016ba8..43722fae 100644 --- a/Drivers/m5stack-module/source/cardputer_keyboard.cpp +++ b/Drivers/m5stack-module/source/cardputer_keyboard.cpp @@ -2,11 +2,13 @@ // Matrix-scan and keymap logic ported from the M5Stack Cardputer keyboard driver at // https://github.com/m5stack/M5Cardputer-UserDemo/tree/main/main/hal/keyboard (MIT licensed). #include + #include #include #include #include +#include #include #include #include @@ -120,11 +122,7 @@ static error_t start(Device* device) { for (int i = 0; i < CARDPUTER_OUTPUT_COUNT; i++) { const auto& pin = config->pins_output[i]; - auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, GPIO_OWNER_GPIO); - if (descriptor != nullptr && gpio_descriptor_set_flags(descriptor, pin.flags | GPIO_FLAG_DIRECTION_OUTPUT) != ERROR_NONE) { - gpio_descriptor_release(descriptor); - descriptor = nullptr; - } + auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, pin.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (descriptor == nullptr) { LOG_E(TAG, "Failed to configure output pin %d", i); for (int j = 0; j < i; j++) { @@ -141,8 +139,9 @@ static error_t start(Device* device) { const auto& pin = config->pins_input[i]; // Rows float high and are pulled low through a pressed key by the active output line, // so an internal pull-up is required regardless of what the devicetree pin flags say. - auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, GPIO_OWNER_GPIO); - if (descriptor == nullptr || gpio_descriptor_set_flags(descriptor, pin.flags | GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP) != ERROR_NONE) { + auto flags = pin.flags | GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP; + auto* descriptor = gpio_descriptor_acquire(pin.gpio_controller, pin.pin, flags, GPIO_OWNER_GPIO); + if (descriptor == nullptr) { LOG_E(TAG, "Failed to configure input pin %d", i); for (int j = 0; j < CARDPUTER_OUTPUT_COUNT; j++) { gpio_descriptor_release(internal->output_descriptors[j]); diff --git a/Drivers/pi4ioe5v6408-module/source/pi4ioe5v6408.cpp b/Drivers/pi4ioe5v6408-module/source/pi4ioe5v6408.cpp index 82b765c6..2e4796ef 100644 --- a/Drivers/pi4ioe5v6408-module/source/pi4ioe5v6408.cpp +++ b/Drivers/pi4ioe5v6408-module/source/pi4ioe5v6408.cpp @@ -47,7 +47,10 @@ static error_t set_level(GpioDescriptor* descriptor, bool high) { auto address = GET_CONFIG(device)->address; uint8_t bit = 1 << descriptor->pin; - if (high) { + // This chip has no output polarity register: active-low must be inverted in software. + bool physical_high = (descriptor->flags & GPIO_FLAG_ACTIVE_LOW) != 0 ? !high : high; + + if (physical_high) { return i2c_controller_register8_set_bits(parent, address, PI4_REGISTER_OUTPUT_LEVEL, bit, portMAX_DELAY); } else { return i2c_controller_register8_reset_bits(parent, address, PI4_REGISTER_OUTPUT_LEVEL, bit, portMAX_DELAY); @@ -65,7 +68,8 @@ static error_t get_level(GpioDescriptor* descriptor, bool* high) { return err; } - *high = (bits & (1 << descriptor->pin)) != 0; + bool physical_high = (bits & (1 << descriptor->pin)) != 0; + *high = (descriptor->flags & GPIO_FLAG_ACTIVE_LOW) != 0 ? !physical_high : physical_high; return ERROR_NONE; } @@ -161,6 +165,8 @@ static error_t get_flags(GpioDescriptor* descriptor, gpio_flags_t* flags) { f |= GPIO_FLAG_HIGH_IMPEDANCE; } + f |= (descriptor->flags & GPIO_FLAG_ACTIVE_LOW); + *flags = f; return ERROR_NONE; } diff --git a/Drivers/rgb-display-module/source/rgb_display.cpp b/Drivers/rgb-display-module/source/rgb_display.cpp index b3c088d8..798b7d87 100644 --- a/Drivers/rgb-display-module/source/rgb_display.cpp +++ b/Drivers/rgb-display-module/source/rgb_display.cpp @@ -9,8 +9,8 @@ #include #include #include +#include #include -#include #include #include @@ -70,17 +70,16 @@ static error_t perform_hardware_reset(const RgbDisplayConfig* config) { return ERROR_NONE; } - auto* descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + auto* descriptor = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (descriptor == nullptr) { LOG_E(TAG, "Failed to acquire reset GPIO descriptor"); return ERROR_RESOURCE; } - bool ok = gpio_descriptor_set_flags(descriptor, GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE; - ok = ok && gpio_descriptor_set_level(descriptor, config->reset_active_high) == ERROR_NONE; + bool ok = gpio_descriptor_set_level(descriptor, true) == ERROR_NONE; if (ok) { delay_millis(100); - ok = gpio_descriptor_set_level(descriptor, !config->reset_active_high) == ERROR_NONE; + ok = gpio_descriptor_set_level(descriptor, false) == ERROR_NONE; delay_millis(10); } diff --git a/Drivers/ssd1306-module/bindings/solomon,ssd1306.yaml b/Drivers/ssd1306-module/bindings/solomon,ssd1306.yaml index 86c40361..ff61eaf6 100644 --- a/Drivers/ssd1306-module/bindings/solomon,ssd1306.yaml +++ b/Drivers/ssd1306-module/bindings/solomon,ssd1306.yaml @@ -23,10 +23,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high power-on-delay-ms: type: int default: 0 diff --git a/Drivers/ssd1306-module/include/drivers/ssd1306.h b/Drivers/ssd1306-module/include/drivers/ssd1306.h index d9d69471..b1101ea4 100644 --- a/Drivers/ssd1306-module/include/drivers/ssd1306.h +++ b/Drivers/ssd1306-module/include/drivers/ssd1306.h @@ -22,7 +22,6 @@ struct Ssd1306Config { // Reset pin. GPIO_PIN_SPEC_NONE skips the reset toggle entirely. struct GpioPinSpec pin_reset; - bool reset_active_high; // See the 'power-on-delay-ms' binding property. uint32_t power_on_delay_ms; diff --git a/Drivers/ssd1306-module/source/ssd1306.cpp b/Drivers/ssd1306-module/source/ssd1306.cpp index d7ab35ee..c39b543a 100644 --- a/Drivers/ssd1306-module/source/ssd1306.cpp +++ b/Drivers/ssd1306-module/source/ssd1306.cpp @@ -119,9 +119,10 @@ static void perform_hardware_reset(const Ssd1306Config* config) { }; gpio_config(&io_conf); - gpio_set_level(pin, config->reset_active_high ? 1 : 0); + // SSD1306's reset line is fixed active-low in hardware. + gpio_set_level(pin, 0); vTaskDelay(pdMS_TO_TICKS(10)); - gpio_set_level(pin, config->reset_active_high ? 0 : 1); + gpio_set_level(pin, 1); vTaskDelay(pdMS_TO_TICKS(100)); } diff --git a/Drivers/st7123-module/bindings/sitronix,st7123-touch.yaml b/Drivers/st7123-module/bindings/sitronix,st7123-touch.yaml index e5ad40d6..84440427 100644 --- a/Drivers/st7123-module/bindings/sitronix,st7123-touch.yaml +++ b/Drivers/st7123-module/bindings/sitronix,st7123-touch.yaml @@ -37,11 +37,3 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Interrupt GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high - interrupt-active-high: - type: boolean - default: false - description: Whether the interrupt pin is active high diff --git a/Drivers/st7123-module/bindings/sitronix,st7123.yaml b/Drivers/st7123-module/bindings/sitronix,st7123.yaml index 6dc9f14e..ac7d302d 100644 --- a/Drivers/st7123-module/bindings/sitronix,st7123.yaml +++ b/Drivers/st7123-module/bindings/sitronix,st7123.yaml @@ -40,10 +40,6 @@ properties: default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin. Falls back to a software reset (sent over the DBI command interface) if not set. - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high ldo-channel: type: int required: true diff --git a/Drivers/st7123-module/include/drivers/st7123.h b/Drivers/st7123-module/include/drivers/st7123.h index 1e1c0a3a..996fd3cc 100644 --- a/Drivers/st7123-module/include/drivers/st7123.h +++ b/Drivers/st7123-module/include/drivers/st7123.h @@ -23,7 +23,6 @@ struct St7123Config { // Reset pin for the panel. GPIO_PIN_SPEC_NONE falls back to a software reset sent over the // DBI command interface (see esp_lcd_st7123's panel_st7123_reset()). struct GpioPinSpec pin_reset; - bool reset_active_high; // LDO channel powering the MIPI DSI PHY - the PHY has no power of its own until this is // acquired, so it must happen before the DSI bus is created. Both fields are int32_t (not diff --git a/Drivers/st7123-module/include/drivers/st7123_touch.h b/Drivers/st7123-module/include/drivers/st7123_touch.h index f4c75e2a..604e1625 100644 --- a/Drivers/st7123-module/include/drivers/st7123_touch.h +++ b/Drivers/st7123-module/include/drivers/st7123_touch.h @@ -25,8 +25,6 @@ struct St7123TouchConfig { // for parity with the other touch drivers (e.g. gt911-module) in case a board wires it directly. struct GpioPinSpec pin_reset; struct GpioPinSpec pin_interrupt; - bool reset_active_high; - bool interrupt_active_high; }; #ifdef __cplusplus diff --git a/Drivers/st7123-module/source/st7123.cpp b/Drivers/st7123-module/source/st7123.cpp index f56e7152..f3b52096 100644 --- a/Drivers/st7123-module/source/st7123.cpp +++ b/Drivers/st7123-module/source/st7123.cpp @@ -225,7 +225,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = config->bits_per_pixel, - .flags = { .reset_active_high = config->reset_active_high }, + // ST7123's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = &vendor_config, }; diff --git a/Drivers/st7123-module/source/st7123_touch.cpp b/Drivers/st7123-module/source/st7123_touch.cpp index 668179d7..ac35820b 100644 --- a/Drivers/st7123-module/source/st7123_touch.cpp +++ b/Drivers/st7123-module/source/st7123_touch.cpp @@ -75,9 +75,10 @@ static error_t start(Device* device) { .y_max = config->y_max, .rst_gpio_num = pin_or_nc(config->pin_reset), .int_gpio_num = pin_or_nc(config->pin_interrupt), + // ST7123's reset and interrupt lines are both fixed active-low in hardware. .levels = { - .reset = config->reset_active_high ? 1u : 0u, - .interrupt = config->interrupt_active_high ? 1u : 0u, + .reset = 0u, + .interrupt = 0u, }, .flags = { .swap_xy = config->swap_xy ? 1u : 0u, diff --git a/Drivers/st7701-module/bindings/sitronix,st7701.yaml b/Drivers/st7701-module/bindings/sitronix,st7701.yaml index b2db4d51..52ba3140 100644 --- a/Drivers/st7701-module/bindings/sitronix,st7701.yaml +++ b/Drivers/st7701-module/bindings/sitronix,st7701.yaml @@ -233,10 +233,6 @@ properties: default: GPIO_PIN_SPEC_NONE description: Optional hardware reset pin for the panel. Falls back to a software reset (sent over the 3-wire bus) if not set. - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high mirror-by-cmd: type: boolean default: false diff --git a/Drivers/st7701-module/include/drivers/st7701.h b/Drivers/st7701-module/include/drivers/st7701.h index 834a1a95..cbba1287 100644 --- a/Drivers/st7701-module/include/drivers/st7701.h +++ b/Drivers/st7701-module/include/drivers/st7701.h @@ -88,7 +88,6 @@ struct St7701Config { // Optional hardware reset pin for the panel. GPIO_PIN_SPEC_NONE falls back to a software // reset sent over the 3-wire bus (see esp_lcd_st7701's panel_st7701_reset()). struct GpioPinSpec pin_reset; - bool reset_active_high; // See the 'mirror-by-cmd' and 'auto-del-panel-io' binding properties. bool mirror_by_cmd; diff --git a/Drivers/st7701-module/source/st7701.cpp b/Drivers/st7701-module/source/st7701.cpp index 83c3e5f7..2d8b5f57 100644 --- a/Drivers/st7701-module/source/st7701.cpp +++ b/Drivers/st7701-module/source/st7701.cpp @@ -238,7 +238,8 @@ static error_t start(Device* device) { .rgb_ele_order = LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = config->bits_per_pixel, - .flags = { .reset_active_high = config->reset_active_high }, + // ST7701's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = &vendor_config, }; diff --git a/Drivers/st7735-module/bindings/sitronix,st7735.yaml b/Drivers/st7735-module/bindings/sitronix,st7735.yaml index f31afb2d..e6752f27 100644 --- a/Drivers/st7735-module/bindings/sitronix,st7735.yaml +++ b/Drivers/st7735-module/bindings/sitronix,st7735.yaml @@ -67,10 +67,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/st7735-module/include/drivers/st7735.h b/Drivers/st7735-module/include/drivers/st7735.h index dc39cdb3..5e9255df 100644 --- a/Drivers/st7735-module/include/drivers/st7735.h +++ b/Drivers/st7735-module/include/drivers/st7735.h @@ -28,7 +28,6 @@ struct St7735Config { uint8_t gamma_curve; struct GpioPinSpec pin_dc; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/st7735-module/source/st7735.cpp b/Drivers/st7735-module/source/st7735.cpp index 66c2a0b2..65ff21cf 100644 --- a/Drivers/st7735-module/source/st7735.cpp +++ b/Drivers/st7735-module/source/st7735.cpp @@ -117,7 +117,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = config->bits_per_pixel, - .flags = { .reset_active_high = config->reset_active_high }, + // ST7735's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = nullptr, }; diff --git a/Drivers/st7789-i8080-module/bindings/sitronix,st7789-i8080.yaml b/Drivers/st7789-i8080-module/bindings/sitronix,st7789-i8080.yaml index 8eee8489..0be16c85 100644 --- a/Drivers/st7789-i8080-module/bindings/sitronix,st7789-i8080.yaml +++ b/Drivers/st7789-i8080-module/bindings/sitronix,st7789-i8080.yaml @@ -59,10 +59,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/st7789-i8080-module/include/drivers/st7789_i8080.h b/Drivers/st7789-i8080-module/include/drivers/st7789_i8080.h index c71b281f..9b7557dd 100644 --- a/Drivers/st7789-i8080-module/include/drivers/st7789_i8080.h +++ b/Drivers/st7789-i8080-module/include/drivers/st7789_i8080.h @@ -26,7 +26,6 @@ struct St7789I8080Config { // Gamma curve preset index [0,3], sent via the MIPI DCS GAMSET (0x26) command at bring-up. uint8_t gamma_curve; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/st7789-i8080-module/source/st7789_i8080.cpp b/Drivers/st7789-i8080-module/source/st7789_i8080.cpp index d897c6f3..b000e3ec 100644 --- a/Drivers/st7789-i8080-module/source/st7789_i8080.cpp +++ b/Drivers/st7789-i8080-module/source/st7789_i8080.cpp @@ -148,7 +148,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = 16, - .flags = { .reset_active_high = config->reset_active_high }, + // ST7789's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = nullptr, }; diff --git a/Drivers/st7789-module/bindings/sitronix,st7789.yaml b/Drivers/st7789-module/bindings/sitronix,st7789.yaml index 3602b510..9821d2e4 100644 --- a/Drivers/st7789-module/bindings/sitronix,st7789.yaml +++ b/Drivers/st7789-module/bindings/sitronix,st7789.yaml @@ -67,10 +67,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/st7789-module/include/drivers/st7789.h b/Drivers/st7789-module/include/drivers/st7789.h index 6358acac..4dec5531 100644 --- a/Drivers/st7789-module/include/drivers/st7789.h +++ b/Drivers/st7789-module/include/drivers/st7789.h @@ -28,7 +28,6 @@ struct St7789Config { uint8_t gamma_curve; struct GpioPinSpec pin_dc; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/st7789-module/source/st7789.cpp b/Drivers/st7789-module/source/st7789.cpp index 071a88d5..b7466ff2 100644 --- a/Drivers/st7789-module/source/st7789.cpp +++ b/Drivers/st7789-module/source/st7789.cpp @@ -117,7 +117,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = config->bits_per_pixel, - .flags = { .reset_active_high = config->reset_active_high }, + // ST7789's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = nullptr, }; diff --git a/Drivers/st7796-i8080-module/bindings/sitronix,st7796-i8080.yaml b/Drivers/st7796-i8080-module/bindings/sitronix,st7796-i8080.yaml index 0159d332..40d721e7 100644 --- a/Drivers/st7796-i8080-module/bindings/sitronix,st7796-i8080.yaml +++ b/Drivers/st7796-i8080-module/bindings/sitronix,st7796-i8080.yaml @@ -59,10 +59,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/st7796-i8080-module/include/drivers/st7796_i8080.h b/Drivers/st7796-i8080-module/include/drivers/st7796_i8080.h index f99fe2a2..371c4ebf 100644 --- a/Drivers/st7796-i8080-module/include/drivers/st7796_i8080.h +++ b/Drivers/st7796-i8080-module/include/drivers/st7796_i8080.h @@ -26,7 +26,6 @@ struct St7796I8080Config { // Gamma curve preset index [0,3], sent via the MIPI DCS GAMSET (0x26) command at bring-up. uint8_t gamma_curve; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/st7796-i8080-module/source/st7796_i8080.cpp b/Drivers/st7796-i8080-module/source/st7796_i8080.cpp index e5aa9cd4..2af77339 100644 --- a/Drivers/st7796-i8080-module/source/st7796_i8080.cpp +++ b/Drivers/st7796-i8080-module/source/st7796_i8080.cpp @@ -116,7 +116,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = 16, - .flags = { .reset_active_high = config->reset_active_high }, + // ST7796's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = nullptr, }; diff --git a/Drivers/st7796-module/bindings/sitronix,st7796.yaml b/Drivers/st7796-module/bindings/sitronix,st7796.yaml index ac9000f7..bbeab1a9 100644 --- a/Drivers/st7796-module/bindings/sitronix,st7796.yaml +++ b/Drivers/st7796-module/bindings/sitronix,st7796.yaml @@ -67,10 +67,6 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Reset GPIO pin - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high backlight: type: phandle default: "NULL" diff --git a/Drivers/st7796-module/include/drivers/st7796.h b/Drivers/st7796-module/include/drivers/st7796.h index 2e4a5e7d..b76744d8 100644 --- a/Drivers/st7796-module/include/drivers/st7796.h +++ b/Drivers/st7796-module/include/drivers/st7796.h @@ -28,7 +28,6 @@ struct St7796Config { uint8_t gamma_curve; struct GpioPinSpec pin_dc; struct GpioPinSpec pin_reset; - bool reset_active_high; // Optional reference to this display's backlight device, NULL if none. struct Device* backlight; }; diff --git a/Drivers/st7796-module/source/st7796.cpp b/Drivers/st7796-module/source/st7796.cpp index 669c3b7b..c8ba2603 100644 --- a/Drivers/st7796-module/source/st7796.cpp +++ b/Drivers/st7796-module/source/st7796.cpp @@ -117,7 +117,8 @@ static error_t start(Device* device) { .rgb_ele_order = config->bgr_order ? LCD_RGB_ELEMENT_ORDER_BGR : LCD_RGB_ELEMENT_ORDER_RGB, .data_endian = LCD_RGB_DATA_ENDIAN_LITTLE, .bits_per_pixel = config->bits_per_pixel, - .flags = { .reset_active_high = config->reset_active_high }, + // ST7796's reset line is fixed active-low in hardware. + .flags = { .reset_active_high = false }, .vendor_config = nullptr, }; diff --git a/Drivers/tca8418-module/bindings/ti,tca8418.yaml b/Drivers/tca8418-module/bindings/ti,tca8418.yaml index 292a62c9..f6b2018f 100644 --- a/Drivers/tca8418-module/bindings/ti,tca8418.yaml +++ b/Drivers/tca8418-module/bindings/ti,tca8418.yaml @@ -68,7 +68,3 @@ properties: type: phandles default: GPIO_PIN_SPEC_NONE description: Optional reset GPIO pin, pulsed once at start (20 ms assert, 60 ms settle) - reset-active-high: - type: boolean - default: false - description: Whether the reset pin is active high diff --git a/Drivers/tca8418-module/include/drivers/tca8418.h b/Drivers/tca8418-module/include/drivers/tca8418.h index 22b52a32..c1e34311 100644 --- a/Drivers/tca8418-module/include/drivers/tca8418.h +++ b/Drivers/tca8418-module/include/drivers/tca8418.h @@ -27,7 +27,6 @@ struct Tca8418Config { uint8_t sym_row; uint8_t sym_col; struct GpioPinSpec pin_reset; - bool reset_active_high; }; #ifdef __cplusplus diff --git a/Drivers/tca8418-module/source/tca8418.cpp b/Drivers/tca8418-module/source/tca8418.cpp index fa974f2f..cab59dc4 100644 --- a/Drivers/tca8418-module/source/tca8418.cpp +++ b/Drivers/tca8418-module/source/tca8418.cpp @@ -1,11 +1,13 @@ // SPDX-License-Identifier: Apache-2.0 #include + #include #include #include #include #include +#include #include #include #include @@ -116,15 +118,18 @@ static void perform_hardware_reset(const Tca8418Config* config) { return; } - auto* rst = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_OWNER_GPIO); + // Not requesting GPIO_FLAG_ACTIVE_LOW here: some GPIO expanders (e.g. xl9555/tca95xx/ + // tca9534) can only invert what's read back from an input, not what's driven on an + // output, so they reject ACTIVE_LOW combined with OUTPUT. Drive the raw physical level + // instead: this pin's reset line is active-low, so low asserts and high releases. + auto* rst = gpio_descriptor_acquire(config->pin_reset.gpio_controller, config->pin_reset.pin, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (rst == nullptr) { return; } - gpio_descriptor_set_flags(rst, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_level(rst, config->reset_active_high); + gpio_descriptor_set_level(rst, false); delay_millis(20); - gpio_descriptor_set_level(rst, !config->reset_active_high); + gpio_descriptor_set_level(rst, true); gpio_descriptor_release(rst); delay_millis(60); } diff --git a/Drivers/xpt2046-softspi-module/source/xpt2046_softspi.cpp b/Drivers/xpt2046-softspi-module/source/xpt2046_softspi.cpp index 81968362..17921f27 100644 --- a/Drivers/xpt2046-softspi-module/source/xpt2046_softspi.cpp +++ b/Drivers/xpt2046-softspi-module/source/xpt2046_softspi.cpp @@ -1,10 +1,12 @@ // SPDX-License-Identifier: Apache-2.0 #include + #include #include #include #include +#include #include #include #include @@ -15,7 +17,7 @@ #include #include -#define TAG "XPT2046SoftSPI" +constexpr auto* TAG = "XPT2046SoftSPI"; #define GET_CONFIG(device) (static_cast((device)->config)) // Rough LiPo discharge curve floor, used together with the configured reference voltage @@ -73,10 +75,10 @@ static error_t start(Device* device) { } *internal = {}; - internal->mosi = gpio_descriptor_acquire(config->pin_mosi.gpio_controller, config->pin_mosi.pin, GPIO_OWNER_GPIO); - internal->miso = gpio_descriptor_acquire(config->pin_miso.gpio_controller, config->pin_miso.pin, GPIO_OWNER_GPIO); - internal->sck = gpio_descriptor_acquire(config->pin_sck.gpio_controller, config->pin_sck.pin, GPIO_OWNER_GPIO); - internal->cs = gpio_descriptor_acquire(config->pin_cs.gpio_controller, config->pin_cs.pin, GPIO_OWNER_GPIO); + internal->mosi = gpio_descriptor_acquire(config->pin_mosi.gpio_controller, config->pin_mosi.pin, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); + internal->miso = gpio_descriptor_acquire(config->pin_miso.gpio_controller, config->pin_miso.pin, GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP, GPIO_OWNER_GPIO); + internal->sck = gpio_descriptor_acquire(config->pin_sck.gpio_controller, config->pin_sck.pin, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); + internal->cs = gpio_descriptor_acquire(config->pin_cs.gpio_controller, config->pin_cs.pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (internal->mosi == nullptr || internal->miso == nullptr || internal->sck == nullptr || internal->cs == nullptr) { LOG_E(TAG, "Failed to acquire GPIO descriptors"); @@ -85,15 +87,8 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } - bool ok = - gpio_descriptor_set_flags(internal->mosi, GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE && - gpio_descriptor_set_flags(internal->sck, GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE && - gpio_descriptor_set_flags(internal->cs, GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE && - gpio_descriptor_set_flags(internal->miso, GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP) == ERROR_NONE; - // Idle state: CS high (deselected), SCK/MOSI low. - ok = ok && - gpio_descriptor_set_level(internal->cs, true) == ERROR_NONE && + bool ok = gpio_descriptor_set_level(internal->cs, false) == ERROR_NONE && gpio_descriptor_set_level(internal->sck, false) == ERROR_NONE && gpio_descriptor_set_level(internal->mosi, false) == ERROR_NONE; @@ -146,7 +141,7 @@ static error_t stop(Device* device) { static int read_spi_command(Xpt2046SoftSpiInternal* internal, uint8_t command) { int result = 0; - gpio_descriptor_set_level(internal->cs, false); + gpio_descriptor_set_level(internal->cs, true); delay_micros(1); for (int i = 7; i >= 0; i--) { @@ -169,7 +164,7 @@ static int read_spi_command(Xpt2046SoftSpiInternal* internal, uint8_t command) { delay_micros(1); } - gpio_descriptor_set_level(internal->cs, true); + gpio_descriptor_set_level(internal->cs, false); return result; } diff --git a/Platforms/platform-esp32/private/tactility/drivers/esp32_gpio_helpers.h b/Platforms/platform-esp32/private/tactility/drivers/esp32_gpio_helpers.h index 010268d5..3da34b98 100644 --- a/Platforms/platform-esp32/private/tactility/drivers/esp32_gpio_helpers.h +++ b/Platforms/platform-esp32/private/tactility/drivers/esp32_gpio_helpers.h @@ -15,7 +15,7 @@ void release_pin(GpioDescriptor** gpio_descriptor); * If the pin spec is invalid, the pointer is set to null. * @return true if the pin was acquired successfully */ -bool acquire_pin_or_set_null(const GpioPinSpec& pin_spec, GpioDescriptor** gpio_descriptor); +bool acquire_pin_or_set_null(const GpioPinSpec& pin_spec, gpio_flags_t direction_flags, GpioDescriptor** gpio_descriptor); /** * Safely acquire the native pin value. diff --git a/Platforms/platform-esp32/source/drivers/esp32_gpio.cpp b/Platforms/platform-esp32/source/drivers/esp32_gpio.cpp index d6d5137a..d2b42876 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_gpio.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_gpio.cpp @@ -22,12 +22,18 @@ struct Esp32GpioInternal { extern "C" { static error_t set_level(GpioDescriptor* descriptor, bool high) { - auto esp_error = gpio_set_level(static_cast(descriptor->pin), high); + // ESP32 GPIO has no hardware output-invert for plain digital I/O: active-low is a + // software-only concept, tracked in descriptor->flags rather than any hw register. + bool level_to_set = (descriptor->flags & GPIO_FLAG_ACTIVE_LOW) != 0 ? !high : high; + + auto esp_error = gpio_set_level(static_cast(descriptor->pin), level_to_set); return esp_err_to_error(esp_error); } static error_t get_level(GpioDescriptor* descriptor, bool* high) { - *high = gpio_get_level(static_cast(descriptor->pin)) != 0; + bool physical_level = gpio_get_level(static_cast(descriptor->pin)) != 0; + *high = (descriptor->flags & GPIO_FLAG_ACTIVE_LOW) != 0 ? !physical_level : physical_level; + return ERROR_NONE; } @@ -88,9 +94,9 @@ static error_t get_flags(GpioDescriptor* descriptor, gpio_flags_t* flags) { output |= GPIO_FLAG_DIRECTION_OUTPUT; } - if (esp_config.oe_inv) { - output |= GPIO_FLAG_ACTIVE_LOW; - } + // oe_inv is the output-enable-signal invert bit (GPIO-matrix routing), unrelated to + // active-low data level; that's a software-only concept tracked in descriptor->flags. + output |= (descriptor->flags & GPIO_FLAG_ACTIVE_LOW); *flags = output; return ERROR_NONE; diff --git a/Platforms/platform-esp32/source/drivers/esp32_gpio_helpers.cpp b/Platforms/platform-esp32/source/drivers/esp32_gpio_helpers.cpp index c4d78b12..e8f08ec5 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_gpio_helpers.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_gpio_helpers.cpp @@ -1,7 +1,7 @@ #include #include -#define TAG "gpio" +constexpr auto* TAG = "gpio"; void release_pin(GpioDescriptor** gpio_descriptor) { if (*gpio_descriptor == nullptr) return; @@ -9,12 +9,13 @@ void release_pin(GpioDescriptor** gpio_descriptor) { *gpio_descriptor = nullptr; } -bool acquire_pin_or_set_null(const GpioPinSpec& pin_spec, GpioDescriptor** gpio_descriptor) { +bool acquire_pin_or_set_null(const GpioPinSpec& pin_spec, gpio_flags_t direction_flags, GpioDescriptor** gpio_descriptor) { if (pin_spec.gpio_controller == nullptr) { *gpio_descriptor = nullptr; return true; } - *gpio_descriptor = gpio_descriptor_acquire(pin_spec.gpio_controller, pin_spec.pin, GPIO_OWNER_GPIO); + + *gpio_descriptor = gpio_descriptor_acquire(pin_spec.gpio_controller, pin_spec.pin, pin_spec.flags | direction_flags, GPIO_OWNER_GPIO); if (*gpio_descriptor == nullptr) { LOG_E(TAG, "Failed to acquire pin %u from %s", pin_spec.pin, pin_spec.gpio_controller->name); } diff --git a/Platforms/platform-esp32/source/drivers/esp32_i2c.cpp b/Platforms/platform-esp32/source/drivers/esp32_i2c.cpp index f1ac2727..fd328e47 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_i2c.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_i2c.cpp @@ -157,14 +157,14 @@ static error_t start(Device* device) { auto dts_config = GET_CONFIG(device); auto& sda_spec = dts_config->pinSda; - auto& scl_spec = dts_config->pinScl; - auto* sda_descriptor = gpio_descriptor_acquire(sda_spec.gpio_controller, sda_spec.pin, GPIO_OWNER_GPIO); + auto* sda_descriptor = gpio_descriptor_acquire(sda_spec.gpio_controller, sda_spec.pin, sda_spec.flags | GPIO_FLAG_DIRECTION_INPUT_OUTPUT, GPIO_OWNER_GPIO); if (!sda_descriptor) { LOG_E(TAG, "Failed to acquire pin %u", sda_spec.pin); return ERROR_RESOURCE; } - auto* scl_descriptor = gpio_descriptor_acquire(scl_spec.gpio_controller, scl_spec.pin, GPIO_OWNER_GPIO); + auto& scl_spec = dts_config->pinScl; + auto* scl_descriptor = gpio_descriptor_acquire(scl_spec.gpio_controller, scl_spec.pin, scl_spec.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (!scl_descriptor) { LOG_E(TAG, "Failed to acquire pin %u", scl_spec.pin); gpio_descriptor_release(sda_descriptor); diff --git a/Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp b/Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp index 190581bf..76c8b36f 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_i2c_master.cpp @@ -184,14 +184,14 @@ static error_t start(Device* device) { auto dts_config = GET_CONFIG(device); auto& sda_spec = dts_config->pinSda; - auto& scl_spec = dts_config->pinScl; - auto* sda_descriptor = gpio_descriptor_acquire(sda_spec.gpio_controller, sda_spec.pin, GPIO_OWNER_GPIO); + auto* sda_descriptor = gpio_descriptor_acquire(sda_spec.gpio_controller, sda_spec.pin, sda_spec.flags | GPIO_FLAG_DIRECTION_INPUT_OUTPUT, GPIO_OWNER_GPIO); if (!sda_descriptor) { LOG_E(TAG, "Failed to acquire pin %u", sda_spec.pin); return ERROR_RESOURCE; } - auto* scl_descriptor = gpio_descriptor_acquire(scl_spec.gpio_controller, scl_spec.pin, GPIO_OWNER_GPIO); + auto& scl_spec = dts_config->pinScl; + auto* scl_descriptor = gpio_descriptor_acquire(scl_spec.gpio_controller, scl_spec.pin, scl_spec.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (!scl_descriptor) { LOG_E(TAG, "Failed to acquire pin %u", scl_spec.pin); gpio_descriptor_release(sda_descriptor); diff --git a/Platforms/platform-esp32/source/drivers/esp32_i2s.cpp b/Platforms/platform-esp32/source/drivers/esp32_i2s.cpp index 54183a21..d57402f9 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_i2s.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_i2s.cpp @@ -65,11 +65,11 @@ struct Esp32I2sInternal { auto& data_out_spec = dts_config->pin_data_out; auto& mclk_spec = dts_config->pin_mclk; - bool success = acquire_pin_or_set_null(ws_spec, &ws_descriptor) && - acquire_pin_or_set_null(bclk_spec, &bclk_descriptor) && - acquire_pin_or_set_null(data_in_spec, &data_in_descriptor) && - acquire_pin_or_set_null(data_out_spec, &data_out_descriptor) && - acquire_pin_or_set_null(mclk_spec, &mclk_descriptor); + bool success = acquire_pin_or_set_null(ws_spec, GPIO_FLAG_DIRECTION_OUTPUT, &ws_descriptor) && + acquire_pin_or_set_null(bclk_spec, GPIO_FLAG_DIRECTION_OUTPUT, &bclk_descriptor) && + acquire_pin_or_set_null(data_in_spec, GPIO_FLAG_DIRECTION_INPUT, &data_in_descriptor) && + acquire_pin_or_set_null(data_out_spec, GPIO_FLAG_DIRECTION_OUTPUT, &data_out_descriptor) && + acquire_pin_or_set_null(mclk_spec, GPIO_FLAG_DIRECTION_OUTPUT, &mclk_descriptor); if (!success) { cleanup_pins(); diff --git a/Platforms/platform-esp32/source/drivers/esp32_i8080.cpp b/Platforms/platform-esp32/source/drivers/esp32_i8080.cpp index 9af6f312..4ec072d6 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_i8080.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_i8080.cpp @@ -68,17 +68,17 @@ static error_t start(Device* device) { const auto* config = GET_CONFIG(device); bool pins_ok = - acquire_pin_or_set_null(config->pin_dc, &data->dc_descriptor) && - acquire_pin_or_set_null(config->pin_wr, &data->wr_descriptor) && - acquire_pin_or_set_null(config->pin_rd, &data->rd_descriptor) && - acquire_pin_or_set_null(config->pin_d0, &data->d0_descriptor) && - acquire_pin_or_set_null(config->pin_d1, &data->d1_descriptor) && - acquire_pin_or_set_null(config->pin_d2, &data->d2_descriptor) && - acquire_pin_or_set_null(config->pin_d3, &data->d3_descriptor) && - acquire_pin_or_set_null(config->pin_d4, &data->d4_descriptor) && - acquire_pin_or_set_null(config->pin_d5, &data->d5_descriptor) && - acquire_pin_or_set_null(config->pin_d6, &data->d6_descriptor) && - acquire_pin_or_set_null(config->pin_d7, &data->d7_descriptor); + acquire_pin_or_set_null(config->pin_dc, GPIO_FLAG_DIRECTION_OUTPUT, &data->dc_descriptor) && + acquire_pin_or_set_null(config->pin_wr, GPIO_FLAG_DIRECTION_OUTPUT, &data->wr_descriptor) && + acquire_pin_or_set_null(config->pin_rd, GPIO_FLAG_DIRECTION_OUTPUT, &data->rd_descriptor) && + acquire_pin_or_set_null(config->pin_d0, GPIO_FLAG_DIRECTION_OUTPUT, &data->d0_descriptor) && + acquire_pin_or_set_null(config->pin_d1, GPIO_FLAG_DIRECTION_OUTPUT, &data->d1_descriptor) && + acquire_pin_or_set_null(config->pin_d2, GPIO_FLAG_DIRECTION_OUTPUT, &data->d2_descriptor) && + acquire_pin_or_set_null(config->pin_d3, GPIO_FLAG_DIRECTION_OUTPUT, &data->d3_descriptor) && + acquire_pin_or_set_null(config->pin_d4, GPIO_FLAG_DIRECTION_OUTPUT, &data->d4_descriptor) && + acquire_pin_or_set_null(config->pin_d5, GPIO_FLAG_DIRECTION_OUTPUT, &data->d5_descriptor) && + acquire_pin_or_set_null(config->pin_d6, GPIO_FLAG_DIRECTION_OUTPUT, &data->d6_descriptor) && + acquire_pin_or_set_null(config->pin_d7, GPIO_FLAG_DIRECTION_OUTPUT, &data->d7_descriptor); if (!pins_ok) { LOG_E(TAG, "Failed to acquire required i8080 pins"); @@ -91,7 +91,6 @@ static error_t start(Device* device) { // RD is never toggled by the i80 LCD peripheral (write-only bus); drive it high once so the // panel doesn't see spurious read strobes. if (data->rd_descriptor != nullptr) { - gpio_descriptor_set_flags(data->rd_descriptor, GPIO_FLAG_DIRECTION_OUTPUT); gpio_descriptor_set_level(data->rd_descriptor, true); } @@ -124,14 +123,13 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } - // Acquire and deselect all CS pins (drive high) + // Acquire and deselect all CS pins for (uint8_t i = 0; i < config->cs_gpios_count; i++) { const GpioPinSpec* cs = &config->cs_gpios[i]; if (cs->gpio_controller == nullptr) continue; - GpioDescriptor* desc = gpio_descriptor_acquire(cs->gpio_controller, cs->pin, GPIO_OWNER_GPIO); + GpioDescriptor* desc = gpio_descriptor_acquire(cs->gpio_controller, cs->pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_GPIO); if (desc != nullptr) { - gpio_descriptor_set_flags(desc, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_level(desc, true); + gpio_descriptor_set_level(desc, false); // logical low = physical high data->cs_descriptors.push_back(desc); } else { LOG_E(TAG, "Failed to acquire CS pin %u", i); diff --git a/Platforms/platform-esp32/source/drivers/esp32_sdmmc.cpp b/Platforms/platform-esp32/source/drivers/esp32_sdmmc.cpp index 4e259c40..7edfbc06 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_sdmmc.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_sdmmc.cpp @@ -14,7 +14,7 @@ #include #include -#define TAG "esp32_sdmmc" +constexpr auto* TAG = "esp32_sdmmc"; #define GET_CONFIG(device) ((const struct Esp32SdmmcConfig*)device->config) #define GET_DATA(device) ((struct Esp32SdmmcInternal*)device_get_driver_data(device)) @@ -84,18 +84,18 @@ static error_t start(Device* device) { // Acquire pins from the specified GPIO pin specs. Optional pins are allowed. bool pins_ok = - acquire_pin_or_set_null(sdmmc_config->pin_clk, &data->pin_clk_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_cmd, &data->pin_cmd_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_d0, &data->pin_d0_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_d1, &data->pin_d1_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_d2, &data->pin_d2_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_d3, &data->pin_d3_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_d4, &data->pin_d4_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_d5, &data->pin_d5_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_d6, &data->pin_d6_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_d7, &data->pin_d7_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_cd, &data->pin_cd_descriptor) && - acquire_pin_or_set_null(sdmmc_config->pin_wp, &data->pin_wp_descriptor); + acquire_pin_or_set_null(sdmmc_config->pin_clk, GPIO_FLAG_DIRECTION_OUTPUT, &data->pin_clk_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_cmd, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_cmd_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_d0, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_d0_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_d1, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_d1_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_d2, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_d2_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_d3, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_d3_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_d4, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_d4_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_d5, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_d5_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_d6, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_d6_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_d7, GPIO_FLAG_DIRECTION_INPUT_OUTPUT, &data->pin_d7_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_cd, GPIO_FLAG_DIRECTION_INPUT, &data->pin_cd_descriptor) && + acquire_pin_or_set_null(sdmmc_config->pin_wp, GPIO_FLAG_DIRECTION_INPUT, &data->pin_wp_descriptor); if (!pins_ok) { LOG_E(TAG, "Failed to acquire required one or more pins"); diff --git a/Platforms/platform-esp32/source/drivers/esp32_sdspi.cpp b/Platforms/platform-esp32/source/drivers/esp32_sdspi.cpp index 7b4bf153..f7d23248 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_sdspi.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_sdspi.cpp @@ -67,9 +67,9 @@ static error_t start(Device* device) { auto* config = GET_CONFIG(device); bool pins_ok = - acquire_pin_or_set_null(config->pin_cd, &data->pin_cd_descriptor) && - acquire_pin_or_set_null(config->pin_wp, &data->pin_wp_descriptor) && - acquire_pin_or_set_null(config->pin_int, &data->pin_int_descriptor); + acquire_pin_or_set_null(config->pin_cd, GPIO_FLAG_DIRECTION_INPUT, &data->pin_cd_descriptor) && + acquire_pin_or_set_null(config->pin_wp, GPIO_FLAG_DIRECTION_INPUT, &data->pin_wp_descriptor) && + acquire_pin_or_set_null(config->pin_int, GPIO_FLAG_DIRECTION_OUTPUT, &data->pin_int_descriptor); if (!pins_ok) { LOG_E(TAG, "Failed to acquire one or more pins"); diff --git a/Platforms/platform-esp32/source/drivers/esp32_spi.cpp b/Platforms/platform-esp32/source/drivers/esp32_spi.cpp index 721d7892..032aab27 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_spi.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_spi.cpp @@ -86,11 +86,11 @@ static error_t start(Device* device) { // Acquire pins from the specified GPIO pin specs. Optional pins are allowed. bool pins_ok = - acquire_pin_or_set_null(dts_config->pin_sclk, &data->sclk_descriptor) && - acquire_pin_or_set_null(dts_config->pin_mosi, &data->mosi_descriptor) && - acquire_pin_or_set_null(dts_config->pin_miso, &data->miso_descriptor) && - acquire_pin_or_set_null(dts_config->pin_wp, &data->wp_descriptor) && - acquire_pin_or_set_null(dts_config->pin_hd, &data->hd_descriptor); + acquire_pin_or_set_null(dts_config->pin_sclk, GPIO_FLAG_DIRECTION_OUTPUT, &data->sclk_descriptor) && + acquire_pin_or_set_null(dts_config->pin_mosi, GPIO_FLAG_DIRECTION_OUTPUT, &data->mosi_descriptor) && + acquire_pin_or_set_null(dts_config->pin_miso, GPIO_FLAG_DIRECTION_INPUT, &data->miso_descriptor) && + acquire_pin_or_set_null(dts_config->pin_wp, GPIO_FLAG_DIRECTION_INPUT, &data->wp_descriptor) && + acquire_pin_or_set_null(dts_config->pin_hd, GPIO_FLAG_DIRECTION_INPUT, &data->hd_descriptor); if (!pins_ok) { LOG_E(TAG, "Failed to acquire required SPI pins"); @@ -135,18 +135,18 @@ static error_t start(Device* device) { gpio_descriptor_set_flags(data->miso_descriptor, GPIO_FLAG_DIRECTION_INPUT | GPIO_FLAG_PULL_UP); } - // Acquire and deselect all CS pins (drive high) + // Acquire CS pins for (uint8_t i = 0; i < dts_config->cs_gpios_count; i++) { const GpioPinSpec* cs = &dts_config->cs_gpios[i]; if (cs->gpio_controller == nullptr) continue; - GpioDescriptor* desc = gpio_descriptor_acquire(cs->gpio_controller, cs->pin, GPIO_OWNER_SPI); + GpioDescriptor* desc = gpio_descriptor_acquire(cs->gpio_controller, cs->pin, GPIO_FLAG_DIRECTION_OUTPUT | GPIO_FLAG_ACTIVE_LOW, GPIO_OWNER_SPI); if (desc != nullptr) { - gpio_descriptor_set_flags(desc, GPIO_FLAG_DIRECTION_OUTPUT); - gpio_descriptor_set_level(desc, true); data->cs_descriptors.push_back(desc); } } + esp32_spi_deselect_all_cs(device); + data->initialized = true; return ERROR_NONE; } @@ -155,7 +155,7 @@ void esp32_spi_deselect_all_cs(Device* device) { auto* data = GET_DATA(device); if (data == nullptr) return; for (auto* desc : data->cs_descriptors) { - gpio_descriptor_set_level(desc, true); + gpio_descriptor_set_level(desc, false); } } diff --git a/Platforms/platform-esp32/source/drivers/esp32_uart.cpp b/Platforms/platform-esp32/source/drivers/esp32_uart.cpp index b7c863ef..56bba1a4 100644 --- a/Platforms/platform-esp32/source/drivers/esp32_uart.cpp +++ b/Platforms/platform-esp32/source/drivers/esp32_uart.cpp @@ -284,10 +284,10 @@ static error_t open(Device* device) { // Acquire pins from the specified GPIO pin specs. Optional pins are allowed. bool pins_ok = - acquire_pin_or_set_null(dts_config->pin_tx, &driver_data->tx_descriptor) && - acquire_pin_or_set_null(dts_config->pin_rx, &driver_data->rx_descriptor) && - acquire_pin_or_set_null(dts_config->pin_cts, &driver_data->cts_descriptor) && - acquire_pin_or_set_null(dts_config->pin_rts, &driver_data->rts_descriptor); + acquire_pin_or_set_null(dts_config->pin_tx, GPIO_FLAG_DIRECTION_OUTPUT, &driver_data->tx_descriptor) && + acquire_pin_or_set_null(dts_config->pin_rx, GPIO_FLAG_DIRECTION_INPUT, &driver_data->rx_descriptor) && + acquire_pin_or_set_null(dts_config->pin_cts, GPIO_FLAG_DIRECTION_INPUT, &driver_data->cts_descriptor) && + acquire_pin_or_set_null(dts_config->pin_rts, GPIO_FLAG_DIRECTION_OUTPUT, &driver_data->rts_descriptor); if (!pins_ok) { LOG_E(TAG, "%s failed to acquire UART pins", device->name); diff --git a/TactilityKernel/include/tactility/drivers/gpio_controller.h b/TactilityKernel/include/tactility/drivers/gpio_controller.h index 44365a96..35223f0a 100644 --- a/TactilityKernel/include/tactility/drivers/gpio_controller.h +++ b/TactilityKernel/include/tactility/drivers/gpio_controller.h @@ -2,13 +2,13 @@ #pragma once +#include "gpio.h" +#include + #ifdef __cplusplus extern "C" { #endif -#include "gpio.h" -#include - struct Device; struct GpioDescriptor; @@ -87,6 +87,12 @@ struct GpioControllerApi { struct GpioDescriptor* gpio_descriptor_acquire( struct Device* controller, gpio_pin_t pin_number, + gpio_flags_t flags, + enum GpioOwnerType owner +); + +struct GpioDescriptor* gpio_descriptor_acquire_pin_spec( + struct GpioPinSpec const* pin_spec, enum GpioOwnerType owner ); @@ -140,6 +146,15 @@ error_t gpio_descriptor_set_flags(struct GpioDescriptor* descriptor, gpio_flags_ */ error_t gpio_descriptor_get_flags(struct GpioDescriptor* descriptor, gpio_flags_t* flags); +/** + * @brief Gets the configuration options for a GPIO pin. + * @param[in] descriptor the pin descriptor + * @param[out] flags 1 or more flags to check + * @param[out] has_flags true when all flags are available + * @return ERROR_NONE if successful + */ +error_t gpio_descriptor_has_flags(struct GpioDescriptor* descriptor, gpio_flags_t flags, bool* has_flags); + /** * @brief Gets the native pin number associated with a descriptor. * @param[in] descriptor the pin descriptor diff --git a/TactilityKernel/include/tactility/drivers/gpio_descriptor.h b/TactilityKernel/include/tactility/drivers/gpio_descriptor.h index 80d4d52b..b5ec8912 100644 --- a/TactilityKernel/include/tactility/drivers/gpio_descriptor.h +++ b/TactilityKernel/include/tactility/drivers/gpio_descriptor.h @@ -9,6 +9,8 @@ struct GpioDescriptor { struct Device* controller; /** @brief Physical pin number */ gpio_pin_t pin; + /** @brief Pin flags: initialized by config, might be updated by user via gpio_descriptor_set_flags() */ + gpio_flags_t flags; /** @brief Current owner */ enum GpioOwnerType owner_type; /** diff --git a/TactilityKernel/source/drivers/gpio_backlight.cpp b/TactilityKernel/source/drivers/gpio_backlight.cpp index b9bde8b4..c5b3d9f5 100644 --- a/TactilityKernel/source/drivers/gpio_backlight.cpp +++ b/TactilityKernel/source/drivers/gpio_backlight.cpp @@ -90,18 +90,12 @@ static constexpr BacklightApi GPIO_BACKLIGHT_API = { static error_t start(Device* device) { const auto* config = GET_CONFIG(device); - auto* descriptor = gpio_descriptor_acquire(config->pin.gpio_controller, config->pin.pin, GPIO_OWNER_GPIO); + auto* descriptor = gpio_descriptor_acquire(config->pin.gpio_controller, config->pin.pin, config->pin.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (descriptor == nullptr) { LOG_E(TAG, "Failed to acquire GPIO descriptor"); return ERROR_RESOURCE; } - if (gpio_descriptor_set_flags(descriptor, config->pin.flags | GPIO_FLAG_DIRECTION_OUTPUT) != ERROR_NONE) { - LOG_E(TAG, "Failed to configure backlight pin as output"); - gpio_descriptor_release(descriptor); - return ERROR_RESOURCE; - } - auto* internal = new(std::nothrow) GpioBacklightInternal { .descriptor = descriptor, .enabled = false }; if (internal == nullptr) { gpio_descriptor_release(descriptor); diff --git a/TactilityKernel/source/drivers/gpio_controller.cpp b/TactilityKernel/source/drivers/gpio_controller.cpp index 922aad6a..ed3d5fc9 100644 --- a/TactilityKernel/source/drivers/gpio_controller.cpp +++ b/TactilityKernel/source/drivers/gpio_controller.cpp @@ -1,14 +1,15 @@ // SPDX-License-Identifier: Apache-2.0 -#include -#include - #include +#include +#include +#include #include #include #include +constexpr auto* TAG = "gpio"; #define GPIO_INTERNAL_API(driver) ((struct GpioControllerApi*)(driver)->api) extern "C" { @@ -31,6 +32,7 @@ struct GpioControllerData { for (uint32_t i = 0; i < pin_count; ++i) { descriptors[i].controller = device; descriptors[i].pin = static_cast(i); + descriptors[i].flags = 0; descriptors[i].owner_type = GPIO_OWNER_NONE; descriptors[i].controller_context = this->controller_context; } @@ -48,6 +50,7 @@ struct GpioControllerData { GpioDescriptor* gpio_descriptor_acquire( Device* controller, gpio_pin_t pin_number, + gpio_flags_t flags, GpioOwnerType owner ) { check(owner != GPIO_OWNER_NONE); @@ -56,22 +59,48 @@ GpioDescriptor* gpio_descriptor_acquire( mutex_lock(&data->mutex); if (pin_number >= data->pin_count) { + LOG_E(TAG, "%s: pin %lu is out of range (> %lu)", controller->name, pin_number, data->pin_count); mutex_unlock(&data->mutex); return nullptr; } GpioDescriptor* desc = &data->descriptors[pin_number]; if (desc->owner_type != GPIO_OWNER_NONE) { + LOG_E(TAG, "%s: pin %lu is in use", controller->name, pin_number); mutex_unlock(&data->mutex); return nullptr; } desc->owner_type = owner; + desc->flags = flags; mutex_unlock(&data->mutex); + // Init flags by implementation + auto init_result = gpio_descriptor_set_flags(desc, flags); + if (init_result != ERROR_NONE) { + LOG_E(TAG, "%s: pin %d failed to set flags to %08lx", controller->name, pin_number, flags); + mutex_lock(&data->mutex); + desc->owner_type = GPIO_OWNER_NONE; + desc->flags = 0; + mutex_unlock(&data->mutex); + return nullptr; + } + return desc; } +GpioDescriptor* gpio_descriptor_acquire_pin_spec( + GpioPinSpec const* pin_spec, + GpioOwnerType owner +) { + return gpio_descriptor_acquire( + pin_spec->gpio_controller, + pin_spec->pin, + pin_spec->flags, + owner + ); +} + error_t gpio_descriptor_release(GpioDescriptor* descriptor) { auto* data = static_cast(device_get_driver_data(descriptor->controller)); mutex_lock(&data->mutex); @@ -133,6 +162,17 @@ error_t gpio_descriptor_get_flags(GpioDescriptor* descriptor, gpio_flags_t* flag return GPIO_INTERNAL_API(driver)->get_flags(descriptor, flags); } +error_t gpio_descriptor_has_flags(GpioDescriptor* descriptor, gpio_flags_t flags, bool* has_flags) { + const auto* driver = device_get_driver(descriptor->controller); + gpio_flags_t available_flags = 0; + error_t result = GPIO_INTERNAL_API(driver)->get_flags(descriptor, &available_flags); + if (result != ERROR_NONE) { + return result; + } + *has_flags = (available_flags & flags) == flags; + return ERROR_NONE; +} + error_t gpio_descriptor_get_pin_number(GpioDescriptor* descriptor, gpio_pin_t* pin) { *pin = descriptor->pin; return ERROR_NONE; diff --git a/TactilityKernel/source/drivers/gpio_hog.cpp b/TactilityKernel/source/drivers/gpio_hog.cpp index c331588f..9b2672d7 100644 --- a/TactilityKernel/source/drivers/gpio_hog.cpp +++ b/TactilityKernel/source/drivers/gpio_hog.cpp @@ -18,32 +18,31 @@ const DeviceType GPIO_HOG_TYPE { .name = "gpio_hog" }; static error_t start(Device* device) { const auto* config = GET_CONFIG(device); - auto* descriptor = gpio_descriptor_acquire(config->pin.gpio_controller, config->pin.pin, GPIO_OWNER_HOG); + gpio_flags_t flags = 0; + bool initial_high = false; + switch (config->mode) { + case GPIO_HOG_MODE_OUTPUT_HIGH: + flags = GPIO_FLAG_DIRECTION_OUTPUT; + initial_high = true; + break; + case GPIO_HOG_MODE_OUTPUT_LOW: + flags = GPIO_FLAG_DIRECTION_OUTPUT; + break; + case GPIO_HOG_MODE_INPUT: + flags = GPIO_FLAG_DIRECTION_INPUT; + break; + default: + return ERROR_RESOURCE; + } + + auto* descriptor = gpio_descriptor_acquire(config->pin.gpio_controller, config->pin.pin, config->pin.flags | flags, GPIO_OWNER_HOG); if (descriptor == nullptr) { LOG_E(TAG, "Failed to acquire GPIO descriptor"); return ERROR_RESOURCE; } - bool ok; - switch (config->mode) { - case GPIO_HOG_MODE_OUTPUT_HIGH: - ok = gpio_descriptor_set_flags(descriptor, GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE && - gpio_descriptor_set_level(descriptor, true) == ERROR_NONE; - break; - case GPIO_HOG_MODE_OUTPUT_LOW: - ok = gpio_descriptor_set_flags(descriptor, GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE && - gpio_descriptor_set_level(descriptor, false) == ERROR_NONE; - break; - case GPIO_HOG_MODE_INPUT: - ok = gpio_descriptor_set_flags(descriptor, GPIO_FLAG_DIRECTION_INPUT) == ERROR_NONE; - break; - default: - ok = false; - break; - } - - if (!ok) { - LOG_E(TAG, "Failed to configure hogged pin %u", config->pin.pin); + if (config->mode != GPIO_HOG_MODE_INPUT && gpio_descriptor_set_level(descriptor, initial_high) != ERROR_NONE) { + LOG_E(TAG, "Failed to set initial level to %d", (int)initial_high); gpio_descriptor_release(descriptor); return ERROR_RESOURCE; } diff --git a/TactilityKernel/source/drivers/rgb_led_gpio.cpp b/TactilityKernel/source/drivers/rgb_led_gpio.cpp index 49efc83a..af22fba1 100644 --- a/TactilityKernel/source/drivers/rgb_led_gpio.cpp +++ b/TactilityKernel/source/drivers/rgb_led_gpio.cpp @@ -1,16 +1,18 @@ // SPDX-License-Identifier: Apache-2.0 +#include #include #include #include +#include #include -#include +#include #include #include #include -#define TAG "RgbLedGpio" +constexpr auto* TAG = "RgbLedGpio"; #define GET_CONFIG(device) (static_cast((device)->config)) #define GET_INTERNAL(device) (static_cast(device_get_driver_data(device))) @@ -77,20 +79,20 @@ static constexpr RgbLedApi RGB_LED_GPIO_API = { static error_t start(Device* device) { const auto* config = GET_CONFIG(device); - auto* descriptor_red = gpio_descriptor_acquire(config->pin_red.gpio_controller, config->pin_red.pin, GPIO_OWNER_GPIO); + auto* descriptor_red = gpio_descriptor_acquire(config->pin_red.gpio_controller, config->pin_red.pin, config->pin_red.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (descriptor_red == nullptr) { LOG_E(TAG, "Failed to acquire red GPIO descriptor"); return ERROR_RESOURCE; } - auto* descriptor_green = gpio_descriptor_acquire(config->pin_green.gpio_controller, config->pin_green.pin, GPIO_OWNER_GPIO); + auto* descriptor_green = gpio_descriptor_acquire(config->pin_green.gpio_controller, config->pin_green.pin, config->pin_green.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (descriptor_green == nullptr) { LOG_E(TAG, "Failed to acquire green GPIO descriptor"); gpio_descriptor_release(descriptor_red); return ERROR_RESOURCE; } - auto* descriptor_blue = gpio_descriptor_acquire(config->pin_blue.gpio_controller, config->pin_blue.pin, GPIO_OWNER_GPIO); + auto* descriptor_blue = gpio_descriptor_acquire(config->pin_blue.gpio_controller, config->pin_blue.pin, config->pin_blue.flags | GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); if (descriptor_blue == nullptr) { LOG_E(TAG, "Failed to acquire blue GPIO descriptor"); gpio_descriptor_release(descriptor_red); @@ -98,17 +100,6 @@ static error_t start(Device* device) { return ERROR_RESOURCE; } - bool ok = gpio_descriptor_set_flags(descriptor_red, config->pin_red.flags | GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE && - gpio_descriptor_set_flags(descriptor_green, config->pin_green.flags | GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE && - gpio_descriptor_set_flags(descriptor_blue, config->pin_blue.flags | GPIO_FLAG_DIRECTION_OUTPUT) == ERROR_NONE; - if (!ok) { - LOG_E(TAG, "Failed to configure LED pins as outputs"); - gpio_descriptor_release(descriptor_red); - gpio_descriptor_release(descriptor_green); - gpio_descriptor_release(descriptor_blue); - return ERROR_RESOURCE; - } - auto* internal = new(std::nothrow) RgbLedGpioInternal { .descriptor_red = descriptor_red, .descriptor_green = descriptor_green,