Add MIX scan list mode

This commit is contained in:
Armel FAUVEAU committed 2026-09-19 05:05:38 +02:00
1 parent e9d4e9e184
commit cc2281d3cb
14 files changed
+317 -59

No files matched your search

+1
View File
@@ -2097,6 +2097,7 @@ void APP_TimeSlice500ms(void)
if (exit_menu) {
gMenuCountdown = 0;
gScanMixEditorActive = false;
const int m = UI_MENU_GetCurrentMenuId();
+3 -3
View File
@@ -1045,9 +1045,9 @@ static void NextFreqChannel(void)
static void NextMemChannel(void)
{
static uint16_t prev_mr_chan = 0;
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT <= MR_CHANNELS_LIST + 1) ? gEeprom.SCAN_LIST_ENABLED : true;
const int16_t chan1 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT <= MR_CHANNELS_LIST + 1 && gEeprom.SCANLIST_PRIORITY_CH[0] != MR_CHANNELS_MAX) ? gEeprom.SCANLIST_PRIORITY_CH[0] : -1;
const int16_t chan2 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT <= MR_CHANNELS_LIST + 1 && gEeprom.SCANLIST_PRIORITY_CH[1] != MR_CHANNELS_MAX) ? gEeprom.SCANLIST_PRIORITY_CH[1] : -1;
const bool enabled = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT <= SCAN_LIST_MODE_MIX) ? gEeprom.SCAN_LIST_ENABLED : true;
const int16_t chan1 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT <= SCAN_LIST_MODE_MIX && gEeprom.SCANLIST_PRIORITY_CH[0] != MR_CHANNELS_MAX) ? gEeprom.SCANLIST_PRIORITY_CH[0] : -1;
const int16_t chan2 = (gEeprom.SCAN_LIST_DEFAULT > 0 && gEeprom.SCAN_LIST_DEFAULT <= SCAN_LIST_MODE_MIX && gEeprom.SCANLIST_PRIORITY_CH[1] != MR_CHANNELS_MAX) ? gEeprom.SCANLIST_PRIORITY_CH[1] : -1;
const uint16_t prev_chan = gNextMrChannel;
uint16_t chan = 0;
+22 -22
View File
@@ -25,6 +25,7 @@
#endif
#include "app/generic.h"
#include "app/main.h"
#include "app/menu.h"
#include "app/scanner.h"
#ifdef ENABLE_SPECTRUM
@@ -104,7 +105,7 @@ static void toggle_chan_scanlist(void)
scanlist++;
if (scanlist > MR_CHANNELS_LIST + 1)
if (scanlist > SCAN_LIST_MODE_ALL)
scanlist = 0;
gTxVfo->SCANLIST_PARTICIPATION = scanlist;
@@ -491,26 +492,6 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
if (!gWasFKeyPressed) { // F-key wasn't pressed
if (gScanStateDir != SCAN_OFF){
/*
switch(Key) {
case KEY_0:
gEeprom.SCAN_LIST_DEFAULT = MR_CHANNELS_LIST + 1;
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
SETTINGS_WriteCurrentState();
#endif
break;
case KEY_1...KEY_9:
gEeprom.SCAN_LIST_DEFAULT = Key;
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
SETTINGS_WriteCurrentState();
#endif
break;
default:
break;
}
return;
*/
INPUTBOX_Append(Key);
/* Wait until exactly two digits are entered */
@@ -525,7 +506,7 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
/* 00 = ALL scan lists */
if (value == 0)
{
gEeprom.SCAN_LIST_DEFAULT = MR_CHANNELS_LIST + 1;
gEeprom.SCAN_LIST_DEFAULT = SCAN_LIST_MODE_ALL;
UI_MAIN_NotifyScanListChanged();
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
SETTINGS_WriteCurrentState();
@@ -533,6 +514,24 @@ static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return;
}
/* 25 = saved MIX selection */
if (value == SCAN_LIST_MIX_SHORTCUT)
{
gEeprom.SCAN_LIST_DEFAULT = SCAN_LIST_MODE_MIX;
if (!RADIO_CheckValidList(SCAN_LIST_MODE_MIX))
{
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
RADIO_NextValidList(1);
}
UI_MAIN_NotifyScanListChanged();
#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE
SETTINGS_WriteCurrentState();
#endif
return;
}
/* 01 .. MR_CHANNELS_LIST */
if (value <= MR_CHANNELS_LIST)
{
@@ -854,6 +853,7 @@ static void MAIN_Key_MENU(bool bKeyPressed, bool bKeyHeld)
#endif
gFlagRefreshSetting = true;
gScanMixEditorActive = false;
gRequestDisplayScreen = DISPLAY_MENU;
#ifdef ENABLE_FEAT_F4HWN_MENU_CAT
gMenuLevel = MENU_LEVEL_CAT;
+138 -2
View File
@@ -37,6 +37,7 @@
#include "frequencies.h"
#include "helper/battery.h"
#include "misc.h"
#include "radio.h"
#include "settings.h"
#include "../driver/st7565.h"
#if defined(ENABLE_OVERLAY)
@@ -48,6 +49,41 @@
uint8_t gUnlockAllTxConfCnt;
bool gScanMixEditorActive;
uint8_t gScanMixEditorCursor;
uint32_t gScanMixEditorMask;
static void MENU_OpenScanMixEditor(void)
{
gScanMixEditorMask = gEeprom.SCAN_LIST_MIX_MASK & SCAN_LIST_MIX_MASK_ALL;
if (gScanMixEditorMask == 0)
gScanMixEditorMask = SCAN_LIST_MIX_MASK_ALL;
gScanMixEditorCursor = 0;
while (gScanMixEditorCursor < MR_CHANNELS_LIST &&
(gScanMixEditorMask & (1u << gScanMixEditorCursor)) == 0)
gScanMixEditorCursor++;
if (gScanMixEditorCursor >= MR_CHANNELS_LIST)
gScanMixEditorCursor = 0;
gInputBoxIndex = 0;
gScanMixEditorActive = true;
gRequestDisplayScreen = DISPLAY_MENU;
gUpdateDisplay = true;
}
static void MENU_SaveScanMixEditor(void)
{
gEeprom.SCAN_LIST_MIX_MASK = gScanMixEditorMask & SCAN_LIST_MIX_MASK_ALL;
gEeprom.SCAN_LIST_DEFAULT = SCAN_LIST_MODE_MIX;
gSubMenuSelection = SCAN_LIST_MODE_MIX;
gScanMixEditorActive = false;
gIsInSubMenu = false;
gInputBoxIndex = 0;
gFlagRefreshSetting = true;
gRequestSaveSettings = true;
gRequestDisplayScreen = DISPLAY_MENU;
}
#ifdef ENABLE_F_CAL_MENU
void writeXtalFreqCal(const int32_t value, const bool update_eeprom)
@@ -319,12 +355,12 @@ int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax)
case MENU_LIST_CH:
//*pMin = 0;
*pMax = MR_CHANNELS_LIST + 1;
*pMax = SCAN_LIST_MODE_ALL;
break;
case MENU_S_LIST:
*pMin = 1;
*pMax = MR_CHANNELS_LIST + 1;
*pMax = SCAN_LIST_MODE_MIX;
break;
#ifdef ENABLE_DTMF_CALLING
@@ -1040,6 +1076,12 @@ static void MENU_ClampSelection(int8_t Direction)
int32_t Min;
int32_t Max;
if (UI_MENU_GetCurrentMenuId() == MENU_S_LIST)
{
gSubMenuSelection = RADIO_GetAdjacentScanList(gSubMenuSelection, Direction);
return;
}
if (!MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max))
{
int32_t Selection = gSubMenuSelection;
@@ -1528,6 +1570,26 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
if (gScanMixEditorActive)
{
if (bKeyHeld)
return;
INPUTBOX_Append(Key);
if (gInputBoxIndex < 2)
return;
gInputBoxIndex = 0;
Value = (gInputBox[0] * 10) + gInputBox[1];
if (Value >= 1 && Value <= MR_CHANNELS_LIST) {
gScanMixEditorCursor = (uint8_t)(Value - 1);
gRequestDisplayScreen = DISPLAY_MENU;
} else {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
return;
}
if (UI_MENU_GetCurrentMenuId() == MENU_MEM_NAME && edit_index >= 0)
{ // currently editing the channel name
if (edit_index >= 10)
@@ -1705,6 +1767,25 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
return;
}
if (m == MENU_S_LIST)
{
if (gInputBoxIndex < 2)
return;
gInputBoxIndex = 0;
Value = (gInputBox[0] * 10) + gInputBox[1];
if (Value == 0)
gSubMenuSelection = SCAN_LIST_MODE_ALL;
else if (Value == SCAN_LIST_MIX_SHORTCUT)
gSubMenuSelection = SCAN_LIST_MODE_MIX;
else if (Value <= MR_CHANNELS_LIST)
gSubMenuSelection = Value;
else
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
if (MENU_GetLimits(UI_MENU_GetCurrentMenuId(), &Min, &Max))
{
gInputBoxIndex = 0;
@@ -1747,6 +1828,16 @@ static void MENU_Key_0_to_9(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
static void MENU_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
{
if (gScanMixEditorActive)
{
if (bKeyHeld || !bKeyPressed)
return;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
MENU_SaveScanMixEditor();
return;
}
if (MENU_IsEditingName())
{
if (!bKeyPressed)
@@ -1863,6 +1954,24 @@ Skip:
static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
{
if (gScanMixEditorActive)
{
if (!bKeyPressed || bKeyHeld)
return;
const uint32_t bit = 1u << gScanMixEditorCursor;
if ((gScanMixEditorMask & bit) != 0 && (gScanMixEditorMask & ~bit) == 0) {
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
gScanMixEditorMask ^= bit;
gInputBoxIndex = 0;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
gRequestDisplayScreen = DISPLAY_MENU;
return;
}
if (!bKeyPressed || (bKeyHeld && (!MENU_IsEditingName() || gAskForConfirmation)))
return;
@@ -1966,6 +2075,13 @@ static void MENU_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
}
}
if (UI_MENU_GetCurrentMenuId() == MENU_S_LIST &&
gSubMenuSelection == SCAN_LIST_MODE_MIX)
{
MENU_OpenScanMixEditor();
return;
}
// exiting the sub menu
if (gIsInSubMenu)
@@ -2122,6 +2238,26 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
if (!bKeyPressed)
return;
if (gScanMixEditorActive)
{
if (!bKeyHeld) {
gInputBoxIndex = 0;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
}
#ifdef ENABLE_FEAT_F4HWN
if (!gEeprom.SET_NAV)
Direction = -Direction;
#else
Direction = -Direction;
#endif
gScanMixEditorCursor = NUMBER_AddWithWraparound(gScanMixEditorCursor,
Direction,
0,
MR_CHANNELS_LIST - 1);
gRequestDisplayScreen = DISPLAY_MENU;
return;
}
if (!bKeyHeld) {
gInputBoxIndex = 0;
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
+3 -1
View File
@@ -24,6 +24,9 @@
#endif
extern uint8_t gUnlockAllTxConfCnt;
extern bool gScanMixEditorActive;
extern uint8_t gScanMixEditorCursor;
extern uint32_t gScanMixEditorMask;
int MENU_GetLimits(uint8_t menu_id, int32_t *pMin, int32_t *pMax);
void MENU_AcceptSetting(void);
@@ -35,4 +38,3 @@ void MENU_StopCssScan(void);
void MENU_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld);
#endif
+2 -1
View File
@@ -58,7 +58,7 @@ static const AddrMapping_t ADDR_MAPPINGS[] = {
// (written directly by app/foxhunt.c; concatenated
// here so aircopy clones them with the VFOs)
_MK_MAPPING(0x00A000, 0x00A000, 0x00A170), // Settings * 16 Bytes (ex 0x004000) 0x00A000 -> 0x00A010
_MK_MAPPING(0x00A000, 0x00A000, 0x00A178), // Settings * 16 Bytes (ex 0x004000) 0x00A000 -> 0x00A010
// Settings * 16 Bytes (ex 0x005000) 0x00A010 -> 0x00A020
// Settings FM * 8 Bytes (0x006000) 0x00A020 -> 0x00A028
// MR FM * 128 Bytes (0x003000) 0x00A028 -> 0x00A0A8
@@ -70,6 +70,7 @@ static const AddrMapping_t ADDR_MAPPINGS[] = {
// Settings * 8 Bytes (0x00B000) 0x00A150 -> 0x00A158
// Settings F4HWN * 8 Bytes (0x00C000) 0x00A158 -> 0x00A160
// Settings Version * 16 Bytes 0x00A160 -> 0x00A170
// Settings Mixed Scan Lists * 8 Bytes 0x00A170 -> 0x00A178
_MK_MAPPING(0x010000, 0x00B000, 0x00B200), // Calibration 512 Bytes!!!
+4
View File
@@ -39,6 +39,10 @@
#define FM_CHANNELS_MAX 48
#define MR_CHANNELS_MAX 1024
#define MR_CHANNELS_LIST 24
#define SCAN_LIST_MODE_ALL (MR_CHANNELS_LIST + 1u)
#define SCAN_LIST_MODE_MIX (MR_CHANNELS_LIST + 2u)
#define SCAN_LIST_MIX_SHORTCUT 25u
#define SCAN_LIST_MIX_MASK_ALL ((1u << MR_CHANNELS_LIST) - 1u)
// CACHE-BASED OPTIMIZATION: Only keep active channels in RAM
// Full array stays in EEPROM, cache holds ~10 most-used channels
#define MR_CHANNELS_CACHE_SIZE 10
+63 -14
View File
@@ -120,14 +120,38 @@ const char gModulationStr[MODULATION_UKNOWN][4] = {
}
#endif
bool RADIO_IsChannelInScanList(uint8_t channelScanList, uint8_t scanList)
{
if (scanList < 1 || scanList > SCAN_LIST_MODE_MIX)
return false;
if (channelScanList == 0)
return false;
if (channelScanList == SCAN_LIST_MODE_ALL)
return true;
if (scanList == SCAN_LIST_MODE_ALL)
return true;
if (scanList == SCAN_LIST_MODE_MIX) {
if (channelScanList > MR_CHANNELS_LIST)
return false;
return (gEeprom.SCAN_LIST_MIX_MASK & (1u << (channelScanList - 1u))) != 0;
}
return scanList >= 1 && scanList <= MR_CHANNELS_LIST && channelScanList == scanList;
}
bool RADIO_CheckValidList(uint8_t scanList)
{
if(scanList == MR_CHANNELS_LIST + 1)
if (scanList == SCAN_LIST_MODE_ALL)
return true;
for (uint16_t i = 0; IS_MR_CHANNEL(i); i++) {
const ChannelAttributes_t* att = MR_GetChannelAttributes(i);
if(att->scanlist == scanList && att->exclude == false)
if (att != NULL && !att->exclude && att->band <= BAND7_470MHz &&
RADIO_IsChannelInScanList(att->scanlist, scanList))
{
return true;
}
@@ -135,20 +159,43 @@ bool RADIO_CheckValidList(uint8_t scanList)
return false;
}
uint8_t RADIO_GetAdjacentScanList(uint8_t scanList, int8_t direction)
{
if (scanList < 1 || scanList > SCAN_LIST_MODE_MIX)
scanList = 1;
if (direction > 0) {
if (scanList == MR_CHANNELS_LIST)
return SCAN_LIST_MODE_MIX;
if (scanList == SCAN_LIST_MODE_MIX)
return SCAN_LIST_MODE_ALL;
if (scanList == SCAN_LIST_MODE_ALL)
return 1;
return scanList + 1;
}
if (direction < 0) {
if (scanList == 1)
return SCAN_LIST_MODE_ALL;
if (scanList == SCAN_LIST_MODE_ALL)
return SCAN_LIST_MODE_MIX;
if (scanList == SCAN_LIST_MODE_MIX)
return MR_CHANNELS_LIST;
return scanList - 1;
}
return scanList;
}
void RADIO_NextValidList(int8_t direction)
{
uint8_t startList = gEeprom.SCAN_LIST_DEFAULT;
uint8_t attempts = 0;
const uint8_t MAX_VALUE = MR_CHANNELS_LIST + 1; // 25 (1-24 lists + ALL)
const uint8_t MAX_VALUE = SCAN_LIST_MODE_MIX;
do {
if (direction > 0) {
// Forward: 1 → 2 → ... → 25 → 1
gEeprom.SCAN_LIST_DEFAULT = (gEeprom.SCAN_LIST_DEFAULT % MAX_VALUE) + 1;
} else {
// Backward: 25 → 24 → ... → 1 → 25
gEeprom.SCAN_LIST_DEFAULT = ((gEeprom.SCAN_LIST_DEFAULT - 2 + MAX_VALUE) % MAX_VALUE) + 1;
}
gEeprom.SCAN_LIST_DEFAULT = RADIO_GetAdjacentScanList(gEeprom.SCAN_LIST_DEFAULT,
direction);
attempts++;
if (RADIO_CheckValidList(gEeprom.SCAN_LIST_DEFAULT))
@@ -158,7 +205,7 @@ void RADIO_NextValidList(int8_t direction)
// Safety fallback: switch to ALL mode
if (!RADIO_CheckValidList(gEeprom.SCAN_LIST_DEFAULT)) {
gEeprom.SCAN_LIST_DEFAULT = MAX_VALUE; // ALL (25)
gEeprom.SCAN_LIST_DEFAULT = SCAN_LIST_MODE_ALL;
}
}
@@ -169,13 +216,15 @@ bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanL
// return true if the channel appears valid
if (!IS_MR_CHANNEL(channel))
return false;
if (att == NULL)
return false;
if (checkScanList && att->exclude == true)
return false;
if (att->band > BAND7_470MHz)
return false;
if (!checkScanList || (scanList > MR_CHANNELS_LIST && att->scanlist != 0) || (scanList > 0 && att->scanlist == MR_CHANNELS_LIST + 1))
if (!checkScanList)
return true;
if ((scanList == 0) || (scanList != att->scanlist)) {
if (!RADIO_IsChannelInScanList(att->scanlist, scanList)) {
return false;
}
@@ -322,7 +371,7 @@ void RADIO_ConfigureChannel(const unsigned int VFO, const unsigned int configure
}
else {
band = channel - FREQ_CHANNEL_FIRST;
bParticipation = MR_CHANNELS_LIST + 1;
bParticipation = SCAN_LIST_MODE_ALL;
}
pVfo->Band = band;
+2
View File
@@ -152,7 +152,9 @@ extern VfoState_t VfoState[2];
extern const char *const VfoStateStr[];
bool RADIO_CheckValidList(uint8_t scanList);
uint8_t RADIO_GetAdjacentScanList(uint8_t scanList, int8_t direction);
void RADIO_NextValidList(int8_t direction);
bool RADIO_IsChannelInScanList(uint8_t channelScanList, uint8_t scanList);
bool RADIO_CheckValidChannel(uint16_t channel, bool checkScanList, uint8_t scanList);
uint16_t RADIO_FindNextChannel(uint16_t ChNum, int8_t Direction, bool bCheckScanList, uint8_t RadioNum);
void RADIO_InitInfo(VFO_Info_t *pInfo, const uint16_t ChannelSave, const uint32_t Frequency);
+27 -1
View File
@@ -28,6 +28,8 @@
#include "settings.h"
#include "ui/menu.h"
#define SETTINGS_SCAN_MIX_ADDR 0x00A170u
EEPROM_Config_t gEeprom = { 0 };
// Load a DTMF code from EEPROM, falling back to default_val if invalid.
@@ -333,7 +335,7 @@ gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data16[5]) ? Data16[5] : (FREQ_CHANNE
PY25Q16_ReadBuffer(0x00A130, Data, 8);
gEeprom.SCAN_LIST_DEFAULT =
(((Data[0] & 0x7F) >= 1) && ((Data[0] & 0x7F) <= (MR_CHANNELS_LIST + 1)))
(((Data[0] & 0x7F) >= 1) && ((Data[0] & 0x7F) <= SCAN_LIST_MODE_MIX))
? (Data[0] & 0x7F)
: 1;
gEeprom.SCAN_LIST_ENABLED = (Data[0] >> 7) & 0x01;
@@ -350,6 +352,19 @@ gEeprom.FreqChannel[1] = IS_FREQ_CHANNEL(Data16[5]) ? Data16[5] : (FREQ_CHANNE
(uint16_t)Data[5] |
((uint16_t)Data[6] << 8);
// 0F58..0F5F
PY25Q16_ReadBuffer(SETTINGS_SCAN_MIX_ADDR, Data, 8);
if (Data[3] == 'M' && Data[4] == 'I' && Data[5] == 'X' && Data[6] == 1) {
gEeprom.SCAN_LIST_MIX_MASK =
(uint32_t)Data[0] |
((uint32_t)Data[1] << 8) |
((uint32_t)Data[2] << 16);
if (gEeprom.SCAN_LIST_MIX_MASK == 0)
gEeprom.SCAN_LIST_MIX_MASK = SCAN_LIST_MIX_MASK_ALL;
} else {
gEeprom.SCAN_LIST_MIX_MASK = SCAN_LIST_MIX_MASK_ALL;
}
// 0F40..0F47
PY25Q16_ReadBuffer(0x00A150, Data, 8);
gSetting_F_LOCK = (Data[0] < F_LOCK_LEN) ? Data[0] : F_LOCK_DEF;
@@ -1150,6 +1165,17 @@ void SETTINGS_SaveSettings(void)
#ifdef ENABLE_FEAT_F4HWN_VOL
SETTINGS_WriteCurrentVol();
#endif
// 0F58..0F5F
PY25Q16_ReadBuffer(SETTINGS_SCAN_MIX_ADDR, SecBuf, 8);
SecBuf[0] = (uint8_t)(gEeprom.SCAN_LIST_MIX_MASK & 0xFFu);
SecBuf[1] = (uint8_t)((gEeprom.SCAN_LIST_MIX_MASK >> 8) & 0xFFu);
SecBuf[2] = (uint8_t)((gEeprom.SCAN_LIST_MIX_MASK >> 16) & 0xFFu);
SecBuf[3] = 'M';
SecBuf[4] = 'I';
SecBuf[5] = 'X';
SecBuf[6] = 1;
PY25Q16_WriteBuffer(SETTINGS_SCAN_MIX_ADDR, SecBuf, 8, false);
}
void SETTINGS_SaveChannel(uint16_t Channel, uint8_t VFO, const VFO_Info_t *pVFO, uint8_t Mode)
+1
View File
@@ -213,6 +213,7 @@ typedef struct {
uint8_t BACKLIGHT_TIME;
uint8_t SCAN_RESUME_MODE;
uint8_t SCAN_LIST_DEFAULT;
uint32_t SCAN_LIST_MIX_MASK;
bool SCAN_LIST_ENABLED;
uint16_t SCANLIST_PRIORITY_CH[6];
//#ifdef ENABLE_FEAT_F4HWN_RESUME_STATE // Fix me !!! What the hell is this?
+7 -11
View File
@@ -268,7 +268,7 @@ static inline bool ScanProgress_GetBit(const uint8_t *map, uint16_t ch)
static uint8_t ScanProgress_GetActiveScanList(void)
{
const uint8_t max_scan_list = MR_CHANNELS_LIST + 1;
const uint8_t max_scan_list = SCAN_LIST_MODE_MIX;
uint8_t scan_list = gEeprom.SCAN_LIST_DEFAULT;
if (scan_list == 0 || scan_list > max_scan_list)
@@ -286,7 +286,9 @@ static void UI_MAIN_DrawScanListName(void)
strcpy(text, "SCAN LIST ");
char *p = text + 10; // sizeof("SCAN LIST ") - 1
if (scan_list > MR_CHANNELS_LIST) {
if (scan_list == SCAN_LIST_MODE_MIX) {
*p++ = 'M'; *p++ = 'I'; *p++ = 'X';
} else if (scan_list == SCAN_LIST_MODE_ALL) {
*p++ = 'A'; *p++ = 'L'; *p++ = 'L';
} else {
const char *name = gListName[scan_list - 1];
@@ -312,13 +314,7 @@ static bool ScanProgress_ChannelBelongsToList(uint16_t channel, const ChannelAtt
if (att->band > BAND7_470MHz)
return false;
if (scan_list > MR_CHANNELS_LIST && att->scanlist != 0)
return true;
if (scan_list > 0 && att->scanlist == (MR_CHANNELS_LIST + 1))
return true;
if (scan_list == 0 || scan_list != att->scanlist)
if (!RADIO_IsChannelInScanList(att->scanlist, scan_list))
return false;
if (gEeprom.SCAN_LIST_ENABLED) {
@@ -1788,11 +1784,11 @@ void UI_DisplayMain(void)
{
// show the scan list assigment symbols
uint8_t countList = att->scanlist;
if(countList > MR_CHANNELS_LIST + 1) {
if(countList > SCAN_LIST_MODE_ALL) {
countList = 0;
}
if (countList == MR_CHANNELS_LIST + 1) {
if (countList == SCAN_LIST_MODE_ALL) {
displayStr = "ALL";
}
else if (countList == 0) {
+38 -3
View File
@@ -825,7 +825,6 @@ static void UI_MENU_DrawTopRightRoundedBadge(const char *text, const uint8_t lin
UI_PrintStringSmallNormalInverse(text, text_x, 0, line);
}
#ifdef ENABLE_FEAT_F4HWN_MULTIBOOT
/* Draw `text` (3x5 font) centred inside a fixed-width rounded inverse capsule:
* left edge `cap_left`, inclusive width `cap_w`, on framebuffer page `line`. Same
* capsule pattern as GUI_DisplaySmallestInverse (0x3E rounded ends, 0x7F body) but
@@ -845,7 +844,34 @@ static void UI_MENU_DrawFixedCapsule(const char *text, uint8_t cap_left,
gFrameBuffer[line][x] ^= 0x7Fu;
gFrameBuffer[line][cap_right] ^= 0x3Eu;
}
#endif
static void UI_MENU_DrawScanMixEditor(void)
{
char text[9];
// Keep the cursor centred, with two neighbouring lists above and below.
for (int8_t row = -2; row <= 2; row++) {
const uint8_t index = (uint8_t)((gScanMixEditorCursor + row +
MR_CHANNELS_LIST) % MR_CHANNELS_LIST);
const uint8_t line = (uint8_t)(3 + row);
const char *name = gListName[index];
if (IsEmptyName(name, sizeof(gListName[0])))
sprintf(text, "%02u", (unsigned)(index + 1));
else
sprintf(text, "%02u (%.3s)", (unsigned)(index + 1), name);
// The longest label ends at x=109; the compact ON capsule stays right-aligned.
if (row == 0) {
UI_PrintStringSmallBold(text, 54, 0, line);
} else {
UI_PrintStringSmallNormal(text, 54, 0, line);
}
if (gScanMixEditorMask & (1u << index))
UI_MENU_DrawFixedCapsule("ON", 115, 11, line);
}
}
void UI_DisplayMenu(void)
{
@@ -972,6 +998,13 @@ void UI_DisplayMenu(void)
BACKLIGHT_TurnOn();
if (gScanMixEditorActive)
{
UI_MENU_DrawScanMixEditor();
ST7565_BlitFullScreen();
return;
}
//#if !defined(ENABLE_SPECTRUM) || !defined(ENABLE_FMRADIO)
uint8_t gaugeLine = 0;
uint8_t gaugeMin = 0;
@@ -1330,7 +1363,9 @@ void UI_DisplayMenu(void)
case MENU_LIST_CH:
case MENU_S_LIST:
if (gSubMenuSelection == MR_CHANNELS_LIST + 1)
if (gSubMenuSelection == SCAN_LIST_MODE_MIX && m == MENU_S_LIST)
strcpy(String, "MIX");
else if (gSubMenuSelection == SCAN_LIST_MODE_ALL)
strcpy(String, "ALL");
else if (gSubMenuSelection == 0 && m == MENU_LIST_CH)
strcpy(String, "OFF");
+6 -1
View File
@@ -157,7 +157,12 @@ void UI_DisplayStatus()
if (IS_MR_CHANNEL(gNextMrChannel) && !SCANNER_IsScanning()) { // channel mode
uint8_t end = 0;
if(gEeprom.SCAN_LIST_DEFAULT == MR_CHANNELS_LIST + 1)
if (gEeprom.SCAN_LIST_DEFAULT == SCAN_LIST_MODE_MIX)
{
strcpy(str, "MIX");
end = 14;
}
else if(gEeprom.SCAN_LIST_DEFAULT == SCAN_LIST_MODE_ALL)
{
strcpy(str, "ALL");
end = 14;