From e639056ee82479d48c0cfc6e77fd83e76fd63403 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Fri, 13 Feb 2026 05:49:34 -0700 Subject: [PATCH] Update library metadata and docs for AutoWire multi-protocol support - library.json: renamed to AutoWire, added obd2/kline/iso9141/14230 keywords - CLAUDE.md: documented composition architecture, OBD-II scanner build, updated project overview and roadmap for dual-protocol support --- CLAUDE.md | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 100 insertions(+), 7 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index ae66abe..9e4b9aa 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,4 +1,4 @@ -# BMW I-Bus / K-Bus Interface Board (ESP32, Optocoupler Isolated) +# AutoWire — Multi-Protocol Automotive Bus Interface (ESP32) ## Attribution @@ -6,9 +6,11 @@ Circuit design and protocol library based on **[muki01/I-K_Bus](https://github.c ## Project Overview -Interface board for BMW I-Bus (Instrumentation Bus) and K-Bus (Body Bus) communication. Uses an ESP32 with PC817 optocouplers for galvanic isolation from the vehicle's electrical system. +Multi-protocol automotive bus library for ESP32. Supports **BMW I/K-Bus** (optocoupler isolated) and **OBD-II K-line** (ISO 9141 / ISO 14230). Both protocols share the same physical layer (single-wire, half-duplex, open-collector/drain) but differ in framing, baud rate, checksum, and bus access model. -**This is NOT the same as OBD-II K-line.** The Tucker project (`~/claude/tucker/k-line-board/`) handles ISO 9141/14230 OBD diagnostics using a transistor-based interface. This project targets BMW's proprietary body/instrumentation bus for module control (lights, windows, locks, multimedia). +**BMW I/K-Bus:** Module control on E31/E38/E39/E46/E53/E83/E85/E87 — lights, windows, locks, multimedia. Uses PC817 optocouplers for galvanic isolation from the vehicle's electrical system. + +**OBD-II K-line:** Standard diagnostic protocol (ISO 9141/14230) for reading PIDs, clearing DTCs, and ECU communication. Used on Ford Fiesta (Tucker project) and other ISO 9141/14230 vehicles. Can use either transistor or optocoupler interface. ### Protocol Comparison: BMW I/K-Bus vs OBD-II K-line @@ -305,6 +307,86 @@ The repo includes an extensive documentation collection (`Docs/`): - **BMW Communication Codes/** — 12 files with I-Bus message codes for E39/E46 - **HackTheIBus/** — 21 PDFs covering individual module protocols (IKE, LCM, MFL, EWS, DSP, etc.) +## Firmware + +PlatformIO project in `firmware/` — builds for ESP32, ESP32-C3, ESP32-S3, and OBD-II scanner. + +``` +firmware/ +├── platformio.ini # 4 environments (BMW sniffer x3, OBD-II scanner) +├── include/config.h # Pin defaults + protocol constants (IBUS_* and KLINE_*) +├── lib/AutoWire/ +│ ├── library.json # PlatformIO lib metadata (v2026.02.13) +│ ├── KLineTransport.h / .cpp # Hardware transport (UART, ISR, ring buffers, idle detect) +│ ├── IbusHandler.h / .cpp # BMW I/K-Bus FSM (FIND_SOURCE -> checksum validation) +│ ├── IbusEsp32.h / .cpp # Backward-compatible facade (wraps Transport + Handler) +│ ├── KLineObd2.h / .cpp # OBD-II K-line handler (slow init, fast init, PID requests) +│ ├── Obd2Pids.h # OBD-II PID constants + SAE J1979 decode helpers +│ ├── RingBuffer.h / .cpp # Circular buffer with bounds-checked remove/peek +│ └── E46Codes.h # ~100 BMW E46 command arrays in namespace ibus{} +└── src/ + ├── main.cpp # BMW I/K-Bus sniffer with module name lookup + └── obd2_scanner.cpp # OBD-II scanner (RPM, speed, coolant, throttle, voltage) +``` + +### Architecture + +``` + +-----------------+ + | KLineTransport | <-- UART, GPIO ISR, ring buffers, idle detection + +-----------------+ + / \ + +------------+ +------------+ + | IbusHandler| | KLineObd2 | <-- Protocol-specific FSMs + +------------+ +------------+ + | + +------------+ + | IbusEsp32 | <-- Backward-compatible facade + +------------+ +``` + +**KLineTransport** owns the hardware: UART init, TX/RX ring buffers, GPIO ISR for idle detection, TX inversion, configurable baud/framing/checksum. Protocol-agnostic. + +**IbusHandler** is the BMW I/K-Bus FSM — reads from transport's RX ring, validates XOR checksum, applies source filter, delivers packets via callback. + +**KLineObd2** is the OBD-II handler — 5-baud slow init (bit-bang), fast init (TiniPulse), request/response framing with half-duplex echo clearing, PID convenience wrapper. + +**IbusEsp32** is preserved as a thin facade so existing BMW sniffer code needs zero changes. + +### Building + +```bash +cd firmware +pio run # build default BMW sniffer (esp32dev) +pio run -e esp32-c3 # build BMW sniffer for ESP32-C3 +pio run -e esp32-s3 # build BMW sniffer for ESP32-S3 +pio run -e obd2-scanner # build OBD-II scanner +pio run -t upload # flash to connected board +pio device monitor # serial monitor at 115200 +``` + +### Key Porting Decisions (AVR -> ESP32) + +| AVR Feature | ESP32 Replacement | +|---|---| +| Timer2 CTC (1.5ms idle) | `esp_timer` periodic 250us + RX pin GPIO interrupt | +| TH3122 SEN/STA pin | GPIO interrupt on UART RX pin (CHANGE) | +| SoftwareSerial debug | Serial (UART0, USB) at 115200 | +| `PROGMEM` / `pgm_read_byte()` | Plain `const` arrays (flash is memory-mapped) | +| TH3122 EN pin sleep | Not ported (no transceiver to disable) | +| Global volatile state | Class members with `volatile` where ISR-shared | +| Hardcoded source filter | Configurable filter, default OFF (sniffer mode) | +| TX signal (for TH3122) | `uart_set_line_inverse(UART_SIGNAL_TXD_INV)` for optocoupler | + +### Defensive Design (Post-Review Fixes) + +- **Atomic timestamps**: `_lastRxTransitionUs` is `uint32_t` (not `int64_t`) — atomic reads on 32-bit CPUs, prevents torn reads between GPIO ISR and timer callback +- **TX loopback race**: idle timer reset BEFORE clearing `_isTransmitting`, with compiler memory barrier (`__asm__ volatile("" ::: "memory")`) +- **Atomic TX writes**: `write()` checks free space before writing any bytes — entire message fits or entire message is dropped, no partial packets +- **Ring buffer bounds**: `remove()` clamps to `available()`, `peek(n)` validates against `available()`, `malloc` failure sets `_size=0` +- **FSM timeout**: `FIND_MESSAGE` state has 100ms timeout to prevent parser stall on partial messages (bus glitch, sender crash) +- **TX corruption recovery**: corrupt length in TX ring flushes entire buffer; underrun mid-packet aborts TX cleanly + ## What's Been Done 1. Optocoupler schematic analyzed (RX path, TX path, isolation topology) @@ -313,13 +395,24 @@ The repo includes an extensive documentation collection (`Docs/`): 4. Module address map and message format documented 5. **SPICE simulation validated** — both RX and TX paths simulated with LTspice PC817 model at 9600 baud. RX path gives clean 0-3.13V logic at 3.3V VCC. TX path confirms signal inversion and 0.27V bus LOW on 1kΩ bus. Rise/fall times within 9600 baud budget. 6. **R2 optimized for 3.3V** — parameter sweeps across R2, bus impedance, and CTR grade identified R2=220Ω (down from 470Ω) as the fix for 3.3V ESP32. Doubles LED drive current to 9.71mA, supports bus pull-ups down to ~530Ω. +7. **IbusSerial ported to ESP32** — PlatformIO project with IbusEsp32 library. Bus sniffer sketch included. Builds for ESP32, ESP32-C3, ESP32-S3. Code reviewed for ISR safety, race conditions, buffer overflows. +8. **Multi-protocol refactor (AutoWire)** — split monolithic IbusEsp32 into KLineTransport (hardware) + IbusHandler (BMW FSM). Library renamed from IbusEsp32 to AutoWire. IbusEsp32 preserved as backward-compatible facade. Zero changes to existing BMW sniffer sketch. +9. **OBD-II K-line support** — KLineObd2 handler with ISO 9141 5-baud slow init, ISO 14230 fast init (TiniPulse), request/response with half-duplex echo clearing. Obd2Pids.h with ~20 common PID decode helpers (SAE J1979). Scanner example sketch polls RPM, speed, coolant temp, throttle, voltage. ## What's Next -1. **Port IbusSerial** library to ESP32 (replace AVR Timer2, adapt pin config) -2. **Breadboard** prototype with PC817 + BC547 + ESP32 -3. **Test** on BMW E46 K-Bus (CD changer connector in trunk) -4. **Build** command library for target features (lights, locks, windows) +### BMW I/K-Bus +1. **Breadboard** prototype with PC817 + BC547 + ESP32 +2. **Loopback test** — wire TX→RX, verify `write()` → callback round-trip +3. **Bench test** — 12V supply + 1kΩ pull-up, inject bytes from USB-UART at 9600 8E1 +4. **Test** on BMW E46 K-Bus (CD changer connector in trunk, key position 1) +5. **Build** command library for target features (goodbye lights, follow-me-home, etc.) + +### OBD-II K-line +1. **Loopback test** — wire TX→RX, verify 5-baud init bit pattern with logic analyzer +2. **Bench test** — USB-UART adapter simulating ECU responses (sync byte + keywords) +3. **Vehicle test** — Tucker k-line-board hardware on Ford Fiesta, key-on, slow init, read RPM PID +4. **DTC support** — Mode 03 (read DTCs) and Mode 04 (clear DTCs) with human-readable decode ## Safety Notes