@typecad/hal 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 +145 -87
- package/dist/adc-pin.d.ts +53 -0
- package/dist/adc-pin.js +69 -0
- package/dist/async.d.ts +3 -11
- package/dist/async.js +3 -15
- package/dist/ble.d.ts +42 -78
- package/dist/ble.js +79 -98
- package/dist/counter.d.ts +16 -0
- package/dist/counter.js +32 -0
- package/dist/dac-pin.d.ts +13 -0
- package/dist/dac-pin.js +21 -0
- package/dist/emit.d.ts +123 -196
- package/dist/emit.js +146 -208
- package/dist/fs.d.ts +12 -31
- package/dist/fs.js +30 -40
- package/dist/gpio-pin.d.ts +46 -0
- package/dist/gpio-pin.js +77 -0
- package/dist/gpio.d.ts +0 -103
- package/dist/gpio.js +16 -227
- package/dist/http.d.ts +38 -39
- package/dist/http.js +53 -78
- package/dist/i2c-target.d.ts +28 -0
- package/dist/i2c-target.js +52 -0
- package/dist/i2c.d.ts +5 -43
- package/dist/i2c.js +17 -130
- package/dist/index.d.ts +30 -42
- package/dist/index.js +27 -39
- package/dist/math.d.ts +0 -13
- package/dist/math.js +9 -13
- package/dist/mqtt.d.ts +15 -25
- package/dist/mqtt.js +32 -28
- package/dist/power.d.ts +9 -17
- package/dist/power.js +22 -20
- package/dist/preferences.d.ts +17 -25
- package/dist/preferences.js +54 -52
- package/dist/pulse.d.ts +4 -4
- package/dist/pulse.js +6 -2
- package/dist/pwm-pin.d.ts +24 -0
- package/dist/pwm-pin.js +38 -0
- package/dist/random.d.ts +0 -2
- package/dist/random.js +14 -20
- package/dist/sensor-catalog.generated.d.ts +997 -0
- package/dist/sensor-catalog.generated.js +764 -0
- package/dist/sensor.d.ts +46 -0
- package/dist/sensor.js +52 -0
- package/dist/shift-pin.d.ts +2 -0
- package/dist/shift-pin.js +13 -0
- package/dist/spi-target.d.ts +25 -0
- package/dist/spi-target.js +42 -0
- package/dist/spi.d.ts +8 -26
- package/dist/spi.js +15 -87
- package/dist/thread.d.ts +18 -0
- package/dist/thread.js +36 -0
- package/dist/time.d.ts +23 -0
- package/dist/time.js +43 -0
- package/dist/timing.d.ts +17 -7
- package/dist/timing.js +17 -7
- package/dist/types.d.ts +4 -34
- package/dist/types.js +5 -47
- package/dist/uart-port.d.ts +26 -0
- package/dist/uart-port.js +52 -0
- package/dist/uart.d.ts +0 -17
- package/dist/uart.js +10 -53
- package/dist/usb.d.ts +26 -0
- package/dist/usb.js +66 -0
- package/dist/watchdog.d.ts +12 -0
- package/dist/watchdog.js +28 -0
- package/dist/wifi.d.ts +88 -64
- package/dist/wifi.js +112 -126
- package/dist/zephyr-tokens.generated.d.ts +8 -0
- package/dist/zephyr-tokens.generated.js +73 -0
- package/package.json +6 -7
- package/src/adc-pin.ts +89 -0
- package/src/async.ts +3 -16
- package/src/ble.ts +84 -111
- package/src/counter.ts +40 -0
- package/src/dac-pin.ts +28 -0
- package/src/emit.ts +157 -238
- package/src/fs.ts +47 -54
- package/src/gpio-pin.ts +91 -0
- package/src/gpio.ts +49 -320
- package/src/http.ts +75 -95
- package/src/i2c-target.ts +63 -0
- package/src/i2c.ts +29 -167
- package/src/index.ts +32 -46
- package/src/math.ts +9 -14
- package/src/mqtt.ts +39 -31
- package/src/preferences.ts +52 -61
- package/src/pwm-pin.ts +54 -0
- package/src/random.ts +14 -21
- package/src/sensor-catalog.generated.ts +1238 -0
- package/src/sensor.ts +80 -0
- package/src/shift-pin.ts +16 -0
- package/src/spi-target.ts +53 -0
- package/src/spi.ts +27 -121
- package/src/thread.ts +44 -0
- package/src/time.ts +50 -0
- package/src/types.ts +14 -89
- package/src/uart-port.ts +64 -0
- package/src/usb.ts +82 -0
- package/src/watchdog.ts +35 -0
- package/src/wifi.ts +147 -179
- package/src/zephyr-tokens.generated.ts +77 -0
- package/src/adc.ts +0 -30
- package/src/capacitive.ts +0 -31
- package/src/constants.ts +0 -23
- package/src/dac.ts +0 -21
- package/src/eeprom.ts +0 -26
- package/src/interrupts.ts +0 -35
- package/src/mdns.ts +0 -50
- package/src/ota.ts +0 -44
- package/src/power.ts +0 -36
- package/src/pulse.ts +0 -63
- package/src/rmt.ts +0 -125
- package/src/shift.ts +0 -88
- package/src/temperature.ts +0 -20
- package/src/timer.ts +0 -58
- package/src/timing.ts +0 -67
- package/src/uart.ts +0 -77
- package/src/utils.ts +0 -17
- package/src/wdt.ts +0 -17
package/README.md
CHANGED
|
@@ -1,127 +1,185 @@
|
|
|
1
1
|
# `@typecad/hal`
|
|
2
2
|
|
|
3
3
|
Hardware abstraction layer for [TypeCAD](https://cuttlefish.typecad.net) —
|
|
4
|
-
GPIO,
|
|
5
|
-
regular TypeScript.
|
|
4
|
+
GPIO, timing, threads, PWM/ADC/DAC, I2C/SPI/UART/USB, persistent storage,
|
|
5
|
+
sensors, and WiFi/HTTP/MQTT/BLE, written as regular TypeScript.
|
|
6
6
|
|
|
7
7
|
`@typecad/hal` is what firmware code imports to talk to hardware. You write
|
|
8
|
-
normal TypeScript (`
|
|
9
|
-
|
|
10
|
-
active
|
|
8
|
+
normal TypeScript (`led.toggle()`, `bus.writeReg(...)`, `Time.sleep(250)`);
|
|
9
|
+
the transpiler (`@typecad/cuttlefish`) resolves each HAL call against the
|
|
10
|
+
active board's facts and emits the equivalent C++ at build time. There are
|
|
11
|
+
no runtime fallbacks — if the HAL doesn't lower it, it doesn't appear in the
|
|
12
|
+
firmware.
|
|
11
13
|
|
|
12
14
|
## Install
|
|
13
15
|
|
|
16
|
+
HAL projects are scaffolded by cuttlefish, which wires the framework,
|
|
17
|
+
board target, and the Zephyr SDK for you:
|
|
18
|
+
|
|
14
19
|
```bash
|
|
15
|
-
|
|
20
|
+
npx @typecad/cuttlefish create my-firmware
|
|
21
|
+
cd my-firmware && npx cuttlefish build --compile
|
|
16
22
|
```
|
|
17
23
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
TypeScript but are intercepted by the transpiler:
|
|
25
|
-
|
|
26
|
-
- **`emit(text)`** — appends a line of C++ to the output (with parameter/field substitution).
|
|
27
|
-
- **`include(header)`** — adds a deduplicated `#include` to the output.
|
|
28
|
-
- **`board(path)`** — looks up a board-specific constant (e.g. pin numbers) inside an `emit()` template.
|
|
29
|
-
|
|
30
|
-
This means there are no runtime fallbacks: if the HAL doesn't `emit()` it, it
|
|
31
|
-
doesn't appear in the firmware. See [`HAL-GUIDE.md`](./HAL-GUIDE.md) for how to
|
|
32
|
-
add new HAL features.
|
|
24
|
+
A project imports hardware from **`@typecad/board`** — the module cuttlefish
|
|
25
|
+
generates per project from the Zephyr board catalog. That module is the
|
|
26
|
+
narrowed gateway: it re-exports a hardware class only when this board's
|
|
27
|
+
facts support it, so importing unavailable hardware fails at module
|
|
28
|
+
resolution (editor and transpile), not at a deep diagnostic. `@typecad/hal`
|
|
29
|
+
is the implementation package.
|
|
33
30
|
|
|
34
31
|
## What's included
|
|
35
32
|
|
|
33
|
+
Every class is thin and Zephyr-shaped: construction carries the facts, and
|
|
34
|
+
each method maps onto the kernel/driver API verbatim — no Arduino
|
|
35
|
+
vocabulary, no transaction dance.
|
|
36
|
+
|
|
36
37
|
| Area | Exports |
|
|
37
38
|
| --- | --- |
|
|
38
|
-
| **Digital I/O** | `Pin
|
|
39
|
-
| **
|
|
40
|
-
| **
|
|
41
|
-
| **
|
|
42
|
-
| **
|
|
43
|
-
| **
|
|
44
|
-
| **
|
|
45
|
-
| **
|
|
46
|
-
| **
|
|
47
|
-
| **
|
|
48
|
-
| **
|
|
49
|
-
| **
|
|
50
|
-
| **
|
|
51
|
-
| **
|
|
52
|
-
| **
|
|
53
|
-
| **
|
|
39
|
+
| **Digital I/O** | `Pin` (identity), `GPIO` (configure/read/write/toggle, `onInterrupt`/`offInterrupt`), `shiftOut`/`shiftIn` |
|
|
40
|
+
| **Timing** | `Time` (`sleep`/`now`/`nowUs`/`busyWaitUs`) |
|
|
41
|
+
| **Concurrency** | `Thread` (kernel threads), `Async` (cooperative await), `Counter` (hardware timers) |
|
|
42
|
+
| **PWM** | `PWM` (`setPulse`/`setDuty`/`setPeriod`; ns-true verbs) |
|
|
43
|
+
| **Analog in** | `ADC` (`read`/`readMillivolts`, gain/reference tokens; every ADC controller the SoC declares) |
|
|
44
|
+
| **Analog out** | `DAC` (`write`) |
|
|
45
|
+
| **I2C** | `I2CTarget` (register verbs; also the Sensor fact-carrier), `I2CBus` (controller selector: `I2C0.device(0x44)` returns a ready target) |
|
|
46
|
+
| **SPI** | `SPITarget` (transceive/register verbs), `SPIBus` (controller selector: `SPI0.device(PA4)` returns a ready target) |
|
|
47
|
+
| **UART** | `UART` (writeLine/read ring) — the board exports ready-to-use instances (`UART0.writeLine(...)`) |
|
|
48
|
+
| **USB** | `USBConsole` (CDC console: open/write/read/linked) |
|
|
49
|
+
| **Storage** | `Store` (persistent typed keys), `File` (littlefs text files) |
|
|
50
|
+
| **Watchdog** | `Watchdog` |
|
|
51
|
+
| **Sensors** | `Sensor` + the generated `SENSOR`/`CHAN` catalog |
|
|
52
|
+
| **Networking** | `WiFi`, `Request` (HTTP), `Mqtt`, `BLE` (GATT peripheral) |
|
|
53
|
+
| **Math / Random** | `abs`/`min`/`max`/`Num`, `Random` (`seed`/`upTo`/`between`/`int`) |
|
|
54
|
+
| **Registers** | `@register`/`@bits` (memory-mapped struct decorators) |
|
|
55
|
+
| **Zephyr tokens** | `ZEPHYR_ADC_GAINS`, `ZEPHYR_ADC_REFERENCES`, `ZEPHYR_GPIO_FLAGS`, `ZEPHYR_GPIO_INTS` (generated from the pinned tree's headers) |
|
|
56
|
+
|
|
57
|
+
Periodic and deferred work is a `Thread` (or a `Counter` for hardware
|
|
58
|
+
timers) — there are no JS-named timers (`setInterval`/`setTimeout`) on
|
|
59
|
+
embedded targets.
|
|
60
|
+
|
|
61
|
+
## Compile-time directives
|
|
62
|
+
|
|
63
|
+
Directives look like ordinary TypeScript but are intercepted by the
|
|
64
|
+
transpiler:
|
|
65
|
+
|
|
66
|
+
- **`rawCpp(text)`** — appends a line of C++ to the output (with field/parameter substitution).
|
|
67
|
+
- **`rawCppExpr(text)`** — the same, in expression position.
|
|
68
|
+
- **`include(header)`** — adds a deduplicated `#include` to the output.
|
|
69
|
+
- **`board(path)`** — resolves a board-fact constant inside a template.
|
|
70
|
+
|
|
71
|
+
`callback(fn)` registers a function value so it can be passed to APIs that
|
|
72
|
+
take handlers (interrupts, threads, bus events). See
|
|
73
|
+
[`HAL-GUIDE.md`](./HAL-GUIDE.md) for how HAL features are built.
|
|
54
74
|
|
|
55
75
|
## Example
|
|
56
76
|
|
|
57
77
|
```ts
|
|
58
|
-
import {
|
|
78
|
+
import { LED } from '@typecad/board';
|
|
79
|
+
import { GPIO, Time, Thread } from '@typecad/hal';
|
|
80
|
+
|
|
81
|
+
const led = new GPIO(LED, GPIO.OUTPUT);
|
|
82
|
+
|
|
83
|
+
// A kernel thread blinks concurrently with main.
|
|
84
|
+
const blinker = new Thread(0, { stackKb: 2 });
|
|
85
|
+
blinker.start((): void => {
|
|
86
|
+
while (true) {
|
|
87
|
+
led.toggle();
|
|
88
|
+
Time.sleep(250);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
blinker.join();
|
|
92
|
+
```
|
|
59
93
|
|
|
60
|
-
|
|
94
|
+
Bus singletons from `@typecad/board` are directly usable — the board
|
|
95
|
+
exports functional instances (no strings, no construction, and unavailable
|
|
96
|
+
buses are simply not exported):
|
|
61
97
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
}
|
|
98
|
+
```ts
|
|
99
|
+
import { UART0 } from '@typecad/board';
|
|
65
100
|
|
|
66
|
-
|
|
67
|
-
led.write(HIGH);
|
|
68
|
-
delay(500);
|
|
69
|
-
led.write(LOW);
|
|
70
|
-
delay(500);
|
|
71
|
-
}
|
|
101
|
+
UART0.writeLine('hello'); // usart1, default 115200
|
|
72
102
|
```
|
|
73
103
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
## Hardware tests
|
|
104
|
+
Explicit construction remains for non-default facts, and takes the board
|
|
105
|
+
instance or the name; targets and sensors carry the bus instance and the
|
|
106
|
+
7-bit address / chip-select from construction:
|
|
78
107
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
using [`@typecad/expect`](https://cuttlefish.typecad.net)
|
|
82
|
-
(`describe()` / `.it()` / `.expect()` / `done()`) over serial. Each file covers
|
|
83
|
-
one subsystem: GPIO, timing, math, random, pulse, shift, interrupts, UART,
|
|
84
|
-
I2C, SPI, ADC, EEPROM, WDT, Preferences, async, and constants.
|
|
108
|
+
```ts
|
|
109
|
+
import { I2C0, SENSOR, CHAN } from '@typecad/board';
|
|
85
110
|
|
|
86
|
-
|
|
87
|
-
|
|
111
|
+
// device() hands back the FUNCTIONAL target — verbs callable immediately,
|
|
112
|
+
// and the same object is the Sensor fact-carrier.
|
|
113
|
+
const dev = I2C0.device(0x44);
|
|
114
|
+
dev.writeReg(0x30, 0xA2); // i2c_reg_write_byte
|
|
88
115
|
|
|
89
|
-
|
|
116
|
+
const sht3x = new Sensor(SENSOR.sensirion_sht3xd, I2C0.device(0x44));
|
|
117
|
+
sht3x.fetch();
|
|
118
|
+
const temp = sht3x.get(CHAN.AMBIENT_TEMP);
|
|
90
119
|
|
|
91
|
-
|
|
92
|
-
npm exec --workspace @typecad/hal -- cuttlefish-test
|
|
120
|
+
// Explicit construction is equivalent: new I2CTarget(I2C0, 0x44).
|
|
93
121
|
```
|
|
94
122
|
|
|
95
|
-
|
|
96
|
-
Like the [`@typecad/framework-arduino`](https://cuttlefish.typecad.net)
|
|
97
|
-
tests, it imports through `@typecad/board` (the board package) and ambient globals
|
|
98
|
-
declared in `cuttlefish-env.d.ts`, never directly from `@typecad/board`, so the
|
|
99
|
-
transpiler resolves each call against the active MCU/board packages.
|
|
100
|
-
|
|
101
|
-
### Skipped on AVR
|
|
102
|
-
|
|
103
|
-
One file is skipped on AVR by a `@typecad-skip-target` directive, for a
|
|
104
|
-
genuine hardware reason (not a transpiler limitation):
|
|
123
|
+
## Hardware tests
|
|
105
124
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
125
|
+
The [`tests/`](./tests/) directory is the HAL hardware suite — the on-metal
|
|
126
|
+
proof that the HAL works. It runs via
|
|
127
|
+
[`@typecad/expect`](../expect/README.md) (`describe()` / `.it()` /
|
|
128
|
+
`.expect()` / `done()`) over the board's console, and one shared suite
|
|
129
|
+
covers every board:
|
|
130
|
+
|
|
131
|
+
- **`tests/common/`** — board-agnostic groups, one file per subsystem:
|
|
132
|
+
timing, math, random, shift, interrupts, UART, I2C, ADC, WDT, Store,
|
|
133
|
+
File, async, constants, Counter.
|
|
134
|
+
- **`tests/board/`** — board-level groups (GPIO, PWM, SPI, LED). These
|
|
135
|
+
import **role names** from the `@typecad/test-pins` virtual module
|
|
136
|
+
(`GPIO_OUT`, `PWM_PIN`, `ADC_PIN`, `I2C_BUS`, …); each board's
|
|
137
|
+
`boards/<name>/test-pins.json` declares which pins fill each role, and the
|
|
138
|
+
runner substitutes them before transpiling. A file whose required roles
|
|
139
|
+
(declared with `// @typecad-requires-roles …`) are absent skips cleanly —
|
|
140
|
+
coverage differences are data, never per-board test copies.
|
|
141
|
+
- **`tests/network/`** — on-hardware HTTP/MQTT/BLE suites against a local
|
|
142
|
+
host server (see [`tests/network/README.md`](./tests/network/README.md)).
|
|
143
|
+
- **`tests/wired/`** — opt-in loopback tier (jumper `gpioOut` → `gpioIn`);
|
|
144
|
+
not part of the default runs.
|
|
145
|
+
|
|
146
|
+
Each board has a config in [`boards/`](./boards/) (currently the WeAct
|
|
147
|
+
Black Pill STM32F411 and the ESP32-S3 DevKitC). Run a suite:
|
|
109
148
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
ATmega328P.
|
|
149
|
+
```bash
|
|
150
|
+
npm run test:hw --workspace @typecad/hal # Black Pill (ST-Link + console UART)
|
|
151
|
+
npm run test:hw:esp32s3 --workspace @typecad/hal # DevKitC (esptool + CH34x console)
|
|
152
|
+
```
|
|
115
153
|
|
|
116
|
-
|
|
117
|
-
|
|
154
|
+
The `[TC:...]` test protocol rides the board's console (its devicetree
|
|
155
|
+
`zephyr,console` node). Port resolution: `--port` / `CUTTLEFISH_PORT` wins,
|
|
156
|
+
then `test.port` in the board's config, then USB-identity discovery
|
|
157
|
+
(`test-pins.json` carries `usb: { vid, pid }` — e.g. the DevKitC's CH34x
|
|
158
|
+
bridge `1A86:55D3`), and the port re-resolves after every flash
|
|
159
|
+
re-enumeration. A program that also constructs `USB0` composes a CDC device
|
|
160
|
+
enumerating at the shared Zephyr-test identity `2FE3:0001`.
|
|
161
|
+
|
|
162
|
+
### Board parity and documented hardware limits
|
|
163
|
+
|
|
164
|
+
Every board runs every group its silicon supports. Gaps are hard hardware
|
|
165
|
+
limits expressed as role skips: the ESP32-S3 DevKitC declares no I2C
|
|
166
|
+
controller and no `led0` node (and its UART0 is the protocol channel), so
|
|
167
|
+
those groups skip there by role. Everything else — GPIO, PWM, ADC (both
|
|
168
|
+
SARADC units), SPI, timing, math, random, shift, interrupts, WDT, Store,
|
|
169
|
+
File, async, constants, Counter — runs on both boards.
|
|
170
|
+
|
|
171
|
+
`Sensor` and `DAC` have a full pipeline (catalog → devicetree
|
|
172
|
+
synthesis → Zephyr driver API) but no sensor or DAC-capable board on the
|
|
173
|
+
current rig, so they are compile-verified only until one is attached. The
|
|
174
|
+
network tier needs the host server (`npm run test:http`) and credentials in
|
|
175
|
+
`tests/network/secrets.ts`.
|
|
118
176
|
|
|
119
177
|
## Ecosystem
|
|
120
178
|
|
|
121
|
-
- [`@typecad/cuttlefish`](
|
|
122
|
-
- [`@typecad/
|
|
123
|
-
- `@typecad/
|
|
124
|
-
- `@typecad/
|
|
179
|
+
- [`@typecad/cuttlefish`](../../README.md) — the transpiler that resolves HAL calls to C++.
|
|
180
|
+
- [`@typecad/framework-zephyr`](../framework-zephyr/README.md) — the Zephyr lowering, board catalog, and toolchain.
|
|
181
|
+
- [`@typecad/expect`](../expect/README.md) — the on-hardware test framework.
|
|
182
|
+
- [`@typecad/ui`](../ui/README.md) — HTML/CSS-driven display graphics.
|
|
125
183
|
|
|
126
184
|
## License
|
|
127
185
|
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Pin } from './gpio.js';
|
|
2
|
+
export declare class ADC {
|
|
3
|
+
static readonly GAIN_1_6 = 1;
|
|
4
|
+
static readonly GAIN_1_5 = 2;
|
|
5
|
+
static readonly GAIN_1_4 = 3;
|
|
6
|
+
static readonly GAIN_2_7 = 4;
|
|
7
|
+
static readonly GAIN_1_3 = 5;
|
|
8
|
+
static readonly GAIN_2_5 = 6;
|
|
9
|
+
static readonly GAIN_1_2 = 7;
|
|
10
|
+
static readonly GAIN_2_3 = 8;
|
|
11
|
+
static readonly GAIN_4_5 = 9;
|
|
12
|
+
static readonly GAIN_1 = 10;
|
|
13
|
+
static readonly GAIN_2 = 11;
|
|
14
|
+
static readonly GAIN_3 = 12;
|
|
15
|
+
static readonly GAIN_4 = 13;
|
|
16
|
+
static readonly GAIN_6 = 14;
|
|
17
|
+
static readonly GAIN_8 = 15;
|
|
18
|
+
static readonly GAIN_12 = 16;
|
|
19
|
+
static readonly GAIN_16 = 17;
|
|
20
|
+
static readonly GAIN_24 = 18;
|
|
21
|
+
static readonly GAIN_32 = 19;
|
|
22
|
+
static readonly GAIN_64 = 20;
|
|
23
|
+
static readonly GAIN_128 = 21;
|
|
24
|
+
static readonly REF_VDD_1 = 256;
|
|
25
|
+
static readonly REF_VDD_1_2 = 257;
|
|
26
|
+
static readonly REF_VDD_1_3 = 258;
|
|
27
|
+
static readonly REF_VDD_1_4 = 259;
|
|
28
|
+
static readonly REF_INTERNAL = 260;
|
|
29
|
+
static readonly REF_EXTERNAL0 = 261;
|
|
30
|
+
static readonly REF_EXTERNAL1 = 262;
|
|
31
|
+
private readonly _pin;
|
|
32
|
+
private readonly _gain;
|
|
33
|
+
private readonly _reference;
|
|
34
|
+
private readonly _channel;
|
|
35
|
+
private readonly _device;
|
|
36
|
+
private readonly _pinctrl;
|
|
37
|
+
/** Construct an analog input channel. Omitted gain/reference fall back to
|
|
38
|
+
* the chip descriptor's pair (the values the platform's driver validates
|
|
39
|
+
* against, e.g. STM32's ADC_GAIN_1 + ADC_REF_INTERNAL). */
|
|
40
|
+
constructor(pin: number | Pin, opts?: {
|
|
41
|
+
gain?: number;
|
|
42
|
+
reference?: number;
|
|
43
|
+
channel?: number;
|
|
44
|
+
device?: string;
|
|
45
|
+
pinctrl?: string;
|
|
46
|
+
});
|
|
47
|
+
/** Read raw counts at the chip's resolution (adc_channel_setup on first
|
|
48
|
+
* use with the construction gain/reference, then adc_read). */
|
|
49
|
+
read(): number;
|
|
50
|
+
/** Read millivolts (adc_raw_to_millivolts against the descriptor's
|
|
51
|
+
* vref). Returns mV. */
|
|
52
|
+
readMillivolts(): number;
|
|
53
|
+
}
|
package/dist/adc-pin.js
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
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
|
+
import { adcReadRaw, adcReadMv } from './emit.js';
|
|
16
|
+
export class ADC {
|
|
17
|
+
/** Construct an analog input channel. Omitted gain/reference fall back to
|
|
18
|
+
* the chip descriptor's pair (the values the platform's driver validates
|
|
19
|
+
* against, e.g. STM32's ADC_GAIN_1 + ADC_REF_INTERNAL). */
|
|
20
|
+
constructor(pin, opts) {
|
|
21
|
+
this._pin = typeof pin === 'number' ? pin : pin.number;
|
|
22
|
+
this._gain = opts?.gain ?? '';
|
|
23
|
+
this._reference = opts?.reference ?? '';
|
|
24
|
+
this._channel = opts?.channel ?? -1;
|
|
25
|
+
this._device = opts?.device ?? '';
|
|
26
|
+
this._pinctrl = opts?.pinctrl ?? '';
|
|
27
|
+
}
|
|
28
|
+
/** Read raw counts at the chip's resolution (adc_channel_setup on first
|
|
29
|
+
* use with the construction gain/reference, then adc_read). */
|
|
30
|
+
read() {
|
|
31
|
+
return adcReadRaw(this._pin, this._gain, this._reference, this._channel, this._device, this._pinctrl);
|
|
32
|
+
}
|
|
33
|
+
/** Read millivolts (adc_raw_to_millivolts against the descriptor's
|
|
34
|
+
* vref). Returns mV. */
|
|
35
|
+
readMillivolts() {
|
|
36
|
+
return adcReadMv(this._pin, this._gain, this._reference, this._channel, this._device, this._pinctrl);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// ── Gain tokens (enum adc_gain, verbatim — generated set, see the
|
|
40
|
+
// token-sync test) ───────────────────────────────────────────────────
|
|
41
|
+
ADC.GAIN_1_6 = 0x01;
|
|
42
|
+
ADC.GAIN_1_5 = 0x02;
|
|
43
|
+
ADC.GAIN_1_4 = 0x03;
|
|
44
|
+
ADC.GAIN_2_7 = 0x04;
|
|
45
|
+
ADC.GAIN_1_3 = 0x05;
|
|
46
|
+
ADC.GAIN_2_5 = 0x06;
|
|
47
|
+
ADC.GAIN_1_2 = 0x07;
|
|
48
|
+
ADC.GAIN_2_3 = 0x08;
|
|
49
|
+
ADC.GAIN_4_5 = 0x09;
|
|
50
|
+
ADC.GAIN_1 = 0x0a;
|
|
51
|
+
ADC.GAIN_2 = 0x0b;
|
|
52
|
+
ADC.GAIN_3 = 0x0c;
|
|
53
|
+
ADC.GAIN_4 = 0x0d;
|
|
54
|
+
ADC.GAIN_6 = 0x0e;
|
|
55
|
+
ADC.GAIN_8 = 0x0f;
|
|
56
|
+
ADC.GAIN_12 = 0x10;
|
|
57
|
+
ADC.GAIN_16 = 0x11;
|
|
58
|
+
ADC.GAIN_24 = 0x12;
|
|
59
|
+
ADC.GAIN_32 = 0x13;
|
|
60
|
+
ADC.GAIN_64 = 0x14;
|
|
61
|
+
ADC.GAIN_128 = 0x15;
|
|
62
|
+
// ── Reference tokens (enum adc_reference, verbatim) ────────────────────
|
|
63
|
+
ADC.REF_VDD_1 = 0x100;
|
|
64
|
+
ADC.REF_VDD_1_2 = 0x101;
|
|
65
|
+
ADC.REF_VDD_1_3 = 0x102;
|
|
66
|
+
ADC.REF_VDD_1_4 = 0x103;
|
|
67
|
+
ADC.REF_INTERNAL = 0x104;
|
|
68
|
+
ADC.REF_EXTERNAL0 = 0x105;
|
|
69
|
+
ADC.REF_EXTERNAL1 = 0x106;
|
package/dist/async.d.ts
CHANGED
|
@@ -2,10 +2,9 @@ export declare class AsyncClass {
|
|
|
2
2
|
static readonly __instance_name = "Async";
|
|
3
3
|
/**
|
|
4
4
|
* Non-blocking sleep for `ms` milliseconds.
|
|
5
|
-
* Returns a Promise<void> that resolves after the given delay.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* on native, or a FreeRTOS vTaskDelay in the future).
|
|
5
|
+
* Returns a Promise<void> that resolves after the given delay. The async
|
|
6
|
+
* runtime resolves it cooperatively (the static state machine on
|
|
7
|
+
* heap-less targets polls the clock in the scheduler loop).
|
|
9
8
|
*/
|
|
10
9
|
sleep(ms: number): Promise<void>;
|
|
11
10
|
/**
|
|
@@ -13,13 +12,6 @@ export declare class AsyncClass {
|
|
|
13
12
|
* (microtasks, timers) to run. Resumes on the next microtask pump cycle.
|
|
14
13
|
*/
|
|
15
14
|
yield(): Promise<void>;
|
|
16
|
-
/**
|
|
17
|
-
* Await a polling condition.
|
|
18
|
-
* Repeatedly checks `condition()` every `pollIntervalMs` milliseconds
|
|
19
|
-
* until it returns true, then resolves.
|
|
20
|
-
* The underlying implementation uses the platform's timer mechanism.
|
|
21
|
-
*/
|
|
22
|
-
sleepUntil(condition: () => boolean, pollIntervalMs?: number): Promise<void>;
|
|
23
15
|
/**
|
|
24
16
|
* Return a human-readable description of the currently executing async task.
|
|
25
17
|
* Useful for debugging / logging in cooperative multitasking environments.
|
package/dist/async.js
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
|
|
@@ -15,10 +14,9 @@ import { rawCpp } from './emit.js';
|
|
|
15
14
|
export class AsyncClass {
|
|
16
15
|
/**
|
|
17
16
|
* Non-blocking sleep for `ms` milliseconds.
|
|
18
|
-
* Returns a Promise<void> that resolves after the given delay.
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* on native, or a FreeRTOS vTaskDelay in the future).
|
|
17
|
+
* Returns a Promise<void> that resolves after the given delay. The async
|
|
18
|
+
* runtime resolves it cooperatively (the static state machine on
|
|
19
|
+
* heap-less targets polls the clock in the scheduler loop).
|
|
22
20
|
*/
|
|
23
21
|
sleep(ms) {
|
|
24
22
|
rawCpp(`__cuttlefish_async_sleep(${ms});`);
|
|
@@ -32,16 +30,6 @@ export class AsyncClass {
|
|
|
32
30
|
rawCpp(`__cuttlefish_async_yield();`);
|
|
33
31
|
return Promise.resolve();
|
|
34
32
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Await a polling condition.
|
|
37
|
-
* Repeatedly checks `condition()` every `pollIntervalMs` milliseconds
|
|
38
|
-
* until it returns true, then resolves.
|
|
39
|
-
* The underlying implementation uses the platform's timer mechanism.
|
|
40
|
-
*/
|
|
41
|
-
sleepUntil(condition, pollIntervalMs = 10) {
|
|
42
|
-
rawCpp(`__cuttlefish_async_sleep_until(${pollIntervalMs});`);
|
|
43
|
-
return Promise.resolve();
|
|
44
|
-
}
|
|
45
33
|
/**
|
|
46
34
|
* Return a human-readable description of the currently executing async task.
|
|
47
35
|
* Useful for debugging / logging in cooperative multitasking environments.
|
package/dist/ble.d.ts
CHANGED
|
@@ -17,18 +17,6 @@ export declare enum BlePerm {
|
|
|
17
17
|
Write = 2,
|
|
18
18
|
Notify = 4
|
|
19
19
|
}
|
|
20
|
-
/** BLE peripheral status (mirrored by the runtime shim). */
|
|
21
|
-
export declare enum BleStatus {
|
|
22
|
-
Idle = 0,
|
|
23
|
-
Initializing = 1,
|
|
24
|
-
Advertising = 2,
|
|
25
|
-
Connected = 3,
|
|
26
|
-
Error = 4
|
|
27
|
-
}
|
|
28
|
-
export declare enum BleAdvertisingMode {
|
|
29
|
-
Connectable = "connectable",
|
|
30
|
-
NonConnectable = "non_connectable"
|
|
31
|
-
}
|
|
32
20
|
/** A well-known GATT characteristic entry in the catalog. */
|
|
33
21
|
export interface GattCharacteristicDef {
|
|
34
22
|
readonly uuid: string;
|
|
@@ -38,9 +26,10 @@ export interface GattCharacteristicDef {
|
|
|
38
26
|
readonly notify?: boolean;
|
|
39
27
|
}
|
|
40
28
|
/**
|
|
41
|
-
* Standard GATT services/characteristics
|
|
42
|
-
*
|
|
43
|
-
*
|
|
29
|
+
* Standard GATT services/characteristics — uuid/type/perms reference data.
|
|
30
|
+
* Pass the pieces explicitly to char():
|
|
31
|
+
* GATT.ENVIRONMENTAL.TEMPERATURE →
|
|
32
|
+
* char('2A6E', BleValueType.Int16, BlePerm.Read | BlePerm.Notify)
|
|
44
33
|
*/
|
|
45
34
|
export declare const GATT: {
|
|
46
35
|
readonly DEVICE_INFO: {
|
|
@@ -92,69 +81,44 @@ export declare const GATT: {
|
|
|
92
81
|
/** The value passed to/from callbacks — narrowed per characteristic by type. */
|
|
93
82
|
export type CharValue = number | string | boolean | Uint8Array;
|
|
94
83
|
/**
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* No `include()` calls here — NimBLE headers are framework-owned and added via
|
|
99
|
-
* forcedIncludes when the program uses ble.* ops.
|
|
100
|
-
*
|
|
101
|
-
* Transpiler note: method bodies pass parameters directly into semantic calls
|
|
102
|
-
* (no local consts / module counters) so the resolver can statically track every
|
|
103
|
-
* argument. The characteristic index is carried through the chain via
|
|
104
|
-
* `this._charCount` fieldValues, mirroring how HttpRequest carries _method/_url.
|
|
84
|
+
* The GATT declaration chain returned by BLE.service()/BLE.char(). Each char()
|
|
85
|
+
* appends a characteristic; onRead/onWrite/notify bind to the most recent one.
|
|
105
86
|
*/
|
|
106
|
-
export declare class
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
|
|
116
|
-
untilConnectedStart(): void;
|
|
117
|
-
isConnected(): boolean;
|
|
118
|
-
status(): BleStatus;
|
|
119
|
-
clientCount(): number;
|
|
120
|
-
txPower(dbm: number): this;
|
|
121
|
-
notify(index: number, value: number): void;
|
|
87
|
+
export declare class BleChain {
|
|
88
|
+
/** Begin a new service grouping; subsequent char() calls attach to it. */
|
|
89
|
+
service(uuid: string): BleChain;
|
|
90
|
+
/** Append a characteristic by uuid, value type, and permissions
|
|
91
|
+
* (`BlePerm.Read | BlePerm.Notify`). Returns this for chaining. */
|
|
92
|
+
char(uuid: string, type: BleValueType, perms: number): BleChain;
|
|
93
|
+
/** Read handler for the most recently declared characteristic. */
|
|
94
|
+
onRead(handler: () => CharValue): BleChain;
|
|
95
|
+
/** Write handler for the most recently declared characteristic. */
|
|
96
|
+
onWrite(handler: (value: number) => void): BleChain;
|
|
122
97
|
}
|
|
123
|
-
/**
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
/** Register a write handler for the most recently added characteristic. */
|
|
150
|
-
onWrite(handler: (value: number) => void): this;
|
|
151
|
-
/** Register a connect handler (called when a central connects). */
|
|
152
|
-
onConnect(handler: () => void): this;
|
|
153
|
-
/** Register a disconnect handler (called when a central disconnects). */
|
|
154
|
-
onDisconnect(handler: () => void): this;
|
|
155
|
-
/** Push a new value to subscribed clients on the most recently added characteristic. */
|
|
156
|
-
notify(value: number): void;
|
|
157
|
-
/** Initialize NimBLE, register services, and start advertising. */
|
|
158
|
-
begin(): void;
|
|
98
|
+
/** A GATT peripheral. The advertised device name is the construction fact. */
|
|
99
|
+
export declare class BLE {
|
|
100
|
+
private readonly _name;
|
|
101
|
+
constructor(name: string);
|
|
102
|
+
/** Begin a service grouping; chain char() declarations off it. */
|
|
103
|
+
service(uuid: string): BleChain;
|
|
104
|
+
/** Append a characteristic under the default (Environmental Sensing)
|
|
105
|
+
* service — the common single-service case. */
|
|
106
|
+
char(uuid: string, type: BleValueType, perms: number): BleChain;
|
|
107
|
+
/** Register the declared GATT database, enable the stack, and start
|
|
108
|
+
* advertising the construction name. */
|
|
109
|
+
start(): void;
|
|
110
|
+
/** Stop advertising (the GATT database and any link stay up). */
|
|
111
|
+
stop(): void;
|
|
112
|
+
/** True while a central is connected. */
|
|
113
|
+
linked(): boolean;
|
|
114
|
+
/** Number of connected centrals (0 or 1 — the shim is single-connection). */
|
|
115
|
+
clients(): number;
|
|
116
|
+
/** Fires when a central connects. */
|
|
117
|
+
onConnect(handler: () => void): void;
|
|
118
|
+
/** Fires when the central disconnects. */
|
|
119
|
+
onDrop(handler: () => void): void;
|
|
120
|
+
/** Push a value to subscribed clients on a characteristic
|
|
121
|
+
* (bt_gatt_notify). `index` is the characteristic's declaration order
|
|
122
|
+
* (0-based — the first char() is 0). */
|
|
123
|
+
notify(index: number, value: number): void;
|
|
159
124
|
}
|
|
160
|
-
export declare const Ble: BleClass;
|