@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
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/** A required property as harvested from a binding. */
|
|
2
|
+
export interface RequiredProp {
|
|
3
|
+
/** Binding type string (e.g. 'int', 'uint8-array', 'boolean'). */
|
|
4
|
+
type?: string;
|
|
5
|
+
/** The binding's default, when it ships one (some props are deliberately
|
|
6
|
+
* default-free — "panel specific" per the sitronix gamma bindings). */
|
|
7
|
+
default?: BindingDefault;
|
|
8
|
+
}
|
|
9
|
+
/** A harvested display binding: what the overlay generator needs. */
|
|
10
|
+
export interface DisplayBindingInfo {
|
|
11
|
+
/** The compatible string this binding documents. */
|
|
12
|
+
compatible: string;
|
|
13
|
+
/** Transport family from the include chain — decides the overlay node
|
|
14
|
+
* shape (I2C child vs mipi-dbi SPI child) and the Kconfig bus. */
|
|
15
|
+
busFamily: 'i2c' | 'spi';
|
|
16
|
+
/** Required properties (DT name → binding facts). */
|
|
17
|
+
required: Map<string, RequiredProp>;
|
|
18
|
+
/** Every property name the binding (or its include chain) declares,
|
|
19
|
+
* optional ones included — rotation-style props (madctl) are optional
|
|
20
|
+
* with neutral defaults, but the drop-in path expresses config rotation
|
|
21
|
+
* through them, so their presence matters. */
|
|
22
|
+
props: Set<string>;
|
|
23
|
+
/** True when the include chain pulls in lcd-controller.yaml — that family
|
|
24
|
+
* makes `pixel-format` required (0 = RGB565 per dt-bindings/display/panel.h). */
|
|
25
|
+
requiresPixelFormat: boolean;
|
|
26
|
+
}
|
|
27
|
+
/** A parsed binding default: scalar or byte-array. */
|
|
28
|
+
export type BindingDefault = {
|
|
29
|
+
kind: 'int';
|
|
30
|
+
value: number;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'bool';
|
|
33
|
+
value: boolean;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'string';
|
|
36
|
+
value: string;
|
|
37
|
+
} | {
|
|
38
|
+
kind: 'bytes';
|
|
39
|
+
value: number[];
|
|
40
|
+
};
|
|
41
|
+
/** @internal Replace the Zephyr tree root (tests only). */
|
|
42
|
+
export declare function __setDisplayBindingRootOverride(root: string | undefined): void;
|
|
43
|
+
/** Locate the Zephyr tree via the board catalog's canonical discovery
|
|
44
|
+
* ($ZEPHYR_BASE → well-known workspaces → installer env-vars). Cached. */
|
|
45
|
+
export declare function findZephyrBase(): string | undefined;
|
|
46
|
+
/** Harvest a display binding by compatible string. Walks the include chain
|
|
47
|
+
* (child requirements win; the lcd-controller family is detected anywhere
|
|
48
|
+
* in the chain). Returns undefined for unknown compatibles or when no
|
|
49
|
+
* Zephyr tree is discoverable. */
|
|
50
|
+
export declare function readDisplayBinding(compatible: string): DisplayBindingInfo | undefined;
|
|
51
|
+
/** @internal Same harvest against an explicit root (tests). */
|
|
52
|
+
export declare function readDisplayBindingFrom(compatible: string, root: string): DisplayBindingInfo | undefined;
|
|
53
|
+
/** All display-panel compatibles with bindings in the tree (for mount
|
|
54
|
+
* validation: ui.mount accepts any of these driver strings). */
|
|
55
|
+
export declare function listBoundDisplayCompatibles(): string[];
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Display binding harvest — the Zephyr tree IS the panel catalog.
|
|
3
|
+
//
|
|
4
|
+
// Drop-in display support ("no special profiles"): a project declares a DT
|
|
5
|
+
// compatible string (display.driver, e.g. 'sitronix,st7796s') plus wiring and
|
|
6
|
+
// geometry; everything the devicetree overlay needs to emit a VALID node for
|
|
7
|
+
// that panel comes from the binding YAMLs in the user's Zephyr checkout —
|
|
8
|
+
// required properties, their defaults, and the include chain (e.g. whether
|
|
9
|
+
// the lcd-controller family makes pixel-format mandatory). Same doctrine as
|
|
10
|
+
// the board catalog: the installed SDK is the source of truth; no curated
|
|
11
|
+
// per-panel database in this package.
|
|
12
|
+
//
|
|
13
|
+
// The parser is deliberately a shape-reader, not a YAML implementation: it
|
|
14
|
+
// extracts `compatible:`, `include:` lists, and per-property `required:`/
|
|
15
|
+
// `default:` scalars from Zephyr's binding grammar (2-space nesting, inline
|
|
16
|
+
// flow arrays). Anything else is ignored — bindings carry descriptions and
|
|
17
|
+
// constraints this consumer does not need.
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
import { readFileSync, readdirSync, statSync } from 'node:fs';
|
|
20
|
+
import { join } from 'node:path';
|
|
21
|
+
import { locateZephyrBaseCheap } from '@typecad/cuttlefish/board-catalog';
|
|
22
|
+
/** Test seam: override the Zephyr root for hermetic fixtures. */
|
|
23
|
+
let rootOverride;
|
|
24
|
+
/** @internal Replace the Zephyr tree root (tests only). */
|
|
25
|
+
export function __setDisplayBindingRootOverride(root) {
|
|
26
|
+
rootOverride = root;
|
|
27
|
+
yamlIndex = undefined;
|
|
28
|
+
}
|
|
29
|
+
let cachedBase;
|
|
30
|
+
let yamlIndex;
|
|
31
|
+
/** Locate the Zephyr tree via the board catalog's canonical discovery
|
|
32
|
+
* ($ZEPHYR_BASE → well-known workspaces → installer env-vars). Cached. */
|
|
33
|
+
export function findZephyrBase() {
|
|
34
|
+
if (rootOverride)
|
|
35
|
+
return rootOverride;
|
|
36
|
+
if (cachedBase !== undefined)
|
|
37
|
+
return cachedBase;
|
|
38
|
+
cachedBase = locateZephyrBaseCheap() ?? undefined;
|
|
39
|
+
return cachedBase;
|
|
40
|
+
}
|
|
41
|
+
/** Index every binding YAML under dts/bindings by filename (bindings include
|
|
42
|
+
* each other by bare filename across subdirectories — e.g. a display
|
|
43
|
+
* binding includes i2c-device.yaml, which lives in bindings/i2c/). */
|
|
44
|
+
function bindingIndex(root) {
|
|
45
|
+
if (yamlIndex)
|
|
46
|
+
return yamlIndex;
|
|
47
|
+
const index = new Map();
|
|
48
|
+
const walk = (dir) => {
|
|
49
|
+
for (const entry of readdirSync(dir)) {
|
|
50
|
+
const full = join(dir, entry);
|
|
51
|
+
const st = statSync(full);
|
|
52
|
+
if (st.isDirectory())
|
|
53
|
+
walk(full);
|
|
54
|
+
else if (entry.endsWith('.yaml') || entry.endsWith('.yml'))
|
|
55
|
+
index.set(entry, full);
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
walk(join(root, 'dts', 'bindings'));
|
|
59
|
+
yamlIndex = index;
|
|
60
|
+
return index;
|
|
61
|
+
}
|
|
62
|
+
/** Parse one binding file's shape: compatible, includes, required props. */
|
|
63
|
+
function parseBinding(path) {
|
|
64
|
+
const text = readFileSync(path, 'utf8');
|
|
65
|
+
const includes = [];
|
|
66
|
+
const required = new Map();
|
|
67
|
+
const props = new Set();
|
|
68
|
+
let compatible;
|
|
69
|
+
let section = 'none';
|
|
70
|
+
let currentProp;
|
|
71
|
+
let currentDefault;
|
|
72
|
+
let currentType;
|
|
73
|
+
const commitProp = () => {
|
|
74
|
+
if (currentProp !== undefined && propIsRequired) {
|
|
75
|
+
const prev = required.get(currentProp);
|
|
76
|
+
required.set(currentProp, {
|
|
77
|
+
type: currentType ?? prev?.type,
|
|
78
|
+
default: finalizeDefault(currentDefault, defaultItems) ?? prev?.default,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
currentProp = undefined;
|
|
82
|
+
currentDefault = undefined;
|
|
83
|
+
currentType = undefined;
|
|
84
|
+
defaultItems = null;
|
|
85
|
+
propIsRequired = false;
|
|
86
|
+
};
|
|
87
|
+
let propIsRequired = false;
|
|
88
|
+
let defaultItems = null;
|
|
89
|
+
for (const rawLine of text.split(/\r?\n/)) {
|
|
90
|
+
if (!rawLine.trim() || rawLine.trimStart().startsWith('#'))
|
|
91
|
+
continue;
|
|
92
|
+
const indent = rawLine.length - rawLine.trimStart().length;
|
|
93
|
+
const line = rawLine.trim();
|
|
94
|
+
// Block-style default list (default: followed by '- item' lines) —
|
|
95
|
+
// common for long byte arrays the real bindings ship multi-line.
|
|
96
|
+
if (defaultItems !== null) {
|
|
97
|
+
if (indent > 4 && line.startsWith('- ')) {
|
|
98
|
+
defaultItems.push(line.slice(2).trim());
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
// Dedent ends the list; fall through to normal handling of this line.
|
|
102
|
+
const items = defaultItems;
|
|
103
|
+
defaultItems = null;
|
|
104
|
+
currentDefault = itemsToDefault(items);
|
|
105
|
+
}
|
|
106
|
+
if (indent === 0) {
|
|
107
|
+
commitProp();
|
|
108
|
+
const key = line.split(':')[0].trim();
|
|
109
|
+
if (key === 'include') {
|
|
110
|
+
section = 'include';
|
|
111
|
+
collectIncludes(line.slice(line.indexOf(':') + 1), includes);
|
|
112
|
+
}
|
|
113
|
+
else if (key === 'properties') {
|
|
114
|
+
section = 'properties';
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
section = 'none';
|
|
118
|
+
if (key === 'compatible') {
|
|
119
|
+
const v = scalarString(line.slice(line.indexOf(':') + 1));
|
|
120
|
+
if (v !== undefined)
|
|
121
|
+
compatible = v;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
if (section === 'include' && indent === 2 && line.startsWith('- ')) {
|
|
127
|
+
collectIncludes(line.slice(2), includes);
|
|
128
|
+
}
|
|
129
|
+
else if (section === 'properties' && indent === 2) {
|
|
130
|
+
commitProp();
|
|
131
|
+
currentProp = line.split(':')[0].trim();
|
|
132
|
+
if (currentProp)
|
|
133
|
+
props.add(currentProp);
|
|
134
|
+
}
|
|
135
|
+
else if (section === 'properties' && indent === 4 && currentProp) {
|
|
136
|
+
const key = line.split(':')[0].trim();
|
|
137
|
+
const rest = line.slice(line.indexOf(':') + 1).trim();
|
|
138
|
+
if (key === 'required' && rest === 'true') {
|
|
139
|
+
propIsRequired = true;
|
|
140
|
+
}
|
|
141
|
+
else if (key === 'type') {
|
|
142
|
+
currentType = rest.replace(/["']/g, '') || undefined;
|
|
143
|
+
}
|
|
144
|
+
else if (key === 'default') {
|
|
145
|
+
if (rest === '') {
|
|
146
|
+
defaultItems = []; // block list follows
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
currentDefault = parseDefault(rest);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
commitProp();
|
|
155
|
+
return { compatible, includes, required, props };
|
|
156
|
+
}
|
|
157
|
+
function finalizeDefault(inline, items) {
|
|
158
|
+
if (items !== null && items.length > 0)
|
|
159
|
+
return itemsToDefault(items);
|
|
160
|
+
return inline ?? (items !== null ? { kind: 'bytes', value: [] } : undefined);
|
|
161
|
+
}
|
|
162
|
+
function itemsToDefault(items) {
|
|
163
|
+
if (items.length === 1)
|
|
164
|
+
return parseDefault(items[0]);
|
|
165
|
+
const bytes = items
|
|
166
|
+
.map((t) => {
|
|
167
|
+
const c = t.replace(/["']/g, '');
|
|
168
|
+
return c.toLowerCase().startsWith('0x') ? parseInt(c.slice(2), 16) : parseInt(c, 10);
|
|
169
|
+
})
|
|
170
|
+
.filter((n) => !Number.isNaN(n));
|
|
171
|
+
return { kind: 'bytes', value: bytes };
|
|
172
|
+
}
|
|
173
|
+
function collectIncludes(fragment, out) {
|
|
174
|
+
const f = fragment.trim();
|
|
175
|
+
if (!f)
|
|
176
|
+
return;
|
|
177
|
+
if (f.startsWith('[')) {
|
|
178
|
+
// Extract filename tokens by pattern (commas INCLUDED — binding
|
|
179
|
+
// filenames are vendor,panel.yaml and cannot be split or excluded on commas) — NEVER split on commas: binding
|
|
180
|
+
// filenames themselves contain commas (vendor,panel.yaml), and a comma
|
|
181
|
+
// split silently mangles them into nonexistent includes.
|
|
182
|
+
for (const m of f.matchAll(/[A-Za-z0-9_.,-]+\.ya?ml/g))
|
|
183
|
+
out.push(m[0]);
|
|
184
|
+
}
|
|
185
|
+
else if (f.startsWith('- ')) {
|
|
186
|
+
pushInclude(f.slice(2).trim(), out);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
pushInclude(f, out);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
function pushInclude(item, out) {
|
|
193
|
+
// The `- name: foo.yaml` include form (with optional property-blocklist).
|
|
194
|
+
// The match is ANCHORED: an unanchored /name:/ can false-match inside
|
|
195
|
+
// filenames (e.g. vendor,panel-common.yaml) and silently mangle the
|
|
196
|
+
// include chain — the missing-prop class this harvest exists to prevent.
|
|
197
|
+
let name = item.trim().replace(/["']/g, '');
|
|
198
|
+
const m = name.match(/^name:\s*(\S+)$/);
|
|
199
|
+
if (m)
|
|
200
|
+
name = m[1];
|
|
201
|
+
if (name.endsWith('.yaml') || name.endsWith('.yml'))
|
|
202
|
+
out.push(name);
|
|
203
|
+
}
|
|
204
|
+
function scalarString(fragment) {
|
|
205
|
+
const f = fragment.trim().replace(/["']/g, '');
|
|
206
|
+
return f || undefined;
|
|
207
|
+
}
|
|
208
|
+
function parseDefault(rest) {
|
|
209
|
+
const f = rest.trim();
|
|
210
|
+
if (f === 'true' || f === 'false')
|
|
211
|
+
return { kind: 'bool', value: f === 'true' };
|
|
212
|
+
if (f.startsWith('[')) {
|
|
213
|
+
const bytes = f
|
|
214
|
+
.slice(1, f.endsWith(']') ? -1 : undefined)
|
|
215
|
+
.split(',')
|
|
216
|
+
.map((s) => {
|
|
217
|
+
const t = s.trim().replace(/["']/g, '');
|
|
218
|
+
return t.toLowerCase().startsWith('0x')
|
|
219
|
+
? parseInt(t.slice(2), 16)
|
|
220
|
+
: parseInt(t, 10);
|
|
221
|
+
})
|
|
222
|
+
.filter((n) => !Number.isNaN(n));
|
|
223
|
+
return { kind: 'bytes', value: bytes };
|
|
224
|
+
}
|
|
225
|
+
if (/^-?\d+$/.test(f))
|
|
226
|
+
return { kind: 'int', value: parseInt(f, 10) };
|
|
227
|
+
return { kind: 'string', value: f.replace(/["']/g, '') };
|
|
228
|
+
}
|
|
229
|
+
/** Harvest a display binding by compatible string. Walks the include chain
|
|
230
|
+
* (child requirements win; the lcd-controller family is detected anywhere
|
|
231
|
+
* in the chain). Returns undefined for unknown compatibles or when no
|
|
232
|
+
* Zephyr tree is discoverable. */
|
|
233
|
+
export function readDisplayBinding(compatible) {
|
|
234
|
+
const root = findZephyrBase();
|
|
235
|
+
if (!root)
|
|
236
|
+
return undefined;
|
|
237
|
+
return readDisplayBindingFrom(compatible, root);
|
|
238
|
+
}
|
|
239
|
+
/** @internal Same harvest against an explicit root (tests). */
|
|
240
|
+
export function readDisplayBindingFrom(compatible, root) {
|
|
241
|
+
const index = bindingIndex(root);
|
|
242
|
+
const visited = new Set();
|
|
243
|
+
const required = new Map();
|
|
244
|
+
const props = new Set();
|
|
245
|
+
let requiresPixelFormat = false;
|
|
246
|
+
let busFamily = 'spi';
|
|
247
|
+
const noteFamily = (fileName) => {
|
|
248
|
+
if (fileName === 'i2c-device.yaml')
|
|
249
|
+
busFamily = 'i2c';
|
|
250
|
+
if (fileName === 'mipi-dbi-spi-device.yaml' || fileName === 'spi-device.yaml')
|
|
251
|
+
busFamily = 'spi';
|
|
252
|
+
};
|
|
253
|
+
const load = (fileName) => {
|
|
254
|
+
const path = index.get(fileName);
|
|
255
|
+
if (!path || visited.has(fileName))
|
|
256
|
+
return;
|
|
257
|
+
visited.add(fileName);
|
|
258
|
+
const raw = parseBinding(path);
|
|
259
|
+
noteFamily(fileName);
|
|
260
|
+
if (fileName === 'lcd-controller.yaml')
|
|
261
|
+
requiresPixelFormat = true;
|
|
262
|
+
for (const [prop, info] of raw.required) {
|
|
263
|
+
const prev = required.get(prop);
|
|
264
|
+
required.set(prop, {
|
|
265
|
+
type: info.type ?? prev?.type,
|
|
266
|
+
default: info.default ?? prev?.default,
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
for (const inc of raw.includes)
|
|
270
|
+
load(inc);
|
|
271
|
+
};
|
|
272
|
+
const noteProps = (fileName) => {
|
|
273
|
+
const path = index.get(fileName);
|
|
274
|
+
if (!path)
|
|
275
|
+
return;
|
|
276
|
+
const raw = parseBinding(path);
|
|
277
|
+
for (const p of raw.props)
|
|
278
|
+
props.add(p);
|
|
279
|
+
for (const inc of raw.includes)
|
|
280
|
+
noteProps(inc);
|
|
281
|
+
};
|
|
282
|
+
// Find the binding whose declared compatible matches.
|
|
283
|
+
for (const [fileName, path] of index) {
|
|
284
|
+
if (!fileName.includes(','))
|
|
285
|
+
continue; // compatibles are vendor,name.yaml
|
|
286
|
+
const raw = parseBinding(path);
|
|
287
|
+
if (raw.compatible === compatible) {
|
|
288
|
+
load(fileName);
|
|
289
|
+
noteProps(fileName);
|
|
290
|
+
return { compatible, required, requiresPixelFormat, props, busFamily };
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
/** All display-panel compatibles with bindings in the tree (for mount
|
|
296
|
+
* validation: ui.mount accepts any of these driver strings). */
|
|
297
|
+
export function listBoundDisplayCompatibles() {
|
|
298
|
+
const root = findZephyrBase();
|
|
299
|
+
if (!root)
|
|
300
|
+
return [];
|
|
301
|
+
const index = bindingIndex(root);
|
|
302
|
+
const out = [];
|
|
303
|
+
for (const [fileName, path] of index) {
|
|
304
|
+
if (!fileName.includes(','))
|
|
305
|
+
continue; // compatibles are vendor,name.yaml
|
|
306
|
+
// Panel bindings live under dts/bindings/display/ — match the path
|
|
307
|
+
// segment, not the filename (compatibles don't contain "display").
|
|
308
|
+
const normalized = path.replace(/\\/g, '/');
|
|
309
|
+
if (!/\/bindings\/display\//.test(normalized))
|
|
310
|
+
continue;
|
|
311
|
+
const raw = parseBinding(path);
|
|
312
|
+
if (raw.compatible)
|
|
313
|
+
out.push(raw.compatible);
|
|
314
|
+
}
|
|
315
|
+
return out.sort();
|
|
316
|
+
}
|
package/dist/display/gfx.d.ts
CHANGED
|
@@ -19,8 +19,7 @@ export interface DisplayRuntimeResult {
|
|
|
19
19
|
* - `'mono'` (OLED, e.g. SSD1306): a full framebuffer — the standard model
|
|
20
20
|
* for page-buffered monochrome panels (the AGENTS.md "no full framebuffer"
|
|
21
21
|
* guardrail targets RGB SPI TFTs, not mono OLEDs). draw ops set bits;
|
|
22
|
-
* display_flush pushes the whole framebuffer
|
|
23
|
-
*
|
|
24
|
-
* bit = 0x80>>(x&7).
|
|
22
|
+
* display_flush pushes the whole framebuffer as VTILED MONO01 (the layout
|
|
23
|
+
* the driver consumes; see monoHelpers).
|
|
25
24
|
*/
|
|
26
25
|
export declare function buildDisplayRuntime(profile: ZephyrDisplayProfile): DisplayRuntimeResult;
|