@typecad/framework-zephyr 1.0.0-alpha.13 → 1.0.0-alpha.15

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 (191) hide show
  1. package/README.md +22 -35
  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/controllers.d.ts +28 -8
  10. package/dist/chips/controllers.js +49 -12
  11. package/dist/chips/esp32s3.js +49 -0
  12. package/dist/chips/index.d.ts +6 -12
  13. package/dist/chips/index.js +18 -34
  14. package/dist/chips/resolve.d.ts +16 -2
  15. package/dist/chips/resolve.js +298 -15
  16. package/dist/chips/soc/.d.ts +2 -0
  17. package/dist/chips/soc/.js +129 -0
  18. package/dist/chips/soc/esp32.d.ts +2 -0
  19. package/dist/chips/soc/esp32.js +120 -0
  20. package/dist/chips/soc/esp32c3.d.ts +2 -0
  21. package/dist/chips/soc/esp32c3.js +90 -0
  22. package/dist/chips/soc/esp32c6.d.ts +2 -0
  23. package/dist/chips/soc/esp32c6.js +109 -0
  24. package/dist/chips/soc/esp32s3.d.ts +2 -0
  25. package/dist/chips/soc/esp32s3.js +189 -0
  26. package/dist/chips/soc/index.d.ts +2 -0
  27. package/dist/chips/soc/index.js +23 -0
  28. package/dist/chips/soc/nrf52840.d.ts +2 -0
  29. package/dist/chips/soc/nrf52840.js +130 -0
  30. package/dist/chips/soc/rp2040.d.ts +2 -0
  31. package/dist/chips/soc/rp2040.js +141 -0
  32. package/dist/chips/soc/rp2350a.d.ts +2 -0
  33. package/dist/chips/soc/rp2350a.js +145 -0
  34. package/dist/chips/soc/samd21g18a.d.ts +2 -0
  35. package/dist/chips/soc/samd21g18a.js +143 -0
  36. package/dist/chips/soc/stm32f411xe.d.ts +2 -0
  37. package/dist/chips/soc/stm32f411xe.js +251 -0
  38. package/dist/chips/types.d.ts +382 -12
  39. package/dist/chips/xiao-ble.js +33 -0
  40. package/dist/display/profiles.js +1 -1
  41. package/dist/doctor.js +38 -4
  42. package/dist/dt-config/custom-board.d.ts +23 -0
  43. package/dist/dt-config/custom-board.js +227 -0
  44. package/dist/dt-config/kconfig.d.ts +83 -1
  45. package/dist/dt-config/kconfig.js +116 -27
  46. package/dist/dt-config/overlay.js +623 -18
  47. package/dist/framework.manifest.d.ts +20 -30
  48. package/dist/framework.manifest.js +124 -178
  49. package/dist/index.d.ts +4 -1
  50. package/dist/index.js +8 -2
  51. package/dist/lowering/adc.d.ts +26 -5
  52. package/dist/lowering/adc.js +137 -31
  53. package/dist/lowering/ble.js +31 -28
  54. package/dist/lowering/dac.js +9 -9
  55. package/dist/lowering/fs.js +18 -10
  56. package/dist/lowering/gpio.d.ts +2 -0
  57. package/dist/lowering/gpio.js +90 -10
  58. package/dist/lowering/http.js +39 -14
  59. package/dist/lowering/hwtimer.d.ts +4 -0
  60. package/dist/lowering/hwtimer.js +35 -10
  61. package/dist/lowering/i2c.js +46 -54
  62. package/dist/lowering/index.d.ts +5 -5
  63. package/dist/lowering/index.js +15 -16
  64. package/dist/lowering/interrupts.d.ts +22 -5
  65. package/dist/lowering/interrupts.js +104 -22
  66. package/dist/lowering/mqtt.js +12 -6
  67. package/dist/lowering/power.js +0 -4
  68. package/dist/lowering/preferences.js +49 -77
  69. package/dist/lowering/pulse.js +5 -36
  70. package/dist/lowering/pwm.d.ts +32 -3
  71. package/dist/lowering/pwm.js +105 -17
  72. package/dist/lowering/random.js +3 -3
  73. package/dist/lowering/sensor.d.ts +37 -0
  74. package/dist/lowering/sensor.js +119 -0
  75. package/dist/lowering/spi.d.ts +12 -0
  76. package/dist/lowering/spi.js +65 -40
  77. package/dist/lowering/thread.d.ts +14 -0
  78. package/dist/lowering/thread.js +55 -0
  79. package/dist/lowering/timing.js +20 -46
  80. package/dist/lowering/tone.js +18 -5
  81. package/dist/lowering/uart.d.ts +13 -0
  82. package/dist/lowering/uart.js +72 -51
  83. package/dist/lowering/usb.d.ts +34 -0
  84. package/dist/lowering/usb.js +206 -0
  85. package/dist/lowering/wdt.d.ts +1 -1
  86. package/dist/lowering/wdt.js +17 -7
  87. package/dist/lowering/wifi.d.ts +3 -2
  88. package/dist/lowering/wifi.js +120 -111
  89. package/dist/sdk/board-catalog-sync.d.ts +16 -0
  90. package/dist/sdk/board-catalog-sync.js +41 -0
  91. package/dist/sdk/board-data.generated.d.ts +2 -0
  92. package/dist/sdk/board-data.generated.js +4 -0
  93. package/dist/sdk/catalog-walker.d.ts +90 -0
  94. package/dist/sdk/catalog-walker.js +682 -0
  95. package/dist/sdk/dts-reader.d.ts +83 -0
  96. package/dist/sdk/dts-reader.js +596 -0
  97. package/dist/strategy.d.ts +136 -17
  98. package/dist/strategy.js +881 -212
  99. package/dist/toolchain/bossac-touch.d.ts +18 -0
  100. package/dist/toolchain/bossac-touch.js +88 -0
  101. package/dist/toolchain/compat.d.ts +2 -2
  102. package/dist/toolchain/compat.js +8 -3
  103. package/dist/toolchain/debug-config.d.ts +21 -26
  104. package/dist/toolchain/debug-config.js +212 -72
  105. package/dist/toolchain/env-check.d.ts +4 -4
  106. package/dist/toolchain/env-check.js +5 -5
  107. package/dist/toolchain/index.d.ts +66 -1
  108. package/dist/toolchain/index.js +713 -58
  109. package/dist/toolchain/scaffold.d.ts +9 -0
  110. package/dist/toolchain/scaffold.js +84 -7
  111. package/dist/toolchain/west-discover.d.ts +8 -1
  112. package/dist/toolchain/west-discover.js +19 -6
  113. package/dist/toolchain/west-spawn.js +17 -5
  114. package/installer/CHANGELOG.md +473 -0
  115. package/installer/README.md +328 -0
  116. package/installer/environment.yml +46 -0
  117. package/installer/etc/conda/activate.d/zephyr.bat +7 -0
  118. package/installer/etc/conda/activate.d/zephyr.ps1 +12 -0
  119. package/installer/etc/conda/activate.d/zephyr.sh +20 -0
  120. package/installer/etc/conda/deactivate.d/zephyr.bat +6 -0
  121. package/installer/etc/conda/deactivate.d/zephyr.ps1 +6 -0
  122. package/installer/etc/conda/deactivate.d/zephyr.sh +4 -0
  123. package/installer/install.mjs +580 -0
  124. package/installer/install.ps1 +619 -0
  125. package/installer/install.sh +310 -0
  126. package/installer/lib/detect-platform.sh +62 -0
  127. package/installer/lib/fetch-sdk.sh +304 -0
  128. package/installer/lib/init-workspace.sh +153 -0
  129. package/installer/lib/write-activation.sh +76 -0
  130. package/installer/patches/tfm-c-include-separators.patch +19 -0
  131. package/installer/patches/zephyr-tfm-nordic-zephyr-include.patch +24 -0
  132. package/installer/templates/project/.typecad/activate-zephyr.ps1 +31 -0
  133. package/installer/templates/project/.typecad/activate-zephyr.sh +31 -0
  134. package/installer/templates/project/.vscode/settings.json +30 -0
  135. package/installer/templates/project/README.md +58 -0
  136. package/installer/versions.env +110 -0
  137. package/package.json +16 -16
  138. package/src/as-built.ts +206 -0
  139. package/src/boardgen.ts +1428 -0
  140. package/src/chips/controllers.ts +61 -12
  141. package/src/chips/index.ts +35 -54
  142. package/src/chips/resolve.ts +316 -14
  143. package/src/chips/types.ts +388 -13
  144. package/src/display/profiles.ts +1 -1
  145. package/src/doctor.ts +110 -77
  146. package/src/dt-config/custom-board.ts +325 -0
  147. package/src/dt-config/kconfig.ts +177 -19
  148. package/src/dt-config/overlay.ts +1058 -450
  149. package/src/framework.manifest.ts +125 -178
  150. package/src/index.ts +57 -41
  151. package/src/lowering/adc.ts +222 -102
  152. package/src/lowering/ble.ts +32 -28
  153. package/src/lowering/dac.ts +82 -82
  154. package/src/lowering/fs.ts +18 -10
  155. package/src/lowering/gpio.ts +242 -152
  156. package/src/lowering/http.ts +512 -488
  157. package/src/lowering/hwtimer.ts +139 -101
  158. package/src/lowering/i2c.ts +116 -126
  159. package/src/lowering/index.ts +91 -93
  160. package/src/lowering/interrupts.ts +113 -21
  161. package/src/lowering/mqtt.ts +12 -6
  162. package/src/lowering/preferences.ts +327 -354
  163. package/src/lowering/pwm.ts +167 -74
  164. package/src/lowering/random.ts +3 -3
  165. package/src/lowering/sensor.ts +155 -0
  166. package/src/lowering/spi.ts +164 -124
  167. package/src/lowering/thread.ts +63 -0
  168. package/src/lowering/timing.ts +46 -72
  169. package/src/lowering/uart.ts +73 -51
  170. package/src/lowering/usb.ts +221 -0
  171. package/src/lowering/wdt.ts +95 -84
  172. package/src/lowering/wifi.ts +120 -111
  173. package/src/sdk/board-catalog-sync.ts +62 -0
  174. package/src/strategy.ts +888 -229
  175. package/src/toolchain/bossac-touch.ts +112 -0
  176. package/src/toolchain/compat.ts +8 -3
  177. package/src/toolchain/debug-config.ts +666 -522
  178. package/src/toolchain/env-check.ts +9 -9
  179. package/src/toolchain/index.ts +765 -44
  180. package/src/toolchain/scaffold.ts +81 -7
  181. package/src/toolchain/west-discover.ts +334 -316
  182. package/src/toolchain/west-spawn.ts +17 -5
  183. package/src/async/timer-polyfill.ts +0 -107
  184. package/src/chips/esp32.ts +0 -74
  185. package/src/chips/esp32s3.ts +0 -57
  186. package/src/chips/xiao-ble.ts +0 -70
  187. package/src/lowering/power.ts +0 -70
  188. package/src/lowering/pulse.ts +0 -93
  189. package/src/lowering/tone.ts +0 -60
  190. package/src/lowering/worker-backing.ts +0 -94
  191. package/src/lowering/worker.ts +0 -17
@@ -43,18 +43,122 @@ export interface ZephyrGpioController {
43
43
  export interface ZephyrBusController {
44
44
  /** Devicetree nodelabel, e.g. 'i2c1', 'spi2', 'uart0'. */
45
45
  readonly nodeLabel: string;
46
+ /**
47
+ * Counter child form only: the labeled TIMER PARENT's nodelabel (ESP32
48
+ * timer0-3). The counter device is an unlabeled `counter {}` child; the
49
+ * nodeLabel above is a label the generated overlay defines on that child,
50
+ * and this field tells the overlay which parent to attach it to.
51
+ */
52
+ readonly counterParent?: string;
53
+ /**
54
+ * Synthesized pinctrl group, for controllers whose board DT ships no
55
+ * default group (e.g. uart1 on rpi_pico/rpi_pico2 — the mainline board DT
56
+ * only pins uart0). When present, the overlay generator emits the group
57
+ * under `&pinctrl` and wires `pinctrl-0`/`pinctrl-names` onto the
58
+ * controller when enabling it. RP2xxx pinmux is fully muxable per pad, so
59
+ * the group is pure data: which pads carry the signals.
60
+ */
61
+ readonly pinctrl?: {
62
+ /** Pinmux header to #include (token definitions). */
63
+ readonly include: string;
64
+ /** Output-signal pinmux tokens (emitted as group1). */
65
+ readonly pinmux: readonly string[];
66
+ /** Input-signal pinmux tokens (emitted as group2 with input-enable). */
67
+ readonly inputPinmux?: readonly string[];
68
+ /**
69
+ * `#define` lines emitted (ifndef-guarded) BEFORE the include — for
70
+ * upstream header bugs where a token's macro body references an
71
+ * undefined helper (e.g. RP2_PINCTRL_GPIO_FUNC_UART_ALT in Zephyr's
72
+ * rp2350 pinctrl headers, unreferenced by mainline so never noticed).
73
+ */
74
+ readonly defines?: readonly string[];
75
+ };
76
+ /**
77
+ * Reference an EXISTING pinctrl group (defined in the board's pinctrl
78
+ * dtsi but not attached to the node) instead of synthesizing one — e.g.
79
+ * uart1_default on esp32s3_devkitc. The overlay wires
80
+ * `pinctrl-0 = <&<group>>` when enabling the controller.
81
+ */
82
+ readonly pinctrlRef?: string;
83
+ /**
84
+ * Raw devicetree property lines emitted inside the enable block — for
85
+ * bindings with required properties the board DTS only sets on its own
86
+ * wired-up nodes (e.g. `current-speed` on the Picos' PL011 UARTs).
87
+ */
88
+ readonly props?: readonly string[];
46
89
  }
47
90
  /**
48
91
  * A PWM channel described as a devicetree spec.
49
92
  *
50
- * Emitted as `struct pwm_dt_spec __tc_pwm<N> = PWM_DT_SPEC_GET(DT_ALIAS(<dtSpec>))`.
51
- * `pwm_set_pulse_dt(&__tc_pwm<N>, pulse_ns)` honors the spec's period/polarity.
93
+ * Two forms, mutually exclusive:
94
+ * - **Board-shipped alias:** `dtSpec` names a DT alias the board's own DTS
95
+ * already defines (e.g. the XIAO's `pwm-led0`). Emitted as
96
+ * `PWM_DT_SPEC_GET(DT_ALIAS(<dtSpec>))`.
97
+ * - **Synthesized** (controller + channel): the board DTS enables a PWM
98
+ * controller node (e.g. `pwm4`) but defines no alias for it. The overlay
99
+ * generator synthesizes a `pwm-leds` consumer node + a `tc-pwm<pin>` alias
100
+ * in `<board>.overlay`; the lowering emits
101
+ * `PWM_DT_SPEC_GET(DT_ALIAS(tc-pwm<pin>))`. Both sides derive the alias
102
+ * name from the pin, so they always agree.
103
+ *
104
+ * `pwm_set_pulse_dt(&spec, pulse_ns)` honors the spec's period/polarity.
52
105
  */
53
106
  export interface ZephyrPwmSpec {
54
107
  /** GPIO number (matches the HAL op `pin` field). */
55
108
  readonly pin: number;
56
- /** Devicetree alias, e.g. 'pwm-led0'. */
57
- readonly dtSpec: string;
109
+ /** Board-shipped DT alias, e.g. 'pwm-led0'. Omit when using the
110
+ * synthesized form (controller + channel). */
111
+ readonly dtSpec?: string;
112
+ /** Synthesized form: PWM controller DT nodelabel, e.g. 'pwm4' (the STM32
113
+ * timer's pwm child node). The overlay's pwm-leds node consumes it. */
114
+ readonly controller?: string;
115
+ /** Synthesized form: channel index within the controller (1-based timer
116
+ * channel, matching the `pwms` binding's channel cell). */
117
+ readonly channel?: number;
118
+ /** Synthesized form: period in nanoseconds, baked into the DT spec. The
119
+ * lowering scales duty against `spec.period`. Default 20 000 000 (20 ms /
120
+ * 50 Hz — the servo convention; harmless for LED dimming). */
121
+ readonly periodNs?: number;
122
+ /** Synthesized form: PWM polarity flag. Default PWM_POLARITY_NORMAL. */
123
+ readonly polarity?: string;
124
+ /**
125
+ * SoC pinctrl dtsi token muxing this channel's pin to the timer (e.g.
126
+ * 'tim4_ch1_pb6' on STM32). Required on custom boards — the st,stm32-pwm
127
+ * binding demands pinctrl-0 on an enabled node and only a board DTS (or
128
+ * the custom-board generator, fed by this token) can provide it. Also
129
+ * gates the generated board's `pwmN: pwm { }` label declaration: the
130
+ * overlay references `&<controller>`, a label that otherwise exists only
131
+ * when a board DTS defines it.
132
+ */
133
+ readonly pinctrl?: string;
134
+ }
135
+ /**
136
+ * A "PWM matrix" controller: any listed pin can carry any channel, routed by
137
+ * the SoC's GPIO matrix rather than a fixed timer-channel↔pad map.
138
+ *
139
+ * ESP32 LEDC is the shape (espressif,esp32-ledc): 8 channels, each routable
140
+ * to (almost) any pad via a pinctrl pinmux token (`LEDC_CH<ch>_GPIO<pin>`).
141
+ * A static `specs` list cannot express this — two arbitrary pins would
142
+ * collide on a statically assigned channel — so the channel assignment is
143
+ * made at build time: the pins the program actually drives are assigned
144
+ * channels 0..N-1 (ascending pin order, capped at `channelCount`), and the
145
+ * overlay generator emits the pinctrl group + per-channel child nodes the
146
+ * espressif,esp32-ledc binding requires. The emitted C++ is channel-blind:
147
+ * it addresses each pin via the same `DT_ALIAS(tc-pwm<pin>)` the synthesized
148
+ * static form uses, so the two paths share the lowering.
149
+ */
150
+ export interface ZephyrPwmMatrix {
151
+ /** PWM controller DT nodelabel, e.g. 'ledc0'. */
152
+ readonly controller: string;
153
+ /** Channels the controller exposes (ESP32-S3 LEDC: 8). */
154
+ readonly channelCount: number;
155
+ /**
156
+ * HAL pins usable as PWM outputs. This is the safety filter as much as the
157
+ * capability list — on the ESP32-S3 it excludes the boot-strap pin, the
158
+ * USB D+/D− pads, the flash/PSRAM pins (GPIO 26–32), the octal-PSRAM pins
159
+ * (GPIO 33–37), and the console UART pads (GPIO 43/44).
160
+ */
161
+ readonly pins: readonly number[];
58
162
  }
59
163
  /**
60
164
  * A GPIO pin usable as an interrupt source.
@@ -69,7 +173,7 @@ export interface ZephyrInterruptPin {
69
173
  readonly dtSpec: string;
70
174
  }
71
175
  /**
72
- * An ADC channel: which SAADC input a given HAL pin maps to.
176
+ * An ADC channel: which ADC input a given HAL pin maps to.
73
177
  *
74
178
  * The XIAO nRF52840 has no pre-declared ADC channel nodes in devicetree, so the
75
179
  * lowering emits `adc_channel_setup` against `DEVICE_DT_GET(DT_NODELABEL(adc))`
@@ -78,8 +182,24 @@ export interface ZephyrInterruptPin {
78
182
  export interface ZephyrAdcChannel {
79
183
  /** GPIO number (matches the HAL op `pin` field). */
80
184
  readonly pin: number;
81
- /** SAADC channel index (AIN0–AIN7). */
185
+ /** ADC channel index (nRF SAADC AIN0–AIN7; STM32 ADC1_IN0–IN9). */
82
186
  readonly channel: number;
187
+ /**
188
+ * ADC device node label that OWNS this channel when the SoC has more than
189
+ * one ADC controller (STM32 adc1/adc2, ESP32 units), e.g. 'adc2'. Omitted
190
+ * for channels on the descriptor's primary controller (`adc.nodeLabel`) —
191
+ * a single-controller manifest is unchanged. Channel indices are unique
192
+ * only WITHIN a controller; the pair (controller, channel) is the key.
193
+ */
194
+ readonly controller?: string;
195
+ /**
196
+ * Pinctrl node label that muxes this pin to analog mode, e.g.
197
+ * 'adc1_in0_pa0' (STM32). When present, the overlay generator rewrites the
198
+ * ADC node's pinctrl-0 to the channels the program actually reads — SoCs
199
+ * like STM32 leave the pad in GPIO mode otherwise and reads float.
200
+ * Omit on SoCs whose ADC needs no pad muxing (nRF SAADC, RP2040).
201
+ */
202
+ readonly pinctrl?: string;
83
203
  }
