mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-21 12:52:16 -05:00
master
7
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
80a4d64ffd |
Prepare next firmware release
Add Fluidd and custom boot scripts, migrate DC24V control, update the web UIs and filament macros, improve startup status reporting, and expand upgrade and replica coverage. |
||
|
|
e20ed98dac |
Refuse to install on FlashForge firmware older than 1.9.6 (#17)
A printer still on 1.9.4 does not come up on this package: the board firmware that release pairs with differs from the one klippy is built to talk to, the MCU never connects, and the failure is at the bottom of the stack -- no Klipper, so no screen and no Mainsail. From the outside it is indistinguishable from a bad flash, and the only way out is flashing stock again. So it is refused before anything is written, with the fix in the message: install FlashForge's own current firmware first, then this. That costs one more flash and leaves a working printer either way. WHAT IS READ is /usr/prog/PROGRAM/software, which holds one directory named for the version of FlashForge's software component -- install_component wipes the previous one before renaming the new one in. No package of ours ever ships a software component, so it goes on describing the printer rather than the mod. The highest is taken when a machine somehow holds two, so a leftover from an interrupted install cannot refuse a printer that should go ahead, and the comparison is field-by-field numeric because a string compare makes 1.9.10 older than 1.9.6. AN UNREADABLE VERSION IS INSTALLED ON. The two failures are not the same size: letting one through costs a printer that has to be flashed back to stock, while refusing on one would break the install path on every machine whose layout is not the one being read. THE REFUSAL HAS TO BE VISIBLE. It happens before the panel is switched to start.img and app_startup.sh goes on booting the printer, so from the outside the flash would just have done nothing. installer/stock-too-old.img is the frame it paints instead -- the same raw 480x800@32 framebuffer dump start.img is, rendered by the same ffscreen.py, so it needs nothing on the printer but `cat > /dev/fb0`. The version in it is DRAWN, so bin/pack.sh carries the command to re-render it when MIN_STOCK_VER changes. anvil-NOT-INSTALLED.txt on the USB stick is the copy that survives the power cycle. Three tests, on the replica. The machine there is a real one in the way that matters -- its /usr/prog/PROGRAM/software holds FlashForge's own 1.9.7 -- so "current firmware installs" needs no setup, the refusal swaps that directory for one holding 1.9.4 and restores it, and the third asserts that a stale 1.9.4 left BESIDE the real version does not refuse. The control matters more than the refusal: a gate that refused everything would pass the refusal test and brick every flash. qa/replica/test_upgrade.py is 19/19; the lane's 10 other failures are the ones master has on this bake. Claude-Session: https://claude.ai/code/session_01Fn1k6kaHWhUrsmBfpxjUcG Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
0747bc500b |
Keep the config in a directory of our own (#16)
* Keep the config in a directory of our own Flashing a stock FlashForge package back over the mod left a printer that would not start. /usr/data is the DATA partition: a stock flash rewrites /usr/prog and does not touch it, so the symlinked printer.base.cfg and the ff-*.cfg beside it outlived the mod, pointing into a /usr/data/anvil that was gone -- and Klipper treats an [include] it cannot resolve as fatal. Nothing of ours runs during a stock flash, so there is no undo to write from inside the mod. Not writing there is the only version of this that works. The live config is /usr/data/anvil-data/config now, seeded once by anvil-link-prog.sh with a copy of everything in /usr/data/config: printer.cfg with the SAVE_CONFIG block of calibrated values at the end of it, and the stock includes the mod neither ships nor parses. The seed test is printer.cfg, which is copied last and through a temp name, so a machine that never finished seeds again on the next boot rather than staying half-configured, and no update ever re-seeds over a tuned file. It is outside $MODDIR, so the installer's wipe-and-extract cannot reach it and nothing has to be stashed on /tmp. Moonraker moved with it, and the lever is the data path rather than -c: moonraker registers its config root as <data path>/config and nothing configures that separately, so -c alone would move the file it READS while file_manager kept registering FlashForge's directory. With -d /usr/data/anvil-data its config directory is klippy's, which is also what Mainsail's config editor lists. gcodes and logs stay where the machine keeps them -- /usr/data/gcodes is klippy's [virtual_sdcard] path -- as symlinks inside the data path, which works because register_directory() realpaths a root that is a link. The database is carried across once, by the service, below the stray-killer: the one point where moonraker is provably not running. What an older release left in /usr/data/config STAYS there. A sweep could delete the links but could not put stock's own printer.base.cfg back, because the release that replaced it kept no copy -- and stock's run.sh force-copies its own onto every flash, which repairs that directory whether or not anything was swept. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fn1k6kaHWhUrsmBfpxjUcG * Ask the config-directory test about this installer, not the bake test_flashforges_config_directory_is_never_written asserted that the mod's filenames are absent from /usr/data/config. On a replica baked from a release that still WROTE them, that is a question about the bake rather than about the installer under test, and it fails for a reason the change cannot fix. Remove them, run the installer over the top, then ask. The property is "an install writes nothing there", and that is now what is measured. Verified on the replica: qa/replica/test_upgrade.py is 18/18. The five test_install.py assertions about the seeded directory still need a machine baked from a package built with this branch -- work/out holds one from 2026-08-30, which symlinks into /usr/data/config as the old code did. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fn1k6kaHWhUrsmBfpxjUcG * Ask the config directory of a machine that has one The five assertions about /usr/data/anvil-data/config could only pass on a replica baked from a package built with this branch, and the bake installs work/out/*.tgz -- whatever was built last. So they failed for a reason the change cannot fix, and the gate could only go green after a full build, which is exactly when nobody runs it. Two different fixes, because the questions are two different kinds. WHAT THE INSTALLED PACKAGE PRODUCED is still asked of the bake, but the directory is now read off the machine instead of written down: PRINTER_CFG in the installed etc/s6-rc/source/klipper/run is the command line klippy is exec'd with, and therefore the only thing that decides which directory is live. test_install.py and test_klippy_extras_import.py follow it, so the include set, the graph walk and the user's printer.cfg are asked about whichever side of the move the installed package was built on. WHAT THIS CODE DOES is a new module, test_config_directory.py, which stages anvil-link-prog.sh from the checkout and runs it -- the way test_upgrade.py stages the installer. Only the timing is mocked: it seeds from a real printer.cfg with FlashForge's real includes beside it, links the ff-*.cfg the installed package really shipped, and reads MACHINE= out of the real app_startup.sh. It asserts the seeding carries the machine's own marker, the links point into $MODDIR, the chamber config matches the model, every include resolves, a second run does not re-seed over an owner's edit, and the run adds NOTHING to /usr/data/config. That last one is a DELTA, not an absolute. A machine that has been through a release which symlinked into FlashForge's directory still holds those links and nothing can restore what they replaced. What this code owes is that it adds nothing. Verified on the replica: 135 passed, and the 10 failures are the same ones master has on this bake -- ffmpeg, numpy, the timelapse component and the hardware services, all missing from the 2026-08-30 package in work/out. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fn1k6kaHWhUrsmBfpxjUcG * Link every .cfg the packages ship, not a list of names test_every_include_resolves_in_the_new_directory failed on CI: printer.base.cfg has [include timelapse.cfg] and no timelapse.cfg was in /usr/data/anvil-data/config, which Klipper treats as fatal. anvil-link-prog.sh linked printer.base.cfg and the ff-*.cfg by name. timelapse.cfg is anvil-timelapse's and matched neither, so it reached the live directory only through the installer's copy of $MODDIR/config -- and never at all on the `apk upgrade` path, where the link script is the only thing that runs. A named list is a file that resolves on a fresh install and goes stale the moment a package adds one. So the rule is the glob: every .cfg in $MODDIR/config is linked, and the installer skips every .cfg rather than the four names it knew. The .conf beside them stay the installer's -- moonraker-custom.conf is the owner's file to edit, so it is copied once and never linked to a package's copy. test_the_mods_configs_are_links_into_moddir asks the same way now, so a package whose config nothing includes is covered too. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YULWHVHyxKm2HE9kiPfEjP --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
fc137ec59d | Prepare beta release documentation | ||
|
|
c536a4f06e |
installing.md: show the first-boot screen instead of describing it (#14)
* Show the first-boot screen instead of describing it bin/preview-boot-screen.py already renders every ffscreen.py phase to PNG on the host, byte-identical to what the printer draws (make boot-screen-sim proves it against the real replica). Four of those frames -- waiting, importing, saving, complete -- now sit in installing.md's first-boot walkthrough instead of leaving the reader to picture a progress bar from prose alone. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RMV6mRtJ4dCxAj2QAifT8v * Two big frames beat four small ones 24% width left the boot-screen text unreadable. Down to importing and complete at 48% -- the same sizing the README already uses for the HelixScreen pair -- and dropped the two frames no longer referenced. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RMV6mRtJ4dCxAj2QAifT8v --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> |
||
|
|
65a7528e09 |
The manual assumed a printer that arrives broken. It arrives calibrated.
The pages written on top of the old README inherited its premise: that after flashing you face a gauntlet -- go/no-go checks, a safety net, a mandatory calibration -- before the machine can be trusted with a model. That is not what happens. The factory numbers import themselves on the first boot, a bed mesh loads at the start of every print, and the mod is built to run the files the stock firmware ran. A printer that printed before the flash prints after it. "Your first print" now says so in its first line, and everything under it is optional, ordered by what you would actually reach for: check the offsets are applied, and calibrate only if that disagrees with the machine. Three audiences now, because owner and contributor was not the real split. "For experienced users" sits between them: How a print runs, and How calibration works. Someone who knows Klipper and wants to change what happens around their file has a place to go that is neither a walkthrough nor the build system. What was cut is most of what changed. Pages that were cryptic to the reader they were aimed at -- Printing, Upgrading -- are out of the nav and kept on disk to be rewritten rather than deleted. Within the pages that stayed: Expected output, Probe sampling, What is being measured, the symptom table, the dark-screen diagnosis, TOOL_Z_ADJUST, PLATE_CHECK, the ff-*.cfg inventory, [ff_legacy] and SAVE_CONFIG in a paragraph about factory calibration. Filenames and internals earn their place on an owner page only when the reader has to type them or look at them; the rest moved to the experienced pages or to Internals, where the audience wants them. Calibration became a section rather than a page, because tool offsets are not the only calibration: bed mesh has its own page now, and its own gotcha written down -- BED_MESH_CALIBRATE writes `default`, a print loads `MESH_DATA`, so a mesh probed by hand is a mesh no print will use. Input shaping is described but has no procedure page yet. Several claims came out because they were not true. "Is this for you" listed calibration and input shaping as things the mod gives you; both are the touchscreen's own sequences, recovered and reimplemented, and the notes say so plainly. What the mod actually gives you is that anything speaking Moonraker can drive the machine -- on stock, FlashForge's Klipper does not toolchange at all, it raises a flag and waits for an application that is not watching a Mainsail print, and the print hangs at the first T2. The page now opens by telling most owners not to flash it. Contributors are still deferred. Their pages are regrouped, not rewritten. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S3XZh4SqPdXAowVndz6tMr |
||
|
|
a6098c7f64 |
The README was the manual. It is a front door now, and the manual is nine pages.
Fourteen sections, install through troubleshooting, in the one file that existed when there was nowhere else to put them. The site gave the manual a home; this moves it there and orders it by what the reader is doing rather than by which subsystem owns the answer. Someone whose printer will not boot should not have to know that the symptom table lives in a file called hardware-testing.md. Three topics were documented two and three times over, and each copy was free to drift: install in README and toolchange.md, calibration in README, calibration.md and toolchange.md, slicer setup in README and toolchange.md, "before you start" in all three. Each is now in one place. The owner path is Is this for you -> Installing -> After the flash -> Your first print -> Nozzle-offset calibration -> Printing -> Upgrading -> When something goes wrong, with error codes, versions and how-it-works behind a Reference group. The README keeps what a front door keeps: what this is, the status checkboxes, what you give up, which file to download, and where to go next. toolchange.md was four documents in one 38 KB file. The owner half -- slicer setup, filament, runout, the offset check before a first print -- is in Printing and Your first print; the design notes, input shaper, roadmap, HelixScreen and reverse-engineering notes stay, and the page moves to Internals. hardware-testing.md was split down the middle by audience the same way: the go/no-go checks and the symptom table were the owner's, and only keeping the two verification files honest as the macros change is ours. Two things this fixes rather than moves. The error-code table was notes/70-error-codes.md, an internals note the README sent owners to; it is docs/error-codes.md now, a page. And toolchange.md still opened "Not yet run on hardware" while the README's checkboxes described a Creator 5 Pro that has been printing for weeks -- the two pages have disagreed since the first hardware run. Contributors are deferred, as agreed: those pages are regrouped, not rewritten. The nav says so. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S3XZh4SqPdXAowVndz6tMr |