@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.
@@ -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 is little-endian, Chirp ul16)
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":"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"}
1
+ {"version":3,"file":"memory-map.d.ts","sourceRoot":"","sources":["../../src/radio/memory-map.ts"],"names":[],"mappings":"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"}
@@ -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
- * One serial exchange: send bytes and/or wait for a reply.
27
- * At least one of `send` or `expect` must be present.
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 RadioExchange = {
30
- description?: string;
31
- send: RadioByteToken[];
32
- expect?: RadioExpect;
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: RadioExpect;
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
- export type RadioProtocolStep = RadioExchange | RadioReadStep | RadioWriteStep;
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;;;;;;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;;;;;;;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,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,aAAa,GAAG,cAAc,CAAC"}
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;CAClC"}
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@springfield/ham-radio-api",
3
- "version": "17.3.0",
3
+ "version": "17.5.0",
4
4
  "author": "Bryan Hunt",
5
5
  "files": [
6
6
  "dist/",
@@ -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
- | { kind: "ascii"; length: number }
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 is little-endian, Chirp ul16)
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
  /**
@@ -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 RadioExpect = RadioByteToken | RadioByteToken[] | RadioExpectBytes;
41
+ export type RadioCatPack = "kenwood-th-f6";
28
42
 
29
43
  /**
30
- * One serial exchange: send bytes and/or wait for a reply.
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 type RadioExchange =
34
- | {
35
- description?: string;
36
- send: RadioByteToken[];
37
- expect?: RadioExpect;
38
- timeout?: number;
39
- }
40
- | {
41
- description?: string;
42
- send?: RadioByteToken[];
43
- expect: RadioExpect;
44
- timeout?: number;
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
- export type RadioProtocolStep = RadioExchange | RadioReadStep | RadioWriteStep;
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
  }