Files
esp32-bmc/plans/esp32-bmc-plan.md
Valentin Haudiquet 064e8812a4 Initial commit
ESP32-S3 firmware acting as BMC for another board, controlling an ATX power supply and providing access to UART.

Co-authored with GLM-5
2026-03-11 17:39:43 +01:00

8.6 KiB

ESP32-S3 BMC Firmware Plan

Overview

This project creates a Baseboard Management Controller (BMC) firmware for ESP32-S3 that provides remote management capabilities for an external board via Ethernet.

Framework Decision: ESP-IDF

Selected Framework: ESP-IDF (Espressif IoT Development Framework)

Rationale:

  • Native W5500 SPI Ethernet driver support
  • Excellent HTTP server performance with esp_http_server
  • FreeRTOS enables efficient multitasking for concurrent operations
  • Production-ready with long-term support
  • Good balance between development speed and performance

System Architecture

flowchart TB
    subgraph ESP32-S3
        subgraph Software
            WEB[HTTP Web Server]
            API[REST API Handler]
            GPIO[GPIO Controller]
            UART[UART Serial Module]
            ETH[Ethernet Manager - W5500]
            NET[Network Stack - LwIP]
        end
        
        subgraph Hardware
            SPI[SPI Bus]
            GP_IO[GPIO Pins 8-16]
            UART_HW[UART Hardware]
        end
    end
    
    subgraph External
        CLIENT[Web Browser Client]
        BOARD[Target Board]
        W5500[W5500 Ethernet Module]
    end
    
    CLIENT -->|HTTP| WEB
    WEB --> API
    API --> GPIO
    API --> UART
    GPIO --> GP_IO --> BOARD
    UART --> UART_HW --> BOARD
    ETH --> SPI --> W5500
    NET --> ETH

Project Structure

esp32-bmc/
├── CMakeLists.txt
├── sdkconfig.defaults
├── main/
│   ├── CMakeLists.txt
│   ├── main.c                 # Application entry point
│   ├── gpio_controller.c      # GPIO management
│   ├── gpio_controller.h
│   ├── uart_handler.c         # UART serial communication
│   ├── uart_handler.h
│   ├── ethernet_manager.c     # W5500 Ethernet setup
│   ├── ethernet_manager.h
│   ├── web_server.c           # HTTP server and routes
│   ├── web_server.h
│   └── html/
│       └── index.html         # Embedded web interface
├── components/
│   └── w5500/                 # W5500 driver component if needed
├── include/
│   └── config.h               # Pin definitions and settings
└── docs/
    └── README.md

Hardware Configuration

Pin Assignments (ESP32-S3)

Function GPIO Pin Description
SPI for W5500
MOSI GPIO 11 SPI MOSI
MISO GPIO 13 SPI MISO
SCLK GPIO 12 SPI Clock
CS GPIO 10 Chip Select
RST GPIO 9 W5500 Reset
INT GPIO 14 W5500 Interrupt
UART Serial
TX GPIO 43 UART0 TX to target board
RX GPIO 44 UART0 RX from target board
BMC GPIOs
POWER_ON GPIO 4 Power control output
POWER_OFF GPIO 5 Power control output
RESET GPIO 6 Reset control output
STATUS_LED GPIO 7 Status LED output
PWR_GOOD GPIO 15 Power good input
TEMP_ALERT GPIO 16 Temperature alert input
FAN_CTRL GPIO 17 Fan control PWM
USER_GPIO_1-8 GPIO 18-25 User configurable GPIOs

REST API Endpoints

GPIO Control

Method Endpoint Description
GET /api/gpio Get all GPIO states
GET /api/gpio/{pin} Get specific GPIO state
POST /api/gpio/{pin} Set GPIO state
PUT /api/gpio/{pin}/config Configure GPIO mode

Example Request/Response:

// GET /api/gpio
{
  "gpios": [
    {"pin": 4, "name": "POWER_ON", "mode": "output", "value": 1},
    {"pin": 5, "name": "POWER_OFF", "mode": "output", "value": 0},
    {"pin": 15, "name": "PWR_GOOD", "mode": "input", "value": 1}
  ]
}

// POST /api/gpio/4
// Request body:
{"value": 1}
// Response:
{"success": true, "pin": 4, "value": 1}

Power Control

Method Endpoint Description
POST /api/power/on Turn board power on
POST /api/power/off Turn board power off
POST /api/power/reset Reset the board
GET /api/power/status Get power status

Serial Console

