mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-22 21:32:16 -05:00
2b3772664aa9aef488b349615218e9c0c07b9fa7
10
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
b5982b09bb |
Fix eleven defects the first pass introduced
An adversarial re-read of master..HEAD, checking the new text rather than
trusting it. The substantive work held up -- all eight dead-code removals prove
out, SAFE-MODE->MOD_UI is complete, A3's reordering is correct -- but eleven
claims were wrong, and one made a document worse than it found it:
* docs/notes/10-hardware.md said `temperature_sensor motor_value` on
eboard:PA1 is "not in anything this repo ships". It is:
printer.motor.cfg:37 declares it and that file is in the package, which is
also why ff-toolchange.cfg can name MOTOR_STOP. The real nuance is that
printer.base.cfg does not include printer.motor.cfg. A correct claim in
25-app-vs-klipper-ownership.md was "corrected" into a false denial.
* docs/toolchange.md pointed at a worked example that reaches 0.125 mm. The
only example is NOZZLE=220 BED=80, which gives 0.045; the 0.08 bed term
needs a bed at 100 or above. Both numbers now stated, no forward reference.
* docs/testing.md said 48 tests; pytest collects 53.
* test_config_ownership.py cited bin/patch.sh:80/:88/:128 -- correct on
master, shifted by two when this branch deleted MARK_BEGIN/MARK_END. The
line numbers are dropped rather than re-pinned, so they cannot rot again.
* test_includes.py invented a reason for ff-legacy being last ("so its import
sees every [ff_tool] already declared"). ff_legacy resolves tools at
klippy:ready; order does not matter.
* fetch-assets.sh's replacement usage text omitted BUILD_MOONRAKER and was
less accurate than the vague line it replaced.
* 49-runout's sensor table still claimed `extruder: extruderN` after the A1
fix made that true only of our override, not of the stock file it describes.
* firmwareExe kept "newest version directory" after the same claim was
corrected in how-it-works.md.
* 25-app inverted the preflight call order and omitted that an M23 print gets
neither call.
* creator5-safe-moves.gcode called the prepare's G1 Z10 "the one move" below
Z50; the G28 and offset move before it also go below.
* DOC-DRIFT-AUDIT.md asserted both "Every finding has been applied" and
"Nothing in this file has been applied", and cited five commits after a
hash the rebase had rewritten.
53 passed.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
d05565284d |
Sections E, F, G: wrong values, stale claims, overclaims
E -- values and counts. The START_PRINT prologue has no M400 and an idle timeout of 864000, not 1800000. The nozzle-clean temperature comes from the material table FIRST, so NOZZLE=240 with no per-tool temp cleans at 220 -- documented backwards before. TOOLS is the paired 0:220,2:240 form. The wipe Z is the raw eddy frame, not the homed one. The runout M117 strings are "T<n> clog" / "T<n> out of filament", not E-codes. Grab-verify raises E0051+tool, not E0143. Docks are at X~297; 250/280 are staging waypoints. The grab sequence is documented in the order _grab actually emits it. ff_print exposes seven status fields, not nine, and never emits TOOLS=. Package sizes reconciled against the real artifacts (62MB built, ~93MB stock, ~370MB of CI assets, ~60s not 90s). testing.md's sample output block matched no header the code prints, so it is replaced with the real ones; its pytest row listed two of six suites. F -- stale claims. _FF_PREFLIGHT is not "missing". SDCARD_SET_CHANNEL is not still issued ( |
||
|
|
e5bd171cf8 |
Correct the docs the code had drifted away from
Applies the audit's sections B, C and D, plus two decisions. Behaviour (A1): fm_ex1..3 carried stock's `extruder: extruder`, so a clog on T1..T3 was measured against T0's filament movement. Each motion sensor now watches its own extruder. Gate count (A6): "four gates" was the number of make test-* targets, not of gates run -- run-tests.py emits twelve. The number is dropped rather than restated, in docs/testing.md and the Makefile help. B, install instructions that failed as written: STOCK_TGZ_CREATOR5 missing its .tgz; a pointer to a ./build.sh that does not exist; klippy-extras/ paths that moved to payload/klipper/extras/ in 0ef9d6b; a calibration recipe both commands refuse without PLATE_REMOVED=1; a storage table that put dock_x/dock_y in an include, which SAVE_CONFIG refuses; four files telling the user to add includes printer.base.cfg already ships; ./pack.sh style paths that do not resolve from where the scripts leave you. The MAINSAIL_ZIP / HELIX_TGZ override was documented in three places as "used as-is, never checksummed". It is checksummed, and fetch-assets.sh overwrites the user's file with the pinned release -- SKIP re-downloads too. Corrected, with the way that actually works (match the hash in versions.env). C, files that contradicted themselves: the -5/-3 ESTOP target, the t<n>_offset_* storage names, the chamber heater's model split, the LED premise, the include order comment in test_includes.py, gear_stepper as a "feed hub" when it is the tool lock, an object list ff-toolchange.cfg says does not exist, the eddy probe vs the under-bed cylinder, "installs them without clobbering" against a gate that enforces the clobber, "keeps two versions" when the installer keeps one, "two changes from stock" when there are three, and ff_legacy's "nothing here runs during normal operation" when auto_import runs on every ready. D, dangling references: OKF/* and firmwareExe-decompiled/* repointed at docs/notes/*, plus case-boot.sh, sim-image.sh, printer-exec.sh, the test/printer build context, wait_for_banner, ff_toolchanger_compat and a nonexistent orca snippet. Not touched, pending a decision: sections E-H, and the printer.base.cfg "verbatim" claim (A7), which depends on how the unpack drift check is fixed. 48 passed, 5 skipped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
15ef06dcef |
Ship [ff_print], fold _FF_PRINT_END into END_PRINT, drop the origin flag
Three things the ff_print move left behind.
[ff_print] was declared nowhere. The module shipped (bin/patch.sh copies
ff_*.py) and the docs promised a stock Orca profile would work, but the
section that instantiates it existed only as a commented-out snippet in a
header and was missing from the required-includes list in docs/toolchange.md.
Following the docs got you the module on disk and nothing wrapping
SDCARD_PRINT_FILE -- so a stock profile printed from its own start block,
whose first motion is G1 Z5 F2400 on an unhomed machine. Declared in
ff-print-macros.cfg, which is already required and already included after
[virtual_sdcard].
_FF_PRINT_END existed only so END_PRINT and CANCEL_PRINT could share a body.
END_PRINT is the public exit macro, symmetric with START_PRINT, so it holds
the body and everything calls it.
_FF_JOB.mainsail told CANCEL_PRINT whether we started the job, because
FlashForge's touchscreen sends CANCEL_PRINT itself and then runs its own
motion cleanup that ours must not double. HelixScreen starts prints through
Moonraker exactly as Mainsail does, and the stock UI is not one this mod
ships, so the flag guarded a caller that no longer exists -- along with a
documented corner case where an abnormal end left it stuck at 1.
Plus the text those moves invalidated: the orphaned "WHY THIS WRAPPER EXISTS"
block in ff-toolchange.cfg (its FIXME described four SDCARD_* lines deleted in
|
||
|
|
a7e0b3fd3e |
Bring the MCU handshake in line with the decompiled stock routine
The level board never left its bootloader, so klippy died on
"mcu 'levelboard': Wait for identify_response". Four separate defects,
three of them in ff-mcu-bringup.py and all of them visible in the
printer's own output once you line the runs up.
The ack. ttyS7 answers 0x01 to 'A', every time, where ttyS4 answers 0x06.
The script sent 'A' once, saw a byte it did not recognise, printed "sent
the banner but acked b'\x01'" and gave up -- leaving the board in its
bootloader. So the three bootSerial* routines were disassembled out of
1.9.7's firmwareExe rather than guessed at any further, and stock does
this:
send = 'A'
for (j = 0; j < 0x32; j++) {
write(fd, &send, 1);
read(fd, &recv, 1);
if (recv == 6) { isAck = 1; break; }
}
Fifty attempts, and the reply is ignored except as a reason to stop
early: isAck is initialised to 1 and never assigned 0 anywhere in the
function, so the ack byte cannot fail the handshake at all. We now do
the same fifty writes and treat a non-0x06 byte as information, not a
verdict.
One port at a time. poke() opened, polled and closed each device in
turn, and a serial port nobody holds open is shut down in the driver --
so every banner ttyS7 sent while ttyS4 was being polled went in the bin.
That is the whole explanation for the two ports taking turns reporting a
banner across consecutive runs. Both are held open for the pass now.
A read count instead of a clock. MAX_READS=50 was documented as a ~5s
ceiling, which holds only when the board says nothing: VTIME=1 bounds an
*idle* read at 0.1s, and a board that is talking returns reads instantly.
Fifty of those can elapse in milliseconds. The pass is on a wall clock
now.
"No banner" reported as "already running". It is not the same thing, and
the printer proved it: ttyS4 was declared already-running on one pass and
sent a bootloader banner on the next. Stock's ready phase is only ~5s and
never waits for a second banner, so it only ever worked when it ran right
after the board powered up; the banner period is longer than that window.
An unknown is reported as an unknown now, and a board that keeps
bannering after fifty 'A' is reported as still in its bootloader.
Separately, start.sh tested -x on the script and printed "missing" while
it sat right there in /usr/data/anvil/bin. It is handed to the
interpreter by path, so the execute bit is irrelevant -- the payload
carries mode 644 in git and only patch.sh and run-append.sh ever chmod
it. Tests -f now.
Verified against ptys standing in for the boards: heat acking 0x06 and
level acking 0x01 both come up; a board that yields 0x06 only on the
eleventh 'A' is caught in 0.2s; a board that keeps bannering is reported
as stuck with a non-zero exit; a silent port reports the real deadline;
missing devices still name both ports and do not raise.
docs/notes/10-hardware.md carries the decompiled handshake, including the
two things the three routines do not share and stock's odd
tcsetattr(fd, TCSETS, ...).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
3a28fdf65b |
Drop test-chelper and its build gate
test-chelper.py compared c_helper.so's exported symbols against the cdef blocks in the klippy tree shipped beside it, and bin/patch.sh ran it as a hard build gate with ALLOW_STALE_CHELPER=1 as the escape hatch. Both are gone, along with the Makefile target, the suite entry and the ALLOW_STALE_CHELPER passthrough that had nothing left to pass through. patch.sh still refuses a c_helper.so that is not MIPS32r2/nan2008/o32, so the ABI failure mode is still caught. The symbol failure mode is not: cffi resolves lazily, so a .so older than its klippy imports cleanly, passes the ABI check, installs, boots, and dies at connect with a traceback that names cffi rather than the stale build. That is a real thing that shipped once, so it is written down in docs/building.md and docs/notes/20-klipper-fork.md rather than left for someone to rediscover -- the fork path this guarded is winding down anyway, per the same note. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
607e6595fb |
Start the camera ourselves: mjpg-streamer was on the disk all along
Correcting the previous commit, which said the :8080 stream could not be
restored without cross-compiling a streamer. Both halves are actually true:
* firmwareExe really did serve the stream itself -- its own accept loop,
`GET /?action=stream`, boundarydonotcross, even announcing
`Server: MJPG-Streamer/0.2` -- so killing it does take the camera down.
* ...but /usr/prog/mjpg-streamer/ ships the genuine article: mjpg_streamer,
input_uvc.so, output_http.so, its own libjpeg.so.9 and www/.
app_startup.sh:159 exports LD_LIBRARY_PATH for it and then never launches
it. Nothing needs building; the binary just needs starting.
S65camera does that, on the S50wifi pattern -- the wait for /dev/video0 and the
respawn loop run in a background subshell, so a printer with no camera plugged
in never holds up Klipper or the UI. stop() kills the supervisor before the
streamer, or it would come back three seconds later.
Two details are load-bearing and easy to lose: libjpeg.so.9 lives in the
mjpg-streamer directory, so without LD_LIBRARY_PATH the binary dies on a
missing shared object (the same trap moonrakerDaemon has in S60web); and the
plugin .so names resolve against the working directory, hence the cd.
nginx proxies it at /webcam/ with buffering off and no read timeout, since
MJPEG is one endless response, and moonraker.conf's [webcam] entry uses
relative URLs through that proxy -- so one forwarded port carries the stream,
tunnels included. MOD_CAM=0 turns it off; MOD_CAM_RES/FPS/PORT tune it.
The earlier claim is corrected in docs/notes/25 and in the README, which no
longer lists the camera as something you give up.
Verified: parses under the printer's own busybox ash, lint-danger clean. The
full suite was not re-run to completion -- the working tree is being edited
concurrently and a build lane raced it (tar: file changed as we read it).
bin/patch.sh's MOD_CAM line is deliberately left out of this commit for the
same reason.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
5bdf78109a |
Retire firmwareExe: own the web stack, and say what goes with it
The mod replaces FlashForge's application outright, so the reasoning that still framed the web stack as coexisting with it was wrong on its own terms. * nginx and moonraker are documented as the only web stack on the printer. MOD_WEB=0 is a debugging switch that leaves ssh and the touchscreen, not a way back to stock -- that is a stock FlashForge package. The own-prefix rule stays, for the reason that is actually true: /usr/prog is the firmware partition and every FlashForge package reinstalls it, so a config written there is undone by the next stock flash. * Configs the mod ships now update when you have not edited them. A live file still byte-identical to the one the last package wrote is replaced; one you changed is kept and the new version lands beside it as .mod-new. $MODDIR/config-installed holds that last-written copy. Without this a config we own could only ever be written once: it exists on the second flash, so it would land as .mod-new forever and updates would never reach the printer. * Dropped the three dead /server/files/ alias blocks from nginx.conf. The regex location above them matches /server/ too and nginx gives regex locations precedence, so they never fired -- and had they fired, serving those paths from disk would 405 the DELETE and POST that Mainsail sends to the very same URLs. * Recorded what dies with firmwareExe, in docs/notes/25 and in the README: the :8898 REST API (FlashPrint, Orca's FlashForge profile, the mobile app) and the :8080 camera stream. The camera is the one that looks restorable and is not -- the MJPEG server is compiled into firmwareExe (its own accept loop, `GET /?action=stream`, boundarydonotcross) rather than being mjpg-streamer, so there is no daemon left to point a [webcam] at. assets/moonraker.conf carries the block, commented, for when a streamer is built for this board. Also in this change: the MOD_UI switch and the stock-UI path are gone, the chamber-heater model gate arrives with ff-model.cfg/ff-chamber.cfg, and the tests follow. make test: 32 passed, 1 failed. The failure is the probe end-to-end, which dies at "mount: failed to setup loop device for /stick.img" -- leaked loop devices on this build host, not the package. Probe installs nothing, and the default profile's install -> re-install -> boot passes in the same run. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
44d45f2c46 |
Repoint the toolchange docs at their new paths
The imported README and notes still described a standalone checkout: relative links to klippy-extras/ and config/ that no longer resolve, an scp recipe naming the old directories, and a header about the klipper-vanilla and main branches, neither of which exists here. Paths now point at payload/klipper/ and assets/orca/, and the header keeps the not-yet-run-on-hardware warning without the branch bookkeeping. Every relative link in docs/ resolves. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GgNhSa1Qvwvxb2nQXT6b1Y |
||
|
|
0ef9d6b86b |
Move the imported toolchange files into this repo's layout
Pure renames, no content changes, so `git log --follow` walks straight back into the toolchange history imported by the previous commit. klippy-extras/ff_*.py -> payload/klipper/extras/ config/ff-*.cfg -> payload/klipper/config/ helixscreen/*.json -> payload/helixscreen/printer_database.d/ orca/ -> assets/orca/ docs/notes/ -> docs/notes/ README.md -> docs/toolchange.md payload/ is the right home for the first three: they are files that ship to the printer, which is what everything else under payload/ is. The Orca snippets go to assets/ instead -- they are pasted into a slicer on the desktop and never reach the machine. bin/patch.sh still reads them from $TOOLCHANGE; the next commit points it here. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GgNhSa1Qvwvxb2nQXT6b1Y |