Commit Graph
98 Commits
Author SHA1 Message Date
ScottW514 abf85fccfe Add the gfcloud full-cloud controller daemon
gfcloud runs the machine under the Glowforge web service (the factory
cloud experience: the app drives homing, framing, printing). Its init
service starts it only when controller_mode = cloud - mutually exclusive
with grblHAL, which already stands down for that mode - so it owns
/dev/glowforge exclusively. Persistent GFUIService loop with a clean
SIGTERM shutdown that safes the hardware; the init script mirrors
grblhal.init. The image installs gfcloud and python3-ffmachine.
2026-08-08 19:08:13 -04:00
ScottW514 5d7ca46c07 Share the web-service machine glue between gfhome and gfcloud
Extract the shared-config identity overrides and the forgectrl-routed
ForgectrlMachine from gfhome into an installed module (python3-ffmachine);
gfhome imports it instead of carrying its own copy, so the coming gfcloud
daemon builds the same machine the same way.
2026-08-08 19:08:13 -04:00
ScottW514 26069a8258 gfhome: route actions through the shared cloud dispatcher
Replace the local dispatch table with gfutilities' dispatch_action
(allow_print=False), so the homing runner and GFUIService share one
action surface and cannot drift.
2026-08-08 18:51:06 -04:00
ScottW514 2b25a937a5 Bump grblhal-glowforge pin (gfcloud homing timeout fix)
b5c6d9c declares the shared config readers in glowforge_homing.c;
without the declaration the hard-float build read the homing-session
timeout from the wrong register and SIGTERMed every gfcloud homing
runner ~55 ms after spawn.
2026-08-08 17:47:08 -04:00
ScottW514 6811bbf825 Bump grblhal-glowforge pin to HEAD (CI workflow; no binary change) 2026-08-08 17:01:56 -04:00
ScottW514 25f2721500 forgectrl: wireless radio-policy revision; runbook: regulatory record
Bump to the forgectrl revision whose startup pass reloads
regulatory.db (required while the flashed kernel still has built-in
cfg80211 - its boot-time load fails pre-mount and stays failed
without a reload), hints a region only when one is set (unset =
automatic: the AP's 802.11d country, else world; a 00 hint over the
kernel's own world default reports the confusing intersection alias
"country 98"), and pins wlan0 power save off.

