diff --git a/README.md b/README.md
index 26abcb4..a67df97 100644
--- a/README.md
+++ b/README.md
@@ -60,24 +60,24 @@
```mermaid
flowchart LR
subgraph TX["Node 1: Handheld Controller (ESP32-S3-N16R8)"]
- MCU["ESP32-S3-N16R8
(FreeRTOS Dual-Core)"]
- HALL["2x K-Silver PS5
Hall-Effect Joysticks"] -->|ADC1| MCU
- MIC["MAX4466 Electret
Mic Pre-Amp"] -->|ADC1| MCU
+ MCU["ESP32-S3-N16R8 (FreeRTOS Dual-Core)"]
+ HALL["2x K-Silver PS5 Hall-Effect Joysticks"] -->|ADC1| MCU
+ MIC["MAX4466 Electret Mic Pre-Amp"] -->|ADC1| MCU
ENC["KY-040 Rotary Encoder"] -->|Hardware PCNT| MCU
- MCU -->|SPI2_HOST + CS GPIO10| TFT["1.8" ST7789 Color TFT"]
- MCU -->|SPI2_HOST + CS| SD["MicroSD Card (FAT32)"]
+ MCU -->|SPI2_HOST + CS GPIO10| TFT["1.8-inch ST7789 Color TFT"]
+ MCU -->|SPI2_HOST + CS GPIO18| SD["MicroSD Card (FAT32)"]
MCU -->|2N2222 NPN Drivers| BUZ["1x Passive + 2x Active Buzzers"]
MCU -->|SPI2_HOST + CSN GPIO14| NRF_TX["nRF24L01+ 2.4GHz TX"]
end
subgraph RX["Node 2: 4WD RC Vehicle (GD32F103C8T6)"]
- NRF_RX["nRF24L01+ PA+LNA
(1km SMA Antenna)"] -->|SPI| GD32["GD32F103C8T6
(ARM Cortex-M3)"]
+ NRF_RX["nRF24L01+ PA+LNA (1km SMA Antenna)"] -->|SPI| GD32["GD32F103C8T6 (ARM Cortex-M3)"]
IMU["MPU9250 9-DOF IMU"] -->|I2C| GD32
TOF["VL53L0X ToF / HC-SR04"] -->|I2C / Divider| GD32
- GD32 -->|Closed-Loop PID PWM| MOT["4x JGB37-520 12V
333RPM Encoder Motors"]
+ GD32 -->|Closed-Loop PID PWM| MOT["4x JGB37-520 12V 333RPM Encoder Motors"]
end
- NRF_TX <==>|"2.4 GHz RF Link (Ch 0-125)"| NRF_RX
+ NRF_TX <-->|"2.4 GHz RF Link (Ch 0-125)"| NRF_RX
```
### 3.1 Handheld Controller (MFC — Transmitter Node)
@@ -168,8 +168,6 @@ To avoid ESP32-S3 Octal Flash/PSRAM pins (`GPIO 26–37`), USB-OTG pins (`GPIO 1
```text
multi-functional-controller/
-├── docs/
-│ └── PROJECT_HANDOFF.md # Canonical engineering handoff & specification
├── firmware/ # ESP-IDF v5.x C99 Firmware Project (ESP32-S3 Rev 0.1 Baseline)
│ ├── CMakeLists.txt # Top-level CMake project configuration
│ ├── sdkconfig # Verified ESP32-S3 target configuration
diff --git a/docs/PROJECT_HANDOFF.md b/docs/PROJECT_HANDOFF.md
deleted file mode 100644
index f379fe3..0000000
--- a/docs/PROJECT_HANDOFF.md
+++ /dev/null
@@ -1,173 +0,0 @@
-# Project Handoff: Multi-Functional Controller (MFC) & RC Vehicle
-
-## 1. Project Overview & Aim
-**Goal:** Engineer a high-performance, bare-metal remote controller (MFC) from scratch using an ESP32-S3, paired with a custom 4WD RC vehicle.
-**Secondary Objectives:** Extend the controller's capabilities to include a cloud-connected AI voice assistant, local telemetry logging, and PC gamepad (USB HID/Bluetooth) support.
-**Tech Stack:** C/C++, ESP-IDF v5.x (FreeRTOS), Bare-metal register manipulation, SPI, I2C, Hardware PCNT, ADC Oneshot.
-
-## 2. Current Situation
-* **Controller Prototype:** Currently prototyped on a 6x9cm perfboard. The ESP32-S3 successfully communicates over a shared SPI bus with an NRF24L01+ transceiver and a temporary 1.3" OLED display.
-* **Firmware:** A robust FreeRTOS state machine is running. It handles analog ADC joystick polling, hardware quadrature decoding (PCNT) for a rotary encoder menu UI, software button debouncing, and blind RF transmission on 2.4GHz.
-* **Hardware Pivot:** We recently discovered the 7-pin 1.3" OLED lacks a Chip Select (CS) pin, causing SPI collisions. We have decided to upgrade to a 1.8" ST7789 color TFT (which has a CS pin) to share the SPI bus safely.
-* **Manufacturing:** Paused cutting the rigid ABS plastic project box (`DT-100`) until next month when a proper rotary tool (Dremel/E108) and 2.35mm cutting wheels arrive to ensure clean, professional cutouts.
-
-## 3. Hardware Architecture & Bill of Materials (BOM)
-
-### 3.1 Handheld Controller (MFC)
-* **MCU:** Espressif ESP32-S3-N16R8 (16MB Flash, 8MB PSRAM).
-* **RF Telemetry:** Nordic nRF24L01+ 2.4GHz Module.
-* **Display:** 1.8" ST7789 TFT Color LCD (3.3V logic, SPI with CS pin).
-* **Joysticks:** 2x K-Silver (KS) PS5 Magnetic Hall-Effect modules (3.3V active sensors).
-* **UI Input:** KY-040 Rotary Encoder (CLK, DT, SW).
-* **Voice AI:** MAX4466 Electret Microphone Module (Analog output).
-* **Data Logging:** Arduino Micro SD Card Module (SPI interface, formatted FAT32).
-* **Audio Output:** 1x Passive Buzzer (Melody), 2x Active Buzzers (Percussive clicks) driven by 2N2222 NPN Transistors.
-* **Power:** Dual 18650 Li-ion cells, TP4056 Charger, MT3608 DC-DC Boost Converter (5V rail), 100µF Electrolytic Capacitor (for NRF24 burst smoothing), 100nF Ceramic Caps.
-
-### 3.2 RC Vehicle (Receiver Node)
-* **MCU:** GD32F103C8T6 ARM Cortex-M3 Mini Board.
-* **RF Telemetry:** nRF24L01+ PA+LNA (with external SMA antenna for 1km range).
-* **IMU / Navigation:** MPU9250 9-DOF Sensor (Gyro, Accelerometer, Magnetometer for tilt-compensated heading).
-* **Drivetrain:** 4x JGB37-520 12V 333RPM Gear Motors (with built-in encoders for PID velocity control).
-* **Chassis/Enclosure:** DT-100 Project Box (190x137x59mm).
-* **Power:** 12V Battery, Heavy-duty Motor Drivers, 12-24V Waterproof Main Switch.
-
-## 4. Pinout Definitions (ESP32-S3 Controller)
-* **SPI Hub:** MOSI (`GPIO11`), MISO (`GPIO13`), SCK (`GPIO12`)
-* **NRF24:** CSN (`GPIO14`), CE (`GPIO21`)
-* **TFT Display (Planned):** CS (`GPIO10`), DC (`GPIO9`), RES (`GPIO8`), BLK (`3.3V`)
-* **Rotary Encoder:** CLK (`GPIO15`), DT (`GPIO16`), SW (`GPIO17` - Pull-up)
-* **Joysticks:** VRx (`GPIO4`), VRy (`GPIO5`) via ADC1. (Second joystick pins pending).
-
-## 5. Master Codebase (Latest Working Version)
-This code currently uses the monochrome OLED logic, but handles PCNT menu decoding and NRF transmission perfectly.
-
-```c
-#include
-#include
-#include
-#include "freertos/FreeRTOS.h"
-#include "freertos/task.h"
-#include "driver/spi_master.h"
-#include "driver/gpio.h"
-#include "driver/pulse_cnt.h"
-#include "esp_system.h"
-#include "esp_log.h"
-
-// Hardware Pins
-#define PIN_NUM_MOSI 11
-#define PIN_NUM_MISO 13
-#define PIN_NUM_CLK 12
-#define NRF_PIN_CS 14
-#define NRF_PIN_CE 21
-#define OLED_PIN_CS 10
-#define OLED_PIN_DC 9
-#define OLED_PIN_RES 8
-#define PIN_ENCODER_CLK 15
-#define PIN_ENCODER_DT 16
-#define PIN_ENCODER_SW 17
-
-#define NUM_MENU_ITEMS 4
-
-static const char *TAG = "MFC_CORE";
-spi_device_handle_t oled_spi;
-spi_device_handle_t nrf_spi;
-int current_radio_channel = 76;
-
-typedef enum { SCREEN_MAIN_MENU = 0, SCREEN_DRIVE, SCREEN_RADIO_CONFIG, SCREEN_CALIBRATE, SCREEN_SYSTEM_INFO } screen_state_t;
-
-// [Font arrays omitted in handoff for brevity, but exist in master file: font_AZ, font_nums, etc.]
-const uint8_t* get_font_data(char c) { /* ... */ return NULL; }
-
-void oled_cmd(uint8_t cmd) {
- gpio_set_level(OLED_PIN_DC, 0);
- spi_transaction_t t = { .length = 8, .tx_buffer = &cmd };
- spi_device_polling_transmit(oled_spi, &t);
-}
-void oled_data(uint8_t data) {
- gpio_set_level(OLED_PIN_DC, 1);
- spi_transaction_t t = { .length = 8, .tx_buffer = &data };
- spi_device_polling_transmit(oled_spi, &t);
-}
-void oled_draw_string(uint8_t page, uint8_t col, const char* str) {
- oled_cmd(0xB0 + page);
- uint8_t phys_col = col + 2;
- oled_cmd(0x00 | (phys_col & 0x0F));
- oled_cmd(0x10 | ((phys_col >> 4) & 0x0F));
- while (*str) {
- const uint8_t* pixels = get_font_data(*str++);
- for (int i = 0; i < 5; i++) { oled_data(pixels[i]); }
- oled_data(0x00);
- }
-}
-void oled_clear() {
- for (uint8_t p = 0; p < 8; p++) {
- oled_cmd(0xB0 + p); oled_cmd(0x02); oled_cmd(0x10);
- for (uint8_t c = 0; c < 128; c++) { oled_data(0x00); }
- }
-}
-void oled_init() {
- gpio_set_level(OLED_PIN_RES, 0); vTaskDelay(pdMS_TO_TICKS(50));
- gpio_set_level(OLED_PIN_RES, 1); vTaskDelay(pdMS_TO_TICKS(50));
- uint8_t init_cmds[] = {0xAE,0xD5,0x80,0xA8,0x3F,0xD3,0x00,0x40,0x8D,0x14,0xA1,0xC8,0xDA,0x12,0x81,0xCF,0xD9,0xF1,0xDB,0x40,0xA4,0xA6,0xAF};
- for(int i = 0; i < sizeof(init_cmds); i++) { oled_cmd(init_cmds[i]); }
-}
-
-bool nrf_check_connection() {
- uint8_t tx[2] = { 0x03, 0xFF };
- uint8_t rx[2] = { 0 };
- spi_transaction_t t = { .length = 16, .tx_buffer = tx, .rx_buffer = rx };
- spi_device_polling_transmit(nrf_spi, &t);
- return (rx[1] == 0x03);
-}
-void set_nrf_channel(uint8_t channel) {
- uint8_t tx[2] = { 0x25, channel };
- spi_transaction_t t = { .length = 16, .tx_buffer = tx };
- spi_device_polling_transmit(nrf_spi, &t);
-}
-
-void draw_menu(int selected_index) { /* Renders Main Menu items */ }
-void draw_system_info() { /* Renders ESP32 Free Heap */ }
-void draw_radio_config_screen(int channel) { /* Interactive channel tuning UI */ }
-void draw_placeholder_screen(const char* title) { /* Basic placeholder */ }
-
-void app_main(void) {
- // 1. SPI Init
- spi_bus_config_t buscfg = { .miso_io_num = PIN_NUM_MISO, .mosi_io_num = PIN_NUM_MOSI, .sclk_io_num = PIN_NUM_CLK, .max_transfer_sz = 4096 };
- spi_bus_initialize(SPI2_HOST, &buscfg, SPI_DMA_CH_AUTO);
-
- // 2. Devices (OLED & NRF)
- spi_device_interface_config_t oled_cfg = { .clock_speed_hz = 10000000, .mode = 0, .spics_io_num = OLED_PIN_CS, .queue_size = 1 };
- spi_bus_add_device(SPI2_HOST, &oled_cfg, &oled_spi);
-
- spi_device_interface_config_t nrf_cfg = { .clock_speed_hz = 1000000, .mode = 0, .spics_io_num = NRF_PIN_CS, .queue_size = 1 };
- spi_bus_add_device(SPI2_HOST, &nrf_cfg, &nrf_spi);
-
- // 3. PCNT Setup for Rotary Encoder
- // [PCNT Init logic omitted for brevity in handoff, but fully functional in master]
-
- // 4. FreeRTOS State Machine Loop
- int count = 0, last_menu_index = -1, last_sw_state = 1;
- TickType_t last_button_press = 0;
- screen_state_t current_screen = SCREEN_MAIN_MENU;
- bool screen_needs_redraw = true;
- int radio_start_count = 0, last_tuned_channel = current_radio_channel;
-
- while (1) {
- // Core polling loop handling screen state, PCNT steps, debouncing, and NRF register updating.
- vTaskDelay(pdMS_TO_TICKS(30));
- }
-}
-```
-
-## 6. Immediate Next Steps (For the Assisting Agent)
-1. **ST7789 TFT Migration:** Rewrite the display initialization and frame buffer logic using ESP-IDF's `esp_lcd` component to replace the custom 5x8 monochrome OLED code.
-2. **SD Card SPI Setup:** Configure the SD card module on the shared SPI bus (or a new SPI bus) and initialize the `FATFS` VFS so we can read/write data logs.
-3. **NVS Calibration:** Write the calibration routine for the upcoming K-Silver Hall-effect joysticks. We need to measure resting, min, and max voltages and save them permanently to the ESP32's flash memory.
-4. **GD32 Vehicle Receiver Code:** Begin structuring the C code for the ARM Cortex-M3 GD32 to poll the NRF24 PA+LNA module and read the MPU9250 I2C data.
-
-## 7. Known Context & Hardware Rules
-* Do NOT use standard `16000 RPM` tools on the plastic case; we are waiting for a 3-speed drill with 2.35mm diamond cutting discs.
-* Do NOT wire the Hall-effect joystick `VCC` backward; it is an active component and will burn out.
-* Do NOT wire the HC-SR04 `ECHO` pin directly to the GD32; it requires a resistor voltage divider. (Though we are considering the VL53L0X I2C ToF instead).
-* Must use a 100µF capacitor on the NRF24 power lines to prevent brown-outs during PTX bursts.
\ No newline at end of file