@typecad/hal 0.1.0-alpha.1
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/LICENSE +21 -0
- package/README.md +127 -0
- package/dist/adc.d.ts +13 -0
- package/dist/adc.js +22 -0
- package/dist/async.d.ts +30 -0
- package/dist/async.js +56 -0
- package/dist/board.d.ts +3 -0
- package/dist/board.js +5 -0
- package/dist/callback.d.ts +4 -0
- package/dist/callback.js +6 -0
- package/dist/constants.d.ts +21 -0
- package/dist/constants.js +23 -0
- package/dist/dac.d.ts +12 -0
- package/dist/dac.js +17 -0
- package/dist/eeprom.d.ts +16 -0
- package/dist/eeprom.js +21 -0
- package/dist/emit.d.ts +121 -0
- package/dist/emit.js +177 -0
- package/dist/fs.d.ts +13 -0
- package/dist/fs.js +39 -0
- package/dist/gpio.d.ts +108 -0
- package/dist/gpio.js +230 -0
- package/dist/i2c.d.ts +40 -0
- package/dist/i2c.js +126 -0
- package/dist/include.d.ts +5 -0
- package/dist/include.js +5 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.js +30 -0
- package/dist/interrupts.d.ts +17 -0
- package/dist/interrupts.js +25 -0
- package/dist/math.d.ts +22 -0
- package/dist/math.js +28 -0
- package/dist/power.d.ts +14 -0
- package/dist/power.js +21 -0
- package/dist/preferences.d.ts +18 -0
- package/dist/preferences.js +55 -0
- package/dist/pulse.d.ts +24 -0
- package/dist/pulse.js +53 -0
- package/dist/random.d.ts +12 -0
- package/dist/random.js +26 -0
- package/dist/register.d.ts +11 -0
- package/dist/register.js +21 -0
- package/dist/shift.d.ts +31 -0
- package/dist/shift.js +71 -0
- package/dist/spi.d.ts +31 -0
- package/dist/spi.js +90 -0
- package/dist/timer.d.ts +35 -0
- package/dist/timer.js +50 -0
- package/dist/timing.d.ts +29 -0
- package/dist/timing.js +53 -0
- package/dist/types.d.ts +48 -0
- package/dist/types.js +67 -0
- package/dist/uart.d.ts +21 -0
- package/dist/uart.js +58 -0
- package/dist/utils.d.ts +10 -0
- package/dist/utils.js +14 -0
- package/dist/wdt.d.ts +7 -0
- package/dist/wdt.js +14 -0
- package/package.json +64 -0
- package/src/adc.ts +30 -0
- package/src/async.ts +63 -0
- package/src/board.ts +5 -0
- package/src/callback.ts +6 -0
- package/src/constants.ts +23 -0
- package/src/dac.ts +21 -0
- package/src/eeprom.ts +26 -0
- package/src/emit.ts +210 -0
- package/src/fs.ts +46 -0
- package/src/gpio.ts +298 -0
- package/src/i2c.ts +155 -0
- package/src/include.ts +5 -0
- package/src/index.ts +48 -0
- package/src/interrupts.ts +35 -0
- package/src/math.ts +32 -0
- package/src/power.ts +26 -0
- package/src/preferences.ts +58 -0
- package/src/pulse.ts +63 -0
- package/src/random.ts +31 -0
- package/src/register.ts +35 -0
- package/src/shift.ts +88 -0
- package/src/spi.ts +118 -0
- package/src/timer.ts +59 -0
- package/src/timing.ts +67 -0
- package/src/types.ts +144 -0
- package/src/uart.ts +77 -0
- package/src/utils.ts +17 -0
- package/src/wdt.ts +17 -0
package/dist/emit.js
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// HAL compile-time semantic functions
|
|
3
|
+
//
|
|
4
|
+
// These functions are resolved to HALOpIR nodes by the transpiler's HAL
|
|
5
|
+
// resolver. The framework strategy translates each operation into
|
|
6
|
+
// framework-specific C++ at code generation time.
|
|
7
|
+
//
|
|
8
|
+
// Pin parameters accept both `number` (legacy framework pin number) and
|
|
9
|
+
// `string` (MCU port name like "PB5"). The transpiler resolves port names
|
|
10
|
+
// to framework pin numbers via the MCU package's pin mapping.
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// GPIO — digital pin control
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
/** Set a digital pin HIGH or LOW. */
|
|
16
|
+
export function gpioWrite(pin, value) { }
|
|
17
|
+
/** Read a digital pin. Returns HIGH (1) or LOW (0). */
|
|
18
|
+
export function gpioRead(pin) { return 0; }
|
|
19
|
+
/** Toggle a digital pin. */
|
|
20
|
+
export function gpioToggle(pin) { }
|
|
21
|
+
/** Set pin mode: "output" | "input" | "input_pullup" | "input_pulldown". */
|
|
22
|
+
export function gpioSetMode(pin, mode) { }
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
// PWM — pulse-width modulation
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
/** Write PWM duty cycle to a pin. */
|
|
27
|
+
export function pwmWrite(pin, duty) { }
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// ADC — analog-to-digital conversion
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
/** Read analog value from a pin. */
|
|
32
|
+
export function adcRead(pin) { return 0; }
|
|
33
|
+
/** Read analog voltage from a pin (ADC value converted to voltage). */
|
|
34
|
+
export function adcReadVoltage(pin) { return 0; }
|
|
35
|
+
/** Set the analog reference. */
|
|
36
|
+
export function adcSetReference(ref) { }
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
// Interrupts
|
|
39
|
+
// ---------------------------------------------------------------------------
|
|
40
|
+
/** Attach an interrupt handler to a pin. */
|
|
41
|
+
export function interruptAttach(pin, handler, mode) { }
|
|
42
|
+
/** Detach an interrupt from a pin. */
|
|
43
|
+
export function interruptDetach(pin) { }
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Tone / audio output
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
/** Play a tone on a pin at the given frequency, optionally for a duration. */
|
|
48
|
+
export function tonePlay(pin, frequency, duration) { }
|
|
49
|
+
/** Stop tone playback on a pin. */
|
|
50
|
+
export function toneStop(pin) { }
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
// Timing
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
/** Delay for the given number of milliseconds. */
|
|
55
|
+
export function delayMs(ms) { }
|
|
56
|
+
/** Delay for the given number of microseconds. */
|
|
57
|
+
export function delayMicro(us) { }
|
|
58
|
+
/** Get milliseconds since boot. */
|
|
59
|
+
export function getMillis() { return 0; }
|
|
60
|
+
/** Get microseconds since boot. */
|
|
61
|
+
export function getMicros() { return 0; }
|
|
62
|
+
/** Get free heap bytes. Architecture-aware: the strategy maps this to the right
|
|
63
|
+
* symbol per target (ESP.getFreeHeap() on ESP32, __heap_start trick on AVR). */
|
|
64
|
+
export function getFreeHeap() { return 0; }
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// I2C — inter-integrated circuit bus
|
|
67
|
+
// ---------------------------------------------------------------------------
|
|
68
|
+
/** Initialize I2C bus (master mode if no address, slave mode with address). */
|
|
69
|
+
export function i2cBegin(bus, address) { }
|
|
70
|
+
/** Disable I2C bus. */
|
|
71
|
+
export function i2cEnd(bus) { }
|
|
72
|
+
/** Set I2C bus clock speed. */
|
|
73
|
+
export function i2cSetClock(bus, hz) { }
|
|
74
|
+
/** Begin I2C transmission to a slave address. */
|
|
75
|
+
export function i2cBeginTx(bus, address) { }
|
|
76
|
+
/** Write data to I2C bus. */
|
|
77
|
+
export function i2cWrite(bus, data) { }
|
|
78
|
+
/** Write a byte buffer to I2C bus (expands array literals to per-byte writes). */
|
|
79
|
+
export function i2cWriteBuffer(bus, data) { }
|
|
80
|
+
/** End I2C transmission. Returns status. */
|
|
81
|
+
export function i2cEndTx(bus, stop) { return 0; }
|
|
82
|
+
/** Request bytes from I2C slave. */
|
|
83
|
+
export function i2cRequestFrom(bus, address, quantity, stop) { return 0; }
|
|
84
|
+
/** Check if bytes are available from I2C. */
|
|
85
|
+
export function i2cAvailable(bus) { return 0; }
|
|
86
|
+
/** Read a byte from I2C. */
|
|
87
|
+
export function i2cRead(bus) { return 0; }
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// SPI — serial peripheral interface
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
/** Initialize SPI bus. */
|
|
92
|
+
export function spiBegin(bus) { }
|
|
93
|
+
/** Disable SPI bus. */
|
|
94
|
+
export function spiEnd(bus) { }
|
|
95
|
+
/** Transfer data on SPI bus. */
|
|
96
|
+
export function spiTransfer(bus, data) { return 0; }
|
|
97
|
+
/** Begin SPI transaction with settings. */
|
|
98
|
+
export function spiBeginTx(bus, settings) { }
|
|
99
|
+
/** End SPI transaction. */
|
|
100
|
+
export function spiEndTx(bus) { }
|
|
101
|
+
/** Set SPI chip-select pin LOW. */
|
|
102
|
+
export function spiCsLow(pin) { }
|
|
103
|
+
/** Set SPI chip-select pin HIGH. */
|
|
104
|
+
export function spiCsHigh(pin) { }
|
|
105
|
+
/** Set SPI data mode. */
|
|
106
|
+
export function spiSetMode(bus, mode) { }
|
|
107
|
+
/** Set SPI bit order. */
|
|
108
|
+
export function spiSetBitOrder(bus, order) { }
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
// UART — serial communication
|
|
111
|
+
// ---------------------------------------------------------------------------
|
|
112
|
+
/** Initialize serial port with baud rate. */
|
|
113
|
+
export function uartBegin(port, baud) { }
|
|
114
|
+
/** Disable serial port. */
|
|
115
|
+
export function uartEnd(port) { }
|
|
116
|
+
/** Print value to serial. */
|
|
117
|
+
export function uartPrint(port, value) { }
|
|
118
|
+
/** Print value with newline to serial. */
|
|
119
|
+
export function uartPrintln(port, value) { }
|
|
120
|
+
/** printf-style formatted print to serial. */
|
|
121
|
+
export function uartPrintf(port, format, args) { }
|
|
122
|
+
/** Write raw data to serial. */
|
|
123
|
+
export function uartWrite(port, data) { }
|
|
124
|
+
/** Read a byte from serial. */
|
|
125
|
+
export function uartRead(port) { return 0; }
|
|
126
|
+
/** Peek at next byte from serial without consuming. */
|
|
127
|
+
export function uartPeek(port) { return 0; }
|
|
128
|
+
/** Check if bytes are available from serial. */
|
|
129
|
+
export function uartAvailable(port) { return 0; }
|
|
130
|
+
/** Flush serial output. */
|
|
131
|
+
export function uartFlush(port) { }
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// Pulse measurement
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
/** Measure pulse duration on a pin. */
|
|
136
|
+
export function pulseIn_(pin, value, timeout) { return 0; }
|
|
137
|
+
/** Measure long pulse using high-precision timer. */
|
|
138
|
+
export function pulseInLong_(pin, value) { return 0; }
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
// Shift register
|
|
141
|
+
// ---------------------------------------------------------------------------
|
|
142
|
+
/** Shift a byte out to a pin. */
|
|
143
|
+
export function shiftOut_(dataPin, clockPin, bitOrder, value) { }
|
|
144
|
+
/** Shift a byte in from a pin. */
|
|
145
|
+
export function shiftIn_(dataPin, clockPin, bitOrder) { return 0; }
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Board constant resolution
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
/** Write a value to a DAC pin. */
|
|
150
|
+
export function dacWrite(pin, value) { }
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// Watchdog timer (WDT)
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
/** Enable the watchdog timer with the given timeout (string preset or number). */
|
|
155
|
+
export function wdtEnable(timeout) { }
|
|
156
|
+
/** Reset (kick) the watchdog timer. */
|
|
157
|
+
export function wdtReset() { }
|
|
158
|
+
/** Disable the watchdog timer. */
|
|
159
|
+
export function wdtDisable() { }
|
|
160
|
+
/** Resolve a board definition path to a compile-time constant. */
|
|
161
|
+
export function boardResolve(path) { return undefined; }
|
|
162
|
+
// ---------------------------------------------------------------------------
|
|
163
|
+
// Power — MCU power states and clock frequency
|
|
164
|
+
// ---------------------------------------------------------------------------
|
|
165
|
+
/** Enter deep sleep for the given duration (ms). Architecture-aware: the
|
|
166
|
+
* strategy emits the right call per target (esp_deep_sleep on ESP32, a
|
|
167
|
+
* not-supported comment elsewhere). */
|
|
168
|
+
export function powerDeepSleep(ms) { }
|
|
169
|
+
/** Enter light sleep. Architecture-aware. */
|
|
170
|
+
export function powerLightSleep() { }
|
|
171
|
+
/** Set the CPU frequency (MHz). */
|
|
172
|
+
export function powerSetCpuFrequency(mhz) { }
|
|
173
|
+
// ---------------------------------------------------------------------------
|
|
174
|
+
// Raw C++ escape hatch
|
|
175
|
+
// ---------------------------------------------------------------------------
|
|
176
|
+
/** Emit raw C++ code (escape hatch for unsupported operations). */
|
|
177
|
+
export function rawCpp(code) { }
|
package/dist/fs.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FSClass provides a high-level abstraction for filesystem operations.
|
|
3
|
+
* Maps to SD.h or LittleFS depending on the board configuration.
|
|
4
|
+
*/
|
|
5
|
+
export declare class FSClass {
|
|
6
|
+
static readonly __instance_name = "FS";
|
|
7
|
+
begin(): boolean;
|
|
8
|
+
readText(path: string): string;
|
|
9
|
+
writeText(path: string, content: string): void;
|
|
10
|
+
exists(path: string): boolean;
|
|
11
|
+
remove(path: string): boolean;
|
|
12
|
+
}
|
|
13
|
+
export declare const FS: FSClass;
|
package/dist/fs.js
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { rawCpp } from './emit.js';
|
|
2
|
+
import { include } from './include.js';
|
|
3
|
+
/**
|
|
4
|
+
* FSClass provides a high-level abstraction for filesystem operations.
|
|
5
|
+
* Maps to SD.h or LittleFS depending on the board configuration.
|
|
6
|
+
*/
|
|
7
|
+
export class FSClass {
|
|
8
|
+
begin() {
|
|
9
|
+
include("<FS.h>");
|
|
10
|
+
rawCpp(`return FS.begin();`);
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
readText(path) {
|
|
14
|
+
include("<FS.h>");
|
|
15
|
+
rawCpp(`File f = FS.open(${path}.c_str(), "r");`);
|
|
16
|
+
rawCpp(`if (!f) return "";`);
|
|
17
|
+
rawCpp(`String s = f.readString();`);
|
|
18
|
+
rawCpp(`f.close();`);
|
|
19
|
+
rawCpp(`return s.c_str();`);
|
|
20
|
+
return "";
|
|
21
|
+
}
|
|
22
|
+
writeText(path, content) {
|
|
23
|
+
include("<FS.h>");
|
|
24
|
+
rawCpp(`File f = FS.open(${path}.c_str(), "w");`);
|
|
25
|
+
rawCpp(`if (f) { f.print(${content}.c_str()); f.close(); }`);
|
|
26
|
+
}
|
|
27
|
+
exists(path) {
|
|
28
|
+
include("<FS.h>");
|
|
29
|
+
rawCpp(`return FS.exists(${path}.c_str());`);
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
remove(path) {
|
|
33
|
+
include("<FS.h>");
|
|
34
|
+
rawCpp(`return FS.remove(${path}.c_str());`);
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
FSClass.__instance_name = "FS";
|
|
39
|
+
export const FS = new FSClass();
|
package/dist/gpio.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
export declare class OutputPin {
|
|
2
|
+
private _pin;
|
|
3
|
+
readonly number: number;
|
|
4
|
+
readonly gpio: number;
|
|
5
|
+
constructor(pin: number);
|
|
6
|
+
high(): void;
|
|
7
|
+
low(): void;
|
|
8
|
+
toggle(): void;
|
|
9
|
+
write(value: number | boolean): void;
|
|
10
|
+
pulse(durationMs: number): void;
|
|
11
|
+
tone(frequency: number): ToneChain;
|
|
12
|
+
toneFor(frequency: number, duration: number): void;
|
|
13
|
+
noTone(): void;
|
|
14
|
+
pwm(duty: number): void;
|
|
15
|
+
getPwmFrequency(): number;
|
|
16
|
+
getPwmResolution(): number;
|
|
17
|
+
}
|
|
18
|
+
export declare class InputPin {
|
|
19
|
+
private _pin;
|
|
20
|
+
readonly number: number;
|
|
21
|
+
readonly gpio: number;
|
|
22
|
+
constructor(pin: number);
|
|
23
|
+
read(): boolean;
|
|
24
|
+
isHigh(): boolean;
|
|
25
|
+
isLow(): boolean;
|
|
26
|
+
readAnalog(): number;
|
|
27
|
+
readVoltage(): number;
|
|
28
|
+
getAnalogResolution(): number;
|
|
29
|
+
setAnalogReference(ref: string): void;
|
|
30
|
+
onFalling(handler: () => void): void;
|
|
31
|
+
onRising(handler: () => void): void;
|
|
32
|
+
onChange(handler: () => void): void;
|
|
33
|
+
offAll(): void;
|
|
34
|
+
/** Alias matching the BasePin.offInterrupts() interface name. */
|
|
35
|
+
offInterrupts(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Wait for a RISING edge on this input pin.
|
|
38
|
+
* Returns a Promise<void> that resolves when the pin transitions from LOW to HIGH.
|
|
39
|
+
* The platform strategy controls whether this uses interrupts, polling, or a stub.
|
|
40
|
+
*
|
|
41
|
+
* @param timeout Optional timeout in milliseconds. If provided, the promise
|
|
42
|
+
* rejects (or resolves with a false/error) after the timeout expires.
|
|
43
|
+
*/
|
|
44
|
+
waitForRising(timeout?: number): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Wait for a FALLING edge on this input pin.
|
|
47
|
+
* Returns a Promise<void> that resolves when the pin transitions from HIGH to LOW.
|
|
48
|
+
*
|
|
49
|
+
* @param timeout Optional timeout in milliseconds. If provided, the promise
|
|
50
|
+
* rejects (or resolves with a false/error) after the timeout expires.
|
|
51
|
+
*/
|
|
52
|
+
waitForFalling(timeout?: number): Promise<void>;
|
|
53
|
+
}
|
|
54
|
+
export declare class ToneChain {
|
|
55
|
+
private _pin;
|
|
56
|
+
private _lastFreq;
|
|
57
|
+
constructor(pin: number, frequency: number);
|
|
58
|
+
for(duration: number): void;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Represents a physical hardware pin before it has been configured for a specific mode.
|
|
62
|
+
* Use `.asInput()` or `.asOutput()` to obtain a functional pin instance.
|
|
63
|
+
*
|
|
64
|
+
* Pins can be created two ways:
|
|
65
|
+
* - `new Pin(number)` — legacy, using framework pin number (e.g. Arduino pin 13)
|
|
66
|
+
* - `Pin.fromPort("PB5")` — preferred, using MCU datasheet port name
|
|
67
|
+
*
|
|
68
|
+
* When created via `fromPort()`, the pin carries its canonical port identity.
|
|
69
|
+
* The transpiler resolves the port name to a framework pin number at compile time
|
|
70
|
+
* using the MCU package's pin mapping (e.g. arduino-map.ts).
|
|
71
|
+
*/
|
|
72
|
+
export declare class Pin {
|
|
73
|
+
/** MCU port name (e.g. "PB5") — empty string for legacy numeric pins */
|
|
74
|
+
private _port;
|
|
75
|
+
/** Framework pin number (e.g. 13 for Arduino). -1 for port-based pins. */
|
|
76
|
+
private _pin;
|
|
77
|
+
/** Public readonly access to port name */
|
|
78
|
+
readonly port: string;
|
|
79
|
+
readonly number: number;
|
|
80
|
+
readonly gpio: number;
|
|
81
|
+
/** Legacy constructor — creates a Pin from a framework pin number */
|
|
82
|
+
constructor(pin: number);
|
|
83
|
+
/**
|
|
84
|
+
* Create a Pin from its MCU datasheet port name (e.g. "PB5", "PC0").
|
|
85
|
+
* The port name is the canonical identity; framework-specific pin numbers
|
|
86
|
+
* are resolved at transpile time via the MCU package's pin mapping.
|
|
87
|
+
*/
|
|
88
|
+
static fromPort(portName: string): Pin;
|
|
89
|
+
asOutput(initial?: number | boolean): OutputPin;
|
|
90
|
+
/** Alias for asOutput() — shorter fluent form. */
|
|
91
|
+
output(initial?: number | boolean): OutputPin;
|
|
92
|
+
asInput(): InputPin;
|
|
93
|
+
asInputPullUp(): InputPin;
|
|
94
|
+
asInputPullDown(): InputPin;
|
|
95
|
+
inputPullUp(): InputPin;
|
|
96
|
+
/** Alias for asInputPullDown() — shorter fluent form. */
|
|
97
|
+
inputPullDown(): InputPin;
|
|
98
|
+
read(): boolean;
|
|
99
|
+
isHigh(): boolean;
|
|
100
|
+
isLow(): boolean;
|
|
101
|
+
write(value: number | boolean): void;
|
|
102
|
+
high(): void;
|
|
103
|
+
low(): void;
|
|
104
|
+
toggle(): void;
|
|
105
|
+
pwm(duty: number): void;
|
|
106
|
+
tone(frequency: number): ToneChain;
|
|
107
|
+
noTone(): void;
|
|
108
|
+
}
|
package/dist/gpio.js
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
import { gpioWrite, gpioRead, gpioToggle, gpioSetMode, tonePlay, toneStop, adcRead, adcReadVoltage, adcSetReference, interruptAttach, interruptDetach, pwmWrite, rawCpp, boardResolve } from './emit.js';
|
|
2
|
+
import { callback } from './callback.js';
|
|
3
|
+
import { ADC } from './adc.js';
|
|
4
|
+
export class OutputPin {
|
|
5
|
+
constructor(pin) {
|
|
6
|
+
this._pin = pin;
|
|
7
|
+
this.number = pin;
|
|
8
|
+
this.gpio = pin;
|
|
9
|
+
}
|
|
10
|
+
high() {
|
|
11
|
+
gpioWrite(this._pin, 1);
|
|
12
|
+
}
|
|
13
|
+
low() {
|
|
14
|
+
gpioWrite(this._pin, 0);
|
|
15
|
+
}
|
|
16
|
+
toggle() {
|
|
17
|
+
gpioToggle(this._pin);
|
|
18
|
+
}
|
|
19
|
+
write(value) {
|
|
20
|
+
gpioWrite(this._pin, value);
|
|
21
|
+
}
|
|
22
|
+
pulse(durationMs) {
|
|
23
|
+
gpioWrite(this._pin, 1);
|
|
24
|
+
rawCpp(`delay(${durationMs});`);
|
|
25
|
+
gpioWrite(this._pin, 0);
|
|
26
|
+
}
|
|
27
|
+
tone(frequency) {
|
|
28
|
+
tonePlay(this._pin, frequency);
|
|
29
|
+
return new ToneChain(this._pin, frequency);
|
|
30
|
+
}
|
|
31
|
+
toneFor(frequency, duration) {
|
|
32
|
+
tonePlay(this._pin, frequency, duration);
|
|
33
|
+
}
|
|
34
|
+
noTone() {
|
|
35
|
+
toneStop(this._pin);
|
|
36
|
+
}
|
|
37
|
+
pwm(duty) {
|
|
38
|
+
pwmWrite(this._pin, duty);
|
|
39
|
+
}
|
|
40
|
+
getPwmFrequency() {
|
|
41
|
+
return boardResolve("peripherals.pwm.maxFrequency");
|
|
42
|
+
}
|
|
43
|
+
getPwmResolution() {
|
|
44
|
+
return boardResolve("peripherals.pwm.resolution");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export class InputPin {
|
|
48
|
+
constructor(pin) {
|
|
49
|
+
this._pin = pin;
|
|
50
|
+
this.number = pin;
|
|
51
|
+
this.gpio = pin;
|
|
52
|
+
}
|
|
53
|
+
read() {
|
|
54
|
+
return gpioRead(this._pin);
|
|
55
|
+
}
|
|
56
|
+
isHigh() {
|
|
57
|
+
return this.read();
|
|
58
|
+
}
|
|
59
|
+
isLow() {
|
|
60
|
+
return !this.read();
|
|
61
|
+
}
|
|
62
|
+
readAnalog() {
|
|
63
|
+
return adcRead(this._pin);
|
|
64
|
+
}
|
|
65
|
+
readVoltage() {
|
|
66
|
+
return adcReadVoltage(this._pin);
|
|
67
|
+
}
|
|
68
|
+
getAnalogResolution() {
|
|
69
|
+
return boardResolve("peripherals.adc.0.resolution");
|
|
70
|
+
}
|
|
71
|
+
setAnalogReference(ref) {
|
|
72
|
+
ADC._reference = ref;
|
|
73
|
+
adcSetReference(ref);
|
|
74
|
+
}
|
|
75
|
+
onFalling(handler) {
|
|
76
|
+
interruptAttach(this._pin, callback(handler), "FALLING");
|
|
77
|
+
}
|
|
78
|
+
onRising(handler) {
|
|
79
|
+
interruptAttach(this._pin, callback(handler), "RISING");
|
|
80
|
+
}
|
|
81
|
+
onChange(handler) {
|
|
82
|
+
interruptAttach(this._pin, callback(handler), "CHANGE");
|
|
83
|
+
}
|
|
84
|
+
offAll() {
|
|
85
|
+
interruptDetach(this._pin);
|
|
86
|
+
}
|
|
87
|
+
/** Alias matching the BasePin.offInterrupts() interface name. */
|
|
88
|
+
offInterrupts() {
|
|
89
|
+
interruptDetach(this._pin);
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Wait for a RISING edge on this input pin.
|
|
93
|
+
* Returns a Promise<void> that resolves when the pin transitions from LOW to HIGH.
|
|
94
|
+
* The platform strategy controls whether this uses interrupts, polling, or a stub.
|
|
95
|
+
*
|
|
96
|
+
* @param timeout Optional timeout in milliseconds. If provided, the promise
|
|
97
|
+
* rejects (or resolves with a false/error) after the timeout expires.
|
|
98
|
+
*/
|
|
99
|
+
waitForRising(timeout) {
|
|
100
|
+
rawCpp(`__cuttlefish_wait_pin_edge(${this._pin}, RISING, ${timeout ?? -1});`);
|
|
101
|
+
return Promise.resolve();
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Wait for a FALLING edge on this input pin.
|
|
105
|
+
* Returns a Promise<void> that resolves when the pin transitions from HIGH to LOW.
|
|
106
|
+
*
|
|
107
|
+
* @param timeout Optional timeout in milliseconds. If provided, the promise
|
|
108
|
+
* rejects (or resolves with a false/error) after the timeout expires.
|
|
109
|
+
*/
|
|
110
|
+
waitForFalling(timeout) {
|
|
111
|
+
rawCpp(`__cuttlefish_wait_pin_edge(${this._pin}, FALLING, ${timeout ?? -1});`);
|
|
112
|
+
return Promise.resolve();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
export class ToneChain {
|
|
116
|
+
constructor(pin, frequency) {
|
|
117
|
+
this._pin = pin;
|
|
118
|
+
this._lastFreq = frequency;
|
|
119
|
+
}
|
|
120
|
+
for(duration) {
|
|
121
|
+
tonePlay(this._pin, this._lastFreq, duration);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Represents a physical hardware pin before it has been configured for a specific mode.
|
|
126
|
+
* Use `.asInput()` or `.asOutput()` to obtain a functional pin instance.
|
|
127
|
+
*
|
|
128
|
+
* Pins can be created two ways:
|
|
129
|
+
* - `new Pin(number)` — legacy, using framework pin number (e.g. Arduino pin 13)
|
|
130
|
+
* - `Pin.fromPort("PB5")` — preferred, using MCU datasheet port name
|
|
131
|
+
*
|
|
132
|
+
* When created via `fromPort()`, the pin carries its canonical port identity.
|
|
133
|
+
* The transpiler resolves the port name to a framework pin number at compile time
|
|
134
|
+
* using the MCU package's pin mapping (e.g. arduino-map.ts).
|
|
135
|
+
*/
|
|
136
|
+
export class Pin {
|
|
137
|
+
/** Legacy constructor — creates a Pin from a framework pin number */
|
|
138
|
+
constructor(pin) {
|
|
139
|
+
this._port = '';
|
|
140
|
+
this._pin = pin;
|
|
141
|
+
this.port = '';
|
|
142
|
+
this.number = pin;
|
|
143
|
+
this.gpio = pin;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Create a Pin from its MCU datasheet port name (e.g. "PB5", "PC0").
|
|
147
|
+
* The port name is the canonical identity; framework-specific pin numbers
|
|
148
|
+
* are resolved at transpile time via the MCU package's pin mapping.
|
|
149
|
+
*/
|
|
150
|
+
static fromPort(portName) {
|
|
151
|
+
const p = new Pin(-1);
|
|
152
|
+
p._port = portName;
|
|
153
|
+
// Bypass readonly for factory method
|
|
154
|
+
p.port = portName;
|
|
155
|
+
return p;
|
|
156
|
+
}
|
|
157
|
+
asOutput(initial) {
|
|
158
|
+
gpioSetMode(this._pin, "OUTPUT");
|
|
159
|
+
if (initial !== undefined) {
|
|
160
|
+
gpioWrite(this._pin, initial);
|
|
161
|
+
}
|
|
162
|
+
// Returns `this` so the transpiler can suppress the C++ return emission
|
|
163
|
+
// (it resolves `this` to the same instance and tracks the result as an
|
|
164
|
+
// OutputPin via the method name). Returning `new OutputPin(this._pin)`
|
|
165
|
+
// would leak the literal text into generated C++. The cast is required
|
|
166
|
+
// because Pin and OutputPin are structurally distinct classes; the
|
|
167
|
+
// transpiler handles the mode transition semantically.
|
|
168
|
+
return this;
|
|
169
|
+
}
|
|
170
|
+
/** Alias for asOutput() — shorter fluent form. */
|
|
171
|
+
output(initial) {
|
|
172
|
+
gpioSetMode(this._pin, "OUTPUT");
|
|
173
|
+
if (initial !== undefined) {
|
|
174
|
+
gpioWrite(this._pin, initial);
|
|
175
|
+
}
|
|
176
|
+
return this;
|
|
177
|
+
}
|
|
178
|
+
asInput() {
|
|
179
|
+
gpioSetMode(this._pin, "INPUT");
|
|
180
|
+
return this;
|
|
181
|
+
}
|
|
182
|
+
asInputPullUp() {
|
|
183
|
+
gpioSetMode(this._pin, "INPUT_PULLUP");
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
asInputPullDown() {
|
|
187
|
+
gpioSetMode(this._pin, "INPUT_PULLDOWN");
|
|
188
|
+
return this;
|
|
189
|
+
}
|
|
190
|
+
inputPullUp() {
|
|
191
|
+
gpioSetMode(this._pin, "INPUT_PULLUP");
|
|
192
|
+
return this;
|
|
193
|
+
}
|
|
194
|
+
/** Alias for asInputPullDown() — shorter fluent form. */
|
|
195
|
+
inputPullDown() {
|
|
196
|
+
gpioSetMode(this._pin, "INPUT_PULLDOWN");
|
|
197
|
+
return this;
|
|
198
|
+
}
|
|
199
|
+
read() {
|
|
200
|
+
return gpioRead(this._pin);
|
|
201
|
+
}
|
|
202
|
+
isHigh() {
|
|
203
|
+
return this.read();
|
|
204
|
+
}
|
|
205
|
+
isLow() {
|
|
206
|
+
return !this.read();
|
|
207
|
+
}
|
|
208
|
+
write(value) {
|
|
209
|
+
gpioWrite(this._pin, value);
|
|
210
|
+
}
|
|
211
|
+
high() {
|
|
212
|
+
gpioWrite(this._pin, 1);
|
|
213
|
+
}
|
|
214
|
+
low() {
|
|
215
|
+
gpioWrite(this._pin, 0);
|
|
216
|
+
}
|
|
217
|
+
toggle() {
|
|
218
|
+
gpioToggle(this._pin);
|
|
219
|
+
}
|
|
220
|
+
pwm(duty) {
|
|
221
|
+
pwmWrite(this._pin, duty);
|
|
222
|
+
}
|
|
223
|
+
tone(frequency) {
|
|
224
|
+
tonePlay(this._pin, frequency);
|
|
225
|
+
return new ToneChain(this._pin, frequency);
|
|
226
|
+
}
|
|
227
|
+
noTone() {
|
|
228
|
+
toneStop(this._pin);
|
|
229
|
+
}
|
|
230
|
+
}
|
package/dist/i2c.d.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export declare class I2CDevice {
|
|
2
|
+
private _bus;
|
|
3
|
+
private _address;
|
|
4
|
+
constructor(bus: string, address: number);
|
|
5
|
+
writeByte(register: number, value: number): void;
|
|
6
|
+
readByte(register: number): number;
|
|
7
|
+
writeBytes(register: number, data: number[] | Uint8Array): void;
|
|
8
|
+
readBytes(register: number, count: number): Uint8Array;
|
|
9
|
+
}
|
|
10
|
+
export declare class I2CBus {
|
|
11
|
+
static readonly __includes: string[];
|
|
12
|
+
private _bus;
|
|
13
|
+
constructor(bus: string);
|
|
14
|
+
device(address: number): I2CDevice;
|
|
15
|
+
begin(): this;
|
|
16
|
+
beginSlave(address: number): void;
|
|
17
|
+
end(): void;
|
|
18
|
+
setClock(hz: number): void;
|
|
19
|
+
/** Recover a locked I2C bus by clocking SCL until the stuck slave releases SDA.
|
|
20
|
+
*
|
|
21
|
+
* NOTE: This references the board-defined `SCL` pin macro. All current MCU
|
|
22
|
+
* packages (atmega328p, esp32, esp32c3, esp32c6, esp32s3) export SCL, so
|
|
23
|
+
* this works in practice. A fully portable version would resolve the SCL
|
|
24
|
+
* pin number via a board constant (e.g. peripherals.i2c.0.sclPin), but that
|
|
25
|
+
* requires adding resolved numeric pin fields to the board-constants
|
|
26
|
+
* pipeline — deferred for now. */
|
|
27
|
+
recover(): void;
|
|
28
|
+
take(): this | null;
|
|
29
|
+
release(): void;
|
|
30
|
+
writeByte(address: number, register: number, value: number): void;
|
|
31
|
+
readByte(address: number, register: number): number;
|
|
32
|
+
beginTransmission(address: number): void;
|
|
33
|
+
write(data: number | number[] | Uint8Array): void;
|
|
34
|
+
endTransmission(stop?: boolean): number;
|
|
35
|
+
requestFrom(address: number, quantity: number, stop?: boolean): number;
|
|
36
|
+
available(): number;
|
|
37
|
+
read(): number;
|
|
38
|
+
}
|
|
39
|
+
/** Map TypeCAD I2C instance number to Arduino C++ object name. I2C0→Wire, I2C1→Wire1 */
|
|
40
|
+
export declare function i2cName(instance: number): string;
|