2023-09-09 07:03:56 +00:00
|
|
|
/* Copyright 2023 Dual Tachyon
|
|
|
|
* https://github.com/DualTachyon
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "app/action.h"
|
|
|
|
#include "app/app.h"
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_FMRADIO
|
|
|
|
#include "app/fm.h"
|
|
|
|
#endif
|
2023-09-09 07:03:56 +00:00
|
|
|
#include "app/generic.h"
|
|
|
|
#include "app/main.h"
|
|
|
|
#include "app/scanner.h"
|
|
|
|
#include "audio.h"
|
2023-09-27 22:22:01 +00:00
|
|
|
#include "driver/bk4819.h"
|
2023-09-09 07:03:56 +00:00
|
|
|
#include "dtmf.h"
|
|
|
|
#include "frequencies.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "radio.h"
|
|
|
|
#include "settings.h"
|
|
|
|
#include "ui/inputbox.h"
|
|
|
|
#include "ui/ui.h"
|
|
|
|
|
2023-09-14 19:15:35 +00:00
|
|
|
static void processFKeyFunction(const KEY_Code_t Key, const bool beep)
|
2023-09-09 07:03:56 +00:00
|
|
|
{
|
|
|
|
uint8_t Band;
|
|
|
|
uint8_t Vfo = gEeprom.TX_CHANNEL;
|
|
|
|
|
|
|
|
switch (Key)
|
|
|
|
{
|
|
|
|
case KEY_0:
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_FMRADIO
|
|
|
|
ACTION_FM();
|
2023-09-25 12:27:52 +00:00
|
|
|
#else
|
2023-09-26 23:26:58 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-09-25 12:27:52 +00:00
|
|
|
// TODO: do something useful with the key
|
2023-09-26 23:26:58 +00:00
|
|
|
|
|
|
|
|
2023-09-25 17:08:21 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2023-09-14 08:56:30 +00:00
|
|
|
#endif
|
2023-09-09 07:03:56 +00:00
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_1:
|
|
|
|
if (!IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
{
|
|
|
|
gWasFKeyPressed = false;
|
|
|
|
gUpdateStatus = true;
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Band = gTxVfo->Band + 1;
|
|
|
|
if (gSetting_350EN || Band != BAND5_350MHz)
|
|
|
|
{
|
2023-09-25 17:08:21 +00:00
|
|
|
if (Band > BAND7_470MHz)
|
2023-09-09 07:03:56 +00:00
|
|
|
Band = BAND1_50MHz;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
Band = BAND6_400MHz;
|
|
|
|
gTxVfo->Band = Band;
|
|
|
|
|
|
|
|
gEeprom.ScreenChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
|
|
|
|
gEeprom.FreqChannel[Vfo] = FREQ_CHANNEL_FIRST + Band;
|
2023-09-25 17:08:21 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
gRequestSaveVFO = true;
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
2023-09-14 19:15:35 +00:00
|
|
|
|
|
|
|
if (beep)
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_2:
|
|
|
|
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_A)
|
|
|
|
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_B;
|
|
|
|
else
|
|
|
|
if (gEeprom.CROSS_BAND_RX_TX == CROSS_BAND_CHAN_B)
|
|
|
|
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_CHAN_A;
|
|
|
|
else
|
|
|
|
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_A)
|
|
|
|
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_B;
|
|
|
|
else
|
|
|
|
if (gEeprom.DUAL_WATCH == DUAL_WATCH_CHAN_B)
|
|
|
|
gEeprom.DUAL_WATCH = DUAL_WATCH_CHAN_A;
|
|
|
|
else
|
|
|
|
gEeprom.TX_CHANNEL = (Vfo == 0);
|
|
|
|
|
|
|
|
gRequestSaveSettings = 1;
|
|
|
|
gFlagReconfigureVfos = true;
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
2023-09-14 19:15:35 +00:00
|
|
|
|
|
|
|
if (beep)
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_3:
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_NOAA
|
2023-09-09 07:03:56 +00:00
|
|
|
if (gEeprom.VFO_OPEN && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
#else
|
|
|
|
if (gEeprom.VFO_OPEN)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
uint8_t Channel;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
{
|
|
|
|
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
|
|
|
|
#endif
|
|
|
|
gRequestSaveVFO = true;
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
|
|
break;
|
|
|
|
}
|
2023-09-12 10:01:34 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
Channel = RADIO_FindNextChannel(gEeprom.MrChannel[gEeprom.TX_CHANNEL], 1, false, 0);
|
|
|
|
if (Channel != 0xFF)
|
|
|
|
{
|
|
|
|
gEeprom.ScreenChannel[Vfo] = Channel;
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
|
|
|
|
AUDIO_SetDigitVoice(1, Channel + 1);
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)0xFE;
|
|
|
|
#endif
|
|
|
|
gRequestSaveVFO = true;
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-09-12 10:01:34 +00:00
|
|
|
|
2023-09-14 19:15:35 +00:00
|
|
|
if (beep)
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_4:
|
|
|
|
gWasFKeyPressed = false;
|
|
|
|
gFlagStartScan = true;
|
|
|
|
gScanSingleFrequency = false;
|
|
|
|
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
|
|
|
|
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
2023-09-18 10:29:28 +00:00
|
|
|
gUpdateStatus = true;
|
2023-09-14 19:15:35 +00:00
|
|
|
|
|
|
|
if (beep)
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_5:
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_NOAA
|
2023-09-09 07:03:56 +00:00
|
|
|
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
2023-09-12 10:01:34 +00:00
|
|
|
{
|
2023-09-09 07:03:56 +00:00
|
|
|
gEeprom.ScreenChannel[Vfo] = gEeprom.NoaaChannel[gEeprom.TX_CHANNEL];
|
2023-09-12 10:01:34 +00:00
|
|
|
}
|
2023-09-09 07:03:56 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
gEeprom.ScreenChannel[Vfo] = gEeprom.FreqChannel[gEeprom.TX_CHANNEL];
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
gAnotherVoiceID = VOICE_ID_FREQUENCY_MODE;
|
|
|
|
#endif
|
|
|
|
}
|
2023-09-15 21:48:06 +00:00
|
|
|
gRequestSaveVFO = true;
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
2023-09-17 23:48:40 +00:00
|
|
|
#else
|
2023-09-24 00:36:43 +00:00
|
|
|
// toggle scanlist-1
|
|
|
|
if (gScreenToDisplay != DISPLAY_SCANNER)
|
|
|
|
{
|
|
|
|
gTxVfo->SCANLIST1_PARTICIPATION = gTxVfo->SCANLIST1_PARTICIPATION ? 0 : 1;
|
|
|
|
SETTINGS_UpdateChannel(gTxVfo->CHANNEL_SAVE, gTxVfo, true);
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_1;
|
|
|
|
gFlagResetVfos = true;
|
|
|
|
}
|
2023-09-09 07:03:56 +00:00
|
|
|
#endif
|
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_6:
|
|
|
|
ACTION_Power();
|
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_7:
|
|
|
|
ACTION_Vox();
|
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_8:
|
|
|
|
gTxVfo->FrequencyReverse = gTxVfo->FrequencyReverse == false;
|
|
|
|
gRequestSaveChannel = 1;
|
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
case KEY_9:
|
|
|
|
if (RADIO_CheckValidChannel(gEeprom.CHAN_1_CALL, false, 0))
|
|
|
|
{
|
|
|
|
gEeprom.MrChannel[Vfo] = gEeprom.CHAN_1_CALL;
|
|
|
|
gEeprom.ScreenChannel[Vfo] = gEeprom.CHAN_1_CALL;
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
AUDIO_SetVoiceID(0, VOICE_ID_CHANNEL_MODE);
|
|
|
|
AUDIO_SetDigitVoice(1, gEeprom.CHAN_1_CALL + 1);
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)0xFE;
|
|
|
|
#endif
|
|
|
|
gRequestSaveVFO = true;
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2023-09-14 19:15:35 +00:00
|
|
|
if (beep)
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
2023-09-09 07:03:56 +00:00
|
|
|
break;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
default:
|
|
|
|
gUpdateStatus = true;
|
|
|
|
gWasFKeyPressed = false;
|
2023-09-14 19:15:35 +00:00
|
|
|
|
|
|
|
if (beep)
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
2023-09-09 07:03:56 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
static void MAIN_Key_DIGITS(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|
|
|
{
|
|
|
|
if (bKeyHeld)
|
|
|
|
{ // key held down
|
|
|
|
|
|
|
|
#ifdef ENABLE_MAIN_KEY_HOLD
|
|
|
|
if (bKeyPressed)
|
|
|
|
{
|
|
|
|
if (gScreenToDisplay == DISPLAY_MAIN)
|
2023-09-26 23:26:58 +00:00
|
|
|
{
|
2023-09-14 18:38:28 +00:00
|
|
|
if (gInputBoxIndex > 0)
|
2023-09-14 18:53:01 +00:00
|
|
|
{ // delete any inputted chars
|
2023-09-14 19:43:02 +00:00
|
|
|
gInputBoxIndex = 0;
|
2023-09-14 18:38:28 +00:00
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
}
|
2023-09-15 14:36:43 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
gWasFKeyPressed = false;
|
|
|
|
gUpdateStatus = true;
|
2023-09-15 14:36:43 +00:00
|
|
|
|
2023-09-14 19:15:35 +00:00
|
|
|
processFKeyFunction(Key, false);
|
2023-09-14 18:38:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-14 19:43:02 +00:00
|
|
|
#ifdef ENABLE_MAIN_KEY_HOLD
|
|
|
|
if (bKeyPressed)
|
|
|
|
{ // key is pressed
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL; // beep when key is pressed
|
|
|
|
return; // don't use the key till it's released
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
if (!bKeyPressed)
|
|
|
|
return;
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-14 19:43:02 +00:00
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
#endif
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
if (!gWasFKeyPressed)
|
2023-09-14 19:15:35 +00:00
|
|
|
{ // F-key wasn't pressed
|
|
|
|
|
2023-09-26 23:26:58 +00:00
|
|
|
const uint8_t Vfo = gEeprom.TX_CHANNEL;
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-16 16:16:36 +00:00
|
|
|
gKeyInputCountdown = key_input_timeout_500ms;
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
INPUTBOX_Append(Key);
|
|
|
|
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
|
|
|
|
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
2023-09-27 20:28:30 +00:00
|
|
|
{ // user is entering channel number
|
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
uint16_t Channel;
|
|
|
|
|
|
|
|
if (gInputBoxIndex != 3)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_VOICE
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
|
|
#endif
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gInputBoxIndex = 0;
|
|
|
|
|
|
|
|
Channel = ((gInputBox[0] * 100) + (gInputBox[1] * 10) + gInputBox[2]) - 1;
|
2023-09-20 07:29:11 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
if (!RADIO_CheckValidChannel(Channel, false, 0))
|
|
|
|
{
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef ENABLE_VOICE
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
|
|
#endif
|
2023-09-27 20:28:30 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
gEeprom.MrChannel[Vfo] = (uint8_t)Channel;
|
|
|
|
gEeprom.ScreenChannel[Vfo] = (uint8_t)Channel;
|
|
|
|
gRequestSaveVFO = true;
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
2023-09-27 20:28:30 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-27 20:28:30 +00:00
|
|
|
// #ifdef ENABLE_NOAA
|
|
|
|
// if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
// #endif
|
|
|
|
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
{ // user is entering frequency
|
2023-09-27 21:14:39 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
uint32_t Frequency;
|
|
|
|
|
|
|
|
if (gInputBoxIndex < 6)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_VOICE
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
|
|
#endif
|
2023-09-27 20:28:30 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gInputBoxIndex = 0;
|
|
|
|
|
|
|
|
NUMBER_Get(gInputBox, &Frequency);
|
|
|
|
|
2023-09-27 21:14:39 +00:00
|
|
|
if (Frequency < LowerLimitFrequencyBandTable[0])
|
|
|
|
{
|
|
|
|
Frequency = LowerLimitFrequencyBandTable[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (Frequency >= bx_stop1_Hz && Frequency < bx_start2_Hz)
|
|
|
|
{ // move the frequency to the closest limit
|
|
|
|
const uint32_t center = (bx_stop1_Hz + bx_start2_Hz) / 2;
|
|
|
|
Frequency = (Frequency < center) ? bx_stop1_Hz - 10 : bx_start2_Hz;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (Frequency > UpperLimitFrequencyBandTable[6])
|
|
|
|
{
|
|
|
|
Frequency = UpperLimitFrequencyBandTable[6];
|
|
|
|
}
|
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < 7; i++)
|
|
|
|
{
|
|
|
|
if (Frequency >= LowerLimitFrequencyBandTable[i] && Frequency <= UpperLimitFrequencyBandTable[i])
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_VOICE
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if (gTxVfo->Band != i)
|
|
|
|
{
|
|
|
|
gTxVfo->Band = i;
|
|
|
|
gEeprom.ScreenChannel[Vfo] = i + FREQ_CHANNEL_FIRST;
|
|
|
|
gEeprom.FreqChannel[Vfo] = i + FREQ_CHANNEL_FIRST;
|
|
|
|
|
|
|
|
SETTINGS_SaveVfoIndices();
|
|
|
|
|
|
|
|
RADIO_ConfigureChannel(Vfo, 2);
|
|
|
|
}
|
|
|
|
|
2023-09-27 21:14:39 +00:00
|
|
|
// Frequency += 75; // is this for rounding
|
|
|
|
Frequency += gTxVfo->StepFrequency / 2; // this is though
|
|
|
|
|
2023-09-25 17:08:21 +00:00
|
|
|
gTxVfo->freq_config_RX.Frequency = FREQUENCY_FloorToStep(Frequency, gTxVfo->StepFrequency, LowerLimitFrequencyBandTable[gTxVfo->Band]);
|
2023-09-14 18:38:28 +00:00
|
|
|
|
|
|
|
gRequestSaveChannel = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2023-09-27 20:28:30 +00:00
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
}
|
|
|
|
#ifdef ENABLE_NOAA
|
|
|
|
else
|
2023-09-27 20:28:30 +00:00
|
|
|
if (IS_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
{ // user is entering NOAA channel
|
|
|
|
|
2023-09-14 18:38:28 +00:00
|
|
|
uint8_t Channel;
|
|
|
|
|
|
|
|
if (gInputBoxIndex != 2)
|
|
|
|
{
|
|
|
|
#ifdef ENABLE_VOICE
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
|
|
#endif
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gInputBoxIndex = 0;
|
|
|
|
|
|
|
|
Channel = (gInputBox[0] * 10) + gInputBox[1];
|
2023-09-20 07:29:11 +00:00
|
|
|
if (Channel >= 1 && Channel <= ARRAY_SIZE(NoaaFrequencyTable))
|
2023-09-14 18:38:28 +00:00
|
|
|
{
|
|
|
|
Channel += NOAA_CHANNEL_FIRST;
|
|
|
|
#ifdef ENABLE_VOICE
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)Key;
|
|
|
|
#endif
|
|
|
|
gEeprom.NoaaChannel[Vfo] = Channel;
|
|
|
|
gEeprom.ScreenChannel[Vfo] = Channel;
|
|
|
|
gRequestSaveVFO = true;
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gWasFKeyPressed = false;
|
|
|
|
gUpdateStatus = true;
|
|
|
|
|
2023-09-14 19:15:35 +00:00
|
|
|
processFKeyFunction(Key, true);
|
2023-09-14 18:38:28 +00:00
|
|
|
}
|
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
static void MAIN_Key_EXIT(bool bKeyPressed, bool bKeyHeld)
|
|
|
|
{
|
|
|
|
if (!bKeyHeld && bKeyPressed)
|
|
|
|
{
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
2023-09-10 23:02:57 +00:00
|
|
|
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_FMRADIO
|
|
|
|
if (!gFmRadioMode)
|
|
|
|
#endif
|
2023-09-09 07:03:56 +00:00
|
|
|
{
|
|
|
|
if (gScanState == SCAN_OFF)
|
|
|
|
{
|
|
|
|
if (gInputBoxIndex == 0)
|
|
|
|
return;
|
|
|
|
gInputBox[--gInputBoxIndex] = 10;
|
2023-09-10 23:02:57 +00:00
|
|
|
|
2023-09-16 16:16:36 +00:00
|
|
|
gKeyInputCountdown = key_input_timeout_500ms;
|
2023-09-15 14:36:43 +00:00
|
|
|
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
if (gInputBoxIndex == 0)
|
|
|
|
gAnotherVoiceID = VOICE_ID_CANCEL;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
SCANNER_Stop();
|
2023-09-10 23:02:57 +00:00
|
|
|
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
gAnotherVoiceID = VOICE_ID_SCANNING_STOP;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
return;
|
|
|
|
}
|
2023-09-10 23:02:57 +00:00
|
|
|
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_FMRADIO
|
|
|
|
ACTION_FM();
|
|
|
|
#endif
|
2023-09-26 23:26:58 +00:00
|
|
|
|
2023-09-15 14:36:43 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bKeyHeld && bKeyPressed)
|
|
|
|
{
|
|
|
|
if (gInputBoxIndex > 0)
|
|
|
|
{ // cancel key input mode (channel/frequency entry)
|
|
|
|
gDTMF_InputMode = false;
|
|
|
|
gDTMF_InputIndex = 0;
|
|
|
|
memset(gDTMF_String, 0, sizeof(gDTMF_String));
|
|
|
|
gInputBoxIndex = 0;
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
}
|
2023-09-09 07:03:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-26 23:26:58 +00:00
|
|
|
static void MAIN_Key_MENU(const bool bKeyPressed, const bool bKeyHeld)
|
2023-09-09 07:03:56 +00:00
|
|
|
{
|
2023-09-26 23:26:58 +00:00
|
|
|
if (bKeyHeld)
|
|
|
|
{ // key held down (long press)
|
|
|
|
|
|
|
|
if (bKeyPressed)
|
|
|
|
{
|
|
|
|
if (gScreenToDisplay == DISPLAY_MAIN)
|
|
|
|
{
|
|
|
|
if (gInputBoxIndex > 0)
|
|
|
|
{ // delete any inputted chars
|
|
|
|
gInputBoxIndex = 0;
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
gWasFKeyPressed = false;
|
|
|
|
gUpdateStatus = true;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// TODO: long press M-key
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef ENABLE_COPY_CHAN_TO_VFO
|
|
|
|
{ // copy channel to VFO
|
|
|
|
int channel = -1;
|
|
|
|
int vfo = -1;
|
|
|
|
//int selected = -1;
|
|
|
|
|
|
|
|
if (IS_FREQ_CHANNEL(gRxVfo->CHANNEL_SAVE))
|
|
|
|
{ // VFO mode
|
|
|
|
if (IS_MR_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
{ // other VFO is in channel mode
|
|
|
|
channel = gTxVfo->CHANNEL_SAVE;
|
|
|
|
vfo = gRxVfo->CHANNEL_SAVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
if (IS_FREQ_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
{ // VFO mode
|
|
|
|
if (IS_MR_CHANNEL(gRxVfo->CHANNEL_SAVE))
|
|
|
|
{ // other VFO is in channel mode
|
|
|
|
channel = gRxVfo->CHANNEL_SAVE;
|
|
|
|
vfo = gTxVfo->CHANNEL_SAVE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (channel >= 0 && vfo >= 0)
|
|
|
|
{ // copy the channel into the VFO
|
|
|
|
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//gEeprom.RX_CHANNEL = () & 1; // swap to the VFO
|
|
|
|
|
|
|
|
|
|
|
|
// gRequestSaveVFO = true;
|
|
|
|
// gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
|
|
// gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!bKeyPressed)
|
2023-09-09 07:03:56 +00:00
|
|
|
{
|
|
|
|
bool bFlag;
|
|
|
|
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
bFlag = (gInputBoxIndex == 0);
|
|
|
|
gInputBoxIndex = 0;
|
|
|
|
if (bFlag)
|
|
|
|
{
|
|
|
|
gFlagRefreshSetting = true;
|
|
|
|
gRequestDisplayScreen = DISPLAY_MENU;
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
gAnotherVoiceID = VOICE_ID_MENU;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void MAIN_Key_STAR(bool bKeyPressed, bool bKeyHeld)
|
|
|
|
{
|
|
|
|
if (gInputBoxIndex)
|
|
|
|
{
|
|
|
|
if (!bKeyHeld && bKeyPressed)
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (bKeyHeld || !bKeyPressed)
|
|
|
|
{
|
|
|
|
if (bKeyHeld || bKeyPressed)
|
|
|
|
{
|
|
|
|
if (!bKeyHeld)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!bKeyPressed)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ACTION_Scan(false);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_NOAA
|
2023-09-09 07:03:56 +00:00
|
|
|
if (gScanState == SCAN_OFF && IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
#else
|
|
|
|
if (gScanState == SCAN_OFF)
|
|
|
|
#endif
|
|
|
|
{
|
2023-09-16 16:16:36 +00:00
|
|
|
gKeyInputCountdown = key_input_timeout_500ms;
|
2023-09-09 07:03:56 +00:00
|
|
|
gDTMF_InputMode = true;
|
2023-09-17 15:51:35 +00:00
|
|
|
memmove(gDTMF_InputBox, gDTMF_String, sizeof(gDTMF_InputBox));
|
2023-09-09 07:03:56 +00:00
|
|
|
gDTMF_InputIndex = 0;
|
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
if (!gWasFKeyPressed)
|
|
|
|
{
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gWasFKeyPressed = false;
|
|
|
|
gUpdateStatus = true;
|
|
|
|
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_NOAA
|
2023-09-09 07:03:56 +00:00
|
|
|
if (IS_NOT_NOAA_CHANNEL(gTxVfo->CHANNEL_SAVE))
|
|
|
|
{
|
|
|
|
gFlagStartScan = true;
|
|
|
|
gScanSingleFrequency = true;
|
|
|
|
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
|
|
|
|
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
gFlagStartScan = true;
|
|
|
|
gScanSingleFrequency = true;
|
|
|
|
gBackupCROSS_BAND_RX_TX = gEeprom.CROSS_BAND_RX_TX;
|
|
|
|
gEeprom.CROSS_BAND_RX_TX = CROSS_BAND_OFF;
|
|
|
|
#endif
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
gPttWasReleased = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void MAIN_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction)
|
|
|
|
{
|
|
|
|
uint8_t Channel = gEeprom.ScreenChannel[gEeprom.TX_CHANNEL];
|
|
|
|
|
|
|
|
if (bKeyHeld || !bKeyPressed)
|
|
|
|
{
|
2023-09-27 20:28:30 +00:00
|
|
|
if (gInputBoxIndex > 0)
|
2023-09-09 07:03:56 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (!bKeyPressed)
|
|
|
|
{
|
|
|
|
if (!bKeyHeld)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (IS_FREQ_CHANNEL(Channel))
|
|
|
|
return;
|
|
|
|
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
AUDIO_SetDigitVoice(0, gTxVfo->CHANNEL_SAVE + 1);
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)0xFE;
|
|
|
|
#endif
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-09-27 20:28:30 +00:00
|
|
|
if (gInputBoxIndex > 0)
|
2023-09-09 07:03:56 +00:00
|
|
|
{
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
2023-09-27 20:28:30 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (gScanState == SCAN_OFF)
|
|
|
|
{
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_NOAA
|
2023-09-09 07:03:56 +00:00
|
|
|
if (IS_NOT_NOAA_CHANNEL(Channel))
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
uint8_t Next;
|
|
|
|
|
|
|
|
if (IS_FREQ_CHANNEL(Channel))
|
2023-09-27 20:28:30 +00:00
|
|
|
{ // step/down in frequency
|
|
|
|
const uint32_t frequency = APP_SetFrequencyByStep(gTxVfo, Direction);
|
|
|
|
|
|
|
|
if (RX_FREQUENCY_Check(frequency) < 0)
|
|
|
|
{ // frequency not allowed
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
gTxVfo->freq_config_RX.Frequency = frequency;
|
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
gRequestSaveChannel = 1;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Next = RADIO_FindNextChannel(Channel + Direction, Direction, false, 0);
|
|
|
|
if (Next == 0xFF)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (Channel == Next)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gEeprom.MrChannel[gEeprom.TX_CHANNEL] = Next;
|
|
|
|
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Next;
|
|
|
|
|
|
|
|
if (!bKeyHeld)
|
|
|
|
{
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_VOICE
|
2023-09-09 07:03:56 +00:00
|
|
|
AUDIO_SetDigitVoice(0, Next + 1);
|
|
|
|
gAnotherVoiceID = (VOICE_ID_t)0xFE;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_NOAA
|
2023-09-09 07:03:56 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
Channel = NOAA_CHANNEL_FIRST + NUMBER_AddWithWraparound(gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] - NOAA_CHANNEL_FIRST, Direction, 0, 9);
|
|
|
|
gEeprom.NoaaChannel[gEeprom.TX_CHANNEL] = Channel;
|
|
|
|
gEeprom.ScreenChannel[gEeprom.TX_CHANNEL] = Channel;
|
|
|
|
}
|
|
|
|
#endif
|
2023-09-14 18:38:28 +00:00
|
|
|
|
2023-09-09 07:03:56 +00:00
|
|
|
gRequestSaveVFO = true;
|
|
|
|
gVfoConfigureMode = VFO_CONFIGURE_RELOAD;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
CHANNEL_Next(false, Direction);
|
|
|
|
|
|
|
|
gPttWasReleased = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
void MAIN_ProcessKeys(KEY_Code_t Key, bool bKeyPressed, bool bKeyHeld)
|
|
|
|
{
|
2023-09-14 08:56:30 +00:00
|
|
|
#ifdef ENABLE_FMRADIO
|
|
|
|
if (gFmRadioMode && Key != KEY_PTT && Key != KEY_EXIT)
|
|
|
|
{
|
|
|
|
if (!bKeyHeld && bKeyPressed)
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#endif
|
2023-09-09 07:03:56 +00:00
|
|
|
|
2023-09-15 14:36:43 +00:00
|
|
|
if (gDTMF_InputMode && bKeyPressed)
|
2023-09-09 07:03:56 +00:00
|
|
|
{
|
2023-09-15 14:36:43 +00:00
|
|
|
if (!bKeyHeld)
|
2023-09-09 07:03:56 +00:00
|
|
|
{
|
2023-09-15 14:36:43 +00:00
|
|
|
const char Character = DTMF_GetCharacter(Key);
|
|
|
|
if (Character != 0xFF)
|
|
|
|
{ // add key to DTMF string
|
|
|
|
DTMF_Append(Character);
|
|
|
|
|
2023-09-16 16:16:36 +00:00
|
|
|
gKeyInputCountdown = key_input_timeout_500ms;
|
2023-09-15 14:36:43 +00:00
|
|
|
gRequestDisplayScreen = DISPLAY_MAIN;
|
|
|
|
gPttWasReleased = true;
|
|
|
|
gBeepToPlay = BEEP_1KHZ_60MS_OPTIONAL;
|
|
|
|
return;
|
|
|
|
}
|
2023-09-09 07:03:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO: ???
|
2023-09-15 14:36:43 +00:00
|
|
|
if (Key > KEY_PTT)
|
2023-09-09 07:03:56 +00:00
|
|
|
{
|
|
|
|
Key = KEY_SIDE2;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (Key)
|
|
|
|
{
|
|
|
|
case KEY_0:
|
|
|
|
case KEY_1:
|
|
|
|
case KEY_2:
|
|
|
|
case KEY_3:
|
|
|
|
case KEY_4:
|
|
|
|
case KEY_5:
|
|
|
|
case KEY_6:
|
|
|
|
case KEY_7:
|
|
|
|
case KEY_8:
|
|
|
|
case KEY_9:
|
|
|
|
MAIN_Key_DIGITS(Key, bKeyPressed, bKeyHeld);
|
|
|
|
break;
|
|
|
|
case KEY_MENU:
|
|
|
|
MAIN_Key_MENU(bKeyPressed, bKeyHeld);
|
|
|
|
break;
|
|
|
|
case KEY_UP:
|
|
|
|
MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, 1);
|
|
|
|
break;
|
|
|
|
case KEY_DOWN:
|
|
|
|
MAIN_Key_UP_DOWN(bKeyPressed, bKeyHeld, -1);
|
|
|
|
break;
|
|
|
|
case KEY_EXIT:
|
|
|
|
MAIN_Key_EXIT(bKeyPressed, bKeyHeld);
|
|
|
|
break;
|
|
|
|
case KEY_STAR:
|
|
|
|
MAIN_Key_STAR(bKeyPressed, bKeyHeld);
|
|
|
|
break;
|
|
|
|
case KEY_F:
|
|
|
|
GENERIC_Key_F(bKeyPressed, bKeyHeld);
|
|
|
|
break;
|
|
|
|
case KEY_PTT:
|
|
|
|
GENERIC_Key_PTT(bKeyPressed);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (!bKeyHeld && bKeyPressed)
|
|
|
|
gBeepToPlay = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|