Compare commits

...
Author SHA1 Message Date
Armel FAUVEAU dbc520cf8d WIP: display detected CSS code during scan range 2026-05-23 02:40:19 +02:00
Armel FAUVEAU 6cceb26814 Merge pull request #357 from mrkusypl/feature_update_v5_2
Code refactoring (54 B)
2026-05-17 17:12:44 +02:00
mrkusypl a77b132fa5 Code refactoring (54 B) 2026-05-17 16:48:43 +02:00
Armel FAUVEAU 86aa05f1ec Sync screensaver frames to k5viewer 2026-05-17 12:33:16 +02:00
Armel FAUVEAU 953f579adb Prevent screensaver during FM scan 2026-05-17 02:40:13 +02:00
Armel FAUVEAU d429b3afe8 Prevent screensaver during Beam 2026-05-17 02:34:06 +02:00
Armel FAUVEAU a65a4f601a Improve F+4 frequency copy scan UI 2026-05-17 02:15:22 +02:00
Armel FAUVEAU 546cd35681 Add LOGO+ scrolling SetSav mode 2026-05-13 03:21:43 +02:00
Armel FAUVEAU 8ecf976067 Exit SetSav when waking from SetTmr sleep 2026-05-13 02:49:21 +02:00
Armel FAUVEAU 3e54dc1c00 Merge pull request #350 from mrkusypl/feature_update_v5_2
Code refactoring (16 B)
2026-05-13 01:24:17 +02:00
Armel FAUVEAU 9eb9a9da5c Keep RX blink while reducing LCD redraws 2026-05-13 01:16:57 +02:00
mrkusypl a74529b9ec Code refactoring (16 B) 2026-05-13 01:10:47 +02:00
Armel FAUVEAU 7ccb53572a Fix SetNav is BLTime is OFF 2026-05-13 00:44:17 +02:00
Armel FAUVEAU c515188a06 Improve SetSav from @mrkusypl feedback 2026-05-12 23:19:23 +02:00
Armel FAUVEAU cdcb950ccd Block SetSav during RX 2026-05-12 19:39:27 +02:00
Armel FAUVEAU 13ca3b8a39 Skip SetSav during TX 2026-05-12 18:38:40 +02:00
Armel FAUVEAU 34acff0fbf Throttle SetTmr status refresh 2026-05-12 18:34:10 +02:00
Armel FAUVEAU fa75ab4243 Add SetSav BLMin screensaver 2026-05-12 18:01:46 +02:00
Armel FAUVEAU 1589d8bdd7 Merge pull request #345 from mrkusypl/feature_update_v5_2
Code refactoring (288 B)
2026-05-11 22:59:28 +02:00
mrkusypl a5597a1ab9 Minor corrections to refactoring 2026-05-11 21:43:05 +02:00
mrkusypl 955b245e66 Code refactoring (328 B) 2026-05-11 15:21:48 +02:00
Armel FAUVEAU 2c4bca4202 Archive LOGO 2026-05-10 15:24:01 +02:00
Armel FAUVEAU 6c4c240e9a Enable boot beep with POnMsg LOGO (Issue #340) 2026-05-08 16:57:09 +02:00
24 changed files with 791 additions and 302 deletions

No files matched your search

+5
View File
@@ -215,6 +215,11 @@ if(ENABLE_FEAT_F4HWN_BEAM AND NOT ENABLE_AIRCOPY)
endif() endif()
enable_feature(ENABLE_FEAT_F4HWN_QRCODE) enable_feature(ENABLE_FEAT_F4HWN_QRCODE)
enable_feature(ENABLE_FEAT_F4HWN_LOGO) enable_feature(ENABLE_FEAT_F4HWN_LOGO)
enable_feature(ENABLE_FEAT_F4HWN_LOGO_SAV)
if(ENABLE_FEAT_F4HWN_LOGO_SAV AND NOT ENABLE_FEAT_F4HWN_LOGO)
message(FATAL_ERROR "ENABLE_FEAT_F4HWN_LOGO_SAV requires ENABLE_FEAT_F4HWN_LOGO.")
endif()
# ---- DEBUGGING ---- # ---- DEBUGGING ----
+310 -6
View File
@@ -72,11 +72,13 @@
#include "sram-overlay.h" #include "sram-overlay.h"
#endif #endif
#include "ui/battery.h" #include "ui/battery.h"
#include "ui/helper.h"
#include "ui/inputbox.h" #include "ui/inputbox.h"
#include "ui/main.h" #include "ui/main.h"
#include "ui/menu.h" #include "ui/menu.h"
#include "ui/status.h" #include "ui/status.h"
#include "ui/ui.h" #include "ui/ui.h"
#include "ui/welcome.h"
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
#include "screenshot.h" #include "screenshot.h"
@@ -86,6 +88,19 @@ static bool flagSaveVfo;
static bool flagSaveSettings; static bool flagSaveSettings;
static bool flagSaveChannel; static bool flagSaveChannel;
#ifdef ENABLE_FEAT_F4HWN_SLEEP
static KEY_Code_t gSleepWakeKey = KEY_INVALID;
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
static bool gScreenSaverDisplayed;
static uint8_t gScreenSaverTick;
static uint16_t gMatrixRandom = 0xACE1;
static uint8_t gMatrixHeads[32];
static uint8_t gMatrixSpeeds[32];
static KEY_Code_t gScreenSaverWakeKey = KEY_INVALID;
#endif
static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld); static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
@@ -110,11 +125,199 @@ static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM-1);
static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM); static_assert(ARRAY_SIZE(ProcessKeysFunctions) == DISPLAY_N_ELEM);
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
static uint8_t ScreenSaverRandom(void)
{
gMatrixRandom = (uint16_t)(gMatrixRandom * 2053u + 13849u);
return (uint8_t)(gMatrixRandom >> 8);
}
static void ScreenSaverSetPixel(uint8_t x, uint8_t y, bool fill)
{
const uint8_t pattern = 1u << (y & 7u);
if (y < 8) {
if (fill)
gStatusLine[x] |= pattern;
else
gStatusLine[x] &= (uint8_t)~pattern;
return;
}
y -= 8;
if (fill)
gFrameBuffer[y >> 3][x] |= pattern;
else
gFrameBuffer[y >> 3][x] &= (uint8_t)~pattern;
}
static void ScreenSaverDrawMatrixGlyph(uint8_t x, int16_t y, uint8_t glyph)
{
static const uint8_t glyphs[][3] = {
{0x1F, 0x11, 0x1F},
{0x15, 0x1F, 0x15},
{0x1D, 0x15, 0x17},
{0x17, 0x15, 0x1D},
{0x1F, 0x04, 0x1F},
{0x1B, 0x15, 0x1B},
{0x0E, 0x11, 0x0E},
{0x11, 0x0A, 0x04}
};
for (uint8_t dx = 0; dx < 3; dx++) {
uint8_t pixels = glyphs[glyph & 7u][dx];
for (uint8_t dy = 0; dy < 5; dy++) {
const int16_t py = y + dy;
if ((pixels & (1u << dy)) && py >= 0 && py < LCD_HEIGHT)
ScreenSaverSetPixel(x + dx, (uint8_t)py, true);
}
}
}
static void ScreenSaverRenderMatrix(bool reset)
{
if (reset) {
for (uint8_t i = 0; i < ARRAY_SIZE(gMatrixHeads); i++) {
gMatrixHeads[i] = ScreenSaverRandom() % 112u;
gMatrixSpeeds[i] = 1u + (ScreenSaverRandom() % 3u);
}
} else {
for (uint8_t i = 0; i < ARRAY_SIZE(gMatrixHeads); i++) {
gMatrixHeads[i] += gMatrixSpeeds[i];
if (gMatrixHeads[i] > 112u)
gMatrixHeads[i] = ScreenSaverRandom() & 0x0Fu;
}
}
UI_StatusClear();
UI_DisplayClear();
for (uint8_t col = 0; col < ARRAY_SIZE(gMatrixHeads); col++) {
const uint8_t x = col * 4u;
for (uint8_t trail = 0; trail < 8; trail++) {
const int16_t y = (int16_t)gMatrixHeads[col] - ((int16_t)trail * 7);
const uint8_t glyph = (uint8_t)(col + trail + gMatrixHeads[col]);
if (trail == 0) {
ScreenSaverDrawMatrixGlyph(x, y, glyph);
} else if ((trail < 4) || ((glyph & 1u) != 0)) {
ScreenSaverDrawMatrixGlyph(x, y, glyph);
}
}
}
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
}
static void ScreenSaverScrollLogoLine(uint8_t *line)
{
const uint8_t first = line[0];
memmove(line, line + 1, LCD_WIDTH - 1);
line[LCD_WIDTH - 1] = first;
}
static void ScreenSaverRenderLogoPlus(bool reset)
{
if (reset) {
UI_DisplayLogo();
return;
}
ScreenSaverScrollLogoLine(gStatusLine);
for (uint8_t line = 0; line < FRAME_LINES; line++)
ScreenSaverScrollLogoLine(gFrameBuffer[line]);
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
}
static void ScreenSaverUpdateViewer(void)
{
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
SCREENSHOT_Update(false);
#endif
}
static bool ScreenSaverCanDisplay(void)
{
if (gSetting_set_sav == SET_SAV_OFF ||
gEeprom.BACKLIGHT_TIME == 0 ||
gEeprom.BACKLIGHT_TIME >= 61 ||
gScreenSaverDisplayed ||
gCurrentFunction == FUNCTION_TRANSMIT ||
FUNCTION_IsRx() ||
gPttIsPressed
#ifdef ENABLE_FMRADIO
|| gFM_ScanState != FM_SCAN_OFF
#endif
#ifdef ENABLE_FEAT_F4HWN_BEAM
|| gBeamActive
#endif
)
{
return false;
}
if (gScreenToDisplay == DISPLAY_MAIN)
return true;
#ifdef ENABLE_FMRADIO
if (gScreenToDisplay == DISPLAY_FM)
return true;
#endif
return false;
}
static void ScreenSaverTryDisplay(void)
{
if (!ScreenSaverCanDisplay())
return;
if (gSetting_set_sav == SET_SAV_LOGO)
UI_DisplayLogo();
else if (gSetting_set_sav == SET_SAV_LOGO_PLUS)
ScreenSaverRenderLogoPlus(true);
else if (gSetting_set_sav == SET_SAV_MATRIX)
ScreenSaverRenderMatrix(true);
gScreenSaverDisplayed = true;
gScreenSaverTick = 0;
gUpdateDisplay = false;
gUpdateStatus = false;
ScreenSaverUpdateViewer();
}
static void ScreenSaverExit(void)
{
if (gScreenSaverDisplayed) {
gScreenSaverDisplayed = false;
gUpdateDisplay = true;
gUpdateStatus = true;
}
}
#endif
bool APP_IsScreenSaverDisplayed(void)
{
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
return gScreenSaverDisplayed;
#else
return false;
#endif
}
static void CheckForIncoming(void) static void CheckForIncoming(void)
{ {
if (!g_SquelchLost) if (!g_SquelchLost)
return; // squelch is closed return; // squelch is closed
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
ScreenSaverExit();
#endif
// squelch is open // squelch is open
if (gScanStateDir == SCAN_OFF) if (gScanStateDir == SCAN_OFF)
@@ -495,6 +698,10 @@ void APP_StartListening(FUNCTION_Type_t function)
{ {
const unsigned int vfo = gEeprom.RX_VFO; const unsigned int vfo = gEeprom.RX_VFO;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
ScreenSaverExit();
#endif
#ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER #ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER
gRxTimerCountdown_500ms = 7200; gRxTimerCountdown_500ms = 7200;
#endif #endif
@@ -1416,6 +1623,36 @@ void APP_TimeSlice10ms(void)
if (gUpdateDisplayCurrent) { if (gUpdateDisplayCurrent) {
gUpdateDisplay = false; gUpdateDisplay = false;
}
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
bool screenSaverRendered = false;
if (gScreenSaverDisplayed) {
if (gUpdateDisplayCurrent) {
gUpdateDisplayCurrent = false;
} else if (gUpdateStatusCurrent) {
gUpdateStatusCurrent = false;
gUpdateStatus = false;
}
if (gSetting_set_sav == SET_SAV_MATRIX) {
if (++gScreenSaverTick >= 8u) {
gScreenSaverTick = 0;
ScreenSaverRenderMatrix(false);
screenSaverRendered = true;
}
} else if (gSetting_set_sav == SET_SAV_LOGO_PLUS) {
if (++gScreenSaverTick >= 16u) {
gScreenSaverTick = 0;
ScreenSaverRenderLogoPlus(false);
screenSaverRendered = true;
}
}
}
#endif
if (gUpdateDisplayCurrent) {
GUI_DisplayScreen(); GUI_DisplayScreen();
} }
@@ -1424,7 +1661,11 @@ void APP_TimeSlice10ms(void)
} }
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT #ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
if (gUpdateDisplayCurrent || gUpdateStatusCurrent) { if (gUpdateDisplayCurrent || gUpdateStatusCurrent
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
|| screenSaverRendered
#endif
) {
SCREENSHOT_Update(false); SCREENSHOT_Update(false);
} }
#endif #endif
@@ -1521,6 +1762,10 @@ void APP_TimeSlice10ms(void)
SCANNER_TimeSlice10ms(); SCANNER_TimeSlice10ms();
#ifdef ENABLE_SCAN_RANGES
CHFRSCANNER_UpdateCssDetection();
#endif
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY
if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1) { if (gScreenToDisplay == DISPLAY_AIRCOPY && gAircopyState == AIRCOPY_TRANSFER && gAirCopyIsSendMode == 1) {
if (!AIRCOPY_SendMessage()) { if (!AIRCOPY_SendMessage()) {
@@ -1563,6 +1808,17 @@ void APP_TimeSlice500ms(void)
if (--gKeypadLocked == 0) if (--gKeypadLocked == 0)
gUpdateDisplay = true; gUpdateDisplay = true;
#ifdef ENABLE_FEAT_F4HWN_RX_TX_TIMER
if (gSetting_set_tmr && (gCurrentFunction == FUNCTION_TRANSMIT || FUNCTION_IsRx())) {
const uint16_t timerCountdown = (gCurrentFunction == FUNCTION_TRANSMIT)
? gTxTimerCountdown_500ms
: gRxTimerCountdown_500ms;
if ((timerCountdown & 1u) != 0u)
gUpdateStatus = true;
}
#endif
if (gKeyInputCountdown > 0) if (gKeyInputCountdown > 0)
{ {
if (--gKeyInputCountdown == 0) if (--gKeyInputCountdown == 0)
@@ -1634,15 +1890,23 @@ void APP_TimeSlice500ms(void)
&& gEeprom.BACKLIGHT_TIME < 61 && gEeprom.BACKLIGHT_TIME < 61
) { ) {
BACKLIGHT_TurnOff(); BACKLIGHT_TurnOff();
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
ScreenSaverTryDisplay();
#endif
} }
#ifdef ENABLE_FEAT_F4HWN_SLEEP #ifdef ENABLE_FEAT_F4HWN_SLEEP
if (gSleepModeCountdown_500ms == gSetting_set_off * 120 && gWakeUp) { if (gSleepModeCountdown_500ms == gSetting_set_off * 120 && gWakeUp) {
//ST7565_Init(); //ST7565_Init();
ST7565_FixInterfGlitch(); ST7565_FixInterfGlitch();
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
ScreenSaverExit();
#endif
BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false); BK4819_ToggleGpioOut(BK4819_GPIO5_PIN1_RED, false);
gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10; gPowerSave_10ms = gEeprom.BATTERY_SAVE * 10;
gWakeUp = false; gWakeUp = false;
gUpdateDisplay = true;
gUpdateStatus = true;
} }
if(gCurrentFunction != FUNCTION_TRANSMIT && !FUNCTION_IsRx() if(gCurrentFunction != FUNCTION_TRANSMIT && !FUNCTION_IsRx()
@@ -1815,6 +2079,17 @@ void APP_TimeSlice500ms(void)
#endif #endif
} }
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
if (gBacklightCountdown_500ms == 0 &&
gEeprom.BACKLIGHT_TIME > 0 &&
gEeprom.BACKLIGHT_TIME < 61 &&
!gAskToSave &&
!gCssBackgroundScan)
{
ScreenSaverTryDisplay();
}
#endif
BATTERY_TimeSlice500ms(); BATTERY_TimeSlice500ms();
SCANNER_TimeSlice500ms(); SCANNER_TimeSlice500ms();
UI_MAIN_TimeSlice500ms(); UI_MAIN_TimeSlice500ms();
@@ -1876,24 +2151,53 @@ static void ALARM_Off(void)
static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld) static void ProcessKey(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
{ {
#ifdef ENABLE_FEAT_F4HWN_SLEEP #ifdef ENABLE_FEAT_F4HWN_SLEEP
if (gSleepWakeKey != KEY_INVALID) {
if (Key == gSleepWakeKey && !bKeyPressed)
gSleepWakeKey = KEY_INVALID;
return;
}
if(gWakeUp) if(gWakeUp)
{ {
if(!bKeyPressed || Key == KEY_PTT) if(bKeyPressed || Key == KEY_PTT)
{ {
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
ScreenSaverExit();
#endif
BACKLIGHT_TurnOn(); BACKLIGHT_TurnOn();
if(Key != KEY_PTT) if(Key != KEY_PTT)
{ {
Key = KEY_INVALID; gSleepWakeKey = Key;
gBeepToPlay = BEEP_NONE;
return;
} }
} }
else else if(Key != KEY_PTT)
{ {
Key = KEY_INVALID;
}
}
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
if (gScreenSaverWakeKey != KEY_INVALID) {
if (Key == gScreenSaverWakeKey && !bKeyPressed)
gScreenSaverWakeKey = KEY_INVALID;
return;
}
if (bKeyPressed && gScreenSaverDisplayed) {
ScreenSaverExit();
BACKLIGHT_TurnOn();
if (Key != KEY_PTT) {
gScreenSaverWakeKey = Key;
gBeepToPlay = BEEP_NONE;
return; return;
} }
} }
#endif #endif
if (Key == KEY_EXIT && !BACKLIGHT_IsOn() && gEeprom.BACKLIGHT_TIME > 0) if (Key == KEY_EXIT && !BACKLIGHT_IsOn() && gEeprom.BACKLIGHT_TIME > 0)
{ // just turn the light on for now so the user can see what's what { // just turn the light on for now so the user can see what's what
+1 -1
View File
@@ -31,6 +31,6 @@ uint32_t APP_SetFrequencyByStep(VFO_Info_t *pInfo, int8_t direction);
void APP_Update(void); void APP_Update(void);
void APP_TimeSlice10ms(void); void APP_TimeSlice10ms(void);
void APP_TimeSlice500ms(void); void APP_TimeSlice500ms(void);
bool APP_IsScreenSaverDisplayed(void);
#endif #endif
+54
View File
@@ -20,6 +20,10 @@ bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES #ifdef ENABLE_SCAN_RANGES
uint32_t gScanRangeStart; uint32_t gScanRangeStart;
uint32_t gScanRangeStop; uint32_t gScanRangeStop;
DCS_CodeType_t gScanRangeCssType = CODE_TYPE_OFF;
uint8_t gScanRangeCssCode = 0xFF;
static uint8_t scanRangeCssCandidate = 0xFF;
static uint8_t scanRangeCssHitCount = 0;
#define SCAN_RANGE_SKIP_MAX 32 #define SCAN_RANGE_SKIP_MAX 32
#if (SCAN_RANGE_SKIP_MAX & (SCAN_RANGE_SKIP_MAX - 1)) != 0 #if (SCAN_RANGE_SKIP_MAX & (SCAN_RANGE_SKIP_MAX - 1)) != 0
@@ -182,6 +186,56 @@ bool CHFRSCANNER_HasScanRangeExcludedOrdinal(uint32_t first_ordinal, uint32_t la
return false; return false;
} }
void CHFRSCANNER_UpdateCssDetection(void)
{
if (!gScanRangeStart || !FUNCTION_IsRx())
{
gScanRangeCssType = CODE_TYPE_OFF;
gScanRangeCssCode = 0xFF;
scanRangeCssCandidate = 0xFF;
scanRangeCssHitCount = 0;
return;
}
uint32_t cdcssFreq;
uint16_t ctcssFreq;
const BK4819_CssScanResult_t result = BK4819_GetCxCSSScanResult(&cdcssFreq, &ctcssFreq);
if (result == BK4819_CSS_RESULT_CDCSS)
{
const uint8_t Code = DCS_GetCdcssCode(cdcssFreq);
if (Code != 0xFF && Code != gScanRangeCssCode)
{
gScanRangeCssType = CODE_TYPE_DIGITAL;
gScanRangeCssCode = Code;
scanRangeCssCandidate = 0xFF;
scanRangeCssHitCount = 0;
gUpdateDisplay = true;
}
}
else if (result == BK4819_CSS_RESULT_CTCSS)
{
const uint8_t Code = DCS_GetCtcssCode(ctcssFreq);
if (Code != 0xFF)
{
if (Code == scanRangeCssCandidate)
{
if (++scanRangeCssHitCount >= 2 && Code != gScanRangeCssCode)
{
gScanRangeCssType = CODE_TYPE_CONTINUOUS_TONE;
gScanRangeCssCode = Code;
gUpdateDisplay = true;
}
}
else
{
scanRangeCssCandidate = Code;
scanRangeCssHitCount = 1;
}
}
}
}
#endif #endif
static void CHFRSCANNER_AbortActiveReception(void) static void CHFRSCANNER_AbortActiveReception(void)
+3
View File
@@ -15,8 +15,11 @@ extern bool gScanPauseMode;
#ifdef ENABLE_SCAN_RANGES #ifdef ENABLE_SCAN_RANGES
extern uint32_t gScanRangeStart; extern uint32_t gScanRangeStart;
extern uint32_t gScanRangeStop; extern uint32_t gScanRangeStop;
extern DCS_CodeType_t gScanRangeCssType;
extern uint8_t gScanRangeCssCode;
bool CHFRSCANNER_ExcludeCurrentScanRange(void); bool CHFRSCANNER_ExcludeCurrentScanRange(void);
bool CHFRSCANNER_HasScanRangeExcludedOrdinal(uint32_t first_ordinal, uint32_t last_ordinal); bool CHFRSCANNER_HasScanRangeExcludedOrdinal(uint32_t first_ordinal, uint32_t last_ordinal);
void CHFRSCANNER_UpdateCssDetection(void);
#endif #endif
void CHFRSCANNER_Found(void); void CHFRSCANNER_Found(void);
+17
View File
@@ -222,6 +222,13 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
*pMax = ARRAY_SIZE(gSubMenu_RX_TX) - 1; *pMax = ARRAY_SIZE(gSubMenu_RX_TX) - 1;
break; break;
#if defined(ENABLE_FEAT_F4HWN) && defined(ENABLE_FEAT_F4HWN_LOGO_SAV)
case MENU_SET_SAV:
//*pMin = 0;
*pMax = SET_SAV_LEN - 1;
break;
#endif
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
case MENU_AM_FIX: case MENU_AM_FIX:
@@ -1030,6 +1037,11 @@ void MENU_AcceptSetting(void)
case MENU_SET_TMR: case MENU_SET_TMR:
gSetting_set_tmr = gSubMenuSelection; gSetting_set_tmr = gSubMenuSelection;
break; break;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
case MENU_SET_SAV:
gSetting_set_sav = gSubMenuSelection;
break;
#endif
case MENU_TX_LOCK: case MENU_TX_LOCK:
gTxVfo->TX_LOCK = gSubMenuSelection; gTxVfo->TX_LOCK = gSubMenuSelection;
gRequestSaveChannel = 1; gRequestSaveChannel = 1;
@@ -1497,6 +1509,11 @@ void MENU_ShowCurrentSetting(void)
case MENU_SET_TMR: case MENU_SET_TMR:
gSubMenuSelection = gSetting_set_tmr; gSubMenuSelection = gSetting_set_tmr;
break; break;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
case MENU_SET_SAV:
gSubMenuSelection = gSetting_set_sav;
break;
#endif
case MENU_TX_LOCK: case MENU_TX_LOCK:
gSubMenuSelection = gTxVfo->TX_LOCK; gSubMenuSelection = gTxVfo->TX_LOCK;
break; break;
+3 -3
View File
@@ -506,8 +506,8 @@ void SCANNER_TimeSlice500ms(void)
if (SCANNER_IsScanning() && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) { if (SCANNER_IsScanning() && gScannerSaveState == SCAN_SAVE_NO_PROMPT && gScanCssState < SCAN_CSS_STATE_FOUND) {
gScanProgressIndicator++; gScanProgressIndicator++;
#ifndef ENABLE_NO_CODE_SCAN_TIMEOUT #ifndef ENABLE_NO_CODE_SCAN_TIMEOUT
if (gScanProgressIndicator > 32) { if (gScanCssState == SCAN_CSS_STATE_SCANNING && gScanProgressIndicator > 32) {
if (gScanCssState == SCAN_CSS_STATE_SCANNING && !gScanSingleFrequency) if (!gScanSingleFrequency)
gScanCssState = SCAN_CSS_STATE_FOUND; gScanCssState = SCAN_CSS_STATE_FOUND;
else else
gScanCssState = SCAN_CSS_STATE_FAILED; gScanCssState = SCAN_CSS_STATE_FAILED;
@@ -525,4 +525,4 @@ void SCANNER_TimeSlice500ms(void)
bool SCANNER_IsScanning(void) bool SCANNER_IsScanning(void)
{ {
return gCssBackgroundScan || (gScreenToDisplay == DISPLAY_SCANNER); return gCssBackgroundScan || (gScreenToDisplay == DISPLAY_SCANNER);
} }
+2 -11
View File
@@ -1604,7 +1604,7 @@ static void ShowChannelName(uint32_t f)
if (f != channelF) { if (f != channelF) {
channelF = f; channelF = f;
unsigned int i; unsigned int i;
memset(channelName, 0, sizeof(channelName)); channelName[0] = 0;
for (i = 0; IS_MR_CHANNEL(i); i++) for (i = 0; IS_MR_CHANNEL(i); i++)
{ {
if (RADIO_CheckValidChannel(i, false, 0)) if (RADIO_CheckValidChannel(i, false, 0))
@@ -1715,16 +1715,7 @@ static bool SpectrumColumnAtOrAboveY(const uint8_t *topY, uint8_t x, uint8_t y)
static uint8_t GetScanStepTextWidth() static uint8_t GetScanStepTextWidth()
{ {
uint16_t whole = GetScanStep() / 100; return (sprintf(NULL, "%u", GetScanStep() / 100) + 4) * 4; // "%u.%02uk", 4 px advance per char
uint8_t digits = 1;
while (whole >= 10)
{
whole /= 10;
digits++;
}
return (digits + 4) * 4; // "%u.%02uk", 4 px advance per char
} }
static void DrawRssiTriggerLevel(const uint8_t *topY) static void DrawRssiTriggerLevel(const uint8_t *topY)
+6 -1
View File
@@ -107,7 +107,12 @@ void BACKLIGHT_InitHardware()
static void BACKLIGHT_Sound(void) static void BACKLIGHT_Sound(void)
{ {
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_ALL) if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND ||
gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_ALL
#ifdef ENABLE_FEAT_F4HWN_LOGO
|| gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_LOGO
#endif
)
{ {
AUDIO_PlayBeep(BEEP_880HZ_60MS_TRIPLE_BEEP); AUDIO_PlayBeep(BEEP_880HZ_60MS_TRIPLE_BEEP);
AUDIO_PlayBeep(BEEP_880HZ_60MS_TRIPLE_BEEP); AUDIO_PlayBeep(BEEP_880HZ_60MS_TRIPLE_BEEP);
+3
View File
@@ -137,6 +137,9 @@ enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
#ifdef ENABLE_FEAT_F4HWN_NARROWER #ifdef ENABLE_FEAT_F4HWN_NARROWER
bool gSetting_set_nfm = 0; bool gSetting_set_nfm = 0;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
uint8_t gSetting_set_sav = SET_SAV_OFF;
#endif
bool gSetting_set_tmr = 0; bool gSetting_set_tmr = 0;
bool gSetting_set_ptt_session; bool gSetting_set_ptt_session;
#ifdef ENABLE_FEAT_F4HWN_DEBUG #ifdef ENABLE_FEAT_F4HWN_DEBUG
+13
View File
@@ -181,6 +181,16 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
enum SET_SAV_t {
SET_SAV_OFF,
SET_SAV_LOGO,
SET_SAV_LOGO_PLUS,
SET_SAV_MATRIX,
SET_SAV_LEN
};
#endif
extern uint8_t gSetting_set_pwr; extern uint8_t gSetting_set_pwr;
extern bool gSetting_set_ptt; extern bool gSetting_set_ptt;
extern uint8_t gSetting_set_tot; extern uint8_t gSetting_set_tot;
@@ -197,6 +207,9 @@ extern enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx;
#ifdef ENABLE_FEAT_F4HWN_NARROWER #ifdef ENABLE_FEAT_F4HWN_NARROWER
extern bool gSetting_set_nfm; extern bool gSetting_set_nfm;
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
extern uint8_t gSetting_set_sav;
#endif
extern bool gSetting_set_tmr; extern bool gSetting_set_tmr;
extern bool gSetting_set_ptt_session; extern bool gSetting_set_ptt_session;
#ifdef ENABLE_FEAT_F4HWN_DEBUG #ifdef ENABLE_FEAT_F4HWN_DEBUG
+17 -6
View File
@@ -454,11 +454,19 @@ gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data16[5]) ? Data16[5] : (FREQ_CHANNE
// 1FF0..0x1FF7 // 1FF0..0x1FF7
// TODO: address TBD // TODO: address TBD
PY25Q16_ReadBuffer(0x00A158, Data, 8); PY25Q16_ReadBuffer(0x00A158, Data, 8);
const uint8_t set_ptt_scn = Data[7] & 0x0F; const uint8_t set_ptt_scn_sav = Data[7] & 0x0F;
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
const bool set_ptt_scn_sav_valid = set_ptt_scn_sav < (SET_SAV_LEN << 2);
#else
const bool set_ptt_scn_sav_valid = set_ptt_scn_sav < 4;
#endif
gSetting_set_pwr = (((Data[7] & 0xF0) >> 4) < 7) ? ((Data[7] & 0xF0) >> 4) : 0; gSetting_set_pwr = (((Data[7] & 0xF0) >> 4) < 7) ? ((Data[7] & 0xF0) >> 4) : 0;
gSetting_set_ptt = (set_ptt_scn < 4) ? (set_ptt_scn & 0x01) : 0; gSetting_set_ptt = set_ptt_scn_sav_valid ? (set_ptt_scn_sav & 0x01) : 0;
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER #ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
gSetting_set_scn = (set_ptt_scn < 4) ? ((set_ptt_scn & 0x02) == 0) : 1; gSetting_set_scn = set_ptt_scn_sav_valid ? ((set_ptt_scn_sav & 0x02) == 0) : 1;
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
gSetting_set_sav = set_ptt_scn_sav_valid ? ((set_ptt_scn_sav >> 2) & 0x03) : SET_SAV_OFF;
#endif #endif
gSetting_set_tot = (((Data[6] & 0xF0) >> 4) < 4) ? ((Data[6] & 0xF0) >> 4) : 0; gSetting_set_tot = (((Data[6] & 0xF0) >> 4) < 4) ? ((Data[6] & 0xF0) >> 4) : 0;
@@ -1131,13 +1139,16 @@ void SETTINGS_SaveSettings(void)
State[5] = ((tmp << 4) | (gSetting_set_ctr & 0x0F)); State[5] = ((tmp << 4) | (gSetting_set_ctr & 0x0F));
State[6] = ((gSetting_set_tot << 4) | (gSetting_set_eot & 0x0F)); State[6] = ((gSetting_set_tot << 4) | (gSetting_set_eot & 0x0F));
uint8_t set_ptt_scn = gSetting_set_ptt & 0x01; uint8_t set_ptt_scn_sav = gSetting_set_ptt & 0x01;
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER #ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
if (!gSetting_set_scn) if (!gSetting_set_scn)
set_ptt_scn |= 0x02; set_ptt_scn_sav |= 0x02;
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
set_ptt_scn_sav |= (gSetting_set_sav & 0x03) << 2;
#endif #endif
State[7] = ((gSetting_set_pwr << 4) | set_ptt_scn); State[7] = ((gSetting_set_pwr << 4) | set_ptt_scn_sav);
gEeprom.KEY_LOCK_PTT = gSetting_set_lck; gEeprom.KEY_LOCK_PTT = gSetting_set_lck;
+45 -52
View File
@@ -37,9 +37,8 @@ static int get_bit(uint8_t* array, int bit_index) {
void UI_DisplayAircopy(void) void UI_DisplayAircopy(void)
{ {
char String[16] = { 0 }; char String[16];
char *pPrintStr = { 0 }; char *pPrintStr;
uint16_t percent;
UI_DisplayClear(); UI_DisplayClear();
@@ -60,15 +59,13 @@ void UI_DisplayAircopy(void)
// show the remaining 2 small frequency digits // show the remaining 2 small frequency digits
UI_PrintStringSmallNormal(String + 7, 97, 0, 3); UI_PrintStringSmallNormal(String + 7, 97, 0, 3);
String[7] = 0; String[7] = 0;
// show the main large frequency digits
UI_DisplayFrequency(String, 16, 2, false);
} else { } else {
const char *ascii = INPUTBOX_GetAscii(); const char *ascii = INPUTBOX_GetAscii();
sprintf(String, "%.3s.%.3s", ascii, ascii + 3); sprintf(String, "%.3s.%.3s", ascii, ascii + 3);
UI_DisplayFrequency(String, 16, 2, false);
} }
memset(String, 0, sizeof(String)); // show the main large frequency digits
UI_DisplayFrequency(String, 16, 2, false);
// Get the current map and calculate percentage based on its total blocks // Get the current map and calculate percentage based on its total blocks
const AIRCOPY_TransferMap_t *currentMap = AIRCOPY_GetCurrentMap(); const AIRCOPY_TransferMap_t *currentMap = AIRCOPY_GetCurrentMap();
@@ -78,47 +75,44 @@ void UI_DisplayAircopy(void)
if (doneBlocks > currentMap->total_blocks) if (doneBlocks > currentMap->total_blocks)
doneBlocks = currentMap->total_blocks; doneBlocks = currentMap->total_blocks;
percent = (doneBlocks * 10000) / currentMap->total_blocks;
if (gAirCopyIsSendMode == 0) {
sprintf(String, "RCV:%02u.%02u%% E:%d", percent / 100, percent % 100, gErrorsDuringAirCopy);
} else if (gAirCopyIsSendMode == 1) {
sprintf(String, "SND:%02u.%02u%%", percent / 100, percent % 100);
}
// Draw gauge
if(gAircopyStep != 0)
{
UI_PrintString(String, 2, 127, 5, 8);
gFrameBuffer[4][1] = 0x3c;
gFrameBuffer[4][2] = 0x42;
for(uint8_t i = 1; i <= AIRCOPY_BAR_WIDTH + 2; i++)
{
gFrameBuffer[4][2 + i] = 0x81;
}
gFrameBuffer[4][125] = 0x42;
gFrameBuffer[4][126] = 0x3c;
}
// Draw memory selection // Draw memory selection
if(gAircopyState == AIRCOPY_READY) if (gAircopyState == AIRCOPY_READY)
{ {
doneBlocks = 0; doneBlocks = 0;
memset(gFrameBuffer[5], 0, 128);
memset(gFrameBuffer[6], 0, 128);
if(gAircopyCurrentMapIndex < AIRCOPY_NUM_BANKS) { if(gAircopyCurrentMapIndex < AIRCOPY_NUM_BANKS) {
sprintf(String, "MEM %03u - %03u%", (gAircopyCurrentMapIndex * 128) + 1, (gAircopyCurrentMapIndex + 1) * 128); sprintf(String, "MEM %03u - %03u", (gAircopyCurrentMapIndex * 128) + 1, (gAircopyCurrentMapIndex + 1) * 128);
} } else {
else strcpy(String, "Settings");
{
sprintf(String, "Settings");
} }
UI_PrintString(String, 2, 127, 5, 8); UI_PrintString(String, 2, 127, 5, 8);
}
else
{
uint16_t percent = (doneBlocks * 10000) / currentMap->total_blocks;
if (gAirCopyIsSendMode == 0) {
sprintf(String, "RCV:%02u.%02u%% E:%d", percent / 100, percent % 100, gErrorsDuringAirCopy);
} else {
sprintf(String, "SND:%02u.%02u%%", percent / 100, percent % 100);
}
// Draw gauge
if(gAircopyStep != 0)
{
UI_PrintString(String, 2, 127, 5, 8);
gFrameBuffer[4][1] = 0x3c;
gFrameBuffer[4][2] = 0x42;
for(uint8_t i = 1; i <= AIRCOPY_BAR_WIDTH + 2; i++)
{
gFrameBuffer[4][2 + i] = 0x81;
}
gFrameBuffer[4][125] = 0x42;
gFrameBuffer[4][126] = 0x3c;
}
} }
if (doneBlocks > 0) if (doneBlocks > 0)
@@ -131,19 +125,12 @@ void UI_DisplayAircopy(void)
lErrorsDuringAirCopy = gErrorsDuringAirCopy; lErrorsDuringAirCopy = gErrorsDuringAirCopy;
} }
const AIRCOPY_TransferMap_t *currentMap = AIRCOPY_GetCurrentMap(); uint16_t b = 0;
uint16_t fraction_accumulator = 0;
uint16_t total = currentMap->total_blocks;
uint16_t done = gAirCopyBlockNumber + gErrorsDuringAirCopy;
if (done > total) done = total;
for (uint8_t col = 0; col < AIRCOPY_BAR_WIDTH; col++) for (uint8_t col = 0; col < AIRCOPY_BAR_WIDTH; col++)
{ {
/* Map column [0..BAR_WIDTH-1] to block [0..total-1] */ bool processed = (b < doneBlocks);
uint16_t b = (uint16_t)((col * (uint32_t)total) / AIRCOPY_BAR_WIDTH);
bool processed = (b < done);
bool error = processed && get_bit(crc, b); bool error = processed && get_bit(crc, b);
if (!processed) if (!processed)
@@ -152,8 +139,14 @@ void UI_DisplayAircopy(void)
gFrameBuffer[4][col + 4] = 0x81; // error gap (intentional hole) gFrameBuffer[4][col + 4] = 0x81; // error gap (intentional hole)
else else
gFrameBuffer[4][col + 4] = 0xBD; // ok filled gFrameBuffer[4][col + 4] = 0xBD; // ok filled
}
// DDA/Bresenham algorythm
fraction_accumulator += currentMap->total_blocks;
while (fraction_accumulator >= AIRCOPY_BAR_WIDTH) {
fraction_accumulator -= AIRCOPY_BAR_WIDTH;
b++;
}
}
} }
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
+1 -2
View File
@@ -31,7 +31,7 @@
void UI_DisplayFM(void) void UI_DisplayFM(void)
{ {
char String[16] = {0}; char String[16];
char *pPrintStr = String; char *pPrintStr = String;
UI_DisplayClear(); UI_DisplayClear();
@@ -80,7 +80,6 @@ void UI_DisplayFM(void)
UI_PrintString(pPrintStr, 0, 127, 3, 10); // memory, vfo, scan UI_PrintString(pPrintStr, 0, 127, 3, 10); // memory, vfo, scan
memset(String, 0, sizeof(String));
if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex > 0)) { if (gAskToSave || (gEeprom.FM_IsMrMode && gInputBoxIndex > 0)) {
UI_GenerateChannelString(String, gFM_ChannelPosition); UI_GenerateChannelString(String, gFM_ChannelPosition);
} else if (gAskToDelete) { } else if (gAskToDelete) {
+2
View File
@@ -40,6 +40,8 @@ void UI_GenerateChannelString(char *pString, const uint16_t Channel)
pString[2] = '-'; pString[2] = '-';
for (i = 0; i < 2; i++) for (i = 0; i < 2; i++)
pString[i + 3] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0'; pString[i + 3] = (gInputBox[i] == 10) ? '-' : gInputBox[i] + '0';
pString[5] = 0;
} }
void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint16_t ChannelNumber) void UI_GenerateChannelStringEx(char *pString, const bool bShowPrefix, const uint16_t ChannelNumber)
+56 -10
View File
@@ -17,6 +17,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> // abs() #include <stdlib.h> // abs()
#include "app/app.h"
#include "app/chFrScanner.h" #include "app/chFrScanner.h"
#include "app/dtmf.h" #include "app/dtmf.h"
@@ -321,16 +322,9 @@ static void ScanProgress_DrawGaugeLine(uint8_t line, uint32_t current_index, uin
} }
} }
static uint8_t ScanProgress_DecimalDigits(uint32_t value) static inline uint8_t ScanProgress_DecimalDigits(uint32_t value)
{ {
uint8_t digits = 1; return sprintf(NULL, "%u", value);
while (value >= 10u) {
value /= 10u;
digits++;
}
return digits;
} }
static void ScanProgress_FormatIndex(char *out, size_t out_size, uint32_t current_index, uint32_t total, uint8_t width) static void ScanProgress_FormatIndex(char *out, size_t out_size, uint32_t current_index, uint32_t total, uint8_t width)
@@ -853,6 +847,8 @@ void UI_DisplayAudioScope(void)
void DisplayRSSIBar(const bool now) void DisplayRSSIBar(const bool now)
{ {
#if defined(ENABLE_RSSI_BAR) #if defined(ENABLE_RSSI_BAR)
if (APP_IsScreenSaverDisplayed())
return;
const unsigned int txt_width = 7 * 8; // 8 text chars const unsigned int txt_width = 7 * 8; // 8 text chars
const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph const unsigned int bar_x = 2 + txt_width + 4; // X coord of bar graph
@@ -899,13 +895,17 @@ void DisplayRSSIBar(const bool now)
p_line0[i] = (p_line0[i] & 0x80) | BITMAP_VFO_Empty[i]; p_line0[i] = (p_line0[i] & 0x80) | BITMAP_VFO_Empty[i];
} }
ST7565_BlitLine(RxLine); ST7565_DrawLine(0, RxLine + 1, p_line0, sizeof(BITMAP_VFO_Default));
} }
#else #else
const unsigned int line = 3; const unsigned int line = 3;
#endif #endif
uint8_t *p_line = gFrameBuffer[line]; uint8_t *p_line = gFrameBuffer[line];
char str[16]; char str[16];
#ifdef ENABLE_FEAT_F4HWN
uint8_t oldLine[LCD_WIDTH];
#endif
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
const char plus[] = { const char plus[] = {
@@ -930,8 +930,15 @@ void DisplayRSSIBar(const bool now)
) )
return; // display is in use return; // display is in use
#ifdef ENABLE_FEAT_F4HWN
if (now) {
memcpy(oldLine, p_line, LCD_WIDTH);
memset(p_line, 0, LCD_WIDTH);
}
#else
if (now) if (now)
memset(p_line, 0, LCD_WIDTH); memset(p_line, 0, LCD_WIDTH);
#endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
int16_t rssi_dBm = int16_t rssi_dBm =
@@ -1021,8 +1028,13 @@ void DisplayRSSIBar(const bool now)
UI_PrintStringSmallNormal(str, 2, 0, line); UI_PrintStringSmallNormal(str, 2, 0, line);
#endif #endif
DrawLevelBar(bar_x, line, s_level + overS9Bars, 13); DrawLevelBar(bar_x, line, s_level + overS9Bars, 13);
#ifdef ENABLE_FEAT_F4HWN
if (now && memcmp(oldLine, p_line, LCD_WIDTH) != 0)
ST7565_BlitLine(line);
#else
if (now) if (now)
ST7565_BlitLine(line); ST7565_BlitLine(line);
#endif
#else #else
int16_t rssi = BK4819_GetRSSI(); int16_t rssi = BK4819_GetRSSI();
uint8_t Level; uint8_t Level;
@@ -1255,6 +1267,16 @@ void UI_DisplayMain(void)
UI_FormatFrequency(gScanRangeStop, String); UI_FormatFrequency(gScanRangeStop, String);
UI_PrintStringSmallNormal(String, 56, 0, line + shift + 1); UI_PrintStringSmallNormal(String, 56, 0, line + shift + 1);
if (!isMainOnly() && gScanRangeCssCode != 0xFF)
{
if (gScanRangeCssType == CODE_TYPE_CONTINUOUS_TONE)
sprintf(String, "CTCSS %u.%uHz", CTCSS_Options[gScanRangeCssCode] / 10, CTCSS_Options[gScanRangeCssCode] % 10);
else
sprintf(String, "DCS D%03o%c", DCS_Options[gScanRangeCssCode],
gScanRangeCssType == CODE_TYPE_REVERSE_DIGITAL ? 'I' : 'N');
UI_PrintStringSmallNormal(String, 6, 0, line + 2);
}
if (!isMainOnly()) if (!isMainOnly())
continue; continue;
} }
@@ -1268,6 +1290,17 @@ void UI_DisplayMain(void)
UI_PrintStringSmallNormal(String, 56, 0, line); UI_PrintStringSmallNormal(String, 56, 0, line);
UI_FormatFrequency(gScanRangeStop, String); UI_FormatFrequency(gScanRangeStop, String);
UI_PrintStringSmallNormal(String, 56, 0, line + 1); UI_PrintStringSmallNormal(String, 56, 0, line + 1);
if (gScanRangeCssCode != 0xFF)
{
if (gScanRangeCssType == CODE_TYPE_CONTINUOUS_TONE)
sprintf(String, "CTCSS:%u.%uHz", CTCSS_Options[gScanRangeCssCode] / 10, CTCSS_Options[gScanRangeCssCode] % 10);
else
sprintf(String, "DCS:D%03o%c", DCS_Options[gScanRangeCssCode],
gScanRangeCssType == CODE_TYPE_REVERSE_DIGITAL ? 'I' : 'N');
UI_PrintStringSmallNormal(String, 2, 0, line + 2);
}
continue; continue;
#endif #endif
} }
@@ -2087,6 +2120,18 @@ void UI_DisplayMain(void)
UI_MAIN_PrintAGC(false); UI_MAIN_PrintAGC(false);
#endif #endif
#if defined(ENABLE_SCAN_RANGES) && defined(ENABLE_FEAT_F4HWN)
if (isMainOnly() && gScanRangeStart && gScanRangeCssCode != 0xFF)
{
if (gScanRangeCssType == CODE_TYPE_CONTINUOUS_TONE)
sprintf(String, "CTCSS %u.%uHz", CTCSS_Options[gScanRangeCssCode] / 10, CTCSS_Options[gScanRangeCssCode] % 10);
else
sprintf(String, "DCS D%03o%c", DCS_Options[gScanRangeCssCode],
gScanRangeCssType == CODE_TYPE_REVERSE_DIGITAL ? 'I' : 'N');
UI_PrintStringSmallNormal(String, 2, 0, 6);
}
#endif
if (center_line == CENTER_LINE_NONE) if (center_line == CENTER_LINE_NONE)
{ // we're free to use the middle line { // we're free to use the middle line
@@ -2140,6 +2185,7 @@ void UI_DisplayMain(void)
else else
#endif #endif
#ifdef ENABLE_RSSI_BAR #ifdef ENABLE_RSSI_BAR
if (rx) { if (rx) {
center_line = CENTER_LINE_RSSI; center_line = CENTER_LINE_RSSI;
+113 -96
View File
@@ -171,6 +171,9 @@ const t_menu_item MenuList[] =
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER #ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
{"SetScn", MENU_SET_SCN }, {"SetScn", MENU_SET_SCN },
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
{"SetSav", MENU_SET_SAV },
#endif
#endif #endif
// hidden menu items from here on // hidden menu items from here on
// enabled if pressing both the PTT and upper side button at power-on // enabled if pressing both the PTT and upper side button at power-on
@@ -197,7 +200,7 @@ const t_menu_item MenuList[] =
const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK; const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK;
const char gSubMenu_TXP[][6] = const char* const gSubMenu_TXP[] =
{ {
"USER", "USER",
"LOW 1", "LOW 1",
@@ -209,29 +212,26 @@ const char gSubMenu_TXP[][6] =
"HIGH" "HIGH"
}; };
const char gSubMenu_SFT_D[][4] = const char* const gSubMenu_SFT_D[] =
{ {
"OFF", "OFF",
"+", "+",
"-" "-"
}; };
const char gSubMenu_W_N[][7] = const char* const gSubMenu_W_N[] =
{ {
"WIDE", "WIDE",
"NARROW" "NARROW"
}; };
const char gSubMenu_OFF_ON[][4] = const char* const gSubMenu_OFF_ON[] =
{ {
"OFF", "OFF",
"ON" "ON"
}; };
const char gSubMenu_NA[4] = const char* gSubMenu_NA = "N/A";
{
"N/A"
};
const char* const gSubMenu_RXMode[] = const char* const gSubMenu_RXMode[] =
{ {
@@ -242,7 +242,7 @@ const char* const gSubMenu_RXMode[] =
}; };
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
const char gSubMenu_VOICE[][4] = const char* const gSubMenu_VOICE[] =
{ {
"OFF", "OFF",
"CHI", "CHI",
@@ -259,7 +259,7 @@ const char* const gSubMenu_MDF[] =
}; };
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
const char gSubMenu_AL_MOD[][5] = const char* const gSubMenu_AL_MOD[] =
{ {
"SITE", "SITE",
"TONE" "TONE"
@@ -267,7 +267,7 @@ const char* const gSubMenu_MDF[] =
#endif #endif
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
const char gSubMenu_D_RSP[][11] = const char* const gSubMenu_D_RSP[] =
{ {
"DO\nNOTHING", "DO\nNOTHING",
"RING", "RING",
@@ -285,7 +285,7 @@ const char* const gSubMenu_PTT_ID[] =
"APOLLO\nQUINDAR" "APOLLO\nQUINDAR"
}; };
const char gSubMenu_PONMSG[][8] = const char* const gSubMenu_PONMSG[] =
{ {
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
"ALL", "ALL",
@@ -301,20 +301,30 @@ const char gSubMenu_PONMSG[][8] =
"NONE" "NONE"
}; };
const char gSubMenu_ROGER[][6] = #if defined(ENABLE_FEAT_F4HWN) && defined(ENABLE_FEAT_F4HWN_LOGO_SAV)
const char* const gSubMenu_SET_SAV[] =
{
"OFF",
"LOGO",
"LOGO+",
"MATRIX"
};
#endif
const char* const gSubMenu_ROGER[] =
{ {
"OFF", "OFF",
"ROGER", "ROGER",
"MDC" "MDC"
}; };
const char gSubMenu_RESET[][4] = const char* const gSubMenu_RESET[] =
{ {
"VFO", "VFO",
"ALL" "ALL"
}; };
const char * const gSubMenu_F_LOCK[] = const char* const gSubMenu_F_LOCK[] =
{ {
"DEFAULT+\n137-174\n400-470", "DEFAULT+\n137-174\n400-470",
"FCC HAM\n144-148\n420-450", "FCC HAM\n144-148\n420-450",
@@ -335,7 +345,7 @@ const char * const gSubMenu_F_LOCK[] =
"UNLOCK\nALL", "UNLOCK\nALL",
}; };
const char gSubMenu_RX_TX[][6] = const char* const gSubMenu_RX_TX[] =
{ {
"OFF", "OFF",
"TX", "TX",
@@ -343,14 +353,14 @@ const char gSubMenu_RX_TX[][6] =
"TX/RX" "TX/RX"
}; };
const char gSubMenu_BAT_TXT[][8] = const char* const gSubMenu_BAT_TXT[] =
{ {
"NONE", "NONE",
"VOLTAGE", "VOLTAGE",
"PERCENT" "PERCENT"
}; };
const char gSubMenu_BATTYP[][12] = const char* const gSubMenu_BATTYP[] =
{ {
"1600mAh K5", "1600mAh K5",
"2200mAh K5", "2200mAh K5",
@@ -359,14 +369,14 @@ const char gSubMenu_BATTYP[][12] =
"2500mAh K1" "2500mAh K1"
}; };
const char gSubMenu_SET_NAV[][17] = const char* const gSubMenu_SET_NAV[] =
{ {
"LEFT\nRIGHT\nUV-K1", "LEFT\nRIGHT\nUV-K1",
"UP\nDOWN\nUV-K5(8)", "UP\nDOWN\nUV-K5(8)",
}; };
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
const char gSubMenu_SCRAMBLER[][7] = const char* const gSubMenu_SCRAMBLER[] =
{ {
"OFF", "OFF",
"2600Hz", "2600Hz",
@@ -383,7 +393,7 @@ const char gSubMenu_SCRAMBLER[][7] =
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
const char gSubMenu_SET_PWR[][6] = const char* const gSubMenu_SET_PWR[] =
{ {
"< 20m", "< 20m",
"125m", "125m",
@@ -394,13 +404,13 @@ const char gSubMenu_SCRAMBLER[][7] =
"5" "5"
}; };
const char gSubMenu_SET_PTT[][8] = const char* const gSubMenu_SET_PTT[] =
{ {
"CLASSIC", "CLASSIC",
"ONEPUSH" "ONEPUSH"
}; };
const char gSubMenu_SET_TOT[][7] = // Use by SET_EOT too const char* const gSubMenu_SET_TOT[] =
{ {
"OFF", "OFF",
"SOUND", "SOUND",
@@ -408,20 +418,20 @@ const char gSubMenu_SCRAMBLER[][7] =
"ALL" "ALL"
}; };
const char gSubMenu_SET_LCK[][9] = const char* const gSubMenu_SET_LCK[] =
{ {
"KEYS", "KEYS",
"KEYS+PTT" "KEYS+PTT"
}; };
const char gSubMenu_SET_MET[][8] = const char* const gSubMenu_SET_MET[] =
{ {
"TINY", "TINY",
"CLASSIC" "CLASSIC"
}; };
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER #ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
const char gSubMenu_SET_SCN[][7] = const char* const gSubMenu_SET_SCN[] =
{ {
"NORMAL", "NORMAL",
"FAST" "FAST"
@@ -429,7 +439,7 @@ const char gSubMenu_SCRAMBLER[][7] =
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_AUDIO #ifdef ENABLE_FEAT_F4HWN_AUDIO
const char gSubMenu_SET_AUD_FM[][6] = const char* const gSubMenu_SET_AUD_FM[] =
{ {
"FLAT", "FLAT",
"CLEAN", "CLEAN",
@@ -438,7 +448,7 @@ const char gSubMenu_SCRAMBLER[][7] =
"MAX" "MAX"
}; };
const char gSubMenu_SET_AUD_AM[][6] = const char* const gSubMenu_SET_AUD_AM[] =
{ {
"SHARP", "SHARP",
"STOCK", "STOCK",
@@ -447,7 +457,7 @@ const char gSubMenu_SCRAMBLER[][7] =
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER #ifdef ENABLE_FEAT_F4HWN_NARROWER
const char gSubMenu_SET_NFM[][9] = const char* const gSubMenu_SET_NFM[] =
{ {
"NARROW", "NARROW",
"NARROWER" "NARROWER"
@@ -455,7 +465,7 @@ const char gSubMenu_SCRAMBLER[][7] =
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
const char gSubMenu_SET_KEY[][9] = const char* const gSubMenu_SET_KEY[] =
{ {
"KEY_MENU", "KEY_MENU",
"KEY_UP", "KEY_UP",
@@ -496,7 +506,7 @@ const t_sidefunction gSubMenu_SIDEFUNCTIONS[] =
{"VFO\nMEM", ACTION_OPT_VFO_MR}, {"VFO\nMEM", ACTION_OPT_VFO_MR},
{"MODE", ACTION_OPT_SWITCH_DEMODUL}, {"MODE", ACTION_OPT_SWITCH_DEMODUL},
#ifdef ENABLE_BLMIN_TMP_OFF #ifdef ENABLE_BLMIN_TMP_OFF
{"BLMIN\nTMP OFF", ACTION_OPT_BLMIN_TMP_OFF}, //BackLight Minimum Temporay OFF {"BLMIN\nTMP OFF", ACTION_OPT_BLMIN_TMP_OFF}, //BackLight Minimum Temporary OFF
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
{"RX MODE", ACTION_OPT_RXMODE}, {"RX MODE", ACTION_OPT_RXMODE},
@@ -658,58 +668,56 @@ void UI_DisplayMenu(void)
#else #else
{ // new menu layout .. experimental & unfinished { // new menu layout .. experimental & unfinished
const int menu_index = gMenuCursor; // current selected menu item const int menu_index = gMenuCursor; // current selected menu item
i = 1; const int menu_count = (int)gMenuListCount;
if (!gIsInSubMenu) { if (menu_index >= 0 && menu_index < menu_count)
while (i < 2) {
{ // leading menu items - small text if (!gIsInSubMenu)
const int k = menu_index + i - 2; {
if (k < 0) // leading menu items - small text
UI_PrintStringSmallNormal(MenuList[gMenuListCount + k].name, 0, 0, i); // wrap-a-round int prev_index = menu_index - 1;
else if (k >= 0 && k < (int)gMenuListCount) if (prev_index < 0) {
UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, i); prev_index = menu_count - 1;
i++; }
} UI_PrintStringSmallNormal(MenuList[prev_index].name, 0, 0, 1);
// current menu item - keep big n fat // current menu item - keep big n fat
if (menu_index >= 0 && menu_index < (int)gMenuListCount)
UI_PrintString(MenuList[menu_index].name, 0, 0, 2, 8); UI_PrintString(MenuList[menu_index].name, 0, 0, 2, 8);
i++;
while (i < 4) // trailing menu item - small text
{ // trailing menu item - small text int next_index = menu_index + 1;
const int k = menu_index + i - 2; if (next_index >= menu_count) {
if (k >= 0 && k < (int)gMenuListCount) next_index = 0;
UI_PrintStringSmallNormal(MenuList[k].name, 0, 0, 1 + i); }
else if (k >= (int)gMenuListCount) UI_PrintStringSmallNormal(MenuList[next_index].name, 0, 0, 4);
UI_PrintStringSmallNormal(MenuList[gMenuListCount - k].name, 0, 0, 1 + i); // wrap-a-round
i++;
// draw the menu index number/count
#ifndef ENABLE_FEAT_F4HWN
sprintf(String, "%2u.%u", 1 + menu_index, menu_count);
UI_PrintStringSmallNormal(String, 2, 0, 6);
#endif
}
else
{
// current menu item
// strcat(String, ":");
UI_PrintString(MenuList[menu_index].name, 0, 0, 0, 8);
// UI_PrintStringSmallNormal(String, 0, 0, 0);
} }
// draw the menu index number/count #ifdef ENABLE_FEAT_F4HWN
#ifndef ENABLE_FEAT_F4HWN sprintf(String, "%02u/%u", 1 + menu_index, menu_count);
sprintf(String, "%2u.%u", 1 + gMenuCursor, gMenuListCount); UI_PrintStringSmallNormal(String, 6, 0, 6);
UI_PrintStringSmallNormal(String, 2, 0, 6); #endif
#endif
} }
else if (menu_index >= 0 && menu_index < (int)gMenuListCount)
{ // current menu item
// strcat(String, ":");
UI_PrintString(MenuList[menu_index].name, 0, 0, 0, 8);
// UI_PrintStringSmallNormal(String, 0, 0, 0);
}
#ifdef ENABLE_FEAT_F4HWN
sprintf(String, "%02u/%u", 1 + gMenuCursor, gMenuListCount);
UI_PrintStringSmallNormal(String, 6, 0, 6);
#endif
} }
#endif #endif
// ************** // **************
memset(String, 0, sizeof(String)); String[0] = '\0';
memset(top_right_badge, 0, sizeof(top_right_badge)); top_right_badge[0] = '\0';
bool already_printed = false; bool already_printed = false;
@@ -923,6 +931,12 @@ void UI_DisplayMenu(void)
strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]); strcpy(String, gSubMenu_OFF_ON[gSubMenuSelection]);
break; break;
#if defined(ENABLE_FEAT_F4HWN) && defined(ENABLE_FEAT_F4HWN_LOGO_SAV)
case MENU_SET_SAV:
strcpy(String, gSubMenu_SET_SAV[gSubMenuSelection]);
break;
#endif
case MENU_MEM_CH: case MENU_MEM_CH:
case MENU_1_CALL: case MENU_1_CALL:
case MENU_DEL_CH: case MENU_DEL_CH:
@@ -1103,11 +1117,19 @@ void UI_DisplayMenu(void)
break; break;
#endif #endif
case MENU_UPCODE: case MENU_UPCODE:
sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_UP_CODE, gEeprom.DTMF_UP_CODE + 8); if (gEeprom.DTMF_UP_CODE[8] != '\0' && gEeprom.DTMF_UP_CODE[8] != 0xFF) {
sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_UP_CODE, gEeprom.DTMF_UP_CODE + 8);
} else {
sprintf(String, "%.8s", gEeprom.DTMF_UP_CODE);
}
break; break;
case MENU_DWCODE: case MENU_DWCODE:
sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_DOWN_CODE, gEeprom.DTMF_DOWN_CODE + 8); if (gEeprom.DTMF_DOWN_CODE[8] != '\0' && gEeprom.DTMF_DOWN_CODE[8] != 0xFF) {
sprintf(String, "%.8s\n%.8s", gEeprom.DTMF_DOWN_CODE, gEeprom.DTMF_DOWN_CODE + 8);
} else {
sprintf(String, "%.8s", gEeprom.DTMF_DOWN_CODE);
}
break; break;
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
@@ -1441,7 +1463,7 @@ void UI_DisplayMenu(void)
unsigned int len = strlen(String); unsigned int len = strlen(String);
bool small = false; bool small = false;
if (len > 0) if (String[0] != '\0')
{ {
// count number of lines // count number of lines
for (i = 0; i < len; i++) for (i = 0; i < len; i++)
@@ -1508,30 +1530,25 @@ void UI_DisplayMenu(void)
} }
#endif #endif
if (m == MENU_R_CTCS || const bool is_ctcs = (m == MENU_R_CTCS || m == MENU_T_CTCS);
m == MENU_T_CTCS) { const bool is_dcs = (m == MENU_R_DCS || m == MENU_T_DCS);
const uint8_t approved_index =
(gSubMenuSelection > 0) ? DCS_GetCtcssApprovedIndex(gSubMenuSelection - 1) : 0xFF;
if (gSubMenuSelection == 0) if (is_ctcs || is_dcs) {
sprintf(top_right_badge, "00/00"); if (gSubMenuSelection == 0) {
else if (approved_index != 0xFF) strcpy(top_right_badge, is_ctcs ? "00/00" : "000/00");
sprintf(top_right_badge, "%02u/%02u", (unsigned)gSubMenuSelection, (unsigned)approved_index + 1); } else {
else const uint8_t approved_index = is_ctcs ?
sprintf(top_right_badge, "%02u/--", (unsigned)gSubMenuSelection); DCS_GetCtcssApprovedIndex(gSubMenuSelection - 1) :
} DCS_GetDcsApprovedIndex(gSubMenuSelection - 1);
if (m == MENU_R_DCS || const uint8_t width = is_ctcs ? 2 : 3;
m == MENU_T_DCS) {
const uint8_t approved_index =
(gSubMenuSelection > 0) ? DCS_GetDcsApprovedIndex(gSubMenuSelection - 1) : 0xFF;
if (gSubMenuSelection == 0) if (approved_index != 0xFF) {
sprintf(top_right_badge, "000/00"); sprintf(top_right_badge, "%0*u/%02u", width, (unsigned)gSubMenuSelection, (unsigned)approved_index + 1);
else if (approved_index != 0xFF) } else {
sprintf(top_right_badge, "%03u/%02u", (unsigned)gSubMenuSelection, (unsigned)approved_index + 1); sprintf(top_right_badge, "%0*u/--", width, (unsigned)gSubMenuSelection);
else }
sprintf(top_right_badge, "%03u/--", (unsigned)gSubMenuSelection); }
} }
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
+47 -35
View File
@@ -23,7 +23,7 @@
#include "audio.h" // VOICE_ID_t #include "audio.h" // VOICE_ID_t
#include "settings.h" #include "settings.h"
typedef struct { typedef struct __attribute__((packed)) {
const char name[7]; // menu display area only has room for 6 characters const char name[7]; // menu display area only has room for 6 characters
uint8_t menu_id; uint8_t menu_id;
} t_menu_item; } t_menu_item;
@@ -163,76 +163,88 @@ enum
MENU_F2SHRT, MENU_F2SHRT,
MENU_F2LONG, MENU_F2LONG,
MENU_MLONG, MENU_MLONG,
MENU_BATTYP MENU_BATTYP,
#if defined(ENABLE_FEAT_F4HWN) && defined(ENABLE_FEAT_F4HWN_LOGO_SAV)
MENU_SET_SAV
#endif
}; };
extern const uint8_t FIRST_HIDDEN_MENU_ITEM; extern const uint8_t FIRST_HIDDEN_MENU_ITEM;
extern const t_menu_item MenuList[]; extern const t_menu_item MenuList[];
extern const char gSubMenu_TXP[8][6]; extern const char* const gSubMenu_TXP[8];
extern const char gSubMenu_SFT_D[3][4]; extern const char* const gSubMenu_SFT_D[3];
extern const char gSubMenu_W_N[2][7]; extern const char* const gSubMenu_W_N[2];
extern const char gSubMenu_OFF_ON[2][4]; extern const char* const gSubMenu_OFF_ON[2];
extern const char gSubMenu_NA[4]; extern const char* gSubMenu_NA;
extern const char gSubMenu_TOT[11][7]; extern const char* const gSubMenu_TOT[11];
extern const char* const gSubMenu_RXMode[4]; extern const char* const gSubMenu_RXMode[4];
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
extern const char gSubMenu_VOICE[3][4]; extern const char* const gSubMenu_VOICE[3];
#endif #endif
extern const char* const gSubMenu_MDF[4]; extern const char* const gSubMenu_MDF[4];
#ifdef ENABLE_ALARM #ifdef ENABLE_ALARM
extern const char gSubMenu_AL_MOD[2][5]; extern const char* const gSubMenu_AL_MOD[2];
#endif #endif
#ifdef ENABLE_DTMF_CALLING #ifdef ENABLE_DTMF_CALLING
extern const char gSubMenu_D_RSP[4][11]; extern const char* const gSubMenu_D_RSP[4];
#endif #endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
extern const char gSubMenu_SET_PWR[7][6]; extern const char* const gSubMenu_SET_PWR[7];
extern const char gSubMenu_SET_PTT[2][8]; extern const char* const gSubMenu_SET_PTT[2];
extern const char gSubMenu_SET_TOT[4][7]; extern const char* const gSubMenu_SET_TOT[4];
extern const char gSubMenu_SET_LCK[2][9]; extern const char* const gSubMenu_SET_LCK[2];
extern const char gSubMenu_SET_MET[2][8]; extern const char* const gSubMenu_SET_MET[2];
#ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER #ifdef ENABLE_FEAT_F4HWN_SCAN_FASTER
extern const char gSubMenu_SET_SCN[2][7]; extern const char* const gSubMenu_SET_SCN[2];
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_NARROWER #ifdef ENABLE_FEAT_F4HWN_NARROWER
extern const char gSubMenu_SET_NFM[2][9]; extern const char* const gSubMenu_SET_NFM[2];
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS #ifdef ENABLE_FEAT_F4HWN_RESCUE_OPS
extern const char gSubMenu_SET_KEY[][9]; extern const char* const gSubMenu_SET_KEY[5];
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_AUDIO #ifdef ENABLE_FEAT_F4HWN_AUDIO
extern const char gSubMenu_SET_AUD_FM[5][6]; extern const char* const gSubMenu_SET_AUD_FM[5];
extern const char gSubMenu_SET_AUD_AM[3][6]; extern const char* const gSubMenu_SET_AUD_AM[3];
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO_SAV
extern const char* const gSubMenu_SET_SAV[];
#endif #endif
#endif #endif
extern const char* const gSubMenu_PTT_ID[5]; extern const char* const gSubMenu_PTT_ID[5];
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
#ifdef ENABLE_FEAT_F4HWN_LOGO #ifdef ENABLE_FEAT_F4HWN_LOGO
extern const char gSubMenu_PONMSG[6][8]; extern const char* const gSubMenu_PONMSG[6];
#else #else
extern const char gSubMenu_PONMSG[5][8]; extern const char* const gSubMenu_PONMSG[5];
#endif #endif
#else #else
extern const char gSubMenu_PONMSG[4][8]; extern const char* const gSubMenu_PONMSG[4];
#endif #endif
extern const char gSubMenu_ROGER[3][6];
extern const char gSubMenu_RESET[2][4]; extern const char* const gSubMenu_ROGER[3];
extern const char* const gSubMenu_F_LOCK[F_LOCK_LEN]; extern const char* const gSubMenu_RESET[2];
extern const char gSubMenu_RX_TX[4][6]; extern const char* const gSubMenu_F_LOCK[F_LOCK_LEN];
extern const char gSubMenu_BAT_TXT[3][8]; extern const char* const gSubMenu_RX_TX[4];
extern const char gSubMenu_BATTYP[5][12]; extern const char* const gSubMenu_BAT_TXT[3];
extern const char* const gSubMenu_BATTYP[5];
extern const char* const gSubMenu_SET_NAV[2];
#ifndef ENABLE_FEAT_F4HWN #ifndef ENABLE_FEAT_F4HWN
extern const char gSubMenu_SCRAMBLER[11][7]; extern const char* const gSubMenu_SCRAMBLER[11];
#endif #endif
typedef struct {char* name; uint8_t id;} t_sidefunction; typedef struct /* __attribute__((packed)) */ {
const char* name;
uint8_t id;
} t_sidefunction;
extern const uint8_t gSubMenu_SIDEFUNCTIONS_size; extern const uint8_t gSubMenu_SIDEFUNCTIONS_size;
extern const t_sidefunction gSubMenu_SIDEFUNCTIONS[]; extern const t_sidefunction gSubMenu_SIDEFUNCTIONS[];
extern bool gIsInSubMenu; extern bool gIsInSubMenu;
+34 -36
View File
@@ -26,58 +26,56 @@
void UI_DisplayScanner(void) void UI_DisplayScanner(void)
{ {
char String[16] = {0}; char String[16];
char *pPrintStr = String; char *pPrintStr = String;
bool bCentered;
uint8_t Start;
UI_DisplayClear(); UI_DisplayClear();
if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED)) { // 1st line
sprintf(String, "FREQ:%u.%05u", gScanFrequency / 100000, gScanFrequency % 100000); if (gScannerSaveState == SCAN_SAVE_CHANNEL) {
pPrintStr = "Save?";
} else if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
strcpy(String, "Save:");
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
pPrintStr = String; pPrintStr = String;
} else if ((gScanCssState < SCAN_CSS_STATE_FOUND) && ((gScanProgressIndicator & 1u) != 0)) {
pPrintStr = "";
} else if (gScanCssState == SCAN_CSS_STATE_OFF) {
pPrintStr = "Search Freq";
} else if (gScanCssState == SCAN_CSS_STATE_SCANNING) {
pPrintStr = "Search Tone";
} else if (gScanCssState == SCAN_CSS_STATE_FOUND) {
pPrintStr = "Scan Complete";
} else { } else {
pPrintStr = "FREQ:**.*****"; pPrintStr = "Scan Failed";
} }
UI_PrintString(pPrintStr, 2, 0, 1, 8); UI_PrintString(pPrintStr, 2, 0, 1, 8);
if (gScanCssState < SCAN_CSS_STATE_FOUND || !gScanUseCssResult) { // 2nd line
pPrintStr = "CTC:******"; if (gScanSingleFrequency || (gScanCssState != SCAN_CSS_STATE_OFF && gScanCssState != SCAN_CSS_STATE_FAILED)) {
sprintf(String, "Freq:%u.%05u", gScanFrequency / 100000, gScanFrequency % 100000);
pPrintStr = String;
} else {
pPrintStr = "Freq:---.-----";
}
UI_PrintString(pPrintStr, 2, 0, 3, 8);
// 3rd line
if (gScanCssState < SCAN_CSS_STATE_FOUND) {
pPrintStr = "Tone:---";
} else if (!gScanUseCssResult) {
pPrintStr = "Tone:None";
} else if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) { } else if (gScanCssResultType == CODE_TYPE_CONTINUOUS_TONE) {
sprintf(String, "CTC:%u.%uHz", CTCSS_Options[gScanCssResultCode] / 10, CTCSS_Options[gScanCssResultCode] % 10); sprintf(String, "CTCSS:%u.%uHz", CTCSS_Options[gScanCssResultCode] / 10, CTCSS_Options[gScanCssResultCode] % 10);
pPrintStr = String; pPrintStr = String;
} else { } else {
sprintf(String, "DCS:D%03oN", DCS_Options[gScanCssResultCode]); sprintf(String, "DCS:D%03oN", DCS_Options[gScanCssResultCode]);
pPrintStr = String; pPrintStr = String;
} }
UI_PrintString(pPrintStr, 2, 0, 3, 8); UI_PrintString(pPrintStr, 2, 0, 5, 8);
memset(String, 0, sizeof(String));
if (gScannerSaveState == SCAN_SAVE_CHANNEL) {
pPrintStr = "SAVE?";
Start = 0;
bCentered = 1;
} else {
Start = 2;
bCentered = 0;
if (gScannerSaveState == SCAN_SAVE_CHAN_SEL) {
strcpy(String, "SAVE:");
UI_GenerateChannelStringEx(String + 5, gShowChPrefix, gScanChannel);
pPrintStr = String;
} else if (gScanCssState < SCAN_CSS_STATE_FOUND) {
strcpy(String, "SCAN");
memset(String + 4, '.', (gScanProgressIndicator & 7) + 1);
pPrintStr = String;
} else if (gScanCssState == SCAN_CSS_STATE_FOUND) {
pPrintStr = "SCAN CMP.";
} else {
pPrintStr = "SCAN FAIL.";
}
}
UI_PrintString(pPrintStr, Start, bCentered ? 127 : 0, 5, 8);
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
} }
+19 -12
View File
@@ -16,6 +16,7 @@
#include <string.h> #include <string.h>
#include "app/app.h"
#include "app/chFrScanner.h" #include "app/chFrScanner.h"
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
#include "app/fm.h" #include "app/fm.h"
@@ -48,22 +49,24 @@ static void convertTime(uint8_t *line, uint8_t type)
char str[6]; char str[6];
sprintf(str, "%02u:%02u", m, s); sprintf(str, "%02u:%02u", m, s);
UI_PrintStringSmallBufferNormal(str, line); UI_PrintStringSmallBufferNormal(str, line);
gUpdateStatus = true;
} }
#endif #endif
#endif #endif
void UI_DisplayStatus() void UI_DisplayStatus()
{ {
char str[8] = "";
gUpdateStatus = false; gUpdateStatus = false;
if (APP_IsScreenSaverDisplayed())
return;
UI_StatusClear(); UI_StatusClear();
uint8_t *line = gStatusLine; uint8_t *line = gStatusLine;
unsigned int x = 0; unsigned int x = 0;
char str[8] = "";
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
// NOAA indicator // NOAA indicator
if (!(gScanStateDir != SCAN_OFF || SCANNER_IsScanning()) && gIsNoaaMode) { // NOASS SCAN indicator if (!(gScanStateDir != SCAN_OFF || SCANNER_IsScanning()) && gIsNoaaMode) { // NOASS SCAN indicator
@@ -99,8 +102,8 @@ void UI_DisplayStatus()
if(gEeprom.SCAN_LIST_DEFAULT == MR_CHANNELS_LIST + 1) if(gEeprom.SCAN_LIST_DEFAULT == MR_CHANNELS_LIST + 1)
{ {
sprintf(str, gEeprom.SCAN_LIST_ENABLED ? "%s+" : "%s", "ALL"); strcpy(str, "ALL");
end = gEeprom.SCAN_LIST_ENABLED ? 18 : 14; end = 14;
} }
else else
{ {
@@ -108,15 +111,19 @@ void UI_DisplayStatus()
// Check if name is valid // Check if name is valid
if (!IsEmptyName(name, sizeof(gListName[0]))) { if (!IsEmptyName(name, sizeof(gListName[0]))) {
sprintf(str, "%.3s%s", name, gEeprom.SCAN_LIST_ENABLED ? "+" : ""); sprintf(str, "%.3s", name);
end = gEeprom.SCAN_LIST_ENABLED ? 18 : 14; end = 14;
} } else {
else { sprintf(str, "%02d", gEeprom.SCAN_LIST_DEFAULT);
sprintf(str, "%02d%s", gEeprom.SCAN_LIST_DEFAULT, gEeprom.SCAN_LIST_ENABLED ? "+" : ""); end = 10;
end = gEeprom.SCAN_LIST_ENABLED ? 14 : 10;
} }
} }
if (gEeprom.SCAN_LIST_ENABLED) {
strcat(str, "+");
end += 4;
}
GUI_DisplaySmallest(str, 2, 1, true, true); GUI_DisplaySmallest(str, 2, 1, true, true);
gStatusLine[0] ^= 0x3E; gStatusLine[0] ^= 0x3E;
+33 -29
View File
@@ -44,6 +44,21 @@
#define LOGO_FLASH_ADDR 0x011000 #define LOGO_FLASH_ADDR 0x011000
#define LOGO_HEADER_SIZE 8 #define LOGO_HEADER_SIZE 8
#define LOGO_BITMAP_ADDR (LOGO_FLASH_ADDR + LOGO_HEADER_SIZE) #define LOGO_BITMAP_ADDR (LOGO_FLASH_ADDR + LOGO_HEADER_SIZE)
static void UI_LoadLogo(void)
{
// Skip 8-byte header, then read 128x64 bitmap (1024 B):
// page 0 -> gStatusLine, pages 1..7 -> gFrameBuffer.
PY25Q16_ReadBuffer(LOGO_BITMAP_ADDR, gStatusLine, sizeof(gStatusLine));
PY25Q16_ReadBuffer(LOGO_BITMAP_ADDR + sizeof(gStatusLine), gFrameBuffer, sizeof(gFrameBuffer));
}
void UI_DisplayLogo(void)
{
UI_LoadLogo();
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
}
#endif #endif
#ifdef ENABLE_FEAT_F4HWN_QRCODE #ifdef ENABLE_FEAT_F4HWN_QRCODE
@@ -217,11 +232,6 @@ void UI_DisplayReleaseKeys(void)
void UI_DisplayWelcome(void) void UI_DisplayWelcome(void)
{ {
char WelcomeString0[16];
char WelcomeString1[16];
char WelcomeString2[16];
char WelcomeString3[32];
UI_StatusClear(); UI_StatusClear();
#if defined(ENABLE_FEAT_F4HWN_CTR) || defined(ENABLE_FEAT_F4HWN_INV) #if defined(ENABLE_FEAT_F4HWN_CTR) || defined(ENABLE_FEAT_F4HWN_INV)
@@ -229,36 +239,30 @@ void UI_DisplayWelcome(void)
#endif #endif
UI_DisplayClear(); UI_DisplayClear();
#ifdef ENABLE_FEAT_F4HWN_LOGO
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_LOGO) {
// Skip 8-byte header, then read 128x64 bitmap (1024 B):
// page 0 -> gStatusLine, pages 1..7 -> gFrameBuffer.
PY25Q16_ReadBuffer(LOGO_BITMAP_ADDR, gStatusLine, sizeof(gStatusLine));
PY25Q16_ReadBuffer(LOGO_BITMAP_ADDR + sizeof(gStatusLine), gFrameBuffer, sizeof(gFrameBuffer));
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
SCREENSHOT_Update(true);
#endif
return;
}
#endif
#ifdef ENABLE_FEAT_F4HWN #ifdef ENABLE_FEAT_F4HWN
ST7565_BlitStatusLine(); ST7565_BlitStatusLine();
ST7565_BlitFullScreen(); ST7565_BlitFullScreen();
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND) { if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_SOUND) {
ST7565_FillScreen(0x00); ST7565_FillScreen(0x00);
return;
} }
#else #else
if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_FULL_SCREEN) { if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_NONE || gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_FULL_SCREEN) {
ST7565_FillScreen(0xFF); ST7565_FillScreen(0xFF);
return;
}
#endif
#ifdef ENABLE_FEAT_F4HWN_LOGO
else if (gEeprom.POWER_ON_DISPLAY_MODE == POWER_ON_DISPLAY_MODE_LOGO) {
UI_LoadLogo();
} }
#endif #endif
else { else {
memset(WelcomeString0, 0, sizeof(WelcomeString0)); char WelcomeString0[16];
memset(WelcomeString1, 0, sizeof(WelcomeString1)); char WelcomeString1[16];
char WelcomeString2[16];
char WelcomeString3[32];
// 0x0EB0 // 0x0EB0
PY25Q16_ReadBuffer(0x00A0C8, WelcomeString0, 16); PY25Q16_ReadBuffer(0x00A0C8, WelcomeString0, 16);
@@ -346,12 +350,12 @@ void UI_DisplayWelcome(void)
#else #else
UI_PrintStringSmallNormal(Version, 0, 127, 6); UI_PrintStringSmallNormal(Version, 0, 127, 6);
#endif #endif
//ST7565_BlitStatusLine(); // blank status line : I think it's useless
ST7565_BlitFullScreen();
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
SCREENSHOT_Update(true);
#endif
} }
ST7565_BlitStatusLine();
ST7565_BlitFullScreen();
#ifdef ENABLE_FEAT_F4HWN_SCREENSHOT
SCREENSHOT_Update(true);
#endif
} }
+4 -1
View File
@@ -23,6 +23,10 @@
void UI_DisplayReleaseKeys(void); void UI_DisplayReleaseKeys(void);
void UI_DisplayWelcome(void); void UI_DisplayWelcome(void);
#ifdef ENABLE_FEAT_F4HWN_LOGO
void UI_DisplayLogo(void);
#endif
#ifdef ENABLE_FEAT_F4HWN_QRCODE #ifdef ENABLE_FEAT_F4HWN_QRCODE
// Draw the embedded GitHub QR code (V4, 33x33) at (origin_x, origin_y). // Draw the embedded GitHub QR code (V4, 33x33) at (origin_x, origin_y).
// `wiki` selects the wiki URL bitmap, otherwise the repo URL bitmap. // `wiki` selects the wiki URL bitmap, otherwise the repo URL bitmap.
@@ -35,4 +39,3 @@ void UI_GetMemPercents(uint16_t *flash_pct_x100, uint16_t *ram_pct_x100);
#endif #endif
#endif #endif
+3 -1
View File
@@ -34,7 +34,7 @@
"ENABLE_BOOT_BEEPS": false, "ENABLE_BOOT_BEEPS": false,
"ENABLE_SHOW_CHARGE_LEVEL": false, "ENABLE_SHOW_CHARGE_LEVEL": false,
"ENABLE_REVERSE_BAT_SYMBOL": false, "ENABLE_REVERSE_BAT_SYMBOL": false,
"ENABLE_NO_CODE_SCAN_TIMEOUT": true, "ENABLE_NO_CODE_SCAN_TIMEOUT": false,
"ENABLE_SQUELCH_MORE_SENSITIVE": true, "ENABLE_SQUELCH_MORE_SENSITIVE": true,
"ENABLE_FASTER_CHANNEL_SCAN": true, "ENABLE_FASTER_CHANNEL_SCAN": true,
"ENABLE_RSSI_BAR": true, "ENABLE_RSSI_BAR": true,
@@ -72,6 +72,7 @@
"ENABLE_FEAT_F4HWN_SCAN_FASTER": false, "ENABLE_FEAT_F4HWN_SCAN_FASTER": false,
"ENABLE_FEAT_F4HWN_BEAM": false, "ENABLE_FEAT_F4HWN_BEAM": false,
"ENABLE_FEAT_F4HWN_LOGO": false, "ENABLE_FEAT_F4HWN_LOGO": false,
"ENABLE_FEAT_F4HWN_LOGO_SAV": false,
"ENABLE_AGC_SHOW_DATA": false, "ENABLE_AGC_SHOW_DATA": false,
"ENABLE_UART_RW_BK_REGS": false, "ENABLE_UART_RW_BK_REGS": false,
"ENABLE_SWD": false, "ENABLE_SWD": false,
@@ -202,6 +203,7 @@
"ENABLE_FEAT_F4HWN_QRCODE": true, "ENABLE_FEAT_F4HWN_QRCODE": true,
"ENABLE_FEAT_F4HWN_MEM": true, "ENABLE_FEAT_F4HWN_MEM": true,
"ENABLE_FEAT_F4HWN_LOGO": true, "ENABLE_FEAT_F4HWN_LOGO": true,
"ENABLE_FEAT_F4HWN_LOGO_SAV": true,
"ENABLE_SWD": true, "ENABLE_SWD": true,
"EDITION_STRING": "Fusion", "EDITION_STRING": "Fusion",
"TARGET": "f4hwn.fusion" "TARGET": "f4hwn.fusion"
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB