Recent Firmware Changes
Firmware development log
Firmware recent changes
New ECU functions and user-facing behavior first, followed by maintenance and integration audits.
New functions & user impact
record SD selection in manifests and correct profile tests
Packaged firmware manifests now record the requested sd_card selection separately from the normalized features string and preserve resolved required_modules. The documentation clarifies that sd_card is default-on only on supported boards and that nucleo_f767 and small-can-board declare it unsupported. Consumers of the manifest should read requested.sd_card and resolved.required_modules rather than inferring SD logging from the features field.
a7aae5e3d5 · Oct 23, 2026Source: fix(builder): record SD selection in manifests and correct profile testsexpose default SD selection and board-required modules
The web custom-firmware build gains a dedicated sd_card boolean input, default true, separate from the features list. The resolver rejects sd_card=false combined with sd_card in features, rejects disabling a board-required module such as Atlas sd_card, and reports required_modules per board. The resource calibration plan now treats board-required modules as part of the mandatory baseline and emits sd_card separately from features. Builders using the catalog or calibration tools should pass --sd-card and read required_modules to lock required selections.
35e904b2df · Oct 23, 2026Source: feat(builder): expose default SD selection and board-required modulespreserve legacy SD and USB exclusions on reduced boards
Reduced boards keep their previous exclusions. nucleo_f767 and small-can-board declare sd_card unsupported and keep EFI_FILE_LOGGING and EFI_USB_MSD disabled. The main firmware Makefile now strips board-level EFI_FILE_LOGGING definitions before applying the module-derived value, so the module profile controls file logging in the application while the bootloader keeps its own board value. Builders of these boards cannot enable sd_card through FOME_MODULES.
3c035a5450 · Oct 23, 2026Source: fix(firmware): preserve legacy SD and USB exclusions on reduced boardsadd default-enabled SD card module and Atlas requirement
SD-card file logging becomes a build module named sd_card. It is in the default profile, Atlas requires it, and the main firmware Makefile now derives USE_FATFS and EFI_FILE_LOGGING from the resolved module list. Builders who set USE_FATFS explicitly must remove it, because a conflicting value now fails configuration. Explicit FOME_MODULES profiles must include sd_card to keep card logging. USB mass storage and the embedded INI drive are now independent of SD logging. The TunerStudio SD Card Logger menu, indicators, and SD CS pin field appear only when the module is built.
68e67ba81a · Oct 23, 2026Source: feat(firmware): add default-enabled SD card module and Atlas requirementseparate INI and SD block sizing
Capoworks ECU separated the USB block sizing of the embedded INI drive from the SD driver. The INI drive keeps a fixed 512-byte block size whether or not SD support is compiled in, and the SD-card USB buffer is now sized from the SD driver's block size instead of a shared constant. This matters for builders of INI-only mass-storage firmware and for boards whose SD driver uses a different block size; no TunerStudio setting or tune migration is involved. The existing USB Mass Storage page is updated to describe the split and to pin its source links to this revision.
preserve fractional activation delay
Capoworks ECU fixed the VVT activation delay comparison in VvtController::onFastCallback. The configured vvtActivationDelayMs is now divided by a float MS_PER_SECOND, so fractional delays are preserved instead of being truncated by integer division. Practical effect: VVT output stays inhibited until the engine has run longer than the configured delay, and the delay now matches the value entered in TunerStudio. No tune migration is needed; existing delay values remain valid. Recheck VVT arming behavior after updating if a non-whole-millisecond delay was configured.
stop startup prime after ignition off
Capoworks ECU now requires the ignition to be on for the timed startup prime, so the low-pressure pump no longer stays primed after key-off. Each ignition-on transition restarts the prime interval, and the prime still ends when the configured Prime duration expires. The recent-trigger hold and the forced-on bench request are unchanged, so a recent trigger can still run the pump with the ignition off, and Fuel pump off still only clears the manual request. No tune setting or migration is required; use a build that includes this change and do not assume older or differently branded binaries behave the same way.
b74186ddce · Oct 22, 2026Source: fix(fuel-pump): stop startup prime after ignition offinvalidate pending prime requests on ignition off
Capoworks ECU changed priming-pulse scheduling so a key-off invalidates any pending delayed prime. Previously a delayed start could still fire after the ignition was switched off, or a stale request from an earlier key cycle could run during a later one. Now a pending prime is discarded on key-off, and an already-opened pulse still receives its matching close so injectors are not left open. No tune setting changes and no user action is required; the priming delay and prime table behave as before. This is a firmware behavior change, so it applies only to builds that include it.
d7d245eef4 · Oct 22, 2026Source: fix(fuel): invalidate pending prime requests on ignition offenforce continuous activation timeout
Antilag activation is now limited by a continuous timer. The timer starts on a false-to-true transition of the arming conditions and antilag turns off when elapsed time reaches ALSMaxDuration. After a timeout, antilag does not restart while the arming conditions remain true; they must clear and re-apply. Setting ALSMaxDuration to zero or a negative value now prevents antilag from activating, so tuners must use a positive duration. The default ALSMaxDuration changed from 3.5 to 3 seconds; existing tunes keep their stored value. Verify the duration and arming conditions on the bench before relying on antilag.
df9a30dfc3 · Oct 22, 2026Source: fix(antilag): enforce continuous activation timeoutinclude active secondary injector duty
The injector duty cycle cut now also watches the secondary injector stage. With staged injection enabled, the higher of the primary and stage 2 duty cycles is used for both the instantaneous and sustained limits, and the cut releases only when both active stages drop below 20 percent duty. Tuners running staged injection should check that the duty limits suit the secondary injectors as well, since a stage 2 excursion can now cut fuel even when the primary stage looks safe. With staged injection disabled, behavior is unchanged. This is a firmware logic change; it has not been validated on an engine.
9695e6e913 · Oct 22, 2026Source: fix(protection): include active secondary injector dutyretain boost cut across invalid MAP samples
Boost cut now treats a missing, invalid, or non-finite MAP reading as neither a rising nor a falling event. If the cut is already active, fuel stays cut until a valid MAP reading falls 20 kPa below the configured Boost cut pressure. A missing or invalid MAP reading cannot start a new cut. No setting changes are needed; the existing Boost cut pressure value and its 20 kPa hysteresis still apply. Check MAP sensor wiring and diagnostics if fuel stays cut after boost falls.
0c7fa68747 · Oct 22, 2026Source: fix(protection): retain boost cut across invalid MAP samplesgate ALS spark skipping on active anti-lag
Capoworks ECU changed anti-lag soft spark skipping so the configured ALSSkipRatio is applied only when anti-lag is enabled and the anti-lag controller reports an active condition; otherwise the target skip ratio is zero. Drivers and tuners no longer lose sparks to a stale skip ratio when anti-lag is off or not armed, and skipping resumes when anti-lag re-arms. No tune migration is needed, but re-check anti-lag spark behavior on the bench because the change is validated only by unit tests, not on an engine.
79bdd855d9 · Oct 22, 2026Source: fix(ignition): gate ALS spark skipping on active anti-lagreject invalid pedal intent and inhibit ETB addition
Anti-lag arming now fails closed: if the driver throttle-intent signal is missing or non-finite, the anti-lag throttle condition is false and anti-lag does not activate, even if RPM, coolant, and switch conditions are met. The anti-lag ETB target addition is also gated on anti-lag being enabled and on a valid, finite accelerator-pedal reading, so a stale active flag or a failed pedal sensor no longer adds ALSEtbAdd to the throttle target. No tune migration is required; existing anti-lag tunes keep their settings. Check that the pedal and throttle-intent sensors are calibrated and healthy before relying on anti-lag, and treat a lost pedal signal as an anti-lag inhibit rather than a fault to tune around.
03b4833c94 · Oct 22, 2026Source: fix(antilag): reject invalid pedal intent and inhibit ETB additionPresent on-demand firmware builder in repository README
The repository README now advertises the public Capoworks ECU on-demand firmware builder at capoworks.undo.it/firmware and adds a section describing the user flow: sign in, select a supported board, choose opt-in modules and table dimensions, then download the matching firmware image and generated TunerStudio INI. It also states a limit of six builds per user per day. The on-demand firmware build wiki page is updated so readers can use the public builder as well as the manual GitHub Actions workflow, while keeping the same profile rules, the requirement to treat firmware and INI as one matching pair, and the warning that a successful build is not engine or hardware validation.
bcad6ff1ff · Oct 21, 2026Source: Present on-demand firmware builder in repository READMEAdd board resource evidence and opt-in feature preflight
Adds Capoworks ECU build-resource tooling and a new build-resource guide. Custom firmware builds now accept VE RPM count (16/32), airmass blend size (8/16), cylinder trim count (1-12), and engine presets, and are resolved through the canonical catalog instead of the workflow's own board table. A resource gate now runs after the build and before packaging, so a rejected resource report prevents firmware publication. Normal firmware CI and Core8 CI also collect resource evidence. Builders should read the new resource guide and expect a failed resource gate to block artifacts; results prove build-time technical fit only, not runtime or hardware behavior.
c1c6fa222a · Oct 20, 2026Source: Add board resource evidence and opt-in feature preflightAdd build-time fuel table dimensions and engine preset selection
Capoworks ECU adds two build-profile options. FOME_VE_RPM_COUNT accepts 16 or 32 and sets the RPM points of the Speed Density VE and Alpha-N tables; FOME_AIRMASS_BLEND_SIZE accepts 8 or 16 and sets both axes of the SD + Alpha-N authority table. Defaults stay at 16 and 8, so existing builds are unchanged. FOME_ENGINE_PRESETS accepts all, none, or exact engine_type_e symbol names and filters which preset dispatch code is compiled; omitting it keeps all presets at default dimensions but includes none when either dimension is expanded, and an explicit symbol list is rejected in expanded builds. Changing either dimension changes the persistent layout, so binary tunes from a differently sized build are rejected and reset; export values with the matching generated TunerStudio INI and re-import them manually. On STM32F7 a new static assertion rejects a persistent record larger than the 32 KiB copy slot, so expanded tables plus a high cylinder-trim count can fail to compile. Builders should set the options on the compile command, not as compiler defines, and rebuild without a clean build.
3060ccd587 · Oct 20, 2026Source: Add build-time fuel table dimensions and engine preset selectionAdd validated on-demand firmware build workflow
Capoworks ECU adds a manual GitHub Actions workflow, Custom firmware build, that builds firmware for one selected board from the current master source. The request must supply a request_id of letters, digits, underscores, and hyphens, a board from the fixed list, and optionally a comma-separated list of opt-in modules. The workflow always includes the base modules fan, fuel_pump, gear_detector, tachometer, trip_odometer, and map_averaging, and rejects base modules, unknown or duplicate tokens, empty tokens, and over-long input. It rejects lua on hellen128 and shock_preload on boards other than core8, atlas, proteus_f4, proteus_f7, and proteus_h7. It also fails if the workflow's module list no longer matches the firmware module catalog. The build uses the repository's own compile script for the board, so the resulting binary and generated INI must be treated as one matching pair. Artifacts are retained for 14 days and include fome.bin, fome_update.srec when produced, the board INI when produced, and a manifest.json with SHA-256 hashes and the source commit. This is a build convenience only: it does not flash hardware, and a successful build is not engine or hardware validation.
restore Frankenso config generation and Windows simulator build
Capoworks ECU restored Frankenso configuration generation: gen_config_board.sh now resolves the host-only module profile against the f407-discovery board metadata when the board directory is config/boards/frankenso, because Frankenso has no board.mk of its own. Config generation itself still uses the Frankenso board directory. Builders generating Frankenso configuration no longer need a manual workaround; no tune, flashing, or runtime behavior changes. The simulator's SleepExecutor batch-order test now casts its expected and actual callback counts to int for the firmwareError format, so the Windows simulator build compiles. This is a test-only change with no effect on simulator or ECU behavior.
95d6e40b34 · Oct 20, 2026Source: fix: restore Frankenso config generation and Windows simulator buildenable six cylinder fuel trim tables by default
Cylinder fuel trim is now default-on with capacity 6; FOME_CYLINDER_TRIM_COUNT is optional and defaults to 6. Engines with more than 6 cylinders must raise the count or omit the module.
b852c8d82e · Oct 20, 2026Source: build: enable six cylinder fuel trim tables by defaultmake cylinder fuel trims optional and sized per build
Cylinder fuel trim becomes an optional build module with one 16x16 factor table per configured cylinder, a dedicated 1-to-12 count, all six load coordinates, shared axes, and materialized TunerStudio tables. Enabling it or changing its count changes the persistent layout with no binary migration.
a2cfe90ad4 · Oct 20, 2026Source: feat: make cylinder fuel trims optional and sized per builddescribe MCU resource budgets and validation limits
Documents MCU resource budgets: Lua heap sizes per MCU, F4 SRAM/CCM placement, 16 KiB DEFLATE dictionary, and F7 4-byte alignment, noting these are compile-time defaults and not validated hardware margins.
530330507e · Oct 19, 2026Source: docs: describe MCU resource budgets and validation limitsSecondary change logMaintenance and integration audits39 entries with no user-facing change
Merge pull request #84 from capoworks/feature/sd-card-module
This is the integration merge of the SD-card module branch. Its child commits are audited separately and the merge adds no distinct user-facing firmware, setup, flashing, or tune-migration change beyond them.
09394f14eb · Oct 23, 2026Source: Merge pull request #84 from capoworks/feature/sd-card-moduleemit Java boolean constants for module flags
This changes the Java configuration generator so boolean definitions such as FOME_SD_CARD_ENABLED are emitted as typed Java boolean constants instead of strings, with a compile-checking test. It is internal code generation and test work; no firmware behavior, flashing step, tune migration, or builder workflow changes for users.
695ceedb03 · Oct 23, 2026Source: fix(codegen): emit Java boolean constants for module flagsMerge pull request #82 from capoworks/fix/usb-ini-block-size
Integration merge of the USB INI/SD block-sizing fix. The merge introduces no changes beyond the child commit already documented, so no additional documentation change is needed.
a15846a97f · Oct 23, 2026Source: Merge pull request #82 from capoworks/fix/usb-ini-block-sizeMerge pull request #81 from capoworks/fix/pr849-08-vvt-delay
Integration merge of the VVT activation delay fix. Its child commits are audited separately and the merge introduces no additional user-facing change.
776881beac · Oct 22, 2026Source: Merge pull request #81 from capoworks/fix/pr849-08-vvt-delayapply repository formatting to corrective change
Formatting-only change to the VVT unit test file: include ordering and comment alignment. No firmware behavior, configuration, or user-facing documentation changes.
Merge pull request #80 from capoworks/fix/pr849-07-pump-prime
Integration merge of the fuel-pump prime fix. The merge introduces no changes beyond the child commit already documented, so no additional documentation change is needed.
ecf6fda1fa · Oct 22, 2026Source: Merge pull request #80 from capoworks/fix/pr849-07-pump-primeMerge pull request #79 from capoworks/fix/pr849-06-prime-keyoff
Integration merge of the priming key-off fix. Its child commits are audited separately and the merge adds no additional user-facing change.
4bcf5e2712 · Oct 22, 2026Source: Merge pull request #79 from capoworks/fix/pr849-06-prime-keyoffapply repository formatting to corrective change
Formatting-only change that re-wraps one conditional in the priming controller. No behavior, configuration, or user-facing documentation change.
Merge pull request #78 from capoworks/fix/pr849-05-als-timeout
Integration merge of the antilag timeout fix. It adds no user-facing change beyond the child commit already documented.
10e7ca7ccd · Oct 22, 2026Source: Merge pull request #78 from capoworks/fix/pr849-05-als-timeoutMerge pull request #77 from capoworks/fix/pr849-04-injector-duty
Integration merge of the secondary injector duty fix. Its only content is the child commit already documented, and the merge introduces no additional user-facing change.
dfeba99a63 · Oct 22, 2026Source: Merge pull request #77 from capoworks/fix/pr849-04-injector-dutyMerge pull request #76 from capoworks/fix/pr849-03-boost-cut
Integration merge of the boost-cut fix. It adds no changes beyond the child commit already documented, so no further documentation change is needed.
15b1ee0261 · Oct 22, 2026Source: Merge pull request #76 from capoworks/fix/pr849-03-boost-cutMerge pull request #75 from capoworks/fix/pr849-02-spark-skip
Integration merge of the anti-lag spark-skip fix branch. Its child commits are documented separately and the merge adds no further user-facing change.
9965355315 · Oct 22, 2026Source: Merge pull request #75 from capoworks/fix/pr849-02-spark-skipapply repository ternary formatting
Formatting-only change that reflows the ternary expression introduced by the previous commit. No behavior, configuration, or user-facing effect.
Merge pull request #74 from capoworks/fix/pr849-01-pedal-etb
Integration merge of the anti-lag pedal-intent fix. Its child commit is documented separately and the merge adds no further user-facing change.
5a4d0a9611 · Oct 22, 2026Source: Merge pull request #74 from capoworks/fix/pr849-01-pedal-etbMerge pull request #73 from capoworks/docs/giacomo-author-attribution
Integration merge of the attribution branch. Its child commits are audited separately and the merge adds no conflict-resolution or behavioral change, so it has no additional user-facing documentation effect.
eb220b087c · Oct 21, 2026Source: Merge pull request #73 from capoworks/docs/giacomo-author-attributioncorrect EMP authorship and remove inaccurate provenance
Edits only the comment headers of the EMP pump source files, replacing the adaptation note with an author line and removing a provenance paragraph. The EMP pump protocol, configuration, and runtime behavior are unchanged, so no documentation or user action follows.
8f4cb53a76 · Oct 21, 2026Source: docs: correct EMP authorship and remove inaccurate provenancecredit Giacomo di Ciocco and record source attribution policy
Adds a contributor credit to the repository README, a new AGENTS.md attribution policy, and Doxygen file/author headers to existing source files. No firmware behavior, configuration field, tune layout, build option, or flashing step changed, so no driver, tuner, or builder action is required.
551cb085c0 · Oct 21, 2026Source: docs: credit Giacomo di Ciocco and record source attribution policyMerge pull request #72 from capoworks/feat/build-resource-matrix
Integration merge of the build-resource-matrix branch. Its child commits are audited separately and the merge adds no conflict-resolution changes with distinct user-facing effect.
413ce9aace · Oct 21, 2026Source: Merge pull request #72 from capoworks/feat/build-resource-matrixSelect modern Bash for macOS configuration generation
Build-tooling portability change: the macOS unit-test job installs Homebrew Bash and prints make/bash versions, and gen_config_board.sh uses an env-based Bash shebang. No firmware feature, build option, or tune behavior changes for users.
Keep engine preset generation compatible with Bash 3.2
Replaces mapfile with a read loop in the engine preset renderer so it runs under Bash 3.2. The generated preset profile output is unchanged; this is a build-script portability fix with no user-facing firmware or configuration change.
Use Homebrew GNU Make for macOS unit tests
CI-only change: the macOS unit-test job installs Homebrew GNU Make and prepends its bin directory to PATH. No firmware behavior, build option, flashing step, or tune layout changes for users.
Merge pull request #71 from capoworks/feat/build-time-table-profiles
Integration merge of the build-time table profile branch. Its child commit is documented separately and the merge adds no conflict-resolution changes of its own, so no additional user-facing documentation is needed.
9a6fb7c5a6 · Oct 20, 2026Source: Merge pull request #71 from capoworks/feat/build-time-table-profilesMerge pull request #70 from capoworks/fix/ci-configs-windows-simulator
Integration merge of pull request #70 with no conflict-resolution changes beyond the child commit already documented. No additional user-facing documentation change.
1734a4b70c · Oct 20, 2026Source: Merge pull request #70 from capoworks/fix/ci-configs-windows-simulatorMerge pull request #69 from capoworks/ops/github-hosted-runners
This merge integrates the two CI commits already covered above. The combined diff contains only the same workflow runner and binutils changes, with no conflict-resolution edits and no additional user-facing effect.
728292632f · Oct 20, 2026Source: Merge pull request #69 from capoworks/ops/github-hosted-runnersuse bundled ARM binutils on hosted firmware builds
The hosted firmware build now links the bundled ARM objcopy and objdump into a temporary tools directory and adds it to the job PATH. This is CI-internal tooling setup; the documented local Core8 helper already uses the bundled ARM binutils, and no firmware, artifact, or user workflow changes.
move software workflows to GitHub-hosted runners
The software workflows were moved from a self-hosted runner label to GitHub-hosted Ubuntu 24.04 runners, with Java 21 and build packages installed inside the job. This affects only how Capoworks CI jobs are executed; firmware behavior, artifacts for users, and local build instructions are unchanged.
Merge pull request #67 from capoworks/build/firmware-memory-budget
Integration merge of the firmware memory budget branch; child commits are audited separately and the merge adds no distinct user-facing change.
ee8be3687e · Oct 20, 2026Source: Merge pull request #67 from capoworks/build/firmware-memory-budgetMerge pull request #63 from capoworks/ci/ephemeral-runner
Integration merge of the ephemeral runner branch; the only conflict resolution is a PCH cleanup line in common_make.sh, which is build tooling with no firmware or user-facing effect.
0207f7e100 · Oct 20, 2026Source: Merge pull request #63 from capoworks/ci/ephemeral-runneradd an isolated ephemeral self-hosted runner
CI infrastructure only: adds an isolated ephemeral self-hosted runner and JOBS validation. It does not change firmware, flashing, or tune behavior.
Merge pull request #57 from capoworks/modularity/01-static-composition
Integration merge of the static composition branch; child commits are audited separately and the merge adds no distinct user-facing change.
2099f11a64 · Oct 20, 2026Source: Merge pull request #57 from capoworks/modularity/01-static-compositionMerge pull request #58 from capoworks/modularity/02-hella-opst
Integration merge of the Hella OPS-T branch; child commits are audited separately and the merge adds no distinct user-facing change.
da1f76475d · Oct 20, 2026Source: Merge pull request #58 from capoworks/modularity/02-hella-opstMerge pull request #59 from capoworks/modularity/03-boost
Integration merge of the Boost branch; child commits are audited separately and the merge adds no distinct user-facing change.
d73a32e99f · Oct 20, 2026Source: Merge pull request #59 from capoworks/modularity/03-boostMerge pull request #60 from capoworks/modularity/04-engine-sniffer
Integration merge of the Engine Sniffer branch; child commits are audited separately and the merge adds no distinct user-facing change.
beda34e75a · Oct 20, 2026Source: Merge pull request #60 from capoworks/modularity/04-engine-snifferMerge pull request #61 from capoworks/modularity/05-lua
Integration merge of the Lua module branch; child commits are audited separately and the merge adds no distinct user-facing change.
f4c3a3b4c8 · Oct 20, 2026Source: Merge pull request #61 from capoworks/modularity/05-luaMerge pull request #64 from capoworks/modularity/06-emp-pump
Integration merge of the EMP pump branch; child commits are audited separately and the merge adds no distinct user-facing change.
a6ee931372 · Oct 20, 2026Source: Merge pull request #64 from capoworks/modularity/06-emp-pumpMerge pull request #65 from capoworks/modularity/07-shock-preload
Integration merge of the shock preload branch; child commits are audited separately and the merge adds no distinct user-facing change.
f423fbe27a · Oct 20, 2026Source: Merge pull request #65 from capoworks/modularity/07-shock-preloadMerge pull request #66 from capoworks/modularity/08-board-module-policy
Integration merge of the board module policy branch; child commits are audited separately and the merge adds no distinct user-facing change.
69fd4a3d95 · Oct 20, 2026Source: Merge pull request #66 from capoworks/modularity/08-board-module-policyMerge pull request #68 from capoworks/modularity/09-cylinder-fuel-trim
Integration merge of the cylinder fuel trim branch; child commits are audited separately and the merge adds no distinct user-facing change.
b143c3040b · Oct 20, 2026Source: Merge pull request #68 from capoworks/modularity/09-cylinder-fuel-trimcover six cylinder defaults and full engine capacity
Test-only change adding a 6-cylinder CI matrix entry and a unit-test default of 12; it does not change firmware defaults or user-facing behavior.
e5c84bb88f · Oct 20, 2026Source: test: cover six cylinder defaults and full engine capacitySource coverage and analyzed head
- Coverage
- 60 commits · 34 changes · 26 merge audits
- Analyzed head
09394f14eb·