diff --git a/CHANGELOG.md b/CHANGELOG.md index b056265..1cabe54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,17 @@ single running list until the first versioned release. ## Unreleased +_Nothing yet._ + +## 0.2.0 + +- **Fix crash** opening Display Options with **voice announcements on**: the Screen + Dim value ("100%"/"50%"/…) is a plain literal, but the shared menu code fed it to + `voicePromptsAppendLanguageString()`, which derives the prompt index from the + string's offset within the language table — a foreign pointer produced a garbage + index and crashed. The value now goes through `voicePromptsAppendString()`. Also + moved the dim-level high bit off a low legacy option bit (bit 2 → 29) and clamped + the level so it can never index past the option arrays. - **7-segment frequency font:** inactive segments are now off (background) instead of faintly lit — no dim "ghosting". "MHz" now matches the frequency colour, and there's 1px more space between the RX and TX frequency lines. diff --git a/MDUV380_firmware/application/include/freetrxVersion.h b/MDUV380_firmware/application/include/freetrxVersion.h index 6e9ed0b..e5e87b4 100644 --- a/MDUV380_firmware/application/include/freetrxVersion.h +++ b/MDUV380_firmware/application/include/freetrxVersion.h @@ -5,9 +5,9 @@ #define _FREETRX_VERSION_H_ #define FREETRX_VERSION_MAJOR 0 -#define FREETRX_VERSION_MINOR 1 +#define FREETRX_VERSION_MINOR 2 #define FREETRX_VERSION_PATCH 0 -#define FREETRX_VERSION "0.1.0" +#define FREETRX_VERSION "0.2.0" #endif // _FREETRX_VERSION_H_ diff --git a/MDUV380_firmware/application/include/functions/settings.h b/MDUV380_firmware/application/include/functions/settings.h index b453ed3..599d8f5 100644 --- a/MDUV380_firmware/application/include/functions/settings.h +++ b/MDUV380_firmware/application/include/functions/settings.h @@ -129,7 +129,7 @@ typedef enum { BIT_INVERSE_VIDEO = (SETTINGS_BITS_BANK_0 | (1 << 0)), BIT_PTT_LATCH = (SETTINGS_BITS_BANK_0 | (1 << 1)), - BIT_SCREEN_DIM_2 = (SETTINGS_BITS_BANK_0 | (1 << 2)), // high bit of the 3-bit screen-dim level + BIT_UNUSED_2 = (SETTINGS_BITS_BANK_0 | (1 << 2)), BIT_BATTERY_VOLTAGE_IN_HEADER = (SETTINGS_BITS_BANK_0 | (1 << 3)), BIT_SETTINGS_UPDATED = (SETTINGS_BITS_BANK_0 | (1 << 4)), BIT_TX_RX_FREQ_LOCK = (SETTINGS_BITS_BANK_0 | (1 << 5)), @@ -154,6 +154,7 @@ typedef enum #endif BIT_SECONDARY_LANGUAGE = (SETTINGS_BITS_BANK_0 | (1 << 19)), BIT_SCREEN_DIM_1 = (SETTINGS_BITS_BANK_0 | (1 << 20)), // middle bit of the 3-bit screen-dim level + BIT_SCREEN_DIM_2 = (SETTINGS_BITS_BANK_0 | (1 << 29)), // high bit of the 3-bit screen-dim level (kept off low legacy bits) BIT_DISPLAY_CHANNEL_DISTANCE = (SETTINGS_BITS_BANK_0 | (1 << 21)), #if defined(PLATFORM_MD2017) BIT_TRACKBALL_ENABLED = (SETTINGS_BITS_BANK_0 | (1 << 22)), diff --git a/MDUV380_firmware/application/source/functions/settings.c b/MDUV380_firmware/application/source/functions/settings.c index 1025001..475db67 100644 --- a/MDUV380_firmware/application/source/functions/settings.c +++ b/MDUV380_firmware/application/source/functions/settings.c @@ -607,7 +607,9 @@ bool settingsIsOptionBitSet(bitfieldOptions_t bit) // no new settings field (existing codeplugs keep both bits clear = SCREEN_DIM_OFF). uint8_t settingsGetScreenDimLevel(void) { - return (settingsIsOptionBitSet(BIT_SCREEN_DIM_0) ? 1 : 0) | (settingsIsOptionBitSet(BIT_SCREEN_DIM_1) ? 2 : 0) | (settingsIsOptionBitSet(BIT_SCREEN_DIM_2) ? 4 : 0); + uint8_t level = (settingsIsOptionBitSet(BIT_SCREEN_DIM_0) ? 1 : 0) | (settingsIsOptionBitSet(BIT_SCREEN_DIM_1) ? 2 : 0) | (settingsIsOptionBitSet(BIT_SCREEN_DIM_2) ? 4 : 0); + // Never return an out-of-range level: dimOpts[]/dimPercent[] are SCREEN_DIM_NUM long. + return (level < SCREEN_DIM_NUM) ? level : SCREEN_DIM_OFF; } void settingsSetScreenDimLevel(uint8_t level) diff --git a/MDUV380_firmware/application/source/user_interface/menuDisplayOptions.c b/MDUV380_firmware/application/source/user_interface/menuDisplayOptions.c index d082656..68bfe26 100644 --- a/MDUV380_firmware/application/source/user_interface/menuDisplayOptions.c +++ b/MDUV380_firmware/application/source/user_interface/menuDisplayOptions.c @@ -249,9 +249,23 @@ static void updateScreen(bool isFirstRun) case DISPLAY_SCREEN_DIM: { - const char *dimOpts[] = { currentLanguage->off, "100%", "50%", "30%", "15%" }; + // The "%" values are plain string literals, not currentLanguage entries, + // so they must go through rightSideVar -> voicePromptsAppendString(). + // Passing them to voicePromptsAppendLanguageString() (as the shared code + // does for rightSideConst) would treat the pointer as an offset into the + // language table and crash when voice prompts are enabled. "Off" is a real + // language string, so it can stay in rightSideConst. + const char *dimOpts[] = { NULL, "100%", "50%", "30%", "15%" }; + uint8_t dimLevel = settingsGetScreenDimLevel(); leftSide = "Screen Dim"; - rightSideConst = dimOpts[settingsGetScreenDimLevel()]; + if (dimLevel == SCREEN_DIM_OFF) + { + rightSideConst = currentLanguage->off; + } + else + { + snprintf(rightSideVar, SCREEN_LINE_BUFFER_SIZE, "%s", dimOpts[dimLevel]); + } } break;