@typecad/framework-zephyr 1.0.0-alpha.16 → 1.0.0-alpha.19
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.
- package/LICENSE +202 -21
- package/README.md +49 -87
- package/dist/as-built.d.ts +2 -2
- package/dist/as-built.js +2 -2
- package/dist/audit.d.ts +111 -0
- package/dist/audit.js +416 -0
- package/dist/boardgen.d.ts +1 -9
- package/dist/boardgen.js +288 -47
- package/dist/chips/resolve.js +20 -0
- package/dist/chips/types.d.ts +22 -1
- package/dist/debug-codegen.js +1 -1
- package/dist/display/bindings.d.ts +55 -0
- package/dist/display/bindings.js +316 -0
- package/dist/display/gfx.d.ts +2 -3
- package/dist/display/gfx.js +166 -154
- package/dist/display/index.js +20 -1
- package/dist/display/mipi-dbi-host.d.ts +9 -0
- package/dist/display/mipi-dbi-host.js +174 -0
- package/dist/display/profiles.d.ts +109 -4
- package/dist/display/profiles.js +270 -7
- package/dist/display/touch-adapter.js +119 -49
- package/dist/display/ui-adapter-eink.d.ts +2 -0
- package/dist/display/ui-adapter-eink.js +4 -0
- package/dist/display/ui-adapter-gray.d.ts +8 -0
- package/dist/display/ui-adapter-gray.js +170 -0
- package/dist/display/ui-adapter-mono.d.ts +13 -0
- package/dist/display/ui-adapter-mono.js +230 -0
- package/dist/display/ui-adapter-native.d.ts +10 -0
- package/dist/display/ui-adapter-native.js +295 -0
- package/dist/display/ui-adapter-shared.d.ts +11 -0
- package/dist/display/ui-adapter-shared.js +122 -0
- package/dist/display/ui-adapter.js +510 -558
- package/dist/doctor.js +4 -4
- package/dist/dt-config/custom-board.js +2 -2
- package/dist/dt-config/kconfig.d.ts +62 -1
- package/dist/dt-config/kconfig.js +141 -38
- package/dist/dt-config/overlay.d.ts +15 -2
- package/dist/dt-config/overlay.js +433 -18
- package/dist/framework.manifest.d.ts +10 -4
- package/dist/framework.manifest.js +133 -17
- package/dist/index.d.ts +2 -0
- package/dist/index.js +14 -6
- package/dist/licenses.d.ts +2 -2
- package/dist/licenses.js +13 -92
- package/dist/lowering/can.d.ts +25 -0
- package/dist/lowering/can.js +97 -0
- package/dist/lowering/clock.d.ts +17 -0
- package/dist/lowering/clock.js +58 -0
- package/dist/lowering/fs.js +1 -1
- package/dist/lowering/gpio.js +0 -32
- package/dist/lowering/hid.d.ts +27 -0
- package/dist/lowering/hid.js +244 -0
- package/dist/lowering/http.js +264 -32
- package/dist/lowering/i2c.d.ts +8 -0
- package/dist/lowering/i2c.js +137 -5
- package/dist/lowering/i2s.d.ts +27 -0
- package/dist/lowering/i2s.js +98 -0
- package/dist/lowering/index.d.ts +9 -1
- package/dist/lowering/index.js +25 -1
- package/dist/lowering/interrupts.js +6 -0
- package/dist/lowering/matrix.d.ts +15 -0
- package/dist/lowering/matrix.js +63 -0
- package/dist/lowering/mqtt.js +110 -8
- package/dist/lowering/power.d.ts +3 -2
- package/dist/lowering/power.js +20 -45
- package/dist/lowering/pwm.js +25 -0
- package/dist/lowering/sensor.d.ts +2 -2
- package/dist/lowering/sensor.js +8 -4
- package/dist/lowering/strip.d.ts +16 -0
- package/dist/lowering/strip.js +70 -0
- package/dist/lowering/thread.js +5 -1
- package/dist/lowering/trace.d.ts +44 -0
- package/dist/lowering/trace.js +239 -0
- package/dist/lowering/uart.js +6 -1
- package/dist/lowering/usb.d.ts +3 -1
- package/dist/lowering/usb.js +16 -13
- package/dist/lowering/wdt.js +2 -29
- package/dist/sbom.d.ts +181 -0
- package/dist/sbom.js +901 -0
- package/dist/sdk/board-catalog-sync.d.ts +1 -3
- package/dist/sdk/board-catalog-sync.js +4 -10
- package/dist/strategy.d.ts +82 -46
- package/dist/strategy.js +639 -182
- package/dist/tmp-probe.d.ts +2 -0
- package/dist/tmp-probe.js +9 -0
- package/dist/toolchain/debug-config.d.ts +50 -90
- package/dist/toolchain/debug-config.js +239 -510
- package/dist/toolchain/env-check.d.ts +1 -3
- package/dist/toolchain/env-check.js +2 -7
- package/dist/toolchain/index.d.ts +28 -3
- package/dist/toolchain/index.js +498 -62
- package/dist/toolchain/runners.d.ts +16 -0
- package/dist/toolchain/runners.js +75 -0
- package/dist/toolchain/scaffold.d.ts +5 -2
- package/dist/toolchain/scaffold.js +79 -15
- package/dist/toolchain/west-discover.d.ts +6 -0
- package/dist/toolchain/west-discover.js +36 -13
- package/dist/toolchain/west-spawn.js +8 -2
- package/dist/west-inventory.d.ts +25 -0
- package/dist/west-inventory.js +97 -0
- package/installer/README.md +328 -328
- package/installer/install.sh +2 -2
- package/installer/templates/project/.typecad/activate-zephyr.ps1 +1 -1
- package/installer/templates/project/.typecad/activate-zephyr.sh +1 -1
- package/installer/templates/project/.vscode/settings.json +1 -1
- package/installer/templates/project/README.md +2 -2
- package/package.json +5 -5
- package/src/as-built.ts +206 -206
- package/src/audit.ts +529 -0
- package/src/boardgen.ts +265 -50
- package/src/chips/resolve.ts +21 -0
- package/src/chips/types.ts +10 -1
- package/src/display/bindings.ts +347 -0
- package/src/display/gfx.ts +318 -306
- package/src/display/index.ts +87 -70
- package/src/display/mipi-dbi-host.ts +183 -0
- package/src/display/profiles.ts +458 -139
- package/src/display/touch-adapter.ts +119 -49
- package/src/display/ui-adapter-eink.ts +13 -0
- package/src/display/ui-adapter-gray.ts +178 -0
- package/src/display/ui-adapter-mono.ts +238 -0
- package/src/display/ui-adapter-native.ts +304 -0
- package/src/display/ui-adapter-shared.ts +125 -0
- package/src/display/ui-adapter.ts +732 -781
- package/src/doctor.ts +4 -4
- package/src/dt-config/custom-board.ts +2 -2
- package/src/dt-config/kconfig.ts +647 -505
- package/src/dt-config/overlay.ts +1475 -1058
- package/src/framework.manifest.ts +659 -535
- package/src/index.ts +16 -6
- package/src/licenses.ts +346 -425
- package/src/lowering/can.ts +140 -0
- package/src/lowering/clock.ts +91 -0
- package/src/lowering/fs.ts +135 -135
- package/src/lowering/gpio.ts +0 -33
- package/src/lowering/hid.ts +261 -0
- package/src/lowering/http.ts +264 -32
- package/src/lowering/i2c.ts +142 -5
- package/src/lowering/i2s.ts +143 -0
- package/src/lowering/index.ts +18 -1
- package/src/lowering/interrupts.ts +6 -0
- package/src/lowering/matrix.ts +70 -0
- package/src/lowering/mqtt.ts +109 -8
- package/src/lowering/power.ts +41 -0
- package/src/lowering/pwm.ts +192 -167
- package/src/lowering/sensor.ts +159 -155
- package/src/lowering/strip.ts +81 -0
- package/src/lowering/thread.ts +5 -1
- package/src/lowering/trace.ts +270 -0
- package/src/lowering/uart.ts +6 -1
- package/src/lowering/usb.ts +16 -13
- package/src/lowering/wdt.ts +2 -25
- package/src/sbom.ts +1117 -0
- package/src/sdk/board-catalog-sync.ts +4 -25
- package/src/strategy.ts +2680 -2309
- package/src/toolchain/debug-config.ts +262 -522
- package/src/toolchain/env-check.ts +279 -285
- package/src/toolchain/index.ts +1792 -1359
- package/src/toolchain/runners.ts +80 -0
- package/src/toolchain/scaffold.ts +355 -296
- package/src/toolchain/west-discover.ts +35 -13
- package/src/toolchain/west-spawn.ts +174 -168
- package/src/west-inventory.ts +102 -0
- package/dist/async/timer-polyfill.d.ts +0 -10
- package/dist/async/timer-polyfill.js +0 -95
- package/dist/chips/board-overrides.d.ts +0 -7
- package/dist/chips/board-overrides.js +0 -11
- package/dist/chips/esp32.d.ts +0 -2
- package/dist/chips/esp32.js +0 -71
- package/dist/chips/esp32s3.d.ts +0 -2
- package/dist/chips/esp32s3.js +0 -103
- package/dist/chips/soc/.d.ts +0 -2
- package/dist/chips/soc/.js +0 -129
- package/dist/chips/soc/esp32.d.ts +0 -2
- package/dist/chips/soc/esp32.js +0 -120
- package/dist/chips/soc/esp32c3.d.ts +0 -2
- package/dist/chips/soc/esp32c3.js +0 -90
- package/dist/chips/soc/esp32c6.d.ts +0 -2
- package/dist/chips/soc/esp32c6.js +0 -109
- package/dist/chips/soc/esp32s3.d.ts +0 -2
- package/dist/chips/soc/esp32s3.js +0 -189
- package/dist/chips/soc/index.d.ts +0 -2
- package/dist/chips/soc/index.js +0 -23
- package/dist/chips/soc/nrf52840.d.ts +0 -2
- package/dist/chips/soc/nrf52840.js +0 -130
- package/dist/chips/soc/rp2040.d.ts +0 -2
- package/dist/chips/soc/rp2040.js +0 -141
- package/dist/chips/soc/rp2350a.d.ts +0 -2
- package/dist/chips/soc/rp2350a.js +0 -145
- package/dist/chips/soc/samd21g18a.d.ts +0 -2
- package/dist/chips/soc/samd21g18a.js +0 -143
- package/dist/chips/soc/stm32f411xe.d.ts +0 -2
- package/dist/chips/soc/stm32f411xe.js +0 -251
- package/dist/chips/xiao-ble.d.ts +0 -2
- package/dist/chips/xiao-ble.js +0 -100
- package/dist/lowering/pulse.d.ts +0 -7
- package/dist/lowering/pulse.js +0 -51
- package/dist/lowering/tone.d.ts +0 -10
- package/dist/lowering/tone.js +0 -63
- package/dist/lowering/worker-backing.d.ts +0 -14
- package/dist/lowering/worker-backing.js +0 -79
- package/dist/lowering/worker.d.ts +0 -6
- package/dist/lowering/worker.js +0 -14
- package/dist/sdk/board-data.generated.d.ts +0 -2
- package/dist/sdk/board-data.generated.js +0 -4
- package/dist/sdk/catalog-walker.d.ts +0 -90
- package/dist/sdk/catalog-walker.js +0 -682
- package/dist/sdk/dts-reader.d.ts +0 -83
- package/dist/sdk/dts-reader.js +0 -596
- package/src/debug-codegen.ts +0 -207
|
@@ -10,7 +10,10 @@ export interface ZephyrDisplayProfile {
|
|
|
10
10
|
* effective size (e.g. a 320x480 panel mounted landscape = 480x320). */
|
|
11
11
|
readonly nativeWidth?: number;
|
|
12
12
|
readonly nativeHeight?: number;
|
|
13
|
-
readonly colorFormat: 'rgb565' | 'mono';
|
|
13
|
+
readonly colorFormat: 'rgb565' | 'mono' | 'gray8';
|
|
14
|
+
/** Panel class — drives the capability derivation (eink ⇒ deferred
|
|
15
|
+
* refresh, all dynamic features off). */
|
|
16
|
+
readonly displayClass?: 'tft' | 'eink' | 'oled';
|
|
14
17
|
/** Applied via display_set_orientation (0/90/180/270). */
|
|
15
18
|
readonly rotation?: number;
|
|
16
19
|
/** DT alias for the backlight GPIO (set high at init), if any. */
|
|
@@ -20,6 +23,38 @@ export interface ZephyrDisplayProfile {
|
|
|
20
23
|
* Required for rgb565 profiles; mono profiles use the direct-op GFX
|
|
21
24
|
* runtime and ignore it. */
|
|
22
25
|
readonly controller?: ZephyrPanelController;
|
|
26
|
+
/** How the UI adapter reaches the panel:
|
|
27
|
+
* - 'direct-spi' (default): the emitted adapter drives the panel directly
|
|
28
|
+
* over spi_write (Adafruit ST77xx protocol, CS held across command+data).
|
|
29
|
+
* Required for panels the in-tree drivers cannot init (clone ST7796S —
|
|
30
|
+
* the generic mipi-dbi-spi bridge deasserts CS between the command byte
|
|
31
|
+
* and its parameters, which scrambles those panels).
|
|
32
|
+
* - 'zephyr-display': the adapter calls Zephyr's display API
|
|
33
|
+
* (display_write/display_get_capabilities) on the DT display device; an
|
|
34
|
+
* in-tree panel driver (bound from the overlay's display node) owns the
|
|
35
|
+
* init sequence, rotation, and wire format. */
|
|
36
|
+
readonly transport?: ZephyrDisplayTransport;
|
|
37
|
+
/** Which mipi-dbi host device backs the panel driver under the
|
|
38
|
+
* 'zephyr-display' transport:
|
|
39
|
+
* - 'spi-bridge' (default): the stock zephyr,mipi-dbi-spi host
|
|
40
|
+
* (CONFIG_MIPI_DBI_SPI). Fine for panels that tolerate per-transaction
|
|
41
|
+
* CS (standard ILI9341 modules).
|
|
42
|
+
* - 'local-hold-cs': an app-local host device the adapter emits — the
|
|
43
|
+
* mipi-dbi-spi protocol with CS held across each command+data burst
|
|
44
|
+
* (GPIO-managed, mirroring the hardware-verified direct transport).
|
|
45
|
+
* Needed for clone ST77xx panels the stock bridge scrambles; implements
|
|
46
|
+
* the mipi-hold-cs behavior the binding documents but 4.4.2 does not. */
|
|
47
|
+
readonly dbiHost?: ZephyrDbiHost;
|
|
48
|
+
/** The panel's R and B channels are crossed in 16-bit mode (verified clone
|
|
49
|
+
* ST7796S quirk): the native adapter swaps R/B channels at pack time so
|
|
50
|
+
* the in-tree driver's RGB565 stream renders with true colors (lossless —
|
|
51
|
+
* the direct transport instead avoids it by driving 18-bit mode). */
|
|
52
|
+
readonly channelSwapRb?: boolean;
|
|
53
|
+
/** RGB565 wire byte-order inversion: the overlay emits the st7796s-family
|
|
54
|
+
* rgb-is-inverted DT property, flipping the format the in-tree driver
|
|
55
|
+
* reports (565 <-> 565X) so the adapter byte-swaps at pack time. Clone
|
|
56
|
+
* SPI panels whose white reads purple / dark reads green need it. */
|
|
57
|
+
readonly rgbInverted?: boolean;
|
|
23
58
|
/** DT compatible string for the display@0 node. Defaults per controller
|
|
24
59
|
* (see PANEL_CONTROLLER_DEFAULTS) — override only for a panel whose DT
|
|
25
60
|
* binding differs from its controller family. */
|
|
@@ -30,17 +65,87 @@ export interface ZephyrDisplayProfile {
|
|
|
30
65
|
/** Nodelabel of the MIPI DBI bridge node carrying the dc/reset GPIOs.
|
|
31
66
|
* Default 'mipi_dbi' (the overlay emits the bridge under that label). */
|
|
32
67
|
readonly bridgeLabel?: string;
|
|
68
|
+
/** The board's own devicetree already wires this display (native_sim's
|
|
69
|
+
* built-in sdl_dc): the overlay emits NO display node — the dtLabel points
|
|
70
|
+
* at the board's node. */
|
|
71
|
+
readonly boardProvidesDisplay?: boolean;
|
|
72
|
+
/** Extra Kconfig fragments the profile requires (e.g. the SDL panel's mono
|
|
73
|
+
* pixel-format choice). Appended verbatim to the generated prj.conf. */
|
|
74
|
+
readonly kconfig?: readonly string[];
|
|
33
75
|
}
|
|
76
|
+
/** How the UI adapter talks to the panel (see ZephyrDisplayProfile.transport). */
|
|
77
|
+
export type ZephyrDisplayTransport = 'direct-spi' | 'zephyr-display';
|
|
78
|
+
/** Which mipi-dbi host backs the panel driver (see ZephyrDisplayProfile.dbiHost). */
|
|
79
|
+
export type ZephyrDbiHost = 'spi-bridge' | 'local-hold-cs';
|
|
80
|
+
/** Resolve a profile's transport with the historical default. */
|
|
81
|
+
export declare function transportFor(profile: Pick<ZephyrDisplayProfile, 'transport'>): ZephyrDisplayTransport;
|
|
82
|
+
/** Resolve a profile's mipi-dbi host. Clone-ST77xx panels need the local
|
|
83
|
+
* CS-holding host; everything else defaults to the stock SPI bridge. */
|
|
84
|
+
export declare function dbiHostFor(profile: Pick<ZephyrDisplayProfile, 'dbiHost' | 'controller'>): ZephyrDbiHost;
|
|
85
|
+
/** Marker the display adapters stamp into the emitted source so the toolchain
|
|
86
|
+
* can recover the exact profile that produced it (one source of truth — the
|
|
87
|
+
* profile registry — instead of re-deriving geometry from emitted C). */
|
|
88
|
+
export declare const DISPLAY_PROFILE_MARKER = "typecad-display-profile:";
|
|
89
|
+
/** Machine-readable facts line the adapters stamp beside the marker: JSON
|
|
90
|
+
* carrying everything the toolchain needs to regenerate the DT overlay —
|
|
91
|
+
* including synthesized (compatible-driven) profiles that have no registry
|
|
92
|
+
* entry. */
|
|
93
|
+
export declare function displayFactsLine(profile: ZephyrDisplayProfile): string;
|
|
94
|
+
/** Recover the profile whose adapter emitted this source, or undefined when
|
|
95
|
+
* no display adapter marker is present (no display in the program). Prefers
|
|
96
|
+
* the JSON facts line (carries synthesized profiles); falls back to the
|
|
97
|
+
* plain marker + registry lookup. */
|
|
98
|
+
export declare function profileFromEmittedSource(src: string): ZephyrDisplayProfile | undefined;
|
|
34
99
|
/** Panel controllers the direct-drive UI adapter knows how to init. */
|
|
35
|
-
export type ZephyrPanelController = 'st7796s' | 'ili9341';
|
|
100
|
+
export type ZephyrPanelController = 'st7796s' | 'ili9341' | 'ssd16xx' | 'uc81xx';
|
|
36
101
|
/** Per-controller DT + transport defaults, shared by the overlay generator
|
|
37
102
|
* (DT node props) and the UI adapter (init sequence + wire format). */
|
|
38
103
|
export declare const PANEL_CONTROLLER_DEFAULTS: Record<ZephyrPanelController, {
|
|
39
104
|
dtCompatible: string;
|
|
40
105
|
}>;
|
|
41
106
|
/** Resolve a profile's panel controller, inferring it from the driver id when
|
|
42
|
-
* the profile doesn't declare one (the '<controller>-zephyr' naming scheme).
|
|
43
|
-
|
|
107
|
+
* the profile doesn't declare one (the '<controller>-zephyr' naming scheme).
|
|
108
|
+
* Synthesized (compatible-driven) profiles carry no controller — undefined
|
|
109
|
+
* routes them to the binding-driven generic paths. */
|
|
110
|
+
export declare function panelControllerFor(profile: Pick<ZephyrDisplayProfile, 'driver' | 'controller'>): ZephyrPanelController | undefined;
|
|
111
|
+
/** A DT compatible string (vendor,name) — the drop-in driver id shape. */
|
|
112
|
+
export declare function isDtCompatible(driver: string): boolean;
|
|
113
|
+
/** True when a drop-in compatible (or explicit config) selects the e-ink
|
|
114
|
+
* lowering target — mono format + deferred refresh. */
|
|
115
|
+
export declare function isEinkDisplay(display: {
|
|
116
|
+
driver: string;
|
|
117
|
+
displayClass?: string;
|
|
118
|
+
}): boolean;
|
|
119
|
+
/** True when a drop-in compatible (or explicit config) selects the gray8
|
|
120
|
+
* (8-bit luminance) lowering target. */
|
|
121
|
+
export declare function isGrayDisplay(display: {
|
|
122
|
+
driver: string;
|
|
123
|
+
colorFormat?: string;
|
|
124
|
+
}): boolean;
|
|
125
|
+
/** True when a drop-in compatible (or explicit config) selects the mono
|
|
126
|
+
* (1bpp) lowering target. */
|
|
127
|
+
export declare function isMonoDisplay(display: {
|
|
128
|
+
driver: string;
|
|
129
|
+
colorFormat?: string;
|
|
130
|
+
}): boolean;
|
|
131
|
+
/** Synthesize a native-transport profile for a compatible-driven config
|
|
132
|
+
* (display.driver = DT compatible, no registry profile). The in-tree driver
|
|
133
|
+
* bound by the overlay's display node owns init/geometry/quirks; the
|
|
134
|
+
* config's panel-quirk flags (channelSwapRb, csHold) carry what the
|
|
135
|
+
* driver cannot know. Returns undefined unless the driver string is a
|
|
136
|
+
* compatible shape. */
|
|
137
|
+
export declare function synthesizeZephyrProfile(display: {
|
|
138
|
+
driver: string;
|
|
139
|
+
width: number;
|
|
140
|
+
height: number;
|
|
141
|
+
nativeWidth?: number;
|
|
142
|
+
nativeHeight?: number;
|
|
143
|
+
colorFormat?: string;
|
|
144
|
+
rotation?: number;
|
|
145
|
+
channelSwapRb?: boolean;
|
|
146
|
+
csHold?: boolean;
|
|
147
|
+
rgbInverted?: boolean;
|
|
148
|
+
}): ZephyrDisplayProfile | undefined;
|
|
44
149
|
/**
|
|
45
150
|
* Built-in profile registry. Looked up by driver id. Add a profile here when a
|
|
46
151
|
* new board's display node is wired into its devicetree.
|
package/dist/display/profiles.js
CHANGED
|
@@ -6,20 +6,206 @@
|
|
|
6
6
|
// pin wiring. The GFX runtime (gfx.ts) reads width/height/colorFormat from the
|
|
7
7
|
// active profile to size its line buffer.
|
|
8
8
|
// ---------------------------------------------------------------------------
|
|
9
|
+
/** Resolve a profile's transport with the historical default. */
|
|
10
|
+
export function transportFor(profile) {
|
|
11
|
+
return profile.transport ?? 'direct-spi';
|
|
12
|
+
}
|
|
13
|
+
/** Resolve a profile's mipi-dbi host. Clone-ST77xx panels need the local
|
|
14
|
+
* CS-holding host; everything else defaults to the stock SPI bridge. */
|
|
15
|
+
export function dbiHostFor(profile) {
|
|
16
|
+
if (profile.dbiHost)
|
|
17
|
+
return profile.dbiHost;
|
|
18
|
+
return profile.controller === 'st7796s' ? 'local-hold-cs' : 'spi-bridge';
|
|
19
|
+
}
|
|
20
|
+
/** Marker the display adapters stamp into the emitted source so the toolchain
|
|
21
|
+
* can recover the exact profile that produced it (one source of truth — the
|
|
22
|
+
* profile registry — instead of re-deriving geometry from emitted C). */
|
|
23
|
+
export const DISPLAY_PROFILE_MARKER = 'typecad-display-profile:';
|
|
24
|
+
/** Machine-readable facts line the adapters stamp beside the marker: JSON
|
|
25
|
+
* carrying everything the toolchain needs to regenerate the DT overlay —
|
|
26
|
+
* including synthesized (compatible-driven) profiles that have no registry
|
|
27
|
+
* entry. */
|
|
28
|
+
export function displayFactsLine(profile) {
|
|
29
|
+
const controller = panelControllerFor(profile);
|
|
30
|
+
const facts = {
|
|
31
|
+
driver: profile.driver,
|
|
32
|
+
transport: transportFor(profile),
|
|
33
|
+
width: profile.width,
|
|
34
|
+
height: profile.height,
|
|
35
|
+
};
|
|
36
|
+
if (profile.nativeWidth !== undefined)
|
|
37
|
+
facts.nativeWidth = profile.nativeWidth;
|
|
38
|
+
if (profile.nativeHeight !== undefined)
|
|
39
|
+
facts.nativeHeight = profile.nativeHeight;
|
|
40
|
+
if (controller !== undefined)
|
|
41
|
+
facts.controller = controller;
|
|
42
|
+
if (profile.rotation !== undefined)
|
|
43
|
+
facts.rotation = profile.rotation;
|
|
44
|
+
if (profile.channelSwapRb === true)
|
|
45
|
+
facts.channelSwapRb = true;
|
|
46
|
+
if (profile.rgbInverted === true)
|
|
47
|
+
facts.rgbInverted = true;
|
|
48
|
+
if (transportFor(profile) === 'zephyr-display') {
|
|
49
|
+
facts.dbiHost = dbiHostFor(profile);
|
|
50
|
+
}
|
|
51
|
+
return `// typecad-display-facts: ${JSON.stringify(facts)}`;
|
|
52
|
+
}
|
|
53
|
+
/** Recover the profile whose adapter emitted this source, or undefined when
|
|
54
|
+
* no display adapter marker is present (no display in the program). Prefers
|
|
55
|
+
* the JSON facts line (carries synthesized profiles); falls back to the
|
|
56
|
+
* plain marker + registry lookup. */
|
|
57
|
+
export function profileFromEmittedSource(src) {
|
|
58
|
+
const facts = src.match(/typecad-display-facts: (\{.*\})/);
|
|
59
|
+
if (facts) {
|
|
60
|
+
try {
|
|
61
|
+
const f = JSON.parse(facts[1]);
|
|
62
|
+
const registered = ZEPHYR_DISPLAY_PROFILES[f.driver];
|
|
63
|
+
if (registered)
|
|
64
|
+
return registered;
|
|
65
|
+
if (typeof f.driver === 'string' && isDtCompatible(f.driver)) {
|
|
66
|
+
const synth = synthesizeZephyrProfile({
|
|
67
|
+
driver: f.driver,
|
|
68
|
+
width: f.width,
|
|
69
|
+
height: f.height,
|
|
70
|
+
nativeWidth: f.nativeWidth,
|
|
71
|
+
nativeHeight: f.nativeHeight,
|
|
72
|
+
rotation: f.rotation,
|
|
73
|
+
channelSwapRb: f.channelSwapRb === true,
|
|
74
|
+
rgbInverted: f.rgbInverted === true,
|
|
75
|
+
csHold: f.dbiHost === 'local-hold-cs',
|
|
76
|
+
});
|
|
77
|
+
if (synth)
|
|
78
|
+
return synth;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
// Malformed facts line — fall through to the plain marker.
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const m = src.match(/typecad-display-profile: ([\w-]+)/);
|
|
86
|
+
if (!m)
|
|
87
|
+
return undefined;
|
|
88
|
+
return ZEPHYR_DISPLAY_PROFILES[m[1]];
|
|
89
|
+
}
|
|
9
90
|
/** Per-controller DT + transport defaults, shared by the overlay generator
|
|
10
91
|
* (DT node props) and the UI adapter (init sequence + wire format). */
|
|
11
92
|
export const PANEL_CONTROLLER_DEFAULTS = {
|
|
12
93
|
st7796s: { dtCompatible: 'sitronix,st7796s' },
|
|
13
94
|
ili9341: { dtCompatible: 'ilitek,ili9341' },
|
|
95
|
+
// E-ink families: no single dtCompatible (the drop-in driver IS one of the
|
|
96
|
+
// many panel compatibles) — the overlay branch keys off the driver string.
|
|
97
|
+
ssd16xx: { dtCompatible: 'solomon,ssd16xx' },
|
|
98
|
+
uc81xx: { dtCompatible: 'ultrachip,uc81xx' },
|
|
14
99
|
};
|
|
15
100
|
/** Resolve a profile's panel controller, inferring it from the driver id when
|
|
16
|
-
* the profile doesn't declare one (the '<controller>-zephyr' naming scheme).
|
|
101
|
+
* the profile doesn't declare one (the '<controller>-zephyr' naming scheme).
|
|
102
|
+
* Synthesized (compatible-driven) profiles carry no controller — undefined
|
|
103
|
+
* routes them to the binding-driven generic paths. */
|
|
17
104
|
export function panelControllerFor(profile) {
|
|
18
105
|
if (profile.controller)
|
|
19
106
|
return profile.controller;
|
|
20
107
|
if (profile.driver.startsWith('ili9341'))
|
|
21
108
|
return 'ili9341';
|
|
22
|
-
|
|
109
|
+
if (profile.driver.startsWith('st7796'))
|
|
110
|
+
return 'st7796s';
|
|
111
|
+
// E-ink families (drop-in compatibles): the driver symbol the Kconfig
|
|
112
|
+
// layer enables under the mipi-dbi SPI branch.
|
|
113
|
+
if (profile.driver.startsWith('solomon,ssd16'))
|
|
114
|
+
return 'ssd16xx';
|
|
115
|
+
if (profile.driver.startsWith('ultrachip,uc81'))
|
|
116
|
+
return 'uc81xx';
|
|
117
|
+
return undefined;
|
|
118
|
+
}
|
|
119
|
+
/** A DT compatible string (vendor,name) — the drop-in driver id shape. */
|
|
120
|
+
export function isDtCompatible(driver) {
|
|
121
|
+
return /^[a-z0-9]+(-[a-z0-9]+)*,[a-z0-9-]+$/i.test(driver);
|
|
122
|
+
}
|
|
123
|
+
/** 1bpp mono panel compatibles (DATA, not code): the Zephyr drivers behind
|
|
124
|
+
* these report PIXEL_FORMAT_MONO01/10 — the Stage 2 full-frame lowering
|
|
125
|
+
* target. A drop-in config naming one of these synthesizes a mono profile
|
|
126
|
+
* without an explicit colorFormat. Grows as mono drivers are verified; an
|
|
127
|
+
* unlisted mono panel still works via display.init({ colorFormat: 'mono' }).
|
|
128
|
+
* (ssd1320/ssd1327-class are L8/grayscale — Stage 3, not here.) */
|
|
129
|
+
const MONO_PANEL_COMPATIBLES = new Set([
|
|
130
|
+
'solomon,ssd1306',
|
|
131
|
+
'solomon,ssd1309',
|
|
132
|
+
'sinowealth,sh1106',
|
|
133
|
+
]);
|
|
134
|
+
/** 16-gray panels (Stage 3): Zephyr's solomon,ssd1327 driver accepts
|
|
135
|
+
* PIXEL_FORMAT_L_8 (8-bit luminance in, nibble-reduced to the panel's 16
|
|
136
|
+
* levels) — the Stage 3 gray8 lowering target. Same drop-in rule as mono. */
|
|
137
|
+
const GRAY_PANEL_COMPATIBLES = new Set([
|
|
138
|
+
'solomon,ssd1327',
|
|
139
|
+
]);
|
|
140
|
+
/** E-Ink panels (Stage 4): the ssd16xx/uc81xx SPI families — same 1bpp
|
|
141
|
+
* format as mono, the new axis is the REFRESH MODEL (deferred: render on
|
|
142
|
+
* signal change, flush with the panel's flash cycle, panel sleeps). Grows
|
|
143
|
+
* as e-ink drivers are verified. */
|
|
144
|
+
const EINK_PANEL_COMPATIBLES = new Set([
|
|
145
|
+
'solomon,ssd1608',
|
|
146
|
+
'solomon,ssd1673',
|
|
147
|
+
'solomon,ssd1675a',
|
|
148
|
+
'solomon,ssd1680',
|
|
149
|
+
'solomon,ssd1681',
|
|
150
|
+
'ultrachip,uc8151d',
|
|
151
|
+
'ultrachip,uc8175',
|
|
152
|
+
'ultrachip,uc8176',
|
|
153
|
+
'ultrachip,uc8179',
|
|
154
|
+
]);
|
|
155
|
+
/** True when a drop-in compatible (or explicit config) selects the e-ink
|
|
156
|
+
* lowering target — mono format + deferred refresh. */
|
|
157
|
+
export function isEinkDisplay(display) {
|
|
158
|
+
if (display.displayClass === 'eink')
|
|
159
|
+
return true;
|
|
160
|
+
return EINK_PANEL_COMPATIBLES.has(display.driver);
|
|
161
|
+
}
|
|
162
|
+
/** True when a drop-in compatible (or explicit config) selects the gray8
|
|
163
|
+
* (8-bit luminance) lowering target. */
|
|
164
|
+
export function isGrayDisplay(display) {
|
|
165
|
+
if (display.colorFormat === 'gray8')
|
|
166
|
+
return true;
|
|
167
|
+
if (display.colorFormat && display.colorFormat !== 'gray8')
|
|
168
|
+
return false;
|
|
169
|
+
return GRAY_PANEL_COMPATIBLES.has(display.driver);
|
|
170
|
+
}
|
|
171
|
+
/** True when a drop-in compatible (or explicit config) selects the mono
|
|
172
|
+
* (1bpp) lowering target. */
|
|
173
|
+
export function isMonoDisplay(display) {
|
|
174
|
+
if (display.colorFormat === 'mono')
|
|
175
|
+
return true;
|
|
176
|
+
if (display.colorFormat && display.colorFormat !== 'mono')
|
|
177
|
+
return false;
|
|
178
|
+
return MONO_PANEL_COMPATIBLES.has(display.driver);
|
|
179
|
+
}
|
|
180
|
+
/** Synthesize a native-transport profile for a compatible-driven config
|
|
181
|
+
* (display.driver = DT compatible, no registry profile). The in-tree driver
|
|
182
|
+
* bound by the overlay's display node owns init/geometry/quirks; the
|
|
183
|
+
* config's panel-quirk flags (channelSwapRb, csHold) carry what the
|
|
184
|
+
* driver cannot know. Returns undefined unless the driver string is a
|
|
185
|
+
* compatible shape. */
|
|
186
|
+
export function synthesizeZephyrProfile(display) {
|
|
187
|
+
if (!isDtCompatible(display.driver))
|
|
188
|
+
return undefined;
|
|
189
|
+
return {
|
|
190
|
+
driver: display.driver,
|
|
191
|
+
dtLabel: 'display0',
|
|
192
|
+
width: display.width,
|
|
193
|
+
height: display.height,
|
|
194
|
+
nativeWidth: display.nativeWidth,
|
|
195
|
+
nativeHeight: display.nativeHeight,
|
|
196
|
+
// E-ink compatibles are mono-format panels with a deferred refresh
|
|
197
|
+
// model — displayClass drives deriveCapabilities' eink branch (all
|
|
198
|
+
// features off, deferred-partial) and the e-ink adapter dispatch.
|
|
199
|
+
displayClass: isEinkDisplay(display) ? 'eink' : undefined,
|
|
200
|
+
colorFormat: isMonoDisplay(display) || isEinkDisplay(display) ? 'mono' : isGrayDisplay(display) ? 'gray8' : 'rgb565',
|
|
201
|
+
controller: undefined,
|
|
202
|
+
transport: 'zephyr-display',
|
|
203
|
+
dbiHost: display.csHold === true ? 'local-hold-cs' : undefined,
|
|
204
|
+
channelSwapRb: display.channelSwapRb === true ? true : undefined,
|
|
205
|
+
rgbInverted: display.rgbInverted === true ? true : undefined,
|
|
206
|
+
rotation: display.rotation ?? 0,
|
|
207
|
+
backlight: 'backlight',
|
|
208
|
+
};
|
|
23
209
|
}
|
|
24
210
|
/**
|
|
25
211
|
* Built-in profile registry. Looked up by driver id. Add a profile here when a
|
|
@@ -36,6 +222,28 @@ export const ZEPHYR_DISPLAY_PROFILES = {
|
|
|
36
222
|
rotation: 90,
|
|
37
223
|
backlight: 'backlight',
|
|
38
224
|
},
|
|
225
|
+
// Same ILI9341 panel as 'ili9341-zephyr', but driven through Zephyr's
|
|
226
|
+
// display API: the overlay's display0 node (ilitek,ili9341 under the
|
|
227
|
+
// mipi-dbi-spi bridge) binds the in-tree driver with CONFIG_MIPI_DBI_SPI +
|
|
228
|
+
// CONFIG_ILI9341, and the emitted adapter speaks display_write instead of
|
|
229
|
+
// spi_write. The panel init sequence, rotation, and pixel wire format move
|
|
230
|
+
// upstream (the driver owns them). Per-transaction CS (the mipi-dbi-spi
|
|
231
|
+
// bridge's behavior) is fine on standard ILI9341 SPI modules — the
|
|
232
|
+
// CS-held-across-command+data requirement that forces 'direct-spi' is a
|
|
233
|
+
// clone-ST7796S-class quirk. The sibling 'st7796-zephyr-display' profile
|
|
234
|
+
// is hardware-verified end-to-end; this one is compile/link-verified only
|
|
235
|
+
// (no ILI9341 module on the rig yet).
|
|
236
|
+
'ili9341-zephyr-display': {
|
|
237
|
+
driver: 'ili9341-zephyr-display',
|
|
238
|
+
dtLabel: 'display0',
|
|
239
|
+
width: 320,
|
|
240
|
+
height: 240,
|
|
241
|
+
colorFormat: 'rgb565',
|
|
242
|
+
controller: 'ili9341',
|
|
243
|
+
transport: 'zephyr-display',
|
|
244
|
+
rotation: 90,
|
|
245
|
+
backlight: 'backlight',
|
|
246
|
+
},
|
|
39
247
|
'st7796-zephyr': {
|
|
40
248
|
// ST7796S SPI TFT, 320x480 RGB565 mounted landscape (effective 480x320).
|
|
41
249
|
// Same DT nodelabel convention as the ILI9341 — the board's devicetree
|
|
@@ -54,18 +262,73 @@ export const ZEPHYR_DISPLAY_PROFILES = {
|
|
|
54
262
|
backlight: 'backlight',
|
|
55
263
|
},
|
|
56
264
|
'ssd1306-zephyr': {
|
|
57
|
-
// Monochrome OLED (SSD1306-class, 128x64, 1bpp)
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
// on
|
|
61
|
-
//
|
|
265
|
+
// Monochrome OLED (SSD1306-class, 128x64, 1bpp) — Stage 2's mono
|
|
266
|
+
// lowering target. The full-frame adapter (ui-adapter-mono.ts) keeps a
|
|
267
|
+
// vtiled MONO01 backing store and pushes it whole each frame through
|
|
268
|
+
// display_write on the DT display node (the ssd1306 driver over I2C
|
|
269
|
+
// self-builds from the overlay's node). Raw display.* ops ride the same
|
|
270
|
+
// model through gfx.ts's mono branch.
|
|
62
271
|
driver: 'ssd1306-zephyr',
|
|
63
272
|
dtLabel: 'display0',
|
|
273
|
+
dtCompatible: 'solomon,ssd1306',
|
|
64
274
|
width: 128,
|
|
65
275
|
height: 64,
|
|
66
276
|
colorFormat: 'mono',
|
|
67
277
|
rotation: 0,
|
|
68
278
|
},
|
|
279
|
+
// The verified clone ST7796S on the demo rig, on the native display API:
|
|
280
|
+
// the in-tree sitronix,st7796s driver (CONFIG_ST7796S) owns init/gamma/
|
|
281
|
+
// geometry, backed by an app-local CS-holding mipi-dbi host the adapter
|
|
282
|
+
// emits (dbiHost 'local-hold-cs' — the stock bridge deasserts CS between
|
|
283
|
+
// command and data, which scrambles this clone; the local host implements
|
|
284
|
+
// the mipi-hold-cs behavior Zephyr documents but 4.4.2 does not ship).
|
|
285
|
+
// The clone's 16-bit color pipeline is handled at pack time (byte swap
|
|
286
|
+
// via the reported 565X format — see the color notes below); the direct
|
|
287
|
+
// transport avoids the question entirely by driving 18-bit mode.
|
|
288
|
+
// Color pipeline (hardware-verified on the rig, 16-bit mode, three knobs):
|
|
289
|
+
// - rgb-is-inverted: byte-swap at pack time (565 wire order).
|
|
290
|
+
// - NO R/B channel swap (the 18-bit BGR finding does not transfer).
|
|
291
|
+
// - CS-hold (this profile's default local host): REQUIRED on this clone —
|
|
292
|
+
// the stock mipi-dbi-spi bridge toggles CS per transaction and
|
|
293
|
+
// corrupts pixel bursts (confirmed twice: the original bring-up, and
|
|
294
|
+
// the drop-in path's first stock-bridge build showed the same
|
|
295
|
+
// corruption until csHold was set). With all three, colors are
|
|
296
|
+
// hardware-confirmed correct on the rig. Ladder testing observed a
|
|
297
|
+
// slight uniform dimness vs the direct path's 18-bit mode; the direct
|
|
298
|
+
// profile remains the max-fidelity option for this panel.
|
|
299
|
+
// Touch: FT6336U on the input subsystem — its power enable must be driven
|
|
300
|
+
// (resetPin 4 on the rig; see touch-adapter.ts for the rig-verified
|
|
301
|
+
// sequence). Touch + UI interaction hardware-verified on the rig.
|
|
302
|
+
'st7796-zephyr-display': {
|
|
303
|
+
driver: 'st7796-zephyr-display',
|
|
304
|
+
dtLabel: 'display0',
|
|
305
|
+
width: 480,
|
|
306
|
+
height: 320,
|
|
307
|
+
nativeWidth: 320,
|
|
308
|
+
nativeHeight: 480,
|
|
309
|
+
colorFormat: 'rgb565',
|
|
310
|
+
controller: 'st7796s',
|
|
311
|
+
transport: 'zephyr-display',
|
|
312
|
+
rotation: 1,
|
|
313
|
+
backlight: 'backlight',
|
|
314
|
+
},
|
|
315
|
+
// Stage 2g — the no-hardware gate: the whole mono lowering on native_sim's
|
|
316
|
+
// built-in SDL panel (zephyr,sdl-dc, 320x240). The board's devicetree
|
|
317
|
+
// already wires sdl_dc, so the overlay emits no display node; the SDL
|
|
318
|
+
// panel's pixel-format choice flips to MONO01 so the 1bpp adapter's
|
|
319
|
+
// display_write flows render as black/white in the emulator window.
|
|
320
|
+
// Compile+link only in CI (Linux — the POSIX arch does not build on
|
|
321
|
+
// Windows); the SDL window needs libsdl2-dev on the runner to link.
|
|
322
|
+
'native-sim-mono': {
|
|
323
|
+
driver: 'native-sim-mono',
|
|
324
|
+
dtLabel: 'sdl_dc',
|
|
325
|
+
width: 320,
|
|
326
|
+
height: 240,
|
|
327
|
+
colorFormat: 'mono',
|
|
328
|
+
transport: 'zephyr-display',
|
|
329
|
+
boardProvidesDisplay: true,
|
|
330
|
+
kconfig: ['CONFIG_SDL_DISPLAY_DEFAULT_PIXEL_FORMAT_MONO01=y'],
|
|
331
|
+
},
|
|
69
332
|
};
|
|
70
333
|
/** The default profile used when resolveDisplayOp is probed without a display.init. */
|
|
71
334
|
export const DEFAULT_ZEPHYR_DISPLAY_PROFILE = ZEPHYR_DISPLAY_PROFILES['ili9341-zephyr'];
|