gpio: update config to use only one gpio for ATX PSU
All checks were successful
Build ESP32 BMC Firmware / build (push) Successful in 59s
All checks were successful
Build ESP32 BMC Firmware / build (push) Successful in 59s
This commit is contained in:
10
README.md
10
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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
// ============================================================================
|
||||
|
||||
@@ -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);
|
||||
gpio_write(BMC_GPIO_POWER, 1);
|
||||
return ESP_OK;
|
||||
} else {
|
||||
ESP_LOGW(TAG, "Power ON completed - no power good signal");
|
||||
return ESP_OK; // Still return OK, just no confirmation
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
22
main/main.c
22
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user