@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/shift.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { rawCpp } from './emit.js';
|
|
2
|
+
import { LSBFIRST, MSBFIRST } from './constants.js';
|
|
3
|
+
export function shiftIn(dataPin, clockPin, bitOrder) {
|
|
4
|
+
rawCpp(`return shiftIn(${dataPin}, ${clockPin}, ${bitOrder});`);
|
|
5
|
+
return 0;
|
|
6
|
+
}
|
|
7
|
+
export function shiftOut(dataPin, clockPin, bitOrder, value) {
|
|
8
|
+
rawCpp(`shiftOut(${dataPin}, ${clockPin}, ${bitOrder}, ${value});`);
|
|
9
|
+
}
|
|
10
|
+
export class Shift {
|
|
11
|
+
/** Directly shifts a byte out to a pin. */
|
|
12
|
+
static out(dataPin, clockPin, order, value) {
|
|
13
|
+
const bitOrder = order === 'lsb' ? LSBFIRST : MSBFIRST;
|
|
14
|
+
rawCpp(`shiftOut(${dataPin.number}, ${clockPin.number}, ${bitOrder}, ${value});`);
|
|
15
|
+
}
|
|
16
|
+
/** Directly shifts a byte in from a pin. */
|
|
17
|
+
static in(dataPin, clockPin, order) {
|
|
18
|
+
const bitOrder = order === 'lsb' ? LSBFIRST : MSBFIRST;
|
|
19
|
+
rawCpp(`return shiftIn(${dataPin.number}, ${clockPin.number}, ${bitOrder});`);
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
/** Fluent builder for shifting out. */
|
|
23
|
+
static write(dataPin, value) {
|
|
24
|
+
return new ShiftOutBuilder(dataPin, value);
|
|
25
|
+
}
|
|
26
|
+
/** Fluent builder for shifting in. */
|
|
27
|
+
static read(dataPin) {
|
|
28
|
+
return new ShiftInBuilder(dataPin);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
class ShiftOutBuilder {
|
|
32
|
+
constructor(dataPin, value) {
|
|
33
|
+
this._dataPin = dataPin.number;
|
|
34
|
+
this._value = value;
|
|
35
|
+
}
|
|
36
|
+
clock(clk) {
|
|
37
|
+
this._clockPin = clk.number;
|
|
38
|
+
return this;
|
|
39
|
+
}
|
|
40
|
+
msbFirst() {
|
|
41
|
+
if (this._clockPin === undefined)
|
|
42
|
+
throw new Error("Clock pin must be specified");
|
|
43
|
+
rawCpp(`shiftOut(${this._dataPin}, ${this._clockPin}, MSBFIRST, ${this._value});`);
|
|
44
|
+
}
|
|
45
|
+
lsbFirst() {
|
|
46
|
+
if (this._clockPin === undefined)
|
|
47
|
+
throw new Error("Clock pin must be specified");
|
|
48
|
+
rawCpp(`shiftOut(${this._dataPin}, ${this._clockPin}, LSBFIRST, ${this._value});`);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
class ShiftInBuilder {
|
|
52
|
+
constructor(dataPin) {
|
|
53
|
+
this._dataPin = dataPin.number;
|
|
54
|
+
}
|
|
55
|
+
clock(clk) {
|
|
56
|
+
this._clockPin = clk.number;
|
|
57
|
+
return this;
|
|
58
|
+
}
|
|
59
|
+
msbFirst() {
|
|
60
|
+
if (this._clockPin === undefined)
|
|
61
|
+
throw new Error("Clock pin must be specified");
|
|
62
|
+
rawCpp(`return shiftIn(${this._dataPin}, ${this._clockPin}, MSBFIRST);`);
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
lsbFirst() {
|
|
66
|
+
if (this._clockPin === undefined)
|
|
67
|
+
throw new Error("Clock pin must be specified");
|
|
68
|
+
rawCpp(`return shiftIn(${this._dataPin}, ${this._clockPin}, LSBFIRST);`);
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
package/dist/spi.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
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
|
+
export declare class SPIBus {
|
|
13
|
+
static readonly __includes: string[];
|
|
14
|
+
private _bus;
|
|
15
|
+
constructor(bus: string);
|
|
16
|
+
device(chipSelect: Pin): SPIDevice;
|
|
17
|
+
begin(): this;
|
|
18
|
+
end(): void;
|
|
19
|
+
take(): this | null;
|
|
20
|
+
release(): void;
|
|
21
|
+
transfer(value: number | Uint8Array): number;
|
|
22
|
+
setFrequency(hz: number): void;
|
|
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;
|
|
29
|
+
}
|
|
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
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { spiBegin, spiEnd, spiTransfer, spiBeginTx, spiEndTx, spiCsLow, spiCsHigh, spiSetMode, spiSetBitOrder, rawCpp } from './emit.js';
|
|
2
|
+
import { include } from './include.js';
|
|
3
|
+
export class SPIDevice {
|
|
4
|
+
constructor(bus, chipSelect) {
|
|
5
|
+
this._bus = bus;
|
|
6
|
+
this._cs = chipSelect;
|
|
7
|
+
}
|
|
8
|
+
transfer(data) {
|
|
9
|
+
include("<SPI.h>");
|
|
10
|
+
spiCsLow(this._cs);
|
|
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
|
+
rawCpp(`digitalWrite(${this._cs}, LOW);`);
|
|
25
|
+
rawCpp(`${this._bus}.transfer(${register});`);
|
|
26
|
+
rawCpp(`static uint8_t __spi_buf[${count}];`);
|
|
27
|
+
rawCpp(`for (int i=0; i<${count}; i++) __spi_buf[i] = ${this._bus}.transfer(0x00);`);
|
|
28
|
+
rawCpp(`digitalWrite(${this._cs}, HIGH);`);
|
|
29
|
+
rawCpp(`return __spi_buf;`);
|
|
30
|
+
return new Uint8Array(count);
|
|
31
|
+
}
|
|
32
|
+
writeRegister(register, value) {
|
|
33
|
+
include("<SPI.h>");
|
|
34
|
+
spiCsLow(this._cs);
|
|
35
|
+
spiTransfer(this._bus, register);
|
|
36
|
+
spiTransfer(this._bus, value);
|
|
37
|
+
spiCsHigh(this._cs);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export class SPIBus {
|
|
41
|
+
constructor(bus) {
|
|
42
|
+
this._bus = bus;
|
|
43
|
+
}
|
|
44
|
+
device(chipSelect) {
|
|
45
|
+
return new SPIDevice(this._bus, chipSelect.number);
|
|
46
|
+
}
|
|
47
|
+
begin() {
|
|
48
|
+
include("<SPI.h>");
|
|
49
|
+
spiBegin(this._bus);
|
|
50
|
+
return this;
|
|
51
|
+
}
|
|
52
|
+
end() {
|
|
53
|
+
spiEnd(this._bus);
|
|
54
|
+
}
|
|
55
|
+
take() {
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
release() {
|
|
59
|
+
// No-op for standard Arduino.
|
|
60
|
+
}
|
|
61
|
+
transfer(value) {
|
|
62
|
+
return spiTransfer(this._bus, value);
|
|
63
|
+
}
|
|
64
|
+
setFrequency(hz) {
|
|
65
|
+
spiBeginTx(this._bus, `SPISettings(${hz}, MSBFIRST, SPI_MODE0)`);
|
|
66
|
+
}
|
|
67
|
+
beginTransaction(settings) {
|
|
68
|
+
spiBeginTx(this._bus, settings);
|
|
69
|
+
}
|
|
70
|
+
endTransaction() {
|
|
71
|
+
spiEndTx(this._bus);
|
|
72
|
+
}
|
|
73
|
+
setMode(mode) {
|
|
74
|
+
spiSetMode(this._bus, mode);
|
|
75
|
+
}
|
|
76
|
+
setBitOrder(order) {
|
|
77
|
+
spiSetBitOrder(this._bus, order);
|
|
78
|
+
}
|
|
79
|
+
write(value) {
|
|
80
|
+
spiTransfer(this._bus, value);
|
|
81
|
+
}
|
|
82
|
+
write16(value) {
|
|
83
|
+
rawCpp(`${this._bus}.transfer16(${value});`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
SPIBus.__includes = ["<SPI.h>"];
|
|
87
|
+
/** Map TypeCAD SPI instance number to Arduino C++ object name. SPI0→SPI, SPI1→SPI1 */
|
|
88
|
+
export function spiName(instance) {
|
|
89
|
+
return instance === 0 ? "SPI" : `SPI${instance}`;
|
|
90
|
+
}
|
package/dist/timer.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HardwareTimer provides direct control over the board's hardware timers.
|
|
3
|
+
*
|
|
4
|
+
* Hardware timers are distinct from the software-based setInterval/setTimeout
|
|
5
|
+
* and are typically used for high-precision timing, PWM generation, or
|
|
6
|
+
* interrupt-driven tasks.
|
|
7
|
+
*/
|
|
8
|
+
export declare class HardwareTimer {
|
|
9
|
+
private _instance;
|
|
10
|
+
constructor(instance: number);
|
|
11
|
+
/**
|
|
12
|
+
* Sets the timer frequency in Hertz.
|
|
13
|
+
* Note: The actual frequency may be limited by the hardware's clock dividers.
|
|
14
|
+
*/
|
|
15
|
+
setFrequency(hz: number): void;
|
|
16
|
+
/**
|
|
17
|
+
* Attaches an interrupt handler that executes when the timer overflows.
|
|
18
|
+
*/
|
|
19
|
+
onOverflow(handler: () => void): void;
|
|
20
|
+
/**
|
|
21
|
+
* Starts the timer.
|
|
22
|
+
*/
|
|
23
|
+
start(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Stops the timer.
|
|
26
|
+
*/
|
|
27
|
+
stop(): void;
|
|
28
|
+
/**
|
|
29
|
+
* Returns the bit resolution of the timer (e.g., 8, 16, 32).
|
|
30
|
+
*/
|
|
31
|
+
getBits(): number;
|
|
32
|
+
}
|
|
33
|
+
export declare const Timer0: HardwareTimer;
|
|
34
|
+
export declare const Timer1: HardwareTimer;
|
|
35
|
+
export declare const Timer2: HardwareTimer;
|
package/dist/timer.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { rawCpp, boardResolve } from './emit.js';
|
|
2
|
+
import { callback } from './callback.js';
|
|
3
|
+
/**
|
|
4
|
+
* HardwareTimer provides direct control over the board's hardware timers.
|
|
5
|
+
*
|
|
6
|
+
* Hardware timers are distinct from the software-based setInterval/setTimeout
|
|
7
|
+
* and are typically used for high-precision timing, PWM generation, or
|
|
8
|
+
* interrupt-driven tasks.
|
|
9
|
+
*/
|
|
10
|
+
export class HardwareTimer {
|
|
11
|
+
constructor(instance) {
|
|
12
|
+
this._instance = instance;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Sets the timer frequency in Hertz.
|
|
16
|
+
* Note: The actual frequency may be limited by the hardware's clock dividers.
|
|
17
|
+
*/
|
|
18
|
+
setFrequency(hz) {
|
|
19
|
+
rawCpp(`Timer${this._instance}.setFrequency(${hz});`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Attaches an interrupt handler that executes when the timer overflows.
|
|
23
|
+
*/
|
|
24
|
+
onOverflow(handler) {
|
|
25
|
+
rawCpp(`Timer${this._instance}.onOverflow(${callback(handler)});`);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Starts the timer.
|
|
29
|
+
*/
|
|
30
|
+
start() {
|
|
31
|
+
rawCpp(`Timer${this._instance}.start();`);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Stops the timer.
|
|
35
|
+
*/
|
|
36
|
+
stop() {
|
|
37
|
+
rawCpp(`Timer${this._instance}.stop();`);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Returns the bit resolution of the timer (e.g., 8, 16, 32).
|
|
41
|
+
*/
|
|
42
|
+
getBits() {
|
|
43
|
+
// "peripherals.timer" (singular) matches the board-resolver's array-key
|
|
44
|
+
// derivation (TIMER_INSTANCES → peripherals.timer.<index>.*).
|
|
45
|
+
return boardResolve("peripherals.timer." + this._instance + ".bits");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export const Timer0 = new HardwareTimer(0);
|
|
49
|
+
export const Timer1 = new HardwareTimer(1);
|
|
50
|
+
export const Timer2 = new HardwareTimer(2);
|
package/dist/timing.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export declare class TimingClass {
|
|
2
|
+
static readonly __instance_name = "Timing";
|
|
3
|
+
millis(): number;
|
|
4
|
+
micros(): number;
|
|
5
|
+
delay(ms: number): void;
|
|
6
|
+
delayMicroseconds(us: number): void;
|
|
7
|
+
freeHeap(): number;
|
|
8
|
+
setInterval(handler: () => void, timeout: number): number;
|
|
9
|
+
setTimeout(handler: () => void, timeout: number): number;
|
|
10
|
+
clearInterval(id: number): void;
|
|
11
|
+
clearTimeout(id: number): void;
|
|
12
|
+
}
|
|
13
|
+
export declare const Timing: TimingClass;
|
|
14
|
+
export declare function delay(ms: number): void;
|
|
15
|
+
export declare function millis(): number;
|
|
16
|
+
export declare function micros(): number;
|
|
17
|
+
export declare function delayMicroseconds(us: number): void;
|
|
18
|
+
export declare function freeHeap(): number;
|
|
19
|
+
export declare function setInterval(handler: () => void, timeout: number): number;
|
|
20
|
+
export declare function setTimeout(handler: () => void, timeout: number): number;
|
|
21
|
+
export declare function clearInterval(id: number): void;
|
|
22
|
+
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
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { rawCpp, getMillis, getMicros, getFreeHeap, delayMs, delayMicro } from './emit.js';
|
|
2
|
+
import { callback } from './callback.js';
|
|
3
|
+
export class TimingClass {
|
|
4
|
+
millis() { return getMillis(); }
|
|
5
|
+
micros() { return getMicros(); }
|
|
6
|
+
delay(ms) { delayMs(ms); }
|
|
7
|
+
delayMicroseconds(us) { delayMicro(us); }
|
|
8
|
+
freeHeap() {
|
|
9
|
+
return getFreeHeap();
|
|
10
|
+
}
|
|
11
|
+
setInterval(handler, timeout) {
|
|
12
|
+
rawCpp(`return __tc_setInterval(${callback(handler)}, ${timeout});`);
|
|
13
|
+
return 0;
|
|
14
|
+
}
|
|
15
|
+
setTimeout(handler, timeout) {
|
|
16
|
+
rawCpp(`return __tc_setTimeout(${callback(handler)}, ${timeout});`);
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
clearInterval(id) {
|
|
20
|
+
rawCpp(`__tc_clearInterval(${id});`);
|
|
21
|
+
}
|
|
22
|
+
clearTimeout(id) {
|
|
23
|
+
rawCpp(`__tc_clearTimeout(${id});`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
TimingClass.__instance_name = "Timing";
|
|
27
|
+
export const Timing = new TimingClass();
|
|
28
|
+
export function delay(ms) { delayMs(ms); }
|
|
29
|
+
export function millis() { return getMillis(); }
|
|
30
|
+
export function micros() { return getMicros(); }
|
|
31
|
+
export function delayMicroseconds(us) { delayMicro(us); }
|
|
32
|
+
export function freeHeap() { return Timing.freeHeap(); }
|
|
33
|
+
export function setInterval(handler, timeout) {
|
|
34
|
+
rawCpp(`return __tc_setInterval(${callback(handler)}, ${timeout});`);
|
|
35
|
+
return 0;
|
|
36
|
+
}
|
|
37
|
+
export function setTimeout(handler, timeout) {
|
|
38
|
+
rawCpp(`return __tc_setTimeout(${callback(handler)}, ${timeout});`);
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
export function clearInterval(id) {
|
|
42
|
+
rawCpp(`__tc_clearInterval(${id});`);
|
|
43
|
+
}
|
|
44
|
+
export function clearTimeout(id) {
|
|
45
|
+
rawCpp(`__tc_clearTimeout(${id});`);
|
|
46
|
+
}
|
|
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
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** A digital value is a plain boolean. */
|
|
2
|
+
export type DigitalValue = boolean;
|
|
3
|
+
/** An analog value is a plain number (resolution-dependent). */
|
|
4
|
+
export type AnalogValue = number;
|
|
5
|
+
export declare enum PinMode {
|
|
6
|
+
INPUT = "INPUT",
|
|
7
|
+
OUTPUT = "OUTPUT",
|
|
8
|
+
INPUT_PULLUP = "INPUT_PULLUP",
|
|
9
|
+
INPUT_PULLDOWN = "INPUT_PULLDOWN",
|
|
10
|
+
OUTPUT_OPEN_DRAIN = "OUTPUT_OPEN_DRAIN",
|
|
11
|
+
ANALOG = "ANALOG"
|
|
12
|
+
}
|
|
13
|
+
export declare enum InterruptMode {
|
|
14
|
+
RISING = "RISING",
|
|
15
|
+
FALLING = "FALLING",
|
|
16
|
+
CHANGE = "CHANGE",
|
|
17
|
+
LOW = "LOW",
|
|
18
|
+
HIGH = "HIGH"
|
|
19
|
+
}
|
|
20
|
+
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
|
+
export type ArchitectureIdentifier = 'avr' | 'esp32' | 'esp32s2' | 'esp32s3' | 'esp32c3' | 'esp32c6' | 'rp2040' | '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
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// ---------------------------------------------------------------------------
|
|
2
|
+
// @typecad/hal — Public type definitions
|
|
3
|
+
//
|
|
4
|
+
// Transpiler-shim type surface: enums, type aliases, and the pin-group API
|
|
5
|
+
// consumed by the HAL's transpiler-shim classes (Pin/OutputPin/InputPin,
|
|
6
|
+
// I2CBus/SPIBus/SerialPort) and re-exported for downstream type-checking.
|
|
7
|
+
//
|
|
8
|
+
// Runtime-contract interfaces (BasePin, II2CBus, ISPIBus, ISerialPort, the
|
|
9
|
+
// status enums, capability guards, etc.) have been relocated to
|
|
10
|
+
// @typecad/simulator/src/contracts.ts — they describe the runtime objects the
|
|
11
|
+
// simulator implements, not the transpiler shims that live here.
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Pin mode enum
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
export var PinMode;
|
|
17
|
+
(function (PinMode) {
|
|
18
|
+
PinMode["INPUT"] = "INPUT";
|
|
19
|
+
PinMode["OUTPUT"] = "OUTPUT";
|
|
20
|
+
PinMode["INPUT_PULLUP"] = "INPUT_PULLUP";
|
|
21
|
+
PinMode["INPUT_PULLDOWN"] = "INPUT_PULLDOWN";
|
|
22
|
+
PinMode["OUTPUT_OPEN_DRAIN"] = "OUTPUT_OPEN_DRAIN";
|
|
23
|
+
PinMode["ANALOG"] = "ANALOG";
|
|
24
|
+
})(PinMode || (PinMode = {}));
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Interrupt mode enum
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
export var InterruptMode;
|
|
29
|
+
(function (InterruptMode) {
|
|
30
|
+
InterruptMode["RISING"] = "RISING";
|
|
31
|
+
InterruptMode["FALLING"] = "FALLING";
|
|
32
|
+
InterruptMode["CHANGE"] = "CHANGE";
|
|
33
|
+
InterruptMode["LOW"] = "LOW";
|
|
34
|
+
InterruptMode["HIGH"] = "HIGH";
|
|
35
|
+
})(InterruptMode || (InterruptMode = {}));
|
|
36
|
+
export function createPinGroup(pins) {
|
|
37
|
+
return {
|
|
38
|
+
name: 'PinGroup',
|
|
39
|
+
pins: Object.freeze(pins),
|
|
40
|
+
writePattern(pattern) {
|
|
41
|
+
for (let i = 0; i < this.pins.length; i++) {
|
|
42
|
+
const bit = (pattern >> i) & 1;
|
|
43
|
+
const pin = this.pins[i];
|
|
44
|
+
if ('write' in pin && typeof pin.write === 'function') {
|
|
45
|
+
pin.write(bit === 1);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
readPattern() {
|
|
50
|
+
let value = 0;
|
|
51
|
+
for (let i = 0; i < this.pins.length; i++) {
|
|
52
|
+
const pin = this.pins[i];
|
|
53
|
+
if ('isHigh' in pin && typeof pin.isHigh === 'function' && pin.isHigh()) {
|
|
54
|
+
value |= (1 << i);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return value;
|
|
58
|
+
},
|
|
59
|
+
fill(value) {
|
|
60
|
+
for (const pin of this.pins) {
|
|
61
|
+
if ('write' in pin && typeof pin.write === 'function') {
|
|
62
|
+
pin.write(value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
package/dist/uart.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export declare class SerialPort {
|
|
2
|
+
static readonly __includes: string[];
|
|
3
|
+
private _port;
|
|
4
|
+
constructor(port: string);
|
|
5
|
+
begin(baud?: number): this;
|
|
6
|
+
end(): void;
|
|
7
|
+
print(value: any): void;
|
|
8
|
+
println(value: any): void;
|
|
9
|
+
printf(format: string, ...args: any[]): void;
|
|
10
|
+
write(data: any): void;
|
|
11
|
+
read(): number;
|
|
12
|
+
readLine(): string;
|
|
13
|
+
peek(): number;
|
|
14
|
+
available(): number;
|
|
15
|
+
flush(): void;
|
|
16
|
+
waitForConnection(timeout?: number): Promise<void>;
|
|
17
|
+
take(): this | null;
|
|
18
|
+
release(): void;
|
|
19
|
+
}
|
|
20
|
+
/** Map TypeCAD UART instance number to Arduino C++ object name. UART0→Serial, UART1→Serial1 */
|
|
21
|
+
export declare function serialName(instance: number): string;
|
package/dist/uart.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { uartBegin, uartEnd, uartPrint, uartPrintln, uartPrintf, uartWrite, uartRead, uartPeek, uartAvailable, uartFlush, rawCpp } from './emit.js';
|
|
2
|
+
export class SerialPort {
|
|
3
|
+
constructor(port) {
|
|
4
|
+
this._port = port;
|
|
5
|
+
}
|
|
6
|
+
begin(baud = 9600) {
|
|
7
|
+
uartBegin(this._port, baud);
|
|
8
|
+
return this;
|
|
9
|
+
}
|
|
10
|
+
end() {
|
|
11
|
+
uartEnd(this._port);
|
|
12
|
+
}
|
|
13
|
+
print(value) {
|
|
14
|
+
uartPrint(this._port, value);
|
|
15
|
+
}
|
|
16
|
+
println(value) {
|
|
17
|
+
uartPrintln(this._port, value);
|
|
18
|
+
}
|
|
19
|
+
printf(format, ...args) {
|
|
20
|
+
uartPrintf(this._port, format, args);
|
|
21
|
+
}
|
|
22
|
+
write(data) {
|
|
23
|
+
uartWrite(this._port, data);
|
|
24
|
+
}
|
|
25
|
+
read() {
|
|
26
|
+
return uartRead(this._port);
|
|
27
|
+
}
|
|
28
|
+
readLine() {
|
|
29
|
+
rawCpp(`return ${this._port}.readStringUntil('\\n');`);
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
peek() {
|
|
33
|
+
return uartPeek(this._port);
|
|
34
|
+
}
|
|
35
|
+
available() {
|
|
36
|
+
return uartAvailable(this._port);
|
|
37
|
+
}
|
|
38
|
+
flush() {
|
|
39
|
+
uartFlush(this._port);
|
|
40
|
+
}
|
|
41
|
+
waitForConnection(timeout) {
|
|
42
|
+
rawCpp(`while (!${this._port}) { delay(10); }`);
|
|
43
|
+
return Promise.resolve();
|
|
44
|
+
}
|
|
45
|
+
take() {
|
|
46
|
+
// Basic implementation for single-threaded Arduino;
|
|
47
|
+
// real locking would be framework-specific.
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
release() {
|
|
51
|
+
// No-op for standard Arduino.
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
SerialPort.__includes = ["<Arduino.h>"];
|
|
55
|
+
/** Map TypeCAD UART instance number to Arduino C++ object name. UART0→Serial, UART1→Serial1 */
|
|
56
|
+
export function serialName(instance) {
|
|
57
|
+
return instance === 0 ? "Serial" : `Serial${instance}`;
|
|
58
|
+
}
|
package/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper to inflate peripheral instances from a definition list into a sparse array
|
|
3
|
+
* for named destructuring.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* export const [UART0, UART1] = createHALInstances(UART_INSTANCES, i => new SerialPort(serialName(i)));
|
|
7
|
+
*/
|
|
8
|
+
export declare function createHALInstances<T>(instances: readonly {
|
|
9
|
+
instance: number;
|
|
10
|
+
}[], factory: (instance: number) => T): T[];
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helper to inflate peripheral instances from a definition list into a sparse array
|
|
3
|
+
* for named destructuring.
|
|
4
|
+
*
|
|
5
|
+
* @example
|
|
6
|
+
* export const [UART0, UART1] = createHALInstances(UART_INSTANCES, i => new SerialPort(serialName(i)));
|
|
7
|
+
*/
|
|
8
|
+
export function createHALInstances(instances, factory) {
|
|
9
|
+
const result = [];
|
|
10
|
+
for (const item of instances) {
|
|
11
|
+
result[item.instance] = factory(item.instance);
|
|
12
|
+
}
|
|
13
|
+
return result;
|
|
14
|
+
}
|
package/dist/wdt.d.ts
ADDED
package/dist/wdt.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { wdtEnable, wdtReset, wdtDisable } from './emit.js';
|
|
2
|
+
export class WDTClass {
|
|
3
|
+
enable(timeout) {
|
|
4
|
+
wdtEnable(timeout);
|
|
5
|
+
}
|
|
6
|
+
reset() {
|
|
7
|
+
wdtReset();
|
|
8
|
+
}
|
|
9
|
+
disable() {
|
|
10
|
+
wdtDisable();
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
WDTClass.__instance_name = "WDT";
|
|
14
|
+
export const WDT = new WDTClass();
|
package/package.json
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@typecad/hal",
|
|
3
|
+
"version": "0.1.0-alpha.1",
|
|
4
|
+
"description": "TypeCAD hardware abstraction layer — GPIO, I2C, SPI, UART as regular TypeScript",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"src"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"prepublishOnly": "npm run build",
|
|
15
|
+
"test:hw": "npm exec -- cuttlefish-test",
|
|
16
|
+
"test:hw:basics": "npm exec -- cuttlefish-test tests/01-gpio.test.ts"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"publishConfig": {
|
|
20
|
+
"access": "public"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/justind000/typecode.git",
|
|
25
|
+
"directory": "packages/hal"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://github.com/justind000/typecode/tree/main/packages/hal",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/justind000/typecode/issues"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"arduino",
|
|
33
|
+
"cpp",
|
|
34
|
+
"cuttlefish",
|
|
35
|
+
"embedded",
|
|
36
|
+
"firmware",
|
|
37
|
+
"gpio",
|
|
38
|
+
"hal",
|
|
39
|
+
"hardware-abstraction",
|
|
40
|
+
"i2c",
|
|
41
|
+
"microcontroller",
|
|
42
|
+
"spi",
|
|
43
|
+
"typecad",
|
|
44
|
+
"typescript",
|
|
45
|
+
"uart"
|
|
46
|
+
],
|
|
47
|
+
"engines": {
|
|
48
|
+
"node": ">=18"
|
|
49
|
+
},
|
|
50
|
+
"author": "typecad0",
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@typecad/expect": "0.1.0-alpha.1",
|
|
53
|
+
"@typecad/board-arduino-uno": "0.1.0-alpha.1",
|
|
54
|
+
"@typecad/mcu-atmega328p": "0.1.0-alpha.1"
|
|
55
|
+
},
|
|
56
|
+
"sideEffects": false,
|
|
57
|
+
"exports": {
|
|
58
|
+
".": {
|
|
59
|
+
"types": "./dist/index.d.ts",
|
|
60
|
+
"default": "./dist/index.js"
|
|
61
|
+
},
|
|
62
|
+
"./package.json": "./package.json"
|
|
63
|
+
}
|
|
64
|
+
}
|