BRINGUP.md: bench record for the wireless-regulatory diagnosis and
the live-verified wifi_country / power-save flow; the kernel-batch
note now carries CFG80211/MAC80211=m, DEFAULT_PS off, and the lm75
vs-supply.
2026-08-08 16:51:06 -04:00
ScottW514 d2131c161b forgectrl: wireless region support; add iw runtime dep
Bump to the forgectrl revision that adds the wifi_country setting
(System-tab region picker); the daemon applies it with iw reg set at
startup and on change, so iw joins RDEPENDS. regulatory.db itself
ships via the glowforge-image base (wireless-regdb-static).
2026-08-08 15:32:47 -04:00
ScottW514 501e1d4591 installer: confirm target-slot content; record semantic version
Before writing the target slot, the installer now shows what it holds
(factory firmware v<ver>, ForgeFIRM, an unrecognized filesystem, or
unknown/unreadable content). Factory images are archived as before;
anything else requires the operator to type ERASE, since it is
overwritten without a backup. The archive manifest now records the
semantic FIRMWARE_VERSION (ver=), which the update manager displays in
the restore list. Bump forgectrl to the matching GUI change.
2026-08-08 14:54:28 -04:00
ScottW514 e9d3ce40a8 Bump forgectrl (legacy/sd slots shown only when present) 2026-08-08 14:42:13 -04:00
ScottW514 d1bbecb9ee forgefirm-keys: verification trust anchors; forgectrl update manager
/etc/forgefirm/keys ships the ForgeFIRM release-signing public key
and the Glowforge factory keyring (public keys only) - the update
manager verifies release downloads/uploads against the former and
factory archives against the latter. forgectrl SRCREV bumped to the
update-manager commit; runtime deps on ffboot, fwup, the keyring, and
curl made explicit.
2026-08-08 14:02:15 -04:00
ScottW514 6c418bfb92 docs: no bench-machine identity in public documents; re-pin forgectrl
The runbook no longer records the bench machine's fuse identity (a
fuse identity cannot be rotated, so a public document must never
carry it); the forgectrl pin follows that repo's history rewrite.
2026-08-08 13:37:22 -04:00
ScottW514 21251bc89f Bump forgectrl (units, fuse identity, always-on position, viewer) 2026-08-08 13:26:57 -04:00
ScottW514 cea0439e17 slotmigrate: sector counts from sysfs; log to kmsg
The image's busybox has no blockdev applet, so the grow path silently
skipped. Sector counts now come from /sys/class/block (no external
tool); log lines also go to /dev/kmsg so migration results are visible
in dmesg after boot.
2026-08-08 12:59:21 -04:00
ScottW514 6c9cce3184 gfhome: derive the service hostname from the effective serial
The gf_hostname override is gone (the forgectrl UI no longer offers
it): the hostname is a pure derivation of the serial - base 23 over
the factory consonant alphabet - so a gf_serial override re-derives
MACHINE.HOSTNAME and the fuse derivation stands otherwise. BRINGUP
records the panel rework (units, fuse identity, always-on position)
as offline-verified; board deploy and pin bumps held during the
firmware-upgrade bench testing.
2026-08-08 12:44:56 -04:00
ScottW514 1097184e13 installer v2: single-stage slot install; slotmigrate legacy reclaim
install-forgefirm.sh is now single-stage and never repartitions: run
from factory firmware, it archives every factory slot version plus the
recovery boot partitions to /data/forgefirm/archive (manifest with
md5s), verifies the signed forgefirm.fw against the embedded ForgeFIRM
pubkey (raw 32-byte form for the factory's fwup 0.14.2; dev key until
the production key ceremony), applies it to the INACTIVE slot with the
factory's own fwup, post-verifies the written rootfs, installs
/data/ffboot, and flips the saved env with read-back verification. The
booted factory slot stays installed and bootable; /data is untouched
beyond the archive. Fixed release asset name forgefirm.fw (version in
the fwup metadata and release tag).

slotmigrate (new recipe, rcS before mountall) reclaims the legacy
layout on eMMC-slot boots: deletes p4, grows p3 to the end of the
disk (sfdisk + partx BLKPG - works with a sibling partition as root),
then e2fsck+resize2fs. Every step is keyed off the actual disk state,
so interrupted runs resume and factory-layout disks are a no-op; SD
boots never touch the eMMC.
2026-08-08 12:26:33 -04:00
ScottW514 11fec891ed ffboot v2: slot inventory, verified atomic env flips, target probe
-l inventories every bootable partition (SD, eMMC slots 1/2, legacy
p4) as machine-parsable key=value lines: firmware type
(forgefirm/factory), version, kernel presence, booted/next markers,
plus the saved-env selection - the shared probe for the installer and
the forgectrl update manager.

Boot switching now writes all four selection variables (mmcdev,
mmchwpart, mmcpart, mmcroot) in one fw_setenv -s transaction and
read-back verifies, falling back from the libubootenv script format
to the classic u-boot-tools format to per-variable writes - the same
script works on factory firmware and ForgeFIRM. mmchwpart was
previously never set and a mixed env could survive a mid-flip power
cut. Switch targets must pass a content probe (rootfs mounts, kernel
present) unless -f. -e picks the newest factory slot by probing,
excluding slots occupied by ForgeFIRM.

