@typecad/framework-zephyr 1.0.0-alpha.14 → 1.0.0-alpha.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/README.md +22 -47
  2. package/dist/as-built.d.ts +33 -0
  3. package/dist/as-built.js +188 -0
  4. package/dist/async/timer-polyfill.js +1 -1
  5. package/dist/boardgen.d.ts +128 -0
  6. package/dist/boardgen.js +1366 -0
  7. package/dist/chips/board-overrides.d.ts +7 -0
  8. package/dist/chips/board-overrides.js +11 -0
  9. package/dist/chips/esp32s3.js +49 -0
  10. package/dist/chips/index.d.ts +6 -12
  11. package/dist/chips/index.js +18 -34
  12. package/dist/chips/resolve.d.ts +16 -2
  13. package/dist/chips/resolve.js +267 -10
  14. package/dist/chips/soc/.d.ts +2 -0
  15. package/dist/chips/soc/.js +129 -0
  16. package/dist/chips/soc/esp32.d.ts +2 -0
  17. package/dist/chips/soc/esp32.js +120 -0
  18. package/dist/chips/soc/esp32c3.d.ts +2 -0
  19. package/dist/chips/soc/esp32c3.js +90 -0
  20. package/dist/chips/soc/esp32c6.d.ts +2 -0
  21. package/dist/chips/soc/esp32c6.js +109 -0
  22. package/dist/chips/soc/esp32s3.d.ts +2 -0
  23. package/dist/chips/soc/esp32s3.js +189 -0
  24. package/dist/chips/soc/index.d.ts +2 -0
  25. package/dist/chips/soc/index.js +23 -0
  26. package/dist/chips/soc/nrf52840.d.ts +2 -0
  27. package/dist/chips/soc/nrf52840.js +130 -0
  28. package/dist/chips/soc/rp2040.d.ts +2 -0
  29. package/dist/chips/soc/rp2040.js +141 -0
  30. package/dist/chips/soc/rp2350a.d.ts +2 -0
  31. package/dist/chips/soc/rp2350a.js +145 -0
  32. package/dist/chips/soc/samd21g18a.d.ts +2 -0
  33. package/dist/chips/soc/samd21g18a.js +143 -0
  34. package/dist/chips/soc/stm32f411xe.d.ts +2 -0
  35. package/dist/chips/soc/stm32f411xe.js +251 -0
  36. package/dist/chips/types.d.ts +319 -0
  37. package/dist/chips/xiao-ble.js +21 -0
  38. package/dist/display/profiles.js +1 -1
  39. package/dist/doctor.js +38 -4
  40. package/dist/dt-config/custom-board.d.ts +23 -0
  41. package/dist/dt-config/custom-board.js +227 -0
  42. package/dist/dt-config/kconfig.d.ts +72 -1
  43. package/dist/dt-config/kconfig.js +115 -26
  44. package/dist/dt-config/overlay.js +548 -28
  45. package/dist/framework.manifest.d.ts +3 -3
  46. package/dist/framework.manifest.js +122 -185
  47. package/dist/index.d.ts +4 -1
  48. package/dist/index.js +8 -2
  49. package/dist/lowering/adc.d.ts +20 -2
  50. package/dist/lowering/adc.js +121 -29
  51. package/dist/lowering/ble.js +31 -28
  52. package/dist/lowering/dac.js +9 -9
  53. package/dist/lowering/fs.js +18 -10
  54. package/dist/lowering/gpio.d.ts +2 -0
  55. package/dist/lowering/gpio.js +82 -5
  56. package/dist/lowering/http.js +39 -14
  57. package/dist/lowering/hwtimer.d.ts +4 -0
  58. package/dist/lowering/hwtimer.js +35 -10
  59. package/dist/lowering/i2c.js +46 -54
  60. package/dist/lowering/index.d.ts +5 -5
  61. package/dist/lowering/index.js +15 -16
  62. package/dist/lowering/interrupts.d.ts +22 -5
  63. package/dist/lowering/interrupts.js +104 -22
  64. package/dist/lowering/mqtt.js +3 -5
  65. package/dist/lowering/power.js +0 -4
  66. package/dist/lowering/preferences.js +49 -77
  67. package/dist/lowering/pulse.js +0 -31
  68. package/dist/lowering/pwm.d.ts +12 -1
  69. package/dist/lowering/pwm.js +78 -14
  70. package/dist/lowering/random.js +3 -3
  71. package/dist/lowering/sensor.d.ts +37 -0
  72. package/dist/lowering/sensor.js +119 -0
  73. package/dist/lowering/spi.d.ts +12 -0
  74. package/dist/lowering/spi.js +65 -40
  75. package/dist/lowering/thread.d.ts +14 -0
  76. package/dist/lowering/thread.js +55 -0
  77. package/dist/lowering/timing.js +20 -46
  78. package/dist/lowering/tone.js +16 -4
  79. package/dist/lowering/uart.d.ts +13 -0
  80. package/dist/lowering/uart.js +72 -51
  81. package/dist/lowering/usb.d.ts +34 -0
  82. package/dist/lowering/usb.js +206 -0
  83. package/dist/lowering/wdt.d.ts +1 -1
  84. package/dist/lowering/wdt.js +17 -7
  85. package/dist/lowering/wifi.d.ts +3 -2
  86. package/dist/lowering/wifi.js +97 -111
  87. package/dist/sdk/board-catalog-sync.d.ts +16 -0
  88. package/dist/sdk/board-catalog-sync.js +41 -0
  89. package/dist/sdk/board-data.generated.d.ts +2 -0
  90. package/dist/sdk/board-data.generated.js +4 -0
  91. package/dist/sdk/catalog-walker.d.ts +90 -0
  92. package/dist/sdk/catalog-walker.js +682 -0
  93. package/dist/sdk/dts-reader.d.ts +83 -0
  94. package/dist/sdk/dts-reader.js +596 -0
  95. package/dist/strategy.d.ts +136 -17
  96. package/dist/strategy.js +839 -222
  97. package/dist/toolchain/bossac-touch.d.ts +18 -0
  98. package/dist/toolchain/bossac-touch.js +88 -0
  99. package/dist/toolchain/compat.d.ts +2 -2
  100. package/dist/toolchain/compat.js +8 -3
  101. package/dist/toolchain/debug-config.d.ts +21 -26
  102. package/dist/toolchain/debug-config.js +226 -76
  103. package/dist/toolchain/env-check.d.ts +4 -4
  104. package/dist/toolchain/env-check.js +5 -5
  105. package/dist/toolchain/index.d.ts +115 -1
  106. package/dist/toolchain/index.js +680 -71
  107. package/dist/toolchain/scaffold.js +39 -7
  108. package/dist/toolchain/west-discover.d.ts +4 -0
  109. package/dist/toolchain/west-discover.js +17 -6
  110. package/installer/CHANGELOG.md +473 -0
  111. package/installer/README.md +328 -0
  112. package/installer/environment.yml +46 -0
  113. package/installer/etc/conda/activate.d/zephyr.bat +7 -0
  114. package/installer/etc/conda/activate.d/zephyr.ps1 +12 -0
  115. package/installer/etc/conda/activate.d/zephyr.sh +20 -0
  116. package/installer/etc/conda/deactivate.d/zephyr.bat +6 -0
  117. package/installer/etc/conda/deactivate.d/zephyr.ps1 +6 -0
  118. package/installer/etc/conda/deactivate.d/zephyr.sh +4 -0
  119. package/installer/install.mjs +580 -0
  120. package/installer/install.ps1 +619 -0
  121. package/installer/install.sh +310 -0
  122. package/installer/lib/detect-platform.sh +62 -0
  123. package/installer/lib/fetch-sdk.sh +304 -0
  124. package/installer/lib/init-workspace.sh +153 -0
  125. package/installer/lib/write-activation.sh +76 -0
  126. package/installer/patches/tfm-c-include-separators.patch +19 -0
  127. package/installer/patches/zephyr-tfm-nordic-zephyr-include.patch +24 -0
  128. package/installer/templates/project/.typecad/activate-zephyr.ps1 +31 -0
  129. package/installer/templates/project/.typecad/activate-zephyr.sh +31 -0
  130. package/installer/templates/project/.vscode/settings.json +30 -0
  131. package/installer/templates/project/README.md +58 -0
  132. package/installer/versions.env +110 -0
  133. package/package.json +15 -15
  134. package/src/as-built.ts +206 -0
  135. package/src/boardgen.ts +1428 -0
  136. package/src/chips/index.ts +35 -54
  137. package/src/chips/resolve.ts +285 -10
  138. package/src/chips/types.ts +325 -1
  139. package/src/display/profiles.ts +1 -1
  140. package/src/doctor.ts +110 -77
  141. package/src/dt-config/custom-board.ts +325 -0
  142. package/src/dt-config/kconfig.ts +165 -18
  143. package/src/dt-config/overlay.ts +537 -25
  144. package/src/framework.manifest.ts +123 -185
  145. package/src/index.ts +57 -41
  146. package/src/lowering/adc.ts +222 -118
  147. package/src/lowering/ble.ts +32 -28
  148. package/src/lowering/dac.ts +82 -82
  149. package/src/lowering/fs.ts +18 -10
  150. package/src/lowering/gpio.ts +242 -155
  151. package/src/lowering/http.ts +512 -488
  152. package/src/lowering/hwtimer.ts +139 -101
  153. package/src/lowering/i2c.ts +116 -126
  154. package/src/lowering/index.ts +91 -93
  155. package/src/lowering/interrupts.ts +113 -21
  156. package/src/lowering/mqtt.ts +3 -5
  157. package/src/lowering/preferences.ts +327 -354
  158. package/src/lowering/pwm.ts +167 -99
  159. package/src/lowering/random.ts +3 -3
  160. package/src/lowering/sensor.ts +155 -0
  161. package/src/lowering/spi.ts +164 -124
  162. package/src/lowering/thread.ts +63 -0
  163. package/src/lowering/timing.ts +46 -72
  164. package/src/lowering/uart.ts +73 -51
  165. package/src/lowering/usb.ts +221 -0
  166. package/src/lowering/wdt.ts +95 -84
  167. package/src/lowering/wifi.ts +97 -112
  168. package/src/sdk/board-catalog-sync.ts +62 -0
  169. package/src/strategy.ts +848 -237
  170. package/src/toolchain/bossac-touch.ts +112 -0
  171. package/src/toolchain/compat.ts +8 -3
  172. package/src/toolchain/debug-config.ts +676 -522
  173. package/src/toolchain/env-check.ts +9 -9
  174. package/src/toolchain/index.ts +1359 -645
  175. package/src/toolchain/scaffold.ts +38 -7
  176. package/src/toolchain/west-discover.ts +19 -6
  177. package/src/async/timer-polyfill.ts +0 -107
  178. package/src/chips/esp32.ts +0 -74
  179. package/src/chips/esp32s3.ts +0 -57
  180. package/src/chips/xiao-ble.ts +0 -82
  181. package/src/lowering/power.ts +0 -70
  182. package/src/lowering/pulse.ts +0 -93
  183. package/src/lowering/tone.ts +0 -60
  184. package/src/lowering/worker-backing.ts +0 -94
  185. package/src/lowering/worker.ts +0 -17
