Skip to main content

Recent Firmware Changes

Firmware development log

Firmware recent changes

AI-generated · reviewed

New ECU functions and user-facing behavior first, followed by maintenance and integration audits.

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.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Source coverage and analyzed head
Coverage
60 commits · 34 changes · 26 merge audits
Analyzed head
09394f14eb ·