# 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 ```mermaid 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:** ```json // 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 ```mermaid 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: ```c // 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 ```c // 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 ```c // 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: ```c // 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: ```mermaid 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