The second receiver's link
A radio with two SoCs, each with its own receiver (the GD-88), runs RadioFoundry on both. The main SoC (A) has the UI, PTT and
the transmitter; the other (B) is a second receiver. They talk over a UART with this protocol (core/rx2/rx2_link.c).
The radio core sees B as board.rx2 (radio-features.md 2.2).
1. Frames
A5 5A len type seq payload[len] crc_hi crc_lo
lenis 0 to 96.seqcounts each side's frames. B'sACKnames theseqof theTUNEit answers.- The CRC is CRC-16/CCITT-FALSE (poly 0x1021, init 0xFFFF) over
len,type,seqand the payload. It is sent big endian. - A bad frame is dropped and counted. The parser looks for the next
A5 5A. - Payload numbers are little endian.
2. Messages
| Type | Name | From | Payload |
|---|---|---|---|
| 0x01 | HELLO_REQ |
A | none. B answers HELLO, then stops and mutes: A has just started or lost it |
| 0x02 | TUNE |
A | the settings (2.1). B answers ACK and a STATUS |
| 0x03 | STOP |
A | none. B stops receiving and mutes |
| 0x04 | AUDIO |
A | u8 on, u8 volume (percent) |
| 0x05 | STUB |
A | u32 0x53545542. B enters the flash stub on the link UART |
| 0x06 | RESET |
A | u32 0x53545542. B restarts |
| 0x07 | LED |
A | u8: the LEDs on B's SoC that are on (bit 0 LED 1, bit 1 LED 2). On the GD-88 A's status LEDs are wired to B. A sends it on a change and again when B comes back; B turns them off at HELLO_REQ |
| 0x81 | HELLO |
B | u8 protocol version (1), u8 flags (bit 0: B decodes DMR), then B's firmware version as text |
| 0x82 | STATUS |
B | 13 bytes (2.2) |
| 0x83 | ACK |
B | u8 the TUNE's seq, u8 result (0 = on it, else refused) |
| 0x84 | LOG |
B | text for A's log |
2.1 TUNE
| Offset | Size | Field |
|---|---|---|
| 0 | 4 | RX frequency (Hz) |
| 4 | 1 | mode (radio_mode_t) |
| 5 | 1 | bandwidth (radio_bw_t) |
| 6 | 1 | squelch level, 0 = open to 9 = tight |
| 7 | 1 | RX tone type (tone_type_t) |
| 8 | 2 | RX tone value (subtone_t.value) |
| 10 | 1 | DMR color code |
| 11 | 1 | DMR timeslot (1, 2) |
| 12 | 4 | our DMR ID |
| 16 | 4 | the channel's talk group, 0 = none |
| 20 | 1 | n, the RX group list's groups (0 to 16) |
| 21 | 4 | reserved, 0 |
| 25 | 4 n | the groups |
On DMR, B decodes the calls itself. It plays a call to one of the groups, to the talk group, or a private call to our ID.
2.2 STATUS
| Offset | Size | Field |
|---|---|---|
| 0 | 1 | bit 0 on its settings, 1 active (FM: squelch open with the right tone; DMR: a call for us), 2 DMR, 3 a group call, 4 heard (active and its audio on) |
| 1 | 2 | RSSI (dBm, signed) |
| 3 | 1 | noise |
| 4 | 4 | DMR source ID |
| 8 | 4 | DMR destination ID |
| 12 | 1 | reserved |
B sends one on every change, and at least every 500 ms.
3. Timing
- A sends
HELLO_REQevery second until B answers. - A counts B as down after 1.5 s without a frame. The core then alternates A's receiver.
- A sends a
TUNEagain when it has no goodACKafter 300 ms. - When B comes back, A sends its settings and audio state again.
- A drops a
TUNEwith the same settings as the last one.
4. Updating B
B has no USB or PC connector of its own. Its first install goes through its IAP loader. Later ones go through A:
- The host asks A's debug link for the bridge (
DL_CMD_RX2BRIDGE, debuglink.md 3.22). - After the reply, A sends
STUB. B writesSTAY(0x53544159) at 0x0004FFF8 and jumps to its first stage at 0x0300C000 (boot/README.md). - A copies bytes between the PC cable (UART1) and the link (UART3) both ways. Its transmitter stays off, and it feeds its watchdog.
- B's first stage sees
STAYand offers the boot ROM's handshake on the link for up to a minute. The host answers through A and loads the stub, which is told to stay on UART3. - The host writes B's image and restarts B (
--boot reset). - A restarts 10 s after the host's last byte, or after 90 s if the host never sends one. It finds B again with
HELLO_REQ. Bytes from B don't count: its handshake offers go on until the host answers.
The link stays at 115200 baud through the bridge: the host does not switch speed. stubtool.py --board gd88b
does steps 1, 4 and 5. Without a host, B's first stage starts B's application again after the minute, and A restarts.