Files
samplez/tunie/docs/ROADMAP.md
uhryniuk 4aa5da53d2 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
2026-08-27 01:34:05 -05:00

165 lines
9.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# tunie — roadmap: open-sourcing + what's next
Two tracks: **getting this into a shippable open-source project**, and the
**technical work** still needed to actually tune the bike. Read
[CONTEXT.md](CONTEXT.md) first for the full state.
---
## Track A — open-sourcing
The code is original; the risk in publishing is the **third-party derived data**
and the **flashing capability**. Handle these deliberately before a public repo.
### A1. Legal / IP (do this first)
- **No proprietary binaries in the repo.** Already enforced: `*.hex`, `*.dec.bin`,
`maps_cache/`, `table_map.json` are gitignored. Keep it that way — map files are
Triumph/TuneECU calibration data and must not be redistributed.
- **APK-derived data** (`maps.json`, `mapdefs.json`, embedded `c.a`/`s.a`, the AES
keys, protocol constants) are facts extracted for **interoperability**. Frame the
project explicitly as independent interoperability research on hardware you own.
Add a clear NOTICE describing what's derived and why, and cite that it contains
no TuneECU source.
- **The AES seed/key** enables writing to the ECU. Decide the posture: keep the
key/flashing material in a clearly-separated `research/` area with a warning, or
gate the write path behind an explicit build flag. Do not make bricking a
one-liner.
- **License:** pick one (MIT/Apache-2.0 for the tool; note that embedded
extracted constants are facts, not licensed code). Add `LICENSE` and a top-level
legal/README section.
### A2. Repo hygiene
- Move `tunie/` out of the `samplez` grab-bag into its **own repo** for a real
project (keep samplez as the scratch mirror if you like).
- Add: `CONTRIBUTING.md`, `SECURITY.md` (responsible-disclosure + "don't flash
blindly" warning), issue templates, a CHANGELOG.
- Reproducible builds: pin deps, document `build_viewer.py` inputs (needs a
decompiled APK the repo can't ship — document how to produce it, don't include it).
### A3. Packaging & CI
- `pip install tunie` — the `pyproject.toml` is already there; add a wheel build.
- CI: run `tests/verify_protocol.py` + the reference-map self-tests (`decode_map.py`,
`reconstruct_rom.py`, `table_map.py` — but those need map binaries, so gate them
behind a locally-provided fixtures dir / skip in public CI).
- Lint/format (ruff/black), type-check (mypy) the `src/tunie` package.
### A4. Docs & polish
- A real top-level README with a quickstart, the safety stance, and a screenshot.
- Host the viewer as a static page (it's a single self-contained file).
- Turn `docs/CONTEXT.md` into a short "how the format works" explainer — it's
genuinely novel RE and good for the project's credibility.
### A5. Community
- The SuperH ECU community (npkern/FastECU/ScoobyRom authors, TunerPro forums,
triumphrat) is the natural audience. A working open Keihin decrypt + table map is
a real contribution. Coordinate rather than surprise — some of this overlaps
commercial XDF vendors.
---
## Track B — technical, to actually tune the bike
Ordered by dependency. Phases 1–2 are safe reads; 3+ is the write path.
### B1. First contact (READ) — the current blocker
1. Identify the VAG KKL chip (`tunie ports`); install CH340 driver if needed.
2. **Confirm the Triumph diagnostic-connector pinout** and build the adapter
(K-Line + switched 12V + ground). *This is the one real electrical risk.*
3. `tunie info` — read ECU ID, current map, DTCs. Confirms which stock map is on
the bike (should be 20187/20191 for production silencers, mechanical odo).
### B2. ROM dump (READ, deliberate)
- Enable `0x35` RequestUpload (currently blocked in the read-only tool) to dump the
stock ROM as a recovery image. Do this before any write work.
- Cross-check the dump against our decrypt/unpack: a stock dump should reconstruct
to the same flat ROM as the matching `.hex`, validating the whole pipeline on the
real bike's data.
- **Before implementing this ourselves, reverse-engineer TuneECU's own Recovery
mode first** (Aug 2026 finding, `../research/TUNING_IMPL_PLAN.md`): TuneECU has
a dedicated Recovery function (`menu_recovery` in the decompile, dispatched
through the same mode-switch machinery as the rest of `m.java`'s `Ue()`), with a
multi-year, multi-ECU-family bug-fix history in the app's own changelog (5DM/7SM,
Dorsoduro/Shiver 750, Walbro, Ducati recovery bugs fixed 2019-2021) — real
evidence this isn't a trivial retry loop, it's hardened against failure modes
only discoverable across many real units. Extracting and understanding that
procedure statically, before ever attempting our own upload/write path on the
one ECU we have, meaningfully de-risks this phase. **Near-term (not blocked on
this):** use TuneECU's own app's "Read Map" for the actual first dump — this
reverse-engineering is prep for when `tunie` builds its own upload path for
real, not a prerequisite for getting one file off the bike today.
### B3. Finish the calibration model
- **Absolute scaling** for fuel and ignition (units), via an XDF cross-check (~€70
OldSkull/Tuniverse) or more RE of `Nc`/`Lb`. Relative editing already works.
- **AFR table** dimensions/axes (partly reversed; 128 = λ1.00 confirmed).
- **Remaining device flags** (exhaust valve, air flap…) — needs the `x.a()` device
layout reverse (`x.t/x.s/x.q` for i27=72) or more single-mod reference maps.
- Individual **SAI-vs-O2** isolation — only matters if hand-editing flags; the
owner's path (a complete AIRBOXBONNY-style map) sidesteps it.
### B4. Write / flash path (the risky part — bench first)
- Port the **flash kernel**: `fenugrec/npkern` explicitly lists SH7054 (untested) —
the strongest lead. `miikasyvanen/FastECU` shows a full end-to-end flow.
- Finish **seed/key**: which of the 3 AES keys + the seed-block padding (one
captured pair from the bike/logging APK settles it).
- ~~**ECU flash checksum** at write time.~~ **Solved, Aug 2026** — see
`../research/reference-maps/checksum.py`. 16-bit sum-of-words over the
flat-ROM calibration region (`0x50000`-`0x60000`, the same range this
project's own `table_map.py` already uses), stored in the region's last 2
bytes. Validated against 6 real, unmodified, official downloads —
computed matches stored, exact, every time. **Caveat that keeps this from
being "done done":** this is the *app-side* checksum TuneECU computes for
its own map-info display (flags "*No-OEM"/"Error" on mismatch) —
confirmed it's not a hard gate on its own, since a real community file
with a stale (unrecomputed) checksum apparently still worked for people.
Whether the ECU's own bootloader *also* independently verifies something
during the actual `0x36` TransferData sequence is a separate, still-open
question — this solves "how do I produce a checksum TuneECU accepts as
valid," not necessarily "the ECU's own integrity check."
- **Head start already done (Aug 2026):** `../research/WRITE_PATH.md` traced
TuneECU's actual shared write/reprogram routine from the mode-flag entry
point down through the connection/retry driver into a 5-baud slow-init
bit-bang for the Triumph K-line address (`0xD5`) — real protocol detail,
not a plan. Traced as far as the post-slow-init handoff (unopened). Read
that before starting this section for real; it's ahead-of-time
reconnaissance done opportunistically while tracing Recovery mode
(`../research/RECOVERY_MODE.md`), not yet validated against a live ECU.
- **Recovery**: `v-ladimir/audprog` (AUD debugger) for SH705x un-brick via the PCB
debug pins — mandatory backstop when developing a flasher.
- Develop against a **spare/bench ECU**, on a stable supply, never the bike's only
ECU, and validate output against TuneECU before trusting our own writes.
### B5. Editor completion
- Full flat-ROM edit → re-pack → `dc`-encode → `.hex` for **arbitrary** table edits
(device flags already round-trip; generalize to any chunk + fix the edit
checksum).
- In-viewer table editing with axes + a wideband/dyno-oriented diff workflow.
### B6. The owner's actual goal
2-1 exhaust + airbox removal + O2 + SAI delete:
1. Base on `20188Map2009AIRBOXBONNY` (validated: flags off + airbox fueling done).
2. Verify in the viewer (devices off, fuel tables sane vs stock).
3. Flash it — via the tunie write path once it exists, or TuneECU meanwhile.
4. Fine-tune midrange fuel for the 2-1 with a wideband (ideally a dyno).
---
## Immediate next steps (this week, if picking back up)
1. **Cable + pinout** → run `tunie info` on the bike (unblocks everything).
2. Pull `20188Map2009AIRBOXBONNY` into the viewer catalogue and diff it vs stock
20187 so the exact delete-tune changes are visible.
3. Decide the open-source posture on the AES keys / write path (Track A1) before
any public repo.
## Risk register
| Risk | Status |
|---|---|
| Software bricking via the read tool | eliminated (write path not implemented) |
| Electrical (wrong connector pin) | **live** — confirm pinout before plugging in |
| Bad tune from flags-only edit | mitigated by guidance; use a complete map |
| Flashing (comms drop / bad checksum) | future — needs bench ECU + recovery tooling |
| Legal (redistributing proprietary maps) | mitigated — binaries gitignored |
| One ECU, no spare | validate writes against TuneECU; get a spare before B4 |