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

9.2 KiB
Raw Blame History

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 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.

  • 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