@typecad/hal 1.0.0-alpha.13 → 1.0.0-alpha.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. package/README.md +145 -87
  2. package/dist/adc-pin.d.ts +53 -0
  3. package/dist/adc-pin.js +69 -0
  4. package/dist/async.d.ts +3 -11
  5. package/dist/async.js +3 -15
  6. package/dist/ble.d.ts +42 -78
  7. package/dist/ble.js +79 -98
  8. package/dist/counter.d.ts +16 -0
  9. package/dist/counter.js +32 -0
  10. package/dist/dac-pin.d.ts +13 -0
  11. package/dist/dac-pin.js +21 -0
  12. package/dist/emit.d.ts +123 -196
  13. package/dist/emit.js +146 -208
  14. package/dist/fs.d.ts +12 -31
  15. package/dist/fs.js +30 -40
  16. package/dist/gpio-pin.d.ts +46 -0
  17. package/dist/gpio-pin.js +77 -0
  18. package/dist/gpio.d.ts +0 -103
  19. package/dist/gpio.js +16 -227
  20. package/dist/http.d.ts +38 -39
  21. package/dist/http.js +53 -78
  22. package/dist/i2c-target.d.ts +28 -0
  23. package/dist/i2c-target.js +52 -0
  24. package/dist/i2c.d.ts +5 -43
  25. package/dist/i2c.js +17 -130
  26. package/dist/index.d.ts +30 -42
  27. package/dist/index.js +27 -39
  28. package/dist/math.d.ts +0 -13
  29. package/dist/math.js +9 -13
  30. package/dist/mqtt.d.ts +15 -25
  31. package/dist/mqtt.js +32 -28
  32. package/dist/power.d.ts +9 -17
  33. package/dist/power.js +22 -20
  34. package/dist/preferences.d.ts +17 -25
  35. package/dist/preferences.js +54 -52
  36. package/dist/pulse.d.ts +4 -4
  37. package/dist/pulse.js +6 -2
  38. package/dist/pwm-pin.d.ts +24 -0
  39. package/dist/pwm-pin.js +38 -0
  40. package/dist/random.d.ts +0 -2
  41. package/dist/random.js +14 -20
  42. package/dist/sensor-catalog.generated.d.ts +997 -0
  43. package/dist/sensor-catalog.generated.js +764 -0
  44. package/dist/sensor.d.ts +46 -0
  45. package/dist/sensor.js +52 -0
  46. package/dist/shift-pin.d.ts +2 -0
  47. package/dist/shift-pin.js +13 -0
  48. package/dist/spi-target.d.ts +25 -0
  49. package/dist/spi-target.js +42 -0
  50. package/dist/spi.d.ts +8 -26
  51. package/dist/spi.js +15 -87
  52. package/dist/thread.d.ts +18 -0
  53. package/dist/thread.js +36 -0
  54. package/dist/time.d.ts +23 -0
  55. package/dist/time.js +43 -0
  56. package/dist/timing.d.ts +17 -7
  57. package/dist/timing.js +17 -7
  58. package/dist/types.d.ts +4 -34
  59. package/dist/types.js +5 -47
  60. package/dist/uart-port.d.ts +26 -0
  61. package/dist/uart-port.js +52 -0
  62. package/dist/uart.d.ts +0 -17
  63. package/dist/uart.js +10 -53
  64. package/dist/usb.d.ts +26 -0
  65. package/dist/usb.js +66 -0
  66. package/dist/watchdog.d.ts +12 -0
  67. package/dist/watchdog.js +28 -0
  68. package/dist/wifi.d.ts +88 -64
  69. package/dist/wifi.js +112 -126
  70. package/dist/zephyr-tokens.generated.d.ts +8 -0
  71. package/dist/zephyr-tokens.generated.js +73 -0
  72. package/package.json +7 -8
  73. package/src/adc-pin.ts +89 -0
  74. package/src/async.ts +3 -16
  75. package/src/ble.ts +84 -111
  76. package/src/counter.ts +40 -0
  77. package/src/dac-pin.ts +28 -0
  78. package/src/emit.ts +157 -238
  79. package/src/fs.ts +47 -54
  80. package/src/gpio-pin.ts +91 -0
  81. package/src/gpio.ts +49 -320
  82. package/src/http.ts +75 -95
  83. package/src/i2c-target.ts +63 -0
  84. package/src/i2c.ts +29 -167
  85. package/src/index.ts +32 -46
  86. package/src/math.ts +9 -14
  87. package/src/mqtt.ts +39 -31
  88. package/src/preferences.ts +52 -61
  89. package/src/pwm-pin.ts +54 -0
  90. package/src/random.ts +14 -21
  91. package/src/sensor-catalog.generated.ts +1238 -0
  92. package/src/sensor.ts +80 -0
  93. package/src/shift-pin.ts +16 -0
  94. package/src/spi-target.ts +53 -0
  95. package/src/spi.ts +27 -121
  96. package/src/thread.ts +44 -0
  97. package/src/time.ts +50 -0
  98. package/src/types.ts +14 -89
  99. package/src/uart-port.ts +64 -0
  100. package/src/usb.ts +82 -0
  101. package/src/watchdog.ts +35 -0
  102. package/src/wifi.ts +147 -179
  103. package/src/zephyr-tokens.generated.ts +77 -0
  104. package/src/adc.ts +0 -30
  105. package/src/capacitive.ts +0 -31
  106. package/src/constants.ts +0 -23
  107. package/src/dac.ts +0 -21
  108. package/src/eeprom.ts +0 -26
  109. package/src/interrupts.ts +0 -35
  110. package/src/mdns.ts +0 -50
  111. package/src/ota.ts +0 -44
  112. package/src/power.ts +0 -36
  113. package/src/pulse.ts +0 -63
  114. package/src/rmt.ts +0 -125
  115. package/src/shift.ts +0 -88
  116. package/src/temperature.ts +0 -20
  117. package/src/timer.ts +0 -58
  118. package/src/timing.ts +0 -67
  119. package/src/uart.ts +0 -77
  120. package/src/utils.ts +0 -17
  121. package/src/wdt.ts +0 -17
