Commit tune maps and research so tunes are reachable from the phone

Removes the *.hex/maps_cache gitignore rule (explicit user call, reversing
the earlier no-redistribution stance) so the official TuneECU catalogue
maps, derived SAI/O2-delete composites, and the checksum/composition
tooling are actually available to pull up on a phone browser when using
the real TuneECU app. Also folds in tonight's KWP2000 fixes (TesterPresent
keep-alive, connect-failure cleanup, slow-init StartCommunication fix) and
the accumulated research docs.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FP2GaxS9HkUdL5sLBnjKje
This commit is contained in:
2026-08-27 01:34:05 -05:00
parent 587f75eab4
commit 4aa5da53d2
98 changed files with 4148 additions and 49 deletions

172
tunie/FIRST_READ.md Normal file
View File

@@ -0,0 +1,172 @@
# First ECU read (KKL cable) — offline quick reference
Pull this up locally, no signal needed. Everything here is already known/
confirmed as of tonight (2026-08-26) — nothing depends on being online.
Bluetooth (vLinker MC+) is parked for now: it needed a full unpair/re-pair
after nearly every attempt tonight (likely the adapter's own KWP firmware,
not something software fixes) — the KKL cable sidesteps that whole class
of problem, which is why it's next.
## ⚠ Current KKL cable (`/dev/cu.usbserial-A50285BI`) — confirmed bad, 2026-08-26
Both fast and slow init failed in a way that points at the cable itself,
not wiring/pinout/software:
- **Fast init**: `timed out waiting for 1 bytes, got 0 (none)` — failed at
the very first echo check, right after transmitting. K-Line is
half-duplex: your own transmission always echoes back on a working
line. Zero bytes back, not even the echo, means RX isn't picking up
anything at all.
- **Slow init**: `expected sync byte 0x55, got 00` — not silence this
time, a real `0x00` byte. Consistent with RX stuck permanently low
(a UART can't frame a start bit without a high→low transition, so a
dead-low line reads back as a stream of `0x00`s).
Both symptoms match a well-known, common failure mode for cheap
"VAG-COM 409.1 KKL" cables: a bare FTDI FT232R with **no real K-Line
transceiver chip** (should be something like an L9637) actually soldered
in. TX may weakly drive the line, but RX never sees a clean signal,
including its own echo. Nothing in `tunie`'s K-Line code looks suspect —
echo-consumption and 5-baud timing both match spec exactly.
**Before writing this cable off for good**, one more isolated check next
time it's plugged in — independent of any init timing:
```sh
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3.10 -m tunie.cli raw --port /dev/cu.usbserial-A50285BI --baud 10400 --command AA --hex
```
If that returns nothing at all, that's about as clean a "cable is dead"
confirmation as possible without a scope — worth getting a known-good
KKL cable (or leaning on the Bluetooth path / TuneECU's own bundled
cable) rather than continuing to debug this one in software.
## Before you plug anything in
- [ ] **Connector location and shape checked.** Real accounts from other
owners on this same ECU family describe it as a standard **16-pin
OBD-II-style plug, in front of the fusebox, behind the tank, no tools
needed**. If it matches, plug in directly. **If it looks different/
smaller/non-standard, stop** — that's the one real electrical risk here.
- [ ] **Pull the headlight AND taillight fuses before connecting anything**
— protects the battery (Keihin ECUs are sensitive to voltage drop) and
doubles as a safety interlock. Fuse numbers are bike-specific, check the
fusebox cover.
- [ ] Battery tender/maintainer connected (a real smart tender, not a bare
trickle charger).
- [ ] Ignition **on**, engine **off**. Kill switch in run position.
- [ ] KKL cable plugged in.
## Step 1 — confirm the port shows up
```sh
cd /Users/dylan/dojo/samplez/tunie
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3.10 -m tunie.cli ports
```
Look for an FTDI/USB-serial entry (last confirmed working port this
session: `/dev/cu.usbserial-A50285BI` — but ports can renumber, trust
what this actually prints over memory). If nothing FTDI-looking shows up,
stop here — that's a driver/cable problem, not a bike problem.
## Step 2 — raw wiring smoke test (new tonight, do this before `info`)
K-Line is half-duplex: anything you write is normally echoed straight
back over the wire if the adapter and wiring are electrically sound. This
new `tunie raw` command proves that *before* risking a real protocol
handshake:
```sh
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3.10 -m tunie.cli raw --port /dev/cu.usbserial-A50285BI --baud 10400 --command ATZ
```
- **Exact echo of `ATZ` comes back** → wiring/pinout/adapter proven sound.
This is the *good* result for K-Line (unlike Bluetooth, where an echo
would mean something else). Move on to Step 3.
- **Nothing comes back at all** → wiring/pinout/driver issue. Don't bother
with `info` yet — recheck the connector, recheck `tunie ports`, confirm
the FTDI driver is actually bound to that device.
## Step 3 — the real read
```sh
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3.10 -m tunie.cli info --port /dev/cu.usbserial-A50285BI --adapter kline --retries 5
```
If fast init times out, slow init is a normal fallback, not a sign of a
deeper problem:
```sh
/Library/Frameworks/Python.framework/Versions/3.10/bin/python3.10 -m tunie.cli info --port /dev/cu.usbserial-A50285BI --adapter kline --init slow --retries 5
```
Add `-v` before `info` (i.e. `tunie.cli -v info ...`) if you want every
raw frame logged — only useful for troubleshooting a failed connection.
## What changed tonight (fixed, already in the code you'll be running)
- `tunie` now sends a `TesterPresent` keep-alive between every read during
the interrogation sweep, so a long scan can't let the ECU's diagnostic
session lapse partway through (this was a real bug, found by tracing
TuneECU's own decompiled code — `m.java`'s `hd()` does the same thing).
- Connection cleanup now always runs even when every retry fails — no
more stale handles left open after a failed attempt.
- Bad-port errors are now a clean message, not a raw Python traceback.
None of tonight's fixes were K-Line-specific bugs (they were mostly found
chasing the Bluetooth adapter), but they all apply to this path too and
none of them introduced anything new to worry about — `tests/verify_protocol.py`
passes clean as of the last edit.
## How you'll know it's done
Normal synchronous command — no background process. It prints a result
(success or a friendly error) and returns you to the shell prompt.
**Prompt back = done.** A few seconds to ~30s, longer if retries kick in.
Retries are automatic and visible:
```
Attempt 1/5 failed (...); retrying in 5s...
```
This does **not** power-cycle the bike for you — if all retries fail,
that's the signal a real ignition off/on cycle is worth trying, not just
re-running the command again.
Every run writes its own timestamped file to `tunie/logs/` regardless of
outcome:
```
(full session log: logs/tunie-info-20260826-201432.txt)
```
`ls -t logs/` shows the newest one first if you lose track.
## Reading the output
- **"Queries that did not answer" is normal**, not a failure — the sweep
deliberately probes a range of manufacturer-defined record numbers.
- **The record under `0x94`** (software part number) is what to
cross-check afterward against `maps.json` to confirm exactly which
stock calibration is on the bike.
- **DTCs will most likely say "none reported"** unless something's
actually faulting right now.
## If the connection won't work
In order:
1. Ignition on, engine off — the ECU sleeps otherwise, most common miss.
2. Re-check the connector pinout before suspecting anything else.
3. Try `--init slow` if fast init times out (Step 3 above).
4. Real ignition off/on power cycle if software retries don't help.
5. If `raw` in Step 2 got nothing back at all, this is a wiring/adapter
problem — no amount of retrying `info` will fix that on its own.
## While you're at it
- **Watch the battery voltage manually** — `tunie` doesn't read/display
it. Multimeter on the terminals, or the bike's dash if it shows one.
Below ~12.5V connection attempts get flaky; ~12.2V is the "stop and
recharge" point.
- Multiple attempts before success is normal — don't read one failed try
as a real problem.
## After you're done
Turn ignition off. Bring the log file back — paste its contents into a
conversation with me, or just tell me the map ID under `0x94` and I'll
cross-check it against `maps.json` directly.