ui: settings: add CTCSS enable to FM settings menu

Added the ability to manage CTCSS enablement via the FM settings menu.
As part of this, refactored the existing instances of setting and
displaying this value on the main vfo screen and on the macro menu.

Acked-by: Silvano Seva <silseva@fastwebnet.it>
This commit is contained in:
Silvano Seva 2025-09-22 21:16:18 +02:00
parent f7e5e45d09
commit d092c51df5
7 changed files with 102 additions and 46 deletions

View File

@ -98,5 +98,10 @@ const stringsTable_t englishStrings =
.noGps = "No GPS",
.batteryIcon = "Battery Icon",
.CTCSSTone = "CTCSS Frequency",
.CTCSSEn = "CTCSS En.",
.Encode = "Encode",
.Decode = "Decode",
.Both = "Both",
.None = "None"
};
#endif // ENGLISHSTRINGS_H

View File

@ -99,5 +99,10 @@ const stringsTable_t spanishStrings =
.noGps = "Ningún GPS",
.batteryIcon = "Icon de batteria",
.CTCSSTone = "Tono CTCSS",
.CTCSSEn = "CTCSS En.",
.Encode = "Codificar",
.Decode = "Decodificar",
.Both = "Ambos",
.None = "Ni"
};
#endif // SPANISHSTRINGS_H

View File