package/dist/wifi.js CHANGED
@@ -1,151 +1,137 @@
1
- import { wifiConnect, wifiConnectStart, wifiDisconnect, wifiStatus, wifiIsConnected, wifiLocalIp, wifiRssi, wifiMac, wifiSetHostname, wifiSetStaticIp, wifiSetAutoReconnect, wifiSetPowerSave, wifiSetTxPower, wifiOnEvent, wifiApStart, wifiApStop, wifiApClientCount, wifiApIp, wifiApSetChannel, wifiApSetHidden, wifiApSetMaxClients, wifiScan, wifiScanStart, wifiScanCount, wifiScanSsid, wifiScanRssi, wifiScanEncryption, wifiScanChannel, wifiSaveCredentials, wifiConnectSaved, wifiClearCredentials, wifiWaitConnected, wifiWaitDisconnected, } from './emit.js';
1
+ // ---------------------------------------------------------------------------
2
+ // WiFi — the thin Zephyr-shaped station/AP wrappers
3
+ //
4
+ // The link policy is CONSTRUCTION facts: credentials, security, band/channel,
5
+ // join timeout, power-save, and (optionally) static IPv4 all ride the join op
6
+ // (the sensor discipline — every op carries its construction facts). Methods
7
+ // lower 1:1 onto Zephyr's net_mgmt/wifi_mgmt surface:
8
+ //
9
+ // join() → wifi_connect_req_params from the facts + a bounded wait on
10
+ // the L4 connected flag (conn_mgr monitor raises it post-DHCP,
11
+ // or immediately when static IPv4 facts are configured).
12
+ // Returns boolean — no exceptions. Awaitable in async contexts
13
+ // (start + poll split, like Time.sleep).
14
+ // leave() → NET_REQUEST_WIFI_DISCONNECT
15
+ // linked() / rssi() / ip() / mac() → iface-status + net_if queries
16
+ // onUp() / onDrop() → the L4 / IPv4-addr net_mgmt event callbacks
17
+ // scan() → one blocking scan, results read through the Scan handle
18
+ // (fixed pool, no heap)
19
+ //
20
+ // WiFiAP carries the SoftAP facts (ssid/psk/channel) the same way:
21
+ // start()/stop() map to NET_REQUEST_WIFI_AP_ENABLE/DISABLE.
22
+ // ----------------------------------------------------------------------------
23
+ import { wifiJoin, wifiConnectStart, wifiDisconnect, wifiIsConnected, wifiLocalIp, wifiRssi, wifiMac, wifiOnEvent, wifiScan, wifiScanCount, wifiScanSsid, wifiScanRssi, wifiScanEncryption, wifiScanChannel, wifiApStart, wifiApStop, } from './emit.js';
2
24
  import { callback } from './callback.js';
