code wiki / _hdl_build / nx_gcode_job_gate.nx

nx_gcode_job_gate.nx source

↩ module page · 59 lines · 3792 B

1// nx_gcode_job_gate.nx -- second STATE_MACHINE composition gate (NXMOTION M1 seed): the 2// PRINT-JOB LIFECYCLE machine authored by _gjob_author via emit13. States 0=IDLE 1=HOMING 3// 2=READY 3=PRINTING 4=PAUSED 5=COMPLETE; events 0=home_cmd 1=home_done 2=start 3=pause 4// 4=resume 5=finish. THE SAFETY LAW IS THE TABLE: an unhomed start REFUSES (the Klipper-class 5// "must home before print" property, as a gate not a comment). Durable: GJOB-ROW/GJOB-GATE -> 6// knowledge/status/gcode_job_gate.log. Exit 0 iff all rows pass. Owner: Engineer (verify). 7// license_tier: ORIGINAL 8import "_pe_gjob.nx" 9import "nx_syscalls.nx" 10 11func gj_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd, s, n); return 0 } 12func gj_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m; sys_write(fd,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 } 13 14func gj_row(lfd: i64, name: *u8, got: i64, want: i64) -> i64 { 15 gj_w(1, " " as *u8); gj_w(1, name); gj_w(1, ": got=" as *u8); gj_wn(1, got) 16 gj_w(lfd, "GJOB-ROW name=" as *u8); gj_w(lfd, name) 17 gj_w(lfd, " got=" as *u8); gj_wn(lfd, got); gj_w(lfd, " want=" as *u8); gj_wn(lfd, want) 18 if got == want { gj_w(1, " PASS\n" as *u8); gj_w(lfd, " verdict=PASS\n" as *u8); return 1 } 19 gj_w(1, " FAIL\n" as *u8); gj_w(lfd, " verdict=FAIL\n" as *u8) 20 return 0 21} 22 23// run the first n of a 6-slot event sequence from IDLE 24func gj_run(e0: i64, e1: i64, e2: i64, e3: i64, e4: i64, n: i64) -> i64 { 25 let ev: *i64 = sys_mmap(64) as *i64 26 ev[0]=e0; ev[1]=e1; ev[2]=e2; ev[3]=e3; ev[4]=e4 27 return _pe_gjob_run(ev, n, 0) 28} 29 30func main() -> i64 { 31 gj_w(1, "=== GCODE JOB GATE: print-job lifecycle law on the team-authored machine ===\n" as *u8) 32 let lfd: i64 = sys_openat_append("knowledge/status/gcode_job_gate.log" as *u8, 0x1a4) 33 if lfd < 0 { gj_w(1, " gate log open FAILED -- loud fail\n" as *u8); sys_exit(1); return 1 } 34 var pass: i64 = 0 35 // [1] happy path: home, done, start, pause, resume -> PRINTING(3) 36 pass = pass + gj_row(lfd, "home-start-pause-resume" as *u8, gj_run(0, 1, 2, 3, 4, 5), 3) 37 // [2] full job: home, done, start, finish -> COMPLETE(5) 38 pass = pass + gj_row(lfd, "full-job-completes" as *u8, gj_run(0, 1, 2, 5, 0, 4), 5) 39 // [3] THE SAFETY LAW: start while IDLE (unhomed) refused 40 pass = pass + gj_row(lfd, "unhomed-start-refused" as *u8, gj_run(2, 0, 0, 0, 0, 1), 0 - 1) 41 // [4] start while HOMING (home not done) refused 42 pass = pass + gj_row(lfd, "mid-homing-start-refused" as *u8, gj_run(0, 2, 0, 0, 0, 2), 0 - 1) 43 // [5] pause before printing refused 44 pass = pass + gj_row(lfd, "pause-before-print-refused" as *u8, gj_run(0, 1, 3, 0, 0, 3), 0 - 1) 45 // [6] resume without pause refused 46 pass = pass + gj_row(lfd, "resume-without-pause-refused" as *u8, gj_run(0, 1, 2, 4, 0, 4), 0 - 1) 47 // [7] nothing after COMPLETE 48 let ev6: *i64 = sys_mmap(64) as *i64 49 ev6[0]=0; ev6[1]=1; ev6[2]=2; ev6[3]=5; ev6[4]=2; ev6[5]=0 50 pass = pass + gj_row(lfd, "restart-after-complete-refused" as *u8, _pe_gjob_run(ev6, 5, 0), 0 - 1) 51 gj_w(lfd, "GJOB-GATE rows=7 pass=" as *u8); gj_wn(lfd, pass) 52 if pass == 7 { gj_w(lfd, " verdict=GREEN\n" as *u8) } else { gj_w(lfd, " verdict=RED\n" as *u8) } 53 sys_close(lfd) 54 gj_w(1, " --- GCODE JOB GATE: " as *u8); gj_wn(1, pass); gj_w(1, "/7 rows ---\n" as *u8) 55 if pass == 7 { gj_w(1, " GCODE JOB GATE: GREEN (home-before-print law held by authored machine)\n" as *u8); sys_exit(0); return 0 } 56 gj_w(1, " GCODE JOB GATE: RED (fix the table or the emitter, never the gate)\n" as *u8) 57 sys_exit(1) 58 return 1 59}