@@ -9,7 +9,7 @@ declare const _default: {
9
9
  entrypoint: {
10
10
  entrypointFunctionName: string;
11
11
  requiresLoopFunction: boolean;
12
- sourceExtension: "cpp" | "ino" | "cc" | "h";
12
+ sourceExtension: "cpp" | "h" | "ino" | "cc";
13
13
  generateHeaderFile: boolean;
14
14
  overrideBaseName?: string | undefined;
15
15
  outputSubdirectory?: string | undefined;
@@ -22,7 +22,7 @@ declare const _default: {
22
22
  };
23
23
  hal: Record<string, {
24
24
  supported: boolean;
25
- ops: Record<string, "unsupported" | "supported" | "polyfill" | "probe-inconclusive" | "stub">;
25
+ ops: Record<string, "stub" | "polyfill" | "supported" | "unsupported" | "probe-inconclusive">;
26
26
  partialCoverage: boolean;
27
27
  unsupportedReason?: string | undefined;
28
28
  }>;
@@ -50,7 +50,7 @@ declare const _default: {
50
50
  };
51
51
  typeEmission: {
52
52
  normalizeCppType: boolean;
53
- mathHeader: "<math.h>" | "none" | "<Arduino.h>";
53
+ mathHeader: "<cmath>" | "none" | "<math.h>" | "<Arduino.h>";
54
54
  needsStdString: boolean;
55
55
  needsStdVector: boolean;
56
56
  needsIostream: boolean;
@@ -2,7 +2,7 @@
2
2
  // Zephyr framework manifest
3
3
  //
4
4
  // Coverage reflects actual resolveHALOperation / lowerHalOp + resolveDisplayOp
5
- // behavior. GPIO, PWM, ADC, I2C, SPI, UART, interrupts, tone, power, pulse,
5
+ // behavior. GPIO, PWM, ADC, I2C, SPI, UART, interrupts, pulse,
6
6
  // shift, WDT, BLE, timing, WiFi, HTTP/S, MQTT, board constants, and random
7
7
  // are lowered; display is lowered via the generic <zephyr/drivers/display.h>
8
8
  // GFX runtime. WiFi/HTTP/MQTT require an ESP32 target (nRF52840 has no radio).
@@ -34,27 +34,22 @@ export default defineFrameworkManifest({
34
34
  'GPIO is lowered through devicetree specs (gpio_pin_*_dt).',
35
35
  implementationMode: 'from-scratch',
36
36
  entrypoint: {
37
- entrypointFunctionName: 'setup',
38
- requiresLoopFunction: true,
37
+ // Zephyr is a main()-based RTOS: top-level statements lower straight into
38
+ // main() (no setup()/loop() pair, no bridge shim). Event-driven programs
39
+ // get their scheduler loop appended inside main() by the driver machinery.
40
+ entrypointFunctionName: 'main',
41
+ requiresLoopFunction: false,
39
42
  sourceExtension: 'cpp',
40
43
  overrideBaseName: 'main',
41
44
  outputSubdirectory: 'src',
42
45
  generateHeaderFile: true,
43
- customBridgeShim: 'main',
44
46
  },
45
47
  profile: {
46
48
  // Informational list of supported board targets. The manifest validator
47
- // never iterates this; chipForTarget (src/chips/index.ts) is the real
48
- // resolver. ESP32-S3 + plain ESP32 added alongside the nRF52840 MVP target;
49
- // rpi_pico / rpi_pico2 / esp32c3 / esp32c6 / blackpill_f411ce resolve via
50
- // the board packages' zephyr chip data (resolveChipFromBoard), not the
51
- // hardcoded chip registry.
52
- targets: [
53
- 'xiao_ble', 'esp32s3_devkitc', 'esp32_devkitc',
54
- 'rpi_pico', 'rpi_pico2/rp2350a/m33',
55
- 'esp32c3_devkitm/esp32c3', 'esp32c6_devkitc/esp32c6/hpcore',
56
- 'blackpill_f411ce/stm32f411xe',
57
- ],
49
+ // never iterates this. Every board in the catalog resolves the same way
50
+ // (resolveChipFromBoard over the generated manifest) there is no
51
+ // curated target list.
52
+ targets: [],
58
53
  forcedIncludes: ['<zephyr/kernel.h>', '<zephyr/drivers/gpio.h>', '<cstdint>'],
59
54
  symbolAliases: {},
60
55
  },
@@ -67,26 +62,28 @@ export default defineFrameworkManifest({
67
62
  'gpio.write': 'supported',
68
63
  'gpio.read': 'supported',
69
64
  'gpio.toggle': 'supported',
70
- 'gpio.set_mode': 'supported',
65
+ // Thin GPIO (hal/gpio-pin.ts): construction flags as tokens, applied
66
+ // once per pin ahead of first use.
67
+ 'gpio.configure': 'supported',
68
+ 'gpio.read_cfg': 'supported', // fused guarded configure + read
69
+ 'gpio.shift_out': 'supported',
70
+ 'gpio.shift_in': 'supported',
71
71
  },
72
72
  },
73
- // ── Supported: Timing (delay/millis/delay_us/micros/free_heap; timers via polyfill) ─
73
+ // ── Supported: Timing (delay/millis/delay_us/micros; timers via polyfill) ─
74
74
  timing: {
75
75
  supported: true,
76
76
  partialCoverage: false,
77
77
  ops: {
78
- 'timing.delay': 'supported', // → k_msleep(ms)
79
- 'timing.delay_microseconds': 'supported', // → k_busy_wait(us)
80
- 'timing.millis': 'supported', // → k_uptime_get_32()
81
- 'timing.micros': 'supported', // → k_cycle_get_32 + cycles/sec
82
- 'timing.free_heap': 'supported', // → 0 (no portable query; see lowering)
83
78
  // Timer ops are POLYFILL_BACKED_OPS → timer_methods. The validator skips
84
79
  // the resolver probe (these legitimately return polyfill-helper calls,
85
80
  // not direct lowering) and requires the polyfill be in polyfills.emitted.
86
- 'timing.set_interval': 'polyfill',
87
- 'timing.set_timeout': 'polyfill',
88
- 'timing.clear_interval': 'polyfill',
89
- 'timing.clear_timeout': 'polyfill',
81
+ // Time.* — the TS-flavored surface (hal/time.ts), preferred over the
82
+ // Arduino-named forms above for new code.
83
+ 'timing.sleep': 'supported', // → k_msleep(ms) — Time.sleep
84
+ 'timing.now': 'supported', // → k_uptime_get() — Time.now
85
+ 'timing.now_us': 'supported', // → k_cyc_to_us_floor64 — Time.nowUs
86
+ 'timing.busy_wait_us': 'supported', // → k_busy_wait(us) — Time.busyWaitUs
90
87
  },
91
88
  },
92
89
  // ── Supported: PWM (pwm_dt_spec via pwm-led0) ──────────────────────────
@@ -94,9 +91,11 @@ export default defineFrameworkManifest({
94
91
  supported: true,
95
92
  partialCoverage: false,
96
93
  ops: {
97
- 'pwm.write': 'supported',
98
- 'pwm.get_frequency': 'supported',
99
- 'pwm.get_resolution': 'supported',
94
+ // Thin PWM (hal/pwm-pin.ts): ns-true verbs; construction period
95
+ // applies once, setDuty is 0.0–1.0 sugar over one set_pulse call.
96
+ 'pwm.set_pulse': 'supported',
97
+ 'pwm.set_duty': 'supported',
98
+ 'pwm.set_period': 'supported',
100
99
  },
101
100
  },
102
101
  // ── Supported: ADC (SAADC via adc_read + channel setup) ────────────────
@@ -104,11 +103,10 @@ export default defineFrameworkManifest({
104
103
  supported: true,
105
104
  partialCoverage: false,
106
105
  ops: {
107
- 'adc.read': 'supported',
108
- 'adc.get_resolution': 'supported',
109
- 'adc.set_reference': 'supported',
110
- 'adc.get_reference': 'supported',
111
- 'adc.read_voltage': 'supported',
106
+ // Thin ADC (hal/adc-pin.ts): construction gain/reference tokens,
107
+ // lazy inline channel setup.
108
+ 'adc.read_raw': 'supported',
109
+ 'adc.read_mv': 'supported',
112
110
  },
113
111
  },
114
112
  dac: {
@@ -118,77 +116,57 @@ export default defineFrameworkManifest({
118
116
  // (zephyr-dac-pin-unavailable).
119
117
  supported: true,
120
118
  partialCoverage: true,
121
- ops: { 'dac.write': 'supported' },
119
+ ops: {
120
+ // Thin DAC (hal/dac-pin.ts): raw code, construction resolution.
121
+ 'dac.write_value': 'supported',
122
+ },
122
123
  },
123
124
  interrupts: {
124
125
  supported: true,
125
126
  partialCoverage: true,
126
127
  unsupportedReason: undefined,
127
128
  ops: {
128
- 'interrupt.attach': 'supported',
129
129
  'interrupt.detach': 'supported',
130
- },
131
- },
132
- tone: {
133
- supported: true,
134
- partialCoverage: true,
135
- ops: {
136
- 'tone.play': 'supported', // PWM-based square wave (blocking for duration)
137
- 'tone.stop': 'supported',
138
- },
139
- },
140
- power: {
141
- supported: true,
142
- partialCoverage: true,
143
- ops: {
144
- 'power.deep_sleep': 'supported', // k_sleep (deepest allowed state)
145
- 'power.light_sleep': 'supported', // pm_state_force SUSPEND_TO_IDLE
146
- 'power.set_cpu_frequency': 'supported', // comment (nRF clock API deferred)
147
- 'power.deep_sleep_pin': 'supported', // GPIO-interrupt wake + k_sleep
130
+ // Thin GPIO interrupts (hal/gpio-pin.ts onInterrupt): INT_* tokens,
131
+ // covering the level modes the legacy mode strings could not express.
132
+ 'interrupt.attach_flags': 'supported',
148
133
  },
149
134
  },
150
135
  i2c: {
151
136
  supported: true,
152
137
  partialCoverage: false,
153
138
  ops: {
154
- 'i2c.begin': 'supported', 'i2c.end': 'supported', 'i2c.set_clock': 'supported',
155
- 'i2c.begin_transmission': 'supported', 'i2c.write': 'supported',
156
- 'i2c.write_bytes': 'supported', 'i2c.write_buffer': 'supported',
157
- 'i2c.read_buffer': 'supported', 'i2c.end_transmission': 'supported',
158
- 'i2c.request_from': 'supported', 'i2c.available': 'supported', 'i2c.read': 'supported',
159
- 'i2c.recover': 'supported',
139
+ // Thin I2C device (hal/i2c-target.ts): Zephyr register verbs.
140
+ 'i2c.reg_write': 'supported',
141
+ 'i2c.reg_read': 'supported',
142
+ 'i2c.reg_update': 'supported',
143
+ 'i2c.dev_write': 'supported',
160
144
  },
161
145
  },
162
146
  spi: {
163
147
  supported: true,
164
148
  partialCoverage: false,
165
149
  ops: {
166
- 'spi.begin': 'supported', 'spi.end': 'supported', 'spi.transfer': 'supported',
167
- 'spi.begin_transaction': 'supported', 'spi.end_transaction': 'supported',
168
- 'spi.set_mode': 'supported', 'spi.set_bit_order': 'supported',
169
- 'spi.cs_low': 'supported', 'spi.cs_high': 'supported', 'spi.read_buffer': 'supported',
150
+ // Thin SPI device (hal/spi-target.ts): spi_dt_spec against the DT
151
+ // child node the overlay emits per constructed target.
152
+ 'spi.transceive': 'supported',
153
+ 'spi.dev_write': 'supported',
154
+ 'spi.reg_read': 'supported',
170
155
  },
171
156
  },
172
157
  uart: {
173
158
  supported: true,
174
159
  partialCoverage: true,
175
160
  ops: {
176
- 'uart.begin': 'supported', 'uart.end': 'supported', 'uart.print': 'supported',
177
- 'uart.println': 'supported', 'uart.printf': 'supported', 'uart.write': 'supported',
178
- 'uart.read': 'supported', 'uart.peek': 'supported', 'uart.available': 'supported',
179
- 'uart.flush': 'supported',
161
+ // Thin UART (hal/uart-port.ts): poll API with construction baud.
162
+ 'uart.poll_write': 'supported',
163
+ // Interrupt-drained RX ring (hal/uart-port.ts).
164
+ 'uart.rx_arm': 'supported',
165
+ 'uart.rx_available': 'supported',
166
+ 'uart.rx_peek': 'supported',
167
+ 'uart.rx_read': 'supported',
180
168
  },
181
169
  },
182
- pulse: {
183
- supported: true,
184
- partialCoverage: true,
185
- ops: { 'pulse.in': 'supported', 'pulse.in_long': 'supported' },
186
- },
187
- shift: {
188
- supported: true,
189
- partialCoverage: false,
190
- ops: { 'shift.out': 'supported', 'shift.in': 'supported' },
191
- },
192
170
  board: {
193
171
  // Board constant resolution. Board.definition.<path> /
194
172
  // Pins.definition.<path> property accesses are folded by
@@ -206,9 +184,33 @@ export default defineFrameworkManifest({
206
184
  supported: true,
207
185
  partialCoverage: false,
208
186
  ops: {
209
- 'wdt.enable': 'supported',
210
- 'wdt.reset': 'supported',
211
187
  'wdt.disable': 'supported',
188
+ // Thin Watchdog (hal/watchdog.ts): construction timeout in ms.
189
+ 'wdt.setup': 'supported',
190
+ 'wdt.feed': 'supported',
191
+ },
192
+ },
193
+ // Thin Counter (hal/counter.ts) — Zephyr's counter driver with Zephyr's
194
+ // verbs, over the same per-instance state as hwtimer.*. Chips without a
195
+ // declared free counter lower to a comment + profileDiagnostics flag.
196
+ counter: {
197
+ supported: true,
198
+ partialCoverage: true,
199
+ ops: {
200
+ 'counter.on_alarm': 'supported',
201
+ 'counter.start': 'supported',
202
+ 'counter.stop': 'supported',
203
+ },
204
+ },
205
+ // Thin Thread (hal/thread.ts) — kernel threads. start(fn) is
206
+ // k_thread_create (K_NO_WAIT) over a per-slot stack sized by the
207
+ // construction stackKb; join is k_thread_join (K_FOREVER).
208
+ thread: {
209
+ supported: true,
210
+ partialCoverage: false,
211
+ ops: {
212
+ 'thread.start': 'supported',
213
+ 'thread.join': 'supported',
212
214
  },
213
215
  },
214
216
  // ── Partial: WiFi (STA connect + scan + config via conn_mgr/net_mgmt) ────
@@ -222,50 +224,32 @@ export default defineFrameworkManifest({
222
224
  // driver hook; credentials need a custom settings-subsystem layer; static IP
223
225
  // / auto-reconnect / tx-power aren't wifi-shaped or aren't exposed by the
224
226
  // esp32 Zephyr driver. See per-op reasons.
225
- unsupportedReason: 'AP client enumeration/IP/per-station config, credential persistence, static IP, auto-reconnect, and tx-power have no Zephyr lowering (no driver/Kconfig hook).',
227
+ unsupportedReason: 'Per-station AP enumeration and credential persistence have no Zephyr lowering (no driver/Kconfig hook).',
226
228
  ops: {
227
- // Connection (8) — net_mgmt connect/disconnect + L4 connectivity state.
228
- 'wifi.connect': 'supported', 'wifi.connect_start': 'supported',
229
- 'wifi.disconnect': 'supported', 'wifi.status': 'supported',
230
- 'wifi.is_connected': 'supported', 'wifi.local_ip': 'supported',
231
- 'wifi.rssi': 'supported', 'wifi.mac': 'supported',
232
- // Waits (2) — block on the L4 connected flag (k_msleep poll).
233
- 'wifi.wait_connected': 'supported', 'wifi.wait_disconnected': 'supported',
229
+ // Station (8) — join carries the construction facts (credentials,
230
+ // security, band/channel, timeout, static IPv4, power-save);
231
+ // net_mgmt connect/disconnect + L4 connectivity state underneath.
232
+ 'wifi.join': 'supported', 'wifi.connect_start': 'supported',
233
+ 'wifi.disconnect': 'supported', 'wifi.is_connected': 'supported',
234
+ 'wifi.local_ip': 'supported', 'wifi.rssi': 'supported',
235
+ 'wifi.mac': 'supported',
234
236
  // Scan (8) — net_mgmt NET_REQUEST_WIFI_SCAN + result pool.
235
- 'wifi.scan': 'supported', 'wifi.scan_start': 'supported',
237
+ // scan_start is the async split of scan (kick + poll scan_done);
238
+ // emitted synthetically by the async tier, no TS-facing method.
239
+ 'wifi.scan': 'supported',
240
+ 'wifi.scan_start': 'supported',
236
241
  'wifi.scan_done': 'supported', 'wifi.scan_count': 'supported',
237
242
  'wifi.scan_ssid': 'supported', 'wifi.scan_rssi': 'supported',
238
243
  'wifi.scan_encryption': 'supported', 'wifi.scan_channel': 'supported',
239
- // AP mode (2 of 7) — esp32 driver wires ap_enable/ap_disable. Only
240
- // ssid/password/channel are honored; the rest of the AP surface has no
241
- // driver hook (config_params isn't wired, max_clients hardcodes 5).
244
+ // AP mode (2) — esp32 driver wires ap_enable/ap_disable. Only
245
+ // ssid/psk/channel are honored (the thin WiFiAP facts carry exactly those).
242
246
  'wifi.ap_start': 'supported', 'wifi.ap_stop': 'supported',
243
- // Config (2) — hostname (best-effort no-op) + power save (real net_mgmt).
244
- 'wifi.set_hostname': 'supported', 'wifi.set_power_save': 'supported',
245
247
  // on_event: 'disconnect' (NET_EVENT_L4_DISCONNECTED) + 'connect'
246
248
  // (NET_EVENT_IPV4_ADDR_ADD) are lowered.
247
249
  'wifi.on_event': 'supported',
248
- // ── Genuinely unsupported (no Zephyr/driver hook) ───────────────────
250
+ // ── Genuinely unsupported (no driver hook) ─────────────────────────
249
251
  // ap_client_count: no API to enumerate connected AP stations.
250
- // ap_ip: set via net_if, not wifi net_mgmt.
251
- // ap_set_channel: channel set at ap_start; driver doesn't wire ap_config_params.
252
- // ap_set_hidden: esp32 ap_enable config has no ssid_hidden field.
253
- // ap_set_max_clients: driver hardcodes max_connection to 5; config_params unwired.
254
- // save_credentials/connect_saved/clear_credentials: no wifi-credentials API in
255
- // Zephyr (would need a custom settings-subsystem layer).
256
- // set_static_ip: a net_if operation, not a wifi net_mgmt request.
257
- // set_auto_reconnect: esp32 driver doesn't expose esp_wifi_set_auto_connect.
258
- // set_tx_power: driver owns the radio; the PHY ceiling isn't a Zephyr Kconfig (zephyr#45580).
259
252
  'wifi.ap_client_count': 'unsupported',
260
- 'wifi.ap_ip': 'unsupported',
261
- 'wifi.ap_set_channel': 'unsupported',
262
- 'wifi.ap_set_hidden': 'unsupported',
263
- 'wifi.ap_set_max_clients': 'unsupported',
264
- 'wifi.save_credentials': 'unsupported', 'wifi.connect_saved': 'unsupported',
265
- 'wifi.clear_credentials': 'unsupported',
266
- 'wifi.set_static_ip': 'unsupported',
267
- 'wifi.set_auto_reconnect': 'unsupported',
268
- 'wifi.set_tx_power': 'unsupported',
269
253
  },
270
254
  },
271
255
  http: {
@@ -277,7 +261,7 @@ export default defineFrameworkManifest({
277
261
  // a networked target (ESP32 WiFi); profileDiagnostics flags usage on a
278
262
  // radioless chip as 'zephyr-http-unavailable-on-target'.
279
263
  ops: {
280
- 'http.begin': 'supported', 'http.reset': 'supported',
264
+ 'http.begin': 'supported',
281
265
  'http.set_header': 'supported', 'http.set_timeout': 'supported',
282
266
  'http.set_max_body': 'supported', 'http.set_body': 'supported',
283
267
  'http.set_insecure': 'supported', 'http.set_ca_cert': 'supported',
@@ -313,25 +297,12 @@ export default defineFrameworkManifest({
313
297
  ops: Object.fromEntries(HAL_OPERATION_KINDS.filter((k) => k.startsWith('ble.')).map((k) => [k, 'supported'])),
314
298
  },
315
299
  // ── Supported: Worker offload (k_work system workqueue + k_sem) ──────────
316
- // worker.* is lowered via lowerWorkerOp against the shared __tc_worker
317
- // contract; the Zephyr backing (worker-backing.ts) supplies k_work + k_sem.
318
- worker: {
319
- supported: true,
320
- partialCoverage: false,
321
- ops: { 'worker.submit': 'supported', 'worker.done': 'supported' },
322
- },
323
300
  // ── Honestly unsupported extended categories ─────────────────────────────
324
301
  // These have op-kinds in HAL_OPERATION_KINDS but no Zephyr lowering. Each
325
302
  // is declared unsupported (with a reason) so the coverage matrix is uniform
326
303
  // and the resolver's `return undefined` for these prefixes is honest. The
327
304
  // catchall schema (HalCoverageSchema) validates any declared extended
328
305
  // category; declaring them keeps the manifest a complete coverage record.
329
- rmt: {
330
- supported: false,
331
- unsupportedReason: 'RMT (ESP32 infrared/transaction peripheral) has no Zephyr lowering.',
332
- partialCoverage: false,
333
- ops: unsupportedOps('rmt.'),
334
- },
335
306
  snprintf: {
336
307
  supported: false,
337
308
  unsupportedReason: 'snprintf.emit is a raw escape hatch; the Zephyr resolver returns undefined (use rawCpp()).',
@@ -352,10 +323,8 @@ export default defineFrameworkManifest({
352
323
  supported: true,
353
324
  partialCoverage: false,
354
325
  ops: {
355
- 'preferences.begin': 'supported', 'preferences.end': 'supported',
356
326
  'preferences.clear': 'supported', 'preferences.remove': 'supported',
357
327
  'preferences.put_int': 'supported', 'preferences.get_int': 'supported',
358
- 'preferences.put_uint': 'supported', 'preferences.get_uint': 'supported',
359
328
  'preferences.put_bool': 'supported', 'preferences.get_bool': 'supported',
360
329
  'preferences.put_float': 'supported', 'preferences.get_float': 'supported',
361
330
  'preferences.put_string': 'supported', 'preferences.get_string': 'supported',
@@ -382,16 +351,10 @@ export default defineFrameworkManifest({
382
351
  supported: true,
383
352
  partialCoverage: false,
384
353
  ops: {
385
- 'fs.begin': 'supported', 'fs.read_text': 'supported', 'fs.write_text': 'supported',
354
+ 'fs.read_text': 'supported', 'fs.write_text': 'supported',
386
355
  'fs.exists': 'supported', 'fs.remove': 'supported',
387
356
  },
388
357
  },
389
- mdns: {
390
- supported: false,
391
- unsupportedReason: 'No mDNS lowering on Zephyr (requires networking stack).',
392
- partialCoverage: false,
393
- ops: unsupportedOps('mdns.'),
394
- },
395
358
  mqtt: {
396
359
  supported: true,
397
360
  partialCoverage: false,
@@ -408,43 +371,19 @@ export default defineFrameworkManifest({
408
371
  'mqtt.connected': 'supported', 'mqtt.disconnect': 'supported',
409
372
  },
410
373
  },
411
- ota: {
412
- supported: false,
413
- unsupportedReason: 'No OTA lowering on Zephyr (Zephyr has MCUmgr; not wired).',
414
- partialCoverage: false,
415
- ops: unsupportedOps('ota.'),
416
- },
417
- temp: {
418
- supported: false,
419
- unsupportedReason: 'No on-chip temperature lowering on Zephyr (nRF52840 TEMP peripheral; not wired).',
420
- partialCoverage: false,
421
- ops: { 'temp.read': 'unsupported' },
422
- },
423
- hwtimer: {
424
- // Hardware timers via the Zephyr counter driver (<zephyr/drivers/counter.h>).
425
- // set_frequency → top value (counter_freq/hz) + on_overflow callback;
426
- // start arms both; stop halts. A chip declares its free counters
427
- // (e.g. nRF RTC1; RTC0 is kernel-owned). This is distinct from the JS
428
- // setInterval/setTimeout k_timer polyfill, which is unaffected.
374
+ sensor: {
375
+ // DT-bound sensor parts — the generic catalog (hal/sensor.ts +
376
+ // sensor-catalog.generated.ts). fetch sensor_sample_fetch,
377
+ // get → sensor_channel_get on a per-sensor device handle; the overlay
378
+ // generator emits the DT child node, and the driver's own Kconfig
379
+ // `default y` lights it up (only CONFIG_SENSOR is set, usage-gated).
429
380
  supported: true,
430
- partialCoverage: true,
381
+ partialCoverage: false,
431
382
  ops: {
432
- 'hwtimer.set_frequency': 'supported', 'hwtimer.on_overflow': 'supported',
433
- 'hwtimer.start': 'supported', 'hwtimer.stop': 'supported',
383
+ 'sensor.fetch': 'supported',
384
+ 'sensor.get': 'supported',
434
385
  },
435
386
  },
436
- capacitive: {
437
- // FT6336U capacitive touch is handled via the strategy-owned touch adapter
438
- // (src/display/touch-adapter.ts → touch_init/touch_isTouched/touch_readRaw),
439
- // NOT via a HAL op lowering. The manifest marks it unsupported here (no
440
- // resolveHALOperation path for capacitive.read); the touch adapter provides
441
- // the integration. partialCoverage reflects that it works on targets with
442
- // the FT6336U DT node (ESP32), not on the bare nRF52840.
443
- supported: false,
444
- unsupportedReason: 'Capacitive touch is handled via the strategy touch adapter (FT6336U I2C), not a HAL op. Requires the ft6336u DT node.',
445
- partialCoverage: true,
446
- ops: { 'capacitive.read': 'unsupported' },
447
- },
448
387
  i2s: {
449
388
  supported: false,
450
389
  unsupportedReason: 'No I2S / digital audio lowering on Zephyr.',
@@ -458,8 +397,12 @@ export default defineFrameworkManifest({
458
397
  ops: unsupportedOps('twai.'),
459
398
  },
460
399
  usb: {
400
+ // CDC-ACM serial over the board's USB connector. BOARD-GATED: the
401
+ // lowering only fires when the board's manifest carries zephyr.usb.*
402
+ // (boardgen emits it from the board's own DTS) — the manifest probe
403
+ // runs with no board, so the honest declaration is unsupported here.
461
404
  supported: false,
462
- unsupportedReason: 'No USB OTG / USB-Serial lowering on Zephyr (Zephyr USB device stack not wired).',
405
+ unsupportedReason: 'Board-gated: USB lowers only on boards whose DTS enables the USB device controller (boardgen emits zephyr.usb.* from the catalog).',
463
406
  partialCoverage: false,
464
407
  ops: unsupportedOps('usb.'),
465
408
  },
@@ -501,7 +444,6 @@ export default defineFrameworkManifest({
501
444
  { id: 'wiring_compat', domain: 'standard', notes: 'HIGH/LOW/digitalRead/etc. macros routing Wiring tokens (referenced unconditionally by the UI runtime header) to the __tc_gpio_* helpers' },
502
445
  { id: 'string_methods', domain: 'embedded', notes: 'STL-free __tc_* string helpers (const char*, inline ASCII case conv, <cstring> only)' },
503
446
  { id: 'static_array', domain: 'embedded', notes: 'STL-free __tc_StaticArray<T,N> wrapper for no-<vector> mutated/struct array literals' },
504
- { id: 'timer_methods', domain: 'embedded', notes: 'k_timer + k_work pool (system workqueue); callbacks run in thread context' },
505
447
  { id: 'async_runtime', domain: 'embedded', notes: 'Heap-free static Promise/microtask runtime (generateStaticAsyncRuntime), pumped in loop()' },
506
448
  ],
507
449
  suppressed: [],
@@ -518,7 +460,7 @@ export default defineFrameworkManifest({
518
460
  },
519
461
  typeEmission: {
520
462
  normalizeCppType: true,
521
- mathHeader: '<math.h>',
463
+ mathHeader: '<cmath>',
522
464
  needsStdString: false,
523
465
  needsStdVector: false,
524
466
  needsIostream: false,
@@ -535,17 +477,11 @@ export default defineFrameworkManifest({
535
477
  },
536
478
  ambientTypes: ['Preferences'],
537
479
  conformance: {
538
- // Hardware-test groups each entry is backed by a tests/<group>.test.ts
539
- // file in this package (validated by the manifest validator). Mirrors the
540
- // framework-avr/framework-esp32 convention. These run on metal via
541
- // `npm run test:hw` (cuttlefish-test transpiles west build → flash).
542
- hardwareTestGroups: [
543
- '01-basics',
544
- '30-timing',
545
- '40-gpio',
546
- '41-analog',
547
- '42-timers',
548
- ],
480
+ // Hardware-test groups moved to the shared HAL suite
481
+ // (packages/hal/tests common/ + board/ via board test-pins.json), which
482
+ // runs on Zephyr targets through the hal board configs. The
483
+ // hal-resolution snapshots below stay.
484
+ hardwareTestGroups: [],
549
485
  // Per-op HAL-resolution suite — one tests/packages/framework-zephyr/
550
486
  // hal-resolution/<cat>.test.ts per category, snapshotting the exact C++
551
487
  // each op lowers to. Mirrors the framework-esp32 convention. These are
@@ -553,8 +489,9 @@ export default defineFrameworkManifest({
553
489
  // catches regressions like silent pull-resistor / interrupt no-ops.
554
490
  halResolutionTests: [
555
491
  'adc', 'ble', 'board', 'dac', 'fs', 'gpio', 'http', 'hwtimer', 'i2c',
556
- 'interrupts', 'mqtt', 'power', 'preferences', 'pulse', 'pwm', 'random',
557
- 'spi', 'timing', 'tone', 'uart', 'wdt', 'worker',
492
+ 'interrupts', 'mqtt', 'preferences', 'pwm', 'random',
493
+ 'spi', 'thin-buses', 'thin-classes', 'thread', 'timing',
494
+ 'uart', 'usb', 'wdt', 'wifi',
558
495
  ],
559
496
  },
560
497
  // Declared compatibility range for the installed Zephyr RTOS. The framework's
package/dist/index.d.ts CHANGED
@@ -1,8 +1,11 @@
1
1
  export { ZephyrStrategy as FrameworkStrategy } from './strategy.js';
2
2
  export { ZephyrStrategy } from './strategy.js';
3
3
  export { Toolchain } from './toolchain/index.js';
4
+ export { bossacTouchReset } from './toolchain/bossac-touch.js';
4
5
  export { writeProjectDebugArtifacts } from './toolchain/debug-config.js';
5
6
  export { runDoctor as doctor } from './doctor.js';
6
7
  export { runLicensesPresenter as licenses } from './licenses.js';
7
- export { chipForTarget, setActiveChip, getActiveChip, XIAO_BLE, } from './chips/index.js';
8
+ export { setActiveChip, getActiveChip, NO_BOARD_CHIP, } from './chips/index.js';
8
9
  export type { ZephyrChipDescriptor, ZephyrGpioDtSpec, } from './chips/types.js';
10
+ export { syncBoardCatalog, ensureFreshBoardCatalog, loadBoardCatalogOverlay, resetBoardCatalogOverlayCache, } from './sdk/board-catalog-sync.js';
11
+ export type { BoardCatalogSyncReport, BoardCatalogEnsureResult, BoardCatalogOverlay, } from './sdk/board-catalog-sync.js';
package/dist/index.js CHANGED
@@ -8,6 +8,7 @@
8
8
  export { ZephyrStrategy as FrameworkStrategy } from './strategy.js';
9
9
  export { ZephyrStrategy } from './strategy.js';
10
10
  export { Toolchain } from './toolchain/index.js';
11
+ export { bossacTouchReset } from './toolchain/bossac-touch.js';
11
12
  // Create-time starter debug artifacts. The `cuttlefish create` flow reads this
12
13
  // optional named export off the loaded framework module (same loader pattern
13
14
  // as doctor/licenses) and calls it for freshly scaffolded projects, so F5 in
@@ -23,5 +24,10 @@ export { runDoctor as doctor } from './doctor.js';
23
24
  // alias `licenses` so the loader picks it up as mod.licenses (see
24
25
  // framework-package.ts). Mirrors framework-arduino's presenter.
25
26
  export { runLicensesPresenter as licenses } from './licenses.js';
26
- // Chip descriptor registry (for downstream tooling / additional boards).
27
- export { chipForTarget, setActiveChip, getActiveChip, XIAO_BLE, } from './chips/index.js';
27
+ // Chip descriptor cache (the lowering's resolved-board view; no curated
28
+ // registry every board reconstructs from its generated manifest).
29
+ export { setActiveChip, getActiveChip, NO_BOARD_CHIP, } from './chips/index.js';
30
+ // Board catalog sync — regenerate the local board overlay from the user's
31
+ // own Zephyr tree (`cuttlefish board sync`), so board add/change/remove
32
+ // tracks `west update` instead of cuttlefish releases.
33
+ export { syncBoardCatalog, ensureFreshBoardCatalog, loadBoardCatalogOverlay, resetBoardCatalogOverlayCache, } from './sdk/board-catalog-sync.js';
@@ -1,7 +1,25 @@
1
1
  import type { HALOpIR } from '@typecad/cuttlefish/api/shared';
2
2
  import type { ZephyrChipDescriptor } from '../chips/types.js';
3
- /** Resolve the SAADC channel index for a HAL pin number; -1 if unmapped. */
3
+ /**
4
+ * Resolve the SAADC channel index for an adc.read argument; -1 if unmapped.
5
+ *
6
+ * The numeric argument serves two HAL forms: `InputPin.readAnalog()` passes
7
+ * a GPIO number, while the Arduino-compat `ADC.read(channel)` passes an ADC
8
+ * channel number. Pin-first resolution keeps readAnalog behavior unchanged;
9
+ * the channel fallback makes `ADC.read(n)` resolve on targets where channel
10
+ * n does not alias GPIO n (e.g. the XIAO's AIN2 = P0.28). Where a number
11
+ * matches both a mapped pin and another channel's index, the pin wins.
12
+ */
4
13
  export declare function adcChannelForPin(chip: ZephyrChipDescriptor, pin: number): number;
14
+ /**
15
+ * Resolve the owning ADC controller's node label for an adc.read argument.
16
+ * Defaults to the descriptor's primary (`chip.adc.nodeLabel`) — channels on
17
+ * additional controllers (STM32 adc3-only routes, ESP32 adc2 pads) carry
18
+ * their controller explicitly, and their device handle is
19
+ * `__tc_adc_<label>_dev` (the primary keeps the unsuffixed `__tc_adc_dev`
20
+ * so single-controller output is unchanged).
21
+ */
22
+ export declare function adcControllerForPin(chip: ZephyrChipDescriptor, pin: number): string;
5
23
  /**
6
24
  * Emit the per-channel ADC setup state. One block per channel in the chip
7
25
  * descriptor that the PROGRAM ACTUALLY READS (`usedPins`) — an unread
@@ -11,7 +29,7 @@ export declare function adcChannelForPin(chip: ZephyrChipDescriptor, pin: number
11
29
  * `static bool __tc_adc<N>_ready` so the first read configures it and
12
30
  * subsequent reads skip. Called from shimLines when the program uses ADC.
13
31
  */
14
- export declare function adcInitLines(chip: ZephyrChipDescriptor, usedPins?: ReadonlySet<number>): string[];
32
+ export declare function adcInitLines(chip: ZephyrChipDescriptor, usedPins?: ReadonlySet<number>, overrideDevices?: ReadonlySet<string>): string[];
15
33
  /**
16
34
  * Resolve a HAL adc.* op to Zephyr C++.
17
35
  * Returns `{ code }` for statement ops, `{ expression }` for value-returning ops.