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

3035 lines
71 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-10-27 17:27:31 +01:00
#ifdef ENABLE_AM_FIX
#include "am_fix.h"
#endif
2023-09-09 08:03:56 +01:00
#include "app/action.h"
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_AIRCOPY
2023-09-09 08:03:56 +01:00
#include "app/aircopy.h"
#endif
#include "app/app.h"
#include "app/dtmf.h"
#ifdef ENABLE_FMRADIO
2023-09-14 09:56:30 +01:00
#include "app/fm.h"
#endif
2023-09-09 08:03:56 +01:00
#include "app/generic.h"
#include "app/main.h"
#include "app/menu.h"
#include "app/search.h"
2023-09-09 08:03:56 +01:00
#include "app/uart.h"
#include "ARMCM0.h"
#include "audio.h"
#include "board.h"
#include "bsp/dp32g030/gpio.h"
#include "driver/backlight.h"
#ifdef ENABLE_FMRADIO
2023-09-14 09:56:30 +01:00
#include "driver/bk1080.h"
#endif
2023-09-09 08:03:56 +01:00
#include "driver/bk4819.h"
#include "driver/gpio.h"
#include "driver/keyboard.h"
#include "driver/st7565.h"
#include "driver/system.h"
2023-10-27 10:52:32 +01:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
#include "driver/uart.h"
#endif
2023-09-09 08:03:56 +01:00
#include "dtmf.h"
#include "external/printf/printf.h"
#include "frequencies.h"
#ifdef ENABLE_SCAN_IGNORE_LIST
#include "freq_ignore.h"
#endif
2023-09-09 08:03:56 +01:00
#include "functions.h"
#include "helper/battery.h"
2023-10-25 19:26:22 +01:00
#ifdef ENABLE_MDC1200
#include "mdc1200.h"
#endif
2023-09-09 08:03:56 +01:00
#include "misc.h"
2023-11-18 18:44:10 +00:00
#ifdef ENABLE_PANADAPTER
#include "panadapter.h"
#endif
2023-09-09 08:03:56 +01:00
#include "radio.h"
#include "settings.h"
2023-09-16 07:08:18 +01:00
#if defined(ENABLE_OVERLAY)
#include "sram-overlay.h"
#endif
2023-09-09 08:03:56 +01:00
#include "ui/battery.h"
#include "ui/inputbox.h"
#include "ui/main.h"
2023-09-09 08:03:56 +01:00
#include "ui/menu.h"
#include "ui/status.h"
#include "ui/ui.h"
static void APP_process_key(const key_code_t Key, const bool key_pressed, const bool key_held);
2023-09-09 08:03:56 +01:00
2023-11-08 19:07:52 +00:00
static void APP_update_rssi(const int vfo, const bool force)
{
2023-11-03 18:41:54 +00:00
int16_t rssi = BK4819_GetRSSI();
uint8_t glitch = BK4819_GetGlitchIndicator();
uint8_t noise = BK4819_GetExNoiceIndicator();
2023-09-27 17:29:49 +01:00
#ifdef ENABLE_AM_FIX
2023-09-27 17:29:49 +01:00
// add RF gain adjust compensation
2023-11-18 18:44:10 +00:00
#ifdef ENABLE_PANADAPTER
2023-11-19 06:59:38 +00:00
if (!PAN_scanning())
2023-11-18 18:44:10 +00:00
#endif
if (g_current_vfo->channel.mod_mode != MOD_MODE_FM && g_eeprom.config.setting.am_fix)
rssi -= rssi_gain_diff[vfo];
#endif
2023-09-30 11:22:19 +01:00
2023-11-08 19:07:52 +00:00
if (g_current_rssi[vfo] == rssi && !force)
2023-09-27 17:29:49 +01:00
return; // no change
2023-09-30 11:22:19 +01:00
2023-11-03 18:41:54 +00:00
g_current_rssi[vfo] = rssi;
g_current_glitch[vfo] = glitch;
g_current_noise[vfo] = noise;
2023-11-03 18:41:54 +00:00
UI_update_rssi(rssi, glitch, noise, vfo);
2023-11-08 19:07:52 +00:00
g_update_rssi = false;
}
2023-10-23 14:02:54 +01:00
static void APP_check_for_new_receive(void)
2023-09-09 08:03:56 +01:00
{
2023-11-19 06:59:38 +00:00
#ifdef ENABLE_PANADAPTER
if (PAN_scanning())
return;
#endif
2023-10-29 22:33:38 +00:00
if (!g_squelch_open && !g_monitor_enabled)
return;
2023-09-09 08:03:56 +01:00
2023-09-21 23:06:47 +01:00
// squelch is open
if (g_scan_state_dir == SCAN_STATE_DIR_OFF)
2023-09-21 23:06:47 +01:00
{ // not RF scanning
2023-10-08 20:23:37 +01:00
if (g_css_scan_mode != CSS_SCAN_MODE_OFF && g_rx_reception_mode == RX_MODE_NONE)
2023-09-21 23:06:47 +01:00
{ // CTCSS/DTS scanning
2023-11-08 11:27:26 +00:00
g_scan_tick_10ms = scan_pause_code_10ms;
g_scan_pause_time_mode = false;
g_rx_reception_mode = RX_MODE_DETECTED;
2023-09-09 08:03:56 +01:00
}
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.dual_watch == DUAL_WATCH_OFF)
2023-09-21 23:06:47 +01:00
{ // dual watch is disabled
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_NOAA
2023-11-02 10:00:51 +00:00
if (g_noaa_mode)
2023-09-09 08:03:56 +01:00
{
g_noaa_tick_10ms = noaa_tick_3_10ms;
g_schedule_noaa = false;
2023-09-09 08:03:56 +01:00
}
#endif
2023-09-11 00:02:57 +01:00
goto done;
2023-09-09 08:03:56 +01:00
}
2023-09-21 23:06:47 +01:00
// dual watch is enabled and we're RX'ing a signal
2023-10-08 20:23:37 +01:00
if (g_rx_reception_mode != RX_MODE_NONE)
goto done;
2023-11-02 10:00:51 +00:00
g_dual_watch_tick_10ms = g_eeprom.config.setting.scan_hold_time * 50;
g_scan_pause_time_mode = false;
g_update_status = true;
2023-09-09 08:03:56 +01:00
}
else
{ // RF scanning
2023-10-08 20:23:37 +01:00
if (g_rx_reception_mode != RX_MODE_NONE)
goto done;
2023-09-11 00:02:57 +01:00
2023-11-08 19:07:52 +00:00
g_scan_tick_10ms = scan_pause_chan_10ms;
g_scan_pause_time_mode = false;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
g_rx_reception_mode = RX_MODE_DETECTED;
2023-09-09 08:03:56 +01:00
done:
if (g_current_function != FUNCTION_NEW_RECEIVE)
{
2023-10-23 14:02:54 +01:00
FUNCTION_Select(FUNCTION_NEW_RECEIVE);
2023-10-28 08:46:27 +01:00
#ifdef ENABLE_MDC1200
{ // reset the FSK receiver
2023-11-05 23:16:19 +00:00
//const uint16_t fsk_reg59 = BK4819_read_reg(0x59) & ~((1u << 15) | (1u << 14) | (1u << 12) | (1u << 11));
2023-11-08 19:07:52 +00:00
//BK4819_enable_mdc1200_rx(true);
2023-11-05 23:16:19 +00:00
//BK4819_write_reg(0x59, (1u << 15) | (1u << 14) | fsk_reg59);
//BK4819_write_reg(0x59, (1u << 12) | fsk_reg59);
2023-10-28 08:46:27 +01:00
}
#endif
}
2023-11-08 19:07:52 +00:00
APP_update_rssi(g_rx_vfo_num, true);
g_update_rssi = true;
2023-09-09 08:03:56 +01:00
}
2023-10-23 14:02:54 +01:00
static void APP_process_new_receive(void)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
bool flag;
2023-09-09 08:03:56 +01:00
2023-11-19 06:59:38 +00:00
#ifdef ENABLE_PANADAPTER
if (PAN_scanning())
{
BK4819_set_AFC(0);
return;
}
#endif
2023-11-11 13:09:24 +00:00
if (!g_squelch_open)
BK4819_set_AFC(0);
2023-10-29 22:33:38 +00:00
if (!g_squelch_open && !g_monitor_enabled)
2023-09-21 23:06:47 +01:00
{ // squelch is closed
2023-09-30 11:22:19 +01:00
2023-10-08 20:23:37 +01:00
if (g_dtmf_rx_index > 0)
2023-09-30 11:22:19 +01:00
DTMF_clear_RX();
2023-10-08 20:23:37 +01:00
if (g_current_function != FUNCTION_FOREGROUND)
{
FUNCTION_Select(FUNCTION_FOREGROUND);
2023-10-08 20:23:37 +01:00
g_update_display = true;
2023-11-11 13:09:24 +00:00
// g_update_status = true;
}
2023-10-23 14:02:54 +01:00
2023-09-09 08:03:56 +01:00
return;
}
2023-11-11 13:09:24 +00:00
switch (g_rx_vfo->channel.mod_mode)
{
case MOD_MODE_FM:
case MOD_MODE_AM:
BK4819_set_AFC(2);
break;
default:
case MOD_MODE_DSB:
BK4819_set_AFC(0);
break;
}
flag = (g_scan_state_dir == SCAN_STATE_DIR_OFF && g_current_code_type == CODE_TYPE_NONE);
2023-09-09 08:03:56 +01:00
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_NOAA
if (IS_NOAA_CHANNEL(g_rx_vfo->channel_save) && g_noaa_tick_10ms > 0)
2023-09-09 08:03:56 +01:00
{
g_noaa_tick_10ms = 0;
flag = true;
2023-09-09 08:03:56 +01:00
}
#endif
2023-09-10 18:11:25 +01:00
if (g_ctcss_lost && g_current_code_type == CODE_TYPE_CONTINUOUS_TONE)
2023-09-09 08:03:56 +01:00
{
2023-10-14 09:43:53 +01:00
g_found_ctcss = false;
flag = true;
2023-09-09 08:03:56 +01:00
}
if (g_cdcss_lost && g_cdcss_code_type == CDCSS_POSITIVE_CODE && (g_current_code_type == CODE_TYPE_DIGITAL || g_current_code_type == CODE_TYPE_REVERSE_DIGITAL))
2023-09-13 09:20:09 +01:00
{
2023-10-14 09:43:53 +01:00
g_found_cdcss = false;
2023-09-13 09:20:09 +01:00
}
2023-09-09 08:03:56 +01:00
else
2023-10-08 20:23:37 +01:00
if (!flag)
2023-09-09 08:03:56 +01:00
return;
if (g_scan_state_dir == SCAN_STATE_DIR_OFF && g_css_scan_mode == CSS_SCAN_MODE_OFF)
2023-11-11 13:09:24 +00:00
{ // not scanning
#ifdef ENABLE_KILL_REVIVE
2023-11-02 21:44:53 +00:00
if (g_rx_vfo->channel.dtmf_decoding_enable || g_eeprom.config.setting.radio_disabled)
#else
2023-11-02 21:44:53 +00:00
if (g_rx_vfo->channel.dtmf_decoding_enable)
#endif
2023-09-30 11:22:19 +01:00
{ // DTMF DCD is enabled
2023-10-03 00:14:36 +01:00
DTMF_HandleRequest();
2023-09-30 11:22:19 +01:00
2023-10-08 20:23:37 +01:00
if (g_dtmf_call_state == DTMF_CALL_STATE_NONE)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (g_rx_reception_mode == RX_MODE_DETECTED)
2023-09-09 08:03:56 +01:00
{
2023-11-02 10:00:51 +00:00
g_dual_watch_tick_10ms = g_eeprom.config.setting.scan_hold_time * 50;
g_rx_reception_mode = RX_MODE_LISTENING;
g_update_status = true;
2023-10-08 20:23:37 +01:00
g_update_display = true;
2023-09-09 08:03:56 +01:00
return;
}
}
}
}
2023-10-29 22:33:38 +00:00
APP_start_listening();
2023-09-09 08:03:56 +01:00
}
enum end_of_rx_mode_e {
END_OF_RX_MODE_NONE = 0,
END_OF_RX_MODE_END,
END_OF_RX_MODE_TTE
};
typedef enum end_of_rx_mode_e end_of_rx_mode_t;
2023-09-09 08:03:56 +01:00
static void APP_process_rx(void)
{
2023-11-19 06:59:38 +00:00
#ifdef ENABLE_PANADAPTER
if (PAN_scanning())
return;
#endif
end_of_rx_mode_t Mode = END_OF_RX_MODE_NONE;
2023-09-09 08:03:56 +01:00
2023-11-08 19:07:52 +00:00
// APP_update_rssi(g_rx_vfo_num);
g_update_rssi = true;
2023-11-11 13:09:24 +00:00
// if (!g_squelch_open)
// BK4819_set_AFC(0);
2023-10-08 20:23:37 +01:00
if (g_flag_tail_tone_elimination_complete)
2023-09-09 08:03:56 +01:00
{
Mode = END_OF_RX_MODE_END;
goto Skip;
}
2023-10-25 19:26:22 +01:00
if (g_scan_state_dir != SCAN_STATE_DIR_OFF) // && IS_FREQ_CHANNEL(g_scan_next_channel))
2023-09-09 08:03:56 +01:00
{
2023-10-29 22:33:38 +00:00
if (g_squelch_open || g_monitor_enabled)
2023-10-25 08:47:00 +01:00
{
2023-11-02 10:00:51 +00:00
switch (g_eeprom.config.setting.carrier_search_mode)
2023-10-25 08:47:00 +01:00
{
case SCAN_RESUME_TIME: // stay only for a limited time
break;
case SCAN_RESUME_CARRIER: // stay untill the carrier goes away
2023-11-08 19:07:52 +00:00
g_scan_tick_10ms = g_eeprom.config.setting.scan_hold_time * 50;
2023-10-25 08:47:00 +01:00
g_scan_pause_time_mode = false;
break;
case SCAN_RESUME_STOP: // stop scan once we find any signal
APP_stop_scan();
break;
}
2023-10-24 18:16:16 +01:00
return;
2023-10-25 08:47:00 +01:00
}
2023-10-25 19:26:22 +01:00
2023-09-09 08:03:56 +01:00
Mode = END_OF_RX_MODE_END;
goto Skip;
}
2023-10-24 18:16:16 +01:00
2023-10-08 20:23:37 +01:00
switch (g_current_code_type)
2023-09-09 08:03:56 +01:00
{
2023-09-13 09:20:09 +01:00
default:
case CODE_TYPE_NONE:
2023-09-13 09:20:09 +01:00
break;
2023-09-09 08:03:56 +01:00
case CODE_TYPE_CONTINUOUS_TONE:
if (g_found_ctcss && g_found_ctcss_tick_10ms == 0)
2023-09-09 08:03:56 +01:00
{
2023-10-14 09:43:53 +01:00
g_found_ctcss = false;
g_found_cdcss = false;
2023-10-23 14:02:54 +01:00
Mode = END_OF_RX_MODE_END;
2023-09-09 08:03:56 +01:00
goto Skip;
}
break;
2023-09-13 09:20:09 +01:00
2023-09-09 08:03:56 +01:00
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
if (g_found_cdcss && g_found_cdcss_tick_10ms == 0)
2023-09-09 08:03:56 +01:00
{
2023-10-14 09:43:53 +01:00
g_found_ctcss = false;
g_found_cdcss = false;
2023-10-23 14:02:54 +01:00
Mode = END_OF_RX_MODE_END;
2023-09-09 08:03:56 +01:00
goto Skip;
}
break;
}
2023-10-29 22:33:38 +00:00
if (g_squelch_open || g_monitor_enabled)
2023-09-09 08:03:56 +01:00
{
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.backlight_on_tx_rx >= 2)
2023-11-10 16:45:07 +00:00
BACKLIGHT_turn_on(backlight_tx_rx_time_secs); // keep the backlight on while we're receiving
2023-10-24 18:16:16 +01:00
if (!g_end_of_rx_detected_maybe && IS_NOT_NOAA_CHANNEL(g_rx_vfo->channel_save))
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
switch (g_current_code_type)
2023-09-09 08:03:56 +01:00
{
case CODE_TYPE_NONE:
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.squelch_level > 0)
2023-09-09 08:03:56 +01:00
{
if (g_cxcss_tail_found)
2023-09-09 08:03:56 +01:00
{
Mode = END_OF_RX_MODE_TTE;
g_cxcss_tail_found = false;
2023-09-09 08:03:56 +01:00
}
}
break;
2023-09-10 18:11:25 +01:00
2023-09-09 08:03:56 +01:00
case CODE_TYPE_CONTINUOUS_TONE:
if (g_ctcss_lost)
2023-09-09 08:03:56 +01:00
{
2023-10-14 09:43:53 +01:00
g_found_ctcss = false;
2023-09-09 08:03:56 +01:00
}
else
2023-10-14 09:43:53 +01:00
if (!g_found_ctcss)
2023-09-09 08:03:56 +01:00
{
g_found_ctcss = true;
g_found_ctcss_tick_10ms = 100; // 1 sec
2023-09-09 08:03:56 +01:00
}
if (g_cxcss_tail_found)
2023-09-09 08:03:56 +01:00
{
Mode = END_OF_RX_MODE_TTE;
g_cxcss_tail_found = false;
2023-09-09 08:03:56 +01:00
}
break;
2023-09-10 18:11:25 +01:00
2023-09-09 08:03:56 +01:00
case CODE_TYPE_DIGITAL:
case CODE_TYPE_REVERSE_DIGITAL:
if (g_cdcss_lost && g_cdcss_code_type == CDCSS_POSITIVE_CODE)
2023-09-13 09:20:09 +01:00
{
2023-10-14 09:43:53 +01:00
g_found_cdcss = false;
2023-09-13 09:20:09 +01:00
}
2023-09-09 08:03:56 +01:00
else
2023-10-14 09:43:53 +01:00
if (!g_found_cdcss)
2023-09-09 08:03:56 +01:00
{
g_found_cdcss = true;
g_found_cdcss_tick_10ms = 100; // 1 sec
2023-09-09 08:03:56 +01:00
}
2023-09-11 00:02:57 +01:00
if (g_cxcss_tail_found)
2023-09-09 08:03:56 +01:00
{
if (BK4819_GetCTCType() == 1)
Mode = END_OF_RX_MODE_TTE;
2023-09-11 00:02:57 +01:00
g_cxcss_tail_found = false;
2023-09-09 08:03:56 +01:00
}
2023-09-11 00:02:57 +01:00
2023-09-09 08:03:56 +01:00
break;
}
}
}
else
2023-10-23 14:02:54 +01:00
{
2023-09-09 08:03:56 +01:00
Mode = END_OF_RX_MODE_END;
2023-10-23 14:02:54 +01:00
}
2023-10-25 19:26:22 +01:00
if (!g_end_of_rx_detected_maybe &&
Mode == END_OF_RX_MODE_NONE &&
g_next_time_slice_40ms &&
2023-11-02 10:00:51 +00:00
g_eeprom.config.setting.tail_tone_elimination &&
2023-10-08 20:23:37 +01:00
(g_current_code_type == CODE_TYPE_DIGITAL || g_current_code_type == CODE_TYPE_REVERSE_DIGITAL) &&
2023-09-13 09:20:09 +01:00
BK4819_GetCTCType() == 1)
{
2023-09-09 08:03:56 +01:00
Mode = END_OF_RX_MODE_TTE;
}
2023-09-09 08:03:56 +01:00
else
{
2023-10-08 20:23:37 +01:00
g_next_time_slice_40ms = false;
}
2023-09-09 08:03:56 +01:00
Skip:
switch (Mode)
{
case END_OF_RX_MODE_NONE:
2023-09-13 09:20:09 +01:00
break;
2023-09-09 08:03:56 +01:00
case END_OF_RX_MODE_END:
RADIO_setup_registers(true);
2023-09-10 18:11:25 +01:00
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_noaa_tick_10ms = 3000 / 10; // 3 sec
2023-09-09 08:03:56 +01:00
#endif
2023-09-10 18:11:25 +01:00
2023-10-08 20:23:37 +01:00
g_update_display = true;
2023-09-09 08:03:56 +01:00
break;
2023-09-10 18:11:25 +01:00
2023-09-09 08:03:56 +01:00
case END_OF_RX_MODE_TTE:
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.tail_tone_elimination)
2023-09-09 08:03:56 +01:00
{
if (!g_monitor_enabled)
2023-10-29 22:33:38 +00:00
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-09-13 09:20:09 +01:00
2023-10-29 22:33:38 +00:00
g_tail_tone_elimination_tick_10ms = 20; // 200ms
g_flag_tail_tone_elimination_complete = false;
g_end_of_rx_detected_maybe = true;
2023-09-09 08:03:56 +01:00
}
2023-10-25 19:26:22 +01:00
2023-09-09 08:03:56 +01:00
break;
}
if (g_scan_state_dir != SCAN_STATE_DIR_OFF)
{ // we're RF scanning
2023-11-02 10:00:51 +00:00
switch (g_eeprom.config.setting.carrier_search_mode)
{
case SCAN_RESUME_TIME: // stay only for a limited time
break;
2023-10-25 08:47:00 +01:00
case SCAN_RESUME_CARRIER: // stay untill the carrier goes away
2023-11-08 19:07:52 +00:00
g_scan_tick_10ms = g_eeprom.config.setting.scan_hold_time * 50;
g_scan_pause_time_mode = false;
break;
2023-10-25 08:47:00 +01:00
case SCAN_RESUME_STOP: // stop scan once we find any signal
APP_stop_scan();
break;
}
}
2023-09-09 08:03:56 +01:00
}
2023-10-29 22:33:38 +00:00
bool APP_start_listening(void)
2023-09-09 08:03:56 +01:00
{
2023-11-02 10:00:51 +00:00
const unsigned int chan = g_rx_vfo_num;
2023-10-08 20:23:37 +01:00
// const unsigned int chan = g_rx_vfo->channel_save;
#ifdef ENABLE_KILL_REVIVE
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.radio_disabled)
return false;
#endif
2023-09-21 23:06:47 +01:00
2023-10-29 22:33:38 +00:00
if (g_squelch_open)
BK4819_set_GPIO_pin(BK4819_GPIO6_PIN2_GREEN, true); // LED on
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.backlight_on_tx_rx >= 2)
2023-11-10 16:45:07 +00:00
BACKLIGHT_turn_on(backlight_tx_rx_time_secs);
2023-10-25 19:26:22 +01:00
#ifdef ENABLE_MDC1200
2023-10-27 10:52:32 +01:00
// MDC1200_reset_rx();
2023-10-25 19:26:22 +01:00
#endif
// clear the other vfo's rssi level (to hide the antenna symbol)
2023-10-08 20:23:37 +01:00
g_vfo_rssi_bar_level[(chan + 1) & 1u] = 0;
2023-09-09 08:03:56 +01:00
2023-11-11 13:09:24 +00:00
switch (g_rx_vfo->channel.mod_mode)
{
case MOD_MODE_FM:
case MOD_MODE_AM:
BK4819_set_AFC(2);
break;
default:
case MOD_MODE_DSB:
BK4819_set_AFC(0);
break;
}
if (g_scan_state_dir != SCAN_STATE_DIR_OFF)
{ // we're RF scanning
2023-10-23 14:02:54 +01:00
2023-11-08 14:26:27 +00:00
g_rx_vfo->freq_in_channel = 0xff;
if (IS_FREQ_CHANNEL(g_scan_next_channel))
2023-11-08 14:26:27 +00:00
g_rx_vfo->freq_in_channel = SETTINGS_find_channel(g_rx_vfo->freq_config_rx.frequency);
2023-11-02 10:00:51 +00:00
switch (g_eeprom.config.setting.carrier_search_mode)
2023-09-09 08:03:56 +01:00
{
2023-10-23 14:02:54 +01:00
case SCAN_RESUME_TIME:
if (!g_scan_pause_time_mode)
2023-09-21 23:06:47 +01:00
{
2023-11-08 19:07:52 +00:00
g_scan_tick_10ms = g_eeprom.config.setting.scan_hold_time * 50;
g_scan_pause_time_mode = true;
2023-09-21 23:06:47 +01:00
}
break;
2023-10-30 00:14:38 +00:00
2023-10-23 14:02:54 +01:00
case SCAN_RESUME_CARRIER:
2023-11-08 19:07:52 +00:00
g_scan_tick_10ms = g_eeprom.config.setting.scan_hold_time * 50;
g_scan_pause_time_mode = false;
break;
2023-10-30 00:14:38 +00:00
2023-10-25 08:47:00 +01:00
case SCAN_RESUME_STOP:
2023-11-08 19:07:52 +00:00
g_scan_tick_10ms = 0;
g_scan_pause_time_mode = false;
2023-09-21 23:06:47 +01:00
break;
2023-09-09 08:03:56 +01:00
}
2023-09-21 23:06:47 +01:00
}
2023-09-09 08:03:56 +01:00
2023-09-21 23:06:47 +01:00
#ifdef ENABLE_NOAA
2023-11-08 14:26:27 +00:00
if (IS_NOAA_CHANNEL(g_rx_vfo->channel_save) && g_noaa_mode)
2023-09-09 08:03:56 +01:00
{
2023-11-08 14:26:27 +00:00
g_rx_vfo->channel_save = g_noaa_channel + NOAA_CHANNEL_FIRST;
g_rx_vfo->p_rx->frequency = NOAA_FREQUENCY_TABLE[g_noaa_channel];
g_rx_vfo->p_tx->frequency = NOAA_FREQUENCY_TABLE[g_noaa_channel];
g_eeprom.config.setting.indices.vfo[chan].screen = g_rx_vfo->channel_save;
2023-10-30 00:14:38 +00:00
g_noaa_tick_10ms = 5000 / 10; // 5 sec
2023-10-08 20:23:37 +01:00
g_schedule_noaa = false;
2023-09-09 08:03:56 +01:00
}
2023-09-21 23:06:47 +01:00
#endif
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
if (g_css_scan_mode != CSS_SCAN_MODE_OFF)
g_css_scan_mode = CSS_SCAN_MODE_FOUND;
2023-09-18 20:37:42 +01:00
if (g_scan_state_dir == SCAN_STATE_DIR_OFF &&
2023-10-08 20:23:37 +01:00
g_css_scan_mode == CSS_SCAN_MODE_OFF &&
2023-11-02 10:00:51 +00:00
g_eeprom.config.setting.dual_watch != DUAL_WATCH_OFF)
{ // dual watch is active
2023-09-18 20:37:42 +01:00
2023-11-02 10:00:51 +00:00
g_dual_watch_tick_10ms = g_eeprom.config.setting.scan_hold_time * 50;
2023-10-30 00:14:38 +00:00
g_rx_vfo_is_active = true;
g_update_status = true;
2023-09-21 23:06:47 +01:00
}
2023-10-18 11:31:30 +01:00
// AF gain - original QS values
2023-11-08 14:26:27 +00:00
// if (g_rx_vfo->channel.mod_mode != MOD_MODE_FM)
2023-10-30 00:14:38 +00:00
// {
2023-11-05 23:16:19 +00:00
// BK4819_write_reg(0x48, 0xB3A8); // 1011 0011 1010 1000
2023-10-30 00:14:38 +00:00
// }
// else
2023-10-25 21:05:47 +01:00
{
2023-11-05 23:16:19 +00:00
BK4819_write_reg(0x48,
2023-11-08 19:07:52 +00:00
(11u << 12) | // ??? .. 0 ~ 15, doesn't seem to make any difference
( 0u << 10) | // AF Rx Gain-1
2023-11-02 10:00:51 +00:00
(g_eeprom.calib.volume_gain << 4) | // AF Rx Gain-2
(g_eeprom.calib.dac_gain << 0)); // AF DAC Gain (after Gain-1 and Gain-2)
2023-10-25 21:05:47 +01:00
}
2023-10-27 10:52:32 +01:00
2023-11-03 16:41:05 +00:00
#ifdef ENABLE_FMRADIO
if (g_fm_radio_mode)
BK1080_Init(0, false); // disable the FM radio audio
#endif
2023-10-29 22:33:38 +00:00
2023-11-03 16:41:05 +00:00
FUNCTION_Select(FUNCTION_RECEIVE);
2023-09-21 23:06:47 +01:00
#ifdef ENABLE_VOICE
#ifdef MUTE_AUDIO_FOR_VOICE
if (g_voice_write_index == 0)
2023-11-08 14:26:27 +00:00
AUDIO_set_mod_mode(g_rx_vfo->channel.mod_mode);
#else
2023-11-08 14:26:27 +00:00
AUDIO_set_mod_mode(g_rx_vfo->channel.mod_mode);
#endif
#else
2023-11-08 14:26:27 +00:00
AUDIO_set_mod_mode(g_rx_vfo->channel.mod_mode);
2023-11-08 12:17:35 +00:00
#endif
2023-11-09 05:59:50 +00:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
UART_printf("mode %u\r\n", g_rx_vfo->channel.mod_mode);
#endif
2023-11-03 16:41:05 +00:00
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-10-29 22:33:38 +00:00
if (g_current_display_screen != DISPLAY_MENU)
GUI_SelectNextDisplay(DISPLAY_MAIN);
2023-11-08 19:07:52 +00:00
APP_update_rssi(g_rx_vfo_num, true);
2023-10-30 00:14:38 +00:00
g_update_status = true;
2023-10-29 22:33:38 +00:00
g_update_display = true;
2023-10-25 19:26:22 +01:00
return true;
2023-09-09 08:03:56 +01:00
}
void APP_stop_scan(void)
{
if (g_scan_state_dir == SCAN_STATE_DIR_OFF)
return; // but, but, we weren't doing anything !
// yes we were
g_scan_state_dir = SCAN_STATE_DIR_OFF;
if (g_scan_pause_time_mode ||
2023-11-07 08:48:32 +00:00
g_scan_tick_10ms > (200 / 10) ||
2023-10-29 22:33:38 +00:00
g_monitor_enabled ||
g_current_function == FUNCTION_RECEIVE ||
2023-10-23 14:02:54 +01:00
g_current_function == FUNCTION_NEW_RECEIVE)
{ // stay where we are
g_scan_restore_channel = 0xff;
g_scan_restore_frequency = 0xffffffff;
}
if (g_scan_restore_channel != 0xff ||
(g_scan_restore_frequency > 0 && g_scan_restore_frequency != 0xffffffff))
{ // revert to where we were when starting the scan
if (g_scan_next_channel <= USER_CHANNEL_LAST)
2023-11-09 05:59:50 +00:00
{ // we were channel scanning
if (g_scan_restore_channel != 0xff)
{
2023-11-02 10:00:51 +00:00
g_eeprom.config.setting.indices.vfo[g_rx_vfo_num].user = g_scan_restore_channel;
g_eeprom.config.setting.indices.vfo[g_rx_vfo_num].screen = g_scan_restore_channel;
2023-11-02 10:00:51 +00:00
RADIO_configure_channel(g_rx_vfo_num, VFO_CONFIGURE_RELOAD);
2023-11-09 05:59:50 +00:00
RADIO_ConfigureSquelch(g_rx_vfo);
RADIO_setup_registers(true);
}
}
else
if (g_scan_restore_frequency > 0 && g_scan_restore_frequency != 0xffffffff)
{ // we were frequency scanning
g_rx_vfo->freq_config_rx.frequency = g_scan_restore_frequency;
// find the first channel that contains this frequency
2023-11-02 10:00:51 +00:00
g_rx_vfo->freq_in_channel = SETTINGS_find_channel(g_rx_vfo->freq_config_rx.frequency);
2023-11-10 07:31:50 +00:00
RADIO_apply_offset(g_rx_vfo, false);
2023-11-09 05:59:50 +00:00
RADIO_ConfigureSquelch(g_rx_vfo);
RADIO_setup_registers(true);
}
g_update_display = true;
}
else
{ // stay where we are
if (g_rx_vfo->channel_save > USER_CHANNEL_LAST)
{ // frequency mode
2023-11-10 07:31:50 +00:00
RADIO_apply_offset(g_rx_vfo, false);
2023-11-09 05:59:50 +00:00
RADIO_ConfigureSquelch(g_rx_vfo);
2023-11-02 10:00:51 +00:00
SETTINGS_save_channel(g_rx_vfo->channel_save, g_rx_vfo_num, g_rx_vfo, 1);
return;
}
2023-10-19 14:21:37 +01:00
SETTINGS_save_vfo_indices();
}
2023-10-17 21:22:40 +01:00
#ifdef ENABLE_VOICE
g_another_voice_id = VOICE_ID_SCANNING_STOP;
#endif
2023-11-07 08:48:32 +00:00
g_scan_tick_10ms = 0;
g_scan_pause_time_mode = false;
g_update_status = true;
}
static void APP_next_freq(void)
2023-09-09 08:03:56 +01:00
{
2023-11-08 11:27:26 +00:00
uint32_t freq = g_tx_vfo->freq_config_rx.frequency;
#ifdef ENABLE_SCAN_IGNORE_LIST
do {
#endif
2023-11-08 11:27:26 +00:00
freq += g_scan_initial_step_size * g_scan_state_dir;
// wrap-a-round
2023-11-08 11:27:26 +00:00
while (freq >= g_scan_initial_upper)
freq -= g_scan_initial_upper - g_scan_initial_lower;
while (freq < g_scan_initial_lower)
freq += g_scan_initial_upper - g_scan_initial_lower;
// round
#ifdef ENABLE_SCAN_RANGES
2023-11-09 12:22:54 +00:00
if (g_eeprom.config.setting.scan_ranges_enable)
2023-11-11 13:09:24 +00:00
//freq = g_scan_initial_lower + ((((freq - g_scan_initial_lower) + (g_scan_initial_step_size / 2)) / g_scan_initial_step_size) * g_scan_initial_step_size);
freq = FREQUENCY_floor_to_step(freq, g_scan_initial_step_size, g_scan_initial_lower, g_scan_initial_upper);
#else
//freq = FREQUENCY_floor_to_step(freq, g_scan_initial_step_size, g_scan_initial_lower, g_scan_initial_upper);
2023-11-08 11:27:26 +00:00
#endif
#ifdef ENABLE_SCAN_IGNORE_LIST
} while (FI_freq_ignored(freq) >= 0);
#endif
g_tx_vfo->freq_in_channel = 0xff;
g_tx_vfo->freq_config_rx.frequency = freq;
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
// UART_printf("APP_next_freq %u %u\r\n", freq, new_band);
#endif
#if 0
// original slower method
2023-11-10 07:31:50 +00:00
RADIO_apply_offset(g_tx_vfo, false);
RADIO_setup_registers(true);
#ifdef ENABLE_FASTER_CHANNEL_SCAN
2023-11-07 08:48:32 +00:00
g_scan_tick_10ms = 10; // 100ms
#else
2023-11-07 08:48:32 +00:00
g_scan_tick_10ms = scan_pause_freq_10ms;
#endif
#else
// don't need to go through all the other stuff .. speed things up !!
BK4819_set_rf_frequency(g_tx_vfo->freq_config_rx.frequency, true);
BK4819_set_rf_filter_path(g_tx_vfo->freq_config_rx.frequency);
2023-11-10 07:31:50 +00:00
RADIO_apply_offset(g_tx_vfo, false);
#ifdef ENABLE_FASTER_CHANNEL_SCAN
2023-11-07 08:48:32 +00:00
//g_scan_tick_10ms = 10; // 100ms
2023-11-10 07:31:50 +00:00
g_scan_tick_10ms = 6; // 60ms
#else
2023-11-07 08:48:32 +00:00
g_scan_tick_10ms = scan_pause_freq_10ms;
#endif
#endif
2023-10-02 19:23:37 +01:00
g_scan_pause_time_mode = false;
g_update_display = true;
2023-09-09 08:03:56 +01:00
}
static void APP_next_channel(void)
2023-09-09 08:03:56 +01:00
{
2023-10-08 17:14:13 +01:00
static unsigned int prevChannel = 0;
2023-11-02 10:00:51 +00:00
const unsigned int index = g_eeprom.config.setting.scan_list_default;
const bool enabled = (index < 2) ? !!g_eeprom.config.setting.priority_scan_list[index].enabled : true;
const int chan1 = (index < 2) ? g_eeprom.config.setting.priority_scan_list[index].channel[0] : -1;
const int chan2 = (index < 2) ? g_eeprom.config.setting.priority_scan_list[index].channel[1] : -1;
const unsigned int prev_chan = g_scan_next_channel;
2023-10-08 17:14:13 +01:00
unsigned int chan = 0;
if (enabled)
2023-09-09 08:03:56 +01:00
{
switch (g_scan_current_scan_list)
2023-09-09 08:03:56 +01:00
{
case SCAN_NEXT_CHAN_SCANLIST1:
prevChannel = g_scan_next_channel;
2023-10-07 15:12:53 +01:00
2023-10-04 22:08:13 +01:00
if (chan1 >= 0)
{
2023-11-06 18:52:18 +00:00
if (RADIO_channel_valid(chan1, false, 0))
2023-10-04 22:08:13 +01:00
{
g_scan_current_scan_list = SCAN_NEXT_CHAN_SCANLIST1;
g_scan_next_channel = chan1;
2023-10-04 22:08:13 +01:00
break;
}
}
2023-10-07 15:12:53 +01:00
2023-10-28 23:11:57 +01:00
// Fallthrough
case SCAN_NEXT_CHAN_SCANLIST2:
2023-10-04 22:08:13 +01:00
if (chan2 >= 0)
{
2023-11-06 18:52:18 +00:00
if (RADIO_channel_valid(chan2, false, 0))
2023-10-04 22:08:13 +01:00
{
g_scan_current_scan_list = SCAN_NEXT_CHAN_SCANLIST2;
g_scan_next_channel = chan2;
2023-10-04 22:08:13 +01:00
break;
}
}
2023-10-07 15:12:53 +01:00
2023-10-28 23:11:57 +01:00
// Fallthrough
// this bit doesn't yet work if the other VFO is a frequency
2023-10-08 20:23:37 +01:00
case SCAN_NEXT_CHAN_DUAL_WATCH:
// dual watch is enabled - include the other VFO in the scan
2023-11-02 10:00:51 +00:00
// if (g_eeprom.config.setting.dual_watch != DUAL_WATCH_OFF)
// {
2023-11-02 10:00:51 +00:00
// chan = (g_rx_vfo + 1) & 1u;
// chan = g_eeprom.config.setting.indices.vfo[chan].screen;
2023-10-08 17:14:13 +01:00
// if (chan <= USER_CHANNEL_LAST)
// {
// g_scan_current_scan_list = SCAN_NEXT_CHAN_DUAL_WATCH;
// g_scan_next_channel = chan;
// break;
// }
// }
2023-09-09 08:03:56 +01:00
2023-10-28 23:11:57 +01:00
// Fallthrough
default:
2023-10-08 17:14:13 +01:00
case SCAN_NEXT_CHAN_USER:
g_scan_current_scan_list = SCAN_NEXT_CHAN_USER;
g_scan_next_channel = prevChannel;
chan = 0xff;
break;
}
}
if (!enabled || chan == 0xff)
{
2023-11-02 10:00:51 +00:00
chan = RADIO_FindNextChannel(g_scan_next_channel + g_scan_state_dir, g_scan_state_dir, (index < 2) ? true : false, index);
if (chan == 0xFF)
{ // no valid channel found
2023-10-07 15:12:53 +01:00
2023-10-08 17:14:13 +01:00
chan = USER_CHANNEL_FIRST;
// return;
}
2023-10-07 15:12:53 +01:00
g_scan_next_channel = chan;
}
2023-09-09 08:03:56 +01:00
if (g_scan_next_channel != prev_chan)
2023-09-09 08:03:56 +01:00
{
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
// UART_printf("APP_next_channel %u\r\n", g_scan_next_channel);
#endif
2023-11-02 10:00:51 +00:00
g_eeprom.config.setting.indices.vfo[g_rx_vfo_num].user = g_scan_next_channel;
g_eeprom.config.setting.indices.vfo[g_rx_vfo_num].screen = g_scan_next_channel;
2023-09-11 00:02:57 +01:00
2023-11-02 10:00:51 +00:00
RADIO_configure_channel(g_rx_vfo_num, VFO_CONFIGURE_RELOAD);
RADIO_setup_registers(true);
2023-09-11 00:02:57 +01:00
2023-10-08 20:23:37 +01:00
g_update_display = true;
2023-09-09 08:03:56 +01:00
}
#ifdef ENABLE_FASTER_CHANNEL_SCAN
2023-11-07 08:48:32 +00:00
g_scan_tick_10ms = 9; // 90ms .. <= ~60ms it misses signals (squelch response and/or PLL lock time) ?
#else
2023-11-07 08:48:32 +00:00
g_scan_tick_10ms = scan_pause_chan_10ms;
#endif
g_scan_pause_time_mode = false;
if (enabled)
if (++g_scan_current_scan_list >= SCAN_NEXT_NUM)
g_scan_current_scan_list = SCAN_NEXT_CHAN_SCANLIST1; // back round we go
2023-09-09 08:03:56 +01:00
}
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_NOAA
static void APP_next_noaa(void)
2023-09-09 08:03:56 +01:00
{
if (++g_noaa_channel >= ARRAY_SIZE(NOAA_FREQUENCY_TABLE))
2023-10-08 20:23:37 +01:00
g_noaa_channel = 0;
2023-09-09 08:03:56 +01:00
}
#endif
2023-11-02 10:00:51 +00:00
static bool APP_toggle_dual_watch_vfo(void)
2023-09-09 08:03:56 +01:00
{
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.dual_watch == DUAL_WATCH_OFF)
return false;
if (g_current_function == FUNCTION_FOREGROUND && g_current_function == FUNCTION_POWER_SAVE)
return false;
if (g_current_display_screen == DISPLAY_SEARCH)
return false;
if (g_scan_state_dir != SCAN_STATE_DIR_OFF)
return false;
if (g_css_scan_mode != CSS_SCAN_MODE_OFF)
return false;
if (g_ptt_is_pressed)
return false;
if (g_dtmf_call_state != DTMF_CALL_STATE_NONE)
return false;
#ifdef ENABLE_FMRADIO
2023-11-03 16:41:05 +00:00
if (g_fm_radio_mode)
return false;
2023-11-02 10:00:51 +00:00
#endif
if (g_dual_watch_tick_10ms > 0)
return false;
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
2023-11-07 13:07:47 +00:00
// UART_SendText("dual wot\r\n");
#endif
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_NOAA
2023-11-02 10:00:51 +00:00
if (g_noaa_mode)
2023-09-09 08:03:56 +01:00
{
2023-11-02 10:00:51 +00:00
if (IS_NOT_NOAA_CHANNEL(g_eeprom.config.setting.indices.vfo[0].screen) || IS_NOT_NOAA_CHANNEL(g_eeprom.config.setting.indices.vfo[1].screen))
g_rx_vfo_num = (g_rx_vfo_num + 1) & 1u;
2023-09-09 08:03:56 +01:00
else
2023-11-02 10:00:51 +00:00
g_rx_vfo_num = 0;
2023-09-10 18:11:25 +01:00
2023-11-02 10:00:51 +00:00
g_rx_vfo = &g_vfo_info[g_rx_vfo_num];
2023-09-10 18:11:25 +01:00
2023-11-02 10:00:51 +00:00
if (g_vfo_info[0].channel_save >= NOAA_CHANNEL_FIRST)
APP_next_noaa();
2023-09-09 08:03:56 +01:00
}
else
#endif
2023-09-13 17:34:56 +01:00
{ // toggle between VFO's
2023-11-02 10:00:51 +00:00
g_rx_vfo_num = (g_rx_vfo_num + 1) & 1u;
g_rx_vfo = &g_vfo_info[g_rx_vfo_num];
g_update_status = true;
2023-09-09 08:03:56 +01:00
}
RADIO_setup_registers(false);
2023-09-09 08:03:56 +01:00
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_NOAA
2023-11-02 10:00:51 +00:00
g_dual_watch_tick_10ms = g_noaa_mode ? dual_watch_delay_noaa_10ms : dual_watch_delay_toggle_10ms;
2023-09-09 08:03:56 +01:00
#else
2023-10-29 22:33:38 +00:00
g_dual_watch_tick_10ms = dual_watch_delay_toggle_10ms;
2023-09-09 08:03:56 +01:00
#endif
2023-11-02 10:00:51 +00:00
return true;
2023-09-09 08:03:56 +01:00
}
void APP_process_radio_interrupts(void)
2023-09-09 08:03:56 +01:00
{
if (g_current_display_screen == DISPLAY_SEARCH)
2023-09-09 08:03:56 +01:00
return;
while (1)
{ // BK4819 chip interrupt request
2023-09-13 17:34:56 +01:00
uint16_t int_bits;
2023-11-05 23:16:19 +00:00
const uint16_t reg_c = BK4819_read_reg(0x0C);
if ((reg_c & 1u) == 0)
break;
2023-10-28 08:46:27 +01:00
2023-11-05 23:16:19 +00:00
BK4819_write_reg(0x02, 0);
int_bits = BK4819_read_reg(0x02);
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
2023-11-03 10:39:43 +00:00
#ifdef ENABLE_AIRCOPY
if (g_current_display_screen != DISPLAY_AIRCOPY)
#endif
{
int i;
UART_printf("int bits %04X %04X ", reg_c, int_bits);
for (i = 15; i >= 0; i--)
UART_printf("%c", (reg_c & (1u << i)) ? '#' : '.');
UART_SendText(" ");
for (i = 15; i >= 0; i--)
UART_printf("%c", (int_bits & (1u << i)) ? '#' : '.');
UART_SendText("\r\n");
}
#endif
2023-09-09 08:03:56 +01:00
if (int_bits & BK4819_REG_02_DTMF_5TONE_FOUND)
2023-09-30 11:22:19 +01:00
{ // save the RX'ed DTMF character
2023-09-17 04:58:27 +01:00
const char c = DTMF_GetCharacter(BK4819_GetDTMF_5TONE_Code());
if (c != 0xff && g_current_function != FUNCTION_TRANSMIT)
{
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.dtmf_live_decoder)
2023-09-17 09:54:24 +01:00
{
size_t len = strlen(g_dtmf_rx_live);
if (len >= (sizeof(g_dtmf_rx_live) - 1))
{ // make room
memmove(&g_dtmf_rx_live[0], &g_dtmf_rx_live[1], sizeof(g_dtmf_rx_live) - 1);
len--;
2023-09-30 11:22:19 +01:00
}
g_dtmf_rx_live[len++] = c;
g_dtmf_rx_live[len] = 0;
g_dtmf_rx_live_timeout = dtmf_rx_live_timeout_500ms; // time till we delete it
g_update_display = true;
}
2023-11-02 10:00:51 +00:00
#ifdef ENABLE_KILL_REVIVE
2023-11-02 21:44:53 +00:00
if (g_rx_vfo->channel.dtmf_decoding_enable || g_eeprom.config.setting.radio_disabled)
#else
2023-11-02 21:44:53 +00:00
if (g_rx_vfo->channel.dtmf_decoding_enable)
#endif
{
if (g_dtmf_rx_index >= (sizeof(g_dtmf_rx) - 1))
{ // make room
memmove(&g_dtmf_rx[0], &g_dtmf_rx[1], sizeof(g_dtmf_rx) - 1);
g_dtmf_rx_index--;
2023-09-30 11:22:19 +01:00
}
g_dtmf_rx[g_dtmf_rx_index++] = c;
g_dtmf_rx[g_dtmf_rx_index] = 0;
g_dtmf_rx_timeout = dtmf_rx_timeout_500ms; // time till we delete it
g_dtmf_rx_pending = true;
2023-11-02 10:00:51 +00:00
DTMF_HandleRequest();
2023-09-17 09:54:24 +01:00
}
}
2023-09-09 08:03:56 +01:00
}
if (int_bits & BK4819_REG_02_CxCSS_TAIL)
{
g_cxcss_tail_found = true;
g_ctcss_tail_phase_shift_rx = (reg_c >> 12) & 3u;
2023-09-09 08:03:56 +01:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
UART_printf("cxcss tail %u\r\n", g_ctcss_tail_phase_shift_rx);
#endif
}
if (int_bits & BK4819_REG_02_CDCSS_LOST)
2023-09-09 08:03:56 +01:00
{
2023-10-30 00:14:38 +00:00
g_cdcss_lost = true;
g_cdcss_code_type = BK4819_get_CDCSS_code_type();
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
UART_printf("cdcss lost %u\r\n", g_cdcss_code_type);
#endif
2023-09-09 08:03:56 +01:00
}
if (int_bits & BK4819_REG_02_CDCSS_FOUND)
{
g_cdcss_lost = false;
2023-09-09 08:03:56 +01:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
UART_SendText("cdcss found\r\n");
#endif
}
if (int_bits & BK4819_REG_02_CTCSS_LOST)
{
g_ctcss_lost = true;
2023-09-09 08:03:56 +01:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
UART_SendText("cdcss lost\r\n");
#endif
}
if (int_bits & BK4819_REG_02_CTCSS_FOUND)
{
g_ctcss_lost = false;
2023-09-09 08:03:56 +01:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
UART_SendText("ctcss found\r\n");
#endif
}
#ifdef ENABLE_VOX
if (int_bits & BK4819_REG_02_VOX_LOST)
2023-09-09 08:03:56 +01:00
{
2023-10-30 00:14:38 +00:00
g_vox_lost = true;
g_vox_pause_tick_10ms = 10; // 100ms
2023-10-07 15:12:53 +01:00
g_update_status = true;
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
// UART_SendText("vox lost\r\n");
#endif
if (g_eeprom.config.setting.vox_enabled)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (g_current_function == FUNCTION_POWER_SAVE && !g_rx_idle_mode)
{
2023-10-30 00:14:38 +00:00
g_power_save_tick_10ms = power_save2_10ms;
g_power_save_expired = false;
}
2023-10-07 15:12:53 +01:00
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.dual_watch != DUAL_WATCH_OFF &&
2023-10-29 22:33:38 +00:00
(g_dual_watch_tick_10ms == 0 || g_dual_watch_tick_10ms < dual_watch_delay_after_vox_10ms))
{
2023-10-29 22:33:38 +00:00
g_dual_watch_tick_10ms = dual_watch_delay_after_vox_10ms;
2023-10-30 00:14:38 +00:00
g_update_status = true;
}
2023-09-09 08:03:56 +01:00
}
}
if (int_bits & BK4819_REG_02_VOX_FOUND)
{
2023-10-30 00:14:38 +00:00
g_vox_lost = false;
2023-10-29 22:33:38 +00:00
g_vox_pause_tick_10ms = 0;
g_update_status = true;
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
// UART_SendText("vox found\r\n");
#endif
}
#endif
2023-09-09 08:03:56 +01:00
if (int_bits & BK4819_REG_02_SQUELCH_CLOSED)
2023-09-09 08:03:56 +01:00
{
2023-10-23 14:02:54 +01:00
g_squelch_open = false;
2023-10-29 22:33:38 +00:00
2023-10-27 10:52:32 +01:00
BK4819_set_GPIO_pin(BK4819_GPIO6_PIN2_GREEN, false); // LED off
2023-10-23 14:02:54 +01:00
if (!g_monitor_enabled)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-10-23 14:02:54 +01:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
2023-10-28 08:46:27 +01:00
UART_SendText("sq close\r\n");
2023-10-23 14:02:54 +01:00
#endif
2023-10-30 00:14:38 +00:00
2023-11-08 19:07:52 +00:00
//APP_update_rssi(g_rx_vfo_num, false);
2023-10-30 16:28:41 +00:00
g_update_rssi = true;
2023-10-30 00:14:38 +00:00
g_update_display = true;
2023-09-09 08:03:56 +01:00
}
if (int_bits & BK4819_REG_02_SQUELCH_OPENED)
2023-09-09 08:03:56 +01:00
{
2023-10-23 14:02:54 +01:00
g_squelch_open = true;
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
2023-10-28 08:46:27 +01:00
UART_SendText("sq open\r\n");
2023-10-23 14:02:54 +01:00
#endif
2023-10-30 00:14:38 +00:00
2023-11-08 19:07:52 +00:00
//APP_update_rssi(g_rx_vfo_num, false);
2023-10-30 16:28:41 +00:00
g_update_rssi = true;
2023-10-30 00:14:38 +00:00
if (g_monitor_enabled)
BK4819_set_GPIO_pin(BK4819_GPIO6_PIN2_GREEN, true); // LED on
2023-11-02 10:00:51 +00:00
2023-10-30 00:14:38 +00:00
g_update_display = true;
2023-09-09 08:03:56 +01:00
}
#ifdef ENABLE_MDC1200
MDC1200_process_rx(int_bits);
#endif
2023-09-09 08:03:56 +01:00
}
}
void APP_end_tx(void)
2023-09-16 07:08:18 +01:00
{ // back to RX mode
2023-10-18 11:31:30 +01:00
RADIO_tx_eot();
2023-11-07 08:48:32 +00:00
ST7565_Init(false);
if (g_current_vfo->p_tx->code_type != CODE_TYPE_NONE)
2023-10-30 00:14:38 +00:00
{ // CTCSS/CDCSS is enabled
2023-11-02 10:00:51 +00:00
//if (g_eeprom.config.setting.tail_tone_elimination && g_eeprom.config.setting.repeater_tail_tone_elimination > 0)
if (g_eeprom.config.setting.tail_tone_elimination)
2023-09-13 17:34:56 +01:00
{ // send the CTCSS/DCS tail tone - allows the receivers to mute the usual FM squelch tail/crash
RADIO_enable_CxCSS_tail();
}
2023-10-30 00:14:38 +00:00
#if 1
else
2023-10-30 00:14:38 +00:00
{ // TX a short blank carrier after disabling the CTCSS/CDCSS
// this gives the receivers time to mute their RX audio before we drop carrier
BK4819_disable_sub_audible();
SYSTEM_DelayMs(200);
}
#endif
}
RADIO_setup_registers(false);
2023-10-29 22:33:38 +00:00
2023-10-30 00:14:38 +00:00
if (g_monitor_enabled)
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-09-09 08:03:56 +01:00
}
#ifdef ENABLE_VOX
static void APP_process_vox(void)
2023-09-09 08:03:56 +01:00
{
2023-10-29 22:33:38 +00:00
if (g_vox_resume_tick_10ms == 0)
{
if (g_vox_pause_tick_10ms > 0)
return;
}
else
{
g_vox_lost = false;
2023-10-29 22:33:38 +00:00
g_vox_pause_tick_10ms = 0;
2023-10-07 15:12:53 +01:00
g_update_status = true;
}
2023-10-07 15:12:53 +01:00
2023-10-29 22:33:38 +00:00
if (g_current_function == FUNCTION_RECEIVE || g_monitor_enabled)
return;
2023-10-07 15:12:53 +01:00
if (g_scan_state_dir != SCAN_STATE_DIR_OFF || g_css_scan_mode != CSS_SCAN_MODE_OFF)
return;
2023-10-07 15:12:53 +01:00
2023-11-02 15:22:32 +00:00
if (g_vox_audio_detected)
{
2023-10-08 17:14:13 +01:00
if (g_vox_lost)
g_vox_stop_tick_10ms = vox_stop_10ms; // 1 second
2023-09-09 08:03:56 +01:00
else
2023-10-29 22:33:38 +00:00
if (g_vox_stop_tick_10ms == 0)
2023-11-02 15:22:32 +00:00
g_vox_audio_detected = false;
2023-10-07 15:12:53 +01:00
2023-11-02 15:22:32 +00:00
if (g_current_function == FUNCTION_TRANSMIT && !g_ptt_is_pressed && !g_vox_audio_detected)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (g_flag_end_tx)
{ // back to RX mode
FUNCTION_Select(FUNCTION_FOREGROUND);
2023-09-09 08:03:56 +01:00
}
else
{
APP_end_tx();
2023-10-07 15:12:53 +01:00
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.repeater_tail_tone_elimination == 0)
FUNCTION_Select(FUNCTION_FOREGROUND);
else
2023-11-02 10:00:51 +00:00
g_rtte_count_down = g_eeprom.config.setting.repeater_tail_tone_elimination * 10;
}
2023-10-07 15:12:53 +01:00
2023-11-02 15:22:32 +00:00
g_update_display = true;
2023-10-08 20:23:37 +01:00
g_flag_end_tx = false;
2023-09-09 08:03:56 +01:00
}
2023-11-02 15:22:32 +00:00
g_update_status = true;
return;
}
2023-10-07 15:12:53 +01:00
if (!g_vox_lost)
return;
2023-10-07 15:12:53 +01:00
2023-11-02 15:22:32 +00:00
g_vox_audio_detected = true;
2023-10-07 15:12:53 +01:00
g_update_status = true;
#ifdef ENABLE_KILL_REVIVE
if (g_eeprom.config.setting.radio_disabled)
return;
#endif
if (!g_eeprom.config.setting.tx_enable)
return;
#ifdef ENABLE_FMRADIO
if (g_fm_radio_mode)
2023-11-02 15:22:32 +00:00
return; // can't do VOX while the speaker is emitting noise
#endif
if (g_current_display_screen == DISPLAY_MENU)
return;
if (g_current_function == FUNCTION_POWER_SAVE)
FUNCTION_Select(FUNCTION_FOREGROUND);
if (g_current_function == FUNCTION_TRANSMIT || g_serial_config_tick_500ms > 0)
return;
2023-11-02 15:22:32 +00:00
// ************* go into TX mode
g_dtmf_reply_state = DTMF_REPLY_NONE;
RADIO_PrepareTX();
g_update_display = true;
2023-09-09 08:03:56 +01:00
}
#endif
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
// called every 10ms
2023-11-22 11:21:53 +00:00
void APP_process_keys(void)
2023-09-09 08:03:56 +01:00
{
const bool ptt_pressed = !GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT);
2023-09-09 08:03:56 +01:00
2023-11-22 11:21:53 +00:00
static int key_repeat_speedup_ticks = 0;
static uint8_t key_repeat_ticks = 0;
2023-10-28 22:02:07 +01:00
key_code_t key;
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_KILL_REVIVE
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.radio_disabled)
2023-09-14 09:56:30 +01:00
return;
#endif
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
// *****************
// PTT is treated completely separately from all the other buttons
2023-10-07 15:12:53 +01:00
2023-11-05 10:48:37 +00:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
// if (g_input_box_index > 0)
// UART_printf("1 index %u %u\r\n", g_input_box_index, g_flash_light_blink_tick_10ms);
#endif
2023-10-28 22:02:07 +01:00
if (ptt_pressed)
{ // PTT pressed
2023-11-01 08:51:56 +00:00
#ifdef ENABLE_AIRCOPY
2023-11-02 10:00:51 +00:00
if (!g_ptt_is_pressed && g_serial_config_tick_500ms == 0 && g_eeprom.config.setting.tx_enable && g_current_function != FUNCTION_TRANSMIT && g_current_display_screen != DISPLAY_AIRCOPY)
2023-11-01 08:51:56 +00:00
#else
2023-11-02 10:00:51 +00:00
if (!g_ptt_is_pressed && g_serial_config_tick_500ms == 0 && g_eeprom.config.setting.tx_enable && g_current_function != FUNCTION_TRANSMIT)
2023-11-01 08:51:56 +00:00
#endif
2023-10-28 22:02:07 +01:00
{
#ifdef ENABLE_KILL_REVIVE
2023-11-02 10:00:51 +00:00
if (!g_eeprom.config.setting.radio_disabled)
#endif
{
2023-11-01 08:51:56 +00:00
if (++g_ptt_debounce >= 3) // 30ms debounce
{ // start TX'ing
2023-11-02 10:00:51 +00:00
2023-11-01 08:51:56 +00:00
g_boot_tick_10ms = 0; // cancel the boot-up screen
g_ptt_is_pressed = ptt_pressed;
g_ptt_was_released = false;
g_ptt_debounce = 3;
2023-11-02 10:00:51 +00:00
2023-11-01 08:51:56 +00:00
APP_process_key(KEY_PTT, true, false);
2023-10-23 14:02:54 +01:00
}
}
2023-10-28 22:02:07 +01:00
}
}
else
{ // PTT released
2023-11-05 10:48:37 +00:00
if (g_ptt_is_pressed || g_serial_config_tick_500ms > 0)
2023-10-28 22:02:07 +01:00
{
2023-11-05 10:48:37 +00:00
// if (g_ptt_debounce > 0)
{
if (--g_ptt_debounce <= 0)
{ // stop TX'ing
2023-11-10 16:45:07 +00:00
2023-11-05 10:48:37 +00:00
g_ptt_is_pressed = false;
g_ptt_was_released = true;
g_ptt_debounce = 0;
2023-11-10 16:45:07 +00:00
2023-11-05 10:48:37 +00:00
APP_process_key(KEY_PTT, false, false);
}
2023-10-28 22:02:07 +01:00
}
}
2023-09-09 08:03:56 +01:00
}
2023-11-05 10:48:37 +00:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
// if (g_input_box_index > 0)
// UART_printf("2 index %u %u\r\n", g_input_box_index, g_flash_light_blink_tick_10ms);
#endif
2023-10-28 22:02:07 +01:00
// *****************
2023-11-22 11:21:53 +00:00
// key/button processing (non-PTT)
2023-10-28 22:02:07 +01:00
// scan the hardware keys
key = KEYBOARD_Poll();
if (g_serial_config_tick_500ms > 0)
{ // config upload/download in progress
g_key_debounce_press = 0;
g_key_debounce_repeat = 0;
g_key_prev = KEY_INVALID;
g_key_held = false;
g_fkey_pressed = false;
return;
2023-09-09 08:03:56 +01:00
}
2023-10-28 22:02:07 +01:00
if (key == KEY_INVALID || (g_key_prev != KEY_INVALID && key != g_key_prev))
{ // key not pressed or different key pressed
2023-11-21 19:05:43 +00:00
2023-10-28 22:02:07 +01:00
if (g_key_debounce_press > 0)
2023-09-09 08:03:56 +01:00
{
2023-10-28 22:02:07 +01:00
if (--g_key_debounce_press == 0)
{
2023-10-28 22:02:07 +01:00
if (g_key_prev != KEY_INVALID)
{ // key now fully released
APP_process_key(g_key_prev, false, g_key_held);
2023-10-28 22:02:07 +01:00
g_key_debounce_press = 0;
g_key_debounce_repeat = 0;
g_key_prev = KEY_INVALID;
g_key_held = false;
2023-11-22 11:21:53 +00:00
g_boot_tick_10ms = 0; // cancel boot screen/beeps
2023-10-28 22:02:07 +01:00
g_update_status = true;
2023-11-01 08:51:56 +00:00
// g_update_display = true;
2023-10-28 22:02:07 +01:00
}
}
2023-11-05 10:48:37 +00:00
2023-10-28 22:02:07 +01:00
if (g_key_debounce_repeat > 0)
g_key_debounce_repeat--;
}
2023-11-22 11:21:53 +00:00
return;
2023-09-09 08:03:56 +01:00
}
2023-11-22 11:21:53 +00:00
// key pressed
2023-11-22 11:21:53 +00:00
if (g_key_debounce_press < key_debounce_10ms)
{
if (++g_key_debounce_press >= key_debounce_10ms)
2023-10-28 22:02:07 +01:00
{
2023-11-22 11:21:53 +00:00
if (key != g_key_prev)
{ // key pressed
key_repeat_speedup_ticks = key_repeat_speedup_10ms;
key_repeat_ticks = key_repeat_initial_10ms;
g_key_debounce_repeat = key_debounce_10ms;
g_key_prev = key;
g_key_held = false;
APP_process_key(g_key_prev, true, g_key_held);
g_update_status = true;
// g_update_display = true;
2023-09-09 08:03:56 +01:00
}
}
2023-11-22 11:21:53 +00:00
return;
}
// long press time can be different for different keys
const uint8_t long_press_ticks = (key == KEY_SIDE1 || key == KEY_SIDE2) ? key_side_long_press_10ms : key_long_press_10ms;
if (g_key_debounce_repeat < long_press_ticks)
{
if (++g_key_debounce_repeat >= long_press_ticks)
{ // key long press
g_key_held = true;
APP_process_key(g_key_prev, true, g_key_held);
}
return;
}
if (key != KEY_UP && key != KEY_DOWN)
return; // up and down keys are the only repeatables
// speed up key repeat
if (key_repeat_ticks > key_repeat_fastest_10ms)
{
if (--key_repeat_speedup_ticks <= 0)
2023-09-09 08:03:56 +01:00
{
2023-11-22 11:21:53 +00:00
key_repeat_speedup_ticks = key_repeat_speedup_10ms;
key_repeat_ticks = (key_repeat_ticks > (80 / 10)) ? key_repeat_ticks >> 1 : key_repeat_ticks - 1;
2023-09-09 08:03:56 +01:00
}
2023-11-22 11:21:53 +00:00
}
key_repeat_ticks = (key_repeat_ticks < key_repeat_fastest_10ms) ? key_repeat_fastest_10ms : key_repeat_ticks;
2023-11-22 11:21:53 +00:00
// key repeat max 10ms speed if user is moving up/down in freq/channel
// const bool freq_chan = IS_FREQ_CHANNEL(g_eeprom.config.setting.indices.vfo[g_eeprom.config.setting.tx_vfo_num].screen);
// const uint8_t repeat_ticks = (g_manual_scanning && g_monitor_enabled && freq_chan && g_current_display_screen == DISPLAY_MAIN) ? 2 : key_repeat_ticks;
2023-11-22 09:38:41 +00:00
2023-11-22 11:21:53 +00:00
const uint8_t repeat_ticks = key_repeat_ticks;
2023-11-22 11:21:53 +00:00
if (++g_key_debounce_repeat < (long_press_ticks + repeat_ticks))
return;
2023-11-21 19:05:43 +00:00
2023-11-22 11:21:53 +00:00
// key repeat
2023-11-21 19:05:43 +00:00
2023-11-22 11:21:53 +00:00
g_key_debounce_repeat = long_press_ticks;
2023-11-21 19:05:43 +00:00
2023-11-22 11:21:53 +00:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
// UART_printf("rp %u\n", key_repeat_ticks);
#endif
2023-11-22 11:21:53 +00:00
APP_process_key(g_key_prev, true, g_key_held);
2023-09-09 08:03:56 +01:00
}
2023-10-28 22:02:07 +01:00
void APP_cancel_user_input_modes(void)
2023-09-09 08:03:56 +01:00
{
2023-10-28 22:02:07 +01:00
if (g_ask_to_save)
{
2023-10-28 22:02:07 +01:00
g_ask_to_save = false;
g_update_display = true;
}
2023-10-28 22:02:07 +01:00
if (g_ask_to_delete)
{
g_ask_to_delete = false;
g_update_display = true;
}
2023-10-28 22:02:07 +01:00
if (g_dtmf_input_mode || g_dtmf_input_box_index > 0)
{
DTMF_clear_input_box();
#ifdef ENABLE_FMRADIO
if (g_fm_radio_mode)
g_request_display_screen = DISPLAY_FM;
else
g_request_display_screen = DISPLAY_MAIN;
#else
g_request_display_screen = DISPLAY_MAIN;
#endif
2023-10-29 22:33:38 +00:00
g_update_display = true;
}
2023-10-28 22:02:07 +01:00
if (g_fkey_pressed || g_key_input_count_down > 0 || g_input_box_index > 0)
{
2023-10-28 22:02:07 +01:00
g_fkey_pressed = false;
g_input_box_index = 0;
g_key_input_count_down = 0;
g_update_status = true;
g_update_display = true;
}
2023-10-28 22:02:07 +01:00
}
2023-10-28 22:02:07 +01:00
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
static void APP_alarm_off(void)
{
if (!g_squelch_open && !g_monitor_enabled)
2023-10-29 22:33:38 +00:00
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.alarm_mode == ALARM_MODE_TONE)
{
2023-10-28 22:02:07 +01:00
RADIO_tx_eot();
RADIO_enable_CxCSS_tail();
}
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_VOX
2023-10-29 22:33:38 +00:00
g_vox_resume_tick_10ms = 80;
2023-10-28 22:02:07 +01:00
#endif
2023-10-28 22:02:07 +01:00
g_alarm_state = ALARM_STATE_OFF;
SYSTEM_DelayMs(5);
RADIO_setup_registers(true);
if (!g_squelch_open && !g_monitor_enabled)
2023-10-29 22:33:38 +00:00
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
else
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-10-30 00:14:38 +00:00
2023-10-28 22:02:07 +01:00
if (g_current_display_screen != DISPLAY_MENU) // 1of11 .. don't close the menu
g_request_display_screen = DISPLAY_MAIN;
}
2023-10-28 22:02:07 +01:00
#endif
2023-10-28 22:02:07 +01:00
void APP_channel_next(const bool remember_current, const scan_state_dir_t scan_direction)
{
RADIO_select_vfos();
2023-10-28 22:02:07 +01:00
g_scan_next_channel = g_rx_vfo->channel_save;
g_scan_current_scan_list = SCAN_NEXT_CHAN_SCANLIST1;
g_scan_state_dir = scan_direction;
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
if (remember_current)
{
g_scan_restore_channel = 0xff;
g_scan_restore_frequency = 0xffffffff;
}
2023-10-28 22:02:07 +01:00
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
// UART_printf("APP_channel_next %u\r\n", g_scan_next_channel);
#endif
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
if (g_scan_next_channel <= USER_CHANNEL_LAST)
{ // channel mode
if (remember_current)
g_scan_restore_channel = g_scan_next_channel;
APP_next_channel();
}
else
if (IS_FREQ_CHANNEL(g_scan_next_channel))
{ // frequency mode
if (remember_current)
g_scan_restore_frequency = g_rx_vfo->freq_config_rx.frequency;
APP_next_freq();
}
else
2023-09-09 08:03:56 +01:00
{
2023-10-28 22:02:07 +01:00
return;
}
2023-09-10 18:11:25 +01:00
2023-11-08 19:07:52 +00:00
g_scan_tick_10ms = scan_pause_css_10ms;
2023-10-28 22:02:07 +01:00
g_scan_pause_time_mode = false;
g_rx_reception_mode = RX_MODE_NONE;
}
2023-09-10 18:11:25 +01:00
2023-10-29 22:33:38 +00:00
static const uint32_t sos = __extension__ 0b10101000111011101110001010100000;
2023-09-10 18:11:25 +01:00
2023-10-28 22:02:07 +01:00
void APP_process_flash_light_10ms(void)
{
switch (g_flash_light_state)
{
case FLASHLIGHT_OFF:
break;
2023-09-10 18:11:25 +01:00
2023-10-28 22:02:07 +01:00
case FLASHLIGHT_ON:
break;
2023-10-03 00:14:36 +01:00
2023-10-28 22:02:07 +01:00
case FLASHLIGHT_BLINK:
if ((g_flash_light_blink_tick_10ms & 15u) == 0)
GPIO_FlipBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
break;
2023-10-03 00:14:36 +01:00
2023-10-28 22:02:07 +01:00
case FLASHLIGHT_SOS:
2023-10-28 22:27:47 +01:00
{ // 150ms tick
2023-10-28 23:11:57 +01:00
// '16' sets the morse speed, lower value = faster speed
2023-10-28 22:27:47 +01:00
// '+ 6' lengthens the loop time
const unsigned int num_bits = sizeof(sos) * 8;
2023-10-28 23:11:57 +01:00
const unsigned int bit = (g_flash_light_blink_tick_10ms / 16) % (num_bits + 6);
if (bit < num_bits && (sos & (1u << (num_bits - 1 - bit))))
2023-10-29 22:33:38 +00:00
{
if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT))
{ // LED on
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT);
#ifdef ENABLE_FLASH_LIGHT_SOS_TONE
if (!g_squelch_open && !g_monitor_enabled && !GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER))
2023-11-06 09:08:09 +00:00
BK4819_start_tone(880, 70, g_current_function == FUNCTION_TRANSMIT, false);
2023-10-29 22:33:38 +00:00
#endif
}
}
2023-10-28 22:02:07 +01:00
else
2023-10-29 22:33:38 +00:00
{
if (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT))
{ // LED off
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); // OFF
#ifdef ENABLE_FLASH_LIGHT_SOS_TONE
2023-10-30 00:14:38 +00:00
if (!g_squelch_open && !g_monitor_enabled && GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER))
2023-11-06 09:08:09 +00:00
BK4819_stop_tones(g_current_function == FUNCTION_TRANSMIT);
2023-10-29 22:33:38 +00:00
#endif
}
}
2023-10-28 22:02:07 +01:00
}
break;
}
2023-10-28 23:51:34 +01:00
}
void APP_process_scan(void)
{
#ifdef ENABLE_VOICE
if (g_voice_write_index != 0)
return;
#endif
if ((g_current_function == FUNCTION_FOREGROUND ||
g_current_function == FUNCTION_NEW_RECEIVE ||
g_current_function == FUNCTION_RECEIVE) &&
g_current_display_screen != DISPLAY_SEARCH &&
g_scan_state_dir != SCAN_STATE_DIR_OFF &&
!g_ptt_is_pressed)
{ // RF scanning
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
if (g_current_code_type == CODE_TYPE_NONE && g_current_function == FUNCTION_NEW_RECEIVE) // && !g_scan_pause_time_mode)
{
2023-10-29 22:33:38 +00:00
APP_start_listening();
2023-10-28 23:51:34 +01:00
}
else
2023-11-07 08:48:32 +00:00
if (g_scan_tick_10ms == 0)
2023-10-28 23:51:34 +01:00
{ // switch to next channel
g_scan_pause_time_mode = false;
g_rx_reception_mode = RX_MODE_NONE;
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
if (g_scan_next_channel <= USER_CHANNEL_LAST)
APP_next_channel();
else
if (IS_FREQ_CHANNEL(g_scan_next_channel))
APP_next_freq();
}
2023-10-29 22:33:38 +00:00
/*
2023-10-28 23:51:34 +01:00
if (g_scan_next_channel <= USER_CHANNEL_LAST)
{ // channel mode
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
if (g_current_code_type == CODE_TYPE_NONE && g_current_function == FUNCTION_NEW_RECEIVE && !g_scan_pause_time_mode)
{
2023-10-29 22:33:38 +00:00
APP_start_listening();
2023-10-28 23:51:34 +01:00
}
else
{ // switch to next channel
g_scan_pause_time_mode = false;
g_rx_reception_mode = RX_MODE_NONE;
APP_next_channel();
}
}
else
if (IS_FREQ_CHANNEL(g_scan_next_channel))
{ // frequency mode
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
if (g_current_function == FUNCTION_NEW_RECEIVE && !g_scan_pause_time_mode)
{
2023-10-29 22:33:38 +00:00
APP_start_listening();
2023-10-28 23:51:34 +01:00
}
else
{ // switch to next frequency
g_scan_pause_time_mode = false;
g_rx_reception_mode = RX_MODE_NONE;
APP_next_freq();
}
}
2023-10-29 22:33:38 +00:00
*/
2023-10-28 23:51:34 +01:00
}
2023-10-29 22:33:38 +00:00
2023-11-07 08:48:32 +00:00
if (g_css_scan_mode == CSS_SCAN_MODE_SCANNING && g_scan_tick_10ms == 0)
2023-10-28 23:51:34 +01:00
MENU_SelectNextCode();
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
#ifdef ENABLE_NOAA
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.dual_watch == DUAL_WATCH_OFF && g_noaa_mode && g_schedule_noaa)
2023-10-28 23:51:34 +01:00
{
APP_next_noaa();
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
RADIO_setup_registers(false);
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
g_noaa_tick_10ms = 7; // 70ms
g_schedule_noaa = false;
}
#endif
2023-10-29 22:33:38 +00:00
2023-11-02 10:00:51 +00:00
if (APP_toggle_dual_watch_vfo())
2023-10-28 23:51:34 +01:00
{
if (g_rx_vfo_is_active && g_current_display_screen == DISPLAY_MAIN)
GUI_SelectNextDisplay(DISPLAY_MAIN);
2023-11-02 15:22:32 +00:00
2023-10-28 23:51:34 +01:00
g_rx_vfo_is_active = false;
g_rx_reception_mode = RX_MODE_NONE;
}
}
void APP_process_search(void)
{
if (g_current_display_screen != DISPLAY_SEARCH)
return;
2023-10-29 22:33:38 +00:00
2023-10-30 11:23:56 +00:00
g_search_freq_css_tick_10ms++;
2023-10-29 22:33:38 +00:00
2023-10-30 11:23:56 +00:00
if (g_search_tick_10ms > 0)
2023-10-28 23:51:34 +01:00
{
2023-10-30 11:23:56 +00:00
if (--g_search_tick_10ms > 0)
2023-10-28 23:51:34 +01:00
{
2023-11-22 11:21:53 +00:00
APP_process_keys();
2023-10-28 23:51:34 +01:00
return;
}
}
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
if (g_search_edit_state != SEARCH_EDIT_STATE_NONE)
{ // waiting for user input choice
2023-11-22 11:21:53 +00:00
APP_process_keys();
2023-10-28 23:51:34 +01:00
return;
}
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
g_update_display = true;
GUI_SelectNextDisplay(DISPLAY_SEARCH);
2023-10-29 22:33:38 +00:00
2023-10-30 11:23:56 +00:00
SEARCH_process();
2023-10-28 23:51:34 +01:00
}
void APP_process_transmit(void)
2023-10-29 22:33:38 +00:00
{
2023-10-28 23:51:34 +01:00
if (g_current_function != FUNCTION_TRANSMIT)
return;
#ifdef ENABLE_ALARM
if (g_alarm_state == ALARM_STATE_TXALARM || g_alarm_state == ALARM_STATE_ALARM)
{ // TX alarm tone
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
uint16_t Tone;
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
g_alarm_running_counter_10ms++;
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
// loop alarm tone frequency 300Hz ~ 1500Hz ~ 300Hz
Tone = 300 + (g_alarm_tone_counter_10ms++ * 50);
if (Tone >= ((1500 * 2) - 300))
{
Tone = 300;
g_alarm_tone_counter_10ms = 0;
}
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
BK4819_SetScrambleFrequencyControlWord((Tone <= 1500) ? Tone : (1500 * 2) - Tone);
2023-10-29 22:33:38 +00:00
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.alarm_mode == ALARM_MODE_TONE && g_alarm_running_counter_10ms == 512)
2023-10-28 23:51:34 +01:00
{
g_alarm_running_counter_10ms = 0;
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
if (g_alarm_state == ALARM_STATE_TXALARM)
{
g_alarm_state = ALARM_STATE_ALARM;
2023-10-29 22:33:38 +00:00
RADIO_enable_CxCSS_tail();
2023-11-09 05:59:50 +00:00
RADIO_ConfigureTXPower(g_tx_vfo);
2023-10-28 23:51:34 +01:00
BK4819_SetupPowerAmplifier(0, 0);
BK4819_set_GPIO_pin(BK4819_GPIO1_PIN29_PA_ENABLE, false); // PA off
BK4819_Enable_AfDac_DiscMode_TxDsp();
BK4819_set_GPIO_pin(BK4819_GPIO5_PIN1_RED, false); // LED off
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
GUI_DisplayScreen();
}
else
{
g_alarm_state = ALARM_STATE_TXALARM;
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
GUI_DisplayScreen();
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
RADIO_enableTX(false);
BK4819_TransmitTone(true, 500);
SYSTEM_DelayMs(2);
2023-10-29 22:33:38 +00:00
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-10-28 23:51:34 +01:00
g_alarm_tone_counter_10ms = 0;
}
}
}
#endif
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
// repeater tail tone elimination
if (g_rtte_count_down > 0)
{
if (--g_rtte_count_down == 0)
{
FUNCTION_Select(FUNCTION_FOREGROUND);
g_update_status = true;
g_update_display = true;
}
}
}
2023-10-28 23:59:51 +01:00
void APP_process_functions(void)
{
switch (g_current_function)
{
case FUNCTION_FOREGROUND:
APP_check_for_new_receive();
break;
case FUNCTION_TRANSMIT:
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.backlight_on_tx_rx == 1 || g_eeprom.config.setting.backlight_on_tx_rx == 3)
2023-11-10 16:45:07 +00:00
BACKLIGHT_turn_on(backlight_tx_rx_time_secs);
2023-10-28 23:59:51 +01:00
break;
case FUNCTION_NEW_RECEIVE:
APP_process_new_receive();
break;
2023-10-30 00:14:38 +00:00
2023-10-28 23:59:51 +01:00
case FUNCTION_RECEIVE:
APP_process_rx();
break;
case FUNCTION_POWER_SAVE:
if (!g_rx_idle_mode)
APP_check_for_new_receive();
break;
2023-10-29 22:33:38 +00:00
default:
break;
2023-10-28 23:59:51 +01:00
}
}
2023-10-28 23:51:34 +01:00
void APP_process_power_save(void)
{
2023-10-29 22:33:38 +00:00
bool power_save = true;
2023-10-30 00:14:38 +00:00
2023-11-18 18:44:10 +00:00
#ifdef ENABLE_PANADAPTER
if (g_eeprom.config.setting.panadapter)
power_save = false;
#endif
2023-10-29 22:33:38 +00:00
if (g_monitor_enabled ||
#ifdef ENABLE_FMRADIO
g_fm_radio_mode ||
2023-10-28 23:51:34 +01:00
#endif
2023-10-29 22:33:38 +00:00
g_ptt_is_pressed ||
g_fkey_pressed ||
g_key_pressed != KEY_INVALID ||
2023-11-02 10:00:51 +00:00
g_eeprom.config.setting.battery_save_ratio == 0 ||
2023-10-29 22:33:38 +00:00
g_scan_state_dir != SCAN_STATE_DIR_OFF ||
g_css_scan_mode != CSS_SCAN_MODE_OFF ||
g_current_display_screen != DISPLAY_MAIN ||
g_dtmf_call_state != DTMF_CALL_STATE_NONE ||
g_flash_light_state == FLASHLIGHT_SOS)
{
power_save = false;
}
2023-10-30 00:14:38 +00:00
2023-10-29 22:33:38 +00:00
#ifdef ENABLE_NOAA
2023-11-02 10:00:51 +00:00
if (IS_NOAA_CHANNEL(g_eeprom.config.setting.indices.vfo[0].screen) ||
2023-11-18 18:44:10 +00:00
IS_NOAA_CHANNEL(g_eeprom.config.setting.indices.vfo[1].screen) ||
g_noaa_mode)
2023-10-29 22:33:38 +00:00
{
power_save = false;
}
#endif
if (!power_save)
{
// if (g_current_function == FUNCTION_POWER_SAVE && g_rx_idle_mode)
// BK4819_RX_TurnOn();
2023-11-18 18:44:10 +00:00
2023-10-29 22:33:38 +00:00
if (g_current_function == FUNCTION_POWER_SAVE)
FUNCTION_Select(FUNCTION_RECEIVE); // come out of power save mode
2023-11-10 07:50:24 +00:00
g_power_save_pause_tick_10ms = power_save_pause_10ms; // stay out of power save mode
2023-10-28 23:51:34 +01:00
}
2023-10-29 22:33:38 +00:00
else
2023-11-10 07:50:24 +00:00
if (g_power_save_pause_done)
2023-10-29 22:33:38 +00:00
{ // enter power save
FUNCTION_Select(FUNCTION_POWER_SAVE);
}
2023-10-30 00:14:38 +00:00
2023-11-10 07:50:24 +00:00
g_power_save_pause_done = false;
2023-10-29 22:33:38 +00:00
2023-11-02 10:00:51 +00:00
// **************************
2023-10-28 23:51:34 +01:00
#ifdef ENABLE_VOICE
if (g_voice_write_index != 0)
return;
#endif
if (!g_power_save_expired || g_current_function != FUNCTION_POWER_SAVE)
return;
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
// wake up, enable RX then go back to sleep
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
if (g_rx_idle_mode)
{
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
//UART_SendText("ps wake up\r\n");
#endif
2023-10-29 22:33:38 +00:00
BK4819_Conditional_RX_TurnOn();
2023-10-28 23:51:34 +01:00
#ifdef ENABLE_VOX
if (g_eeprom.config.setting.vox_enabled)
RADIO_enable_vox(g_eeprom.config.setting.vox_level);
2023-10-28 23:51:34 +01:00
#endif
2023-10-29 22:33:38 +00:00
2023-11-02 10:00:51 +00:00
if (APP_toggle_dual_watch_vfo())
2023-10-28 23:51:34 +01:00
g_update_rssi = false;
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
FUNCTION_Init();
2023-10-29 22:33:38 +00:00
g_power_save_tick_10ms = power_save1_10ms; // come back here in a bit
g_rx_idle_mode = false; // RX is awake
2023-10-28 23:51:34 +01:00
}
else
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.dual_watch == DUAL_WATCH_OFF ||
2023-10-28 23:51:34 +01:00
g_scan_state_dir != SCAN_STATE_DIR_OFF ||
g_css_scan_mode != CSS_SCAN_MODE_OFF ||
g_update_rssi)
2023-11-02 10:00:51 +00:00
{ // go back to sleep
2023-10-29 22:33:38 +00:00
2023-11-18 18:54:06 +00:00
#ifdef ENABLE_PANADAPTER
if (!g_eeprom.config.setting.panadapter)
#endif
{
APP_update_rssi(g_rx_vfo_num, false);
2023-10-29 22:33:38 +00:00
2023-11-18 18:54:06 +00:00
// go back to sleep
2023-10-29 22:33:38 +00:00
2023-11-18 18:54:06 +00:00
g_power_save_tick_10ms = g_eeprom.config.setting.battery_save_ratio * 10;
g_rx_idle_mode = true;
2023-10-29 22:33:38 +00:00
2023-11-18 18:54:06 +00:00
BK4819_DisableVox();
BK4819_Sleep();
BK4819_set_GPIO_pin(BK4819_GPIO0_PIN28_RX_ENABLE, false);
}
2023-10-28 23:51:34 +01:00
}
else
2023-11-02 10:00:51 +00:00
if (APP_toggle_dual_watch_vfo())
2023-10-28 23:51:34 +01:00
{
2023-11-02 10:00:51 +00:00
g_update_rssi = true;
2023-10-29 22:33:38 +00:00
g_power_save_tick_10ms = power_save1_10ms;
2023-10-28 23:51:34 +01:00
}
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
g_power_save_expired = false;
}
2023-10-03 00:14:36 +01:00
2023-10-28 22:02:07 +01:00
// this is called once every 500ms
void APP_time_slice_500ms(void)
{
bool exit_menu = false;
2023-10-03 00:14:36 +01:00
2023-10-28 22:02:07 +01:00
if (g_key_input_count_down > 0)
{
if (--g_key_input_count_down == 0)
2023-09-09 08:03:56 +01:00
{
2023-10-28 22:02:07 +01:00
APP_cancel_user_input_modes();
if (g_beep_to_play != BEEP_NONE)
2023-09-09 08:03:56 +01:00
{
2023-11-02 11:53:22 +00:00
if (g_serial_config_tick_500ms == 0)
AUDIO_PlayBeep(g_beep_to_play);
2023-10-28 22:02:07 +01:00
g_beep_to_play = BEEP_NONE;
2023-09-09 08:03:56 +01:00
}
}
}
2023-11-02 11:53:22 +00:00
#ifdef ENABLE_AIRCOPY
if (g_current_display_screen == DISPLAY_AIRCOPY)
{ // we're in AIRCOPY mode
BOARD_ADC_GetBatteryInfo(&g_usb_current_voltage, &g_usb_current);
return;
}
#endif
if (g_keypad_locked > 0)
if (--g_keypad_locked == 0)
g_update_display = true;
if (g_serial_config_tick_500ms > 0)
{ // config upload/download is running
return;
}
2023-11-06 13:27:35 +00:00
if (g_current_function == FUNCTION_TRANSMIT)
{
if (g_tx_timer_tick_500ms < 6)
{ // <= 3 seconds left
if (g_tx_timer_tick_500ms & 1u)
BK4819_start_tone(880, 10, true, true);
else
BK4819_stop_tones(true);
}
if (g_tx_timer_tick_500ms & 1u)
g_update_display = true;
}
2023-10-31 10:07:29 +00:00
if (g_update_screen_tick_500ms > 0)
{ // update display once every 500ms
if (--g_update_screen_tick_500ms == 0)
{
RADIO_set_vfo_state(VFO_STATE_NORMAL);
g_update_status = true;
g_update_display = true;
}
//g_update_status = true;
//g_update_display = true;
}
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_MDC1200
if (mdc1200_rx_ready_tick_500ms > 0)
2023-09-09 08:03:56 +01:00
{
2023-10-28 22:02:07 +01:00
if (--mdc1200_rx_ready_tick_500ms == 0)
{
if (g_center_line == CENTER_LINE_MDC1200)
g_center_line = CENTER_LINE_NONE;
g_update_display = true;
2023-09-14 09:56:30 +01:00
}
2023-09-09 08:03:56 +01:00
}
2023-09-14 09:56:30 +01:00
#endif
2023-10-28 22:02:07 +01:00
if (g_dtmf_rx_live_timeout > 0)
2023-09-09 08:03:56 +01:00
{
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_RX_SIGNAL_BAR
if (g_center_line == CENTER_LINE_DTMF_DEC ||
g_center_line == CENTER_LINE_NONE) // wait till the center line is free for us to use before timing out
#endif
2023-09-09 08:03:56 +01:00
{
2023-10-28 22:02:07 +01:00
if (--g_dtmf_rx_live_timeout == 0)
{
2023-10-28 22:02:07 +01:00
if (g_dtmf_rx_live[0] != 0)
{
memset(g_dtmf_rx_live, 0, sizeof(g_dtmf_rx_live));
g_update_display = true;
}
}
2023-09-09 08:03:56 +01:00
}
2023-10-28 22:02:07 +01:00
}
2023-09-09 08:03:56 +01:00
2023-10-29 22:33:38 +00:00
if (g_menu_tick_10ms > 0)
if (--g_menu_tick_10ms == 0)
2023-10-28 22:02:07 +01:00
exit_menu = (g_current_display_screen == DISPLAY_MENU); // exit menu mode
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
if (g_dtmf_rx_timeout > 0)
if (--g_dtmf_rx_timeout == 0)
DTMF_clear_RX();
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_FMRADIO
if (g_fm_radio_tick_500ms > 0)
g_fm_radio_tick_500ms--;
2023-10-29 22:33:38 +00:00
2023-10-31 06:56:21 +00:00
// if (g_fm_radio_mode && g_current_display_screen == DISPLAY_FM && g_fm_scan_state_dir != FM_SCAN_STATE_DIR_OFF)
// g_update_display = true; // can't do this if not FM scanning, it causes audio clicks
2023-10-28 22:02:07 +01:00
#endif
2023-10-28 22:02:07 +01:00
if (g_reduced_service)
{
BOARD_ADC_GetBatteryInfo(&g_usb_current_voltage, &g_usb_current);
2023-11-02 10:00:51 +00:00
if (g_usb_current > 500 || g_eeprom.calib.battery[3] < g_usb_current_voltage)
2023-10-28 22:02:07 +01:00
{
#ifdef ENABLE_OVERLAY
overlay_FLASH_RebootToBootloader();
#else
NVIC_SystemReset();
#endif
}
2023-10-28 22:02:07 +01:00
return;
}
2023-10-28 22:02:07 +01:00
g_battery_check_counter++;
2023-10-29 22:33:38 +00:00
if ((g_battery_check_counter & 1u) == 0)
2023-10-28 22:02:07 +01:00
{
BOARD_ADC_GetBatteryInfo(&g_battery_voltages[g_battery_voltage_index++], &g_usb_current);
if (g_battery_voltage_index > 3)
g_battery_voltage_index = 0;
BATTERY_GetReadings(true);
}
2023-10-29 22:33:38 +00:00
// update every 2 sec
2023-10-28 22:02:07 +01:00
if ((g_battery_check_counter & 3) == 0)
{
2023-11-02 10:00:51 +00:00
if (g_charging_with_type_c || g_eeprom.config.setting.battery_text > 0)
2023-10-28 22:02:07 +01:00
g_update_status = true;
2023-10-29 22:33:38 +00:00
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_SHOW_CHARGE_LEVEL
if (g_charging_with_type_c)
g_update_display = true;
#endif
}
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_FMRADIO
2023-10-30 14:12:27 +00:00
if (g_fm_scan_state_dir == FM_SCAN_STATE_DIR_OFF || g_ask_to_save)
2023-10-28 22:02:07 +01:00
#endif
{
2023-11-02 11:53:22 +00:00
if (g_css_scan_mode == CSS_SCAN_MODE_OFF &&
g_scan_state_dir == SCAN_STATE_DIR_OFF &&
(g_current_display_screen != DISPLAY_SEARCH ||
g_search_css_state == SEARCH_CSS_STATE_FOUND ||
g_search_css_state == SEARCH_CSS_STATE_FAILED ||
g_search_css_state == SEARCH_CSS_STATE_REPEAT))
2023-10-28 22:02:07 +01:00
{
2023-11-02 11:53:22 +00:00
#ifdef ENABLE_KEYLOCK
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.auto_key_lock != 0 &&
2023-11-02 11:53:22 +00:00
g_key_lock_tick_500ms > 0 &&
2023-10-29 22:33:38 +00:00
!g_dtmf_input_mode &&
2023-11-02 11:53:22 +00:00
g_input_box_index == 0 &&
g_current_display_screen != DISPLAY_MENU)
2023-10-28 22:02:07 +01:00
{
if (--g_key_lock_tick_500ms == 0)
{ // lock the keyboard
2023-11-02 10:00:51 +00:00
g_eeprom.config.setting.key_lock = true;
g_update_status = true;
2023-10-28 22:02:07 +01:00
}
2023-09-09 08:03:56 +01:00
}
2023-11-02 11:53:22 +00:00
#endif
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
if (exit_menu)
{
g_menu_tick_10ms = 0;
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
if (g_eeprom.config.setting.backlight_time == 0)
2023-11-10 13:23:32 +00:00
BACKLIGHT_turn_off();
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
if (g_input_box_index > 0 || g_dtmf_input_mode)
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL);
2023-11-02 15:22:32 +00:00
/*
2023-11-02 11:53:22 +00:00
if (g_current_display_screen == DISPLAY_SEARCH)
{
BK4819_StopScan();
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
RADIO_configure_channel(0, VFO_CONFIGURE_RELOAD);
RADIO_configure_channel(1, VFO_CONFIGURE_RELOAD);
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
RADIO_setup_registers(true);
}
2023-11-02 15:22:32 +00:00
*/
2023-11-02 11:53:22 +00:00
DTMF_clear_input_box();
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
g_fkey_pressed = false;
g_input_box_index = 0;
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
g_ask_to_save = false;
g_ask_to_delete = false;
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
g_update_status = true;
g_update_display = true;
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
{
gui_display_type_t disp = DISPLAY_INVALID;
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
#ifdef ENABLE_FMRADIO
if (g_fm_radio_mode &&
g_current_function != FUNCTION_RECEIVE &&
g_current_function != FUNCTION_TRANSMIT &&
!g_monitor_enabled)
2023-10-28 22:02:07 +01:00
{
2023-11-02 11:53:22 +00:00
disp = DISPLAY_FM;
}
2023-11-02 11:53:22 +00:00
#endif
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
if (disp == DISPLAY_INVALID)
{
#ifndef ENABLE_CODE_SEARCH_TIMEOUT
if (g_current_display_screen != DISPLAY_SEARCH)
#endif
disp = DISPLAY_MAIN;
2023-10-28 22:02:07 +01:00
}
2023-11-02 15:22:32 +00:00
2023-11-02 11:53:22 +00:00
if (disp != DISPLAY_INVALID)
GUI_SelectNextDisplay(disp);
}
2023-10-28 22:02:07 +01:00
}
2023-11-02 15:22:32 +00:00
}
2023-10-28 22:02:07 +01:00
}
2023-11-10 07:31:50 +00:00
// if (g_current_function != FUNCTION_POWER_SAVE && g_current_function != FUNCTION_TRANSMIT)
// APP_update_rssi(g_rx_vfo_num, false);
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
if (g_low_battery)
{
2023-10-29 22:33:38 +00:00
g_low_battery_blink = ++g_low_battery_tick_10ms & 1;
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
UI_DisplayBattery(0, g_low_battery_blink);
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
if (g_current_function != FUNCTION_TRANSMIT)
{ // not transmitting
2023-09-09 08:03:56 +01:00
2023-10-29 22:33:38 +00:00
if (g_low_battery_tick_10ms < 30)
2023-10-28 22:02:07 +01:00
{
2023-10-29 22:33:38 +00:00
if (g_low_battery_tick_10ms == 29 && !g_charging_with_type_c)
2023-10-28 22:02:07 +01:00
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
}
else
{
2023-10-29 22:33:38 +00:00
g_low_battery_tick_10ms = 0;
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
if (!g_charging_with_type_c)
{ // not on charge
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP);
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_LOW_VOLTAGE);
#endif
2023-10-03 00:14:36 +01:00
2023-10-28 22:02:07 +01:00
if (g_battery_display_level == 0)
{
#ifdef ENABLE_VOICE
AUDIO_PlaySingleVoice(true);
#endif
2023-10-28 22:02:07 +01:00
g_reduced_service = true;
2023-11-19 06:59:38 +00:00
#ifdef ENABLE_PANADAPTER
PAN_process_10ms(); // disable the panadapter
#endif
2023-10-28 22:02:07 +01:00
FUNCTION_Select(FUNCTION_POWER_SAVE);
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
ST7565_HardwareReset();
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.backlight_time < (ARRAY_SIZE(g_sub_menu_backlight) - 1))
2023-11-10 13:23:32 +00:00
BACKLIGHT_turn_off();
2023-10-28 22:02:07 +01:00
}
#ifdef ENABLE_VOICE
else
AUDIO_PlaySingleVoice(false);
#endif
}
}
}
}
2023-09-09 08:03:56 +01:00
2023-10-29 22:33:38 +00:00
#ifdef ENABLE_FMRADIO
if (g_current_function != FUNCTION_TRANSMIT)
{
if (g_fm_resume_tick_500ms > 0)
{
2023-10-31 06:56:21 +00:00
if (g_fm_radio_mode)
2023-10-29 22:33:38 +00:00
{
2023-10-31 06:56:21 +00:00
if (--g_fm_resume_tick_500ms == 0)
{
if (g_current_function != FUNCTION_RECEIVE && g_fm_radio_mode)
{ // switch back to FM radio mode
if (g_current_display_screen != DISPLAY_FM)
2023-11-03 16:41:05 +00:00
{
2023-10-31 06:56:21 +00:00
FM_turn_on();
2023-11-03 16:41:05 +00:00
GUI_SelectNextDisplay(DISPLAY_FM);
}
2023-10-31 06:56:21 +00:00
}
2023-10-29 22:33:38 +00:00
}
2023-10-31 06:56:21 +00:00
GUI_SelectNextDisplay(DISPLAY_FM);
2023-10-29 22:33:38 +00:00
}
2023-10-31 06:56:21 +00:00
else
FM_turn_off();
2023-10-29 22:33:38 +00:00
}
}
2023-10-30 00:14:38 +00:00
2023-10-29 22:33:38 +00:00
if (g_fm_radio_mode && g_fm_radio_tick_500ms == 0)
return;
#endif
2023-10-28 22:02:07 +01:00
if (g_current_function != FUNCTION_TRANSMIT)
{
2023-10-28 22:02:07 +01:00
if (g_dtmf_decode_ring_tick_500ms > 0)
{ // make "ring-ring" sound
g_dtmf_decode_ring_tick_500ms--;
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_DTMF_CALL_FLASH_LIGHT
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); // light on
#endif
AUDIO_PlayBeep(BEEP_880HZ_200MS);
#ifdef ENABLE_DTMF_CALL_FLASH_LIGHT
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_FLASHLIGHT); // light off
#endif
}
}
2023-10-28 22:02:07 +01:00
else
g_dtmf_decode_ring_tick_500ms = 0;
2023-10-07 15:12:53 +01:00
2023-10-28 22:02:07 +01:00
if (g_dtmf_call_state != DTMF_CALL_STATE_NONE &&
g_current_function != FUNCTION_TRANSMIT &&
g_current_function != FUNCTION_RECEIVE)
{
if (g_dtmf_auto_reset_time_500ms > 0)
{
2023-10-28 22:02:07 +01:00
if (--g_dtmf_auto_reset_time_500ms == 0)
{
2023-11-02 10:00:51 +00:00
if (g_dtmf_call_state == DTMF_CALL_STATE_RECEIVED && g_eeprom.config.setting.dtmf.auto_reset_time >= DTMF_HOLD_MAX)
2023-10-28 22:02:07 +01:00
g_dtmf_call_state = DTMF_CALL_STATE_RECEIVED_STAY; // keep message on-screen till a key is pressed
else
g_dtmf_call_state = DTMF_CALL_STATE_NONE;
g_update_display = true;
}
}
2023-10-28 08:46:27 +01:00
2023-10-28 22:02:07 +01:00
// if (g_dtmf_call_state != DTMF_CALL_STATE_RECEIVED_STAY)
// {
// g_dtmf_call_state = DTMF_CALL_STATE_NONE;
// g_update_display = true;
// }
}
if (g_dtmf_is_tx && g_dtmf_tx_stop_tick_500ms > 0)
2023-09-29 20:48:23 +01:00
{
2023-10-28 22:02:07 +01:00
if (--g_dtmf_tx_stop_tick_500ms == 0)
2023-09-29 20:48:23 +01:00
{
2023-10-28 22:02:07 +01:00
g_dtmf_is_tx = false;
g_update_display = true;
2023-09-29 20:48:23 +01:00
}
}
2023-10-28 22:02:07 +01:00
}
2023-10-28 22:02:07 +01:00
void APP_time_slice_10ms(void)
{
g_flash_light_blink_tick_10ms++;
2023-09-30 11:22:19 +01:00
2023-11-10 13:23:32 +00:00
if (g_backlight_tick_10ms > 0 &&
!g_ask_to_save &&
g_css_scan_mode == CSS_SCAN_MODE_OFF &&
g_current_display_screen != DISPLAY_AIRCOPY)
2023-11-10 17:02:04 +00:00
{ // don't turn off backlight if user is in backlight menu option
if (g_current_display_screen != DISPLAY_MENU || g_menu_cursor != MENU_AUTO_BACKLITE)
2023-11-10 13:23:32 +00:00
if (g_eeprom.config.setting.backlight_time < (ARRAY_SIZE(g_sub_menu_backlight) - 1))
2023-11-10 17:02:04 +00:00
if (--g_backlight_tick_10ms <= BACKLIGHT_MAX_BRIGHTNESS)
2023-11-10 13:23:32 +00:00
BACKLIGHT_set_brightness(g_backlight_tick_10ms);
}
2023-11-06 12:21:52 +00:00
if (g_flag_save_vfo)
{
SETTINGS_save_vfo_indices();
g_flag_save_vfo = false;
}
if (g_flag_save_settings)
{
SETTINGS_save();
g_flag_save_settings = false;
}
if (g_request_display_screen != DISPLAY_INVALID)
{
GUI_SelectNextDisplay(g_request_display_screen);
g_request_display_screen = DISPLAY_INVALID;
}
if (g_update_display)
GUI_DisplayScreen();
if (g_update_status)
UI_DisplayStatus(false);
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_AIRCOPY
if (g_current_display_screen == DISPLAY_AIRCOPY)
{ // we're in AIRCOPY mode
2023-10-28 23:51:34 +01:00
2023-10-28 22:02:07 +01:00
if (g_aircopy_state == AIRCOPY_TX)
AIRCOPY_process_fsk_tx_10ms();
2023-10-28 23:51:34 +01:00
2023-10-28 22:02:07 +01:00
AIRCOPY_process_fsk_rx_10ms();
2023-10-28 23:51:34 +01:00
2023-11-22 11:21:53 +00:00
APP_process_keys();
2023-10-28 22:02:07 +01:00
return;
}
#endif
2023-09-09 08:03:56 +01:00
2023-11-06 12:21:52 +00:00
if (g_flag_save_channel)
{
SETTINGS_save_channel(g_tx_vfo->channel_save, g_eeprom.config.setting.tx_vfo_num, g_tx_vfo, g_flag_save_channel ? 1 : 0);
g_flag_save_channel = false;
RADIO_configure_channel(g_eeprom.config.setting.tx_vfo_num, VFO_CONFIGURE);
RADIO_setup_registers(true);
if (g_monitor_enabled)
APP_start_listening();
GUI_SelectNextDisplay(DISPLAY_MAIN);
}
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_UART
if (UART_IsCommandAvailable())
2023-09-14 09:56:30 +01:00
{
2023-10-28 22:02:07 +01:00
__disable_irq();
UART_HandleCommand();
__enable_irq();
2023-09-14 09:56:30 +01:00
}
#endif
2023-10-28 23:51:34 +01:00
2023-10-28 22:02:07 +01:00
if (g_current_function == FUNCTION_TRANSMIT && (g_tx_timeout_reached || g_serial_config_tick_500ms > 0))
{ // transmitter timed out or must de-key
2023-11-06 12:21:52 +00:00
BK4819_stop_tones(true);
2023-10-28 22:02:07 +01:00
g_tx_timeout_reached = false;
g_flag_end_tx = true;
2023-10-28 22:02:07 +01:00
APP_end_tx();
2023-09-30 11:22:19 +01:00
2023-10-28 22:02:07 +01:00
AUDIO_PlayBeep(BEEP_880HZ_60MS_TRIPLE_BEEP);
2023-09-30 11:22:19 +01:00
RADIO_set_vfo_state(VFO_STATE_TIMEOUT);
2023-10-28 22:02:07 +01:00
GUI_DisplayScreen();
2023-09-09 08:03:56 +01:00
}
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_UART
if (g_serial_config_tick_500ms > 0)
return;
#endif
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_AM_FIX
2023-11-19 06:59:38 +00:00
#ifdef ENABLE_PANADAPTER
if (!PAN_scanning())
#endif
if (g_rx_vfo->channel.mod_mode != MOD_MODE_FM && g_eeprom.config.setting.am_fix)
2023-11-18 18:54:06 +00:00
AM_fix_10ms(g_rx_vfo_num);
2023-10-28 22:02:07 +01:00
#endif
2023-09-09 08:03:56 +01:00
2023-10-28 22:02:07 +01:00
#ifdef ENABLE_FMRADIO
if (g_flag_save_fm)
{
2023-10-28 23:51:34 +01:00
SETTINGS_save_fm();
g_flag_save_fm = false;
}
#endif
2023-10-28 22:02:07 +01:00
2023-10-28 23:59:51 +01:00
if (g_reduced_service || g_serial_config_tick_500ms > 0)
2023-10-28 23:51:34 +01:00
{
if (g_current_function == FUNCTION_TRANSMIT)
g_tx_timeout_reached = true;
2023-10-28 22:02:07 +01:00
2023-10-28 23:51:34 +01:00
return;
}
2023-10-28 22:02:07 +01:00
2023-10-28 23:51:34 +01:00
// ***************************************************
2023-10-28 22:02:07 +01:00
2023-10-29 22:33:38 +00:00
#ifdef ENABLE_BOOT_BEEPS
if (g_boot_tick_10ms > 0 && (g_boot_tick_10ms % 25) == 0)
AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL);
#endif
2023-11-19 06:59:38 +00:00
#ifdef ENABLE_PANADAPTER
if (!PAN_scanning())
#endif
{
// 1of11
// if (g_update_rssi)
if (g_current_function != FUNCTION_POWER_SAVE && g_current_function != FUNCTION_TRANSMIT)
if (!g_flag_save_channel)
APP_update_rssi(g_rx_vfo_num, false);
2023-11-10 07:31:50 +00:00
2023-11-19 06:59:38 +00:00
if (g_current_function != FUNCTION_POWER_SAVE || !g_rx_idle_mode)
APP_process_radio_interrupts();
}
2023-10-28 22:02:07 +01:00
2023-10-28 23:59:51 +01:00
APP_process_functions();
2023-11-10 07:31:50 +00:00
APP_process_flash_light_10ms();
2023-10-28 23:51:34 +01:00
if (g_current_function == FUNCTION_TRANSMIT)
{ // transmitting
#ifdef ENABLE_TX_AUDIO_BAR
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.mic_bar && (g_flash_light_blink_tick_10ms % (150 / 10)) == 0 && !g_update_display) // once every 150ms
2023-10-28 23:51:34 +01:00
UI_DisplayAudioBar(true);
#endif
}
2023-10-28 22:02:07 +01:00
2023-10-28 23:59:51 +01:00
#ifdef ENABLE_VOICE
if (g_flag_play_queued_voice)
{
g_flag_play_queued_voice = false;
AUDIO_PlayQueuedVoice();
}
#endif
2023-10-28 23:51:34 +01:00
#ifdef ENABLE_FMRADIO
if (g_fm_radio_mode && g_fm_radio_tick_500ms > 0)
return;
#endif
2023-10-28 22:02:07 +01:00
2023-10-28 23:51:34 +01:00
#ifdef ENABLE_VOX
2023-10-29 22:33:38 +00:00
if (g_vox_resume_tick_10ms > 0)
g_vox_resume_tick_10ms--;
2023-10-28 22:02:07 +01:00
2023-10-29 22:33:38 +00:00
if (g_vox_pause_tick_10ms > 0)
g_vox_pause_tick_10ms--;
2023-10-28 22:02:07 +01:00
if (g_eeprom.config.setting.vox_enabled)
2023-10-28 23:59:51 +01:00
APP_process_vox();
#endif
2023-10-28 23:51:34 +01:00
APP_process_transmit();
2023-10-29 22:33:38 +00:00
2023-10-28 23:59:51 +01:00
#ifdef ENABLE_FMRADIO
2023-11-10 07:31:50 +00:00
if (g_fm_radio_mode && g_fm_restore_tick_10ms > 0)
{
if (--g_fm_restore_tick_10ms == 0)
{ // switch back to FM radio mode
FM_turn_on();
GUI_SelectNextDisplay(DISPLAY_FM);
}
}
2023-10-30 16:28:41 +00:00
if (g_fm_schedule &&
2023-10-30 14:12:27 +00:00
g_fm_scan_state_dir != FM_SCAN_STATE_DIR_OFF &&
!g_monitor_enabled &&
g_current_function != FUNCTION_RECEIVE &&
2023-10-28 23:59:51 +01:00
g_current_function != FUNCTION_TRANSMIT)
{ // switch to FM radio mode
2023-10-30 14:12:27 +00:00
FM_scan();
2023-10-30 16:28:41 +00:00
g_fm_schedule = false;
2023-10-28 23:59:51 +01:00
}
#endif
2023-11-18 18:44:10 +00:00
#ifdef ENABLE_PANADAPTER
2023-11-19 06:59:38 +00:00
PAN_process_10ms();
2023-11-18 18:44:10 +00:00
#endif
2023-10-28 23:59:51 +01:00
APP_process_power_save();
2023-10-28 23:51:34 +01:00
APP_process_scan();
2023-10-29 22:33:38 +00:00
2023-10-28 23:51:34 +01:00
APP_process_search();
2023-10-29 22:33:38 +00:00
2023-11-22 11:21:53 +00:00
APP_process_keys();
2023-10-28 22:02:07 +01:00
}
static void APP_process_key(const key_code_t Key, const bool key_pressed, const bool key_held)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
bool flag = false;
2023-09-09 08:03:56 +01:00
#ifdef ENABLE_AIRCOPY
if (g_current_display_screen == DISPLAY_AIRCOPY)
{
AIRCOPY_process_key(key, key_pressed, key_held);
return;
}
#endif
if (Key == KEY_INVALID && !key_pressed && !key_held)
return;
// reset the state so as to remove it from the screen
2023-10-08 20:23:37 +01:00
if (Key != KEY_INVALID && Key != KEY_PTT)
RADIO_set_vfo_state(VFO_STATE_NORMAL);
2023-11-10 16:45:07 +00:00
#if 1
// remember the current backlight state (on / off)
if (Key == KEY_EXIT && !BACKLIGHT_is_on() && g_eeprom.config.setting.backlight_time > 0)
{ // just turn the back light on for now so the user can see what's what
if (!key_pressed && !key_held)
{ // key has been released
2023-11-10 13:23:32 +00:00
BACKLIGHT_turn_on(0);
}
2023-10-08 20:23:37 +01:00
g_beep_to_play = BEEP_NONE;
return;
}
#endif
// turn the backlight on
if (key_pressed)
2023-10-16 18:19:28 +01:00
if (Key != KEY_PTT)
2023-11-10 13:23:32 +00:00
BACKLIGHT_turn_on(0);
2023-10-08 20:23:37 +01:00
if (g_current_function == FUNCTION_POWER_SAVE)
2023-09-09 08:03:56 +01:00
FUNCTION_Select(FUNCTION_FOREGROUND);
// stay awake - for now
2023-11-10 07:50:24 +00:00
g_power_save_pause_tick_10ms = power_save_pause_10ms;
g_power_save_pause_done = false;
2023-09-09 08:03:56 +01:00
#ifdef ENABLE_KEYLOCK
2023-11-05 10:48:37 +00:00
// keep the auto keylock at bay
if (g_eeprom.config.setting.auto_key_lock != 0)
g_key_lock_tick_500ms = key_lock_timeout_500ms;
#endif
2023-09-09 08:03:56 +01:00
if (g_fkey_pressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2))
{ // cancel the F-key
g_fkey_pressed = false;
g_update_status = true;
}
// ********************
2023-11-02 10:00:51 +00:00
#ifdef ENABLE_KEYLOCK
if (g_eeprom.config.setting.key_lock && g_current_function != FUNCTION_TRANSMIT && Key != KEY_PTT)
{ // keyboard is locked
if (Key == KEY_F)
{ // function/key-lock key
if (!key_pressed)
return;
if (key_held)
{ // unlock the keypad
2023-11-02 11:53:22 +00:00
g_eeprom.config.setting.key_lock = false;
g_request_save_settings = true;
g_update_status = true;
#ifdef ENABLE_VOICE
g_another_voice_id = VOICE_ID_UNLOCK;
#endif
AUDIO_PlayBeep(BEEP_1KHZ_60MS_OPTIONAL);
}
return;
}
if (Key != KEY_SIDE1 && Key != KEY_SIDE2)
{
if (!key_pressed || key_held)
return;
// keypad is locked, let the user know
g_keypad_locked = 4; // 2 second pop-up
g_update_display = true;
#ifdef ENABLE_FMRADIO
if (!g_fm_radio_mode) // don't beep when the FM radio is on, it cause bad gaps and loud clicks
2023-10-11 18:32:10 +01:00
#endif
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
return;
}
}
2023-11-02 10:00:51 +00:00
#endif
// ********************
2023-09-09 08:03:56 +01:00
if (Key == KEY_EXIT && key_held && key_pressed)
{ // exit key held pressed
// clear the live DTMF decoder
if (g_dtmf_rx_live[0] != 0)
2023-09-09 08:03:56 +01:00
{
memset(g_dtmf_rx_live, 0, sizeof(g_dtmf_rx_live));
g_dtmf_rx_live_timeout = 0;
g_update_display = true;
2023-10-04 10:01:07 +01:00
}
// cancel user input
APP_cancel_user_input_modes();
}
if (key_pressed && g_current_display_screen == DISPLAY_MENU)
2023-10-29 22:33:38 +00:00
g_menu_tick_10ms = menu_timeout_500ms;
2023-09-30 11:22:19 +01:00
// cancel the ringing
if (key_pressed && g_dtmf_decode_ring_tick_500ms > 0)
g_dtmf_decode_ring_tick_500ms = 0;
2023-09-30 11:22:19 +01:00
// ********************
2023-09-09 08:03:56 +01:00
2023-10-10 00:00:22 +01:00
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wtype-limits"
// if (g_scan_state_dir != SCAN_STATE_DIR_OFF || g_css_scan_mode != CSS_SCAN_MODE_OFF)
if (g_css_scan_mode != CSS_SCAN_MODE_OFF)
{ // FREQ/CTCSS/CDCSS scanning
if ((Key >= KEY_0 && Key <= KEY_9) || Key == KEY_F)
{
2023-10-08 20:23:37 +01:00
if (key_pressed && !key_held)
AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL);
return;
}
2023-09-09 08:03:56 +01:00
}
2023-10-10 00:00:22 +01:00
#pragma GCC diagnostic pop
// ********************
2023-10-15 22:34:21 +01:00
if (g_ptt_was_pressed)
2023-09-09 08:03:56 +01:00
{
2023-10-15 22:34:21 +01:00
if (Key == KEY_PTT)
2023-09-09 08:03:56 +01:00
{
2023-10-15 22:34:21 +01:00
flag = key_held;
if (!key_pressed)
{
flag = true;
g_ptt_was_pressed = false;
}
2023-09-09 08:03:56 +01:00
}
2023-10-15 22:34:21 +01:00
// g_ptt_was_pressed = false;
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
2023-10-18 20:44:33 +01:00
// UART_printf("proc key 1 %3u %u %u %u %u\r\n", Key, key_pressed, key_held, g_fkey_pressed, flag);
2023-10-15 22:34:21 +01:00
#endif
2023-09-09 08:03:56 +01:00
}
// this bit of code has caused soooooo many problems due
// to this causing key releases to be ignored :( .. 1of11
2023-10-15 22:34:21 +01:00
if (g_ptt_was_released)
2023-09-09 08:03:56 +01:00
{
2023-10-15 22:34:21 +01:00
// if (Key != KEY_PTT)
if (Key == KEY_PTT)
2023-09-09 08:03:56 +01:00
{
2023-10-15 22:34:21 +01:00
if (key_held)
flag = true;
if (key_pressed) // I now use key released for button press detections
{
flag = true;
g_ptt_was_released = false;
}
2023-10-10 00:00:22 +01:00
}
2023-10-15 22:34:21 +01:00
// g_ptt_was_released = false;
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
2023-10-18 20:44:33 +01:00
// UART_printf("proc key 2 %3u %u %u %u %u\r\n", Key, key_pressed, key_held, g_fkey_pressed, flag);
#endif
2023-09-09 08:03:56 +01:00
}
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
2023-10-18 20:44:33 +01:00
// UART_printf("proc key 3 %3u %u %u %u %u\r\n", Key, key_pressed, key_held, g_fkey_pressed, flag);
#endif
if (!flag) // this flag is responsible for keys being ignored :(
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (g_current_function == FUNCTION_TRANSMIT)
2023-09-14 09:56:30 +01:00
{ // transmitting
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
2023-10-08 20:23:37 +01:00
if (g_alarm_state == ALARM_STATE_OFF)
2023-09-09 09:01:52 +01:00
#endif
2023-09-09 08:03:56 +01:00
{
char Code;
2023-09-09 08:03:56 +01:00
if (Key == KEY_PTT)
{
2023-10-08 20:23:37 +01:00
GENERIC_Key_PTT(key_pressed);
goto Skip;
}
if (Key == KEY_SIDE2)
{ // transmit 1750Hz tone
Code = 0xFE;
2023-09-09 08:03:56 +01:00
}
else
{
Code = DTMF_GetCharacter(Key - KEY_0);
if (Code == 0xFF)
goto Skip;
2023-10-07 15:12:53 +01:00
// transmit DTMF keys
}
2023-10-07 15:12:53 +01:00
2023-10-08 20:23:37 +01:00
if (!key_pressed || key_held)
{
2023-10-08 20:23:37 +01:00
if (!key_pressed)
2023-09-09 08:03:56 +01:00
{
2023-10-18 11:31:30 +01:00
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-10-07 15:12:53 +01:00
BK4819_ExitDTMF_TX(false);
2023-10-07 15:12:53 +01:00
2023-11-04 02:33:04 +00:00
if (g_eeprom.config.setting.enable_scrambler)
BK4819_set_scrambler(g_current_vfo->channel.scrambler);
else
2023-11-04 02:33:04 +00:00
BK4819_set_scrambler(0);
2023-09-09 08:03:56 +01:00
}
}
else
{
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.dtmf.side_tone)
{ // user will here the DTMF tones in speaker
2023-10-18 11:31:30 +01:00
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER);
2023-09-09 08:03:56 +01:00
}
2023-10-07 15:12:53 +01:00
2023-11-04 02:33:04 +00:00
BK4819_set_scrambler(0);
2023-10-07 15:12:53 +01:00
if (Code == 0xFE)
2023-11-02 10:00:51 +00:00
BK4819_TransmitTone(g_eeprom.config.setting.dtmf.side_tone, 1750);
2023-09-09 08:03:56 +01:00
else
2023-11-02 10:00:51 +00:00
BK4819_PlayDTMFEx(g_eeprom.config.setting.dtmf.side_tone, Code);
2023-09-09 08:03:56 +01:00
}
}
#if defined(ENABLE_ALARM) || defined(ENABLE_TX1750)
2023-09-09 08:03:56 +01:00
else
2023-10-08 20:23:37 +01:00
if ((!key_held && key_pressed) || (g_alarm_state == ALARM_STATE_TX1750 && key_held && !key_pressed))
2023-09-09 09:01:52 +01:00
{
APP_alarm_off();
2023-09-10 18:11:25 +01:00
2023-11-02 10:00:51 +00:00
if (g_eeprom.config.setting.repeater_tail_tone_elimination == 0)
FUNCTION_Select(FUNCTION_FOREGROUND);
2023-09-09 09:01:52 +01:00
else
2023-11-02 10:00:51 +00:00
g_rtte_count_down = g_eeprom.config.setting.repeater_tail_tone_elimination * 10;
2023-09-10 18:11:25 +01:00
2023-09-09 09:01:52 +01:00
if (Key == KEY_PTT)
2023-10-08 20:23:37 +01:00
g_ptt_was_pressed = true;
2023-09-09 09:01:52 +01:00
else
2023-10-15 22:34:21 +01:00
// if (!key_held)
2023-10-08 20:23:37 +01:00
g_ptt_was_released = true;
2023-09-09 09:01:52 +01:00
}
#endif
2023-09-09 08:03:56 +01:00
}
else
if (Key != KEY_SIDE1 && Key != KEY_SIDE2)
{
switch (g_current_display_screen)
2023-09-09 08:03:56 +01:00
{
case DISPLAY_MAIN:
MAIN_process_key(Key, key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
#ifdef ENABLE_FMRADIO
2023-09-14 09:56:30 +01:00
case DISPLAY_FM:
FM_process_key(Key, key_pressed, key_held);
2023-09-14 09:56:30 +01:00
break;
#endif
2023-09-09 08:03:56 +01:00
case DISPLAY_MENU:
MENU_process_key(Key, key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
case DISPLAY_SEARCH:
SEARCH_process_key(Key, key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_AIRCOPY
2023-09-09 08:03:56 +01:00
case DISPLAY_AIRCOPY:
AIRCOPY_process_key(Key, key_pressed, key_held);
2023-09-09 08:03:56 +01:00
break;
#endif
2023-09-14 09:56:30 +01:00
case DISPLAY_INVALID:
2023-09-09 08:03:56 +01:00
default:
break;
}
}
else
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_AIRCOPY
if (g_current_display_screen != DISPLAY_SEARCH && g_current_display_screen != DISPLAY_AIRCOPY)
2023-09-09 08:03:56 +01:00
#else
if (g_current_display_screen != DISPLAY_SEARCH)
2023-09-09 08:03:56 +01:00
#endif
2023-09-14 09:56:30 +01:00
{
2023-10-16 06:54:27 +01:00
ACTION_process(Key, key_pressed, key_held);
2023-09-14 09:56:30 +01:00
}
2023-09-09 08:03:56 +01:00
else
2023-10-11 18:32:10 +01:00
{
#ifdef ENABLE_FMRADIO
2023-10-11 18:32:10 +01:00
if (!g_fm_radio_mode)
#endif
if (!key_held && key_pressed)
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
}
2023-09-09 08:03:56 +01:00
}
Skip:
2023-10-08 20:23:37 +01:00
if (g_beep_to_play != BEEP_NONE)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
AUDIO_PlayBeep(g_beep_to_play);
g_beep_to_play = BEEP_NONE;
2023-09-09 08:03:56 +01:00
}
2023-10-14 09:43:53 +01:00
if (g_flag_accept_setting)
2023-09-09 08:03:56 +01:00
{
2023-10-29 22:33:38 +00:00
g_menu_tick_10ms = menu_timeout_500ms;
2023-09-09 08:03:56 +01:00
MENU_AcceptSetting();
2023-11-10 07:31:50 +00:00
g_update_menu = true;
g_flag_accept_setting = false;
2023-09-09 08:03:56 +01:00
}
if (g_search_flag_stop_scan)
2023-09-09 08:03:56 +01:00
{
BK4819_StopScan();
g_search_flag_stop_scan = false;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
if (g_request_save_settings)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (!key_held)
2023-10-19 14:21:37 +01:00
SETTINGS_save();
2023-09-09 08:03:56 +01:00
else
2023-10-14 09:43:53 +01:00
g_flag_save_settings = 1;
2023-10-08 20:23:37 +01:00
g_request_save_settings = false;
g_update_status = true;
2023-09-09 08:03:56 +01:00
}
#ifdef ENABLE_FMRADIO
2023-10-08 20:23:37 +01:00
if (g_request_save_fm)
2023-09-14 09:56:30 +01:00
{
2023-10-08 20:23:37 +01:00
if (!key_held)
2023-10-19 14:21:37 +01:00
SETTINGS_save_fm();
2023-09-14 09:56:30 +01:00
else
2023-10-14 09:43:53 +01:00
g_flag_save_fm = true;
2023-10-08 20:23:37 +01:00
g_request_save_fm = false;
2023-09-14 09:56:30 +01:00
}
#endif
2023-10-08 20:23:37 +01:00
if (g_request_save_vfo)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (!key_held)
2023-10-19 14:21:37 +01:00
SETTINGS_save_vfo_indices();
2023-09-09 08:03:56 +01:00
else
2023-10-14 09:43:53 +01:00
g_flag_save_vfo = true;
2023-10-08 20:23:37 +01:00
g_request_save_vfo = false;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
if (g_request_save_channel > 0)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (!key_held)
2023-09-09 08:03:56 +01:00
{
2023-11-02 10:00:51 +00:00
SETTINGS_save_channel(g_tx_vfo->channel_save, g_eeprom.config.setting.tx_vfo_num, g_tx_vfo, g_request_save_channel);
2023-10-03 00:14:36 +01:00
if (g_current_display_screen != DISPLAY_SEARCH)
if (g_vfo_configure_mode == VFO_CONFIGURE_NONE) // don't wipe previous variable setting
2023-10-08 20:23:37 +01:00
g_vfo_configure_mode = VFO_CONFIGURE;
2023-09-09 08:03:56 +01:00
}
else
{
g_flag_save_channel = g_request_save_channel;
2023-10-03 00:14:36 +01:00
2023-10-08 20:23:37 +01:00
if (g_request_display_screen == DISPLAY_INVALID)
g_request_display_screen = DISPLAY_MAIN;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
g_request_save_channel = 0;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
if (g_vfo_configure_mode != VFO_CONFIGURE_NONE)
2023-09-09 08:03:56 +01:00
{
2023-10-08 20:23:37 +01:00
if (g_flag_reset_vfos)
2023-09-09 08:03:56 +01:00
{
RADIO_configure_channel(0, g_vfo_configure_mode);
RADIO_configure_channel(1, g_vfo_configure_mode);
2023-09-09 08:03:56 +01:00
}
else
{
2023-11-02 10:00:51 +00:00
RADIO_configure_channel(g_eeprom.config.setting.tx_vfo_num, g_vfo_configure_mode);
}
2023-10-08 20:23:37 +01:00
if (g_request_display_screen == DISPLAY_INVALID)
g_request_display_screen = DISPLAY_MAIN;
2023-09-09 08:03:56 +01:00
2023-10-08 20:23:37 +01:00
g_flag_reconfigure_vfos = true;
g_vfo_configure_mode = VFO_CONFIGURE_NONE;
g_flag_reset_vfos = false;
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
if (g_flag_reconfigure_vfos)
2023-09-09 08:03:56 +01:00
{
RADIO_select_vfos();
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_NOAA
2023-09-09 08:03:56 +01:00
RADIO_ConfigureNOAA();
#endif
2023-09-14 09:56:30 +01:00
RADIO_setup_registers(true);
2023-09-09 08:03:56 +01:00
2023-11-02 10:00:51 +00:00
// g_tx_vfo->freq_in_channel = SETTINGS_find_channel(frequency);
2023-10-19 14:21:37 +01:00
g_dtmf_auto_reset_time_500ms = 0;
g_dtmf_call_state = DTMF_CALL_STATE_NONE;
g_dtmf_tx_stop_tick_500ms = 0;
g_dtmf_is_tx = false;
2023-09-09 08:03:56 +01:00
g_vfo_rssi_bar_level[0] = 0;
g_vfo_rssi_bar_level[1] = 0;
2023-09-09 08:03:56 +01:00
if (g_squelch_open || g_monitor_enabled)
2023-10-29 22:33:38 +00:00
APP_start_listening();
2023-10-30 00:14:38 +00:00
2023-10-18 22:20:53 +01:00
g_flag_reconfigure_vfos = false;
2023-09-09 08:03:56 +01:00
}
2023-11-10 07:31:50 +00:00
if (g_update_menu)
2023-09-09 08:03:56 +01:00
{
2023-11-10 07:31:50 +00:00
g_update_menu = false;
2023-10-29 22:33:38 +00:00
g_menu_tick_10ms = menu_timeout_500ms;
MENU_ShowCurrentSetting();
2023-09-09 08:03:56 +01:00
}
if (g_search_flag_start_scan)
2023-09-09 08:03:56 +01:00
{
g_search_flag_start_scan = false;
2023-09-30 11:22:19 +01:00
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_VOICE
2023-09-09 08:03:56 +01:00
AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN);
AUDIO_PlaySingleVoice(true);
#endif
2023-09-10 18:11:25 +01:00
SEARCH_Start();
2023-09-09 08:03:56 +01:00
}
2023-10-08 20:23:37 +01:00
if (g_flag_prepare_tx)
2023-09-09 08:03:56 +01:00
{
RADIO_PrepareTX();
2023-10-08 20:23:37 +01:00
g_flag_prepare_tx = false;
2023-09-09 08:03:56 +01:00
}
2023-09-14 09:56:30 +01:00
#ifdef ENABLE_VOICE
2023-10-08 17:14:13 +01:00
if (g_another_voice_id != VOICE_ID_INVALID)
2023-09-09 08:03:56 +01:00
{
2023-10-08 17:14:13 +01:00
if (g_another_voice_id < 76)
AUDIO_SetVoiceID(0, g_another_voice_id);
2023-09-09 08:03:56 +01:00
AUDIO_PlaySingleVoice(false);
2023-10-08 17:14:13 +01:00
g_another_voice_id = VOICE_ID_INVALID;
2023-09-09 08:03:56 +01:00
}
#endif
}