Method Endpoint Description
GET /api/serial WebSocket for serial console
POST /api/serial/send Send data to serial
GET /api/serial/config Get serial configuration
PUT /api/serial/config Configure serial settings

System

Method Endpoint Description
GET /api/system/info Get system information
GET /api/system/status Get BMC status

Web Interface

A simple HTML/CSS dashboard will be embedded in the firmware providing:

  1. Power Control Panel - Buttons for power on/off/reset with status indicators
  2. GPIO Monitor - Real-time display of GPIO states
  3. Serial Console - Web-based terminal for serial communication
  4. System Info - Display BMC status and network information
flowchart LR
    subgraph Web Interface
        PWR[Power Control Panel]
        GPIO[GPIO Monitor]
        SER[Serial Console]
        SYS[System Info]
    end
    
    PWR -->|REST API| API[REST Endpoints]
    GPIO -->|REST API| API
    SER -->|WebSocket| WS[Serial Bridge]
    SYS -->|REST API| API

Implementation Details

1. Ethernet Manager (W5500)

The W5500 will be configured using SPI interface:

// Key configuration steps
1. Initialize SPI driver
2. Configure W5500 MAC address
3. Set up DHCP client or static IP
4. Handle network events (connect/disconnect)
5. Register network callbacks

2. GPIO Controller

// GPIO configuration structure
typedef struct {
    gpio_num_t pin;
    const char* name;
    gpio_mode_t mode;
    int default_value;
    bool inverted;  // For active-low signals
} bmc_gpio_config_t;

// Functions
void gpio_controller_init(void);
int gpio_read(gpio_num_t pin);
esp_err_t gpio_write(gpio_num_t pin, int value);
esp_err_t gpio_configure(gpio_num_t pin, gpio_mode_t mode);

3. UART Handler

// UART configuration
#define UART_NUM        UART_NUM_1
#define UART_BAUD_RATE  115200
#define UART_BUF_SIZE   2048

// Functions
void uart_handler_init(void);
int uart_read_bytes(uint8_t* buf, size_t len);
int uart_write_bytes(const uint8_t* buf, size_t len);

4. Web Server

Using esp_http_server component:

// Server setup
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();

// Register URI handlers
httpd_register_uri_handler(server, &gpio_get_uri);
httpd_register_uri_handler(server, &gpio_post_uri);
httpd_register_uri_handler(server, &power_on_uri);
httpd_register_uri_handler(server, &serial_ws_uri);

5. Serial WebSocket Bridge

The serial endpoint will use WebSocket for bidirectional communication:

sequenceDiagram
    participant Browser
    participant WebSocket
    participant UART Buffer
    participant Target Board
    
    Browser->>WebSocket: Connect to /api/serial
    WebSocket->>UART Buffer: Start reading task
    
    loop Serial Data
        Target Board->>UART Buffer: Serial data
        UART Buffer->>WebSocket: Data available
        WebSocket->>Browser: Send data frame
    end
    
    Browser->>WebSocket: Send command
    WebSocket->>Target Board: Write to UART

Configuration Options

The firmware will support configuration via sdkconfig and a runtime config file:

Option Default Description
BMC_ETHERNET_DHCP true Use DHCP for IP
BMC_STATIC_IP 192.168.1.100 Static IP if DHCP disabled
BMC_NETMASK 255.255.255.0 Network mask
BMC_GATEWAY 192.168.1.1 Default gateway
BMC_HTTP_PORT 80 Web server port
BMC_UART_BAUD 115200 Serial baud rate
BMC_GPIO_COUNT 16 Number of GPIOs to manage

Development Phases

Phase 1: Core Infrastructure

  • Initialize ESP-IDF project
  • Set up W5500 Ethernet connectivity
  • Basic GPIO read/write functionality

Phase 2: Web Server

  • Implement HTTP server
  • Create REST API endpoints for GPIO
  • Add power control endpoints

Phase 3: Serial Console

  • Implement UART handler
  • Create WebSocket bridge
  • Add serial configuration endpoints

Phase 4: Web Interface

  • Design and implement HTML/CSS dashboard
  • Embed files in firmware
  • Add JavaScript for dynamic updates

Phase 5: Polish and Testing

  • Error handling and recovery
  • Documentation
  • Testing on hardware

Dependencies

  • ESP-IDF v5.0+
  • esp_http_server component
  • driver component (SPI, GPIO, UART)
  • lwIP stack

Next Steps

  1. Initialize the ESP-IDF project structure
  2. Configure W5500 SPI Ethernet
  3. Implement GPIO controller module
  4. Build and test incrementally