84
204
  /**
85
205
  * A DAC channel: which DAC output a given HAL pin maps to. The lowering emits
@@ -92,6 +212,8 @@ export interface ZephyrDacChannel {
92
212
  readonly channel: number;
93
213
  /** DAC resolution in bits (ESP32 DAC is 8-bit). */
94
214
  readonly resolution: number;
215
+ /** Pinctrl node name routing the channel to its pad (STM32 harvest). */
216
+ readonly pinctrl?: string;
95
217
  }
96
218
  /**
97
219
  * Pure-data descriptor for a Zephyr board + its SoC's peripheral layout.
@@ -101,6 +223,33 @@ export interface ZephyrChipDescriptor {
101
223
  readonly id: string;
102
224
  /** SoC family, e.g. 'nrf52840'. */
103
225
  readonly soc: string;
226
+ /**
227
+ * How confident the framework is in this descriptor's facts.
228
+ * - 'validated' — the soc is part of the hardware-tested set; every field
229
+ * was verified against the pinned Zephyr tree and real hardware.
230
+ * - 'derived' — reconstructed from data (board/MCU packages, DTS reading)
231
+ * but never hardware-verified; capability errors may be less precise.
232
+ */
233
+ readonly tier?: 'validated' | 'derived';
234
+ /**
235
+ * Datasheet pin-naming convention — how a controller/pin pair becomes the
236
+ * schematic-facing name the generated board module exports (the
237
+ * `Pin.fromPort()` identity). One of:
238
+ * - 'esp32-gpio' — flat numbering, `GPION` (esp32, esp32s3, esp32c*)
239
+ * - 'stm32-port' — one controller per port, `P<port><bit>` (PA5, PB12)
240
+ * - 'nrf-port' — P0.28 / P1.11 style (`P<port>.<bit>`)
241
+ * - 'rp-gpio' — `GP<n>` flat numbering
242
+ * - 'samd-port' — PA/PB ports like stm32-port
243
+ * Absent on tier-3 socs with no known convention (the generated board
244
+ * exposes only connector/alias pins + LED/BUTTON).
245
+ */
246
+ readonly pinNaming?: 'esp32-gpio' | 'stm32-port' | 'nrf-port' | 'rp-gpio' | 'samd-port';
247
+ /**
248
+ * Pins that exist in the controller ranges but must NOT be exported as
249
+ * usable GPIOs — strapping pads, flash/PSRAM, USB D+/-. The generated
250
+ * board module's pin list subtracts these.
251
+ */
252
+ readonly excludedPins?: readonly number[];
104
253
  /**
105
254
  * Default GPIO controller nodelabel for the raw-pin fallback. Pins not in
106
255
  * `gpio.dtSpecs` are addressed via
@@ -113,11 +262,18 @@ export interface ZephyrChipDescriptor {
113
262
  readonly gpioController: string;
114
263
  /**
115
264
  * Per-range GPIO controllers for SoCs that split GPIO across multiple
116
- * devicetree nodes (ESP32-S3: `gpio0` 0–31, `gpio1` 32–48). When present, the
117
- * lowering routes a HAL pin to its owning controller at runtime via the
118
- * emitted `__tc_gpio_dev(pin)` dispatcher; `gpioController` is the fallback.
119
- * Omit on single-controller SoCs (nRF52840, RP2040, …) every pin is on the
120
- * one controller described by `gpioController`.
265
+ * devicetree nodes (ESP32-S3: `gpio0` 0–31, `gpio1` 32–48; STM32: one
266
+ * controller per port `gpioa` 0–15, `gpiob` 16–31, `gpioc` 32–47).
267
+ * When present, the lowering routes a HAL pin to its owning controller at
268
+ * runtime via the emitted `__tc_gpio_dev(pin)` dispatcher; `gpioController`
269
+ * is the fallback. Omit on single-controller SoCs (RP2040, …) — every pin
270
+ * is on the one controller described by `gpioController`.
271
+ *
272
+ * NUMBERING RULE (load-bearing): `minPin` must equal the controller's port
273
+ * base so the port-relative raw index is `pin - minPin` (STM32 PB12 = pin
274
+ * 28 → raw 12 — the Zephyr raw API addresses the index WITHIN the
275
+ * controller). Number pins by port blocks and never contiguously across
276
+ * unbonded pins.
121
277
  */
