@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.
- 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 +7 -8
- 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/dist/sensor.d.ts
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { I2CTarget } from './i2c-target.js';
|
|
2
|
+
import type { SPITarget } from './spi-target.js';
|
|
3
|
+
import type { SensorChannelOf, SensorBusOf } from './sensor-catalog.generated.js';
|
|
4
|
+
/** Part ids the catalog knows (the Sensor<P> narrowing keys). */
|
|
5
|
+
type SensorPartId = keyof SensorChannelOf;
|
|
6
|
+
/** The bus-device argument a part accepts, from its generated bus map:
|
|
7
|
+
* SPI-only parts take SPITarget, I2C-only take I2CTarget, dual-bus either. */
|
|
8
|
+
type BusDeviceFor<B extends string> = B extends 'spi' ? SPITarget : B extends 'i2c' ? I2CTarget : I2CTarget | SPITarget;
|
|
9
|
+
export type SensorBusDevice<P extends SensorPartId = SensorPartId> = BusDeviceFor<SensorBusOf[P]>;
|
|
10
|
+
/** Construction options. */
|
|
11
|
+
export interface SensorOptions {
|
|
12
|
+
/** SPI clock in Hz, SPI parts only. Default 1 MHz (safe for every
|
|
13
|
+
* catalog part); raise to the breakout's datasheet maximum. */
|
|
14
|
+
spiHz?: number;
|
|
15
|
+
/** SPI mode (CPOL/CPHA bits), 0-3. Default 0. */
|
|
16
|
+
mode?: 0 | 1 | 2 | 3;
|
|
17
|
+
/** Alert GPIO, for parts whose binding declares alert-gpios. */
|
|
18
|
+
alert?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class Sensor<P extends SensorPartId = SensorPartId> {
|
|
21
|
+
private readonly _part;
|
|
22
|
+
private readonly _bus;
|
|
23
|
+
private readonly _port;
|
|
24
|
+
private readonly _kind;
|
|
25
|
+
private readonly _spiHz;
|
|
26
|
+
private readonly _mode;
|
|
27
|
+
private readonly _alert;
|
|
28
|
+
/** Construct a sensor handle. `part` is a `SENSOR.<name>` token;
|
|
29
|
+
* `dev` is the bus device (e.g. `I2C1.device(0x44)`) carrying the bus
|
|
30
|
+
* and address. The transpiler resolves the bus instance and address from
|
|
31
|
+
* `dev` — the class fields are the IR carrier, not runtime state.
|
|
32
|
+
* The `P` parameter is editor-only: it narrows `get()` to this part's
|
|
33
|
+
* channels (from the generated SensorChannelOf map); the transpiler
|
|
34
|
+
* re-validates at build time with the driver's full channel list. */
|
|
35
|
+
constructor(part: P, dev: SensorBusDevice<P>, opts?: SensorOptions);
|
|
36
|
+
/** Fetch a fresh sample (sensor_sample_fetch). Reads reflect the last
|
|
37
|
+
* fetch — Zephyr's own fetch/get split, kept verbatim. */
|
|
38
|
+
fetch(): void;
|
|
39
|
+
/** Read one channel from the fetched sample (sensor_channel_get).
|
|
40
|
+
* Returns the value as a double (val1 + val2/1e6). The parameter is
|
|
41
|
+
* narrowed to this part's channels when constructed from a literal
|
|
42
|
+
* SENSOR token — `sht3x.get(` completes AMBIENT_TEMP | HUMIDITY and
|
|
43
|
+
* rejects the rest in the editor. */
|
|
44
|
+
get(chan: SensorChannelOf[P]): number;
|
|
45
|
+
}
|
|
46
|
+
export {};
|
package/dist/sensor.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Sensor — generic DT-bound sensor part (Zephyr's uniform sensor API)
|
|
3
|
+
//
|
|
4
|
+
// `new Sensor(SENSOR.sensirion_sht3xd, I2C1.device(0x44))` covers every part
|
|
5
|
+
// in the generated catalog: the constructor's facts (part token + bus +
|
|
6
|
+
// address) become a devicetree child node in the generated overlay, and the
|
|
7
|
+
// methods lower to Zephyr's one-shape sensor API (sensor_sample_fetch /
|
|
8
|
+
// sensor_channel_get). No per-part code exists anywhere — the catalog
|
|
9
|
+
// (sensor-catalog.generated.ts) is data, generated from Zephyr's own binding
|
|
10
|
+
// YAMLs and driver channel tables.
|
|
11
|
+
//
|
|
12
|
+
// The channel names are Zephyr verbiage minus the SENSOR_CHAN_ prefix
|
|
13
|
+
// (CHAN.AMBIENT_TEMP ↔ SENSOR_CHAN_AMBIENT_TEMP), so any Zephyr sample or
|
|
14
|
+
// binding doc greps straight into user code.
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
import { sensorFetch, sensorGet } from './emit.js';
|
|
17
|
+
import { include } from './include.js';
|
|
18
|
+
export class Sensor {
|
|
19
|
+
/** Construct a sensor handle. `part` is a `SENSOR.<name>` token;
|
|
20
|
+
* `dev` is the bus device (e.g. `I2C1.device(0x44)`) carrying the bus
|
|
21
|
+
* and address. The transpiler resolves the bus instance and address from
|
|
22
|
+
* `dev` — the class fields are the IR carrier, not runtime state.
|
|
23
|
+
* The `P` parameter is editor-only: it narrows `get()` to this part's
|
|
24
|
+
* channels (from the generated SensorChannelOf map); the transpiler
|
|
25
|
+
* re-validates at build time with the driver's full channel list. */
|
|
26
|
+
constructor(part, dev, opts) {
|
|
27
|
+
this._bus = '';
|
|
28
|
+
this._port = 0;
|
|
29
|
+
this._kind = 'i2c';
|
|
30
|
+
this._spiHz = 1000000;
|
|
31
|
+
this._mode = 0;
|
|
32
|
+
this._alert = -1;
|
|
33
|
+
this._part = part;
|
|
34
|
+
void dev;
|
|
35
|
+
void opts;
|
|
36
|
+
}
|
|
37
|
+
/** Fetch a fresh sample (sensor_sample_fetch). Reads reflect the last
|
|
38
|
+
* fetch — Zephyr's own fetch/get split, kept verbatim. */
|
|
39
|
+
fetch() {
|
|
40
|
+
include('<zephyr/drivers/sensor.h>');
|
|
41
|
+
sensorFetch(this._part, this._bus, this._port, this._kind, this._spiHz, this._mode, this._alert);
|
|
42
|
+
}
|
|
43
|
+
/** Read one channel from the fetched sample (sensor_channel_get).
|
|
44
|
+
* Returns the value as a double (val1 + val2/1e6). The parameter is
|
|
45
|
+
* narrowed to this part's channels when constructed from a literal
|
|
46
|
+
* SENSOR token — `sht3x.get(` completes AMBIENT_TEMP | HUMIDITY and
|
|
47
|
+
* rejects the rest in the editor. */
|
|
48
|
+
get(chan) {
|
|
49
|
+
include('<zephyr/drivers/sensor.h>');
|
|
50
|
+
return sensorGet(this._part, this._bus, this._port, this._kind, this._spiHz, this._mode, this._alert, chan);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// shiftOut / shiftIn — the thin bit-bang shift (the legacy shiftOut/shiftIn
|
|
3
|
+
// shape, Zephyr-lowered): clock idles low; each bit sets data then pulses the
|
|
4
|
+
// clock. For real SPI, use SPITarget. Pin arguments accept board pin aliases
|
|
5
|
+
// (resolved to their numbers by the transpiler).
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
import { gpioShiftOut, gpioShiftIn } from './emit.js';
|
|
8
|
+
export function shiftOut(dataPin, clockPin, value, msbFirst = true) {
|
|
9
|
+
gpioShiftOut(dataPin, clockPin, value, msbFirst);
|
|
10
|
+
}
|
|
11
|
+
export function shiftIn(dataPin, clockPin, msbFirst = true) {
|
|
12
|
+
return gpioShiftIn(dataPin, clockPin, msbFirst);
|
|
13
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Pin } from './gpio.js';
|
|
2
|
+
export declare class SPITarget {
|
|
3
|
+
private readonly _bus;
|
|
4
|
+
private readonly _cs;
|
|
5
|
+
private readonly _hz;
|
|
6
|
+
private readonly _mode;
|
|
7
|
+
/** Construct a device handle. `bus` is the bus instance (SPI0, …); `cs`
|
|
8
|
+
* is the chip-select pin; `hz` the bus clock (spi-max-frequency, default
|
|
9
|
+
* 1 MHz conservative); `mode` the SPI mode 0–3. */
|
|
10
|
+
constructor(bus: string, cs: number | Pin, opts?: {
|
|
11
|
+
hz?: number;
|
|
12
|
+
mode?: 0 | 1 | 2 | 3;
|
|
13
|
+
});
|
|
14
|
+
/** Full-duplex transfer (spi_transceive_dt): `tx` bytes out while `rx`
|
|
15
|
+
* captures — the buffer you pass is the buffer filled, so declare it and
|
|
16
|
+
* read it directly (rx.length decides the capture length). Omit `rx`
|
|
17
|
+
* for a write-only transfer. */
|
|
18
|
+
transceive(tx: number[] | Uint8Array, rx?: Uint8Array): void;
|
|
19
|
+
/** Write bytes (spi_write_dt) — no capture. */
|
|
20
|
+
write(tx: number[] | Uint8Array): void;
|
|
21
|
+
/** Register read sugar: sends `reg`, returns the one captured byte
|
|
22
|
+
* (spi_transceive_dt against an internal buffer — e.g. a BME280's ID
|
|
23
|
+
* register 0xD0 reads 0x60). */
|
|
24
|
+
readReg(reg: number): number;
|
|
25
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// SPITarget — the thin Zephyr-shaped SPI device
|
|
3
|
+
//
|
|
4
|
+
// A chip-select peer on an SPI bus, addressed the Zephyr way: construction
|
|
5
|
+
// emits a devicetree child node (cs-gpios index + spi-max-frequency + mode
|
|
6
|
+
// bits — the same machinery sensors ride), and the verbs lower to
|
|
7
|
+
// spi_transceive_dt / spi_write_dt against a static spi_dt_spec. Hardware
|
|
8
|
+
// CS, no manual GPIO toggling, no runtime spi_config rebuilding.
|
|
9
|
+
//
|
|
10
|
+
// `bus` is the board's bus instance export (SPI0/SPI1), `cs` the chip-select
|
|
11
|
+
// pin, and the options are the wire facts: `hz` (spi-max-frequency) and
|
|
12
|
+
// `mode` (CPOL/CPHA bits 0–3 → spi-cpol/spi-cpha).
|
|
13
|
+
// ----------------------------------------------------------------------------
|
|
14
|
+
import { spiTransceiveDt, spiWriteDt, spiReadReg } from './emit.js';
|
|
15
|
+
export class SPITarget {
|
|
16
|
+
/** Construct a device handle. `bus` is the bus instance (SPI0, …); `cs`
|
|
17
|
+
* is the chip-select pin; `hz` the bus clock (spi-max-frequency, default
|
|
18
|
+
* 1 MHz conservative); `mode` the SPI mode 0–3. */
|
|
19
|
+
constructor(bus, cs, opts) {
|
|
20
|
+
this._bus = bus;
|
|
21
|
+
this._cs = typeof cs === 'number' ? cs : cs.number;
|
|
22
|
+
this._hz = opts?.hz ?? 1000000;
|
|
23
|
+
this._mode = opts?.mode ?? 0;
|
|
24
|
+
}
|
|
25
|
+
/** Full-duplex transfer (spi_transceive_dt): `tx` bytes out while `rx`
|
|
26
|
+
* captures — the buffer you pass is the buffer filled, so declare it and
|
|
27
|
+
* read it directly (rx.length decides the capture length). Omit `rx`
|
|
28
|
+
* for a write-only transfer. */
|
|
29
|
+
transceive(tx, rx) {
|
|
30
|
+
spiTransceiveDt(this._bus, this._cs, this._hz, this._mode, tx, rx ?? new Uint8Array(0));
|
|
31
|
+
}
|
|
32
|
+
/** Write bytes (spi_write_dt) — no capture. */
|
|
33
|
+
write(tx) {
|
|
34
|
+
spiWriteDt(this._bus, this._cs, this._hz, this._mode, tx);
|
|
35
|
+
}
|
|
36
|
+
/** Register read sugar: sends `reg`, returns the one captured byte
|
|
37
|
+
* (spi_transceive_dt against an internal buffer — e.g. a BME280's ID
|
|
38
|
+
* register 0xD0 reads 0x60). */
|
|
39
|
+
readReg(reg) {
|
|
40
|
+
return spiReadReg(this._bus, this._cs, this._hz, this._mode, reg);
|
|
41
|
+
}
|
|
42
|
+
}
|
package/dist/spi.d.ts
CHANGED
|
@@ -1,31 +1,13 @@
|
|
|
1
|
+
import { SPITarget } from './spi-target.js';
|
|
1
2
|
import type { Pin } from './gpio.js';
|
|
2
|
-
import type { SPIMode, SPISettings } from './types.js';
|
|
3
|
-
export declare class SPIDevice {
|
|
4
|
-
private _bus;
|
|
5
|
-
private _cs;
|
|
6
|
-
constructor(bus: string, chipSelect: number);
|
|
7
|
-
transfer(data: number | Uint8Array): number;
|
|
8
|
-
write(data: number | Uint8Array): void;
|
|
9
|
-
readRegister(register: number, count: number): Uint8Array;
|
|
10
|
-
writeRegister(register: number, value: number): void;
|
|
11
|
-
}
|
|
12
3
|
export declare class SPIBus {
|
|
13
|
-
static readonly __includes: string[];
|
|
14
4
|
private _bus;
|
|
15
5
|
constructor(bus: string);
|
|
16
|
-
device
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
beginTransaction(settings: SPISettings): void;
|
|
24
|
-
endTransaction(): void;
|
|
25
|
-
setMode(mode: SPIMode): void;
|
|
26
|
-
setBitOrder(order: 'lsb' | 'msb'): void;
|
|
27
|
-
write(value: number): void;
|
|
28
|
-
write16(value: number): void;
|
|
6
|
+
/** The functional device target behind `chipSelect` on this controller —
|
|
7
|
+
* transceive/write/regRead verbs callable directly, and the fact-carrier
|
|
8
|
+
* `new Sensor(...)` accepts. */
|
|
9
|
+
device(chipSelect: Pin, opts?: {
|
|
10
|
+
hz?: number;
|
|
11
|
+
mode?: 0 | 1 | 2 | 3;
|
|
12
|
+
}): SPITarget;
|
|
29
13
|
}
|
|
30
|
-
/** Map TypeCAD SPI instance number to Arduino C++ object name. SPI0→SPI, SPI1→SPI1 */
|
|
31
|
-
export declare function spiName(instance: number): string;
|
package/dist/spi.js
CHANGED
|
@@ -1,93 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
rawCpp(`auto __res = ${this._bus}.transfer(${data});`);
|
|
12
|
-
spiCsHigh(this._cs);
|
|
13
|
-
rawCpp(`return __res;`);
|
|
14
|
-
return 0;
|
|
15
|
-
}
|
|
16
|
-
write(data) {
|
|
17
|
-
include("<SPI.h>");
|
|
18
|
-
spiCsLow(this._cs);
|
|
19
|
-
spiTransfer(this._bus, data);
|
|
20
|
-
spiCsHigh(this._cs);
|
|
21
|
-
}
|
|
22
|
-
readRegister(register, count) {
|
|
23
|
-
include("<SPI.h>");
|
|
24
|
-
spiCsLow(this._cs);
|
|
25
|
-
spiTransfer(this._bus, register);
|
|
26
|
-
// Clock `count` dummy bytes and drain them into the caller's buffer
|
|
27
|
-
// (declared by the Uint8Array return marker as `uint8_t data[count]`).
|
|
28
|
-
// Using the semantic primitive — NOT rawCpp — keeps the buffer in user
|
|
29
|
-
// scope so it survives the return (no decayed pointer) and `data.length`
|
|
30
|
-
// / `data[i]` work, mirroring I2CDevice.readBytes.
|
|
31
|
-
spiReadBuffer(this._bus, count, new Uint8Array(count));
|
|
32
|
-
spiCsHigh(this._cs);
|
|
33
|
-
return new Uint8Array(count);
|
|
34
|
-
}
|
|
35
|
-
writeRegister(register, value) {
|
|
36
|
-
include("<SPI.h>");
|
|
37
|
-
spiCsLow(this._cs);
|
|
38
|
-
spiTransfer(this._bus, register);
|
|
39
|
-
spiTransfer(this._bus, value);
|
|
40
|
-
spiCsHigh(this._cs);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// SPI — controller selector (legacy SPI API removed)
|
|
3
|
+
//
|
|
4
|
+
// The bus singletons (SPI0/SPI1…) are CONTROLLER SELECTORS; device(cs, opts?)
|
|
5
|
+
// hands back the FUNCTIONAL SPITarget directly — transceive/write/regRead
|
|
6
|
+
// verbs callable with no further construction. Equivalent to
|
|
7
|
+
// `new SPITarget(this, cs, opts)`. The standalone SPIDevice fact-carrier was
|
|
8
|
+
// absorbed by SPITarget.
|
|
9
|
+
// ----------------------------------------------------------------------------
|
|
10
|
+
import { SPITarget } from './spi-target.js';
|
|
43
11
|
export class SPIBus {
|
|
44
12
|
constructor(bus) {
|
|
45
13
|
this._bus = bus;
|
|
46
14
|
}
|
|
47
|
-
device
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
spiBegin(this._bus);
|
|
53
|
-
return this;
|
|
54
|
-
}
|
|
55
|
-
end() {
|
|
56
|
-
spiEnd(this._bus);
|
|
57
|
-
}
|
|
58
|
-
take() {
|
|
59
|
-
return this;
|
|
15
|
+
/** The functional device target behind `chipSelect` on this controller —
|
|
16
|
+
* transceive/write/regRead verbs callable directly, and the fact-carrier
|
|
17
|
+
* `new Sensor(...)` accepts. */
|
|
18
|
+
device(chipSelect, opts) {
|
|
19
|
+
return new SPITarget(this._bus, chipSelect, opts);
|
|
60
20
|
}
|
|
61
|
-
release() {
|
|
62
|
-
// No-op for standard Arduino.
|
|
63
|
-
}
|
|
64
|
-
transfer(value) {
|
|
65
|
-
return spiTransfer(this._bus, value);
|
|
66
|
-
}
|
|
67
|
-
setFrequency(hz) {
|
|
68
|
-
spiBeginTx(this._bus, `SPISettings(${hz}, MSBFIRST, SPI_MODE0)`);
|
|
69
|
-
}
|
|
70
|
-
beginTransaction(settings) {
|
|
71
|
-
spiBeginTx(this._bus, settings);
|
|
72
|
-
}
|
|
73
|
-
endTransaction() {
|
|
74
|
-
spiEndTx(this._bus);
|
|
75
|
-
}
|
|
76
|
-
setMode(mode) {
|
|
77
|
-
spiSetMode(this._bus, mode);
|
|
78
|
-
}
|
|
79
|
-
setBitOrder(order) {
|
|
80
|
-
spiSetBitOrder(this._bus, order);
|
|
81
|
-
}
|
|
82
|
-
write(value) {
|
|
83
|
-
spiTransfer(this._bus, value);
|
|
84
|
-
}
|
|
85
|
-
write16(value) {
|
|
86
|
-
rawCpp(`${this._bus}.transfer16(${value});`);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
SPIBus.__includes = ["<SPI.h>"];
|
|
90
|
-
/** Map TypeCAD SPI instance number to Arduino C++ object name. SPI0→SPI, SPI1→SPI1 */
|
|
91
|
-
export function spiName(instance) {
|
|
92
|
-
return instance === 0 ? "SPI" : `SPI${instance}`;
|
|
93
21
|
}
|
package/dist/thread.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export declare class Thread {
|
|
2
|
+
private readonly _index;
|
|
3
|
+
private readonly _stackBytes;
|
|
4
|
+
private readonly _priority;
|
|
5
|
+
/** Construct a thread handle. `stackKb` defaults to 2 (generous for
|
|
6
|
+
* generated code); `priority` defaults to 5 — preemptive, below main. */
|
|
7
|
+
constructor(index: number, opts?: {
|
|
8
|
+
stackKb?: number;
|
|
9
|
+
priority?: number;
|
|
10
|
+
});
|
|
11
|
+
/** Create the thread and schedule it immediately (k_thread_create with
|
|
12
|
+
* K_NO_WAIT). The entry function runs concurrently with main from here. */
|
|
13
|
+
start(fn: () => void): void;
|
|
14
|
+
/** Block until the thread exits (k_thread_join with K_FOREVER). Requires
|
|
15
|
+
* a prior start() on the same index — an unstarted slot is a build
|
|
16
|
+
* error naming the slot's symbol. */
|
|
17
|
+
join(): void;
|
|
18
|
+
}
|
package/dist/thread.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Thread — the thin Zephyr-shaped thread
|
|
3
|
+
//
|
|
4
|
+
// k_thread_create / k_thread_join with Zephyr's own model: construction
|
|
5
|
+
// carries the thread's facts (stack size, priority); start(fn) creates and
|
|
6
|
+
// schedules it (K_NO_WAIT — running immediately); join() blocks until it
|
|
7
|
+
// exits (K_FOREVER). The entry function is a no-argument closure, trampolined
|
|
8
|
+
// through Zephyr's (void*, void*, void*) entry signature — the same
|
|
9
|
+
// callback machinery interrupts use.
|
|
10
|
+
//
|
|
11
|
+
// The `index` is the thread's identity (0, 1, 2, …) — the slot its stack and
|
|
12
|
+
// k_thread state occupy, like Counter's instance. Priorities: Zephyr's scale
|
|
13
|
+
// — 5 (the default) is preemptive, below main; negative would be cooperative.
|
|
14
|
+
// ----------------------------------------------------------------------------
|
|
15
|
+
import { threadStart, threadJoin } from './emit.js';
|
|
16
|
+
import { callback } from './callback.js';
|
|
17
|
+
export class Thread {
|
|
18
|
+
/** Construct a thread handle. `stackKb` defaults to 2 (generous for
|
|
19
|
+
* generated code); `priority` defaults to 5 — preemptive, below main. */
|
|
20
|
+
constructor(index, opts) {
|
|
21
|
+
this._index = index;
|
|
22
|
+
this._stackBytes = (opts?.stackKb ?? 2) * 1024;
|
|
23
|
+
this._priority = opts?.priority ?? 5;
|
|
24
|
+
}
|
|
25
|
+
/** Create the thread and schedule it immediately (k_thread_create with
|
|
26
|
+
* K_NO_WAIT). The entry function runs concurrently with main from here. */
|
|
27
|
+
start(fn) {
|
|
28
|
+
threadStart(this._index, this._stackBytes, this._priority, callback(fn));
|
|
29
|
+
}
|
|
30
|
+
/** Block until the thread exits (k_thread_join with K_FOREVER). Requires
|
|
31
|
+
* a prior start() on the same index — an unstarted slot is a build
|
|
32
|
+
* error naming the slot's symbol. */
|
|
33
|
+
join() {
|
|
34
|
+
threadJoin(this._index);
|
|
35
|
+
}
|
|
36
|
+
}
|
package/dist/time.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare class TimeClass {
|
|
2
|
+
static readonly __instance_name = "Time";
|
|
3
|
+
/** Yielding sleep in milliseconds (k_msleep). On the generated
|
|
4
|
+
* single-threaded main this blocks the caller — the same semantics
|
|
5
|
+
* delay() had, JS-spelled. Inside an async function, `await`-ed it
|
|
6
|
+
* becomes cooperative: the async state machine arms a deadline and
|
|
7
|
+
* yields (other tasks and timers run) until it passes — the same
|
|
8
|
+
* machinery `await delay()` rides. */
|
|
9
|
+
sleep(ms: number): Promise<void>;
|
|
10
|
+
/** Milliseconds since boot as a double (k_uptime_get) — Date.now()-shaped:
|
|
11
|
+
* milliseconds, monotonic, no uint32 wrap. */
|
|
12
|
+
now(): number;
|
|
13
|
+
/** Microseconds since boot as a double — uptime-derived
|
|
14
|
+
* (k_uptime_get() * 1000) on every board: the cycle-counter form reads a
|
|
15
|
+
* constant on SoCs without a free-running 64-bit counter, so the one
|
|
16
|
+
* uniform, monotonic expression wins. Resolution is the uptime tick
|
|
17
|
+
* (millisecond); for sub-ms determinism use Counter (hardware timer). */
|
|
18
|
+
nowUs(): number;
|
|
19
|
+
/** Spin-wait the given microseconds (k_busy_wait) — no yield; for sub-ms
|
|
20
|
+
* protocol timing where a schedule point would break the waveform. */
|
|
21
|
+
busyWaitUs(us: number): void;
|
|
22
|
+
}
|
|
23
|
+
export declare const Time: TimeClass;
|
package/dist/time.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// Time — the TS-flavored timing surface
|
|
3
|
+
//
|
|
4
|
+
// The Arduino-named forms (delay/millis/micros/delayMicroseconds, module
|
|
5
|
+
// functions and the Timing class) are deprecated for new code but keep
|
|
6
|
+
// lowering — framework-arduino is frozen on them. Time is the replacement:
|
|
7
|
+
// plain-number milliseconds like the rest of the JS ecosystem (Date.now() is
|
|
8
|
+
// ms), microseconds explicit in the name, and the honest Zephyr verbs —
|
|
9
|
+
// k_msleep (yielding sleep), k_uptime_get (ms clock), k_busy_wait (spin).
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
import { timeSleep, timeNow, timeNowUs, timeBusyWaitUs } from './emit.js';
|
|
12
|
+
export class TimeClass {
|
|
13
|
+
/** Yielding sleep in milliseconds (k_msleep). On the generated
|
|
14
|
+
* single-threaded main this blocks the caller — the same semantics
|
|
15
|
+
* delay() had, JS-spelled. Inside an async function, `await`-ed it
|
|
16
|
+
* becomes cooperative: the async state machine arms a deadline and
|
|
17
|
+
* yields (other tasks and timers run) until it passes — the same
|
|
18
|
+
* machinery `await delay()` rides. */
|
|
19
|
+
sleep(ms) {
|
|
20
|
+
timeSleep(ms);
|
|
21
|
+
return Promise.resolve();
|
|
22
|
+
}
|
|
23
|
+
/** Milliseconds since boot as a double (k_uptime_get) — Date.now()-shaped:
|
|
24
|
+
* milliseconds, monotonic, no uint32 wrap. */
|
|
25
|
+
now() {
|
|
26
|
+
return timeNow();
|
|
27
|
+
}
|
|
28
|
+
/** Microseconds since boot as a double — uptime-derived
|
|
29
|
+
* (k_uptime_get() * 1000) on every board: the cycle-counter form reads a
|
|
30
|
+
* constant on SoCs without a free-running 64-bit counter, so the one
|
|
31
|
+
* uniform, monotonic expression wins. Resolution is the uptime tick
|
|
32
|
+
* (millisecond); for sub-ms determinism use Counter (hardware timer). */
|
|
33
|
+
nowUs() {
|
|
34
|
+
return timeNowUs();
|
|
35
|
+
}
|
|
36
|
+
/** Spin-wait the given microseconds (k_busy_wait) — no yield; for sub-ms
|
|
37
|
+
* protocol timing where a schedule point would break the waveform. */
|
|
38
|
+
busyWaitUs(us) {
|
|
39
|
+
timeBusyWaitUs(us);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
TimeClass.__instance_name = 'Time';
|
|
43
|
+
export const Time = new TimeClass();
|
package/dist/timing.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Arduino-named timing surface. Deprecated for new code — use `Time`
|
|
3
|
+
* (hal/time.ts): `Time.sleep`, `Time.now`, `Time.nowUs`, `Time.busyWaitUs`.
|
|
4
|
+
* Kept lowering: framework-arduino is frozen on this vocabulary, so this
|
|
5
|
+
* class is permanent, not scheduled for removal.
|
|
6
|
+
*
|
|
7
|
+
* @deprecated Use `Time` from '@typecad/hal'.
|
|
8
|
+
*/
|
|
1
9
|
export declare class TimingClass {
|
|
2
10
|
static readonly __instance_name = "Timing";
|
|
11
|
+
/** @deprecated Use `Time.sleep(ms)`. */
|
|
3
12
|
millis(): number;
|
|
13
|
+
/** @deprecated Use `Time.nowUs()`. */
|
|
4
14
|
micros(): number;
|
|
15
|
+
/** @deprecated Use `Time.sleep(ms)`. */
|
|
5
16
|
delay(ms: number): void;
|
|
17
|
+
/** @deprecated Use `Time.busyWaitUs(us)`. */
|
|
6
18
|
delayMicroseconds(us: number): void;
|
|
7
19
|
freeHeap(): number;
|
|
8
20
|
setInterval(handler: () => void, timeout: number): number;
|
|
@@ -11,19 +23,17 @@ export declare class TimingClass {
|
|
|
11
23
|
clearTimeout(id: number): void;
|
|
12
24
|
}
|
|
13
25
|
export declare const Timing: TimingClass;
|
|
26
|
+
/** @deprecated Use `Time.sleep(ms)`. */
|
|
14
27
|
export declare function delay(ms: number): void;
|
|
28
|
+
/** @deprecated Use `Time.now()`. */
|
|
15
29
|
export declare function millis(): number;
|
|
30
|
+
/** @deprecated Use `Time.nowUs()`. */
|
|
16
31
|
export declare function micros(): number;
|
|
32
|
+
/** @deprecated Use `Time.busyWaitUs(us)`. */
|
|
17
33
|
export declare function delayMicroseconds(us: number): void;
|
|
34
|
+
/** @deprecated Use `Time.freeHeap()`. */
|
|
18
35
|
export declare function freeHeap(): number;
|
|
19
36
|
export declare function setInterval(handler: () => void, timeout: number): number;
|
|
20
37
|
export declare function setTimeout(handler: () => void, timeout: number): number;
|
|
21
38
|
export declare function clearInterval(id: number): void;
|
|
22
39
|
export declare function clearTimeout(id: number): void;
|
|
23
|
-
/** Re-map a number from one range to another. Passes through to the Arduino
|
|
24
|
-
* core `map()` macro — the transpiler lowers this to a bare `map(...)` call,
|
|
25
|
-
* so the target framework must provide the implementation (Arduino.h does). */
|
|
26
|
-
export declare function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number;
|
|
27
|
-
/** Constrain a number to a range. Passes through to the Arduino core
|
|
28
|
-
* `constrain()` macro — see note on `map()` above. */
|
|
29
|
-
export declare function constrain(value: number, low: number, high: number): number;
|
package/dist/timing.js
CHANGED
|
@@ -1,9 +1,21 @@
|
|
|
1
1
|
import { rawCpp, getMillis, getMicros, getFreeHeap, delayMs, delayMicro } from './emit.js';
|
|
2
2
|
import { callback } from './callback.js';
|
|
3
|
+
/**
|
|
4
|
+
* The Arduino-named timing surface. Deprecated for new code — use `Time`
|
|
5
|
+
* (hal/time.ts): `Time.sleep`, `Time.now`, `Time.nowUs`, `Time.busyWaitUs`.
|
|
6
|
+
* Kept lowering: framework-arduino is frozen on this vocabulary, so this
|
|
7
|
+
* class is permanent, not scheduled for removal.
|
|
8
|
+
*
|
|
9
|
+
* @deprecated Use `Time` from '@typecad/hal'.
|
|
10
|
+
*/
|
|
3
11
|
export class TimingClass {
|
|
12
|
+
/** @deprecated Use `Time.sleep(ms)`. */
|
|
4
13
|
millis() { return getMillis(); }
|
|
14
|
+
/** @deprecated Use `Time.nowUs()`. */
|
|
5
15
|
micros() { return getMicros(); }
|
|
16
|
+
/** @deprecated Use `Time.sleep(ms)`. */
|
|
6
17
|
delay(ms) { delayMs(ms); }
|
|
18
|
+
/** @deprecated Use `Time.busyWaitUs(us)`. */
|
|
7
19
|
delayMicroseconds(us) { delayMicro(us); }
|
|
8
20
|
freeHeap() {
|
|
9
21
|
return getFreeHeap();
|
|
@@ -25,10 +37,15 @@ export class TimingClass {
|
|
|
25
37
|
}
|
|
26
38
|
TimingClass.__instance_name = "Timing";
|
|
27
39
|
export const Timing = new TimingClass();
|
|
40
|
+
/** @deprecated Use `Time.sleep(ms)`. */
|
|
28
41
|
export function delay(ms) { delayMs(ms); }
|
|
42
|
+
/** @deprecated Use `Time.now()`. */
|
|
29
43
|
export function millis() { return getMillis(); }
|
|
44
|
+
/** @deprecated Use `Time.nowUs()`. */
|
|
30
45
|
export function micros() { return getMicros(); }
|
|
46
|
+
/** @deprecated Use `Time.busyWaitUs(us)`. */
|
|
31
47
|
export function delayMicroseconds(us) { delayMicro(us); }
|
|
48
|
+
/** @deprecated Use `Time.freeHeap()`. */
|
|
32
49
|
export function freeHeap() { return Timing.freeHeap(); }
|
|
33
50
|
export function setInterval(handler, timeout) {
|
|
34
51
|
rawCpp(`return __tc_setInterval(${callback(handler)}, ${timeout});`);
|
|
@@ -44,10 +61,3 @@ export function clearInterval(id) {
|
|
|
44
61
|
export function clearTimeout(id) {
|
|
45
62
|
rawCpp(`__tc_clearTimeout(${id});`);
|
|
46
63
|
}
|
|
47
|
-
/** Re-map a number from one range to another. Passes through to the Arduino
|
|
48
|
-
* core `map()` macro — the transpiler lowers this to a bare `map(...)` call,
|
|
49
|
-
* so the target framework must provide the implementation (Arduino.h does). */
|
|
50
|
-
export function map(value, fromLow, fromHigh, toLow, toHigh) { return 0; }
|
|
51
|
-
/** Constrain a number to a range. Passes through to the Arduino core
|
|
52
|
-
* `constrain()` macro — see note on `map()` above. */
|
|
53
|
-
export function constrain(value, low, high) { return 0; }
|
package/dist/types.d.ts
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
export type DigitalValue = boolean;
|
|
3
3
|
/** An analog value is a plain number (resolution-dependent). */
|
|
4
4
|
export type AnalogValue = number;
|
|
5
|
+
/** A value a serial port (UART / USB console) can write: text, a number, or
|
|
6
|
+
* a boolean. Numbers format as decimal (integer + trimmed fractional);
|
|
7
|
+
* booleans print as 1/0. */
|
|
8
|
+
export type SerialValue = string | number | boolean;
|
|
5
9
|
export declare enum PinMode {
|
|
6
10
|
INPUT = "INPUT",
|
|
7
11
|
OUTPUT = "OUTPUT",
|
|
@@ -10,39 +14,5 @@ export declare enum PinMode {
|
|
|
10
14
|
OUTPUT_OPEN_DRAIN = "OUTPUT_OPEN_DRAIN",
|
|
11
15
|
ANALOG = "ANALOG"
|
|
12
16
|
}
|
|
13
|
-
export declare enum InterruptMode {
|
|
14
|
-
RISING = "RISING",
|
|
15
|
-
FALLING = "FALLING",
|
|
16
|
-
CHANGE = "CHANGE",
|
|
17
|
-
LOW = "LOW",
|
|
18
|
-
HIGH = "HIGH"
|
|
19
|
-
}
|
|
20
17
|
export type InterruptHandler = () => void;
|
|
21
|
-
export interface PinGroupMember {
|
|
22
|
-
readonly number: number;
|
|
23
|
-
readonly gpio: number;
|
|
24
|
-
write(value: DigitalValue): void;
|
|
25
|
-
high(): void;
|
|
26
|
-
low(): void;
|
|
27
|
-
toggle(): void;
|
|
28
|
-
read(): DigitalValue;
|
|
29
|
-
isHigh(): boolean;
|
|
30
|
-
isLow(): boolean;
|
|
31
|
-
}
|
|
32
|
-
export interface IPinGroup<T extends PinGroupMember = PinGroupMember> {
|
|
33
|
-
readonly name: string;
|
|
34
|
-
readonly pins: ReadonlyArray<T>;
|
|
35
|
-
writePattern(pattern: number): void;
|
|
36
|
-
readPattern(): number;
|
|
37
|
-
fill(value: DigitalValue): void;
|
|
38
|
-
}
|
|
39
|
-
export declare function createPinGroup<T extends PinGroupMember>(pins: T[]): IPinGroup<T>;
|
|
40
18
|
export type ArchitectureIdentifier = 'avr' | 'esp32' | 'esp32s2' | 'esp32s3' | 'esp32c3' | 'esp32c6' | 'rp2040' | 'rp2350' | 'samd' | 'stm32' | 'nrf52' | (string & {});
|
|
41
|
-
export type I2CAddress = number;
|
|
42
|
-
export type SPIBitOrder = 'msb' | 'lsb';
|
|
43
|
-
export type SPIMode = 0 | 1 | 2 | 3;
|
|
44
|
-
export interface SPISettings {
|
|
45
|
-
frequency: number;
|
|
46
|
-
mode: SPIMode;
|
|
47
|
-
bitOrder: SPIBitOrder;
|
|
48
|
-
}
|