Under [FM] LinkMode=1, linkStateMachine() set m_extSignal false the
instant a single ext-audio sample went missing, with no debounce --
unlike the non-link duplex/simplex paths, which already tolerate a
brief gap via the RELAYING_EXT -> RELAYING_WAIT_EXT / m_ackDelayTimer
pattern before declaring a real loss. Since IO::process() drops PTT
the moment the downstream TX buffer runs dry, that zero-debounce cutoff
meant even a very brief, late-but-recoverable gap from the gateway
(scheduling jitter, a late UDP frame, etc.) could cascade into a full
PTT drop-and-rekey cycle -- far more audible than the underlying gap
itself.
Adds m_extGapTimer, mirroring the existing pattern: on the first missed
sample, start the timer instead of immediately clearing m_extSignal; a
gap that recovers before FM_LINK_EXT_GAP_MS (default 60ms) expires
never affects m_extSignal at all, so the transmitter never notices.
Only a gap that outlasts the timer is treated as a genuine end of
transmission, exactly as before.
linkSamples()'s currentExtSample is now zero-initialized, since
m_extSignal can now stay true for a few samples past an underrun --
silence, not stack garbage, must be what gets played out to the modem
during that window.
The CSBK slot type was only encoded into the ALOHA frame inside
setColorCode(), so it took effect only if a reconfigure happened after
an ALOHA frame had already been received; on the usual command ordering
(SET_CONFIG then ALOHA) the transmitted slot type depended entirely on
the host-supplied bytes. Remember the colour code and stamp the slot
type in writeAloha() as well.
Also clear m_controlChannel when trunking is disabled, so the host has
a way to stop control channel transmission other than rebooting, and
fix a stray tab introduced in createCACH().
The pinMode() call for PIN_FM was guarded by USE_ALTERNATE_POCSAG_LEDS
instead of USE_ALTERNATE_FM_LEDS, a copy and paste error. The Teensy
version and the setFMInt() implementation in this file both use the FM
macro.
m_invalidCount was missing from the constructor initialiser list and was
read uninitialised in process(), making the squelch behaviour after
power-up indeterminate. reset() also cleared neither hysteresis counter,
so state leaked across squelch resets.
handleIRQ() hardcoded USART1 when clearing the RXNE pending bit, so on
boards where the repeater/display UART is not USART1 (Nucleo, Discovery,
F767, UART5-based boards) the flag was cleared on the wrong peripheral.
Use the m_usart member, matching the TXE handling below.
Also fix flush(): it passed a flag constant to USART_GetITStatus and
span while TXE was set, which returns immediately since TXE indicates
the data register is already empty. Wait for the software TX FIFO to
drain and then for the TC flag, which indicates the shift register has
actually emptied.