mirror of
https://github.com/openglow-org/forgefirm.git
synced 2026-09-27 08:41:13 -07:00
Controller promoted to canonical driver repo grblHAL-glowforge
The step backend now lives in github.com/ScottW514/grblHAL-glowforge (grblHAL driver convention: core submodule, driver.c HAL, board header). Add build-glowforge.sh, update the BRINGUP runbook (no -t throttle, EEPROM path, kill-before-scp, producer stats line, reset/disconnect semantics), and teach bench_m2.py to parse the F: status field (no spindle registered = no FS: field). Settings-write crash fix is upstream as grblHAL/core PR 999.
This commit is contained in:
+44
-26
@@ -1,7 +1,8 @@
|
||||
# ForgeFIRM bring-up status & cold-start runbook
|
||||
|
||||
Last updated: **2026-08-02** — milestone 2 (factory-true motion tuning)
|
||||
bench-verified.
|
||||
bench-verified, and the controller promoted to a canonical grblHAL driver
|
||||
repo (**grblHAL-glowforge**) with bench parity re-proven on hardware.
|
||||
Read together with `AUDIT_ACTION_PLAN.md` in the project root (sibling of
|
||||
this repo; per-finding status of the 2026-07-03 audit) and
|
||||
`kernel-module-glowforge/UAPI.md` (the pulse-stream feeder contract).
|
||||
@@ -63,7 +64,7 @@ motion constants were extracted from the `_RESOURCES` pulse files
|
||||
`/sys/class/leds/lid_led*/target`) and resets analog config (below).
|
||||
- **Build host**: WSL2 distro `forge-yocto`, tree at
|
||||
`~/dev/openglow-forgefirm`. `~/src-sync.sh` rsyncs the Windows repos in
|
||||
(now includes `python3-gfhardware`). Build:
|
||||
(includes `python3-gfhardware` and `grblHAL-glowforge`). Build:
|
||||
`cd ~/dev/openglow-forgefirm/forgefirm && kas shell
|
||||
kas/forgefirm-glowforge.yml -c 'bitbake forgefirm-image
|
||||
forgefirm-image-dev'`. Artifacts:
|
||||
@@ -73,29 +74,42 @@ motion constants were extracted from the `_RESOURCES` pulse files
|
||||
-c '...'` eats `$VAR` expansions (use script files run via PowerShell,
|
||||
not Git Bash, which MSYS-mangles `/mnt/c` paths).
|
||||
|
||||
## Running the step backend (grblHAL on the board)
|
||||
## Running the controller (grblHAL-glowforge on the board)
|
||||
|
||||
Source: the ForgeFIRM grblHAL step backend (grblHAL core + the
|
||||
glowforge pulse-stream sink).
|
||||
Source: `C:\dev\openglow-forgefirm\grblHAL-glowforge` — the **canonical
|
||||
grblHAL driver repo** (github.com/ScottW514/grblHAL-glowforge, branch
|
||||
`main`): core as a submodule at `src/grbl` (→ ScottW514/core fork, branch
|
||||
`forgefirm`, carrying the settings-write crash fix, PR'd upstream as
|
||||
grblHAL/core#999), `driver.c` implementing the HAL, machine constants in
|
||||
`src/boards/glowforge.h`. Architecture: a wall-paced producer thread runs
|
||||
the core stepper ISR against a virtual step clock (1000× machine tick)
|
||||
and maps step events to pulse bytes; a SCHED_FIFO shipper feeds
|
||||
`/dev/glowforge` with the bounded queue; a recursive core mutex stands in
|
||||
for interrupt masking. `GFSINK` unset = null-sink mode (full engine, no
|
||||
hardware I/O — host testing).
|
||||
|
||||
1. Build: cross-compile the backend in the forge-yocto WSL distro (from
|
||||
PowerShell). Produces `build-arm/grblHAL_glowforge` in the WSL tree
|
||||
(`-O1 -g`, `GLOWFORGE_DEFAULTS=ON` → machine constants baked in:
|
||||
53.333 µsteps/mm XY @ ×8, 2.832 half-steps/mm Z, 0.417" Z travel,
|
||||
12000 mm/min max, 700/590 mm/s² accel — factory-derived, see
|
||||
`puls_profile.py`).
|
||||
2. Deploy to `/usr/bin/grblHAL_glowforge` on the board.
|
||||
3. Start: `cd /data && GFSINK=/dev/glowforge grblHAL_glowforge -p 23 -n -t 1.0`
|
||||
(`-t 1.0` is REQUIRED: the real-time throttle is what bounds the
|
||||
queue). Env knobs: `GFSINK_RATE` (machine tick, default 28160 Hz =
|
||||
1. Build: `wsl -d forge-yocto -- bash <repo>/forgefirm/scripts/bench/build-glowforge.sh`
|
||||
(from PowerShell). Produces `build-arm/grblHAL_glowforge` in the WSL
|
||||
tree (`-O1 -g`; machine constants live in `src/boards/glowforge.h`,
|
||||
force-included into the core: 53.333 µsteps/mm XY @ ×8, 2.832
|
||||
half-steps/mm Z, 0.417" Z travel, 12000 mm/min max, 700/590 mm/s²
|
||||
accel — factory-derived, see `puls_profile.py`).
|
||||
2. Deploy to `/usr/bin/grblHAL_glowforge` on the board (kill the running
|
||||
instance first — the binary can't be overwritten while executing).
|
||||
3. Start: `cd /data && GFSINK=/dev/glowforge grblHAL_glowforge -p 23 -e
|
||||
/data/EEPROM-glowforge.DAT` (no `-t` — real-time pacing is intrinsic
|
||||
now). Env knobs: `GFSINK_RATE` (machine tick, default 28160 Hz =
|
||||
factory travel tick), `GFSINK_DEPTH_MS` (queue depth = feed-hold
|
||||
latency, default 200). The sink applies the full analog machine config
|
||||
itself at init (×8 modes, decay 1, motor_lock 8, laser latched, PIC
|
||||
hold currents) and swaps PIC run/hold currents around motion — the old
|
||||
manual sysfs block is no longer needed. If the baked $-defaults
|
||||
changed since the last run, `$RST=$` once (stored settings win).
|
||||
latency, default 200). The driver applies the full analog machine
|
||||
config itself at init (×8 modes, decay 1, motor_lock 8, laser latched,
|
||||
PIC hold currents) and swaps PIC run/hold currents around motion. If
|
||||
the baked $-defaults changed since the last run, `$RST=$` once (stored
|
||||
settings win). Each motion run logs a producer-stats line to stderr
|
||||
(callbacks, µs/call, max-behind, clamped) — clamped should stay 0.
|
||||
4. Connect LightBurn/UGS to `172.16.1.97:23`, or jog raw:
|
||||
`$J=G91X40F1200`.
|
||||
`$J=G91X40F1200`. `^X` mid-motion aborts via kernel `cnc/stop`
|
||||
(controlled decel) and raises an alarm; TCP disconnects never kill the
|
||||
process (the deadman fd stays held).
|
||||
|
||||
## Hardware facts bank (measured)
|
||||
|
||||
@@ -143,8 +157,12 @@ glowforge pulse-stream sink).
|
||||
backend; underrun → grblHAL alarm; interlock-trip recovery check.
|
||||
5. **6.6 camera service**: persistent MJPEG (ulfius, forgectrl) — also the
|
||||
natural time for the deferred 5.6 emulator smoke (homing images).
|
||||
6. **Housekeeping**: upstream the settings-write crash fix (grblHAL
|
||||
crashes on every runtime $-settings write — NULL chained
|
||||
`grbl.on_settings_changed` in gcode.c's gc_init); Phase 7 doc sweep
|
||||
(CLAUDE.md charter refresh, README roadmap); kas flip + first GitHub
|
||||
release per kas/README.md once ready to publish.
|
||||
6. **Housekeeping**: ~~pick the controller's remote home~~ **DONE
|
||||
2026-08-02** — the controller is now the canonical driver repo
|
||||
`github.com/ScottW514/grblHAL-glowforge` (+ `ScottW514/core` fork;
|
||||
the settings-write crash fix is upstream PR grblHAL/core#999; repoint
|
||||
the submodule to upstream when it merges). Remaining: a Yocto recipe
|
||||
for grblHAL-glowforge in meta-forgefirm (pin SRCREV; fills the
|
||||
`forgectrl` slot per kas/README.md), Phase 7 doc sweep (CLAUDE.md
|
||||
charter refresh, README roadmap), kas flip + first GitHub release per
|
||||
kas/README.md once ready to publish.
|
||||
|
||||
@@ -8,6 +8,7 @@ target board (dev image, python3 present) unless noted.
|
||||
| `feeder.c` | Spike-step-3 underrun proof: streams NOP pulse bytes to `/dev/glowforge` with wall-clock pacing, bounded queue depth, deadman flock, SCHED_FIFO. Usage: `feeder <hz> <seconds> <depth_ms>`. Passed 100 kHz × 120 s under full load with 0.2 ms worst write latency. Cross-compile with `build-feeder.sh` (WSL). |
|
||||
| `bench_phase2.py` | End-of-data protocol bench (audit M2–M5): underrun detection/ack, parked no-replay guard, resume(0), continuous-feed stability, 20× run/underrun cycles. Motion-safe (motors locked, laser latched). 16/16 PASS on 2026-07-26. |
|
||||
| `check_pwm.py` | Laser PWM register check (audit M8): reads PWM2 PWMCR/PWMPR via /dev/mem, expects divider 13 × ~127 counts ≈ 40 kHz. The scope on LASER_PWM remains the final pre-live-fire gate. |
|
||||
| `build-glowforge.sh` | Cross-compiles **grblHAL-glowforge** (the canonical driver repo, `../../../grblHAL-glowforge`) in the forge-yocto WSL distro. Run: `wsl -d forge-yocto -- bash <path>/build-glowforge.sh` (from PowerShell; Git Bash mangles /mnt/c paths). This is the production controller build. |
|
||||
| `build-feeder.sh` | Cross-compiles `feeder.c` the same way. |
|
||||
| `puls_profile.py` | Decodes factory `.puls` streams (raw or GF1-headered) into velocity/accel profiles: peak speeds, ramp-slope fits, per-move segments, Z cadence. Runs anywhere (stdlib only). Source of the factory-true grblHAL defaults (milestone 2): 700/590 mm/s² accel, 200 mm/s max rate, 28160 Hz travel tick. |
|
||||
| `bench_m2.py` | Milestone-2 motion bench, runs against the board over TCP:23: bounded round-trip jogs (sanity, max-rate, diagonal) + feed-hold/resume mid-move, reporting peak feed, state transitions, and position drift. All-green 2026-08-02 at factory-true settings. |
|
||||
|
||||
@@ -75,9 +75,12 @@ class Grbl:
|
||||
state = st[1:].split('|')[0]
|
||||
if not states or states[-1] != state:
|
||||
states.append(state)
|
||||
for f in st.split('|'):
|
||||
for f in st[1:-1].split('|'):
|
||||
# FS:feed,speed with a spindle registered; F:feed without
|
||||
if f.startswith('FS:'):
|
||||
peak = max(peak, float(f[3:].split(',')[0]))
|
||||
elif f.startswith('F:'):
|
||||
peak = max(peak, float(f[2:].split(',')[0]))
|
||||
if state.startswith('Idle'):
|
||||
return peak, states
|
||||
time.sleep(poll)
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# Cross-compiles grblHAL-glowforge (the canonical driver repo) for the
|
||||
# factory board, borrowing the Yocto cross toolchain from the ulfius work
|
||||
# directory. Run from PowerShell: wsl -d forge-yocto -- bash <path>.
|
||||
set -e
|
||||
TC=/home/builder/dev/openglow-forgefirm/forgefirm/build/tmp/work/cortexa9t2hf-neon-fslc-linux-gnueabi/ulfius/2.7.15
|
||||
export PATH="$TC/recipe-sysroot-native/usr/bin:$TC/recipe-sysroot-native/usr/bin/arm-fslc-linux-gnueabi:$PATH"
|
||||
cd /home/builder/dev/openglow-forgefirm/grblHAL-glowforge
|
||||
rm -rf build-arm
|
||||
cmake -B build-arm \
|
||||
-DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=arm \
|
||||
-DCMAKE_C_COMPILER=arm-fslc-linux-gnueabi-gcc \
|
||||
-DCMAKE_BUILD_TYPE=None \
|
||||
"-DCMAKE_C_FLAGS=--sysroot=$TC/recipe-sysroot -mthumb -mfpu=neon -mfloat-abi=hard -mcpu=cortex-a9 -O1 -g" \
|
||||
"-DCMAKE_EXE_LINKER_FLAGS=--sysroot=$TC/recipe-sysroot" \
|
||||
> /tmp/cmake-gf.log 2>&1
|
||||
cmake --build build-arm -j8 > /tmp/gfbuild.log 2>&1 || { tail -30 /tmp/gfbuild.log; exit 1; }
|
||||
echo BUILD-OK
|
||||
file build-arm/grblHAL_glowforge 2>/dev/null || ls build-arm/
|
||||
Reference in New Issue
Block a user