@ -157,7 +157,8 @@ enum settingsM17Items
enum settingsFMItems
{
CTCSS_Tone
CTCSS_Tone,
CTCSS_Enabled
};
/**

View File

@ -102,6 +102,11 @@ typedef struct
const char* noGps;
const char* batteryIcon;
const char* CTCSSTone;
const char* CTCSSEn;
const char* Encode;
const char* Decode;
const char* Both;
const char* None;
}
stringsTable_t;

View File

@ -119,7 +119,7 @@ extern void _ui_drawSettingsReset2Defaults(ui_state_t* ui_state);
extern void _ui_drawSettingsRadio(ui_state_t* ui_state);
extern bool _ui_drawMacroMenu(ui_state_t* ui_state);
extern void _ui_reset_menu_anouncement_tracking();
// TODO: get these from ui strings / currentLanguage
const char *menu_items[] =
{
"Banks",
@ -188,7 +188,8 @@ const char * settings_m17_items[] =
const char* settings_fm_items[] =
{
"CTCSS Tone"
"CTCSS Tone",
"CTCSS En."
};
const char * settings_accessibility_items[] =
@ -890,6 +891,27 @@ static bool _ui_exitStandby(long long now)
return true;
}
// TODO: find a better home for this function
int _ui_handleToneSelectScroll(bool direction_up)
{
bool tone_tx_enable = state.channel.fm.txToneEn;
bool tone_rx_enable = state.channel.fm.rxToneEn;
uint8_t tone_flags = tone_tx_enable << 1 | tone_rx_enable;
if(direction_up)
tone_flags++;
else
tone_flags--;
tone_flags %= 4;
tone_tx_enable = tone_flags >> 1;
tone_rx_enable = tone_flags & 1;
state.channel.fm.txToneEn = tone_tx_enable;
state.channel.fm.rxToneEn = tone_rx_enable;
return 1;
}
static void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
{
// If there is no keyboard left and right select the menu entry to edit
@ -913,9 +935,6 @@ static void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
ui_state.input_number = input_getPressedNumber(msg);
#endif // CONFIG_UI_NO_KEYBOARD
// CTCSS Encode/Decode Selection
bool tone_tx_enable = state.channel.fm.txToneEn;
bool tone_rx_enable = state.channel.fm.rxToneEn;
uint8_t tone_flags = tone_tx_enable << 1 | tone_rx_enable;
vpQueueFlags_t queueFlags = vp_getVoiceLevelQueueFlags();
switch(ui_state.input_number)
@ -923,12 +942,7 @@ static void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
case 1:
if(state.channel.mode == OPMODE_FM)
{
tone_flags++;
tone_flags %= 4;
tone_tx_enable = tone_flags >> 1;
tone_rx_enable = tone_flags & 1;
state.channel.fm.txToneEn = tone_tx_enable;
state.channel.fm.rxToneEn = tone_rx_enable;
_ui_handleToneSelectScroll(true);
*sync_rtx = true;
vp_announceCTCSS(
state.channel.fm.rxToneEn, state.channel.fm.rxTone,
@ -2387,7 +2401,12 @@ void ui_updateFSM(bool *sync_rtx)
state.channel.fm.txTone--;
}
}
else if (msg.keys & KEY_UP || msg.keys & KNOB_RIGHT)
{
state.channel.fm.txTone++;
} else if (msg.keys & KEY_ENTER) {
ui_state.edit_mode = false;
}
state.channel.fm.txTone %= CTCSS_FREQ_NUM;
state.channel.fm.rxTone = state.channel.fm.txTone;
*sync_rtx = true;
@ -2396,19 +2415,25 @@ void ui_updateFSM(bool *sync_rtx)
state.channel.fm.txToneEn,
state.channel.fm.txTone,
queueFlags);
if (msg.keys & KEY_UP || msg.keys & KNOB_RIGHT)
break;
case CTCSS_Enabled:
if (msg.keys & KEY_DOWN || msg.keys & KNOB_LEFT)
{
state.channel.fm.txTone++;
state.channel.fm.txTone %= CTCSS_FREQ_NUM;
state.channel.fm.rxTone = state.channel.fm.txTone;
*sync_rtx = true;
vp_announceCTCSS(state.channel.fm.rxToneEn,
state.channel.fm.rxTone,
state.channel.fm.txToneEn,
state.channel.fm.txTone,
queueFlags);
_ui_handleToneSelectScroll(true);
} else if (msg.keys & KEY_UP || msg.keys & KNOB_RIGHT)
{
_ui_handleToneSelectScroll(false);
} else if (msg.keys & KEY_ENTER) {
ui_state.edit_mode = false;
}
*sync_rtx = true;
vp_announceCTCSS(state.channel.fm.rxToneEn,
state.channel.fm.rxTone,
state.channel.fm.txToneEn,
state.channel.fm.txTone,
queueFlags | vpqIncludeDescriptions);
break;
}
}
else if (msg.keys & KEY_UP || msg.keys & KNOB_LEFT)

View File

@ -78,10 +78,31 @@ void _ui_drawBankChannel()
b, last_state.channel_index + 1, last_state.channel.name);
}
const char* _ui_getToneEnabledString(bool tone_tx_enable, bool tone_rx_enable,
bool use_abbreviation)
{
const char *strings[2][4] = {
{
currentLanguage->None,
currentLanguage->Encode,
currentLanguage->Decode,
currentLanguage->Both,
}, {
"N",
"T",
"R",
"B"
}
};
uint8_t index = (tone_rx_enable << 1) | (tone_tx_enable);
return strings[use_abbreviation][index];
}
void _ui_drawModeInfo(ui_state_t* ui_state)
{
char bw_str[8] = { 0 };
char encdec_str[9] = { 0 };
switch(last_state.channel.mode)
{
@ -96,23 +117,13 @@ void _ui_drawModeInfo(ui_state_t* ui_state)
// Get encdec string
bool tone_tx_enable = last_state.channel.fm.txToneEn;
bool tone_rx_enable = last_state.channel.fm.rxToneEn;
if (tone_tx_enable && tone_rx_enable)
sniprintf(encdec_str, 9, "ED");
else if (tone_tx_enable && !tone_rx_enable)
sniprintf(encdec_str, 9, " E");
else if (!tone_tx_enable && tone_rx_enable)
sniprintf(encdec_str, 9, " D");
else
sniprintf(encdec_str, 9, " ");
// Print Bandwidth, Tone and encdec info
if (tone_tx_enable || tone_rx_enable)
{
uint16_t tone = ctcss_tone[last_state.channel.fm.txTone];
gfx_print(layout.line2_pos, layout.line2_font, TEXT_ALIGN_CENTER,
color_white, "%s %d.%d %s", bw_str, (tone / 10),
(tone % 10), encdec_str);
(tone % 10), _ui_getToneEnabledString(tone_tx_enable, tone_rx_enable, true));
}
else
{

View File

@ -38,6 +38,8 @@
/* UI main screen helper functions, their implementation is in "ui_main.c" */
extern void _ui_drawMainBottom();
extern const char* _ui_getToneEnabledString(bool tone_tx_enable,
bool tone_rx_enable, bool use_abbreviation);
static char priorSelectedMenuName[MAX_ENTRY_LEN] = "\0";
static char priorSelectedMenuValue[MAX_ENTRY_LEN] = "\0";
@ -466,6 +468,13 @@ int _ui_getFMValueName(char* buf, uint8_t max_len, uint8_t index)
sniprintf(buf, max_len, "%d.%d", (tone / 10), (tone % 10));
break;
}
case CTCSS_Enabled:
sniprintf(buf, max_len, "%s",
_ui_getToneEnabledString(last_state.channel.fm.txToneEn,
last_state.channel.fm.rxToneEn,
false));
break;
}
return 0;
@ -1139,16 +1148,11 @@ bool _ui_drawMacroMenu(ui_state_t* ui_state)
if (last_state.channel.mode == OPMODE_FM)
{
char encdec_str[9] = {0};
bool tone_tx_enable = last_state.channel.fm.txToneEn;
bool tone_rx_enable = last_state.channel.fm.rxToneEn;
if (tone_tx_enable && tone_rx_enable)
sniprintf(encdec_str, 9, " B ");
else if (tone_tx_enable && !tone_rx_enable)
sniprintf(encdec_str, 9, " E ");
else if (!tone_tx_enable && tone_rx_enable)
sniprintf(encdec_str, 9, " D ");
else
sniprintf(encdec_str, 9, " N ");
sniprintf(encdec_str, 9, " %s",
_ui_getToneEnabledString(last_state.channel.fm.txToneEn,
last_state.channel.fm.rxToneEn,
true));
gfx_print(layout.line1_pos, layout.top_font, TEXT_ALIGN_LEFT,
color_white, encdec_str);
uint16_t tone = ctcss_tone[last_state.channel.fm.txTone];