122
278
  readonly gpioControllers?: readonly ZephyrGpioController[];
123
279
  /** GPIO pins with devicetree specs (LEDs, buttons, board-defined pins). */
@@ -138,11 +294,70 @@ export interface ZephyrChipDescriptor {
138
294
  readonly uart?: {
139
295
  readonly controllers: readonly ZephyrBusController[];
140
296
  };
297
+ /**
298
+ * USB device (CDC-ACM serial) capability. Zephyr "next" USB device stack:
299
+ * the UDC controller node (uniformly `zephyr_udc0` on every USB-capable
300
+ * board) plus `cdcInstances` CDC-ACM class child nodes, both composed in
301
+ * the generated overlay. The lowering addresses instance N as
302
+ * DT_NODELABEL(cdc_acm_uart<N>) — a UART-class device driven with the
303
+ * plain uart_* API. Boards without USB device support omit this field;
304
+ * usb.* HAL ops then fail with a clear "board does not expose USB" error.
305
+ */
306
+ readonly usb?: {
307
+ /** UDC controller nodelabel (convention: 'zephyr_udc0'). */
308
+ readonly controller: string;
309
+ /** How many CDC-ACM serial instances to compose (≥1). */
310
+ readonly cdcInstances: number;
311
+ /** USB vendor ID for the device descriptor ('0x2fe3' Zephyr-test default). */
312
+ readonly vid?: string;
313
+ /** USB product ID for the device descriptor ('0x0001' default). */
314
+ readonly pid?: string;
315
+ /**
316
+ * 1200-baud touch-to-reset (BOSSA-bootloader boards, e.g. SAM D21).
317
+ *
318
+ * Present = two things happen automatically:
319
+ * - Device side: the emitted USB shim registers a usbd message callback;
320
+ * when the host sets the CDC baud rate to 1200, the shim writes the
321
+ * bootloader's "stay resident" magic to the flag address and reboots —
322
+ * the board lands in the bootloader with no button press.
323
+ * - Host side: the bossac upload path opens the app's console port at
324
+ * 1200 baud to trigger the above, waits for the bootloader's USB
325
+ * identity, and points bossac at that port.
326
+ * Omit on boards without a cooperative bootloader (probe- or
327
+ * UF2-flashed boards don't need it).
328
+ */
329
+ readonly touchReset?: {
330
+ /** RAM address of the bootloader's stay-resident flag word
331
+ * (SAMD21G18A: 0x20007FFC — the last word of the 32 KB SRAM). */
332
+ readonly flagAddress: number;
333
+ /** Magic word the bootloader checks there (Arduino SAMD: 0x07738135). */
334
+ readonly magic: number;
335
+ /** Bootloader USB vendor id, hex string ('0x2341') — host-side watch. */
336
+ readonly bootloaderVid?: string;
337
+ /** Bootloader USB product id, hex string ('0x0057') — host-side watch. */
338
+ readonly bootloaderPid?: string;
339
+ };
340
+ };
141
341
  /** PWM channels with DT specs. */
142
342
  readonly pwm?: {
143
343
  readonly specs: readonly ZephyrPwmSpec[];
344
+ /**
345
+ * Matrix PWM capability (ESP32 LEDC) — channels assigned to the driven
346
+ * pins at build time instead of enumerated statically. `specs` may be
347
+ * empty when only the matrix is declared.
348
+ */
349
+ readonly matrix?: ZephyrPwmMatrix;
350
+ /**
351
+ * Timer input clock (Hz) for the synthesized specs' controllers — the
352
+ * number the 16-bit overflow check divides by (STM32: APB clock × the
353
+ * timer multiplier; blackpill TIM4 = 96 MHz). When set, the overlay
354
+ * generator derives an `st,prescaler` for the timers node so slow
355
+ * periods (servo 20 ms) fit the 16-bit ARR — without it pwm_stm32
356
+ * rejects the channel ("period cycles exceeds 16-bit timer limit").
357
+ */
358
+ readonly clockHz?: number;
144
359
  };
145
- /** ADC: the SAADC node label + the pin→channel map. */
360
+ /** ADC: the ADC device node label + the pin→channel map. */
146
361
  readonly adc?: {
147
362
  readonly nodeLabel: string;
148
363
  readonly channels: readonly ZephyrAdcChannel[];
@@ -150,6 +365,19 @@ export interface ZephyrChipDescriptor {
150
365
  readonly vrefMv: number;
151
366
  /** ADC resolution in bits. */
152
367
  readonly resolution: number;
368
+ /**
369
+ * Zephyr `enum adc_gain` macro for the channel setup, e.g.
370
+ * 'ADC_GAIN_1_4' (nRF SAADC default) or 'ADC_GAIN_1' (STM32 driver
371
+ * requires exactly this). Defaults to 'ADC_GAIN_1_4'.
372
+ */
373
+ readonly gain?: string;
374
+ /**
375
+ * Zephyr `enum adc_reference` macro, e.g. 'ADC_REF_INTERNAL'. Defaults to
376
+ * 'ADC_REF_INTERNAL' — on nRF that is the 0.6 V internal ref measured
377
+ * through the gain divider; the STM32 driver ALSO requires
378
+ * ADC_REF_INTERNAL (Zephyr maps it to the VREF+ pad) with vrefMv = VDDA.
379
+ */
380
+ readonly reference?: string;
153
381
  };
154
382
  /**
155
383
  * DAC: the DAC device node label + the pin→channel map. Present only on chips
@@ -164,6 +392,25 @@ export interface ZephyrChipDescriptor {
164
392
  readonly wdt?: {
165
393
  readonly nodeLabel: string;
166
394
  };
395
+ /**
396
+ * Storage partition to synthesize when the board DTS ships none. Boards
397
+ * with an MCUboot-style partition map (most STM32s) define boot/slot
398
+ * partitions but no `storage_partition`, which the Preferences/FS backends
399
+ * (ZMS/littlefs) require. Present = "the overlay generator must declare
400
+ * this partition under &flash0"; boards whose DTS already carries one
401
+ * (ESP32 devkits) omit it — the overlay only adds the /chosen pointer.
402
+ * The region must cover ≥2 flash pages (ZMS minimum) and stay clear of
403
+ * the linked application image.
404
+ */
405
+ readonly storage?: {
406
+ /** Partition start offset in flash, page-aligned. */
407
+ readonly offset: number;
408
+ /** Partition size in bytes, a multiple of the flash page size. */
409
+ readonly size: number;
410
+ /** True when the board's own DTS already declares this partition — the
411
+ * overlay must only point /chosen at it, never redeclare the node. */
412
+ readonly preexisting?: boolean;
413
+ };
167
414
  /**
168
415
  * Hardware timers exposed as Zephyr counter devices. `instance` (the HAL
169
416
  * hwtimer.* op's instance index) maps to `controllers[instance].nodeLabel`.
@@ -181,4 +428,127 @@ export interface ZephyrChipDescriptor {
181
428
  readonly wifi?: {
182
429
  readonly supported: true;
183
430
  };
431
+ /**
432
+ * Probe methods the board supports, in user-facing terms. Each entry maps a
433
+ * friendly id (`stlink`, `dfu`, `jlink`, …) to the west runner it drives
434
+ * plus any args the method always needs — the hardware quirks (e.g. openocd
435
+ * needing `reset_config none` when the SRST line is unwired) live here,
436
+ * verified with the board, instead of in user configs. One probe method
437
+ * serves BOTH flashing and debugging (the same attach session); entries
438
+ * that cannot debug (bootloaders) set `debug: false`. Users select one via
439
+ * `zephyr.probe` in cuttlefish.config.ts or `--probe` on the CLI;
440
+ * `zephyr.runner`/`runnerArgs` remain the raw escape hatch underneath.
441
+ */
442
+ readonly probeMethods?: readonly ZephyrProbeMethod[];
443
+ /**
444
+ * Silicon-level inputs for the custom-board generator — present when the
445
+ * chip was resolved from an MCU package's `zephyr` block (an MCU-only
446
+ * config with no board package). The generator emits an out-of-tree Zephyr
447
+ * board (`boards/typecad/<name>/` in the project) from exactly this data:
448
+ * SoC name, devicetree includes, the default console mux, and the default
449
+ * clock plan. Absent on board-resolved chips (their board already exists).
450
+ */
451
+ readonly customBoard?: ZephyrCustomBoardData;
452
+ }
453
+ /**
454
+ * Everything the custom-board generator needs from the silicon to emit a
455
+ * minimal, buildable out-of-tree board for a chip with no board package.
456
+ */
457
+ export interface ZephyrCustomBoardData {
458
+ /** Zephyr SoC name(s) for board.yml + the Kconfig SOC_* selection. */
459
+ readonly socs: readonly string[];
460
+ /** Devicetree includes for the generated board DTS root (SoC + pinctrl). */
461
+ readonly dtsIncludes: readonly string[];
462
+ /** The default console the generated board enables. */
463
+ readonly console: {
464
+ /** Controller nodelabel, e.g. 'usart1'. */
465
+ readonly nodeLabel: string;
466
+ /** TX pinctrl token from the SoC's pinctrl dtsi, e.g. 'usart1_tx_pa9'. */
467
+ readonly tx: string;
468
+ /** RX pinctrl token, e.g. 'usart1_rx_pa10'. */
469
+ readonly rx: string;
470
+ /** Baud rate (the DT `current-speed`). */
471
+ readonly speed: number;
472
+ };
473
+ /**
474
+ * Default clock plan — the numbers the generated DTS writes into the SoC's
475
+ * clock nodes (HSE crystal frequency, PLL dividers, bus prescalers). A
476
+ * board package overrides with its own crystal/plan; a custom board uses
477
+ * this silicon default.
478
+ */
479
+ readonly clocks: {
480
+ /** HSE crystal frequency in MHz. */
481
+ readonly hseMHz: number;
482
+ /** PLL divider/multiplier plan. */
483
+ readonly pll: {
484
+ readonly divM: number;
485
+ readonly mulN: number;
486
+ readonly divP: number;
487
+ readonly divQ: number;
488
+ };
489
+ /** System clock frequency in MHz (the &rcc clock-frequency). */
490
+ readonly sysMHz: number;
491
+ readonly ahbPrescaler: number;
492
+ readonly apb1Prescaler: number;
493
+ readonly apb2Prescaler: number;
494
+ };
495
+ /**
496
+ * Silicon USB node to alias as `usb.controller` in the generated DTS
497
+ * (e.g. 'usbotg_fs' aliased as 'zephyr_udc0'). Omit when usb is absent.
498
+ */
499
+ readonly usbNode?: string;
500
+ /**
501
+ * Pinctrl tokens muxing the USB node's pins (e.g.
502
+ * 'usb_otg_fs_dm_pa11'/'usb_otg_fs_dp_pa12'). The st,stm32-otgfs binding
503
+ * requires pinctrl-0 on an enabled node, so the generated board pre-enables
504
+ * the USB node with exactly these (the blackpill shape). Omit when the
505
+ * SoC's USB needs no board-side muxing.
506
+ */
507
+ readonly usbPinctrl?: readonly string[];
508
+ /**
509
+ * ADC node the generated board must pre-enable with the SoC driver's
510
+ * required properties — e.g. the STM32 F4 binding rejects an enabled adc
511
+ * node without `st,adc-clock-source`/`st,adc-prescaler` (upstream boards
512
+ * set them in their DTS; a custom board has none, so the generator emits
513
+ * them from this data). The baseline pinctrl satisfies the binding's
514
+ * pinctrl-0 requirement; the usage-driven overlay rewrites it to the
515
+ * channels the program actually reads. Omit on SoCs whose ADC needs no
516
+ * board-side enabling.
517
+ */
518
+ readonly adcNode?: {
519
+ readonly nodeLabel: string;
520
+ /** The binding's clock-source property value (e.g. 'SYNC'). */
521
+ readonly clockSource: string;
522
+ /** The binding's prescaler property value (e.g. 2). */
523
+ readonly prescaler: number;
524
+ /** Baseline pinctrl token (e.g. 'adc1_in1_pa1'). */
525
+ readonly pinctrl: string;
526
+ };
527
+ }
528
+ /**
529
+ * A named way to attach a probe to a board — what the user picks, and what
530
+ * flashing/debugging lower to.
531
+ */
532
+ export interface ZephyrProbeMethod {
533
+ /** User-facing id, stable per board (`stlink`, `dfu`, `jlink`, `uf2`, …). */
534
+ readonly id: string;
535
+ /** The west runner this method drives (flash and debug). */
536
+ readonly runner: string;
537
+ /** Args always passed with this method (before any user runnerArgs). */
538
+ readonly args?: readonly string[];
539
+ /** One-line human description for the wizard, doctor, and error messages. */
540
+ readonly description?: string;
541
+ /** Whether this method can debug (default true — SWD/JTAG probes can,
542
+ * bootloaders cannot and set this false explicitly). */
543
+ readonly debug?: boolean;
544
+ /** cortex-debug: the wire protocol (default 'swd'; esp_usb_jtag is 'jtag'). */
545
+ readonly debugInterface?: 'swd' | 'jtag';
546
+ /** cortex-debug servertype=jlink: the J-Link device name (e.g. 'STM32F411CE'). */
547
+ readonly debugDevice?: string;
548
+ /** Raw OpenOCD cfg lines for the debug server config (e.g. 'reset_config
549
+ * none') — the cfg-file form of the quirks `args` carry for west. */
550
+ readonly debugCfg?: readonly string[];
551
+ /** OpenOCD cfg `source [find …]` lines for the debug server (interface +
552
+ * target configs). Omitted entries fall back to the framework default. */
553
+ readonly debugCfgSource?: readonly string[];
184
554
  }
@@ -8,6 +8,18 @@ export const XIAO_BLE = {
8
8
  id: 'xiao_ble',
9
9
  soc: 'nrf52840',
10
10
  gpioController: 'gpio0',
11
+ // GPIO is split across two devicetree controllers: gpio0 (P0.00–P0.31)
12
+ // and gpio1 (P1.00–P1.15, HAL pins 32–47). Declaring the split makes the
13
+ // raw path emit the port-relative index against gpio1 (P1.11 = raw 11),
14
+ // which NRF_GPIO_PIN_MAP(1, 11) resolves to absolute pin 43 — the same
15
+ // physical pin the old single-controller form reached only by accident:
16
+ // gpio0 + global 43 also maps to 43 (MAP(0, 43) = 43), but that form
17
+ // trips the generic layer's port_pin_mask __ASSERT ("Unsupported pin",
18
+ // gpio0's mask covers 0–31) on any assert-enabled build.
19
+ gpioControllers: [
20
+ { nodelabel: 'gpio0', minPin: 0, maxPin: 31 },
21
+ { nodelabel: 'gpio1', minPin: 32, maxPin: 47 },
22
+ ],
11
23
  gpio: {
12
24
  dtSpecs: [
13
25
  // Onboard RGB LEDs — active-low (GPIO_ACTIVE_LOW in xiao_ble_common.dtsi).
@@ -40,6 +52,15 @@ export const XIAO_BLE = {
40
52
  uart: {
41
53
  controllers: [{ nodeLabel: 'uart0' }],
42
54
  },
55
+ // nRF52840 native USB device (USBD). The board DTS carries `zephyr_udc0`
56
+ // (the nRF USBD driver node); the overlay enables it + composes one CDC-ACM
57
+ // instance when a program uses USB0. (The console on this board is already
58
+ // USB-CDC via the board's own chosen cdc_acm_uart0 — this field exposes the
59
+ // same peripheral to usb.* HAL ops.)
60
+ usb: {
61
+ controller: 'zephyr_udc0',
62
+ cdcInstances: 1,
63
+ },
43
64
  pwm: {
44
65
  // pwm-led0 drives the board PWM LED (PWM_OUT0 on P0.17, inverted).
45
66
  specs: [{ pin: 17, dtSpec: 'pwm-led0' }],
@@ -64,4 +85,16 @@ export const XIAO_BLE = {
64
85
  // Verified against the nRF52840 SoC dtsi (rtc0/rtc1 nodes). The kernel uses
65
86
  // RTC0 for the system tick; RTC1 is available for application use.
66
87
  hwtimer: { controllers: [{ nodeLabel: 'rtc1' }] },
88
+ // Mirror of board-xiao-nrf52840's probeMethods (registry fallback parity —
89
+ // the board package's zephyr field wins when board constants are present).
90
+ probeMethods: [
91
+ { id: 'jlink', runner: 'jlink', description: 'J-Link probe (SWD)',
92
+ debug: true, debugInterface: 'swd', debugDevice: 'nRF52840_xxAA' },
93
+ { id: 'openocd', runner: 'openocd',
94
+ description: 'Any SWD probe openocd supports (CMSIS-DAP, cheap clones)',
95
+ debug: true, debugInterface: 'swd',
96
+ debugCfgSource: ['interface/stlink.cfg', 'target/nrf52.cfg'] },
97
+ { id: 'uf2', runner: 'uf2', description: 'Bootloader UF2 drag-and-drop: double-tap reset',
98
+ debug: false },
99
+ ],
67
100
  };
@@ -40,7 +40,7 @@ export const ZEPHYR_DISPLAY_PROFILES = {
40
40
  // ST7796S SPI TFT, 320x480 RGB565 mounted landscape (effective 480x320).
41
41
  // Same DT nodelabel convention as the ILI9341 — the board's devicetree
42
42
  // carries the `display0` node bound to the ST7796 driver; the overlay
43
- // enables it via status="okay". Effective dims match the Arduino
43
+ // enables it via status="okay". Effective dims match the display
44
44
  // st7796-spi profile (480x320 landscape, rotation 1).
45
45
  driver: 'st7796-zephyr',
46
46
  dtLabel: 'display0',
package/dist/doctor.js CHANGED
@@ -4,13 +4,17 @@
4
4
  // `cuttlefish doctor` (Zephyr framework) — verify west (the Zephyr build tool)
5
5
  // is installed + responsive, the Zephyr RTOS is inside the framework's declared
6
6
  // compat range, and the configured board target exists in the checkout. Exits 0
7
- // if the environment is OK, non-zero otherwise. Mirrors framework-arduino's
7
+ // if the environment is OK, non-zero otherwise. Follows the same contract
8
8
  // doctor shape (dispatched via the framework's `doctor` export) and reuses
9
9
  // checkZephyrEnv so the detection logic can be shared with the build/test gates.
10
10
  // ---------------------------------------------------------------------------
11
+ import { existsSync, readFileSync } from 'node:fs';
12
+ import { join } from 'node:path';
11
13
  import * as ui from '@typecad/cuttlefish/utils/ui';
12
14
  import { loadCuttlefishConfig } from '@typecad/cuttlefish/config-loader';
13
15
  import { checkZephyrEnv } from './toolchain/env-check.js';
16
+ import { PINNED_ZEPHYR_MANIFEST_REV, PINNED_ZEPHYR_SDK_VERSION, sdkFingerprint } from '@typecad/cuttlefish/board-catalog';
17
+ import { resolveChipFromBoard } from './chips/resolve.js';
14
18
  /**
15
19
  * Verify west is installed + responsive, the Zephyr RTOS is inside the supported
16
20
  * range, and the configured board target exists in the checkout. Sets
@@ -23,7 +27,7 @@ export function runDoctor() {
23
27
  const buildTarget = config?.buildTarget;
24
28
  const result = checkZephyrEnv(buildTarget);
25
29
  const c = result.check;
26
- // west (the Zephyr build tool) — the analog of arduino-cli presence.
30
+ // west (the Zephyr build tool) presence.
27
31
  if (c.westFound) {
28
32
  const ver = c.westVersion ?? 'found';
29
33
  const src = c.westSource ? ` (${c.westSource})` : '';
@@ -35,6 +39,9 @@ export function runDoctor() {
35
39
  // Zephyr RTOS version + declared compat range.
36
40
  ui.printInfo(`ZEPHYR_BASE ...... ${c.zephyrBase ?? '(not set)'}`);
37
41
  ui.printInfo(`Zephyr version .. ${c.zephyrVersion ?? 'unknown (could not read ZEPHYR_BASE/VERSION)'}`);
42
+ ui.printInfo(`Workspace pin ... ${PINNED_ZEPHYR_MANIFEST_REV} (SDK ${PINNED_ZEPHYR_SDK_VERSION})`);
43
+ const fp = c.zephyrBase ? sdkFingerprint(c.zephyrBase) : undefined;
44
+ ui.printInfo(`SDK fingerprint . ${fp ?? '(no tree — run ' + 'npx --package @typecad/framework-zephyr zephyr-installer)'}`);
38
45
  ui.printInfo(`Supported range . ${c.compatRange ?? '(none declared)'}`);
39
46
  if (c.compatStatus === 'out-of-range') {
40
47
  ui.printError(`Zephyr ${c.zephyrVersion} is OUTSIDE the supported range (${c.compatRange}).`);
@@ -45,7 +52,7 @@ export function runDoctor() {
45
52
  else {
46
53
  ui.printInfo('Zephyr compat ... OK');
47
54
  }
48
- // Board target — the analog of the Arduino core presence check.
55
+ // Board target availability.
49
56
  if (buildTarget) {
50
57
  const resolved = c.resolvedBoardTarget ?? buildTarget;
51
58
  const arrow = resolved === buildTarget ? '' : ` → ${resolved}`;
@@ -64,7 +71,34 @@ export function runDoctor() {
64
71
  else {
65
72
  ui.printInfo('(no buildTarget in cuttlefish.config.ts — skipping board check)');
66
73
  }
67
- // Exit codemirrors framework-arduino's doctor.
74
+ // Probe methodsfrom the board package's table, via the board constants
75
+ // the transpile persists (candidates cover the standard out-dir layouts).
76
+ // The debug line lists the debug-capable subset (bootloaders can't debug).
77
+ if (buildTarget) {
78
+ const bcPath = [
79
+ join(process.cwd(), 'out', 'src', 'board-constants.json'),
80
+ join(process.cwd(), 'out', 'board-constants.json'),
81
+ join(process.cwd(), 'src', 'out', 'src', 'board-constants.json'),
82
+ join(process.cwd(), 'src', 'out', 'board-constants.json'),
83
+ ].find((p) => existsSync(p));
84
+ if (bcPath) {
85
+ try {
86
+ const raw = JSON.parse(readFileSync(bcPath, 'utf8'));
87
+ const chip = resolveChipFromBoard(new Map(Object.entries(raw)));
88
+ const methods = chip?.probeMethods ?? [];
89
+ if (methods.length > 0) {
90
+ ui.printInfo(`Probe methods .... ${methods.map((m) => m.id).join(', ')} (zephyr.probe / --probe)`);
91
+ const debuggable = methods.filter((m) => m.debug !== false).map((m) => m.id);
92
+ ui.printInfo(`Debug methods .... ${debuggable.join(', ') || '(none — an external probe is required)'}`);
93
+ }
94
+ }
95
+ catch { /* best-effort listing */ }
96
+ }
97
+ else {
98
+ ui.printInfo('Probe methods .... (build once to list them)');
99
+ }
100
+ }
101
+ // Exit code — 0 ok, non-zero otherwise.
68
102
  if (result.ok) {
69
103
  ui.printSuccess('Environment OK');
70
104
  return; // exitCode stays unset => 0
@@ -0,0 +1,23 @@
1
+ import type { ZephyrChipDescriptor } from '../chips/types.js';
2
+ /**
3
+ * Sanitize a raw name into a legal Zephyr board name: lowercase, `[a-z0-9_]`
4
+ * (dashes/dots/spaces collapse to underscores, leading/trailing underscores
5
+ * trimmed). Board names become C identifiers in Kconfig symbols, so anything
6
+ * stricter would break `config BOARD_<NAME>`.
7
+ */
8
+ export declare function sanitizeBoardName(raw: string): string;
9
+ /** Generated-board file set, all under `<projectRoot>/boards/typecad/<name>/`. */
10
+ export interface GeneratedCustomBoard {
11
+ /** Absolute directory of the generated board. */
12
+ dir: string;
13
+ /** The sanitized board name (the `west build -b` argument). */
14
+ name: string;
15
+ /** Whether any file changed (idempotent regeneration signal). */
16
+ changed: boolean;
17
+ }
18
+ /**
19
+ * Emit the custom board for a chip whose descriptor carries `customBoard`
20
+ * silicon data. No-op (returns null) when the chip has no generator inputs —
21
+ * board-resolved chips don't need one.
22
+ */
23
+ export declare function generateCustomBoard(projectRoot: string, chip: ZephyrChipDescriptor, rawName: string): GeneratedCustomBoard | null;