0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-04-28 22:31:25 +03:00

518 lines
12 KiB
C
Raw Normal View History

2023-09-09 08:03:56 +01: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.
*/
2023-09-30 11:22:19 +01:00
#include "app/dtmf.h"
2023-09-09 08:03:56 +01:00
#include "app/generic.h"
#include "app/scanner.h"
#include "audio.h"
#include "driver/bk4819.h"
#include "frequencies.h"
#include "misc.h"
#include "radio.h"
#include "settings.h"
#include "ui/inputbox.h"
#include "ui/ui.h"
dcs_code_type_t g_scan_css_result_type;
uint8_t g_scan_css_result_code;
2023-10-08 20:23:37 +01:00
bool g_flag_start_scan;
bool g_flag_stop_scan;
bool g_scan_single_frequency;
scan_edit_state_t g_scanner_edit_state;
uint8_t g_scan_channel;
uint32_t g_scan_frequency;
bool g_scan_pause_mode;
scan_css_state_t g_scan_css_state;
2023-10-08 20:23:37 +01:00
volatile bool g_schedule_scan_listen = true;
volatile uint16_t g_scan_pause_delay_in_10ms;
uint16_t g_scan_freq_css_timer_10ms;
uint8_t g_scan_hit_count;
bool g_scan_use_css_result;
scan_state_dir_t g_scan_state_dir;
bool g_scan_keep_frequency;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
static void SCANNER_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
if (key_held || !key_pressed)
return;
if (g_scanner_edit_state == SCAN_EDIT_STATE_BUSY)
2023-09-09 08:03:56 +01:00
{
uint16_t Channel;
2023-09-09 08:03:56 +01:00
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
2023-10-05 22:44:44 +01:00
INPUTBOX_Append(Key);
2023-10-05 22:44:44 +01:00
g_request_display_screen = DISPLAY_SCANNER;
2023-09-09 08:03:56 +01:00
if (g_input_box_index < 3)
{
#ifdef ENABLE_VOICE
g_another_voice_id = (voice_id_t)Key;
#endif
return;
}
2023-09-09 08:03:56 +01:00
g_input_box_index = 0;
2023-09-09 08:03:56 +01:00
Channel = ((g_input_box[0] * 100) + (g_input_box[1] * 10) + g_input_box[2]) - 1;
if (Channel <= USER_CHANNEL_LAST)
{
#ifdef ENABLE_VOICE
g_another_voice_id = (voice_id_t)Key;
#endif
g_show_chan_prefix = RADIO_CheckValidChannel(Channel, false, 0);
g_scan_channel = (uint8_t)Channel;
return;
2023-09-09 08:03:56 +01:00
}
}
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
static void SCANNER_Key_EXIT(bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
if (key_held || !key_pressed)
return;
2023-09-09 08:03:56 +01:00
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
2023-09-09 08:03:56 +01:00
switch (g_scanner_edit_state)
{
case SCAN_EDIT_STATE_NONE:
g_request_display_screen = DISPLAY_MAIN;
2023-09-11 00:02:57 +01:00
g_eeprom.cross_vfo_rx_tx = g_backup_cross_vfo_rx_tx;
g_update_status = true;
g_flag_stop_scan = true;
g_vfo_configure_mode = VFO_CONFIGURE_RELOAD;
g_flag_reset_vfos = true;
#ifdef ENABLE_VOICE
g_another_voice_id = VOICE_ID_CANCEL;
#endif
break;
2023-09-09 08:03:56 +01:00
case SCAN_EDIT_STATE_BUSY:
if (g_input_box_index > 0)
{
g_input_box[--g_input_box_index] = 10;
g_request_display_screen = DISPLAY_SCANNER;
2023-09-09 08:03:56 +01:00
break;
}
// Fallthrough
case SCAN_EDIT_STATE_DONE:
g_scanner_edit_state = SCAN_EDIT_STATE_NONE;
#ifdef ENABLE_VOICE
g_another_voice_id = VOICE_ID_CANCEL;
#endif
g_request_display_screen = DISPLAY_SCANNER;
break;
2023-09-09 08:03:56 +01:00
}
}
2023-10-08 20:23:37 +01:00
static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
uint8_t Channel;
2023-10-08 20:23:37 +01:00
if (key_held)
2023-09-09 08:03:56 +01:00
return;
2023-10-08 20:23:37 +01:00
if (!key_pressed)
2023-09-09 08:03:56 +01:00
return;
if (g_scan_css_state == SCAN_CSS_STATE_OFF && !g_scan_single_frequency)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
2023-09-09 08:03:56 +01:00
return;
}
if (g_scan_css_state == SCAN_CSS_STATE_SCANNING)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (g_scan_single_frequency)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
2023-09-09 08:03:56 +01:00
return;
}
}
if (g_scan_css_state == SCAN_CSS_STATE_FAILED)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
2023-09-09 08:03:56 +01:00
return;
}
2023-10-08 20:23:37 +01:00
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
2023-09-09 08:03:56 +01:00
switch (g_scanner_edit_state)
2023-09-09 08:03:56 +01:00
{
2023-10-07 15:12:53 +01:00
case SCAN_EDIT_STATE_NONE:
2023-10-08 20:23:37 +01:00
if (!g_scan_single_frequency)
2023-09-09 08:03:56 +01:00
{
2023-10-07 15:12:53 +01:00
#if 0
uint32_t Freq250 = FREQUENCY_FloorToStep(g_scan_frequency, 250, 0);
uint32_t Freq625 = FREQUENCY_FloorToStep(g_scan_frequency, 625, 0);
2023-10-07 15:12:53 +01:00
int16_t Delta250 = (int16_t)g_scan_frequency - (int16_t)Freq250;
2023-10-07 15:12:53 +01:00
int16_t Delta625;
if (125 < Delta250)
{
Delta250 = 250 - Delta250;
Freq250 += 250;
}
Delta625 = (int16_t)g_scan_frequency - (int16_t)Freq625;
2023-10-07 15:12:53 +01:00
if (312 < Delta625)
{
Delta625 = 625 - Delta625;
Freq625 += 625;
}
if (Delta625 < Delta250)
{
2023-10-08 20:23:37 +01:00
g_step_setting = STEP_6_25kHz;
g_scan_frequency = Freq625;
2023-10-07 15:12:53 +01:00
}
else
{
2023-10-08 20:23:37 +01:00
g_step_setting = STEP_2_5kHz;
g_scan_frequency = Freq250;
2023-10-07 15:12:53 +01:00
}
#else
#ifdef ENABLE_1250HZ_STEP
2023-10-08 17:14:13 +01:00
const step_setting_t small_step = STEP_1_25kHz;
const step_setting_t big_step = STEP_6_25kHz;
2023-10-07 15:12:53 +01:00
#else
2023-10-08 17:14:13 +01:00
const step_setting_t small_step = STEP_2_5kHz;
const step_setting_t big_step = STEP_6_25kHz;
2023-10-07 15:12:53 +01:00
#endif
2023-10-08 20:23:37 +01:00
const uint32_t small_step_freq = STEP_FREQ_TABLE[small_step];
const uint32_t big_step_freq = STEP_FREQ_TABLE[big_step];
2023-10-07 15:12:53 +01:00
uint32_t freq_small_step = FREQUENCY_FloorToStep(g_scan_frequency, small_step_freq, 0);
uint32_t freq_big_step = FREQUENCY_FloorToStep(g_scan_frequency, big_step_freq, 0);
2023-10-07 15:12:53 +01:00
int32_t delta_small_step = (int32_t)g_scan_frequency - freq_small_step;
int32_t delta_big_step = (int32_t)g_scan_frequency - freq_big_step;
2023-10-07 15:12:53 +01:00
if (delta_small_step > 125)
{
2023-10-08 20:23:37 +01:00
delta_small_step = STEP_FREQ_TABLE[small_step] - delta_small_step;
2023-10-07 15:12:53 +01:00
freq_big_step += small_step_freq;
}
delta_big_step = (int32_t)g_scan_frequency - freq_big_step;
2023-10-07 15:12:53 +01:00
if (delta_big_step > 312)
{
delta_big_step = big_step_freq - delta_big_step;
freq_big_step += big_step_freq;
}
if (delta_small_step >= delta_big_step)
{
2023-10-08 20:23:37 +01:00
g_step_setting = small_step;
g_scan_frequency = freq_small_step;
2023-10-07 15:12:53 +01:00
}
else
{
2023-10-08 20:23:37 +01:00
g_step_setting = big_step;
g_scan_frequency = freq_big_step;
2023-10-07 15:12:53 +01:00
}
#endif
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
if (g_tx_vfo->channel_save <= USER_CHANNEL_LAST)
2023-09-09 08:03:56 +01:00
{
g_scanner_edit_state = SCAN_EDIT_STATE_BUSY;
g_scan_channel = g_tx_vfo->channel_save;
2023-10-08 20:23:37 +01:00
g_show_chan_prefix = RADIO_CheckValidChannel(g_tx_vfo->channel_save, false, 0);
2023-09-09 08:03:56 +01:00
}
else
{
g_scanner_edit_state = SCAN_EDIT_STATE_DONE;
2023-09-09 08:03:56 +01:00
}
g_scan_css_state = SCAN_CSS_STATE_FOUND;
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_VOICE
2023-10-08 17:14:13 +01:00
g_another_voice_id = VOICE_ID_MEMORY_CHANNEL;
2023-09-09 08:03:56 +01:00
#endif
2023-10-07 15:12:53 +01:00
2023-10-08 20:23:37 +01:00
g_request_display_screen = DISPLAY_SCANNER;
g_update_status = true;
2023-09-09 08:03:56 +01:00
break;
2023-10-07 15:12:53 +01:00
case SCAN_EDIT_STATE_BUSY:
2023-10-08 20:23:37 +01:00
if (g_input_box_index == 0)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
g_request_display_screen = DISPLAY_SCANNER;
g_scanner_edit_state = SCAN_EDIT_STATE_DONE;
2023-09-09 08:03:56 +01:00
}
break;
2023-10-07 15:12:53 +01:00
case SCAN_EDIT_STATE_DONE:
2023-10-08 20:23:37 +01:00
if (!g_scan_single_frequency)
2023-09-09 08:03:56 +01:00
{
RADIO_InitInfo(g_tx_vfo, g_tx_vfo->channel_save, g_scan_frequency);
2023-09-09 08:03:56 +01:00
if (g_scan_use_css_result)
2023-09-09 08:03:56 +01:00
{
g_tx_vfo->freq_config_rx.code_type = g_scan_css_result_type;
g_tx_vfo->freq_config_rx.code = g_scan_css_result_code;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
g_tx_vfo->freq_config_tx = g_tx_vfo->freq_config_rx;
g_tx_vfo->step_setting = g_step_setting;
2023-09-09 08:03:56 +01:00
}
else
{
RADIO_ConfigureChannel(0, VFO_CONFIGURE_RELOAD);
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
2023-09-11 00:02:57 +01:00
g_tx_vfo->freq_config_rx.code_type = g_scan_css_result_type;
g_tx_vfo->freq_config_rx.code = g_scan_css_result_code;
g_tx_vfo->freq_config_tx.code_type = g_scan_css_result_type;
g_tx_vfo->freq_config_tx.code = g_scan_css_result_code;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
if (g_tx_vfo->channel_save <= USER_CHANNEL_LAST)
2023-09-09 08:03:56 +01:00
{
Channel = g_scan_channel;
2023-10-08 17:14:13 +01:00
g_eeprom.user_channel[g_eeprom.tx_vfo] = Channel;
2023-09-09 08:03:56 +01:00
}
else
{
2023-10-08 20:23:37 +01:00
Channel = g_tx_vfo->band + FREQ_CHANNEL_FIRST;
2023-10-08 17:14:13 +01:00
g_eeprom.freq_channel[g_eeprom.tx_vfo] = Channel;
2023-09-09 08:03:56 +01:00
}
g_tx_vfo->channel_save = Channel;
2023-10-08 17:14:13 +01:00
g_eeprom.screen_channel[g_eeprom.tx_vfo] = Channel;
g_request_save_channel = 2;
2023-10-07 15:12:53 +01:00
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_VOICE
2023-10-08 17:14:13 +01:00
g_another_voice_id = VOICE_ID_CONFIRM;
2023-09-09 08:03:56 +01:00
#endif
2023-10-07 15:12:53 +01:00
g_scanner_edit_state = SCAN_EDIT_STATE_NONE;
2023-10-07 15:12:53 +01:00
2023-10-08 20:23:37 +01:00
g_request_display_screen = DISPLAY_SCANNER;
2023-09-09 08:03:56 +01:00
break;
default:
2023-10-08 20:23:37 +01:00
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
2023-09-09 08:03:56 +01:00
break;
}
}
2023-10-08 20:23:37 +01:00
static void SCANNER_Key_STAR(bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
if (key_held || !key_pressed)
return;
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
g_flag_start_scan = true;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
static void SCANNER_Key_UP_DOWN(bool key_pressed, bool pKeyHeld, int8_t Direction)
2023-09-09 08:03:56 +01:00
{
if (pKeyHeld)
{
2023-10-08 20:23:37 +01:00
if (!key_pressed)
2023-09-09 08:03:56 +01:00
return;
}
else
{
2023-10-08 20:23:37 +01:00
if (!key_pressed)
2023-09-09 08:03:56 +01:00
return;
2023-10-08 20:23:37 +01:00
g_input_box_index = 0;
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
2023-09-09 08:03:56 +01:00
}
if (g_scanner_edit_state == SCAN_EDIT_STATE_BUSY)
2023-09-09 08:03:56 +01:00
{
g_scan_channel = NUMBER_AddWithWraparound(g_scan_channel, Direction, 0, USER_CHANNEL_LAST);
g_show_chan_prefix = RADIO_CheckValidChannel(g_scan_channel, false, 0);
2023-10-08 20:23:37 +01:00
g_request_display_screen = DISPLAY_SCANNER;
2023-09-09 08:03:56 +01:00
}
else
2023-10-08 20:23:37 +01:00
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
void SCANNER_ProcessKeys(key_code_t Key, bool key_pressed, bool key_held)
2023-09-09 08:03:56 +01:00
{
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:
2023-10-08 20:23:37 +01:00
SCANNER_Key_DIGITS(Key, key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
case KEY_MENU:
2023-10-08 20:23:37 +01:00
SCANNER_Key_MENU(key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
case KEY_UP:
2023-10-08 20:23:37 +01:00
SCANNER_Key_UP_DOWN(key_pressed, key_held, 1);
2023-09-09 08:03:56 +01:00
break;
case KEY_DOWN:
2023-10-08 20:23:37 +01:00
SCANNER_Key_UP_DOWN(key_pressed, key_held, -1);
2023-09-09 08:03:56 +01:00
break;
case KEY_EXIT:
2023-10-08 20:23:37 +01:00
SCANNER_Key_EXIT(key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
case KEY_STAR:
2023-10-08 20:23:37 +01:00
SCANNER_Key_STAR(key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
case KEY_PTT:
2023-10-08 20:23:37 +01:00
GENERIC_Key_PTT(key_pressed);
2023-09-09 08:03:56 +01:00
break;
default:
2023-10-08 20:23:37 +01:00
if (!key_held && key_pressed)
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
2023-09-09 08:03:56 +01:00
break;
}
}
void SCANNER_Start(void)
{
uint8_t BackupStep;
2023-10-07 10:59:24 +01:00
uint16_t BackupStepFreq;
2023-09-09 08:03:56 +01:00
BK4819_StopScan();
2023-09-11 00:02:57 +01:00
2023-09-09 08:03:56 +01:00
RADIO_SelectVfos();
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_NOAA
2023-10-08 20:23:37 +01:00
if (IS_NOAA_CHANNEL(g_rx_vfo->channel_save))
g_rx_vfo->channel_save = FREQ_CHANNEL_FIRST + BAND6_400MHz;
2023-09-09 08:03:56 +01:00
#endif
2023-10-08 20:23:37 +01:00
BackupStep = g_rx_vfo->step_setting;
BackupStepFreq = g_rx_vfo->step_freq;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
RADIO_InitInfo(g_rx_vfo, g_rx_vfo->channel_save, g_rx_vfo->pRX->frequency);
2023-09-09 08:03:56 +01:00
g_rx_vfo->step_setting = BackupStep;
g_rx_vfo->step_freq = BackupStepFreq;
2023-09-09 08:03:56 +01:00
RADIO_SetupRegisters(true);
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_NOAA
2023-10-08 20:23:37 +01:00
g_is_noaa_mode = false;
2023-09-09 08:03:56 +01:00
#endif
2023-10-08 20:23:37 +01:00
if (g_scan_single_frequency)
2023-09-09 08:03:56 +01:00
{
g_scan_css_state = SCAN_CSS_STATE_SCANNING;
g_scan_frequency = g_rx_vfo->pRX->frequency;
2023-10-08 20:23:37 +01:00
g_step_setting = g_rx_vfo->step_setting;
BK4819_PickRXFilterPathBasedOnFrequency(g_scan_frequency);
BK4819_SetScanFrequency(g_scan_frequency);
2023-09-09 08:03:56 +01:00
}
else
{
g_scan_css_state = SCAN_CSS_STATE_OFF;
g_scan_frequency = 0xFFFFFFFF;
2023-09-09 08:03:56 +01:00
BK4819_PickRXFilterPathBasedOnFrequency(0xFFFFFFFF);
BK4819_EnableFrequencyScan();
}
2023-09-30 11:22:19 +01:00
DTMF_clear_RX();
g_scan_delay_10ms = scan_freq_css_delay_10ms;
g_scan_css_result_code = 0xFF;
g_scan_css_result_type = 0xFF;
g_scan_hit_count = 0;
g_scan_use_css_result = false;
g_CxCSS_tail_found = false;
g_CDCSS_lost = false;
g_CDCSS_code_type = 0;
g_CTCSS_lost = false;
#ifdef ENABLE_VOX
g_vox_lost = false;
#endif
g_squelch_lost = false;
g_scanner_edit_state = SCAN_EDIT_STATE_NONE;
g_scan_freq_css_timer_10ms = 0;
// g_flag_start_scan = false;
2023-10-07 15:12:53 +01:00
2023-10-08 20:23:37 +01:00
g_update_status = true;
2023-09-09 08:03:56 +01:00
}
void SCANNER_Stop(void)
{
2023-10-08 20:23:37 +01:00
const uint8_t Previous = g_restore_channel;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
if (g_scan_state_dir == SCAN_OFF)
return; // but, but, we weren't doing anything !
2023-10-08 20:23:37 +01:00
g_scan_state_dir = SCAN_OFF;
2023-09-09 08:03:56 +01:00
if (!g_scan_keep_frequency)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (g_next_channel <= USER_CHANNEL_LAST)
2023-09-09 08:03:56 +01:00
{
g_eeprom.user_channel[g_eeprom.rx_vfo] = g_restore_channel;
2023-10-08 17:14:13 +01:00
g_eeprom.screen_channel[g_eeprom.rx_vfo] = Previous;
2023-10-08 17:14:13 +01:00
RADIO_ConfigureChannel(g_eeprom.rx_vfo, VFO_CONFIGURE_RELOAD);
2023-09-09 08:03:56 +01:00
}
else
{
2023-10-08 20:23:37 +01:00
g_rx_vfo->freq_config_rx.frequency = g_restore_frequency;
2023-10-08 20:23:37 +01:00
RADIO_ApplyOffset(g_rx_vfo);
RADIO_ConfigureSquelchAndOutputPower(g_rx_vfo);
2023-09-09 08:03:56 +01:00
}
2023-09-09 08:03:56 +01:00
RADIO_SetupRegisters(true);
2023-10-08 20:23:37 +01:00
g_update_display = true;
2023-09-09 08:03:56 +01:00
return;
}
2023-10-08 20:23:37 +01:00
if (g_rx_vfo->channel_save > USER_CHANNEL_LAST)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
RADIO_ApplyOffset(g_rx_vfo);
RADIO_ConfigureSquelchAndOutputPower(g_rx_vfo);
SETTINGS_SaveChannel(g_rx_vfo->channel_save, g_eeprom.rx_vfo, g_rx_vfo, 1);
2023-09-09 08:03:56 +01:00
return;
}
SETTINGS_SaveVfoIndices();
2023-10-08 20:23:37 +01:00
g_update_status = true;
2023-09-09 08:03:56 +01:00
}