@typecad/cuttlefish 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.
- package/README.md +82 -79
- package/assets/editor-extensions/typecad-debug/README.md +141 -0
- package/assets/editor-extensions/typecad-debug/out/extension.js +347 -0
- package/assets/editor-extensions/typecad-debug/out/extension.js.map +1 -0
- package/assets/editor-extensions/typecad-debug/package.json +76 -0
- package/assets/editor-extensions/typecad-ui/LICENSE +27 -0
- package/assets/editor-extensions/typecad-ui/README.md +52 -0
- package/assets/editor-extensions/typecad-ui/file-icon-dark.png +0 -0
- package/assets/editor-extensions/typecad-ui/file-icon-light.png +0 -0
- package/assets/editor-extensions/typecad-ui/icon.png +0 -0
- package/assets/editor-extensions/typecad-ui/language-configuration.json +43 -0
- package/assets/editor-extensions/typecad-ui/package.json +54 -0
- package/assets/editor-extensions/typecad-ui/snippets/typecad-ui.json +80 -0
- package/assets/editor-extensions/typecad-ui/syntaxes/markdown-ui.json +45 -0
- package/assets/editor-extensions/typecad-ui/syntaxes/typecad-ui.tmLanguage.json +1269 -0
- package/dist/api/config.d.ts +30 -27
- package/dist/api/schema/types.d.ts +20 -3
- package/dist/api/shared/async-runtime-static.d.ts +1 -1
- package/dist/api/shared/async-runtime-static.js +5 -5
- package/dist/api/shared/async-types.d.ts +3 -2
- package/dist/api/shared/board-catalog.d.ts +2 -0
- package/dist/api/shared/board-catalog.js +6 -0
- package/dist/api/shared/board-resolver.d.ts +4 -7
- package/dist/api/shared/board-resolver.js +2 -1
- package/dist/api/shared/coop-scheduler.d.ts +1 -1
- package/dist/api/shared/coop-scheduler.js +1 -1
- package/dist/api/shared/cpp-type-ir.d.ts +1 -1
- package/dist/api/shared/cpp-type-ir.js +1 -1
- package/dist/api/shared/display-profile.d.ts +1 -1
- package/dist/api/shared/display-profile.js +3 -5
- package/dist/api/shared/framework-manifest-registry.d.ts +1 -1
- package/dist/api/shared/framework-manifest-registry.js +0 -1
- package/dist/api/shared/framework-manifest.d.ts +65 -507
- package/dist/api/shared/framework-manifest.js +6 -11
- package/dist/api/shared/hal-op-ir.d.ts +294 -685
- package/dist/api/shared/hal-op-ir.js +31 -65
- package/dist/api/shared/index.d.ts +0 -4
- package/dist/api/shared/index.js +1 -7
- package/dist/api/shared/ir-core.d.ts +6 -0
- package/dist/api/shared/ir-declarations.d.ts +4 -0
- package/dist/api/shared/ir.d.ts +1 -3
- package/dist/api/shared/platform-strategy.d.ts +14 -37
- package/dist/api/shared/polyfill-helper-registry.js +0 -5
- package/dist/api/shared/polyfill-types.js +0 -27
- package/dist/api/shared/promise-runtime.js +3 -3
- package/dist/api/shared/spdx-licenses.d.ts +12 -10
- package/dist/api/shared/spdx-licenses.js +1 -1
- package/dist/api/shared/toolchain-types.d.ts +1 -1
- package/dist/api/shared/toolchain-types.js +3 -3
- package/dist/api/shared/types.d.ts +0 -3
- package/dist/api/shared/validate-framework-manifest.js +13 -33
- package/dist/board-catalog/dts-reader.d.ts +220 -0
- package/dist/board-catalog/dts-reader.js +1052 -0
- package/dist/board-catalog/index.d.ts +11 -0
- package/dist/board-catalog/index.js +12 -0
- package/dist/board-catalog/pinconfig.d.ts +48 -0
- package/dist/board-catalog/pinconfig.js +263 -0
- package/dist/board-catalog/sdk.d.ts +82 -0
- package/dist/board-catalog/sdk.js +180 -0
- package/dist/board-catalog/store.d.ts +196 -0
- package/dist/board-catalog/store.js +363 -0
- package/dist/board-catalog/types.d.ts +233 -0
- package/dist/board-catalog/types.js +7 -0
- package/dist/board-catalog/walker.d.ts +112 -0
- package/dist/board-catalog/walker.js +1101 -0
- package/dist/cli-utils.d.ts +2 -2
- package/dist/cli-utils.js +5 -5
- package/dist/cli.js +227 -244
- package/dist/config-loader.d.ts +14 -19
- package/dist/config-loader.js +242 -78
- package/dist/config-schema.d.ts +19 -227
- package/dist/config-schema.js +9 -8
- package/dist/contract/board-generator.d.ts +4 -4
- package/dist/contract/board-generator.js +16 -5
- package/dist/contract/contract-parser.d.ts +36 -127
- package/dist/contract/contract-parser.js +76 -0
- package/dist/contract/index.d.ts +1 -1
- package/dist/contract/index.js +70 -21
- package/dist/create/active-board-catalog.d.ts +9 -0
- package/dist/create/active-board-catalog.js +94 -0
- package/dist/create/board-catalog.generated.d.ts +96 -0
- package/dist/create/board-catalog.generated.js +128737 -0
- package/dist/create/board-search.d.ts +23 -0
- package/dist/create/board-search.js +88 -0
- package/dist/create/editor-integration.d.ts +32 -0
- package/dist/create/editor-integration.js +257 -0
- package/dist/create/eslint-rules-template.d.ts +2 -2
- package/dist/create/framework-catalog.d.ts +48 -8
- package/dist/create/framework-catalog.js +58 -44
- package/dist/create/index.d.ts +8 -13
- package/dist/create/index.js +5 -9
- package/dist/create/mcu-target.d.ts +39 -0
- package/dist/create/mcu-target.js +80 -0
- package/dist/create/pack-targets.d.ts +19 -0
- package/dist/create/pack-targets.js +56 -0
- package/dist/create/{init-scaffold.d.ts → scaffold.d.ts} +8 -11
- package/dist/create/{init-scaffold.js → scaffold.js} +28 -87
- package/dist/create/templates.d.ts +51 -0
- package/dist/create/{init-templates.js → templates.js} +135 -116
- package/dist/create/wizard.d.ts +19 -0
- package/dist/create/wizard.js +314 -0
- package/dist/debug/preprocessor.d.ts +5 -0
- package/dist/debug/preprocessor.js +31 -7
- package/dist/diagnostics/diagnostics-report.d.ts +1 -1
- package/dist/diagnostics/diagnostics-report.js +3 -11
- package/dist/diagnostics/json-schema.d.ts +1 -1
- package/dist/diagnostics/md-writer.js +2 -2
- package/dist/diagnostics/mermaid-builder.d.ts +1 -1
- package/dist/diagnostics/mermaid-builder.js +1 -1
- package/dist/emit/cpp-emitter.js +4 -1
- package/dist/emit/emitters/class-emitter.js +32 -4
- package/dist/emit/emitters/emitter-context.d.ts +11 -0
- package/dist/emit/emitters/entrypoint-synthesizer.js +1 -1
- package/dist/emit/emitters/function-emitter-impl.js +33 -17
- package/dist/emit/emitters/output-finalizer.d.ts +7 -0
- package/dist/emit/emitters/output-finalizer.js +31 -23
- package/dist/emit/emitters/setup.js +147 -63
- package/dist/emit/emitters/top-level-prep.js +1 -1
- package/dist/emit/emitters/type-decl-emitter.js +13 -8
- package/dist/emit/emitters/ui-emitter.js +1 -1
- package/dist/emit/expression-renderer.d.ts +3 -3
- package/dist/emit/expression-renderer.js +17 -7
- package/dist/emit/route-hal-op.js +17 -48
- package/dist/emit/snprintf-helpers.d.ts +1 -3
- package/dist/emit/snprintf-helpers.js +1 -39
- package/dist/emit/statement-renderer.d.ts +0 -4
- package/dist/emit/statement-renderer.js +54 -45
- package/dist/emit/utils/async-state-machine.d.ts +16 -9
- package/dist/emit/utils/async-state-machine.js +56 -54
- package/dist/emit/utils/comment-helpers.d.ts +0 -8
- package/dist/emit/utils/comment-helpers.js +1 -1
- package/dist/emit/utils/cpp-helpers.d.ts +2 -2
- package/dist/emit/utils/cpp-helpers.js +2 -2
- package/dist/emit/utils/hal-op-cpp-type.js +4 -6
- package/dist/emit/utils/index.d.ts +3 -3
- package/dist/emit/utils/index.js +3 -3
- package/dist/emit/utils/type-inference.d.ts +1 -29
- package/dist/emit/utils/type-inference.js +0 -75
- package/dist/framework-package.d.ts +3 -0
- package/dist/framework-package.js +23 -6
- package/dist/framework-registry.d.ts +5 -5
- package/dist/frameworks/native/graphics/terminal-preview.d.ts +5 -0
- package/dist/frameworks/native/graphics/terminal-preview.js +33 -0
- package/dist/frameworks/native/index.d.ts +3 -0
- package/dist/frameworks/native/index.js +15 -0
- package/dist/frameworks/native/native-compile.d.ts +17 -0
- package/dist/frameworks/native/native-compile.js +170 -0
- package/dist/frameworks/native/native-config.d.ts +41 -0
- package/dist/frameworks/native/native-config.js +7 -0
- package/dist/frameworks/native/strategy.d.ts +97 -0
- package/dist/frameworks/native/strategy.js +664 -0
- package/dist/ir/board-resolver.d.ts +18 -23
- package/dist/ir/board-resolver.js +43 -401
- package/dist/ir/build-ir-state.d.ts +3 -0
- package/dist/ir/build-ir-state.js +42 -0
- package/dist/ir/build-ir.d.ts +1 -1
- package/dist/ir/build-ir.js +64 -45
- package/dist/ir/declaration-builders.js +1 -0
- package/dist/ir/expression-to-ir.js +17 -10
- package/dist/ir/hal/hal-emitter.d.ts +0 -2
- package/dist/ir/hal/hal-emitter.js +92 -41
- package/dist/ir/hal/hal-parser.d.ts +5 -5
- package/dist/ir/hal/hal-parser.js +128 -36
- package/dist/ir/hal/hal-plugins.d.ts +0 -1
- package/dist/ir/hal/hal-plugins.js +425 -716
- package/dist/ir/heap-analysis.js +2 -41
- package/dist/ir/identifier-collector.js +32 -20
- package/dist/ir/network-validation.js +7 -11
- package/dist/ir/ownership-analysis.js +75 -13
- package/dist/ir/peripheral-usage.d.ts +8 -2
- package/dist/ir/peripheral-usage.js +78 -149
- package/dist/ir/peripheral-validation.js +23 -3
- package/dist/ir/pin-capability-validation.d.ts +12 -0
- package/dist/ir/pin-capability-validation.js +61 -97
- package/dist/ir/pin-mode-validation.js +5 -5
- package/dist/ir/program-analysis.d.ts +8 -15
- package/dist/ir/program-analysis.js +140 -323
- package/dist/ir/pulldown-validation.js +11 -4
- package/dist/ir/resource-analysis.js +15 -3
- package/dist/ir/statement-to-ir.js +0 -6
- package/dist/ir/timing-validation.js +1 -1
- package/dist/ir/transformers/array-methods.js +11 -5
- package/dist/ir/transformers/call-statement.js +20 -87
- package/dist/ir/transformers/callback-context-registry.d.ts +1 -1
- package/dist/ir/transformers/callback-context-registry.js +8 -16
- package/dist/ir/transformers/control-flow.js +0 -13
- package/dist/ir/transformers/expressions.js +10 -9
- package/dist/ir/transformers/hal-call-resolver.d.ts +2 -2
- package/dist/ir/transformers/hal-call-resolver.js +24 -10
- package/dist/ir/transformers/hal-emit-helpers.d.ts +2 -2
- package/dist/ir/transformers/hal-emit-helpers.js +2 -2
- package/dist/ir/transformers/namespace-methods.js +1 -1
- package/dist/ir/transformers/ui-callback-lowering.d.ts +0 -2
- package/dist/ir/transformers/ui-callback-lowering.js +0 -24
- package/dist/ir/transformers/variables.js +338 -42
- package/dist/ir/try-catch-validation.js +4 -3
- package/dist/ir/type-resolution.js +15 -4
- package/dist/ir/validation-orchestrator.js +0 -9
- package/dist/libdef/cpp-to-decl.d.ts +0 -9
- package/dist/libdef/cpp-to-decl.js +0 -72
- package/dist/libdef/registry.d.ts +0 -1
- package/dist/libdef/registry.js +1 -24
- package/dist/library/catalog.d.ts +35 -0
- package/dist/library/catalog.js +67 -0
- package/dist/library/cli.d.ts +2 -0
- package/dist/library/cli.js +168 -0
- package/dist/library/init.d.ts +25 -0
- package/dist/library/init.js +397 -0
- package/dist/library/install.d.ts +9 -0
- package/dist/library/install.js +80 -0
- package/dist/library/registry-search.d.ts +34 -0
- package/dist/library/registry-search.js +50 -0
- package/dist/library/validate.d.ts +17 -0
- package/dist/library/validate.js +175 -0
- package/dist/library-packages.d.ts +95 -0
- package/dist/library-packages.js +275 -0
- package/dist/mapping/peripheral-names.js +9 -4
- package/dist/mapping/source-map.d.ts +3 -4
- package/dist/mapping/source-map.js +12 -18
- package/dist/orchestrator/graph-builder.d.ts +3 -3
- package/dist/orchestrator/graph-builder.js +29 -12
- package/dist/orchestrator/type-checker.d.ts +3 -3
- package/dist/orchestrator/type-checker.js +3 -3
- package/dist/platform/async-runtime.js +1 -1
- package/dist/platform/coop-scheduler-runtime.js +2 -2
- package/dist/platform/generic-debug-codegen.d.ts +36 -0
- package/dist/platform/generic-debug-codegen.js +185 -0
- package/dist/platform/generic-strategy.d.ts +3 -4
- package/dist/platform/generic-strategy.js +5 -80
- package/dist/platform/index.js +1 -1
- package/dist/platform/registry.d.ts +2 -2
- package/dist/platform/registry.js +2 -2
- package/dist/preview/client.js +17 -3
- package/dist/safety/asil-decorators.d.ts +32 -0
- package/dist/safety/asil-decorators.js +32 -0
- package/dist/safety/authoring.d.ts +85 -0
- package/dist/safety/authoring.js +61 -0
- package/dist/safety/engine.d.ts +3 -0
- package/dist/safety/engine.js +83 -0
- package/dist/safety/hal/ops.d.ts +48 -0
- package/dist/safety/hal/ops.js +46 -0
- package/dist/safety/iso26262/analyze.d.ts +13 -0
- package/dist/safety/iso26262/analyze.js +29 -0
- package/dist/safety/iso26262/asil.d.ts +10 -0
- package/dist/safety/iso26262/asil.js +22 -0
- package/dist/safety/iso26262/collect.d.ts +14 -0
- package/dist/safety/iso26262/collect.js +137 -0
- package/dist/safety/iso26262/goto-checker.d.ts +10 -0
- package/dist/safety/iso26262/goto-checker.js +72 -0
- package/dist/safety/iso26262/heap-checker.d.ts +7 -0
- package/dist/safety/iso26262/heap-checker.js +57 -0
- package/dist/safety/iso26262/init-checker.d.ts +13 -0
- package/dist/safety/iso26262/init-checker.js +127 -0
- package/dist/safety/iso26262/loop-checker.d.ts +7 -0
- package/dist/safety/iso26262/loop-checker.js +86 -0
- package/dist/safety/iso26262/recursion-checker.d.ts +9 -0
- package/dist/safety/iso26262/recursion-checker.js +134 -0
- package/dist/safety/iso26262/sidecar-writer.d.ts +25 -0
- package/dist/safety/iso26262/sidecar-writer.js +13 -0
- package/dist/safety/passes/pinMode-intercept.d.ts +3 -0
- package/dist/safety/passes/pinMode-intercept.js +60 -0
- package/dist/safety/runtime/mode-table.d.ts +5 -0
- package/dist/safety/runtime/mode-table.js +55 -0
- package/dist/safety/runtime/polyfills.d.ts +6 -0
- package/dist/safety/runtime/polyfills.js +12 -0
- package/dist/safety/runtime/result-struct.d.ts +11 -0
- package/dist/safety/runtime/result-struct.js +98 -0
- package/dist/safety/runtime/safe-int.d.ts +33 -0
- package/dist/safety/runtime/safe-int.js +170 -0
- package/dist/safety/runtime/safe-traits.d.ts +4 -0
- package/dist/safety/runtime/safe-traits.js +95 -0
- package/dist/safety/runtime/safe-variable.d.ts +39 -0
- package/dist/safety/runtime/safe-variable.js +226 -0
- package/dist/safety/runtime/vote.d.ts +8 -0
- package/dist/safety/runtime/vote.js +92 -0
- package/dist/safety/runtime/write-verify.d.ts +8 -0
- package/dist/safety/runtime/write-verify.js +71 -0
- package/dist/safety/safe-int-types.d.ts +45 -0
- package/dist/safety/safe-int-types.js +25 -0
- package/dist/safety/safe-variable-types.d.ts +29 -0
- package/dist/safety/safe-variable-types.js +19 -0
- package/dist/safety/safety-bridge.d.ts +5 -6
- package/dist/safety/safety-bridge.js +15 -28
- package/dist/safety/sidecar-bridge.d.ts +1 -3
- package/dist/safety/sidecar-bridge.js +3 -20
- package/dist/safety/specifiers.d.ts +6 -0
- package/dist/safety/specifiers.js +14 -0
- package/dist/safety-hook.d.ts +8 -7
- package/dist/safety-hook.js +12 -13
- package/dist/testing.d.ts +5 -6
- package/dist/testing.js +5 -5
- package/dist/transpile/resolution.d.ts +1 -1
- package/dist/transpile/resolution.js +18 -9
- package/dist/transpile/test-pins.d.ts +18 -0
- package/dist/transpile/test-pins.js +142 -0
- package/dist/transpile.d.ts +1 -2
- package/dist/transpile.js +90 -29
- package/dist/types.d.ts +45 -26
- package/dist/ui-hook.d.ts +1 -1
- package/dist/utils/cli.d.ts +2 -2
- package/dist/utils/cli.js +160 -157
- package/dist/utils/fs.d.ts +3 -4
- package/dist/utils/fs.js +4 -5
- package/dist/utils/strings.d.ts +0 -1
- package/dist/utils/strings.js +0 -8
- package/dist/utils/ui.d.ts +5 -2
- package/dist/utils/ui.js +13 -3
- package/package.json +158 -149
- package/dist/add-preset.d.ts +0 -4
- package/dist/add-preset.js +0 -74
- package/dist/api/shared/async-symbol-detector.d.ts +0 -11
- package/dist/api/shared/async-symbol-detector.js +0 -140
- package/dist/api/shared/native-display-op-resolver.d.ts +0 -10
- package/dist/api/shared/native-display-op-resolver.js +0 -64
- package/dist/create/board-checklist.d.ts +0 -2
- package/dist/create/board-checklist.js +0 -52
- package/dist/create/board-codegen.d.ts +0 -9
- package/dist/create/board-codegen.js +0 -238
- package/dist/create/board-generators.d.ts +0 -12
- package/dist/create/board-generators.js +0 -651
- package/dist/create/board-spec.d.ts +0 -637
- package/dist/create/board-spec.js +0 -214
- package/dist/create/init-templates.d.ts +0 -28
- package/dist/create/init-wizard.d.ts +0 -8
- package/dist/create/init-wizard.js +0 -182
- package/dist/install/framework-catalog.d.ts +0 -53
- package/dist/install/framework-catalog.js +0 -107
- package/dist/install/handle-install.d.ts +0 -35
- package/dist/install/handle-install.js +0 -177
- package/dist/install/index.d.ts +0 -4
- package/dist/install/index.js +0 -3
- package/dist/ir/pin-state-tracking.d.ts +0 -58
- package/dist/ir/pin-state-tracking.js +0 -182
- package/dist/ir/pwm-timer-sharing.d.ts +0 -4
- package/dist/ir/pwm-timer-sharing.js +0 -94
- package/dist/ir/timer0-pwm-timing-conflict.d.ts +0 -4
- package/dist/ir/timer0-pwm-timing-conflict.js +0 -72
- package/dist/libdef/component-decls.d.ts +0 -2
- package/dist/libdef/component-decls.js +0 -6
- package/dist/libdef/component-discovery.d.ts +0 -43
- package/dist/libdef/component-discovery.js +0 -83
- package/dist/theme-tokens.d.ts +0 -22
- package/dist/theme-tokens.js +0 -172
|
@@ -12,7 +12,6 @@ export function createEmptyPeripheralUsage() {
|
|
|
12
12
|
adc: false,
|
|
13
13
|
pwm: false,
|
|
14
14
|
externalInterrupts: false,
|
|
15
|
-
timer0: false,
|
|
16
15
|
i2c: false,
|
|
17
16
|
spi: false,
|
|
18
17
|
uart: false,
|
|
@@ -23,6 +22,9 @@ export function createEmptyPeripheralUsage() {
|
|
|
23
22
|
inputPins: new Set(),
|
|
24
23
|
inputPulldownPins: new Set(),
|
|
25
24
|
i2cInstancesUsed: new Set(),
|
|
25
|
+
sensor: false,
|
|
26
|
+
sensorPartsUsed: new Set(),
|
|
27
|
+
spiTargetsUsed: new Set(),
|
|
26
28
|
spiInstancesUsed: new Set(),
|
|
27
29
|
uartInstancesUsed: new Set(),
|
|
28
30
|
pinsUsed: new Set(),
|
|
@@ -68,25 +70,6 @@ export function analyzePeripheralUsage(program) {
|
|
|
68
70
|
}
|
|
69
71
|
return usage;
|
|
70
72
|
}
|
|
71
|
-
function markTimer0UsageFromText(text, usage) {
|
|
72
|
-
if (!text)
|
|
73
|
-
return;
|
|
74
|
-
const normalized = text.replace(/\s+/g, '');
|
|
75
|
-
if (normalized === 'delay' ||
|
|
76
|
-
normalized === 'millis' ||
|
|
77
|
-
normalized === 'micros' ||
|
|
78
|
-
normalized === 'Board.delay' ||
|
|
79
|
-
normalized === 'Board.millis' ||
|
|
80
|
-
normalized === 'Board.micros' ||
|
|
81
|
-
normalized.startsWith('delay(') ||
|
|
82
|
-
normalized.startsWith('millis(') ||
|
|
83
|
-
normalized.startsWith('micros(') ||
|
|
84
|
-
normalized.startsWith('Board.delay(') ||
|
|
85
|
-
normalized.startsWith('Board.millis(') ||
|
|
86
|
-
normalized.startsWith('Board.micros(')) {
|
|
87
|
-
usage.timer0 = true;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
73
|
function analyzeStatements(statements, usage) {
|
|
91
74
|
if (!statements || !Array.isArray(statements))
|
|
92
75
|
return;
|
|
@@ -174,8 +157,6 @@ function analyzeEmitString(cpp, usage) {
|
|
|
174
157
|
usage.uart = true;
|
|
175
158
|
usage.uartInstancesUsed.add(uartMatch[1] ? parseInt(uartMatch[1], 10) : 0);
|
|
176
159
|
}
|
|
177
|
-
// delay(), millis(), micros() — timer0
|
|
178
|
-
markTimer0UsageFromText(cpp, usage);
|
|
179
160
|
// tone(N, ...) — also implies PWM output
|
|
180
161
|
const toneMatch = cpp.match(/^tone\((\d+)/);
|
|
181
162
|
if (toneMatch) {
|
|
@@ -240,7 +221,6 @@ function analyzeCalleeForPeripheralUsage(callee, usage) {
|
|
|
240
221
|
usage.uartInstancesUsed.add(instance);
|
|
241
222
|
}
|
|
242
223
|
}
|
|
243
|
-
markTimer0UsageFromText(callee, usage);
|
|
244
224
|
}
|
|
245
225
|
/**
|
|
246
226
|
* Extract the bus/UART instance number from a name like "Wire" → 0, "Wire1" → 1, "SPI" → 0, "Serial" → 0, "Serial1" → 1.
|
|
@@ -254,60 +234,65 @@ function extractBusInstance(busOrPort, prefix) {
|
|
|
254
234
|
*/
|
|
255
235
|
function analyzeHALOp(op, usage) {
|
|
256
236
|
switch (op.operation) {
|
|
257
|
-
// GPIO
|
|
258
|
-
case 'gpio.set_mode': {
|
|
259
|
-
trackPinNumberAsName(op.pin, usage);
|
|
260
|
-
const mode = op.mode.toLowerCase();
|
|
261
|
-
if (mode === 'output') {
|
|
262
|
-
usage.outputPins.add(op.pin);
|
|
263
|
-
}
|
|
264
|
-
else if (mode === 'input_pullup') {
|
|
265
|
-
usage.inputPullupPins.add(op.pin);
|
|
266
|
-
}
|
|
267
|
-
else if (mode === 'input_pulldown') {
|
|
268
|
-
usage.inputPulldownPins.add(op.pin);
|
|
269
|
-
}
|
|
270
|
-
else if (mode === 'input') {
|
|
271
|
-
usage.inputPins.add(op.pin);
|
|
272
|
-
}
|
|
273
|
-
break;
|
|
274
|
-
}
|
|
237
|
+
// GPIO
|
|
275
238
|
case 'gpio.write':
|
|
276
239
|
case 'gpio.read':
|
|
240
|
+
case 'gpio.read_cfg':
|
|
277
241
|
case 'gpio.toggle': {
|
|
278
242
|
trackPinNumberAsName(op.pin, usage);
|
|
279
243
|
break;
|
|
280
244
|
}
|
|
281
|
-
|
|
282
|
-
case '
|
|
283
|
-
trackPinNumberAsName(op.
|
|
284
|
-
|
|
285
|
-
usage.
|
|
245
|
+
case 'gpio.shift_out':
|
|
246
|
+
case 'gpio.shift_in': {
|
|
247
|
+
trackPinNumberAsName(op.dataPin, usage);
|
|
248
|
+
trackPinNumberAsName(op.clockPin, usage);
|
|
249
|
+
usage.outputPins.add(op.clockPin);
|
|
250
|
+
usage.outputPins.add(op.dataPin);
|
|
286
251
|
break;
|
|
287
252
|
}
|
|
288
|
-
|
|
289
|
-
|
|
253
|
+
// Thin GPIO configure — flag-token text feeds the same mode sets the
|
|
254
|
+
// legacy mode-set ops do (diagnostics + conflict checks).
|
|
255
|
+
case 'gpio.configure': {
|
|
290
256
|
trackPinNumberAsName(op.pin, usage);
|
|
257
|
+
const flags = String(op.flags ?? '');
|
|
258
|
+
if (flags.includes('GPIO.OUTPUT')) {
|
|
259
|
+
usage.outputPins.add(op.pin);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
if (flags.includes('GPIO.PULL_UP'))
|
|
263
|
+
usage.inputPullupPins.add(op.pin);
|
|
264
|
+
else if (flags.includes('GPIO.PULL_DOWN'))
|
|
265
|
+
usage.inputPulldownPins.add(op.pin);
|
|
266
|
+
else
|
|
267
|
+
usage.inputPins.add(op.pin);
|
|
268
|
+
}
|
|
291
269
|
break;
|
|
292
270
|
}
|
|
293
|
-
//
|
|
294
|
-
case '
|
|
295
|
-
case '
|
|
296
|
-
|
|
297
|
-
|
|
271
|
+
// PWM
|
|
272
|
+
case 'pwm.set_pulse':
|
|
273
|
+
case 'pwm.set_duty':
|
|
274
|
+
case 'pwm.set_period': {
|
|
275
|
+
trackPinNumberAsName(op.pin, usage);
|
|
276
|
+
usage.pwm = true;
|
|
277
|
+
usage.pwmPinsUsed.add(op.pin);
|
|
298
278
|
break;
|
|
299
279
|
}
|
|
300
|
-
|
|
301
|
-
case 'adc.
|
|
302
|
-
case 'adc.
|
|
280
|
+
// ADC
|
|
281
|
+
case 'adc.read_raw':
|
|
282
|
+
case 'adc.read_mv':
|
|
283
|
+
{
|
|
284
|
+
usage.adc = true;
|
|
285
|
+
usage.adcChannelsUsed.add(op.pin);
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
303
288
|
break;
|
|
304
289
|
// DAC
|
|
305
|
-
case 'dac.
|
|
290
|
+
case 'dac.write_value': {
|
|
306
291
|
trackPinNumberAsName(op.pin, usage);
|
|
307
292
|
break;
|
|
308
293
|
}
|
|
309
294
|
// Interrupts
|
|
310
|
-
case 'interrupt.
|
|
295
|
+
case 'interrupt.attach_flags': {
|
|
311
296
|
trackPinNumberAsName(op.pin, usage);
|
|
312
297
|
usage.externalInterrupts = true;
|
|
313
298
|
usage.interruptPinsUsed.add(op.pin);
|
|
@@ -318,103 +303,48 @@ function analyzeHALOp(op, usage) {
|
|
|
318
303
|
break;
|
|
319
304
|
}
|
|
320
305
|
// Tone
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
case '
|
|
327
|
-
trackPinNumberAsName(op.pin, usage);
|
|
328
|
-
break;
|
|
329
|
-
}
|
|
330
|
-
// Timing
|
|
331
|
-
case 'timing.delay':
|
|
332
|
-
case 'timing.delay_microseconds':
|
|
333
|
-
case 'timing.millis':
|
|
334
|
-
case 'timing.micros': {
|
|
335
|
-
usage.timer0 = true;
|
|
336
|
-
break;
|
|
337
|
-
}
|
|
338
|
-
case 'timing.free_heap':
|
|
339
|
-
case 'timing.set_interval':
|
|
340
|
-
case 'timing.set_timeout':
|
|
341
|
-
case 'timing.clear_interval':
|
|
342
|
-
case 'timing.clear_timeout':
|
|
343
|
-
break;
|
|
344
|
-
// I2C
|
|
345
|
-
case 'i2c.begin': {
|
|
346
|
-
usage.i2c = true;
|
|
347
|
-
usage.i2cInstancesUsed.add(extractBusInstance(op.bus, 'Wire'));
|
|
348
|
-
break;
|
|
349
|
-
}
|
|
350
|
-
case 'i2c.end':
|
|
351
|
-
case 'i2c.set_clock':
|
|
352
|
-
case 'i2c.begin_transmission':
|
|
353
|
-
case 'i2c.write':
|
|
354
|
-
case 'i2c.end_transmission':
|
|
355
|
-
case 'i2c.request_from':
|
|
356
|
-
case 'i2c.available':
|
|
357
|
-
case 'i2c.read':
|
|
358
|
-
case 'i2c.recover': {
|
|
359
|
-
usage.i2c = true;
|
|
360
|
-
usage.i2cInstancesUsed.add(extractBusInstance(op.bus, 'Wire'));
|
|
361
|
-
break;
|
|
362
|
-
}
|
|
363
|
-
// SPI
|
|
364
|
-
case 'spi.begin': {
|
|
365
|
-
usage.spi = true;
|
|
366
|
-
usage.spiInstancesUsed.add(extractBusInstance(op.bus, 'SPI'));
|
|
367
|
-
break;
|
|
368
|
-
}
|
|
369
|
-
case 'spi.end':
|
|
370
|
-
case 'spi.transfer':
|
|
371
|
-
case 'spi.begin_transaction':
|
|
372
|
-
case 'spi.end_transaction':
|
|
373
|
-
case 'spi.set_mode':
|
|
374
|
-
case 'spi.set_bit_order': {
|
|
306
|
+
// Tier-2 thin SPI (hal/spi-target.ts) — instances used, plus the distinct
|
|
307
|
+
// constructed targets (bus|cs|hz|mode) that feed the DT child nodes and
|
|
308
|
+
// per-target spi_dt_spec state.
|
|
309
|
+
case 'spi.transceive':
|
|
310
|
+
case 'spi.dev_write':
|
|
311
|
+
case 'spi.reg_read': {
|
|
375
312
|
usage.spi = true;
|
|
376
313
|
usage.spiInstancesUsed.add(extractBusInstance(op.bus, 'SPI'));
|
|
314
|
+
usage.spiTargetsUsed.add(`${String(op.bus)}|${op.cs}|${op.hz ?? 0}|${op.mode ?? 0}`);
|
|
377
315
|
break;
|
|
378
316
|
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
317
|
+
// DT-bound sensor parts (generic catalog). A sensor rides the I2C bus, so
|
|
318
|
+
// each use marks the bus instance used too — the overlay enables exactly
|
|
319
|
+
// the controllers that carry constructed sensors.
|
|
320
|
+
case 'sensor.fetch':
|
|
321
|
+
case 'sensor.get': {
|
|
322
|
+
usage.sensor = true;
|
|
323
|
+
const kind = String(op.busKind ?? 'i2c');
|
|
324
|
+
const part = String(op.part ?? '');
|
|
325
|
+
const busInstance = kind === 'spi' ? extractBusInstance(op.bus, 'SPI') : extractBusInstance(op.bus, 'Wire');
|
|
326
|
+
// Instance-level claims only: the category booleans mean EVERY
|
|
327
|
+
// declared controller is in play to the resource-conflict checker
|
|
328
|
+
// (resource-analysis.ts), which would raise phantom pin conflicts
|
|
329
|
+
// between unused silicon instances.
|
|
330
|
+
if (kind === 'spi') {
|
|
331
|
+
usage.spiInstancesUsed.add(busInstance);
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
usage.i2cInstancesUsed.add(busInstance);
|
|
335
|
+
}
|
|
336
|
+
usage.sensorPartsUsed.add(`${part}|${kind}${busInstance}|${op.port ?? 0}`);
|
|
388
337
|
break;
|
|
389
338
|
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
case 'uart.
|
|
393
|
-
case 'uart.
|
|
394
|
-
case 'uart.
|
|
395
|
-
case 'uart.
|
|
396
|
-
case 'uart.
|
|
397
|
-
case 'uart.available':
|
|
398
|
-
case 'uart.flush': {
|
|
339
|
+
// SPI
|
|
340
|
+
// Tier-2 thin UART (hal/uart-port.ts).
|
|
341
|
+
case 'uart.poll_write':
|
|
342
|
+
case 'uart.rx_arm':
|
|
343
|
+
case 'uart.rx_available':
|
|
344
|
+
case 'uart.rx_peek':
|
|
345
|
+
case 'uart.rx_read': {
|
|
399
346
|
usage.uart = true;
|
|
400
|
-
usage.uartInstancesUsed.add(extractBusInstance(op.port, '
|
|
401
|
-
break;
|
|
402
|
-
}
|
|
403
|
-
// Pulse
|
|
404
|
-
case 'pulse.in':
|
|
405
|
-
case 'pulse.in_long': {
|
|
406
|
-
trackPinNumberAsName(op.pin, usage);
|
|
407
|
-
break;
|
|
408
|
-
}
|
|
409
|
-
// Shift
|
|
410
|
-
case 'shift.out': {
|
|
411
|
-
trackPinNumberAsName(op.dataPin, usage);
|
|
412
|
-
trackPinNumberAsName(op.clockPin, usage);
|
|
413
|
-
break;
|
|
414
|
-
}
|
|
415
|
-
case 'shift.in': {
|
|
416
|
-
trackPinNumberAsName(op.dataPin, usage);
|
|
417
|
-
trackPinNumberAsName(op.clockPin, usage);
|
|
347
|
+
usage.uartInstancesUsed.add(extractBusInstance(op.port, 'UART'));
|
|
418
348
|
break;
|
|
419
349
|
}
|
|
420
350
|
// Board resolve, snprintf, raw — no peripheral tracking needed
|
|
@@ -551,7 +481,6 @@ function analyzeExpression(expr, usage) {
|
|
|
551
481
|
try {
|
|
552
482
|
switch (expr.kind) {
|
|
553
483
|
case 'raw': {
|
|
554
|
-
markTimer0UsageFromText(expr.value, usage);
|
|
555
484
|
break;
|
|
556
485
|
}
|
|
557
486
|
case 'method-call': {
|
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
// ---------------------------------------------------------------------------
|
|
7
7
|
/**
|
|
8
8
|
* Get peripheral capacity from board constants.
|
|
9
|
+
*
|
|
10
|
+
* The count comes from an explicit `peripherals.<bus>.count` key when the
|
|
11
|
+
* board carries one; otherwise it is derived from the flattened instance
|
|
12
|
+
* entries (`peripherals.<bus>.<N>.instance`, produced by the MCU package's
|
|
13
|
+
* *_INSTANCES arrays) so a board whose MCU declares two I2C controllers
|
|
14
|
+
* accepts I2C1 (the Arduino-pico and ESP32 cores both expose the second
|
|
15
|
+
* bus). Only when neither form is present does it fall back to 1.
|
|
9
16
|
*/
|
|
10
17
|
function getPeripheralCapacity(boardConstants) {
|
|
11
18
|
const defaultCapacity = {
|
|
@@ -16,10 +23,23 @@ function getPeripheralCapacity(boardConstants) {
|
|
|
16
23
|
if (!boardConstants) {
|
|
17
24
|
return defaultCapacity;
|
|
18
25
|
}
|
|
26
|
+
const capacityFor = (bus) => {
|
|
27
|
+
const explicit = boardConstants.get(`peripherals.${bus}.count`);
|
|
28
|
+
if (typeof explicit === 'number')
|
|
29
|
+
return explicit;
|
|
30
|
+
let highest = -1;
|
|
31
|
+
for (let i = 0; i < 16; i++) {
|
|
32
|
+
const instance = boardConstants.get(`peripherals.${bus}.${i}.instance`);
|
|
33
|
+
if (instance === undefined)
|
|
34
|
+
break;
|
|
35
|
+
highest = i;
|
|
36
|
+
}
|
|
37
|
+
return highest >= 0 ? highest + 1 : 1;
|
|
38
|
+
};
|
|
19
39
|
return {
|
|
20
|
-
i2c:
|
|
21
|
-
spi:
|
|
22
|
-
uart:
|
|
40
|
+
i2c: capacityFor('i2c'),
|
|
41
|
+
spi: capacityFor('spi'),
|
|
42
|
+
uart: capacityFor('uart'),
|
|
23
43
|
};
|
|
24
44
|
}
|
|
25
45
|
/**
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import type { ProgramIR } from '../api/index.js';
|
|
2
|
+
import type { BoardConstants } from './board-resolver.js';
|
|
2
3
|
import type { Diagnostic } from '../types.js';
|
|
4
|
+
/**
|
|
5
|
+
* Resolve the `pins.all.<INDEX>` entry for a HAL pin NUMBER.
|
|
6
|
+
*
|
|
7
|
+
* The array is keyed by position, but pin numbers are sparse on MCUs with
|
|
8
|
+
* unbonded pads (STM32F411: PB11 doesn't exist, so PB12 = number 28 sits at
|
|
9
|
+
* array index 27) — keying `pins.all.${number}` reads the WRONG pin's entry
|
|
10
|
+
* for every pin past the first gap. Match by the entry's `number` field; the
|
|
11
|
+
* dense case (index === number) is checked first so the common path stays a
|
|
12
|
+
* single lookup. Returns -1 when no entry matches.
|
|
13
|
+
*/
|
|
14
|
+
export declare function pinEntryIndexForNumber(pinNumber: number, boardConstants: BoardConstants | undefined): number;
|
|
3
15
|
/**
|
|
4
16
|
* Validate that capability-specific methods are only called on pins that support them.
|
|
5
17
|
*/
|
|
@@ -15,16 +15,16 @@ function assertNever(x) {
|
|
|
15
15
|
// ---------------------------------------------------------------------------
|
|
16
16
|
/** Maps a HAL operation string to the board-definition capability flag it requires. */
|
|
17
17
|
function operationToCapability(op) {
|
|
18
|
-
if (op === 'pwm.
|
|
18
|
+
if (op === 'pwm.set_pulse' || op === 'pwm.set_duty' || op === 'pwm.set_period') {
|
|
19
19
|
return 'pwm';
|
|
20
20
|
}
|
|
21
|
-
if (op === 'adc.
|
|
21
|
+
if (op === 'adc.read_raw' || op === 'adc.read_mv') {
|
|
22
22
|
return 'analogInput';
|
|
23
23
|
}
|
|
24
|
-
if (op === 'dac.
|
|
24
|
+
if (op === 'dac.write_value') {
|
|
25
25
|
return 'analogOutput';
|
|
26
26
|
}
|
|
27
|
-
if (op === 'interrupt.
|
|
27
|
+
if (op === 'interrupt.attach_flags') {
|
|
28
28
|
return 'interrupt';
|
|
29
29
|
}
|
|
30
30
|
// GPIO and timing ops are always available — no capability check needed.
|
|
@@ -33,11 +33,49 @@ function operationToCapability(op) {
|
|
|
33
33
|
// ---------------------------------------------------------------------------
|
|
34
34
|
// Board constant lookups
|
|
35
35
|
// ---------------------------------------------------------------------------
|
|
36
|
+
/**
|
|
37
|
+
* The number of `pins.all.*` entries the board declares (dense, from 0). The
|
|
38
|
+
* P3 full-SoC-port sweep can push well past the old 100/200 hard caps (the
|
|
39
|
+
* Teensy 4.1 sweeps 288 pads), so every scan bounds itself by the actual
|
|
40
|
+
* count instead of a magic limit.
|
|
41
|
+
*/
|
|
42
|
+
function pinCount(boardConstants) {
|
|
43
|
+
if (!boardConstants)
|
|
44
|
+
return 0;
|
|
45
|
+
let i = 0;
|
|
46
|
+
while (i < 4096 && boardConstants.get(`pins.all.${i}.name`) !== undefined)
|
|
47
|
+
i++;
|
|
48
|
+
return i;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Resolve the `pins.all.<INDEX>` entry for a HAL pin NUMBER.
|
|
52
|
+
*
|
|
53
|
+
* The array is keyed by position, but pin numbers are sparse on MCUs with
|
|
54
|
+
* unbonded pads (STM32F411: PB11 doesn't exist, so PB12 = number 28 sits at
|
|
55
|
+
* array index 27) — keying `pins.all.${number}` reads the WRONG pin's entry
|
|
56
|
+
* for every pin past the first gap. Match by the entry's `number` field; the
|
|
57
|
+
* dense case (index === number) is checked first so the common path stays a
|
|
58
|
+
* single lookup. Returns -1 when no entry matches.
|
|
59
|
+
*/
|
|
60
|
+
export function pinEntryIndexForNumber(pinNumber, boardConstants) {
|
|
61
|
+
if (!boardConstants)
|
|
62
|
+
return -1;
|
|
63
|
+
if (Number(boardConstants.get(`pins.all.${pinNumber}.number`)) === pinNumber)
|
|
64
|
+
return pinNumber;
|
|
65
|
+
for (let i = 0; i < pinCount(boardConstants); i++) {
|
|
66
|
+
if (boardConstants.get(`pins.all.${i}.name`) === undefined)
|
|
67
|
+
continue;
|
|
68
|
+
if (Number(boardConstants.get(`pins.all.${i}.number`)) === pinNumber)
|
|
69
|
+
return i;
|
|
70
|
+
}
|
|
71
|
+
return -1;
|
|
72
|
+
}
|
|
36
73
|
/** Find the human-readable name for a pin number (e.g. 14 → "PC0" or "A0"). */
|
|
37
74
|
function getPinName(pinNumber, boardConstants) {
|
|
38
75
|
if (!boardConstants)
|
|
39
76
|
return `pin ${pinNumber}`;
|
|
40
|
-
const
|
|
77
|
+
const idx = pinEntryIndexForNumber(pinNumber, boardConstants);
|
|
78
|
+
const name = idx >= 0 ? boardConstants.get(`pins.all.${idx}.name`) : undefined;
|
|
41
79
|
return name ? String(name) : `pin ${pinNumber}`;
|
|
42
80
|
}
|
|
43
81
|
/** Find all pins on this board that support a given capability. */
|
|
@@ -45,67 +83,17 @@ function findPinsWithCapability(capability, boardConstants) {
|
|
|
45
83
|
if (!boardConstants)
|
|
46
84
|
return [];
|
|
47
85
|
const result = [];
|
|
48
|
-
|
|
49
|
-
pwm: 'pwm',
|
|
50
|
-
analogInput: 'adc',
|
|
51
|
-
analogOutput: 'dac',
|
|
52
|
-
interrupt: 'interrupt',
|
|
53
|
-
};
|
|
54
|
-
const funcType = funcTypeMap[capability];
|
|
55
|
-
for (let i = 0; i < 100; i++) {
|
|
86
|
+
for (let i = 0; i < pinCount(boardConstants); i++) {
|
|
56
87
|
const name = boardConstants.get(`pins.all.${i}.name`);
|
|
57
88
|
if (name === undefined)
|
|
58
89
|
continue;
|
|
59
|
-
// Check capabilities flag first
|
|
60
90
|
const capFlag = boardConstants.get(`pins.all.${i}.capabilities.${capability}`);
|
|
61
91
|
if (capFlag === true || capFlag === 'true') {
|
|
62
92
|
result.push(String(name));
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
// Fallback: check functions array
|
|
66
|
-
if (funcType) {
|
|
67
|
-
for (let j = 0; j < 10; j++) {
|
|
68
|
-
const type = boardConstants.get(`pins.all.${i}.functions.${j}.type`);
|
|
69
|
-
if (type === undefined)
|
|
70
|
-
break;
|
|
71
|
-
if (String(type) === funcType) {
|
|
72
|
-
result.push(String(name));
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
93
|
}
|
|
77
94
|
}
|
|
78
95
|
return result;
|
|
79
96
|
}
|
|
80
|
-
/**
|
|
81
|
-
* Does the board declare ANY per-pin `type:'pwm'` function entry anywhere?
|
|
82
|
-
*
|
|
83
|
-
* AVR-family boards (atmega328p, etc.) hardwire PWM to specific timer-output
|
|
84
|
-
* pins, so their MCU descriptors list `{ type:'pwm', ... }` per pin and the
|
|
85
|
-
* capability check correctly rejects PWM on non-timer pins. ESP32-family
|
|
86
|
-
* boards route LEDC to ANY output GPIO via the GPIO matrix, so their MCU
|
|
87
|
-
* descriptors carry zero `type:'pwm'` entries — PWM is a board-wide property
|
|
88
|
-
* (the `pins.pwm` collection), not a per-pin function. On such boards the
|
|
89
|
-
* per-pin capability check would false-positive on every pin, so the caller
|
|
90
|
-
* skips it when this returns false. This distinguishes the two families
|
|
91
|
-
* cleanly (AVR has entries, ESP32 has none) without special-casing arch names.
|
|
92
|
-
*/
|
|
93
|
-
function boardHasAnyPwmFunctionEntries(boardConstants) {
|
|
94
|
-
if (!boardConstants)
|
|
95
|
-
return false;
|
|
96
|
-
for (let i = 0; i < 100; i++) {
|
|
97
|
-
if (boardConstants.get(`pins.all.${i}.name`) === undefined)
|
|
98
|
-
continue;
|
|
99
|
-
for (let j = 0; j < 10; j++) {
|
|
100
|
-
const type = boardConstants.get(`pins.all.${i}.functions.${j}.type`);
|
|
101
|
-
if (type === undefined)
|
|
102
|
-
break;
|
|
103
|
-
if (String(type) === 'pwm')
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
return false;
|
|
108
|
-
}
|
|
109
97
|
// ---------------------------------------------------------------------------
|
|
110
98
|
// Capability check for a single HAL operation
|
|
111
99
|
// ---------------------------------------------------------------------------
|
|
@@ -117,53 +105,29 @@ function checkCapability(operation, sourceLine, sourceCol, filePath, boardConsta
|
|
|
117
105
|
const capability = operationToCapability(op);
|
|
118
106
|
if (!capability)
|
|
119
107
|
return; // GPIO/timing — always available.
|
|
120
|
-
//
|
|
121
|
-
//
|
|
122
|
-
//
|
|
123
|
-
//
|
|
124
|
-
|
|
125
|
-
if (
|
|
108
|
+
// Construction-time routing overrides (the escape hatch) let a user vouch
|
|
109
|
+
// for a pin the facts layer doesn't cover — skip the capability check so
|
|
110
|
+
// an explicit channel/device/controller/pinctrl override is never rejected
|
|
111
|
+
// by the per-pin flag.
|
|
112
|
+
const override = operation;
|
|
113
|
+
if ((override.channelOverride !== undefined && override.channelOverride !== -1)
|
|
114
|
+
|| override.deviceOverride
|
|
115
|
+
|| override.pinctrlOverride
|
|
116
|
+
|| override.controllerOverride) {
|
|
126
117
|
return;
|
|
118
|
+
}
|
|
127
119
|
const pin = operation.pin;
|
|
128
120
|
if (typeof pin !== 'number' || pin < 0)
|
|
129
121
|
return;
|
|
130
|
-
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
// functions array (functions.N.type === capability prefix).
|
|
138
|
-
const capFlag = boardConstants?.get(`pins.all.${pin}.capabilities.${capability}`);
|
|
122
|
+
// Check the pin's capability via the board definition's per-pin flag.
|
|
123
|
+
// The entry is resolved by pin NUMBER — the array index diverges from the
|
|
124
|
+
// number on MCUs with unbonded pads (see pinEntryIndexForNumber).
|
|
125
|
+
const entryIdx = pinEntryIndexForNumber(pin, boardConstants);
|
|
126
|
+
if (entryIdx < 0)
|
|
127
|
+
return; // Unknown pin — the emitter's own resolution reports it.
|
|
128
|
+
const capFlag = boardConstants?.get(`pins.all.${entryIdx}.capabilities.${capability}`);
|
|
139
129
|
if (capFlag === true || capFlag === 'true')
|
|
140
130
|
return; // Capability confirmed.
|
|
141
|
-
// Fallback: scan the functions array for a matching type.
|
|
142
|
-
// PWM capability is indicated by functions[N].type === 'pwm',
|
|
143
|
-
// ADC by 'adc', interrupts by 'interrupt' (external), DAC by 'dac'.
|
|
144
|
-
const funcTypeMap = {
|
|
145
|
-
pwm: 'pwm',
|
|
146
|
-
analogInput: 'adc',
|
|
147
|
-
analogOutput: 'dac',
|
|
148
|
-
interrupt: 'interrupt',
|
|
149
|
-
};
|
|
150
|
-
const funcType = funcTypeMap[capability];
|
|
151
|
-
if (funcType) {
|
|
152
|
-
let hasCapabilityData = false;
|
|
153
|
-
for (let i = 0; i < 10; i++) {
|
|
154
|
-
const type = boardConstants?.get(`pins.all.${pin}.functions.${i}.type`);
|
|
155
|
-
if (type === undefined)
|
|
156
|
-
break;
|
|
157
|
-
hasCapabilityData = true;
|
|
158
|
-
if (String(type) === funcType)
|
|
159
|
-
return; // Capability confirmed via functions.
|
|
160
|
-
}
|
|
161
|
-
// If the pin has NO functions entries at all AND the capability we're
|
|
162
|
-
// checking is interrupt (which is stored in capabilities, not functions),
|
|
163
|
-
// we can't determine support — skip to avoid false positives.
|
|
164
|
-
if (!hasCapabilityData && capability === 'interrupt')
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
167
131
|
// Capability NOT supported — emit a diagnostic.
|
|
168
132
|
const pinName = getPinName(pin, boardConstants);
|
|
169
133
|
const validPins = findPinsWithCapability(capability, boardConstants);
|
|
@@ -17,7 +17,7 @@ const READ_METHODS = new Set([
|
|
|
17
17
|
]);
|
|
18
18
|
/** Write operations that implicitly set OUTPUT mode on Wiring-derived frameworks. */
|
|
19
19
|
const WRITE_METHODS = new Set([
|
|
20
|
-
'write', 'high', 'low', 'toggle', 'pulse', 'pwm',
|
|
20
|
+
'write', 'high', 'low', 'toggle', 'pulse', 'pwm',
|
|
21
21
|
]);
|
|
22
22
|
/** Receiver kinds that represent GPIO pins. */
|
|
23
23
|
const PIN_RECEIVER_KINDS = new Set([
|
|
@@ -85,7 +85,7 @@ export function validatePinModeConfig(program) {
|
|
|
85
85
|
const inferReceiverKind = (method) => {
|
|
86
86
|
if (method === 'readAnalog' || method === 'readVoltage')
|
|
87
87
|
return 'analog-input';
|
|
88
|
-
if (method === 'pwm'
|
|
88
|
+
if (method === 'pwm')
|
|
89
89
|
return 'pwm';
|
|
90
90
|
// Methods in the read/write/mode sets that aren't analog/pwm are digital.
|
|
91
91
|
if (READ_METHODS.has(method) || WRITE_METHODS.has(method) || MODE_SET_METHODS.has(method))
|
|
@@ -99,11 +99,11 @@ export function validatePinModeConfig(program) {
|
|
|
99
99
|
if (!op)
|
|
100
100
|
return;
|
|
101
101
|
const pinKey = `pin${op.pin}`;
|
|
102
|
-
if (op.operation === 'gpio.
|
|
102
|
+
if (op.operation === 'gpio.configure' || op.operation === 'gpio.read_cfg') {
|
|
103
103
|
pinModeSet.add(pinKey);
|
|
104
104
|
analogDrivenPins.delete(pinKey);
|
|
105
105
|
}
|
|
106
|
-
else if (op.operation === 'pwm.
|
|
106
|
+
else if (op.operation === 'pwm.set_pulse' || op.operation === 'pwm.set_duty') {
|
|
107
107
|
analogDrivenPins.add(pinKey);
|
|
108
108
|
}
|
|
109
109
|
else if (op.operation === 'gpio.write' || op.operation === 'gpio.toggle') {
|
|
@@ -270,7 +270,7 @@ export function validatePinModeConfig(program) {
|
|
|
270
270
|
const checkStatement = (stmt) => {
|
|
271
271
|
if (!stmt || typeof stmt !== 'object')
|
|
272
272
|
return;
|
|
273
|
-
// HAL-op statements: track pin-mode state from gpio.
|
|
273
|
+
// HAL-op statements: track pin-mode state from gpio.configure and warn on
|
|
274
274
|
// gpio.read/write/toggle without prior mode configuration. After HAL
|
|
275
275
|
// resolution, pin method calls (D2.isHigh(), D2.high()) become these
|
|
276
276
|
// structured ops — the method-call form no longer exists at validation time.
|