GPIO refactored (#495)

* **Refactor**
  * GPIO subsystem moved to a descriptor-based model for per-pin ownership and runtime pin management; many platform drivers now acquire/release descriptors.
  * Device trees and drivers now use GPIO phandle-style pin specifications across all boards and all drivers.

* **Behavior**
  * Device list now encodes per-device status (ok/disabled); boot will skip disabled devices accordingly.

* **Deprecation**
  * Legacy GPIO HAL marked deprecated and replaced with descriptor-based interfaces.

* **Chores**
  * Bindings and platform configs updated to the new GPIO pin-spec format.
This commit is contained in:
Ken Van Hoeylandt
2026-02-11 20:34:54 +01:00
committed by GitHub
parent dff93cb655
commit 26c17986c6
80 changed files with 1129 additions and 665 deletions
@@ -9,6 +9,8 @@
#include <tactility/error_esp32.h>
#include <tactility/log.h>
#include <tactility/time.h>
#include <tactility/drivers/gpio_descriptor.h>
#include <tactility/drivers/esp32_gpio_helpers.h>
#include <new>
@@ -20,13 +22,27 @@ struct Esp32UartInternal {
bool config_set = false;
bool is_open = false;
// Pin descriptors
GpioDescriptor* tx_descriptor = nullptr;
GpioDescriptor* rx_descriptor = nullptr;
GpioDescriptor* cts_descriptor = nullptr;
GpioDescriptor* rts_descriptor = nullptr;
Esp32UartInternal() {
mutex_construct(&mutex);
}
~Esp32UartInternal() {
cleanup_pins();
mutex_destruct(&mutex);
}
void cleanup_pins() {
release_pin(&tx_descriptor);
release_pin(&rx_descriptor);
release_pin(&cts_descriptor);
release_pin(&rts_descriptor);
}
};
#define GET_CONFIG(device) ((Esp32UartConfig*)device->config)
@@ -254,7 +270,7 @@ static error_t open(Device* device) {
}
};
if (dts_config->pinCts != UART_PIN_NO_CHANGE || dts_config->pinRts != UART_PIN_NO_CHANGE) {
if (dts_config->pin_cts.gpio_controller != nullptr || dts_config->pin_rts.gpio_controller != nullptr) {
LOG_W(TAG, "%s: CTS/RTS pins are defined but hardware flow control is disabled (not supported in UartConfig)", device->name);
}
@@ -266,9 +282,31 @@ static error_t open(Device* device) {
return ERROR_RESOURCE;
}
esp_error = uart_set_pin(dts_config->port, dts_config->pinTx, dts_config->pinRx, dts_config->pinCts, dts_config->pinRts);
// 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);
if (!pins_ok) {
LOG_E(TAG, "%s failed to acquire UART pins", device->name);
driver_data->cleanup_pins();
uart_driver_delete(dts_config->port);
unlock(driver_data);
return ERROR_RESOURCE;
}
esp_error = uart_set_pin(dts_config->port,
get_native_pin(driver_data->tx_descriptor),
get_native_pin(driver_data->rx_descriptor),
get_native_pin(driver_data->rts_descriptor),
get_native_pin(driver_data->cts_descriptor)
);
if (esp_error != ESP_OK) {
LOG_E(TAG, "%s failed to set uart pins: %s", device->name, esp_err_to_name(esp_error));
driver_data->cleanup_pins();
uart_driver_delete(dts_config->port);
unlock(driver_data);
return ERROR_RESOURCE;
@@ -293,6 +331,7 @@ static error_t close(Device* device) {
return ERROR_INVALID_STATE;
}
uart_driver_delete(dts_config->port);
driver_data->cleanup_pins();
driver_data->is_open = false;
unlock(driver_data);