@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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +127 -0
  3. package/dist/adc.d.ts +13 -0
  4. package/dist/adc.js +22 -0
  5. package/dist/async.d.ts +30 -0
  6. package/dist/async.js +56 -0
  7. package/dist/board.d.ts +3 -0
  8. package/dist/board.js +5 -0
  9. package/dist/callback.d.ts +4 -0
  10. package/dist/callback.js +6 -0
  11. package/dist/constants.d.ts +21 -0
  12. package/dist/constants.js +23 -0
  13. package/dist/dac.d.ts +12 -0
  14. package/dist/dac.js +17 -0
  15. package/dist/eeprom.d.ts +16 -0
  16. package/dist/eeprom.js +21 -0
  17. package/dist/emit.d.ts +121 -0
  18. package/dist/emit.js +177 -0
  19. package/dist/fs.d.ts +13 -0
  20. package/dist/fs.js +39 -0
  21. package/dist/gpio.d.ts +108 -0
  22. package/dist/gpio.js +230 -0
  23. package/dist/i2c.d.ts +40 -0
  24. package/dist/i2c.js +126 -0
  25. package/dist/include.d.ts +5 -0
  26. package/dist/include.js +5 -0
  27. package/dist/index.d.ts +37 -0
  28. package/dist/index.js +30 -0
  29. package/dist/interrupts.d.ts +17 -0
  30. package/dist/interrupts.js +25 -0
  31. package/dist/math.d.ts +22 -0
  32. package/dist/math.js +28 -0
  33. package/dist/power.d.ts +14 -0
  34. package/dist/power.js +21 -0
  35. package/dist/preferences.d.ts +18 -0
  36. package/dist/preferences.js +55 -0
  37. package/dist/pulse.d.ts +24 -0
  38. package/dist/pulse.js +53 -0
  39. package/dist/random.d.ts +12 -0
  40. package/dist/random.js +26 -0
  41. package/dist/register.d.ts +11 -0
  42. package/dist/register.js +21 -0
  43. package/dist/shift.d.ts +31 -0
  44. package/dist/shift.js +71 -0
  45. package/dist/spi.d.ts +31 -0
  46. package/dist/spi.js +90 -0
  47. package/dist/timer.d.ts +35 -0
  48. package/dist/timer.js +50 -0
  49. package/dist/timing.d.ts +29 -0
  50. package/dist/timing.js +53 -0
  51. package/dist/types.d.ts +48 -0
  52. package/dist/types.js +67 -0
  53. package/dist/uart.d.ts +21 -0
  54. package/dist/uart.js +58 -0
  55. package/dist/utils.d.ts +10 -0
  56. package/dist/utils.js +14 -0
  57. package/dist/wdt.d.ts +7 -0
  58. package/dist/wdt.js +14 -0
  59. package/package.json +64 -0
  60. package/src/adc.ts +30 -0
  61. package/src/async.ts +63 -0
  62. package/src/board.ts +5 -0
  63. package/src/callback.ts +6 -0
  64. package/src/constants.ts +23 -0
  65. package/src/dac.ts +21 -0
  66. package/src/eeprom.ts +26 -0
  67. package/src/emit.ts +210 -0
  68. package/src/fs.ts +46 -0
  69. package/src/gpio.ts +298 -0
  70. package/src/i2c.ts +155 -0
  71. package/src/include.ts +5 -0
  72. package/src/index.ts +48 -0
  73. package/src/interrupts.ts +35 -0
  74. package/src/math.ts +32 -0
  75. package/src/power.ts +26 -0
  76. package/src/preferences.ts +58 -0
  77. package/src/pulse.ts +63 -0
  78. package/src/random.ts +31 -0
  79. package/src/register.ts +35 -0
  80. package/src/shift.ts +88 -0
  81. package/src/spi.ts +118 -0
  82. package/src/timer.ts +59 -0
  83. package/src/timing.ts +67 -0
  84. package/src/types.ts +144 -0
  85. package/src/uart.ts +77 -0
  86. package/src/utils.ts +17 -0
  87. 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;