3
- /** Normalized WiFi link status (mapped from esp_wifi events by the runtime shim). */
4
- export var WiFiStatus;
5
- (function (WiFiStatus) {
6
- WiFiStatus[WiFiStatus["Idle"] = 0] = "Idle";
7
- WiFiStatus[WiFiStatus["Connecting"] = 1] = "Connecting";
8
- WiFiStatus[WiFiStatus["Connected"] = 2] = "Connected";
9
- WiFiStatus[WiFiStatus["ConnectFailed"] = 3] = "ConnectFailed";
10
- WiFiStatus[WiFiStatus["Disconnected"] = 4] = "Disconnected";
11
- })(WiFiStatus || (WiFiStatus = {}));
12
- export var WiFiEncryption;
13
- (function (WiFiEncryption) {
14
- WiFiEncryption[WiFiEncryption["Open"] = 0] = "Open";
15
- WiFiEncryption[WiFiEncryption["WEP"] = 1] = "WEP";
16
- WiFiEncryption[WiFiEncryption["WPA"] = 2] = "WPA";
17
- WiFiEncryption[WiFiEncryption["WPA2"] = 3] = "WPA2";
18
- WiFiEncryption[WiFiEncryption["WPA3"] = 4] = "WPA3";
19
- WiFiEncryption[WiFiEncryption["Enterprise"] = 5] = "Enterprise";
20
- })(WiFiEncryption || (WiFiEncryption = {}));
21
- /**
22
- * WiFi radio / link control, lowered to native ESP-IDF (`esp_wifi` /
23
- * `esp_netif` / `esp_event` / `nvs_flash`) by framework-esp32.
24
- *
25
- * No `include()` calls here ESP-IDF headers are framework-owned and added
26
- * via forcedIncludes when the program uses wifi.* ops (the Preferences
27
- * lesson: HAL files must not carry platform headers). Frameworks without a
28
- * wifi lowering reject these ops with a diagnostic.
29
- */
30
- export class WiFiClass {
31
- /** Blocking at top level; cooperatively awaitable inside async functions. */
32
- connect(ssid, password, timeoutMs = 15000) {
33
- wifiConnect(ssid, password, timeoutMs);
34
- return Promise.resolve(false);
35
- }
36
- /** Fire-and-forget STA begin; poll status() / untilConnected(). */
37
- connectAsync(ssid, password) {
38
- wifiConnectStart(ssid, password);
39
- }
40
- untilConnected(timeoutMs = 15000) {
41
- wifiWaitConnected(timeoutMs);
42
- return Promise.resolve(false);
43
- }
44
- untilDisconnected() {
45
- wifiWaitDisconnected();
46
- return Promise.resolve();
47
- }
48
- disconnect() {
25
+ export class WiFi {
26
+ /** Construct a station link policy. `psk` omitted → open network;
27
+ * `security` defaults WPA2 when a psk is present, OPEN otherwise;
28
+ * `channel` 0/omitted = any. `ipv4` opts out of DHCP with static facts. */
29
+ constructor(ssid, opts = {}) {
30
+ this._ssid = ssid;
31
+ this._psk = opts.psk;
32
+ this._security = opts.security ?? (opts.psk !== undefined ? WiFi.WPA2 : WiFi.OPEN);
33
+ this._channel = opts.channel ?? 0;
34
+ this._band = opts.band ?? WiFi.BAND_2_4;
35
+ this._timeoutMs = opts.timeoutMs ?? 15000;
36
+ this._ps = opts.powerSave ?? 0;
37
+ this._ipAddr = opts.ipv4?.addr;
38
+ this._gateway = opts.ipv4?.gateway;
39
+ this._netmask = opts.ipv4?.netmask;
40
+ }
41
+ /** Join the network. Blocks (bounded by timeoutMs, pumping a mounted UI's
42
+ * tick between polls); returns true once IP connectivity is up, false on
43
+ * timeout or missing radio. Idempotent-ish: re-joining re-associates. */
44
+ join() {
45
+ return wifiJoin(this._ssid, this._psk, this._security, this._channel, this._band, this._timeoutMs, this._ps, this._ipAddr, this._gateway, this._netmask);
46
+ }
47
+ /** Fire-and-forget join — poll linked() or await in an async function. */
48
+ joinStart() {
49
+ wifiConnectStart(this._ssid, this._psk);
50
+ }
51
+ /** Leave the network (NET_REQUEST_WIFI_DISCONNECT). */
52
+ leave() {
49
53
  wifiDisconnect();
50
54
  }
51
- isConnected() {
55
+ /** True once IP connectivity is up (the L4 flag — post-DHCP, or after
56
+ * static IPv4 facts are applied). */
57
+ linked() {
52
58
  return wifiIsConnected();
53
59
  }
54
- status() {
55
- return wifiStatus();
56
- }
57
- localIP() {
58
- return wifiLocalIp();
59
- }
60
+ /** Signal strength in dBm (iface-status query). */
60
61
  rssi() {
61
62
  return wifiRssi();
62
63
  }
63
- macAddress() {
64
- return wifiMac();
65
- }
66
- hostname(name) {
67
- wifiSetHostname(name);
68
- return this;
69
- }
70
- staticIP(ip, gateway, subnet, dns) {
71
- wifiSetStaticIp(ip, gateway, subnet, dns);
72
- return this;
73
- }
74
- autoReconnect(enabled) {
75
- wifiSetAutoReconnect(enabled);
76
- return this;
77
- }
78
- powerSave(mode) {
79
- wifiSetPowerSave(mode);
80
- return this;
81
- }
82
- /** Cap TX power in dBm (roughly 2–20). Safe to call before connect() —
83
- * the value is applied after the radio starts. */
84
- txPower(dbm) {
85
- wifiSetTxPower(dbm);
86
- return this;
87
- }
88
- saveCredentials(ssid, password) {
89
- wifiSaveCredentials(ssid, password);
90
- }
91
- connectSaved(timeoutMs = 15000) {
92
- return wifiConnectSaved(timeoutMs);
93
- }
94
- clearCredentials() {
95
- wifiClearCredentials();
96
- }
97
- onConnect(handler) {
98
- wifiOnEvent("connect", callback(handler));
99
- }
100
- onDisconnect(handler) {
101
- wifiOnEvent("disconnect", callback(handler));
102
- }
103
- startAP(ssid, password) {
104
- return wifiApStart(ssid, password);
105
- }
106
- apChannel(ch) {
107
- wifiApSetChannel(ch);
108
- return this;
109
- }
110
- apHidden(hidden) {
111
- wifiApSetHidden(hidden);
112
- return this;
113
- }
114
- apMaxClients(n) {
115
- wifiApSetMaxClients(n);
116
- return this;
64
+ /** The interface's global IPv4 address as text ("0.0.0.0" when down). */
65
+ ip() {
66
+ return wifiLocalIp();
117
67
  }
118
- stopAP() {
119
- wifiApStop();
68
+ /** The radio's BSSID packed into a number (iface-status query). */
69
+ mac() {
70
+ return wifiMac();
120
71
  }
121
- apClientCount() {
122
- return wifiApClientCount();
72
+ /** Fires once DHCP (or static config) assigns an address. */
73
+ onUp(handler) {
74
+ wifiOnEvent('connect', callback(handler));
123
75
  }
124
- apIP() {
125
- return wifiApIp();
76
+ /** Fires on link loss (deferred off the net_mgmt event chain so the
77
+ * callback may safely call join()). */
78
+ onDrop(handler) {
79
+ wifiOnEvent('disconnect', callback(handler));
126
80
  }
81
+ /** One blocking scan; read the results through the returned handle.
82
+ * Fixed pool of 16 — no heap. */
127
83
  scan() {
128
- return wifiScan();
129
- }
130
- scanAsync() {
131
- wifiScanStart();
132
- return Promise.resolve();
84
+ wifiScan();
85
+ return new Scan();
133
86
  }
134
- scanCount() {
87
+ }
88
+ /** Security tokens — lowered to Zephyr's wifi_security_type enum. */
89
+ WiFi.OPEN = 0;
90
+ WiFi.WPA2 = 1;
91
+ WiFi.WPA3 = 2;
92
+ WiFi.WPA2_WPA3 = 3;
93
+ /** Band tokens. */
94
+ WiFi.BAND_2_4 = 0;
95
+ WiFi.BAND_5 = 1;
96
+ /** Power-save token — pass PS_OFF to disable the radio's modem sleep. */
97
+ WiFi.PS_OFF = 0;
98
+ /** Read-only view over the last scan's fixed result pool. */
99
+ export class Scan {
100
+ /** Number of networks found. */
101
+ count() {
135
102
  return wifiScanCount();
136
103
  }
137
- scanSSID(i) {
104
+ /** Network name ("" when out of range). */
105
+ ssid(i) {
138
106
  return wifiScanSsid(i);
139
107
  }
140
- scanRSSI(i) {
108
+ /** Signal strength in dBm. */
109
+ rssi(i) {
141
110
  return wifiScanRssi(i);
142
111
  }
143
- scanEncryption(i) {
112
+ /** Security family as text: "open" / "wpa" / "wpa2" / "wpa3". */
113
+ security(i) {
144
114
  return wifiScanEncryption(i);
145
115
  }
146
- scanChannel(i) {
116
+ /** Channel number (0 when unknown). */
117
+ channel(i) {
147
118
  return wifiScanChannel(i);
148
119
  }
149
120
  }
150
- WiFiClass.__instance_name = "WiFi";
151
- export const WiFi = new WiFiClass();
121
+ /** SoftAP — the AP facts at construction, then start/stop. */
122
+ export class WiFiAP {
123
+ /** Construct an AP. `psk` omitted → open network. `channel` 0 = auto. */
124
+ constructor(ssid, opts = {}) {
125
+ this._ssid = ssid;
126
+ this._psk = opts.psk;
127
+ this._channel = opts.channel ?? 0;
128
+ }
129
+ /** Bring the interface up as an AP (NET_REQUEST_WIFI_AP_ENABLE). */
130
+ start() {
131
+ wifiApStart(this._ssid, this._psk, this._channel);
132
+ }
133
+ /** Tear the AP down (NET_REQUEST_WIFI_AP_DISABLE). */
134
+ stop() {
135
+ wifiApStop();
136
+ }
137
+ }
@@ -0,0 +1,8 @@
1
+ /** enum adc_gain suffixes — ADC.GAIN_<name> ↔ ADC_GAIN_<name>. */
2
+ export declare const ZEPHYR_ADC_GAINS: readonly string[];
3
+ /** enum adc_reference suffixes — ADC.REF_<name> ↔ ADC_REF_<name>. */
4
+ export declare const ZEPHYR_ADC_REFERENCES: readonly string[];
5
+ /** GPIO config flag names — GPIO.<name> ↔ GPIO_<name>. */
6
+ export declare const ZEPHYR_GPIO_FLAGS: readonly string[];
7
+ /** GPIO interrupt configuration names — GPIO.INT_<name> ↔ GPIO_INT_<name>. */
8
+ export declare const ZEPHYR_GPIO_INTS: readonly string[];
@@ -0,0 +1,73 @@
1
+ // ---------------------------------------------------------------------------
2
+ // zephyr-tokens.generated.ts — the thin-HAL token name sets
3
+ //
4
+ // GENERATED FILE — do not edit by hand. Regenerate against the pinned
5
+ // workspace with:
6
+ //
7
+ // node scripts/gen-zephyr-hal-tokens.mjs <zephyr-base>
8
+ //
9
+ // Derived from Zephyr 4.4.2: enum adc_gain / enum adc_reference
10
+ // (include/zephyr/drivers/adc.h), the GPIO config flags (drivers/gpio.h +
11
+ // dt-bindings/gpio/gpio.h), and the GPIO_INT_* interrupt configurations
12
+ // (drivers/gpio.h). 21 gains, 7 references,
13
+ // 9 flags, 6 interrupt configs.
14
+ //
15
+ // The class statics stay hand-declared for editor typing; the token-sync
16
+ // test asserts they match these sets. The lowerings build their
17
+ // token→macro maps from these lists — names only; values never cross to C++.
18
+ // ---------------------------------------------------------------------------
19
+ /** enum adc_gain suffixes — ADC.GAIN_<name> ↔ ADC_GAIN_<name>. */
20
+ export const ZEPHYR_ADC_GAINS = [
21
+ '1_6',
22
+ '1_5',
23
+ '1_4',
24
+ '2_7',
25
+ '1_3',
26
+ '2_5',
27
+ '1_2',
28
+ '2_3',
29
+ '4_5',
30
+ '1',
31
+ '2',
32
+ '3',
33
+ '4',
34
+ '6',
35
+ '8',
36
+ '12',
37
+ '16',
38
+ '24',
39
+ '32',
40
+ '64',
41
+ '128',
42
+ ];
43
+ /** enum adc_reference suffixes — ADC.REF_<name> ↔ ADC_REF_<name>. */
44
+ export const ZEPHYR_ADC_REFERENCES = [
45
+ 'VDD_1',
46
+ 'VDD_1_2',
47
+ 'VDD_1_3',
48
+ 'VDD_1_4',
49
+ 'INTERNAL',
50
+ 'EXTERNAL0',
51
+ 'EXTERNAL1',
52
+ ];
53
+ /** GPIO config flag names — GPIO.<name> ↔ GPIO_<name>. */
54
+ export const ZEPHYR_GPIO_FLAGS = [
55
+ 'INPUT',
56
+ 'OUTPUT',
57
+ 'OUTPUT_INIT_LOW',
58
+ 'OUTPUT_INIT_HIGH',
59
+ 'PULL_UP',
60
+ 'PULL_DOWN',
61
+ 'OPEN_DRAIN',
62
+ 'OPEN_SOURCE',
63
+ 'DISCONNECTED',
64
+ ];
65
+ /** GPIO interrupt configuration names — GPIO.INT_<name> ↔ GPIO_INT_<name>. */
66
+ export const ZEPHYR_GPIO_INTS = [
67
+ 'INT_DISABLE',
68
+ 'INT_EDGE_RISING',
69
+ 'INT_EDGE_FALLING',
70
+ 'INT_EDGE_BOTH',
71
+ 'INT_LEVEL_LOW',
72
+ 'INT_LEVEL_HIGH',
73
+ ];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typecad/hal",
3
- "version": "1.0.0-alpha.13",
3
+ "version": "1.0.0-alpha.15",
4
4
  "description": "TypeCAD hardware abstraction layer — GPIO, I2C, SPI, UART as regular TypeScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -12,9 +12,10 @@
12
12
  "scripts": {
13
13
  "build": "tsc",
14
14
  "prepublishOnly": "npm run build",
15
- "test:hw": "npm exec -- cuttlefish-test",
16
- "test:hw:basics": "npm exec -- cuttlefish-test tests/01-gpio.test.ts",
17
- "test:hw:preferences": "npm exec -- cuttlefish-test tests/14-preferences.test.ts"
15
+ "test:hw": "npm exec -- cuttlefish-test --config boards/blackpill/cuttlefish.config.ts",
16
+ "test:hw:board": "npm exec -- cuttlefish-test",
17
+ "test:hw:wired": "npm exec -- cuttlefish-test --config boards/blackpill/cuttlefish.config.ts --include \"tests/wired/*.test.ts\"",
18
+ "test:hw:esp32s3": "npm exec -- cuttlefish-test --config boards/esp32s3/cuttlefish.config.ts"
18
19
  },
19
20
  "license": "MIT",
20
21
  "publishConfig": {
@@ -46,13 +47,11 @@
46
47
  "uart"
47
48
  ],
48
49
  "engines": {
49
- "node": ">=18"
50
+ "node": ">=22.11.0"
50
51
  },
51
52
  "author": "typecad0",
52
53
  "devDependencies": {
53
- "@typecad/expect": "1.0.0-alpha.13",
54
- "@typecad/board-arduino-uno": "1.0.0-alpha.13",
55
- "@typecad/mcu-atmega328p": "1.0.0-alpha.13"
54
+ "@typecad/expect": "1.0.0-alpha.15"
56
55
  },
57
56
  "sideEffects": false,
58
57
  "exports": {
package/src/adc-pin.ts ADDED
@@ -0,0 +1,89 @@
1
+ // ---------------------------------------------------------------------------
2
+ // ADC — the thin Zephyr-shaped analog input
3
+ //
4
+ // Construction IS the channel setup: gain and reference are constructor
5
+ // options (exactly struct adc_channel_cfg), defaulting to the chip
6
+ // descriptor's pair when omitted. read() returns raw counts at the chip's
7
+ // resolution; readMillivolts() applies adc_raw_to_millivolts. There is no
8
+ // setReference() — Zephyr applies the reference at channel-setup time, and
9
+ // this surface doesn't promise otherwise.
10
+ //
11
+ // Gain/reference tokens are Zephyr's enum names under the ADC
12
+ // namespace (ADC_GAIN_1_4 ↔ ADC.GAIN_1_4, ADC_REF_INTERNAL ↔
13
+ // ADC.REF_INTERNAL); the lowering maps token names to macros.
14
+ // ----------------------------------------------------------------------------
15
+
16
+ import { adcReadRaw, adcReadMv } from './emit.js';
17
+ import type { Pin } from './gpio.js';
18
+
19
+ export class ADC {
20
+ // ── Gain tokens (enum adc_gain, verbatim — generated set, see the
21
+ // token-sync test) ───────────────────────────────────────────────────
22
+ static readonly GAIN_1_6 = 0x01;
23
+ static readonly GAIN_1_5 = 0x02;
24
+ static readonly GAIN_1_4 = 0x03;
25
+ static readonly GAIN_2_7 = 0x04;
26
+ static readonly GAIN_1_3 = 0x05;
27
+ static readonly GAIN_2_5 = 0x06;
28
+ static readonly GAIN_1_2 = 0x07;
29
+ static readonly GAIN_2_3 = 0x08;
30
+ static readonly GAIN_4_5 = 0x09;
31
+ static readonly GAIN_1 = 0x0a;
32
+ static readonly GAIN_2 = 0x0b;
33
+ static readonly GAIN_3 = 0x0c;
34
+ static readonly GAIN_4 = 0x0d;
35
+ static readonly GAIN_6 = 0x0e;
36
+ static readonly GAIN_8 = 0x0f;
37
+ static readonly GAIN_12 = 0x10;
38
+ static readonly GAIN_16 = 0x11;
39
+ static readonly GAIN_24 = 0x12;
40
+ static readonly GAIN_32 = 0x13;
41
+ static readonly GAIN_64 = 0x14;
42
+ static readonly GAIN_128 = 0x15;
43
+
44
+ // ── Reference tokens (enum adc_reference, verbatim) ────────────────────
45
+ static readonly REF_VDD_1 = 0x100;
46
+ static readonly REF_VDD_1_2 = 0x101;
47
+ static readonly REF_VDD_1_3 = 0x102;
48
+ static readonly REF_VDD_1_4 = 0x103;
49
+ static readonly REF_INTERNAL = 0x104;
50
+ static readonly REF_EXTERNAL0 = 0x105;
51
+ static readonly REF_EXTERNAL1 = 0x106;
52
+
53
+ private readonly _pin: number;
54
+ private readonly _gain: number | string;
55
+ private readonly _reference: number | string;
56
+ // Routing overrides (the inline escape hatch): when the facts layer does
57
+ // not cover this pin, the construction carries the channel (and optional
58
+ // device label + pinctrl token) the lowering uses verbatim.
59
+ private readonly _channel: number;
60
+ private readonly _device: string;
61
+ private readonly _pinctrl: string;
62
+
63
+ /** Construct an analog input channel. Omitted gain/reference fall back to
64
+ * the chip descriptor's pair (the values the platform's driver validates
65
+ * against, e.g. STM32's ADC_GAIN_1 + ADC_REF_INTERNAL). */
66
+ constructor(
67
+ pin: number | Pin,
68
+ opts?: { gain?: number; reference?: number; channel?: number; device?: string; pinctrl?: string },
69
+ ) {
70
+ this._pin = typeof pin === 'number' ? pin : pin.number;
71
+ this._gain = opts?.gain ?? '';
72
+ this._reference = opts?.reference ?? '';
73
+ this._channel = opts?.channel ?? -1;
74
+ this._device = opts?.device ?? '';
75
+ this._pinctrl = opts?.pinctrl ?? '';
76
+ }
77
+
78
+ /** Read raw counts at the chip's resolution (adc_channel_setup on first
79
+ * use with the construction gain/reference, then adc_read). */
80
+ read(): number {
81
+ return adcReadRaw(this._pin, this._gain, this._reference, this._channel, this._device, this._pinctrl);
82
+ }
83
+
84
+ /** Read millivolts (adc_raw_to_millivolts against the descriptor's
85
+ * vref). Returns mV. */
86
+ readMillivolts(): number {
87
+ return adcReadMv(this._pin, this._gain, this._reference, this._channel, this._device, this._pinctrl);
88
+ }
89
+ }
package/src/async.ts CHANGED
@@ -4,7 +4,6 @@
4
4
  // Provides a platform-independent API for:
5
5
  // - sleep(ms) — non-blocking delay via Promise + microtask
6
6
  // - yield() — cooperative yield to other tasks
7
- // - sleepUntil(condition) — await a condition (promise-based)
8
7
  // - currentTask() — return a description of the currently executing task
9
8
  //
10
9
  // Framework packages (Arduino, Native, etc.) provide the C++ runtime behind
@@ -19,10 +18,9 @@ export class AsyncClass {
19
18
 
20
19
  /**
21
20
  * Non-blocking sleep for `ms` milliseconds.
22
- * Returns a Promise<void> that resolves after the given delay.
23
- * The underlying C++ implementation uses the platform's timer/microtask
24
- * mechanism (e.g. millis-based polling on Arduino, std::this_thread::sleep_for
25
- * on native, or a FreeRTOS vTaskDelay in the future).
21
+ * Returns a Promise<void> that resolves after the given delay. The async
22
+ * runtime resolves it cooperatively (the static state machine on
23
+ * heap-less targets polls the clock in the scheduler loop).
26
24
  */
27
25
  sleep(ms: number): Promise<void> {
28
26
  rawCpp(`__cuttlefish_async_sleep(${ms});`);
@@ -38,17 +36,6 @@ export class AsyncClass {
38
36
  return Promise.resolve();
39
37
  }
40
38
 
41
- /**
42
- * Await a polling condition.
43
- * Repeatedly checks `condition()` every `pollIntervalMs` milliseconds
44
- * until it returns true, then resolves.
45
- * The underlying implementation uses the platform's timer mechanism.
46
- */
47
- sleepUntil(condition: () => boolean, pollIntervalMs: number = 10): Promise<void> {
48
- rawCpp(`__cuttlefish_async_sleep_until(${pollIntervalMs});`);
49
- return Promise.resolve();
50
- }
51
-
52
39
  /**
53
40
  * Return a human-readable description of the currently executing async task.
54
41
  * Useful for debugging / logging in cooperative multitasking environments.