This project writes to a real vehicle CAN bus. The cost of an untested patch landing in main is "the next user's car does something unexpected on the road". Please be conservative.
git clone --recursive https://github.com/flipperdevices/flipperzero-firmware.git
cd flipperzero-firmware
git clone https://github.com/hypery11/flipper-tesla-fsd.git applications_user/tesla_fsd
./fbt fap_tesla_fsdThe output .fap lands in dist/<arch>-<api>/apps/GPIO/tesla_fsd.fap.
Since v2.4 the app boots in Listen-Only mode. The MCP2515 is put into its hardware listen-only register, which is physically incapable of TX even on bus error frames. This is the right starting point for any new behaviour.
- Plug the Flipper into the car
- Open the app, leave Mode = Listen
- Watch the RX counter — if it stays at 0 after 5 seconds, your wiring is wrong; the app will display a "No CAN traffic" warning
- Confirm BMS dashboard reads sensible values (SoC, voltage, current)
- Switch to Service mode if you want to test TX paths in a controlled way; switch to Active for normal operation
If you're adding a new TX feature, the PR description should say what you verified in Listen-Only first (what frames you saw, what your handler would have written).
For any change that modifies what we write to CAN, we need at least one on-vehicle confirmation before merging. State in the PR:
- Tesla model + year
- HW version (HW3 / HW4 / Legacy)
- Firmware version (Settings → Software)
- Region (this matters for which UI features are exposed)
- What you changed
- What you observed (UI behaviour, dashboard messages, error counters)
If you don't have a Tesla yourself, that's fine — open the PR and tag it
needs-on-car-test. Other contributors will pick it up.
The C side is plain C99, no C++ features, no allocations on the worker thread. Match the style of the surrounding file. Concretely:
- 4-space indent, no tabs
- snake_case for functions and locals, PascalCase for types and enum values
- Mutex discipline: lock the app mutex when reading or writing
app->fsd_state, unlock immediately, work on a stack copy in the worker - Bounds-check every byte access against
frame->data_lenght(yes,data_lenght, that's the upstream MCP2515 lib spelling — don't fix it) - Add new CAN ID
#defines tofsd_logic/fsd_handler.hwith the decimal value and a one-line comment
main— only release-tagged code, never brokenfeat/*— feature branches, merged via PR with at least one reviewfix/*— bug fixes, smaller turnaround OK
Don't push directly to main.
- AI-generated commit messages, AI-generated PR bodies, AI-style README prose. We get filtered out by readers if it reads like ChatGPT slop. Write what you actually did, in your own voice, in whatever language you're comfortable with — Chinese, English, German, Korean, all welcome in PR conversations.
- Adding features that need a feature flag "for safety" — if it's not safe enough to default on, the design isn't ready
- Touching brakes, steering, or powertrain CAN IDs without a long conversation in an issue first
- Bumping the version in your PR — the maintainer does that at release time
- Real on-car test reports with firmware version, HW, region, and what worked / didn't
- New hardware variants (other CAN modules, other MCUs) — just add a
HARDWARE.mdrow - Bug fixes with a one-sentence reproduction
- Translations of
README.mdinto more languages - CAN frame templates from public Tesla CAN research, with the source cited (opendbc, mikegapinski, talas9, tuncasoftbildik, etc.)
Be civil. We have users from a lot of countries who don't share a first language. Don't pile on, don't gatekeep, don't reply in a way you wouldn't say to someone in person.