From ccf4569969b4784a270ad2186d7c17f0db975c6f Mon Sep 17 00:00:00 2001 From: Valentin Haudiquet Date: Thu, 12 Mar 2026 15:28:20 +0100 Subject: [PATCH] gpio: update config to use only one gpio for ATX PSU --- README.md | 10 +-------- main/config.h | 44 ++++---------------------------------- main/gpio_controller.c | 48 +++++++----------------------------------- main/gpio_controller.h | 14 +++--------- main/main.c | 22 +------------------ main/web_server.c | 30 +++++++------------------- 6 files changed, 25 insertions(+), 143 deletions(-) diff --git a/README.md b/README.md index 7523c41..6c4681a 100644 --- a/README.md +++ b/README.md @@ -37,15 +37,7 @@ A Baseboard Management Controller (BMC) firmware for ESP32-S3 that provides remo #### BMC GPIOs | GPIO | Name | Description | |------|------|-------------| -| 4 | POWER_ON | Power control output | -| 5 | POWER_OFF | Power control output | -| 6 | RESET | Reset control (active-low) | -| 7 | STATUS_LED | Status LED | -| 15 | PWR_GOOD | Power good input | -| 16 | TEMP_ALERT | Temperature alert input | -| 17 | FAN_CTRL | Fan control PWM | -| 18-25 | USER_1-8 | User configurable GPIOs | -| 35-38 | USER_5-8 | Input-only GPIOs | +| 37 | POWER | ATX power supply "PS_ON#" signal | ## Building diff --git a/main/config.h b/main/config.h index a6c7a6d..988bdb0 100644 --- a/main/config.h +++ b/main/config.h @@ -47,7 +47,7 @@ // ============================================================================ // Number of user-configurable GPIOs -#define BMC_GPIO_COUNT 16 +#define BMC_GPIO_COUNT 1 // GPIO pin definitions with names and default modes typedef struct { @@ -60,54 +60,18 @@ typedef struct { } bmc_gpio_def_t; // Predefined GPIO assignments -#define BMC_GPIO_POWER_ON GPIO_NUM_4 -#define BMC_GPIO_POWER_OFF GPIO_NUM_5 -#define BMC_GPIO_RESET GPIO_NUM_6 -#define BMC_GPIO_STATUS_LED GPIO_NUM_7 -#define BMC_GPIO_PWR_GOOD GPIO_NUM_15 -#define BMC_GPIO_TEMP_ALERT GPIO_NUM_16 -#define BMC_GPIO_FAN_CTRL GPIO_NUM_17 -#define BMC_GPIO_USER_1 GPIO_NUM_18 -#define BMC_GPIO_USER_2 GPIO_NUM_21 -#define BMC_GPIO_USER_3 GPIO_NUM_35 -#define BMC_GPIO_USER_4 GPIO_NUM_36 -#define BMC_GPIO_USER_5 GPIO_NUM_37 -#define BMC_GPIO_USER_6 GPIO_NUM_38 -#define BMC_GPIO_USER_7 GPIO_NUM_47 -#define BMC_GPIO_USER_8 GPIO_NUM_48 +#define BMC_GPIO_POWER GPIO_NUM_37 // Default GPIO configuration table static const bmc_gpio_def_t bmc_gpio_defaults[BMC_GPIO_COUNT] = { // Power control outputs - { BMC_GPIO_POWER_ON, "POWER_ON", GPIO_MODE_OUTPUT, 0, false, false}, - { BMC_GPIO_POWER_OFF, "POWER_OFF", GPIO_MODE_OUTPUT, 0, false, false}, - { BMC_GPIO_RESET, "RESET", GPIO_MODE_OUTPUT, 0, true, false}, // Active-low reset - {BMC_GPIO_STATUS_LED, "STATUS_LED", GPIO_MODE_OUTPUT, 0, false, false}, - - // Status inputs - { BMC_GPIO_PWR_GOOD, "PWR_GOOD", GPIO_MODE_INPUT, 0, false, false}, - {BMC_GPIO_TEMP_ALERT, "TEMP_ALERT", GPIO_MODE_INPUT, 0, true, false}, // Active-low alert - - // PWM output - { BMC_GPIO_FAN_CTRL, "FAN_CTRL", GPIO_MODE_OUTPUT, 0, false, false}, - - // User-configurable GPIOs - { BMC_GPIO_USER_1, "USER_1", GPIO_MODE_INPUT, 0, false, false}, - { BMC_GPIO_USER_2, "USER_2", GPIO_MODE_INPUT, 0, false, false}, - { BMC_GPIO_USER_3, "USER_3", GPIO_MODE_INPUT, 0, false, false}, - { BMC_GPIO_USER_4, "USER_4", GPIO_MODE_INPUT, 0, false, false}, - { BMC_GPIO_USER_5, "USER_5", GPIO_MODE_INPUT, 0, false, true}, // Input-only on ESP32-S3 - { BMC_GPIO_USER_6, "USER_6", GPIO_MODE_INPUT, 0, false, true}, // Input-only on ESP32-S3 - { BMC_GPIO_USER_7, "USER_7", GPIO_MODE_INPUT, 0, false, true}, // Input-only on ESP32-S3 - { BMC_GPIO_USER_8, "USER_8", GPIO_MODE_INPUT, 0, false, true}, // Input-only on ESP32-S3 + {BMC_GPIO_POWER, "POWER", GPIO_MODE_OUTPUT, 1 /* AC power ON */, true, false}, }; // ============================================================================ // Power Control Timing // ============================================================================ -#define BMC_POWER_ON_PULSE_MS 100 -#define BMC_POWER_OFF_PULSE_MS 5000 -#define BMC_RESET_PULSE_MS 100 +#define BMC_RESET_PULSE_MS 200 #define BMC_POWER_GOOD_DELAY_MS 2000 // ============================================================================ diff --git a/main/gpio_controller.c b/main/gpio_controller.c index 68f8d99..62ee9ce 100644 --- a/main/gpio_controller.c +++ b/main/gpio_controller.c @@ -218,61 +218,29 @@ esp_err_t gpio_toggle(gpio_num_t pin) { esp_err_t gpio_power_on(void) { ESP_LOGI(TAG, "Power ON sequence initiated"); - - // Pulse the POWER_ON signal - gpio_write(BMC_GPIO_POWER_ON, 1); - vTaskDelay(pdMS_TO_TICKS(BMC_POWER_ON_PULSE_MS)); - gpio_write(BMC_GPIO_POWER_ON, 0); - - // Wait for power good signal - vTaskDelay(pdMS_TO_TICKS(BMC_POWER_GOOD_DELAY_MS)); - - if (gpio_is_power_good()) { - ESP_LOGI(TAG, "Power ON successful - power good detected"); - gpio_set_status_led(true); - return ESP_OK; - } else { - ESP_LOGW(TAG, "Power ON completed - no power good signal"); - return ESP_OK; // Still return OK, just no confirmation - } + gpio_write(BMC_GPIO_POWER, 1); + return ESP_OK; } esp_err_t gpio_power_off(void) { ESP_LOGI(TAG, "Power OFF sequence initiated"); - - // Pulse the POWER_OFF signal - gpio_write(BMC_GPIO_POWER_OFF, 1); - vTaskDelay(pdMS_TO_TICKS(BMC_POWER_OFF_PULSE_MS)); - gpio_write(BMC_GPIO_POWER_OFF, 0); - - gpio_set_status_led(false); - ESP_LOGI(TAG, "Power OFF completed"); - + gpio_write(BMC_GPIO_POWER, 0); return ESP_OK; } esp_err_t gpio_reset(void) { ESP_LOGI(TAG, "Reset sequence initiated"); - // Pulse the RESET signal (active-low) - gpio_write(BMC_GPIO_RESET, 0); // Assert reset (active-low) + // Pulse the POWER signal + gpio_write(BMC_GPIO_POWER, 0); vTaskDelay(pdMS_TO_TICKS(BMC_RESET_PULSE_MS)); - gpio_write(BMC_GPIO_RESET, 1); // De-assert reset + gpio_write(BMC_GPIO_POWER, 1); ESP_LOGI(TAG, "Reset completed"); return ESP_OK; } -bool gpio_is_power_good(void) { - int idx = gpio_find_index(BMC_GPIO_PWR_GOOD); - if (idx < 0) { - return false; - } - - int level = gpio_get_level(BMC_GPIO_PWR_GOOD); +bool gpio_power_status(void) { + int level = gpio_get_level(BMC_GPIO_POWER); return (level == 1); } - -esp_err_t gpio_set_status_led(bool on) { - return gpio_write(BMC_GPIO_STATUS_LED, on ? 1 : 0); -} diff --git a/main/gpio_controller.h b/main/gpio_controller.h index 491c044..cb20dc4 100644 --- a/main/gpio_controller.h +++ b/main/gpio_controller.h @@ -131,18 +131,10 @@ esp_err_t gpio_power_off(void); esp_err_t gpio_reset(void); /** - * @brief Check if power is good + * @brief Check if power is on or off * - * @return true if power good signal is high, false otherwise + * @return true if power signal is high, false otherwise */ -bool gpio_is_power_good(void); - -/** - * @brief Set status LED state - * - * @param on true to turn on, false to turn off - * @return ESP_OK on success, error code otherwise - */ -esp_err_t gpio_set_status_led(bool on); +bool gpio_power_status(void); #endif // GPIO_CONTROLLER_H diff --git a/main/main.c b/main/main.c index 6b5b37d..fe521b4 100644 --- a/main/main.c +++ b/main/main.c @@ -17,12 +17,10 @@ static void eth_event_callback(eth_event_type_t event) { switch (event) { case ETH_EVENT_CONNECTED: ESP_LOGI(TAG, "Ethernet connected"); - gpio_set_status_led(true); break; case ETH_EVENT_DISCONNECTED: ESP_LOGW(TAG, "Ethernet disconnected"); - gpio_set_status_led(false); break; case ETH_EVENT_GOT_IP: { @@ -51,9 +49,6 @@ void app_main(void) { // Continue anyway - some GPIOs might still work } - // Set status LED to indicate initialization - gpio_set_status_led(false); - // Initialize UART handler ESP_LOGI(TAG, "Initializing UART handler..."); ret = uart_handler_init(); @@ -119,20 +114,5 @@ void app_main(void) { ESP_LOGI(TAG, "Web interface: http://%s/", ip); ESP_LOGI(TAG, "========================================"); - // Main loop - monitor system health - while (1) { - // Update status LED based on connection state - if (ethernet_is_connected()) { - gpio_set_status_led(true); - } else { - // Blink LED if not connected - gpio_set_status_led(false); - vTaskDelay(pdMS_TO_TICKS(500)); - gpio_set_status_led(true); - vTaskDelay(pdMS_TO_TICKS(500)); - gpio_set_status_led(false); - } - - vTaskDelay(pdMS_TO_TICKS(5000)); - } + return; } diff --git a/main/web_server.c b/main/web_server.c index b29c966..d689a32 100644 --- a/main/web_server.c +++ b/main/web_server.c @@ -258,24 +258,7 @@ static esp_err_t api_gpio_config_handler(httpd_req_t *req) { static esp_err_t api_power_status_handler(httpd_req_t *req) { cJSON *status = cJSON_CreateObject(); - cJSON_AddBoolToObject(status, "power_good", gpio_is_power_good()); - - // Get power control GPIO states - int power_on_idx = gpio_find_index(BMC_GPIO_POWER_ON); - int power_off_idx = gpio_find_index(BMC_GPIO_POWER_OFF); - - if (power_on_idx >= 0) { - bmc_gpio_state_t state; - gpio_get_state(BMC_GPIO_POWER_ON, &state); - cJSON_AddNumberToObject(status, "power_on_state", state.value); - } - - if (power_off_idx >= 0) { - bmc_gpio_state_t state; - gpio_get_state(BMC_GPIO_POWER_OFF, &state); - cJSON_AddNumberToObject(status, "power_off_state", state.value); - } - + cJSON_AddStringToObject(status, "power_status", gpio_power_status() ? "on" : "off"); return send_json_success(req, status); } @@ -287,7 +270,7 @@ static esp_err_t api_power_on_handler(httpd_req_t *req) { cJSON *response = cJSON_CreateObject(); cJSON_AddStringToObject(response, "message", "Power on sequence initiated"); - cJSON_AddBoolToObject(response, "power_good", gpio_is_power_good()); + cJSON_AddStringToObject(response, "power_status", "on"); return send_json_success(req, response); } @@ -300,6 +283,7 @@ static esp_err_t api_power_off_handler(httpd_req_t *req) { cJSON *response = cJSON_CreateObject(); cJSON_AddStringToObject(response, "message", "Power off sequence initiated"); + cJSON_AddStringToObject(response, "power_status", "off"); return send_json_success(req, response); } @@ -312,6 +296,7 @@ static esp_err_t api_power_reset_handler(httpd_req_t *req) { cJSON *response = cJSON_CreateObject(); cJSON_AddStringToObject(response, "message", "Reset sequence initiated"); + cJSON_AddStringToObject(response, "power_status", "on"); return send_json_success(req, response); } @@ -484,7 +469,7 @@ static esp_err_t api_system_status_handler(httpd_req_t *req) { // Power status cJSON *power = cJSON_CreateObject(); - cJSON_AddBoolToObject(power, "power_good", gpio_is_power_good()); + cJSON_AddBoolToObject(power, "power_status", gpio_power_status()); cJSON_AddItemToObject(status, "power", power); // Network status @@ -918,8 +903,9 @@ esp_err_t web_server_ws_broadcast(const uint8_t *data, size_t len) { // Get client list - httpd has its own internal locking esp_err_t ret = httpd_get_client_list(server, &clients, client_fds); if (ret != ESP_OK) { - ESP_LOGW(TAG, "Failed to get client list: %s", esp_err_to_name(ret)); - return ret; + // This can happen when there are no clients or server is busy - not a critical error + ESP_LOGD(TAG, "Could not get client list: %s (may be no clients connected)", esp_err_to_name(ret)); + return ESP_OK; // Return OK since this is not a critical error } // Count and send to all WebSocket clients