@typecad/framework-zephyr 1.0.0-alpha.14 → 1.0.0-alpha.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -47
- package/dist/as-built.d.ts +33 -0
- package/dist/as-built.js +188 -0
- package/dist/async/timer-polyfill.js +1 -1
- package/dist/boardgen.d.ts +128 -0
- package/dist/boardgen.js +1366 -0
- package/dist/chips/board-overrides.d.ts +7 -0
- package/dist/chips/board-overrides.js +11 -0
- package/dist/chips/esp32s3.js +49 -0
- package/dist/chips/index.d.ts +6 -12
- package/dist/chips/index.js +18 -34
- package/dist/chips/resolve.d.ts +16 -2
- package/dist/chips/resolve.js +267 -10
- package/dist/chips/soc/.d.ts +2 -0
- package/dist/chips/soc/.js +129 -0
- package/dist/chips/soc/esp32.d.ts +2 -0
- package/dist/chips/soc/esp32.js +120 -0
- package/dist/chips/soc/esp32c3.d.ts +2 -0
- package/dist/chips/soc/esp32c3.js +90 -0
- package/dist/chips/soc/esp32c6.d.ts +2 -0
- package/dist/chips/soc/esp32c6.js +109 -0
- package/dist/chips/soc/esp32s3.d.ts +2 -0
- package/dist/chips/soc/esp32s3.js +189 -0
- package/dist/chips/soc/index.d.ts +2 -0
- package/dist/chips/soc/index.js +23 -0
- package/dist/chips/soc/nrf52840.d.ts +2 -0
- package/dist/chips/soc/nrf52840.js +130 -0
- package/dist/chips/soc/rp2040.d.ts +2 -0
- package/dist/chips/soc/rp2040.js +141 -0
- package/dist/chips/soc/rp2350a.d.ts +2 -0
- package/dist/chips/soc/rp2350a.js +145 -0
- package/dist/chips/soc/samd21g18a.d.ts +2 -0
- package/dist/chips/soc/samd21g18a.js +143 -0
- package/dist/chips/soc/stm32f411xe.d.ts +2 -0
- package/dist/chips/soc/stm32f411xe.js +251 -0
- package/dist/chips/types.d.ts +319 -0
- package/dist/chips/xiao-ble.js +21 -0
- package/dist/display/profiles.js +1 -1
- package/dist/doctor.js +38 -4
- package/dist/dt-config/custom-board.d.ts +23 -0
- package/dist/dt-config/custom-board.js +227 -0
- package/dist/dt-config/kconfig.d.ts +72 -1
- package/dist/dt-config/kconfig.js +115 -26
- package/dist/dt-config/overlay.js +548 -28
- package/dist/framework.manifest.d.ts +3 -3
- package/dist/framework.manifest.js +122 -185
- package/dist/index.d.ts +4 -1
- package/dist/index.js +8 -2
- package/dist/lowering/adc.d.ts +20 -2
- package/dist/lowering/adc.js +121 -29
- package/dist/lowering/ble.js +31 -28
- package/dist/lowering/dac.js +9 -9
- package/dist/lowering/fs.js +18 -10
- package/dist/lowering/gpio.d.ts +2 -0
- package/dist/lowering/gpio.js +82 -5
- package/dist/lowering/http.js +39 -14
- package/dist/lowering/hwtimer.d.ts +4 -0
- package/dist/lowering/hwtimer.js +35 -10
- package/dist/lowering/i2c.js +46 -54
- package/dist/lowering/index.d.ts +5 -5
- package/dist/lowering/index.js +15 -16
- package/dist/lowering/interrupts.d.ts +22 -5
- package/dist/lowering/interrupts.js +104 -22
- package/dist/lowering/mqtt.js +3 -5
- package/dist/lowering/power.js +0 -4
- package/dist/lowering/preferences.js +49 -77
- package/dist/lowering/pulse.js +0 -31
- package/dist/lowering/pwm.d.ts +12 -1
- package/dist/lowering/pwm.js +78 -14
- package/dist/lowering/random.js +3 -3
- package/dist/lowering/sensor.d.ts +37 -0
- package/dist/lowering/sensor.js +119 -0
- package/dist/lowering/spi.d.ts +12 -0
- package/dist/lowering/spi.js +65 -40
- package/dist/lowering/thread.d.ts +14 -0
- package/dist/lowering/thread.js +55 -0
- package/dist/lowering/timing.js +20 -46
- package/dist/lowering/tone.js +16 -4
- package/dist/lowering/uart.d.ts +13 -0
- package/dist/lowering/uart.js +72 -51
- package/dist/lowering/usb.d.ts +34 -0
- package/dist/lowering/usb.js +206 -0
- package/dist/lowering/wdt.d.ts +1 -1
- package/dist/lowering/wdt.js +17 -7
- package/dist/lowering/wifi.d.ts +3 -2
- package/dist/lowering/wifi.js +97 -111
- package/dist/sdk/board-catalog-sync.d.ts +16 -0
- package/dist/sdk/board-catalog-sync.js +41 -0
- package/dist/sdk/board-data.generated.d.ts +2 -0
- package/dist/sdk/board-data.generated.js +4 -0
- package/dist/sdk/catalog-walker.d.ts +90 -0
- package/dist/sdk/catalog-walker.js +682 -0
- package/dist/sdk/dts-reader.d.ts +83 -0
- package/dist/sdk/dts-reader.js +596 -0
- package/dist/strategy.d.ts +136 -17
- package/dist/strategy.js +839 -222
- package/dist/toolchain/bossac-touch.d.ts +18 -0
- package/dist/toolchain/bossac-touch.js +88 -0
- package/dist/toolchain/compat.d.ts +2 -2
- package/dist/toolchain/compat.js +8 -3
- package/dist/toolchain/debug-config.d.ts +21 -26
- package/dist/toolchain/debug-config.js +226 -76
- package/dist/toolchain/env-check.d.ts +4 -4
- package/dist/toolchain/env-check.js +5 -5
- package/dist/toolchain/index.d.ts +115 -1
- package/dist/toolchain/index.js +680 -71
- package/dist/toolchain/scaffold.js +39 -7
- package/dist/toolchain/west-discover.d.ts +4 -0
- package/dist/toolchain/west-discover.js +17 -6
- package/installer/CHANGELOG.md +473 -0
- package/installer/README.md +328 -0
- package/installer/environment.yml +46 -0
- package/installer/etc/conda/activate.d/zephyr.bat +7 -0
- package/installer/etc/conda/activate.d/zephyr.ps1 +12 -0
- package/installer/etc/conda/activate.d/zephyr.sh +20 -0
- package/installer/etc/conda/deactivate.d/zephyr.bat +6 -0
- package/installer/etc/conda/deactivate.d/zephyr.ps1 +6 -0
- package/installer/etc/conda/deactivate.d/zephyr.sh +4 -0
- package/installer/install.mjs +580 -0
- package/installer/install.ps1 +619 -0
- package/installer/install.sh +310 -0
- package/installer/lib/detect-platform.sh +62 -0
- package/installer/lib/fetch-sdk.sh +304 -0
- package/installer/lib/init-workspace.sh +153 -0
- package/installer/lib/write-activation.sh +76 -0
- package/installer/patches/tfm-c-include-separators.patch +19 -0
- package/installer/patches/zephyr-tfm-nordic-zephyr-include.patch +24 -0
- package/installer/templates/project/.typecad/activate-zephyr.ps1 +31 -0
- package/installer/templates/project/.typecad/activate-zephyr.sh +31 -0
- package/installer/templates/project/.vscode/settings.json +30 -0
- package/installer/templates/project/README.md +58 -0
- package/installer/versions.env +110 -0
- package/package.json +15 -15
- package/src/as-built.ts +206 -0
- package/src/boardgen.ts +1428 -0
- package/src/chips/index.ts +35 -54
- package/src/chips/resolve.ts +285 -10
- package/src/chips/types.ts +325 -1
- package/src/display/profiles.ts +1 -1
- package/src/doctor.ts +110 -77
- package/src/dt-config/custom-board.ts +325 -0
- package/src/dt-config/kconfig.ts +165 -18
- package/src/dt-config/overlay.ts +537 -25
- package/src/framework.manifest.ts +123 -185
- package/src/index.ts +57 -41
- package/src/lowering/adc.ts +222 -118
- package/src/lowering/ble.ts +32 -28
- package/src/lowering/dac.ts +82 -82
- package/src/lowering/fs.ts +18 -10
- package/src/lowering/gpio.ts +242 -155
- package/src/lowering/http.ts +512 -488
- package/src/lowering/hwtimer.ts +139 -101
- package/src/lowering/i2c.ts +116 -126
- package/src/lowering/index.ts +91 -93
- package/src/lowering/interrupts.ts +113 -21
- package/src/lowering/mqtt.ts +3 -5
- package/src/lowering/preferences.ts +327 -354
- package/src/lowering/pwm.ts +167 -99
- package/src/lowering/random.ts +3 -3
- package/src/lowering/sensor.ts +155 -0
- package/src/lowering/spi.ts +164 -124
- package/src/lowering/thread.ts +63 -0
- package/src/lowering/timing.ts +46 -72
- package/src/lowering/uart.ts +73 -51
- package/src/lowering/usb.ts +221 -0
- package/src/lowering/wdt.ts +95 -84
- package/src/lowering/wifi.ts +97 -112
- package/src/sdk/board-catalog-sync.ts +62 -0
- package/src/strategy.ts +848 -237
- package/src/toolchain/bossac-touch.ts +112 -0
- package/src/toolchain/compat.ts +8 -3
- package/src/toolchain/debug-config.ts +676 -522
- package/src/toolchain/env-check.ts +9 -9
- package/src/toolchain/index.ts +1359 -645
- package/src/toolchain/scaffold.ts +38 -7
- package/src/toolchain/west-discover.ts +19 -6
- package/src/async/timer-polyfill.ts +0 -107
- package/src/chips/esp32.ts +0 -74
- package/src/chips/esp32s3.ts +0 -57
- package/src/chips/xiao-ble.ts +0 -82
- package/src/lowering/power.ts +0 -70
- package/src/lowering/pulse.ts +0 -93
- package/src/lowering/tone.ts +0 -60
- package/src/lowering/worker-backing.ts +0 -94
- package/src/lowering/worker.ts +0 -17
package/dist/lowering/hwtimer.js
CHANGED
|
@@ -26,6 +26,10 @@ function hzVar(instance) {
|
|
|
26
26
|
function cbVar(instance) {
|
|
27
27
|
return `__tc_hw_cb_${instance}`;
|
|
28
28
|
}
|
|
29
|
+
/** The trampoline matching counter_top_callback_t: (dev, user_data). */
|
|
30
|
+
function trampVar(instance) {
|
|
31
|
+
return `__tc_hw_tramp_${instance}`;
|
|
32
|
+
}
|
|
29
33
|
/**
|
|
30
34
|
* Emit the per-instance counter device handles + frequency/callback state.
|
|
31
35
|
* Called from shimLines when the program uses hardware timers.
|
|
@@ -36,7 +40,7 @@ export function hwtimerInitLines(chip) {
|
|
|
36
40
|
return [];
|
|
37
41
|
const lines = ['// CUTTLEFISH_HWTIMER_BEGIN'];
|
|
38
42
|
controllers.forEach((c, i) => {
|
|
39
|
-
lines.push(`static const struct device* ${devVar(i)} = DEVICE_DT_GET(DT_NODELABEL(${c.nodeLabel}));`, `static uint32_t ${hzVar(i)} = 1;`, `static
|
|
43
|
+
lines.push(`static const struct device* ${devVar(i)} = DEVICE_DT_GET(DT_NODELABEL(${c.nodeLabel}));`, `static uint32_t ${hzVar(i)} = 1;`, `static void (*${cbVar(i)})(void) = NULL;`, `static void ${trampVar(i)}(const struct device* dev, void* user_data) {`, ` (void)dev; (void)user_data;`, ` if (${cbVar(i)}) { ${cbVar(i)}(); }`, `}`);
|
|
40
44
|
});
|
|
41
45
|
lines.push('// CUTTLEFISH_HWTIMER_END');
|
|
42
46
|
return lines;
|
|
@@ -57,25 +61,46 @@ export function lowerHwtimer(op, chip) {
|
|
|
57
61
|
return { code: `/* hwtimer instance ${o.instance}: out of range on ${chip.id} */` };
|
|
58
62
|
}
|
|
59
63
|
switch (op.operation) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
default:
|
|
65
|
+
throw new Error(`framework-zephyr does not yet support HAL op \`${op.operation}\`. ` +
|
|
66
|
+
`Open an issue or use rawCpp() to emit it manually.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function lowerCounter(op, chip) {
|
|
70
|
+
const o = op;
|
|
71
|
+
const controllers = chip.hwtimer?.controllers ?? [];
|
|
72
|
+
if (controllers.length === 0) {
|
|
73
|
+
return { code: `/* ${op.operation}: no counter device on ${chip.id} */` };
|
|
74
|
+
}
|
|
75
|
+
const instance = typeof o.instance === 'number' ? o.instance : parseInt(String(o.instance), 10);
|
|
76
|
+
if (isNaN(instance) || instance < 0 || instance >= controllers.length) {
|
|
77
|
+
return { code: `/* counter instance ${o.instance}: out of range on ${chip.id} (${controllers.length} declared) */` };
|
|
78
|
+
}
|
|
79
|
+
switch (op.operation) {
|
|
80
|
+
case 'counter.on_alarm':
|
|
63
81
|
return { code: `${cbVar(instance)} = (${o.handler});` };
|
|
64
|
-
case '
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
82
|
+
case 'counter.start': {
|
|
83
|
+
// Apply the construction hz as the top value, arm the alarm callback,
|
|
84
|
+
// start. hz rides the op, so no ordering constraint exists. The API
|
|
85
|
+
// is counter_set_top_value(dev, const counter_top_cfg*) with a
|
|
86
|
+
// (dev, user_data) callback — the trampoline in hwtimerInitLines
|
|
87
|
+
// adapts the user's void() handler.
|
|
68
88
|
return {
|
|
69
89
|
code: [
|
|
70
90
|
`{`,
|
|
91
|
+
` ${hzVar(instance)} = ${o.hz};`,
|
|
71
92
|
` uint32_t __f = counter_get_frequency(${devVar(instance)});`,
|
|
72
93
|
` uint32_t __top = __f ? (__f / ${hzVar(instance)}) : 0U;`,
|
|
73
|
-
` if (__top > 0U) {
|
|
94
|
+
` if (__top > 0U) {`,
|
|
95
|
+
` struct counter_top_cfg __cfg = { .ticks = __top, .callback = ${trampVar(instance)}, .user_data = NULL, .flags = 0U };`,
|
|
96
|
+
` (void)counter_set_top_value(${devVar(instance)}, &__cfg);`,
|
|
97
|
+
` }`,
|
|
74
98
|
` (void)counter_start(${devVar(instance)});`,
|
|
75
99
|
`}`,
|
|
76
100
|
].join(' '),
|
|
77
101
|
};
|
|
78
|
-
|
|
102
|
+
}
|
|
103
|
+
case 'counter.stop':
|
|
79
104
|
return { code: `(void)counter_stop(${devVar(instance)});` };
|
|
80
105
|
default:
|
|
81
106
|
throw new Error(`framework-zephyr does not yet support HAL op \`${op.operation}\`. ` +
|
package/dist/lowering/i2c.js
CHANGED
|
@@ -11,8 +11,6 @@
|
|
|
11
11
|
// The device handle resolves at compile time via DEVICE_DT_GET(DT_NODELABEL(...)).
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
13
|
import { parseControllerIndex } from './util.js';
|
|
14
|
-
const TXBUF_SIZE = 32;
|
|
15
|
-
const RXBUF_SIZE = 32;
|
|
16
14
|
/** The C variable prefix for a controller's state. */
|
|
17
15
|
function prefix(idx) {
|
|
18
16
|
return `__tc_i2c${idx}`;
|
|
@@ -29,12 +27,6 @@ export function i2cInitLines(chip, controllerIndex) {
|
|
|
29
27
|
return [
|
|
30
28
|
'// CUTTLEFISH_I2C_BEGIN',
|
|
31
29
|
`static const struct device* ${p}_dev = DEVICE_DT_GET(DT_NODELABEL(${ctrl.nodeLabel}));`,
|
|
32
|
-
`static uint16_t ${p}_addr = 0xFFFF;`,
|
|
33
|
-
`static uint8_t ${p}_txbuf[${TXBUF_SIZE}];`,
|
|
34
|
-
`static size_t ${p}_txlen = 0;`,
|
|
35
|
-
`static uint8_t ${p}_rxbuf[${RXBUF_SIZE}];`,
|
|
36
|
-
`static size_t ${p}_rxlen = 0;`,
|
|
37
|
-
`static size_t ${p}_rxpos = 0;`,
|
|
38
30
|
'// CUTTLEFISH_I2C_END',
|
|
39
31
|
];
|
|
40
32
|
}
|
|
@@ -48,6 +40,26 @@ function speedForHz(hz) {
|
|
|
48
40
|
return 'I2C_SPEED_FAST_PLUS';
|
|
49
41
|
return 'I2C_SPEED_HIGH';
|
|
50
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* The (void) comma expression begin/end lower to — a no-op that references
|
|
45
|
+
* the controller's whole state block (device + transaction buffers) so a
|
|
46
|
+
* program calling only begin() stays -Werror clean (-Wunused-variable).
|
|
47
|
+
*/
|
|
48
|
+
function i2cKeepAlive(p) {
|
|
49
|
+
return `(void)${p}_dev;`;
|
|
50
|
+
}
|
|
51
|
+
/** The thin-device bus-speed preamble: apply the construction hz once
|
|
52
|
+
* (i2c_configure with Zephyr's I2C_SPEED_SET tier mapping), or '' when the
|
|
53
|
+
* target constructed without hz. Guarded per controller, so the cost after
|
|
54
|
+
* the first op is one bool test. */
|
|
55
|
+
function i2cSpeedGuard(p, hz) {
|
|
56
|
+
const n = typeof hz === 'number' ? hz : parseInt(String(hz ?? 0), 10);
|
|
57
|
+
if (!n || isNaN(n))
|
|
58
|
+
return '';
|
|
59
|
+
const speed = speedForHz(n);
|
|
60
|
+
const done = `${p}_spd_done`;
|
|
61
|
+
return `{ static bool ${done} = false; if (!${done}) { (void)i2c_configure(${p}_dev, I2C_SPEED_SET(${speed})); ${done} = true; } } `;
|
|
62
|
+
}
|
|
51
63
|
/**
|
|
52
64
|
* Resolve a HAL i2c.* op to Zephyr C++.
|
|
53
65
|
* Returns `{ code }` for statement ops, `{ expression }` for value-returning ops.
|
|
@@ -57,56 +69,36 @@ export function lowerI2c(op, chip) {
|
|
|
57
69
|
const idx = parseControllerIndex(o.bus);
|
|
58
70
|
const p = prefix(idx);
|
|
59
71
|
switch (op.operation) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
case 'i2c.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const hz = typeof o.hz === 'number' ? o.hz : parseInt(String(o.hz), 10);
|
|
68
|
-
const speed = isNaN(hz) ? 'I2C_SPEED_STANDARD' : speedForHz(hz || 100000);
|
|
69
|
-
return { code: `i2c_configure(${p}_dev, I2C_SPEED_SET(${speed}));` };
|
|
72
|
+
// ── Thin I2C device (hal/i2c-target.ts) — Zephyr register verbs ──────
|
|
73
|
+
// One call per op against the controller device handle; the optional
|
|
74
|
+
// construction hz applies once via a guarded i2c_configure (the same
|
|
75
|
+
// call i2c.set_clock lowers to).
|
|
76
|
+
case 'i2c.reg_write': {
|
|
77
|
+
const pre = i2cSpeedGuard(p, o.hz);
|
|
78
|
+
return { code: `${pre} i2c_reg_write_byte(${p}_dev, static_cast<uint16_t>(${o.address}), static_cast<uint8_t>(${o.reg}), static_cast<uint8_t>(${o.value}));` };
|
|
70
79
|
}
|
|
71
|
-
case 'i2c.
|
|
72
|
-
|
|
73
|
-
return {
|
|
74
|
-
case 'i2c.write':
|
|
75
|
-
// Append one byte (clamped to capacity).
|
|
76
|
-
return { code: `if (${p}_txlen < ${TXBUF_SIZE}) { ${p}_txbuf[${p}_txlen++] = static_cast<uint8_t>(${o.data}); }` };
|
|
77
|
-
case 'i2c.write_bytes': {
|
|
78
|
-
const bytes = o.bytes ?? [];
|
|
79
|
-
const stmts = bytes.map((b) => `if (${p}_txlen < ${TXBUF_SIZE}) { ${p}_txbuf[${p}_txlen++] = static_cast<uint8_t>(${b}); }`);
|
|
80
|
-
return { code: stmts.join(' ') };
|
|
81
|
-
}
|
|
82
|
-
case 'i2c.write_buffer': {
|
|
83
|
-
// Copy from a user buffer (its name is o.data), clamped to capacity.
|
|
84
|
-
return {
|
|
85
|
-
code: `for (size_t __i = 0; __i < sizeof(${o.data}) && ${p}_txlen < ${TXBUF_SIZE}; __i++) { ${p}_txbuf[${p}_txlen++] = reinterpret_cast<const uint8_t*>(${o.data})[__i]; }`,
|
|
86
|
-
};
|
|
80
|
+
case 'i2c.reg_read': {
|
|
81
|
+
const pre = i2cSpeedGuard(p, o.hz);
|
|
82
|
+
return { expression: `({ ${pre} uint8_t __v = 0; (void)i2c_reg_read_byte(${p}_dev, static_cast<uint16_t>(${o.address}), static_cast<uint8_t>(${o.reg}), &__v); __v; })` };
|
|
87
83
|
}
|
|
88
|
-
case 'i2c.
|
|
89
|
-
|
|
90
|
-
return { code:
|
|
91
|
-
case 'i2c.request_from': {
|
|
92
|
-
const qty = o.quantity;
|
|
93
|
-
return {
|
|
94
|
-
code: `i2c_read(${p}_dev, ${p}_rxbuf, static_cast<uint32_t>(${qty}), static_cast<uint16_t>(${o.address})); ${p}_rxlen = ${qty}; ${p}_rxpos = 0;`,
|
|
95
|
-
};
|
|
84
|
+
case 'i2c.reg_update': {
|
|
85
|
+
const pre = i2cSpeedGuard(p, o.hz);
|
|
86
|
+
return { code: `${pre} (void)i2c_reg_update_byte(${p}_dev, static_cast<uint16_t>(${o.address}), static_cast<uint8_t>(${o.reg}), static_cast<uint8_t>(${o.mask}), static_cast<uint8_t>(${o.value}));` };
|
|
96
87
|
}
|
|
97
|
-
case 'i2c.
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
88
|
+
case 'i2c.dev_write': {
|
|
89
|
+
const pre = i2cSpeedGuard(p, o.hz);
|
|
90
|
+
const bytes = o.bytes ?? [];
|
|
91
|
+
// Identifier-shaped only — a single-byte literal array arrives as
|
|
92
|
+
// numeric text ("159") and must take the literal path.
|
|
93
|
+
const isBuffer = bytes.length === 1 && typeof bytes[0] === 'string' && /^[A-Za-z_][A-Za-z0-9_]*$/.test(bytes[0]);
|
|
94
|
+
if (isBuffer) {
|
|
95
|
+
const name = bytes[0];
|
|
96
|
+
// A named user buffer: i2c_write against its storage directly.
|
|
97
|
+
return { code: `${pre} (void)i2c_write(${p}_dev, reinterpret_cast<const uint8_t*>(${name}), sizeof(${name}), static_cast<uint16_t>(${o.address}));` };
|
|
98
|
+
}
|
|
99
|
+
const arr = `static const uint8_t __tc_i2cw[] = { ${bytes.join(', ')} };`;
|
|
100
|
+
return { code: `${pre} ${arr} (void)i2c_write(${p}_dev, __tc_i2cw, sizeof(__tc_i2cw), static_cast<uint16_t>(${o.address}));` };
|
|
107
101
|
}
|
|
108
|
-
case 'i2c.recover':
|
|
109
|
-
return { code: `i2c_recover_bus(${p}_dev);` };
|
|
110
102
|
default:
|
|
111
103
|
throw new Error(`framework-zephyr does not yet support HAL op \`${op.operation}\`. ` +
|
|
112
104
|
`Open an issue or use rawCpp() to emit it manually.`);
|
package/dist/lowering/index.d.ts
CHANGED
|
@@ -6,11 +6,9 @@ import { lowerPwm } from './pwm.js';
|
|
|
6
6
|
import { lowerI2c } from './i2c.js';
|
|
7
7
|
import { lowerSpi } from './spi.js';
|
|
8
8
|
import { lowerUart } from './uart.js';
|
|
9
|
+
import { lowerUsb } from './usb.js';
|
|
9
10
|
import { lowerInterrupt } from './interrupts.js';
|
|
10
11
|
import { lowerWdt } from './wdt.js';
|
|
11
|
-
import { lowerPower } from './power.js';
|
|
12
|
-
import { lowerTone } from './tone.js';
|
|
13
|
-
import { lowerPulseOrShift } from './pulse.js';
|
|
14
12
|
import { lowerBle } from './ble.js';
|
|
15
13
|
import { lowerWifi } from './wifi.js';
|
|
16
14
|
import { lowerHttp } from './http.js';
|
|
@@ -20,8 +18,10 @@ import { lowerBoard } from './board.js';
|
|
|
20
18
|
import { lowerRandom } from './random.js';
|
|
21
19
|
import { lowerDac } from './dac.js';
|
|
22
20
|
import { lowerFs } from './fs.js';
|
|
23
|
-
import {
|
|
24
|
-
|
|
21
|
+
import { lowerSensor } from './sensor.js';
|
|
22
|
+
import { lowerHwtimer, lowerCounter } from './hwtimer.js';
|
|
23
|
+
import { lowerThread } from './thread.js';
|
|
24
|
+
export { lowerGpio, lowerTiming, lowerAdc, lowerPwm, lowerI2c, lowerSpi, lowerUart, lowerUsb, lowerInterrupt, lowerWdt, lowerBle, lowerWifi, lowerHttp, lowerMqtt, lowerPreferences, lowerBoard, lowerRandom, lowerDac, lowerFs, lowerHwtimer, lowerCounter, lowerSensor, lowerThread, };
|
|
25
25
|
/**
|
|
26
26
|
* Lower a HAL op to Zephyr C++. Returns undefined for unsupported categories
|
|
27
27
|
* (mirrors lowerHalOp in framework-esp32/src/lowering/index.ts).
|
package/dist/lowering/index.js
CHANGED
|
@@ -23,13 +23,10 @@ import { lowerPwm } from './pwm.js';
|
|
|
23
23
|
import { lowerI2c } from './i2c.js';
|
|
24
24
|
import { lowerSpi } from './spi.js';
|
|
25
25
|
import { lowerUart } from './uart.js';
|
|
26
|
+
import { lowerUsb } from './usb.js';
|
|
26
27
|
import { lowerInterrupt } from './interrupts.js';
|
|
27
28
|
import { lowerWdt } from './wdt.js';
|
|
28
|
-
import { lowerPower } from './power.js';
|
|
29
|
-
import { lowerTone } from './tone.js';
|
|
30
|
-
import { lowerPulseOrShift } from './pulse.js';
|
|
31
29
|
import { lowerBle } from './ble.js';
|
|
32
|
-
import { lowerWorker } from './worker.js';
|
|
33
30
|
import { lowerWifi } from './wifi.js';
|
|
34
31
|
import { lowerHttp } from './http.js';
|
|
35
32
|
import { lowerMqtt } from './mqtt.js';
|
|
@@ -38,8 +35,10 @@ import { lowerBoard } from './board.js';
|
|
|
38
35
|
import { lowerRandom } from './random.js';
|
|
39
36
|
import { lowerDac } from './dac.js';
|
|
40
37
|
import { lowerFs } from './fs.js';
|
|
41
|
-
import {
|
|
42
|
-
|
|
38
|
+
import { lowerSensor } from './sensor.js';
|
|
39
|
+
import { lowerHwtimer, lowerCounter } from './hwtimer.js';
|
|
40
|
+
import { lowerThread } from './thread.js';
|
|
41
|
+
export { lowerGpio, lowerTiming, lowerAdc, lowerPwm, lowerI2c, lowerSpi, lowerUart, lowerUsb, lowerInterrupt, lowerWdt, lowerBle, lowerWifi, lowerHttp, lowerMqtt, lowerPreferences, lowerBoard, lowerRandom, lowerDac, lowerFs, lowerHwtimer, lowerCounter, lowerSensor, lowerThread, };
|
|
43
42
|
/**
|
|
44
43
|
* Lower a HAL op to Zephyr C++. Returns undefined for unsupported categories
|
|
45
44
|
* (mirrors lowerHalOp in framework-esp32/src/lowering/index.ts).
|
|
@@ -62,23 +61,19 @@ export function lowerHalOp(op) {
|
|
|
62
61
|
return lowerSpi(op, chip);
|
|
63
62
|
if (op.operation.startsWith('uart.'))
|
|
64
63
|
return lowerUart(op);
|
|
64
|
+
if (op.operation.startsWith('usb.'))
|
|
65
|
+
return lowerUsb(op, chip);
|
|
65
66
|
if (op.operation.startsWith('interrupt.'))
|
|
66
67
|
return lowerInterrupt(op, chip);
|
|
67
68
|
if (op.operation.startsWith('wdt.'))
|
|
68
|
-
return lowerWdt(op);
|
|
69
|
+
return lowerWdt(op, chip);
|
|
69
70
|
if (op.operation.startsWith('hwtimer.'))
|
|
70
71
|
return lowerHwtimer(op, chip);
|
|
71
|
-
if (op.operation.startsWith('
|
|
72
|
-
return
|
|
73
|
-
|
|
74
|
-
return lowerTone(op, chip);
|
|
75
|
-
// pulse.* and shift.* share a bit-bang lowering module.
|
|
76
|
-
if (op.operation.startsWith('pulse.') || op.operation.startsWith('shift.'))
|
|
77
|
-
return lowerPulseOrShift(op, chip);
|
|
72
|
+
if (op.operation.startsWith('counter.'))
|
|
73
|
+
return lowerCounter(op, chip);
|
|
74
|
+
// (legacy pulse/shift bit-bang module removed)
|
|
78
75
|
if (op.operation.startsWith('ble.'))
|
|
79
76
|
return lowerBle(op);
|
|
80
|
-
if (op.operation.startsWith('worker.'))
|
|
81
|
-
return lowerWorker(op);
|
|
82
77
|
if (op.operation.startsWith('wifi.'))
|
|
83
78
|
return lowerWifi(op);
|
|
84
79
|
if (op.operation.startsWith('http.'))
|
|
@@ -95,6 +90,10 @@ export function lowerHalOp(op) {
|
|
|
95
90
|
return lowerBoard(op);
|
|
96
91
|
if (op.operation.startsWith('random.'))
|
|
97
92
|
return lowerRandom(op);
|
|
93
|
+
if (op.operation.startsWith('sensor.'))
|
|
94
|
+
return lowerSensor(op);
|
|
95
|
+
if (op.operation.startsWith('thread.'))
|
|
96
|
+
return lowerThread(op);
|
|
98
97
|
// raw / snprintf.emit / display.* / ... — not lowered by this
|
|
99
98
|
// framework. Return undefined so the transpiler falls back and the manifest
|
|
100
99
|
// validator confirms the unsupported declaration.
|
|
@@ -1,19 +1,36 @@
|
|
|
1
1
|
import type { HALOpIR } from '@typecad/cuttlefish/api/shared';
|
|
2
2
|
import type { ZephyrChipDescriptor } from '../chips/types.js';
|
|
3
|
+
/** Map thin-GPIO INT token text to the GPIO_INT_* macro. */
|
|
4
|
+
export declare function gpioIntTokenToMacro(intFlags: string): string;
|
|
3
5
|
/**
|
|
4
6
|
* Emit the per-pin interrupt callback state + trampolines. Called from shimLines
|
|
5
7
|
* when the program uses interrupts. The trampoline calls a user function via a
|
|
6
8
|
* function-pointer static, set at attach time.
|
|
9
|
+
*
|
|
10
|
+
* Two paths:
|
|
11
|
+
* - descriptor `gpio.interruptPins` (buttons with DT specs): callback state
|
|
12
|
+
* against the DT spec, polarity-correct via gpio_*_dt.
|
|
13
|
+
* - `usedPins` (any other pin the program attaches to): raw-controller state —
|
|
14
|
+
* GPIO.onInterrupt() works on EVERY GPIO, not just DT-aliased buttons. Each
|
|
15
|
+
* such pin gets its own callback struct + trampoline addressed by the owning
|
|
16
|
+
* controller (STM32 splits gpioa/gpiob/gpioc) and port-relative bit.
|
|
17
|
+
*/
|
|
18
|
+
export declare function interruptInitLines(chip: ZephyrChipDescriptor, usedPins?: ReadonlySet<number>): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Collect the pin numbers the program attaches interrupts to (any GPIO — not
|
|
21
|
+
* just descriptor-listed buttons). Feeds interruptInitLines' raw-path state.
|
|
7
22
|
*/
|
|
8
|
-
export declare function
|
|
23
|
+
export declare function collectInterruptPins(program: unknown): Set<number>;
|
|
9
24
|
/**
|
|
10
25
|
* Resolve a HAL interrupt.* op to Zephyr C++.
|
|
11
26
|
* Returns `{ code }` for statement ops, `{ expression }` for value-returning ops.
|
|
12
27
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* the
|
|
28
|
+
* Two paths: pins listed in the descriptor's gpio.interruptPins (DT-aliased
|
|
29
|
+
* buttons) go through the polarity-correct gpio_*_dt chain; every other GPIO
|
|
30
|
+
* attaches through the raw-controller chain (any GPIO is interrupt-capable on
|
|
31
|
+
* the supported SoCs — the descriptor list exists for DT specs, not as a
|
|
32
|
+
* capability gate). The manifest probe's synthetic op keeps the comment
|
|
33
|
+
* fallback (no program ⇒ no shim state was emitted for the raw path).
|
|
17
34
|
*/
|
|
18
35
|
export declare function lowerInterrupt(op: HALOpIR, chip: ZephyrChipDescriptor): {
|
|
19
36
|
code?: string;
|
|
@@ -5,11 +5,13 @@
|
|
|
5
5
|
// `struct gpio_callback` per pin, registered with gpio_add_callback, with a
|
|
6
6
|
// trampoline that calls the user's C handler. The descriptor's gpio.interruptPins
|
|
7
7
|
// lists the pins with DT specs (buttons). The user's handler is a free C
|
|
8
|
-
// function; the trampoline calls it with no args
|
|
8
|
+
// function; the trampoline calls it with no args.
|
|
9
9
|
//
|
|
10
10
|
// Each interrupt pin gets a static callback struct + a trampoline in shimLines.
|
|
11
11
|
// attach enables + adds the callback; detach disables + removes it.
|
|
12
12
|
// ---------------------------------------------------------------------------
|
|
13
|
+
import { controllerNodelabelForPin, controllerRawPinForPin, controllerRangeForPin } from '../chips/controllers.js';
|
|
14
|
+
import { ZEPHYR_GPIO_INTS } from '@typecad/hal';
|
|
13
15
|
/** Look up an interrupt pin spec by HAL pin number. */
|
|
14
16
|
function findIntPin(chip, pin) {
|
|
15
17
|
return chip.gpio.interruptPins?.find((p) => p.pin === pin);
|
|
@@ -18,62 +20,142 @@ function findIntPin(chip, pin) {
|
|
|
18
20
|
function dtSpecVar(dtSpec) {
|
|
19
21
|
return `__tc_int_${dtSpec.replace(/-/g, '_')}`;
|
|
20
22
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
// ── Thin GPIO interrupts (hal/gpio-pin.ts onInterrupt) — INT_* tokens ─────
|
|
24
|
+
//
|
|
25
|
+
// The name set comes from the GENERATED Zephyr token table (parsed from the
|
|
26
|
+
// pinned tree's drivers/gpio.h).
|
|
27
|
+
const GPIO_INT_TOKENS = Object.fromEntries(ZEPHYR_GPIO_INTS.map((f) => [`GPIO.${f}`, `GPIO_${f}`]));
|
|
28
|
+
/** Map thin-GPIO INT token text to the GPIO_INT_* macro. */
|
|
29
|
+
export function gpioIntTokenToMacro(intFlags) {
|
|
30
|
+
const token = String(intFlags ?? '').trim();
|
|
31
|
+
const m = GPIO_INT_TOKENS[token];
|
|
32
|
+
if (!m) {
|
|
33
|
+
throw new Error(`GPIO interrupt flag '${token}' is not a known GPIO.INT_* token — valid: ${Object.keys(GPIO_INT_TOKENS).join(', ')}.`);
|
|
30
34
|
}
|
|
35
|
+
return m;
|
|
31
36
|
}
|
|
32
37
|
/**
|
|
33
38
|
* Emit the per-pin interrupt callback state + trampolines. Called from shimLines
|
|
34
39
|
* when the program uses interrupts. The trampoline calls a user function via a
|
|
35
40
|
* function-pointer static, set at attach time.
|
|
41
|
+
*
|
|
42
|
+
* Two paths:
|
|
43
|
+
* - descriptor `gpio.interruptPins` (buttons with DT specs): callback state
|
|
44
|
+
* against the DT spec, polarity-correct via gpio_*_dt.
|
|
45
|
+
* - `usedPins` (any other pin the program attaches to): raw-controller state —
|
|
46
|
+
* GPIO.onInterrupt() works on EVERY GPIO, not just DT-aliased buttons. Each
|
|
47
|
+
* such pin gets its own callback struct + trampoline addressed by the owning
|
|
48
|
+
* controller (STM32 splits gpioa/gpiob/gpioc) and port-relative bit.
|
|
36
49
|
*/
|
|
37
|
-
export function interruptInitLines(chip) {
|
|
50
|
+
export function interruptInitLines(chip, usedPins) {
|
|
38
51
|
const pins = chip.gpio.interruptPins ?? [];
|
|
39
|
-
if (pins.length === 0)
|
|
40
|
-
return [];
|
|
41
52
|
const lines = ['// CUTTLEFISH_INT_BEGIN'];
|
|
42
53
|
for (const pin of pins) {
|
|
43
54
|
const v = dtSpecVar(pin.dtSpec);
|
|
44
55
|
lines.push(`static const struct gpio_dt_spec ${v} = GPIO_DT_SPEC_GET(DT_ALIAS(${pin.dtSpec}), gpios);`, `static struct gpio_callback ${v}_cb;`, `static void (*${v}_handler)(void) = NULL;`, `static void ${v}_tramp(const struct device* port, struct gpio_callback* cb, gpio_port_pins_t pins_v) {`, ` (void)port; (void)cb; (void)pins_v;`, ` if (${v}_handler) { ${v}_handler(); }`, `}`);
|
|
45
56
|
}
|
|
57
|
+
if (usedPins) {
|
|
58
|
+
for (const pin of usedPins) {
|
|
59
|
+
if (pins.some((p) => p.pin === pin))
|
|
60
|
+
continue;
|
|
61
|
+
const v = `__tc_int_raw${pin}`;
|
|
62
|
+
lines.push(`static const struct device* ${v}_dev = DEVICE_DT_GET(DT_NODELABEL(${controllerNodelabelForPin(chip, pin)}));`, `static struct gpio_callback ${v}_cb;`, `static void (*${v}_handler)(void) = NULL;`, `static void ${v}_tramp(const struct device* port, struct gpio_callback* cb, gpio_port_pins_t pins_v) {`, ` (void)port; (void)cb; (void)pins_v;`, ` if (${v}_handler) { ${v}_handler(); }`, `}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
46
65
|
lines.push('// CUTTLEFISH_INT_END');
|
|
47
66
|
return lines;
|
|
48
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Collect the pin numbers the program attaches interrupts to (any GPIO — not
|
|
70
|
+
* just descriptor-listed buttons). Feeds interruptInitLines' raw-path state.
|
|
71
|
+
*/
|
|
72
|
+
export function collectInterruptPins(program) {
|
|
73
|
+
const pins = new Set();
|
|
74
|
+
const visit = (node) => {
|
|
75
|
+
if (!node || typeof node !== 'object')
|
|
76
|
+
return;
|
|
77
|
+
const n = node;
|
|
78
|
+
const op = n.operation;
|
|
79
|
+
if (op && typeof op === 'object') {
|
|
80
|
+
const o = op;
|
|
81
|
+
if (o.operation === 'interrupt.attach_flags' && typeof o.pin === 'number') {
|
|
82
|
+
pins.add(o.pin);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
for (const v of Object.values(n)) {
|
|
86
|
+
if (Array.isArray(v)) {
|
|
87
|
+
for (const item of v)
|
|
88
|
+
visit(item);
|
|
89
|
+
}
|
|
90
|
+
else if (v && typeof v === 'object')
|
|
91
|
+
visit(v);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
visit(program);
|
|
95
|
+
return pins;
|
|
96
|
+
}
|
|
49
97
|
/**
|
|
50
98
|
* Resolve a HAL interrupt.* op to Zephyr C++.
|
|
51
99
|
* Returns `{ code }` for statement ops, `{ expression }` for value-returning ops.
|
|
52
100
|
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* the
|
|
101
|
+
* Two paths: pins listed in the descriptor's gpio.interruptPins (DT-aliased
|
|
102
|
+
* buttons) go through the polarity-correct gpio_*_dt chain; every other GPIO
|
|
103
|
+
* attaches through the raw-controller chain (any GPIO is interrupt-capable on
|
|
104
|
+
* the supported SoCs — the descriptor list exists for DT specs, not as a
|
|
105
|
+
* capability gate). The manifest probe's synthetic op keeps the comment
|
|
106
|
+
* fallback (no program ⇒ no shim state was emitted for the raw path).
|
|
57
107
|
*/
|
|
58
108
|
export function lowerInterrupt(op, chip) {
|
|
59
109
|
const o = op;
|
|
60
110
|
const pin = findIntPin(chip, o.pin);
|
|
61
111
|
if (!pin) {
|
|
112
|
+
// Raw-controller path — state comes from interruptInitLines' usedPins.
|
|
113
|
+
// Only for pins a declared controller range covers: an out-of-range number
|
|
114
|
+
// (e.g. pin 99 on a 34-pin SoC) keeps the diagnostic comment. Single-
|
|
115
|
+
// controller chips declare no ranges, so every number is taken as real and
|
|
116
|
+
// the driver rejects invalid bits at runtime (Arduino-like behavior).
|
|
117
|
+
const knownPin = typeof o.pin === 'number' && Number.isInteger(o.pin)
|
|
118
|
+
&& (!chip.gpioControllers || chip.gpioControllers.length === 0
|
|
119
|
+
|| controllerRangeForPin(chip, o.pin) !== undefined);
|
|
120
|
+
if (knownPin) {
|
|
121
|
+
const v = `__tc_int_raw${o.pin}`;
|
|
122
|
+
const raw = controllerRawPinForPin(chip, o.pin);
|
|
123
|
+
if (op.operation === 'interrupt.attach_flags') {
|
|
124
|
+
// Thin GPIO: INT_* tokens instead of mode strings. The pin's
|
|
125
|
+
// input/pull configuration already came from the construction flags
|
|
126
|
+
// (the class emits gpio.configure ahead of this op) — no INPUT
|
|
127
|
+
// override here, unlike the legacy raw path above.
|
|
128
|
+
const flags = gpioIntTokenToMacro(o.intFlags);
|
|
129
|
+
return {
|
|
130
|
+
code: [
|
|
131
|
+
`${v}_handler = (${o.handler});`,
|
|
132
|
+
`gpio_init_callback(&${v}_cb, ${v}_tramp, BIT(${raw}));`,
|
|
133
|
+
`gpio_pin_interrupt_configure(${v}_dev, ${raw}, ${flags});`,
|
|
134
|
+
`gpio_add_callback(${v}_dev, &${v}_cb);`,
|
|
135
|
+
].join(' '),
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (op.operation === 'interrupt.detach') {
|
|
139
|
+
return {
|
|
140
|
+
code: `gpio_pin_interrupt_configure(${v}_dev, ${raw}, GPIO_INT_DISABLE); gpio_remove_callback(${v}_dev, &${v}_cb); ${v}_handler = NULL;`,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
}
|
|
62
144
|
// Fallback (also covers the manifest probe): a diagnostic comment so the
|
|
63
145
|
// resolver returns non-undefined. Real attach needs a descriptor entry.
|
|
64
|
-
if (op.operation === 'interrupt.
|
|
65
|
-
return { code: `/* interrupt.
|
|
146
|
+
if (op.operation === 'interrupt.attach_flags') {
|
|
147
|
+
return { code: `/* interrupt.attach_flags(pin ${o.pin}): no DT spec — add to chip descriptor gpio.interruptPins */` };
|
|
66
148
|
}
|
|
67
149
|
return { code: `/* interrupt.detach(pin ${o.pin}): no DT spec */` };
|
|
68
150
|
}
|
|
69
151
|
const v = dtSpecVar(pin.dtSpec);
|
|
70
152
|
switch (op.operation) {
|
|
71
|
-
case 'interrupt.
|
|
72
|
-
|
|
153
|
+
case 'interrupt.attach_flags': {
|
|
154
|
+
// Thin GPIO: INT_* tokens; construction flags already configured the pin.
|
|
155
|
+
const flags = gpioIntTokenToMacro(o.intFlags);
|
|
73
156
|
return {
|
|
74
157
|
code: [
|
|
75
158
|
`${v}_handler = (${o.handler});`,
|
|
76
|
-
`gpio_pin_configure_dt(&${v}, GPIO_INPUT);`,
|
|
77
159
|
`gpio_init_callback(&${v}_cb, ${v}_tramp, BIT(${v}.pin));`,
|
|
78
160
|
`gpio_pin_interrupt_configure_dt(&${v}, ${flags});`,
|
|
79
161
|
`gpio_add_callback(${v}.port, &${v}_cb);`,
|
package/dist/lowering/mqtt.js
CHANGED
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
//
|
|
4
4
|
// Zephyr's MQTT library is event-driven but has no internal task: the app
|
|
5
5
|
// must call mqtt_input() when the socket is readable and mqtt_live()
|
|
6
|
-
// periodically for keepalive. The generated firmware is
|
|
7
|
-
//
|
|
6
|
+
// periodically for keepalive. The generated firmware is main()-based and
|
|
7
|
+
// the user's main() is not ours to edit — so the connect shim spawns a
|
|
8
8
|
// dedicated k_thread that runs the poll loop (poll() → mqtt_input/mqtt_live)
|
|
9
9
|
// until disconnect. This mirrors a "managed client" model (like ESP-IDF's
|
|
10
|
-
// esp_mqtt internal task) and keeps the user's
|
|
10
|
+
// esp_mqtt internal task) and keeps the user's main() untouched.
|
|
11
11
|
//
|
|
12
12
|
// mqtt_connect() does no DNS — the broker is a resolved sockaddr — so the
|
|
13
13
|
// shim getaddrinfo-resolves the broker host itself (like the HTTP shim).
|
|
@@ -266,8 +266,6 @@ export function mqttInitLines() {
|
|
|
266
266
|
` (void)mqtt_abort(&__tc_mqtt.client);`,
|
|
267
267
|
` return;`,
|
|
268
268
|
` }`,
|
|
269
|
-
` printk("tc-mqtt: connecting to %s:%u\\n", __tc_mqtt.host,`,
|
|
270
|
-
` static_cast<unsigned int>(__tc_mqtt.port));`,
|
|
271
269
|
` // Drive input locally until CONNACK arrives (poll thread hasn't started).`,
|
|
272
270
|
` // mqtt_connect opened the socket; poll it for the connect-ack. Cap the wait`,
|
|
273
271
|
` // so a silent broker doesn't hang setup forever.`,
|
package/dist/lowering/power.js
CHANGED
|
@@ -28,10 +28,6 @@ export function lowerPower(op) {
|
|
|
28
28
|
// Best-effort: force a shallow suspend on the next idle. pm_state_force
|
|
29
29
|
// requires a pm_state_info; SUSPEND_TO_IDLE is a common shallow state.
|
|
30
30
|
return { code: `pm_state_force(0, &(const struct pm_state_info){ .state = PM_STATE_SUSPEND_TO_IDLE, .substate_id = 0 });` };
|
|
31
|
-
case 'power.set_cpu_frequency':
|
|
32
|
-
// nRF52 has a fixed 64 MHz HFXO; no portable dynamic scaling from C++.
|
|
33
|
-
// Documented no-op (best-effort), matching Arduino's approach.
|
|
34
|
-
return { code: `/* power.set_cpu_frequency(${o.mhz}): nRF52 fixed 64 MHz HFXO — no portable scaling */` };
|
|
35
31
|
case 'power.deep_sleep_pin': {
|
|
36
32
|
// Configure the pin as a GPIO wake source (level interrupt), then k_sleep
|
|
37
33
|
// until the interrupt fires. A static gpio_callback + a no-op handler (the
|