diff --git a/CHANGELOG.md b/CHANGELOG.md index e91175f..42cdccb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ single running list until the first versioned release. ## 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 that auto-detects the serial port and sets up a self-contained Python venv (pyserial + pillow) on first run. Saves to `screenshots/`. diff --git a/MDUV380_firmware/application/source/applicationMain.c b/MDUV380_firmware/application/source/applicationMain.c index 6b6aa68..ba42160 100644 --- a/MDUV380_firmware/application/source/applicationMain.c +++ b/MDUV380_firmware/application/source/applicationMain.c @@ -1441,18 +1441,27 @@ void applicationMainTask(void) 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); - LedWrite(LED_GREEN, 0); LedWrite(LED_RED, (flashOn ? 1 : 0)); - muteFlashActive = true; } else if (muteFlashActive) { - // Just unmuted: stop the red flash and restore the green LED to the - // current RX state, so a QSO in progress lights green again instead of - // staying dark. Green is normally lit for an active DMR slot (matching - // our filter) or a received FM/digital signal; if nothing is being - // received it stays off. The normal RX code then keeps it correct. + // Just unmuted: release the green hold, stop the red flash and restore + // the green LED to the current RX state, so a QSO in progress lights + // green again instead of staying dark. Green is normally lit for an + // active DMR slot (matching our filter) or a received FM/digital signal; + // 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) || currentRadioDevice->analogSignalReceived || currentRadioDevice->digitalSignalReceived; LedWrite(LED_RED, 0); diff --git a/MDUV380_firmware/application/source/io/Leds.c b/MDUV380_firmware/application/source/io/Leds.c index 4022e65..5505324 100644 --- a/MDUV380_firmware/application/source/io/Leds.c +++ b/MDUV380_firmware/application/source/io/Leds.c @@ -48,9 +48,28 @@ void LEDsInit(void) #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) { #if ! defined(PLATFORM_GD77S) + if ((theLED == LED_GREEN) && greenLedSuppressed) + { + output = 0; // green is held off (e.g. while muted) + } + LEDsState[theLED] = output; if (settingsIsOptionBitSet(BIT_ALL_LEDS_DISABLED) == 0)