code wiki / _hdl_build / nx_micron_geom.nx
nx_micron_geom.nx source
↩ module page · 49 lines · 2447 B
1// nx_micron_geom.nx -- SHARED SUB-MICRON PRECISION SUBSTRATE (operator: "i want the printer to be
2// able to print cpus and other hardware, i want that level of accuracy"). The machine-agnostic
3// coordinate layer BOTH the FDM printer (0.1mm class) AND the future sovereign litho stepper
4// (sub-micron, CPU class) inherit. Unit = 1 NANOMETER (1 unit = 1nm). int64 spans +/-9.2e18 nm
5// = +/-9.2 BILLION meters at nm resolution -- a 256mm bed is 2.56e8 nm, so we have ~10 decimal
6// orders of headroom; a 5nm transistor gate is 5 units. One number system, plastic bracket to
7// silicon gate.
8// Scale-calibration: real stages have a linear scale error (steps/mm slightly off); we correct in
9// PARTS-PER-MILLION so the SAME planner output drives a coarse or a precision stage accurately.
10// LAWS: struct-free, integer-only. license_tier: ORIGINAL
11import "nx_syscalls.nx"
12
13const MG_NM_PER_UM: i64 = 1000
14const MG_NM_PER_MM: i64 = 1000000
15
16func mg_um(x_um: i64) -> i64 { return x_um * MG_NM_PER_UM }
17func mg_mm(x_mm: i64) -> i64 { return x_mm * MG_NM_PER_MM }
18
19// nm -> whole micrometers (floor) and the nm remainder, for human-readable report
20func mg_to_um_floor(nm: i64) -> i64 { return nm / MG_NM_PER_UM }
21
22// apply a scale calibration of `ppm` parts-per-million to a nominal nm value (round-to-nearest).
23// corrected = nominal * (1e6 + ppm) / 1e6. ppm may be negative.
24func mg_scale_ppm(nominal_nm: i64, ppm: i64) -> i64 {
25 let num: i64 = nominal_nm * (1000000 + ppm)
26 if num >= 0 { return (num + 500000) / 1000000 }
27 return (num - 500000) / 1000000
28}
29
30// affine 1-D correction: corrected = scale_ppm(nominal) + offset_nm (backlash/home offset)
31func mg_correct(nominal_nm: i64, ppm: i64, offset_nm: i64) -> i64 {
32 return mg_scale_ppm(nominal_nm, ppm) + offset_nm
33}
34
35// smallest addressable step a stage of `steps_per_mm` can command, in nm (its native resolution).
36// 1 step = 1mm/steps_per_mm = 1e6 nm / steps_per_mm.
37func mg_step_resolution_nm(steps_per_mm: i64) -> i64 {
38 if steps_per_mm <= 0 { return 0 }
39 return MG_NM_PER_MM / steps_per_mm
40}
41
42// can a stage of `steps_per_mm` even ADDRESS a feature of `feature_nm`? (resolution must be <= feature)
43// returns 1 if addressable, 0 if the feature is finer than one step.
44func mg_can_address(steps_per_mm: i64, feature_nm: i64) -> i64 {
45 let res: i64 = mg_step_resolution_nm(steps_per_mm)
46 if res <= 0 { return 0 }
47 if res <= feature_nm { return 1 }
48 return 0
49}