Fix docs to match UART0 firmware implementation

The firmware uses UART0 (via USB bridge) with ESP-IDF console disabled,
not UART1 on GPIO4/GPIO5 as originally documented. Updated both docs to
reflect the actual hardware-verified configuration:

- protocol-spec.md: UART peripheral description
- hardware-setup.md: wiring section, monitor section, sdkconfig table,
  troubleshooting steps
This commit is contained in:
Ryan Malloy 2026-02-02 15:38:20 -07:00
parent dc6078b296
commit 0e7b8c2ef5
2 changed files with 14 additions and 42 deletions

View File

@ -22,41 +22,13 @@ Any ESP32 board based on the original ESP32 chip should work. Commonly available
## Wiring ## Wiring
### Default: USB only ### USB only (default)
For most development, a single USB cable handles both flashing and protocol communication. The ESP32's built-in USB-to-UART bridge (typically CP2102 or CH340) provides the serial link. A single USB cable handles both flashing and NDJSON protocol communication. The ESP32 dev board's built-in USB-to-UART bridge (typically CP2102 or CH340) connects to UART0 (TX=GPIO1, RX=GPIO3).
The firmware uses **UART1** (GPIO4/GPIO5) for the NDJSON protocol and keeps **UART0** for ESP-IDF console logging. When using USB only, the USB bridge connects to UART0 by default -- so you will need either: The firmware uses **UART0** for the NDJSON protocol. The ESP-IDF console is disabled (`CONFIG_ESP_CONSOLE_NONE=y`) so there is no conflict -- the firmware owns UART0 exclusively. No additional wiring or USB-UART adapters are needed.
1. A board that routes UART1 through the USB bridge (uncommon), or The dev board appears as `/dev/ttyUSB*` on the host. Use this device path for `ESP32_SERIAL_PORT`.
2. A separate USB-UART adapter connected to GPIO4/GPIO5 (described below)
For quick testing with the firmware's default pin assignment, connect a USB-UART adapter.
### Dedicated UART (GPIO4/GPIO5)
Connect a USB-UART adapter (e.g., FTDI FT232R, CP2102, CH340) to the ESP32:
```
ESP32 GPIO4 (TX) ----> USB-UART adapter RX
ESP32 GPIO5 (RX) <---- USB-UART adapter TX
ESP32 GND ----> USB-UART adapter GND
```
The adapter appears as a second `/dev/ttyUSB*` device on the host. Use this device path for `ESP32_SERIAL_PORT`.
Do not connect voltage lines (VCC/3V3) between the adapter and the ESP32 if the board is already powered via its own USB port.
### Pin reassignment
If GPIO4/GPIO5 conflict with other peripherals on your board, change the pin definitions in `firmware/main/uart_handler.c`:
```c
#define UART_TX_PIN GPIO_NUM_4
#define UART_RX_PIN GPIO_NUM_5
```
Rebuild and reflash after changing pins.
## ESP-IDF Setup ## ESP-IDF Setup
@ -115,13 +87,13 @@ make flash SERIAL_PORT=/dev/ttyUSB4
### 5. Monitor (optional) ### 5. Monitor (optional)
Open the ESP-IDF serial monitor to see console logs from UART0: Open the ESP-IDF serial monitor to watch raw UART traffic. Since the firmware owns UART0 (console is disabled), you will see NDJSON protocol messages rather than ESP-IDF log output:
```bash ```bash
idf.py -p /dev/ttyUSB4 monitor idf.py -p /dev/ttyUSB4 monitor
``` ```
Press `Ctrl+]` to exit the monitor. Press `Ctrl+]` to exit the monitor. Note: while the monitor is open, the MCP server cannot use the same serial port.
### 6. Flash and monitor in one step ### 6. Flash and monitor in one step
@ -184,13 +156,13 @@ The project ships `firmware/sdkconfig.defaults` with the required Bluetooth conf
| `CONFIG_BT_BLUEDROID_ENABLED` | y | Use Bluedroid host stack | | `CONFIG_BT_BLUEDROID_ENABLED` | y | Use Bluedroid host stack |
| `CONFIG_BT_CLASSIC_ENABLED` | y | Enable BR/EDR (Classic BT) | | `CONFIG_BT_CLASSIC_ENABLED` | y | Enable BR/EDR (Classic BT) |
| `CONFIG_BT_BLE_ENABLED` | y | Enable BLE | | `CONFIG_BT_BLE_ENABLED` | y | Enable BLE |
| `CONFIG_BT_SSP_ENABLED` | y | Enable Secure Simple Pairing |
| `CONFIG_BT_SPP_ENABLED` | y | Enable Serial Port Profile | | `CONFIG_BT_SPP_ENABLED` | y | Enable Serial Port Profile |
| `CONFIG_BT_GATTS_ENABLE` | y | Enable GATT Server | | `CONFIG_BT_GATTS_ENABLE` | y | Enable GATT Server |
| `CONFIG_BTDM_CTRL_MODE_BTDM` | y | Dual-mode controller (Classic + BLE simultaneously) | | `CONFIG_BTDM_CTRL_MODE_BTDM` | y | Dual-mode controller (Classic + BLE simultaneously) |
| `CONFIG_NVS_ENABLED` | y | Non-volatile storage for bonding data | | `CONFIG_ESP_CONSOLE_NONE` | y | Disable ESP-IDF console so firmware owns UART0 |
| `CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE` | y | 1.5MB app partition (dual-mode BT stack needs >1MB) |
Do not modify these unless you understand the implications. Disabling `CONFIG_BT_CLASSIC_ENABLED` breaks all Classic BT pairing tests. Disabling `CONFIG_BT_SSP_ENABLED` forces legacy PIN-only pairing. Do not modify these unless you understand the implications. Disabling `CONFIG_BT_CLASSIC_ENABLED` breaks all Classic BT pairing tests.
## Troubleshooting ## Troubleshooting
@ -232,13 +204,13 @@ If the board has auto-download circuitry (most DevKitC boards do), this should n
### No response over UART ### No response over UART
1. **Verify TX/RX pin assignment.** The firmware uses UART1 on GPIO4 (TX) and GPIO5 (RX). If your adapter is connected to different pins, update `uart_handler.c`. 1. **Check baud rate.** Both sides must use 115200. Verify in `screen` or your terminal emulator.
2. **Check baud rate.** Both sides must use 115200. Verify in `screen` or your terminal emulator. 2. **Make sure nothing else is using the port.** The ESP-IDF monitor, `screen`, another MCP server instance, or any other serial tool will lock the device. Only one process can open `/dev/ttyUSB*` at a time.
3. **Check the correct serial device.** If the board has two USB-UART interfaces (one for UART0 console, one for UART1 protocol), make sure you are talking to the right one. 3. **Send valid JSON.** The firmware expects complete JSON objects terminated by `\n`. A bare `ping` won't work -- send `{"type":"cmd","id":"1","cmd":"ping"}\n`.
4. **Look at UART0 console output.** Connect the ESP-IDF monitor to the console port. Boot messages and error logs appear there. If you see `UART1 ready (TX=4 RX=5 @ 115200 baud)` in the log, the firmware started correctly. 4. **Verify the firmware booted.** After flashing, the firmware should emit a `boot` event within ~2 seconds. If you see nothing at all, try pressing the EN (reset) button on the board.
### Build errors about missing Bluetooth headers ### Build errors about missing Bluetooth headers

View File

@ -8,7 +8,7 @@ Authoritative reference for the JSON-over-UART protocol used between the Python
- **Baud rate:** 115200 - **Baud rate:** 115200
- **Frame format:** 8N1 (8 data bits, no parity, 1 stop bit) - **Frame format:** 8N1 (8 data bits, no parity, 1 stop bit)
- **Max line length:** 2048 bytes (lines exceeding this are silently dropped) - **Max line length:** 2048 bytes (lines exceeding this are silently dropped)
- **UART peripheral:** ESP32 UART1 on GPIO4 (TX) and GPIO5 (RX), keeping UART0 free for ESP-IDF console logging - **UART peripheral:** ESP32 UART0 via the dev board's USB-to-UART bridge (TX=GPIO1, RX=GPIO3). ESP-IDF console is disabled (`CONFIG_ESP_CONSOLE_NONE=y`) so the firmware owns UART0 exclusively.
- **Encoding:** UTF-8 - **Encoding:** UTF-8
- **Newlines:** `\n` only. Carriage returns (`\r`) are stripped by the firmware reader. - **Newlines:** `\n` only. Carriage returns (`\r`) are stripped by the firmware reader.