@springfield/ham-radio-api 17.3.0 → 17.5.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/radio/memory-map.d.ts +31 -2
- package/dist/radio/memory-map.d.ts.map +1 -1
- package/dist/radio/protocol.d.ts +55 -12
- package/dist/radio/protocol.d.ts.map +1 -1
- package/dist/radio/serial-config.d.ts +12 -0
- package/dist/radio/serial-config.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/radio/memory-map.ts +37 -3
- package/src/radio/protocol.ts +64 -18
- package/src/radio/serial-config.ts +12 -0
|
@@ -38,6 +38,8 @@ export type RadioMemoryMapValueKind = {
|
|
|
38
38
|
} | {
|
|
39
39
|
kind: "ascii";
|
|
40
40
|
length: number;
|
|
41
|
+
/** Fill byte for unused character slots (default 0xFF). Kenwood names use 0. */
|
|
42
|
+
pad?: number;
|
|
41
43
|
} | {
|
|
42
44
|
kind: "digits";
|
|
43
45
|
/** Number of decimal digit bytes. */
|
|
@@ -80,6 +82,20 @@ export type RadioMemoryMapValueKind = {
|
|
|
80
82
|
ctcssMin?: number;
|
|
81
83
|
/** Added to DCS index for reverse polarity (Chirp uses 0x69). */
|
|
82
84
|
reverseOffset?: number;
|
|
85
|
+
} | {
|
|
86
|
+
/**
|
|
87
|
+
* CTCSS tone stored as an index into `values` (Hz * 10, Springfield tenths).
|
|
88
|
+
* Kenwood TH-D74 `rtone` / `ctone` use Chirp TONES order.
|
|
89
|
+
*/
|
|
90
|
+
kind: "ctcss-index";
|
|
91
|
+
values: number[];
|
|
92
|
+
} | {
|
|
93
|
+
/**
|
|
94
|
+
* DCS code stored as an index into `values`.
|
|
95
|
+
* Kenwood TH-D74 `dtcs_code` uses Chirp DTCS_CODES order.
|
|
96
|
+
*/
|
|
97
|
+
kind: "dcs-index";
|
|
98
|
+
values: number[];
|
|
83
99
|
};
|
|
84
100
|
/** UI metadata for a non-reserved field. */
|
|
85
101
|
export interface RadioMemoryMapFieldUi {
|
|
@@ -98,11 +114,11 @@ export interface RadioMemoryMapField {
|
|
|
98
114
|
id: string;
|
|
99
115
|
/**
|
|
100
116
|
* Storage type:
|
|
101
|
-
* - u8 / u16: whole bytes (u16
|
|
117
|
+
* - u8 / u16 / u32: whole bytes (u16/u32 are little-endian, Chirp ul16/ul32)
|
|
102
118
|
* - bits: bitfield of `width` bits within the current byte (MSB-first)
|
|
103
119
|
* - char: ASCII byte (length via value.kind ascii or count)
|
|
104
120
|
*/
|
|
105
|
-
type: "u8" | "u16" | "bits" | "char";
|
|
121
|
+
type: "u8" | "u16" | "u32" | "bits" | "char";
|
|
106
122
|
/** Bit width when type is bits. */
|
|
107
123
|
width?: number;
|
|
108
124
|
/** When true, skip decode/encode for this padding field. */
|
|
@@ -132,6 +148,13 @@ export interface RadioMemoryMapStruct {
|
|
|
132
148
|
*/
|
|
133
149
|
count?: number;
|
|
134
150
|
stride?: number;
|
|
151
|
+
/**
|
|
152
|
+
* When set with `groupPad`, instances are packed into groups of `groupSize`
|
|
153
|
+
* records followed by `groupPad` padding bytes (Kenwood TH-D74: 6 × 40 + 16).
|
|
154
|
+
*/
|
|
155
|
+
groupSize?: number;
|
|
156
|
+
/** Padding bytes after each group of `groupSize` records. */
|
|
157
|
+
groupPad?: number;
|
|
135
158
|
/** Occupancy rule for repeated structs (e.g. empty channel slots). */
|
|
136
159
|
emptyWhen?: RadioMemoryMapEmptyWhen;
|
|
137
160
|
/**
|
|
@@ -155,6 +178,12 @@ export interface RadioMemoryMapChannelBindings {
|
|
|
155
178
|
transmitFrequency: string;
|
|
156
179
|
receiveTone: string;
|
|
157
180
|
transmitTone: string;
|
|
181
|
+
/**
|
|
182
|
+
* Optional parallel struct whose fields merge into each channel's settings
|
|
183
|
+
* (Kenwood TH-D74 flags: used, lockout, group). Occupancy `emptyWhen` on
|
|
184
|
+
* this struct, when present, also skips the channel.
|
|
185
|
+
*/
|
|
186
|
+
extras?: string;
|
|
158
187
|
}
|
|
159
188
|
/**
|
|
160
189
|
* Complete memory-map definition for a radio model's settings and channels.
|
|
@@ -1 +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;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,GAAG,GAAG,GAAG,CAAA;CAAE,CAAC;AAEvD,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;
|
|
1
|
+
{"version":3,"file":"memory-map.d.ts","sourceRoot":"","sources":["../../src/radio/memory-map.ts"],"names":[],"mappings":"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"}
|
package/dist/radio/protocol.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { RadioMemorySegment } from "./memory-segment.js";
|
|
|
5
5
|
* - number 0–255: literal byte
|
|
6
6
|
* - hex string such as `"0x50"`: literal byte
|
|
7
7
|
* - single-character string such as `"S"`: ASCII opcode
|
|
8
|
-
* - placeholder: `"$address"`, `"$chunkSize"`, `"$length"`, `"$data"`
|
|
8
|
+
* - placeholder: `"$address"`, `"$block"`, `"$chunkSize"`, `"$length"`, `"$data"`
|
|
9
9
|
*/
|
|
10
10
|
export type RadioByteToken = number | string;
|
|
11
11
|
/**
|
|
@@ -14,29 +14,58 @@ export type RadioByteToken = number | string;
|
|
|
14
14
|
export interface RadioExpectBytes {
|
|
15
15
|
bytes: number;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Read until a delimiter byte. Used for Kenwood live CAT lines ending in CR.
|
|
19
|
+
*/
|
|
20
|
+
export interface RadioExpectUntil {
|
|
21
|
+
until: RadioByteToken;
|
|
22
|
+
}
|
|
17
23
|
/**
|
|
18
24
|
* Expected serial reply for an exchange.
|
|
19
25
|
*
|
|
20
26
|
* - token: exact 1-byte match (ACK)
|
|
21
27
|
* - token array: exact multi-byte match, or a framed reply with `$` placeholders
|
|
22
28
|
* - `{ bytes: N }`: any N bytes
|
|
29
|
+
* - `{ until: token }`: variable-length reply ending at the delimiter (the delimiter is not included)
|
|
23
30
|
*/
|
|
24
|
-
export type RadioExpect = RadioByteToken | RadioByteToken[] | RadioExpectBytes;
|
|
31
|
+
export type RadioExpect = RadioByteToken | RadioByteToken[] | RadioExpectBytes | RadioExpectUntil;
|
|
25
32
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
33
|
+
* Packer that converts live CAT replies into a logical memory-map record.
|
|
34
|
+
* `kenwood-th-f6` parses `MR`/`MNA` CSV into the 32-byte TH-F6 channel image.
|
|
28
35
|
*/
|
|
29
|
-
export type
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
export type RadioCatPack = "kenwood-th-f6";
|
|
37
|
+
/**
|
|
38
|
+
* Live CAT memory loop: one logical record per channel index, not clone blocks.
|
|
39
|
+
*/
|
|
40
|
+
export interface RadioCatMemoryConfig {
|
|
41
|
+
segment: string;
|
|
42
|
+
count: number;
|
|
43
|
+
recordSize: number;
|
|
44
|
+
pack: RadioCatPack;
|
|
45
|
+
indexWidth?: number;
|
|
46
|
+
emptyByte?: number;
|
|
33
47
|
timeout?: number;
|
|
34
|
-
|
|
48
|
+
interCommandDelayMs?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* One serial exchange: send bytes and/or wait for a reply, and/or change baud.
|
|
52
|
+
* At least one of `send`, `expect`, or `setBaudRate` must be present.
|
|
53
|
+
*/
|
|
54
|
+
export interface RadioExchange {
|
|
35
55
|
description?: string;
|
|
36
56
|
send?: RadioByteToken[];
|
|
37
|
-
expect
|
|
57
|
+
expect?: RadioExpect;
|
|
38
58
|
timeout?: number;
|
|
39
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Milliseconds to wait after send (Kenwood CAT wake CR before ID).
|
|
61
|
+
*/
|
|
62
|
+
delay?: number;
|
|
63
|
+
/**
|
|
64
|
+
* Switch the serial baud rate before send/expect. TH-D74 clone mode
|
|
65
|
+
* enters programming at 9600 then transfers at 57600.
|
|
66
|
+
*/
|
|
67
|
+
setBaudRate?: number;
|
|
68
|
+
}
|
|
40
69
|
/**
|
|
41
70
|
* Chunked memory read: repeat an exchange across named segments.
|
|
42
71
|
* `$data` in `expect` is captured into the memory buffer.
|
|
@@ -72,5 +101,19 @@ export interface RadioWriteStep {
|
|
|
72
101
|
skip?: RadioMemorySegment[];
|
|
73
102
|
};
|
|
74
103
|
}
|
|
75
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Read memories with live CAT commands (Kenwood TH-F6 `MR`/`MNA`).
|
|
106
|
+
*/
|
|
107
|
+
export interface RadioCatReadStep {
|
|
108
|
+
description?: string;
|
|
109
|
+
catRead: RadioCatMemoryConfig;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Write memories with live CAT commands (Kenwood TH-F6 `MW`/`MNA`).
|
|
113
|
+
*/
|
|
114
|
+
export interface RadioCatWriteStep {
|
|
115
|
+
description?: string;
|
|
116
|
+
catWrite: RadioCatMemoryConfig;
|
|
117
|
+
}
|
|
118
|
+
export type RadioProtocolStep = RadioExchange | RadioReadStep | RadioWriteStep | RadioCatReadStep | RadioCatWriteStep;
|
|
76
119
|
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/radio/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/radio/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D;;;;;;;GAOG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,cAAc,CAAC;CACvB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,WAAW,GAAG,cAAc,GAAG,cAAc,EAAE,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAElG;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,eAAe,CAAC;AAE3C;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,cAAc,EAAE,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;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;;;;;;;GAOG;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;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,IAAI,CAAC,EAAE,kBAAkB,EAAE,CAAC;KAC7B,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,oBAAoB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,oBAAoB,CAAC;CAChC;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc,GAAG,gBAAgB,GAAG,iBAAiB,CAAC"}
|
|
@@ -3,5 +3,17 @@ export interface RadioSerialConfig {
|
|
|
3
3
|
dataBits?: 8 | 5 | 6 | 7;
|
|
4
4
|
stopBits?: 1 | 1.5 | 2;
|
|
5
5
|
parity?: "none" | "even" | "odd";
|
|
6
|
+
/**
|
|
7
|
+
* Hardware RTS/CTS flow control. Kenwood TH-D74 clone mode needs this on macOS.
|
|
8
|
+
*/
|
|
9
|
+
rtscts?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Explicit RTS line. TH-F6 live CAT needs this false; omit to keep RTS asserted.
|
|
12
|
+
*/
|
|
13
|
+
rts?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Explicit DTR line. Omit to keep DTR asserted after open.
|
|
16
|
+
*/
|
|
17
|
+
dtr?: boolean;
|
|
6
18
|
}
|
|
7
19
|
//# sourceMappingURL=serial-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"serial-config.d.ts","sourceRoot":"","sources":["../../src/radio/serial-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"serial-config.d.ts","sourceRoot":"","sources":["../../src/radio/serial-config.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,QAAQ,CAAC,EAAE,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;IACjC;;OAEG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;OAEG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;CACf"}
|
package/package.json
CHANGED
package/src/radio/memory-map.ts
CHANGED
|
@@ -27,7 +27,12 @@ export type RadioMemoryMapValueKind =
|
|
|
27
27
|
| { kind: "integer"; min?: number; max?: number }
|
|
28
28
|
| { kind: "boolean" }
|
|
29
29
|
| { kind: "enum"; values: string[] }
|
|
30
|
-
| {
|
|
30
|
+
| {
|
|
31
|
+
kind: "ascii";
|
|
32
|
+
length: number;
|
|
33
|
+
/** Fill byte for unused character slots (default 0xFF). Kenwood names use 0. */
|
|
34
|
+
pad?: number;
|
|
35
|
+
}
|
|
31
36
|
| {
|
|
32
37
|
kind: "digits";
|
|
33
38
|
/** Number of decimal digit bytes. */
|
|
@@ -74,6 +79,22 @@ export type RadioMemoryMapValueKind =
|
|
|
74
79
|
ctcssMin?: number;
|
|
75
80
|
/** Added to DCS index for reverse polarity (Chirp uses 0x69). */
|
|
76
81
|
reverseOffset?: number;
|
|
82
|
+
}
|
|
83
|
+
| {
|
|
84
|
+
/**
|
|
85
|
+
* CTCSS tone stored as an index into `values` (Hz * 10, Springfield tenths).
|
|
86
|
+
* Kenwood TH-D74 `rtone` / `ctone` use Chirp TONES order.
|
|
87
|
+
*/
|
|
88
|
+
kind: "ctcss-index";
|
|
89
|
+
values: number[];
|
|
90
|
+
}
|
|
91
|
+
| {
|
|
92
|
+
/**
|
|
93
|
+
* DCS code stored as an index into `values`.
|
|
94
|
+
* Kenwood TH-D74 `dtcs_code` uses Chirp DTCS_CODES order.
|
|
95
|
+
*/
|
|
96
|
+
kind: "dcs-index";
|
|
97
|
+
values: number[];
|
|
77
98
|
};
|
|
78
99
|
|
|
79
100
|
/** UI metadata for a non-reserved field. */
|
|
@@ -94,11 +115,11 @@ export interface RadioMemoryMapField {
|
|
|
94
115
|
id: string;
|
|
95
116
|
/**
|
|
96
117
|
* Storage type:
|
|
97
|
-
* - u8 / u16: whole bytes (u16
|
|
118
|
+
* - u8 / u16 / u32: whole bytes (u16/u32 are little-endian, Chirp ul16/ul32)
|
|
98
119
|
* - bits: bitfield of `width` bits within the current byte (MSB-first)
|
|
99
120
|
* - char: ASCII byte (length via value.kind ascii or count)
|
|
100
121
|
*/
|
|
101
|
-
type: "u8" | "u16" | "bits" | "char";
|
|
122
|
+
type: "u8" | "u16" | "u32" | "bits" | "char";
|
|
102
123
|
/** Bit width when type is bits. */
|
|
103
124
|
width?: number;
|
|
104
125
|
/** When true, skip decode/encode for this padding field. */
|
|
@@ -130,6 +151,13 @@ export interface RadioMemoryMapStruct {
|
|
|
130
151
|
*/
|
|
131
152
|
count?: number;
|
|
132
153
|
stride?: number;
|
|
154
|
+
/**
|
|
155
|
+
* When set with `groupPad`, instances are packed into groups of `groupSize`
|
|
156
|
+
* records followed by `groupPad` padding bytes (Kenwood TH-D74: 6 × 40 + 16).
|
|
157
|
+
*/
|
|
158
|
+
groupSize?: number;
|
|
159
|
+
/** Padding bytes after each group of `groupSize` records. */
|
|
160
|
+
groupPad?: number;
|
|
133
161
|
/** Occupancy rule for repeated structs (e.g. empty channel slots). */
|
|
134
162
|
emptyWhen?: RadioMemoryMapEmptyWhen;
|
|
135
163
|
/**
|
|
@@ -154,6 +182,12 @@ export interface RadioMemoryMapChannelBindings {
|
|
|
154
182
|
transmitFrequency: string;
|
|
155
183
|
receiveTone: string;
|
|
156
184
|
transmitTone: string;
|
|
185
|
+
/**
|
|
186
|
+
* Optional parallel struct whose fields merge into each channel's settings
|
|
187
|
+
* (Kenwood TH-D74 flags: used, lockout, group). Occupancy `emptyWhen` on
|
|
188
|
+
* this struct, when present, also skips the channel.
|
|
189
|
+
*/
|
|
190
|
+
extras?: string;
|
|
157
191
|
}
|
|
158
192
|
|
|
159
193
|
/**
|
package/src/radio/protocol.ts
CHANGED
|
@@ -6,7 +6,7 @@ import type { RadioMemorySegment } from "./memory-segment.js";
|
|
|
6
6
|
* - number 0–255: literal byte
|
|
7
7
|
* - hex string such as `"0x50"`: literal byte
|
|
8
8
|
* - single-character string such as `"S"`: ASCII opcode
|
|
9
|
-
* - placeholder: `"$address"`, `"$chunkSize"`, `"$length"`, `"$data"`
|
|
9
|
+
* - placeholder: `"$address"`, `"$block"`, `"$chunkSize"`, `"$length"`, `"$data"`
|
|
10
10
|
*/
|
|
11
11
|
export type RadioByteToken = number | string;
|
|
12
12
|
|
|
@@ -17,32 +17,62 @@ export interface RadioExpectBytes {
|
|
|
17
17
|
bytes: number;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Read until a delimiter byte. Used for Kenwood live CAT lines ending in CR.
|
|
22
|
+
*/
|
|
23
|
+
export interface RadioExpectUntil {
|
|
24
|
+
until: RadioByteToken;
|
|
25
|
+
}
|
|
26
|
+
|
|
20
27
|
/**
|
|
21
28
|
* Expected serial reply for an exchange.
|
|
22
29
|
*
|
|
23
30
|
* - token: exact 1-byte match (ACK)
|
|
24
31
|
* - token array: exact multi-byte match, or a framed reply with `$` placeholders
|
|
25
32
|
* - `{ bytes: N }`: any N bytes
|
|
33
|
+
* - `{ until: token }`: variable-length reply ending at the delimiter (the delimiter is not included)
|
|
34
|
+
*/
|
|
35
|
+
export type RadioExpect = RadioByteToken | RadioByteToken[] | RadioExpectBytes | RadioExpectUntil;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Packer that converts live CAT replies into a logical memory-map record.
|
|
39
|
+
* `kenwood-th-f6` parses `MR`/`MNA` CSV into the 32-byte TH-F6 channel image.
|
|
26
40
|
*/
|
|
27
|
-
export type
|
|
41
|
+
export type RadioCatPack = "kenwood-th-f6";
|
|
28
42
|
|
|
29
43
|
/**
|
|
30
|
-
*
|
|
31
|
-
* At least one of `send` or `expect` must be present.
|
|
44
|
+
* Live CAT memory loop: one logical record per channel index, not clone blocks.
|
|
32
45
|
*/
|
|
33
|
-
export
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
export interface RadioCatMemoryConfig {
|
|
47
|
+
segment: string;
|
|
48
|
+
count: number;
|
|
49
|
+
recordSize: number;
|
|
50
|
+
pack: RadioCatPack;
|
|
51
|
+
indexWidth?: number;
|
|
52
|
+
emptyByte?: number;
|
|
53
|
+
timeout?: number;
|
|
54
|
+
interCommandDelayMs?: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* One serial exchange: send bytes and/or wait for a reply, and/or change baud.
|
|
59
|
+
* At least one of `send`, `expect`, or `setBaudRate` must be present.
|
|
60
|
+
*/
|
|
61
|
+
export interface RadioExchange {
|
|
62
|
+
description?: string;
|
|
63
|
+
send?: RadioByteToken[];
|
|
64
|
+
expect?: RadioExpect;
|
|
65
|
+
timeout?: number;
|
|
66
|
+
/**
|
|
67
|
+
* Milliseconds to wait after send (Kenwood CAT wake CR before ID).
|
|
68
|
+
*/
|
|
69
|
+
delay?: number;
|
|
70
|
+
/**
|
|
71
|
+
* Switch the serial baud rate before send/expect. TH-D74 clone mode
|
|
72
|
+
* enters programming at 9600 then transfers at 57600.
|
|
73
|
+
*/
|
|
74
|
+
setBaudRate?: number;
|
|
75
|
+
}
|
|
46
76
|
|
|
47
77
|
/**
|
|
48
78
|
* Chunked memory read: repeat an exchange across named segments.
|
|
@@ -81,4 +111,20 @@ export interface RadioWriteStep {
|
|
|
81
111
|
};
|
|
82
112
|
}
|
|
83
113
|
|
|
84
|
-
|
|
114
|
+
/**
|
|
115
|
+
* Read memories with live CAT commands (Kenwood TH-F6 `MR`/`MNA`).
|
|
116
|
+
*/
|
|
117
|
+
export interface RadioCatReadStep {
|
|
118
|
+
description?: string;
|
|
119
|
+
catRead: RadioCatMemoryConfig;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Write memories with live CAT commands (Kenwood TH-F6 `MW`/`MNA`).
|
|
124
|
+
*/
|
|
125
|
+
export interface RadioCatWriteStep {
|
|
126
|
+
description?: string;
|
|
127
|
+
catWrite: RadioCatMemoryConfig;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export type RadioProtocolStep = RadioExchange | RadioReadStep | RadioWriteStep | RadioCatReadStep | RadioCatWriteStep;
|
|
@@ -3,4 +3,16 @@ export interface RadioSerialConfig {
|
|
|
3
3
|
dataBits?: 8 | 5 | 6 | 7;
|
|
4
4
|
stopBits?: 1 | 1.5 | 2;
|
|
5
5
|
parity?: "none" | "even" | "odd";
|
|
6
|
+
/**
|
|
7
|
+
* Hardware RTS/CTS flow control. Kenwood TH-D74 clone mode needs this on macOS.
|
|
8
|
+
*/
|
|
9
|
+
rtscts?: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Explicit RTS line. TH-F6 live CAT needs this false; omit to keep RTS asserted.
|
|
12
|
+
*/
|
|
13
|
+
rts?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Explicit DTR line. Omit to keep DTR asserted after open.
|
|
16
|
+
*/
|
|
17
|
+
dtr?: boolean;
|
|
6
18
|
}
|