The new ffboot recipe installs it as /usr/sbin/ffboot with
/etc/fw_env.config (factory-identical redundant env layout at eMMC
0x80000/0x82000) - previously the image shipped fw_setenv with no
config. Added to forgefirm-image.
2026-08-08 12:08:14 -04:00
ScottW514 b7eb5fdac5 docs: cooling GUI + diagnostics; bump forgectrl and grblhal
BRINGUP: the conf-backed cooling tunables, the Diagnostics runner
model and both cooling tools, and the 2026-08-08 bench record
(conf re-read drill, takeover semantics, flow-verify PASS 2:42,
flow-calibrate 8:45 recommending 14.8 vs the hand-derived 14.4).
Pins: forgectrl -> 86ff78b (Machine-tab cooling card + Diagnostics
tab + diag runner), grblhal -> ae85682 (cool_* conf keys re-read
per flood start).
2026-08-08 11:48:15 -04:00
ScottW514 2aac59e0e4 image: slot-sized release rootfs, ext4 artifact, fwup, mkfw.sh
The release image now targets the 200 MiB factory eMMC slot: content
plus 40 MiB working space, hard build failure past the slot size. The
raw ext4 is deployed alongside the wic; scripts/mkfw.sh packs it into
a signed .fw with factory-pattern upgrade.a/upgrade.b tasks. fwup
1.16.0 recipe (applies ForgeFIRM and Glowforge-signed archives on
device) is installed in both images. Dev images stay SD-sized with a
256 MiB working margin and no ceiling.

Verified on the 20260808153331 build: release ext4 180.8 MiB; signed
.fw applies byte-exact with fwup 1.16.0 and with the factory's 0.14.2
(raw-format pubkey), and 0.14.2 -V verifies the signature.
2026-08-08 11:37:19 -04:00
ScottW514 75e0eb24da Bump grblhal (flow suspicion state machine) 2026-08-08 10:59:47 -04:00
ScottW514 548d25a4ff Bump forgectrl (firmware version in the panel) 2026-08-07 21:32:59 -04:00
ScottW514 8baed9aa93 images: version stamp in /etc, shown at console and SSH login
Every image writes /etc/forgefirm-version and echoes "ForgeFIRM
<version>" on the serial-console login prompt (/etc/issue, beneath the
OpenGlow banner) and at SSH login (motd). Release images carry
v${FORGEFIRM_RELEASE}; the dev image stamps the build timestamp - the
same DATETIME as the artifact name - tagged (dev) so a bench machine
is never mistaken for a release.
2026-08-07 21:19:50 -04:00
ScottW514 4da39f6131 grblhal init: boot-time controller-mode dispatch
The init script consults controller_mode in /data/forgefirm.conf:
'cloud' (once that mode exists, with its own service reading the same
key) keeps grblHAL down; grbl, unset, or a missing config starts it.
Board-verified both ways: cloud in the conf leaves the controller
stopped with a clear message, grbl starts and serves normally.
2026-08-07 20:59:43 -04:00
ScottW514 607ceb32e7 Bump forgectrl (controller-mode selector, idle settings lock) 2026-08-07 20:56:16 -04:00
ScottW514 85914c16d0 Bump forgectrl (remote-interlock semantics); bench model + interlock facts in the runbook 2026-08-07 20:48:26 -04:00
ScottW514 4184e84558 Bump forgectrl and grblhal-glowforge to the OpenGlow-identity release
forgectrl ad0b441: OpenGlow branding, operational /status dashboard.
grblHAL-glowforge c472a13: position anchor at homing for the status
readers. Runbook updated.
2026-08-07 20:27:46 -04:00
ScottW514 bcf476be74 Bump forgectrl and grblhal-glowforge to the control-panel release 2026-08-07 20:06:17 -04:00
ScottW514 8cd98de605 gfhome: identity overrides from the shared config; budget from env
Non-empty gf_serial / gf_password / gf_hostname in /data/forgefirm.conf
(set from the forgectrl GF Cloud tab) are applied with set_cfg before
Machine() is built, so they beat the OCOTP fuse identity - Machine sets
its fuse values with keep_value. The --timeout default comes from
GFHOME_TIMEOUT_S when the controller provides it, so one GUI setting
governs the whole session. Docs: control-panel runbook notes.
2026-08-07 20:05:49 -04:00
ScottW514 c1d781a137 Bump forgectrl and grblhal-glowforge to the homing release
forgectrl 0b05e48: /settings homing-mode store + UI, snapshot lamp
override. grblHAL-glowforge 948f1c7: runtime-selectable $H with the
Glowforge web-service homing session (stream suspend/resume, gfhome
runner orchestration).
2026-08-07 19:27:52 -04:00
ScottW514 cf24bf3200 gfhome: capture through forgectrl; factory-board machine config
The runner's Machine subclass fetches lid/head images from the
forgectrl snapshot endpoint - forgectrl owns the imx-media pipeline
whenever a stream client (LightBurn) is connected, so direct V4L2
grabs fail busy. Head captures request lamp=0 (the cloud's focus
analysis needs torch-off images); the HCil measure-laser LED is still
driven directly. Direct capture remains the fallback when the daemon
is unreachable.

