@springfield/ham-radio-api 16.3.4 → 17.1.0
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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/radio/memory-map.d.ts +102 -0
- package/dist/radio/memory-map.d.ts.map +1 -0
- package/dist/radio/memory-map.js +8 -0
- package/dist/radio/memory-map.js.map +1 -0
- package/dist/radio/memory-segment.d.ts +1 -0
- package/dist/radio/memory-segment.d.ts.map +1 -1
- package/dist/radio/protocol.d.ts +60 -71
- package/dist/radio/protocol.d.ts.map +1 -1
- package/dist/radio/radio.d.ts +8 -0
- package/dist/radio/radio.d.ts.map +1 -1
- package/dist/radio/settings.d.ts +10 -3
- package/dist/radio/settings.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +1 -0
- package/src/radio/memory-map.ts +102 -0
- package/src/radio/memory-segment.ts +1 -0
- package/src/radio/protocol.ts +62 -70
- package/src/radio/radio.ts +6 -0
- package/src/radio/settings.ts +11 -3
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ export * from "./radio/driver.js";
|
|
|
18
18
|
export * from "./radio/driver-provider.js";
|
|
19
19
|
export * from "./radio/id.js";
|
|
20
20
|
export * from "./radio/memory-config.js";
|
|
21
|
+
export * from "./radio/memory-map.js";
|
|
21
22
|
export * from "./radio/memory-segment.js";
|
|
22
23
|
export * from "./radio/memory.js";
|
|
23
24
|
export * from "./radio/module.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,0CAA0C,CAAC;AACzD,cAAc,+BAA+B,CAAC;AAE9C,cAAc,oBAAoB,CAAC;AAEnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,0CAA0C,CAAC;AACzD,cAAc,+BAA+B,CAAC;AAE9C,cAAc,oBAAoB,CAAC;AAEnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -18,6 +18,7 @@ export * from "./radio/driver.js";
|
|
|
18
18
|
export * from "./radio/driver-provider.js";
|
|
19
19
|
export * from "./radio/id.js";
|
|
20
20
|
export * from "./radio/memory-config.js";
|
|
21
|
+
export * from "./radio/memory-map.js";
|
|
21
22
|
export * from "./radio/memory-segment.js";
|
|
22
23
|
export * from "./radio/memory.js";
|
|
23
24
|
export * from "./radio/module.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,0CAA0C,CAAC;AACzD,cAAc,+BAA+B,CAAC;AAE9C,cAAc,oBAAoB,CAAC;AAEnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,mCAAmC,CAAC;AAClD,cAAc,oCAAoC,CAAC;AACnD,cAAc,qCAAqC,CAAC;AACpD,cAAc,qCAAqC,CAAC;AACpD,cAAc,0CAA0C,CAAC;AACzD,cAAc,+BAA+B,CAAC;AAE9C,cAAc,oBAAoB,CAAC;AAEnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,kBAAkB,CAAC;AACjC,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,kBAAkB,CAAC;AACjC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,eAAe,CAAC;AAC9B,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,qBAAqB,CAAC;AACpC,cAAc,iBAAiB,CAAC;AAChC,cAAc,uBAAuB,CAAC;AAEtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,oBAAoB,CAAC;AACnC,cAAc,yBAAyB,CAAC"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON memory-map DSL: describes how radio EEPROM bytes map to settings
|
|
3
|
+
* without a radio-specific TypeScript decoder.
|
|
4
|
+
*
|
|
5
|
+
* Addresses are radio EEPROM addresses (not Chirp image offsets).
|
|
6
|
+
*/
|
|
7
|
+
/** Scalar JSON values stored in decoded settings. */
|
|
8
|
+
export type RadioSettingScalar = string | number | boolean | null;
|
|
9
|
+
/** Nested settings object produced by decode / consumed by encode. */
|
|
10
|
+
export type RadioSettingValue = RadioSettingScalar | RadioSettingValue[] | {
|
|
11
|
+
[key: string]: RadioSettingValue;
|
|
12
|
+
};
|
|
13
|
+
/** UI widget hint for schema-driven forms. */
|
|
14
|
+
export type RadioMemoryMapWidget = "integer" | "select" | "switch" | "text" | "number";
|
|
15
|
+
/** How a field's raw bits/bytes become a setting value. */
|
|
16
|
+
export type RadioMemoryMapValueKind = {
|
|
17
|
+
kind: "integer";
|
|
18
|
+
min?: number;
|
|
19
|
+
max?: number;
|
|
20
|
+
} | {
|
|
21
|
+
kind: "boolean";
|
|
22
|
+
} | {
|
|
23
|
+
kind: "enum";
|
|
24
|
+
values: string[];
|
|
25
|
+
} | {
|
|
26
|
+
kind: "ascii";
|
|
27
|
+
length: number;
|
|
28
|
+
} | {
|
|
29
|
+
kind: "digits";
|
|
30
|
+
/** Number of decimal digit bytes. */
|
|
31
|
+
length: number;
|
|
32
|
+
/**
|
|
33
|
+
* Scale applied after parsing digits as a decimal integer.
|
|
34
|
+
* VFO frequency uses 10 (Hz/10 stored as 8 digits).
|
|
35
|
+
* Offset uses 1000 (kHz stored as 6 digits → Hz).
|
|
36
|
+
*/
|
|
37
|
+
scale?: number;
|
|
38
|
+
} | {
|
|
39
|
+
kind: "dtmf";
|
|
40
|
+
length: number;
|
|
41
|
+
/** Character set indexed by byte value; 0xFF terminates. */
|
|
42
|
+
charset?: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: "bbcd";
|
|
45
|
+
/** Number of packed BCD bytes (Chirp bbcd). */
|
|
46
|
+
length: number;
|
|
47
|
+
};
|
|
48
|
+
/** UI metadata for a non-reserved field. */
|
|
49
|
+
export interface RadioMemoryMapFieldUi {
|
|
50
|
+
group: string;
|
|
51
|
+
label: string;
|
|
52
|
+
widget: RadioMemoryMapWidget;
|
|
53
|
+
description?: string;
|
|
54
|
+
/** Defaults to true. Set false for firmware / read-only messages. */
|
|
55
|
+
writable?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* One field in a sequential struct.
|
|
59
|
+
* Bitfields pack into the current byte from LSB; width bits are consumed.
|
|
60
|
+
*/
|
|
61
|
+
export interface RadioMemoryMapField {
|
|
62
|
+
id: string;
|
|
63
|
+
/**
|
|
64
|
+
* Storage type:
|
|
65
|
+
* - u8 / u16: whole bytes (u16 is little-endian, Chirp ul16)
|
|
66
|
+
* - bits: bitfield of `width` bits within the current byte (LSB-first)
|
|
67
|
+
* - char: ASCII byte (length via value.kind ascii or count)
|
|
68
|
+
*/
|
|
69
|
+
type: "u8" | "u16" | "bits" | "char";
|
|
70
|
+
/** Bit width when type is bits. */
|
|
71
|
+
width?: number;
|
|
72
|
+
/** When true, skip decode/encode for this padding field. */
|
|
73
|
+
reserved?: boolean;
|
|
74
|
+
value?: RadioMemoryMapValueKind;
|
|
75
|
+
ui?: RadioMemoryMapFieldUi;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* A named struct at a radio EEPROM seek address.
|
|
79
|
+
* Fields are laid out sequentially from `seek`.
|
|
80
|
+
*/
|
|
81
|
+
export interface RadioMemoryMapStruct {
|
|
82
|
+
id: string;
|
|
83
|
+
/** Radio EEPROM start address (number or hex string such as "0x0E20"). */
|
|
84
|
+
seek: number | string;
|
|
85
|
+
fields: RadioMemoryMapField[];
|
|
86
|
+
/**
|
|
87
|
+
* Repeat this struct `count` times with `stride` bytes between entries.
|
|
88
|
+
* Used for PTT-ID code tables.
|
|
89
|
+
*/
|
|
90
|
+
count?: number;
|
|
91
|
+
stride?: number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Complete memory-map definition for a radio model's settings.
|
|
95
|
+
*/
|
|
96
|
+
export interface RadioMemoryMap {
|
|
97
|
+
/** Optional map version for tooling. */
|
|
98
|
+
version?: string;
|
|
99
|
+
description?: string;
|
|
100
|
+
structs: RadioMemoryMapStruct[];
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=memory-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-map.d.ts","sourceRoot":"","sources":["../../src/radio/memory-map.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,qDAAqD;AACrD,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC;AAElE,sEAAsE;AACtE,MAAM,MAAM,iBAAiB,GAAG,kBAAkB,GAAG,iBAAiB,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAAA;CAAE,CAAC;AAEhH,8CAA8C;AAC9C,MAAM,MAAM,oBAAoB,GAAG,SAAS,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEvF,2DAA2D;AAC3D,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACjC;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEN,4CAA4C;AAC5C,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,oBAAoB,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,MAAM,CAAC;IACX;;;;;OAKG;IACH,IAAI,EAAE,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;IACrC,mCAAmC;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4DAA4D;IAC5D,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,EAAE,CAAC,EAAE,qBAAqB,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,0EAA0E;IAC1E,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC;IACtB,MAAM,EAAE,mBAAmB,EAAE,CAAC;IAC9B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wCAAwC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,oBAAoB,EAAE,CAAC;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-map.js","sourceRoot":"","sources":["../../src/radio/memory-map.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory-segment.d.ts","sourceRoot":"","sources":["../../src/radio/memory-segment.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
|
1
|
+
{"version":3,"file":"memory-segment.d.ts","sourceRoot":"","sources":["../../src/radio/memory-segment.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB;IACjC,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB"}
|
package/dist/radio/protocol.d.ts
CHANGED
|
@@ -1,79 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
/**
|
|
2
|
+
* A byte in a send or expect array.
|
|
3
|
+
*
|
|
4
|
+
* - number 0–255: literal byte
|
|
5
|
+
* - hex string such as `"0x50"`: literal byte
|
|
6
|
+
* - single-character string such as `"S"`: ASCII opcode
|
|
7
|
+
* - placeholder: `"$address"`, `"$chunkSize"`, `"$length"`, `"$data"`
|
|
8
|
+
*/
|
|
9
|
+
export type RadioByteToken = number | string;
|
|
10
|
+
/**
|
|
11
|
+
* Receive any content of a fixed length, such as a radio identifier.
|
|
12
|
+
*/
|
|
13
|
+
export interface RadioExpectBytes {
|
|
14
|
+
bytes: number;
|
|
5
15
|
}
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
export
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
export interface RadioReceiveStep {
|
|
38
|
-
receive: {
|
|
39
|
-
type: "exact" | "variable" | "pattern" | "any";
|
|
40
|
-
value?: number;
|
|
41
|
-
length: number;
|
|
42
|
-
pattern?: (string | number | {
|
|
43
|
-
field: string;
|
|
44
|
-
size: number;
|
|
45
|
-
})[];
|
|
46
|
-
description?: string;
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
export interface RadioReadSegmentStep {
|
|
50
|
-
readSegment: {
|
|
16
|
+
/**
|
|
17
|
+
* Expected serial reply for an exchange.
|
|
18
|
+
*
|
|
19
|
+
* - token: exact 1-byte match (ACK)
|
|
20
|
+
* - token array: exact multi-byte match, or a framed reply with `$` placeholders
|
|
21
|
+
* - `{ bytes: N }`: any N bytes
|
|
22
|
+
*/
|
|
23
|
+
export type RadioExpect = RadioByteToken | RadioByteToken[] | RadioExpectBytes;
|
|
24
|
+
/**
|
|
25
|
+
* One serial exchange: send bytes and/or wait for a reply.
|
|
26
|
+
* At least one of `send` or `expect` must be present.
|
|
27
|
+
*/
|
|
28
|
+
export type RadioExchange = {
|
|
29
|
+
description?: string;
|
|
30
|
+
send: RadioByteToken[];
|
|
31
|
+
expect?: RadioExpect;
|
|
32
|
+
timeout?: number;
|
|
33
|
+
} | {
|
|
34
|
+
description?: string;
|
|
35
|
+
send?: RadioByteToken[];
|
|
36
|
+
expect: RadioExpect;
|
|
37
|
+
timeout?: number;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Chunked memory read: repeat an exchange across named segments.
|
|
41
|
+
* `$data` in `expect` is captured into the memory buffer.
|
|
42
|
+
* Optional `ack` is a second exchange after each chunk (for example an ACK).
|
|
43
|
+
*/
|
|
44
|
+
export interface RadioReadStep {
|
|
45
|
+
description?: string;
|
|
46
|
+
read: {
|
|
51
47
|
segments: string[];
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
endChunk: {
|
|
57
|
-
send: (string | number)[];
|
|
58
|
-
receive: RadioReceivePattern;
|
|
59
|
-
};
|
|
60
|
-
description?: string;
|
|
48
|
+
send: RadioByteToken[];
|
|
49
|
+
expect: RadioExpect;
|
|
50
|
+
ack?: RadioExchange;
|
|
51
|
+
timeout?: number;
|
|
61
52
|
};
|
|
62
53
|
}
|
|
63
|
-
|
|
64
|
-
|
|
54
|
+
/**
|
|
55
|
+
* Chunked memory write: repeat an exchange across named segments.
|
|
56
|
+
* `$data` in `send` emits the current chunk from the memory buffer.
|
|
57
|
+
*/
|
|
58
|
+
export interface RadioWriteStep {
|
|
59
|
+
description?: string;
|
|
60
|
+
write: {
|
|
65
61
|
segments: string[];
|
|
66
|
-
send:
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
description?: string;
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
export interface RadioSetVariableStep {
|
|
73
|
-
setVariable: {
|
|
74
|
-
name: string;
|
|
75
|
-
value: string | number;
|
|
62
|
+
send: RadioByteToken[];
|
|
63
|
+
expect: RadioExpect;
|
|
64
|
+
timeout?: number;
|
|
76
65
|
};
|
|
77
66
|
}
|
|
78
|
-
export type RadioProtocolStep =
|
|
67
|
+
export type RadioProtocolStep = RadioExchange | RadioReadStep | RadioWriteStep;
|
|
79
68
|
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/radio/protocol.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/radio/protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,EAAE,GAAG,gBAAgB,CAAC;AAE/E;;;GAGG;AACH,MAAM,MAAM,aAAa,GACrB;IACE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,GACD;IACE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,cAAc,EAAE,CAAC;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEN;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE;QACJ,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,MAAM,EAAE,WAAW,CAAC;QACpB,GAAG,CAAC,EAAE,aAAa,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,EAAE,CAAC;QACnB,IAAI,EAAE,cAAc,EAAE,CAAC;QACvB,MAAM,EAAE,WAAW,CAAC;QACpB,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC"}
|
package/dist/radio/radio.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RadioId } from "./id.js";
|
|
2
2
|
import type { RadioMemoryConfig } from "./memory-config.js";
|
|
3
|
+
import type { RadioMemoryMap } from "./memory-map.js";
|
|
3
4
|
import type { RadioProtocolStep } from "./protocol.js";
|
|
4
5
|
import type { RadioSchema } from "./schema.js";
|
|
5
6
|
import type { RadioSerialConfig } from "./serial-config.js";
|
|
@@ -12,5 +13,12 @@ export interface Radio {
|
|
|
12
13
|
serialConfig: RadioSerialConfig;
|
|
13
14
|
readMemory: RadioProtocolStep[];
|
|
14
15
|
writeMemory: RadioProtocolStep[];
|
|
16
|
+
/**
|
|
17
|
+
* Optional JSON memory-map for radio-wide settings decode/encode.
|
|
18
|
+
* May be an inline map or a path/$ref resolved by the registry/module.
|
|
19
|
+
*/
|
|
20
|
+
memoryMap?: RadioMemoryMap | {
|
|
21
|
+
$ref: string;
|
|
22
|
+
};
|
|
15
23
|
}
|
|
16
24
|
//# sourceMappingURL=radio.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../src/radio/radio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,WAAW,CAAC;IAC5B,YAAY,EAAE,iBAAiB,CAAC;IAChC,YAAY,EAAE,iBAAiB,CAAC;IAChC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,WAAW,EAAE,iBAAiB,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"radio.d.ts","sourceRoot":"","sources":["../../src/radio/radio.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,WAAW,CAAC;IAC5B,YAAY,EAAE,iBAAiB,CAAC;IAChC,YAAY,EAAE,iBAAiB,CAAC;IAChC,UAAU,EAAE,iBAAiB,EAAE,CAAC;IAChC,WAAW,EAAE,iBAAiB,EAAE,CAAC;IACjC;;;OAGG;IACH,SAAS,CAAC,EAAE,cAAc,GAAG;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C"}
|
package/dist/radio/settings.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { RadioSettingValue } from "./memory-map.js";
|
|
2
|
+
/**
|
|
3
|
+
* Decoded radio-wide settings.
|
|
4
|
+
*
|
|
5
|
+
* Values may be nested objects (struct id → fields) or arrays (repeated structs).
|
|
6
|
+
* Channel-specific settings may still use a flat map of primitives.
|
|
7
|
+
*/
|
|
8
|
+
export type RadioSettings = {
|
|
9
|
+
[setting: string]: RadioSettingValue;
|
|
10
|
+
};
|
|
4
11
|
//# sourceMappingURL=settings.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/radio/settings.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/radio/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG;IAC1B,CAAC,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAAC;CACtC,CAAC"}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -20,6 +20,7 @@ export * from "./radio/driver.js";
|
|
|
20
20
|
export * from "./radio/driver-provider.js";
|
|
21
21
|
export * from "./radio/id.js";
|
|
22
22
|
export * from "./radio/memory-config.js";
|
|
23
|
+
export * from "./radio/memory-map.js";
|
|
23
24
|
export * from "./radio/memory-segment.js";
|
|
24
25
|
export * from "./radio/memory.js";
|
|
25
26
|
export * from "./radio/module.js";
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON memory-map DSL: describes how radio EEPROM bytes map to settings
|
|
3
|
+
* without a radio-specific TypeScript decoder.
|
|
4
|
+
*
|
|
5
|
+
* Addresses are radio EEPROM addresses (not Chirp image offsets).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/** Scalar JSON values stored in decoded settings. */
|
|
9
|
+
export type RadioSettingScalar = string | number | boolean | null;
|
|
10
|
+
|
|
11
|
+
/** Nested settings object produced by decode / consumed by encode. */
|
|
12
|
+
export type RadioSettingValue = RadioSettingScalar | RadioSettingValue[] | { [key: string]: RadioSettingValue };
|
|
13
|
+
|
|
14
|
+
/** UI widget hint for schema-driven forms. */
|
|
15
|
+
export type RadioMemoryMapWidget = "integer" | "select" | "switch" | "text" | "number";
|
|
16
|
+
|
|
17
|
+
/** How a field's raw bits/bytes become a setting value. */
|
|
18
|
+
export type RadioMemoryMapValueKind =
|
|
19
|
+
| { kind: "integer"; min?: number; max?: number }
|
|
20
|
+
| { kind: "boolean" }
|
|
21
|
+
| { kind: "enum"; values: string[] }
|
|
22
|
+
| { kind: "ascii"; length: number }
|
|
23
|
+
| {
|
|
24
|
+
kind: "digits";
|
|
25
|
+
/** Number of decimal digit bytes. */
|
|
26
|
+
length: number;
|
|
27
|
+
/**
|
|
28
|
+
* Scale applied after parsing digits as a decimal integer.
|
|
29
|
+
* VFO frequency uses 10 (Hz/10 stored as 8 digits).
|
|
30
|
+
* Offset uses 1000 (kHz stored as 6 digits → Hz).
|
|
31
|
+
*/
|
|
32
|
+
scale?: number;
|
|
33
|
+
}
|
|
34
|
+
| {
|
|
35
|
+
kind: "dtmf";
|
|
36
|
+
length: number;
|
|
37
|
+
/** Character set indexed by byte value; 0xFF terminates. */
|
|
38
|
+
charset?: string;
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
kind: "bbcd";
|
|
42
|
+
/** Number of packed BCD bytes (Chirp bbcd). */
|
|
43
|
+
length: number;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
/** UI metadata for a non-reserved field. */
|
|
47
|
+
export interface RadioMemoryMapFieldUi {
|
|
48
|
+
group: string;
|
|
49
|
+
label: string;
|
|
50
|
+
widget: RadioMemoryMapWidget;
|
|
51
|
+
description?: string;
|
|
52
|
+
/** Defaults to true. Set false for firmware / read-only messages. */
|
|
53
|
+
writable?: boolean;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* One field in a sequential struct.
|
|
58
|
+
* Bitfields pack into the current byte from LSB; width bits are consumed.
|
|
59
|
+
*/
|
|
60
|
+
export interface RadioMemoryMapField {
|
|
61
|
+
id: string;
|
|
62
|
+
/**
|
|
63
|
+
* Storage type:
|
|
64
|
+
* - u8 / u16: whole bytes (u16 is little-endian, Chirp ul16)
|
|
65
|
+
* - bits: bitfield of `width` bits within the current byte (LSB-first)
|
|
66
|
+
* - char: ASCII byte (length via value.kind ascii or count)
|
|
67
|
+
*/
|
|
68
|
+
type: "u8" | "u16" | "bits" | "char";
|
|
69
|
+
/** Bit width when type is bits. */
|
|
70
|
+
width?: number;
|
|
71
|
+
/** When true, skip decode/encode for this padding field. */
|
|
72
|
+
reserved?: boolean;
|
|
73
|
+
value?: RadioMemoryMapValueKind;
|
|
74
|
+
ui?: RadioMemoryMapFieldUi;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A named struct at a radio EEPROM seek address.
|
|
79
|
+
* Fields are laid out sequentially from `seek`.
|
|
80
|
+
*/
|
|
81
|
+
export interface RadioMemoryMapStruct {
|
|
82
|
+
id: string;
|
|
83
|
+
/** Radio EEPROM start address (number or hex string such as "0x0E20"). */
|
|
84
|
+
seek: number | string;
|
|
85
|
+
fields: RadioMemoryMapField[];
|
|
86
|
+
/**
|
|
87
|
+
* Repeat this struct `count` times with `stride` bytes between entries.
|
|
88
|
+
* Used for PTT-ID code tables.
|
|
89
|
+
*/
|
|
90
|
+
count?: number;
|
|
91
|
+
stride?: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Complete memory-map definition for a radio model's settings.
|
|
96
|
+
*/
|
|
97
|
+
export interface RadioMemoryMap {
|
|
98
|
+
/** Optional map version for tooling. */
|
|
99
|
+
version?: string;
|
|
100
|
+
description?: string;
|
|
101
|
+
structs: RadioMemoryMapStruct[];
|
|
102
|
+
}
|
package/src/radio/protocol.ts
CHANGED
|
@@ -1,83 +1,75 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface RadioPatternReceivePattern {
|
|
13
|
-
type: "pattern";
|
|
14
|
-
pattern: (string | number | { field: string; size: number })[];
|
|
15
|
-
dataLength?: number | string; // Optional - actual length determined by segment configuration
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface RadioAnyReceivePattern {
|
|
19
|
-
type: "any";
|
|
20
|
-
length: number;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
export type RadioReceivePattern = RadioExactReceivePattern | RadioVariableReceivePattern | RadioPatternReceivePattern | RadioAnyReceivePattern;
|
|
24
|
-
|
|
25
|
-
export interface RadioSendReceiveStep {
|
|
26
|
-
sendReceive: {
|
|
27
|
-
send: (string | number)[];
|
|
28
|
-
receive: RadioReceivePattern;
|
|
29
|
-
timeout?: number;
|
|
30
|
-
description?: string;
|
|
31
|
-
};
|
|
32
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* A byte in a send or expect array.
|
|
3
|
+
*
|
|
4
|
+
* - number 0–255: literal byte
|
|
5
|
+
* - hex string such as `"0x50"`: literal byte
|
|
6
|
+
* - single-character string such as `"S"`: ASCII opcode
|
|
7
|
+
* - placeholder: `"$address"`, `"$chunkSize"`, `"$length"`, `"$data"`
|
|
8
|
+
*/
|
|
9
|
+
export type RadioByteToken = number | string;
|
|
33
10
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
11
|
+
/**
|
|
12
|
+
* Receive any content of a fixed length, such as a radio identifier.
|
|
13
|
+
*/
|
|
14
|
+
export interface RadioExpectBytes {
|
|
15
|
+
bytes: number;
|
|
39
16
|
}
|
|
40
17
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
18
|
+
/**
|
|
19
|
+
* Expected serial reply for an exchange.
|
|
20
|
+
*
|
|
21
|
+
* - token: exact 1-byte match (ACK)
|
|
22
|
+
* - token array: exact multi-byte match, or a framed reply with `$` placeholders
|
|
23
|
+
* - `{ bytes: N }`: any N bytes
|
|
24
|
+
*/
|
|
25
|
+
export type RadioExpect = RadioByteToken | RadioByteToken[] | RadioExpectBytes;
|
|
50
26
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
27
|
+
/**
|
|
28
|
+
* One serial exchange: send bytes and/or wait for a reply.
|
|
29
|
+
* At least one of `send` or `expect` must be present.
|
|
30
|
+
*/
|
|
31
|
+
export type RadioExchange =
|
|
32
|
+
| {
|
|
33
|
+
description?: string;
|
|
34
|
+
send: RadioByteToken[];
|
|
35
|
+
expect?: RadioExpect;
|
|
36
|
+
timeout?: number;
|
|
37
|
+
}
|
|
38
|
+
| {
|
|
39
|
+
description?: string;
|
|
40
|
+
send?: RadioByteToken[];
|
|
41
|
+
expect: RadioExpect;
|
|
42
|
+
timeout?: number;
|
|
61
43
|
};
|
|
62
|
-
description?: string;
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
44
|
|
|
66
|
-
|
|
67
|
-
|
|
45
|
+
/**
|
|
46
|
+
* Chunked memory read: repeat an exchange across named segments.
|
|
47
|
+
* `$data` in `expect` is captured into the memory buffer.
|
|
48
|
+
* Optional `ack` is a second exchange after each chunk (for example an ACK).
|
|
49
|
+
*/
|
|
50
|
+
export interface RadioReadStep {
|
|
51
|
+
description?: string;
|
|
52
|
+
read: {
|
|
68
53
|
segments: string[];
|
|
69
|
-
send:
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
54
|
+
send: RadioByteToken[];
|
|
55
|
+
expect: RadioExpect;
|
|
56
|
+
ack?: RadioExchange;
|
|
57
|
+
timeout?: number;
|
|
73
58
|
};
|
|
74
59
|
}
|
|
75
60
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
61
|
+
/**
|
|
62
|
+
* Chunked memory write: repeat an exchange across named segments.
|
|
63
|
+
* `$data` in `send` emits the current chunk from the memory buffer.
|
|
64
|
+
*/
|
|
65
|
+
export interface RadioWriteStep {
|
|
66
|
+
description?: string;
|
|
67
|
+
write: {
|
|
68
|
+
segments: string[];
|
|
69
|
+
send: RadioByteToken[];
|
|
70
|
+
expect: RadioExpect;
|
|
71
|
+
timeout?: number;
|
|
80
72
|
};
|
|
81
73
|
}
|
|
82
74
|
|
|
83
|
-
export type RadioProtocolStep =
|
|
75
|
+
export type RadioProtocolStep = RadioExchange | RadioReadStep | RadioWriteStep;
|
package/src/radio/radio.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { RadioId } from "./id.js";
|
|
2
2
|
import type { RadioMemoryConfig } from "./memory-config.js";
|
|
3
|
+
import type { RadioMemoryMap } from "./memory-map.js";
|
|
3
4
|
import type { RadioProtocolStep } from "./protocol.js";
|
|
4
5
|
import type { RadioSchema } from "./schema.js";
|
|
5
6
|
import type { RadioSerialConfig } from "./serial-config.js";
|
|
@@ -13,4 +14,9 @@ export interface Radio {
|
|
|
13
14
|
serialConfig: RadioSerialConfig;
|
|
14
15
|
readMemory: RadioProtocolStep[];
|
|
15
16
|
writeMemory: RadioProtocolStep[];
|
|
17
|
+
/**
|
|
18
|
+
* Optional JSON memory-map for radio-wide settings decode/encode.
|
|
19
|
+
* May be an inline map or a path/$ref resolved by the registry/module.
|
|
20
|
+
*/
|
|
21
|
+
memoryMap?: RadioMemoryMap | { $ref: string };
|
|
16
22
|
}
|
package/src/radio/settings.ts
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import type { RadioSettingValue } from "./memory-map.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Decoded radio-wide settings.
|
|
5
|
+
*
|
|
6
|
+
* Values may be nested objects (struct id → fields) or arrays (repeated structs).
|
|
7
|
+
* Channel-specific settings may still use a flat map of primitives.
|
|
8
|
+
*/
|
|
9
|
+
export type RadioSettings = {
|
|
10
|
+
[setting: string]: RadioSettingValue;
|
|
11
|
+
};
|