code wiki / _hdl_build / nx_jam_check_test.nx

nx_jam_check_test.nx source

↩ module page · 105 lines · 6076 B

1// nx_jam_check_test.nx -- ACCEPTANCE GATE for the jam-physics pre-flight. Every KAT is 2// hand-computed exact integer math (units: um / milli-mm^3 / ms): 3// flow = ((E_um * 2405 / 1000) * 1000) / (dist_um * 60000 / F_milli_mm_min) 4// KAT core move: X 0->50mm at F6000 (100 mm/s) -> time 500ms. 5// E=2.0mm -> vol 4810 milli-mm^3 -> flow 9620 milli-mm^3/s 6// E=0.33mm -> vol 793 -> flow 1586 7// E=8.0mm -> vol 19240 -> flow 38480 (beyond the whole table) 8// Table: 190->6000 200->8000 210->10000 220->11500 230->13000 (PROVISIONAL data; logic exact). 9// license_tier: ORIGINAL 10import "nx_jam_check.nx" 11import "nx_syscalls.nx" 12 13func jt_puts(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 14func jt_putn(v: i64) -> i64 { let bb: *u8 = sys_mmap(28); var m: i64=v; if m<0 {m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0 {t[0]=48 as u8;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(1,bb,k); return 0 } 15func jt_len(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 16 17func main() -> i64 { 18 var pass: i64 = 0 19 var total: i64 = 0 20 let out: *i64 = sys_mmap(64) as *i64 21 22 // T1: capacity interpolation -- exact points + midpoint 23 total = total + 1 24 var t1: i64 = 1 25 if jc_capacity_milli(200) != 8000 { t1 = 0 } 26 if jc_capacity_milli(205) != 9000 { t1 = 0 } // midpoint 200..210: 8000+5*200=9000 27 if jc_capacity_milli(150) != 6000 { t1 = 0 } // clamp low 28 if jc_capacity_milli(300) != 13000 { t1 = 0 } // clamp high 29 if t1 == 1 { pass = pass + 1 } else { jt_puts("T1 FAIL cap\n" as *u8) } 30 31 // T2: temp_for_flow -- 9620 -> 210 (first table cap >= flow); 38480 -> -1 32 total = total + 1 33 var t2: i64 = 1 34 if jc_temp_for_flow(9620) != 210 { t2 = 0 } 35 if jc_temp_for_flow(38480) != (0 - 1) { t2 = 0 } 36 if t2 == 1 { pass = pass + 1 } else { jt_puts("T2 FAIL tff\n" as *u8) } 37 38 // T3: parse_milli -- "2.0"->2000, "0.33"->330, "-1.25"->-1250, "210"->210000, "1.2345"->1234 39 total = total + 1 40 var t3: i64 = 1 41 let pb: *i64 = sys_mmap(16) as *i64 42 let s3a: *u8 = "2.0 " as *u8; pb[0]=0; if jc_parse_milli(s3a, pb, jt_len(s3a)) != 2000 { t3 = 0 } 43 let s3b: *u8 = "0.33 " as *u8; pb[0]=0; if jc_parse_milli(s3b, pb, jt_len(s3b)) != 330 { t3 = 0 } 44 let s3c: *u8 = "-1.25 " as *u8; pb[0]=0; if jc_parse_milli(s3c, pb, jt_len(s3c)) != (0 - 1250) { t3 = 0 } 45 let s3d: *u8 = "210 " as *u8; pb[0]=0; if jc_parse_milli(s3d, pb, jt_len(s3d)) != 210000 { t3 = 0 } 46 let s3e: *u8 = "1.2345 " as *u8; pb[0]=0; if jc_parse_milli(s3e, pb, jt_len(s3e)) != 1234 { t3 = 0 } 47 if t3 == 1 { pass = pass + 1 } else { jt_puts("T3 FAIL parse\n" as *u8) } 48 49 // T4: healthy print -- 200C, gentle flow (1586 < 8000) -> JC_OK 50 total = total + 1 51 let g4: *u8 = "M104 S200\nG1 F6000 X50.0 E0.33\n" as *u8 52 let r4: i64 = jc_scan(g4, jt_len(g4), out) 53 var t4: i64 = 1 54 if r4 != JC_OK { t4 = 0 } 55 if out[5] != 1 { t4 = 0 } // 1 extruding move 56 if out[7] != 1586 { t4 = 0 } // max flow seen 57 if t4 == 1 { pass = pass + 1 } else { jt_puts("T4 FAIL ok-case v=" as *u8); jt_putn(r4); jt_puts(" maxflow=" as *u8); jt_putn(out[7]); jt_puts("\n" as *u8) } 58 59 // T5: THE QIDI JAM CASE -- 200C but flow 9620 > 8000 -> JC_TOO_COLD, fix temp 210, line 2 60 total = total + 1 61 let g5: *u8 = "M104 S200\nG1 F6000 X50.0 E2.0\n" as *u8 62 let r5: i64 = jc_scan(g5, jt_len(g5), out) 63 var t5: i64 = 1 64 if r5 != JC_TOO_COLD { t5 = 0 } 65 if out[1] != 2 { t5 = 0 } // offending line 66 if out[2] != 9620 { t5 = 0 } // demanded flow 67 if out[3] != 8000 { t5 = 0 } // capacity at 200C 68 if out[4] != 210 { t5 = 0 } // the FIX: set 210C 69 if t5 == 1 { pass = pass + 1 } else { jt_puts("T5 FAIL too-cold v=" as *u8); jt_putn(r5); jt_puts(" line=" as *u8); jt_putn(out[1]); jt_puts(" flow=" as *u8); jt_putn(out[2]); jt_puts(" cap=" as *u8); jt_putn(out[3]); jt_puts(" fix=" as *u8); jt_putn(out[4]); jt_puts("\n" as *u8) } 70 71 // T6: beyond the hotend entirely -- flow 38480 -> JC_TOO_FAST (no temp fixes it; slow down) 72 total = total + 1 73 let g6: *u8 = "M109 S230\nG1 F6000 X50.0 E8.0\n" as *u8 74 let r6: i64 = jc_scan(g6, jt_len(g6), out) 75 var t6: i64 = 1 76 if r6 != JC_TOO_FAST { t6 = 0 } 77 if out[4] != (0 - 1) { t6 = 0 } 78 if t6 == 1 { pass = pass + 1 } else { jt_puts("T6 FAIL too-fast v=" as *u8); jt_putn(r6); jt_puts("\n" as *u8) } 79 80 // T7: cold extrusion -- extruding with NO temp ever set -> JC_NO_TEMP 81 total = total + 1 82 let g7: *u8 = "G1 F6000 X50.0 E0.33\n" as *u8 83 let r7: i64 = jc_scan(g7, jt_len(g7), out) 84 if r7 == JC_NO_TEMP { pass = pass + 1 } else { jt_puts("T7 FAIL no-temp v=" as *u8); jt_putn(r7); jt_puts("\n" as *u8) } 85 86 // T8: retraction counting -- negative E moves counted, not flow-flagged 87 total = total + 1 88 let g8: *u8 = "M104 S200\nG1 F6000 X50.0 E0.33\nG1 F2400 E-0.8\nG1 F2400 E-0.8\n" as *u8 89 let r8: i64 = jc_scan(g8, jt_len(g8), out) 90 var t8: i64 = 1 91 if r8 != JC_OK { t8 = 0 } 92 if out[6] != 2 { t8 = 0 } // 2 retractions 93 if t8 == 1 { pass = pass + 1 } else { jt_puts("T8 FAIL retract v=" as *u8); jt_putn(r8); jt_puts(" nret=" as *u8); jt_putn(out[6]); jt_puts("\n" as *u8) } 94 95 // T9: hotter temp covers the same demanding move -- 230C, flow 9620 < 13000 -> JC_OK 96 total = total + 1 97 let g9: *u8 = "M104 S230\nG1 F6000 X50.0 E2.0\n" as *u8 98 let r9: i64 = jc_scan(g9, jt_len(g9), out) 99 if r9 == JC_OK { pass = pass + 1 } else { jt_puts("T9 FAIL hot-ok v=" as *u8); jt_putn(r9); jt_puts("\n" as *u8) } 100 101 jt_puts("JAM-CHECK " as *u8); jt_putn(pass); jt_puts("/" as *u8); jt_putn(total); jt_puts("\n" as *u8) 102 if pass == total { jt_puts("JAM-CHECK ALL-PASS\n" as *u8); sys_exit(0) } 103 sys_exit(1) 104 return 1 105}