The sample config gains the factory-board settings: the estop motion
gate stays off (the board's estop sense reads low during any motion),
and the forgectrl URL is configurable.
2026-08-07 19:13:28 -04:00
ScottW514 f2a5d0f6b6 gfhome: one-shot Glowforge web-service homing runner
New recipe installing /usr/sbin/gfhome.py and /etc/gfhome.conf.sample
(copied to /data/etc/gfhome.conf on first run). The runner signs the
machine in with its fused identity, opens the WSS control channel with
a held client reference (a clean disconnect is impossible through
ws_connect), and drives the GFUIService dispatch table itself - minus
print - so the service's camera homing sequence (settings -> hunt ->
lid image -> corner move -> lid image) runs against the real hardware
Machine. The service ends the sequence silently, so completion is a
hunt plus at least one motion followed by a configurable quiet window;
the lens is then re-referenced against the hall sensor for a
deterministic Z. Lid/e-stop are checked before the session, print
actions are refused, and exit codes distinguish configuration and
connection failures from an incomplete homing.

Installed in both images; invoked by the grblHAL controller for $H
when homing_mode = gfcloud in /data/forgefirm.conf.
2026-08-07 18:32:53 -04:00
ScottW514 ad865bb3c3 grblhal-glowforge SRCREV 683a36a (comment-free core fix); BRINGUP cites the fork commit hash-free 2026-08-07 17:42:53 -04:00
ScottW514 4d22905c2f grblhal-glowforge SRCREV bdab31c: core tracks upstream master (PR 999 merged) + step_us_min fix 2026-08-07 17:31:15 -04:00
ScottW514 b30afd7171 grblhal-glowforge SRCREV 26298a3: fd-blocking pacing, step_us_min fix, accel homing removed 2026-08-07 17:22:36 -04:00
ScottW514 392bf49e5b forgectrl SRCREV 73283b6; BRINGUP: cached capture path bench-verified on flashed image 2026-08-07 16:43:47 -04:00
ScottW514 061def2343 grblhal-glowforge: recipe with boot autostart
gitsm-pinned build of the controller with a sysvinit script (defaults 92, after forgectrl), installed in both images. Reboot-verified on the bench: controller and forgectrl come up unattended and Grbl answers on TCP:23.
2026-08-03 17:22:07 -04:00
ScottW514 7b320c34ac forgectrl: bump SRCREV (VPU errored-frame handling) 2026-08-03 17:05:09 -04:00
ScottW514 8d798fa4b9 forgectrl: promote to its own repo, recipe fetches the pinned git source
Sources live at github.com/ScottW514/forgectrl (history extracted, layout src/ + init/); the recipe pins SRCREV and installs the init script from the repo. Adds the build-forgectrl.sh bench cross-compile script.
2026-08-03 14:06:25 -04:00
ScottW514 421909a6a8 forgectrl: NEON demosaic - 15 fps, sensor-limited
NEON kernel for the YUV420 superpixel convert (vld2q deinterleave, rounding-halving greens, mlal/rshrn luma, pairwise-add chroma block sums), bit-identical to the scalar path and proven so on a live frame via the FORGECTRL_NEON_CHECK one-shot memcmp. Convert 75 to 18 ms; the stream now runs at the OV5648 frame rate. Motion coexistence re-proven at 15 fps (clamped 0).
2026-08-03 13:46:08 -04:00
ScottW514 d75ff717ac forgectrl: VPU JPEG encode for the camera stream - 7.9 fps
Demosaic the superpixels straight to planar YUV420 and encode on the CODA960 (mainline coda V4L2 mem2mem, node found by personality); libjpeg stays as the automatic fallback and the snapshot path. All camera paths now demosaic from a cached bounce copy of the frame: the V4L2 MMAP capture buffers are uncached, and reading them in-place costs ~340 ms/frame vs 43 ms memcpy + 75 ms cached convert. Per-frame stats logged every 100 frames; /cam/status reports the encoder.
2026-08-03 13:31:48 -04:00
ScottW514 dc34fc6602 forgectrl: streams preempt - the newest camera request wins the mux
A stream request for the other camera kicks current stream clients via a generation counter (their streams end cleanly; viewers freeze on the last frame) and switches. The index page retry consults /cam/status first so a preempted view does not steal the camera back.
2026-08-03 12:47:16 -04:00
ScottW514 247cfacb40 forgectrl: cross-camera snapshot borrow and switch grace
Snapshots of the non-streaming camera no longer fail 409: the worker borrows the mux for one frame (stream viewers see a short freeze). Stream switches wait up to 3 s for the previous pin to drain. Arbitration compares the engine home camera, not the transiently borrowed pipeline camera. Index page: single toggled stream with retry plus a head-peek button.
2026-08-03 12:39:34 -04:00
ScottW514 b3a8924c91 forgectrl: implement the camera MJPEG service
Persistent imx-media capture engine (lid/head via the shared video-mux, 409 arbitration, 10 s idle teardown), 1296x972 MJPEG stream via 2x2 Bayer superpixel, full-resolution bilinear snapshots, mjpg-streamer-compatible aliases, sysvinit script; installed in both images. Bench-verified: 3.2 fps stream, clamped 0 during simultaneous motion.
2026-08-03 12:26:23 -04:00
ScottW514 f396dbde34 Remove history narrative and audit references from docs and tooling
temp_calibrate now cross-checks the factory B-equation instead of the retired linear guess.
2026-08-03 11:54:27 -04:00
ScottW514 e92cce2b7e forgefirm-image-dev: build on forgefirm-image
The dev image required the shared glowforge-image base directly, so it
was not a superset of forgefirm-image (it lacked v4l-utils, audit N12).
Require forgefirm-image and add forgectrl + debug tooling on top.
2026-07-26 16:15:25 -04:00
ScottW514 527660c2f5 forgefirm-image: add v4l-utils for camera bring-up
v4l2-ctl (alongside the already-present media-ctl) configures the
imx-media pipeline and grabs raw frames from /dev/video4 while the
gfhardware capture path is ported off the factory NXP V4L2 model.
2026-06-19 16:39:30 -04:00
ScottW514 00ef5a675b forgefirm-image: drop the gfui-client cloud client
gfui-client connects to Glowforge's servers; ForgeFIRM replaces it with a
local grblHAL controller (forgectrl). Remove it from the image via an
override, leaving the shared glowforge-image base untouched.
2026-06-19 10:33:58 -04:00
ScottW514 d42a1588c7 Port meta-forgefirm to Scarthgap
- LAYERSERIES_COMPAT -> scarthgap
- Yocto 3.4+ override syntax (:remove/:append/:${PN})
- ulfius: explicit protocol=https;branch=master on the git SRC_URI
2026-06-19 10:33:52 -04:00
ScottW514 9d520e04d9 initial commit 2020-04-15 17:13:51 -04:00