Fix: green LED flicker between red mute flashes during a DMR QSO
The DMR RX handler re-asserts the green LED whenever it reads it off, racing the main-loop mute clear, so green flickered between the red flashes. Add a LedGreenSuppress() hold in the LED driver: while muted the green LED is forced off (the re-assert becomes a no-op); on un-mute the hold is released and green is restored from the current RX state. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
63a833269a
commit
5ac77c5ae9
3 changed files with 39 additions and 7 deletions
|
|
@ -7,6 +7,10 @@ single running list until the first versioned release.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
- **Fix:** green LED **flickering** between the red flashes while muted during a DMR
|
||||||
|
QSO. The DMR RX handler re-asserts the green LED as soon as it reads it off, racing
|
||||||
|
the main-loop mute clear; the green LED is now **held off at the driver** for the
|
||||||
|
whole mute (and released on un-mute), so only the red flash shows.
|
||||||
- **`screenshot.sh`** — a one-command wrapper around the OpenGD77 screen grabber
|
- **`screenshot.sh`** — a one-command wrapper around the OpenGD77 screen grabber
|
||||||
that auto-detects the serial port and sets up a self-contained Python venv
|
that auto-detects the serial port and sets up a self-contained Python venv
|
||||||
(pyserial + pillow) on first run. Saves to `screenshots/`.
|
(pyserial + pillow) on first run. Saves to `screenshots/`.
|
||||||
|
|
|
||||||
|
|
@ -1441,18 +1441,27 @@ void applicationMainTask(void)
|
||||||
|
|
||||||
if (audioAmpIsMuted() || (lastVolume == -99)) // explicit mute or volume knob fully down
|
if (audioAmpIsMuted() || (lastVolume == -99)) // explicit mute or volume knob fully down
|
||||||
{
|
{
|
||||||
|
if (!muteFlashActive)
|
||||||
|
{
|
||||||
|
// Hold the green LED off for the whole mute, so the DMR RX handler
|
||||||
|
// (which re-asserts green as soon as it reads it off) can't make it
|
||||||
|
// flicker green between the red flashes.
|
||||||
|
LedGreenSuppress(true);
|
||||||
|
muteFlashActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
bool flashOn = ((ticksGetMillis() % 2000) < 500);
|
bool flashOn = ((ticksGetMillis() % 2000) < 500);
|
||||||
LedWrite(LED_GREEN, 0);
|
|
||||||
LedWrite(LED_RED, (flashOn ? 1 : 0));
|
LedWrite(LED_RED, (flashOn ? 1 : 0));
|
||||||
muteFlashActive = true;
|
|
||||||
}
|
}
|
||||||
else if (muteFlashActive)
|
else if (muteFlashActive)
|
||||||
{
|
{
|
||||||
// Just unmuted: stop the red flash and restore the green LED to the
|
// Just unmuted: release the green hold, stop the red flash and restore
|
||||||
// current RX state, so a QSO in progress lights green again instead of
|
// the green LED to the current RX state, so a QSO in progress lights
|
||||||
// staying dark. Green is normally lit for an active DMR slot (matching
|
// green again instead of staying dark. Green is normally lit for an
|
||||||
// our filter) or a received FM/digital signal; if nothing is being
|
// active DMR slot (matching our filter) or a received FM/digital signal;
|
||||||
// received it stays off. The normal RX code then keeps it correct.
|
// if nothing is being received it stays off. The normal RX code then
|
||||||
|
// keeps it correct.
|
||||||
|
LedGreenSuppress(false);
|
||||||
bool rxGreen = (slotState == DMR_STATE_RX_1) || (slotState == DMR_STATE_RX_2) ||
|
bool rxGreen = (slotState == DMR_STATE_RX_1) || (slotState == DMR_STATE_RX_2) ||
|
||||||
currentRadioDevice->analogSignalReceived || currentRadioDevice->digitalSignalReceived;
|
currentRadioDevice->analogSignalReceived || currentRadioDevice->digitalSignalReceived;
|
||||||
LedWrite(LED_RED, 0);
|
LedWrite(LED_RED, 0);
|
||||||
|
|
|
||||||
|
|
@ -48,9 +48,28 @@ void LEDsInit(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// When set, the green LED is held off: any LedWrite(LED_GREEN, 1) is forced to 0.
|
||||||
|
// Used while muted so the DMR RX handler (which re-asserts green whenever it reads
|
||||||
|
// it as 0) can't make the green LED flicker between the red mute flashes.
|
||||||
|
static volatile bool greenLedSuppressed = false;
|
||||||
|
|
||||||
|
void LedGreenSuppress(bool suppress)
|
||||||
|
{
|
||||||
|
greenLedSuppressed = suppress;
|
||||||
|
if (suppress)
|
||||||
|
{
|
||||||
|
LedWrite(LED_GREEN, 0); // force it off now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void LedWrite(LEDs_t theLED, uint8_t output)
|
void LedWrite(LEDs_t theLED, uint8_t output)
|
||||||
{
|
{
|
||||||
#if ! defined(PLATFORM_GD77S)
|
#if ! defined(PLATFORM_GD77S)
|
||||||
|
if ((theLED == LED_GREEN) && greenLedSuppressed)
|
||||||
|
{
|
||||||
|
output = 0; // green is held off (e.g. while muted)
|
||||||
|
}
|
||||||
|
|
||||||
LEDsState[theLED] = output;
|
LEDsState[theLED] = output;
|
||||||
|
|
||||||
if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) == 0)
|
if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) == 0)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue