Firmware ecosystem designed for Ford Fiesta 1.8 diesel with custom electronics. It was built for a custom 1.8 diesel hybrid engine setup that combines elements of the 1.8D (indirect injection) and 1.8TDDI (direct injection) variants, with a VP37 pump installed.
At this stage the project is still a POC and has not yet been validated as one fully integrated system in a road-going car. For ECU and VP37 testing, a dedicated engine was built and mounted on a steel frame in a garage.
The repository contains multiple embedded applications, hardware assets, and validation materials used to build a complete vehicle electronics stack.
Gallery: https://postimg.cc/gallery/pHF4jy2
Fiesta is a system composed of several tightly integrated modules working together.
Some modules are already tested in the car (non-safety-critical paths such as the Clocks extension, and ECU in supervisory/engine-parameter mode without VP37 actuation).
For a full description of the modules, their responsibilities, how they talk
to each other and to the vehicle, and where the external dependencies fit in,
see ARCHITECTURE.md.
The desktop companion lives in
src/SerialConfigurator/.
Current scope: GTK detection / details UI, per-module Flash sections
with UF2 format check + manifest pre-flash gate, end-to-end flashing
flow (auth + reboot + BOOTSEL drive watcher + UF2 copy with progress +
re-enumeration), and a first-class CLI shell (detect, list, meta,
param-list, get-values, get-param) over the same core.
Implementation status and milestone snapshots are tracked in
CHANGELOG.md.
Required external custom library (shared across all modules):
JaszczurHAL(HAL and utility layer): https://github.com/jaszczurtd/JaszczurHAL
Expected layout:
<parent-of-repo-root>/libraries/JaszczurHAL
Example: if this repo is cloned at /home/you/projects/Fiesta, library goes
into /home/you/projects/libraries/.
Required toolchain:
git,build-essential,cmake,python3,curl,gtk-4,ca-certificatescppcheck(static analysis; ships the MISRA addon used bysrc/ECU/misra/check_misra.sh)arduino-cli+rp2040:rp2040core (earlephilhower/arduino-pico)
Each firmware module is a regular C/C++ application with a CMake-generated application entry point. That entry point adapts the module-owned initialization() / looper() functions to the setup() / loop() symbols expected by the current RP2040 build toolchain; modules that opt in to the second core expose setup1() / loop1() the same way.
runmefirst.sh performs the full environment setup end-to-end, and is idempotent (safe to re-run). It:
- installs required apt packages (
git,build-essential,cmake,python3,curl,ca-certificates,cppcheck,gtk-4), - verifies Python 3 is available,
- verifies
cppcheckis available and its MISRA addon is reachable, - installs
arduino-cliif missing, - registers the rp2040 board manager URL and installs the
rp2040:rp2040core, - syncs
JaszczurHALinto$LIB_DIR(default:<parent-of-repo-root>/libraries, matching the path expected by moduleCMakeLists.txtfiles): missing repos are cloned, existing git checkouts are force-reset to their remote default branch and cleaned, - configures, builds, and runs host tests (
ctest) for every module that ships aCMakeLists.txt:ECU,Clocks,OilAndSpeed,Adjustometer(ECU includestest_cppcheckoncecppcheckis present), - compiles firmware for every Fiesta module and reports each module-named
.uf2and.manifest.jsonartifact:ECU,Clocks,OilAndSpeed,Adjustometer,Fiesta_clock; firmware settings come from each module's.vscode/jaszczurhal.project.json, - compiles Fiesta USB Configurator tool (
SerialConfigurator).
The toolchain set up by runmefirst.sh also covers everything src/ECU/misra/check_misra.sh needs (cppcheck + Python 3; cppcheck's Debian package ships the misra.py addon).
Run from repository root as a regular (non-root) user - the script uses sudo only for apt and arduino-cli install and will prompt for the password when needed:
bash runmefirst.shDo not run this script under sudo - because arduino-cli config, rp2040 core, and cloned libraries would end up under /root/ and break later non-root builds.
The script exits early if it detects EUID=0. Override with ALLOW_ROOT=1 only if you know what you are doing.
Useful env overrides: LIB_DIR, ARDUINO_CLI, ALLOW_ROOT=1, SKIP_APT=1, SKIP_TESTS=1, SKIP_BUILD=1.
IMPORTANT: runmefirst.sh treats JaszczurHAL under $LIB_DIR as a disposable build dependency: if that directory already contains a git checkout, the script updates origin, fetches the remote state, runs git reset --hard, and removes untracked files before continuing.
runmefirst.sh exercises all five Fiesta firmware modules and SerialConfigurator end-to-end (compile & run all tests, compile all modules).
The project is developed primarily on Linux (Debian-compatible/Raspberry Pi OS). Visual Studio Code is the main editor. Firmware modules (ECU, Clocks, OilAndSpeed, Adjustometer, Fiesta_clock) ship ready-to-use .vscode/ setups (tasks.json, launch.json, extensions.json, settings.json, and
jaszczurhal.project.json), so compile, upload, serial monitor, host tests, and debugger flows are wired out of the box, and fully controlled by JaszczurHAL scripts.
src/SerialConfigurator ships its own CMake-oriented VS Code task setup, with compatible keybindings.
Platform support summary:
- Linux (Debian-like) - primary target.
runmefirst.sh, JaszczurHALjh-vscodefirmware tasks, host tests, MISRA screening, and the daily Pi runner all work. - WSL2 on Windows - works the same as native Linux for everything except direct USB access;
jh-vscode uploadand BOOTSEL upload still require access to the real USB device / BOOTSEL drive from the Windows side or a native shell. - Native Windows - not tested and probably not working, because the primary development environment is currently Linux and the JaszczurHAL tooling does not support Windows at the moment.
- macOS - untested;
arduino-cliand the CMake host tests should work, shell/python scripts likely need minor tweaks.
src/ECU/scripts/systemd/ ships a user-scope systemd service + timer that once-a-day (13:00 local) pulls the repo, wipes ECU build artifacts, runs runmefirst.sh, and emails a PASS/FAIL status summary (HEAD SHA + commit subject + last 80 lines of log; full log attached, capped at 512 KB). Setup and SMTP notes are documented in src/ECU/scripts/systemd/README.md.
Firmware modules use the shared JaszczurHAL VS Code entry instead of module-local wrapper scripts. Fiesta keeps only project-specific helpers:
src/ECU/scripts/bootstrap.sh- one-shot dev-env setup + tests + firmware build for all Fiesta modules. You can start immediately by invoking this script right after clone. SeeOne-shot setupsection below.src/common/scripts/fiesta-arduino-common.sh- Fiesta-only module token, manifest, UF2, and bootstrap helpers. The firmware build routes through the JaszczurHAL multi-target dispatcher (jh_firmware_project, rp2040 target).
CMake in this repository is used for Serial Configurator compilation, and host test configuration/build; test
targets are compiled as C++ (.cpp). Same pattern for every module:
cmake -S src/<Module> -B src/<Module>/build_test -DCMAKE_BUILD_TYPE=Release
cmake --build src/<Module>/build_test --parallel
ctest --test-dir src/<Module>/build_test --output-on-failureAll modules have their own separate tests.
For a single command that runs host tests across all primary modules (ECU,
Adjustometer, Clocks, OilAndSpeed, SerialConfigurator) and then executes
module-level check-valgrind / check-clang-tidy targets, use:
./runalltests.shThe host-test gate runs runtime tests only (ctest -LE static-analysis) so
static analyzers do not look like a stuck test run.
Useful flags: -j<N>, --skip-cppcheck, --skip-valgrind,
--skip-clang-tidy.
cd src/<ECU|Clocks|OilAndSpeed|Adjustometer|Fiesta_clock>
../../../libraries/JaszczurHAL/vscode/entry/jh-vscode build --project "$PWD"
../../../libraries/JaszczurHAL/vscode/entry/jh-vscode build-debug --project "$PWD"
../../../libraries/JaszczurHAL/vscode/entry/jh-vscode upload --project "$PWD"
../../../libraries/JaszczurHAL/vscode/entry/jh-vscode upload-uf2 --project "$PWD"
../../../libraries/JaszczurHAL/vscode/entry/jh-vscode refresh-intellisense --project "$PWD"Notes:
Project: Upload/Ctrl+Shift+2uses the samejh-vscode uploadpath.Project: Upload (UF2 / BOOTSEL)is the BOOTSEL mass-storage path.Project: Serial Monitor/Ctrl+Shift+3usesjh-vscode monitorwith stable/dev/serial/by-id/usb-Jaszczur_Fiesta_*identity matching.- The module-local VS Code wrappers were removed; task behavior now comes from
libraries/JaszczurHAL/vscode/.
cd src/SerialConfigurator
./scripts/desktop-build.sh build
./scripts/desktop-build.sh run
./scripts/desktop-build.sh test
./build/serial-configurator-cli detectEach module ships a .vscode/launch.json with Cortex-Debug (marus25.cortex-debug) configurations for live debugging via the Raspberry Pi Debug Probe over CMSIS-DAP:
- Debug: RP2040 (Pico/Pico W/Zero/Plus) - flash + break at
main - Debug: RP2350 (Pico 2/Pico 2 W) - flash + break at
main - Debug: Attach RP2040 / RP2350 - attach to a running target without re-flashing
Prerequisites:
- Debug Probe firmware v2 or later (USB VID:PID
2e8a:000c). Older Picoprobe firmware (2e8a:0004) also works since the shipped configs useinterface/cmsis-dap.cfg. - SWD wiring: probe
SC->targetSWCLK,SD->SWDIO,GND->GND. Power the target independently or from the probe's debug header. - The
marus25.cortex-debugextension (listed in each module's.vscode/extensions.json). openocdandarm-none-eabi-gdbcome bundled with therp2040:rp2040Arduino core (installed byrunmefirst.sh). Paths are already set in each module's.vscode/settings.json- review them if your core version differs from the committed defaults.
Usage: open the module in VS Code, press F5, and pick the configuration. The launch variants run Project: Build (Debug) as preLaunchTask so ${workspaceFolder}/.build/firmware.elf stays fresh; attach variants skip the build step.
Note: jh-vscode upload does not use the probe for upload - it flashes over USB CDC. The probe is only used by Cortex-Debug's GDB path.
- No ISO 26262. Correctly absent - no certification authority would accept it for a one-off retrofit, and faking it would be worse than omitting it.
- No AUTOSAR. Unjustifiable overhead for solo scope. JaszczurHAL plays the same architectural role (HAL -> application separation) at roughly one- thousandth of the bureaucracy cost.
- No HIL rig. Host SIL only via mock HAL. A HIL rig is the right answer at production scope, not at one-vehicle scope.
- No formal MISRA compliance. Partial scope (ECU only), runner used as triage evidence not as certification. Treated explicitly as "in progress" with a public deviation register, not as a checkmark.
- No code review. Solo project. Compensated by test infrastructure, cppcheck gating, MISRA screening, CI on every push. Test code is the proxy reviewer.
- No AEC-Q100 silicon. RP2040 is consumer-grade, deliberately. Cost, dual-core, PIO state machines (used for engine Hall sensor capture and VP37 pump-coil resonance), and flash-backed EEPROM picked over automotive silicon precisely because the vehicle is a personal car, not a production platform.
Even though the full stack is not yet running in a real car as one integrated system, safety is treated as a first-class priority.
src/ECUis the safety-critical module and is being aligned with MISRA-C.- Defensive coding and runtime hardening are prioritized over shortcuts, already at this stage of the project.
- Coverage is expanded continuously (host tests + firmware build validation).
- Safety documentation is kept synchronized with code changes.
MISRA-C migration status, policy, and screening entry points live in a
dedicated document: MISRA.md.
Per-module build, test, and CI history is tracked in
CHANGELOG.md.
Author: Marcin "Jaszczur" Kielesiński
Libraries used in src/Fiesta_clock:
- DS18B20 library origin: Davide Gironi.
PCF8563.ccreated 2014-11-18 by Jakub Pachciarek.
This is a test prototype used to test the engine when it is not installed in the car:
Bootstrap script + USB parameters:
Test engine:
Serial (Fiesta) Configurator:
ISO 14229, ISO 14230, and ISO 15765 OBD-2 implementation running with Fordiag diagnostic tool:
Testing bench:









