0
mirror of https://github.com/OneOfEleven/uv-k5-firmware-custom.git synced 2025-04-28 06:11:24 +03:00

Fix serial comms mishap, fix dual-watch not starting at power-on

This commit is contained in:
OneOfEleven 2023-10-11 16:02:45 +01:00
parent 5942582da4
commit 46a082ef05
23 changed files with 612 additions and 506 deletions

View File

@ -13,10 +13,12 @@ ENABLE_AIRCOPY := 1
ENABLE_FMRADIO := 1 ENABLE_FMRADIO := 1
ENABLE_NOAA := 0 ENABLE_NOAA := 0
ENABLE_VOICE := 1 ENABLE_VOICE := 1
ENABLE_MUTE_RADIO_FOR_VOICE := 0
ENABLE_VOX := 1 ENABLE_VOX := 1
ENABLE_ALARM := 1 ENABLE_ALARM := 1
ENABLE_TX1750 := 1 ENABLE_TX1750 := 1
ENABLE_PWRON_PASSWORD := 0 ENABLE_PWRON_PASSWORD := 0
ENABLE_RESET_AES_KEY := 1
ENABLE_BIG_FREQ := 0 ENABLE_BIG_FREQ := 0
ENABLE_SMALL_BOLD := 1 ENABLE_SMALL_BOLD := 1
ENABLE_KEEP_MEM_NAME := 1 ENABLE_KEEP_MEM_NAME := 1
@ -30,7 +32,6 @@ ENABLE_SHOW_CHARGE_LEVEL := 0
ENABLE_REVERSE_BAT_SYMBOL := 1 ENABLE_REVERSE_BAT_SYMBOL := 1
ENABLE_CODE_SCAN_TIMEOUT := 0 ENABLE_CODE_SCAN_TIMEOUT := 0
ENABLE_FREQ_CODE_SCAN_TIMEOUT := 1 ENABLE_FREQ_CODE_SCAN_TIMEOUT := 1
ENABLE_FREQ_CODE_ROUNDING := 0
ENABLE_AM_FIX := 1 ENABLE_AM_FIX := 1
ENABLE_AM_FIX_SHOW_DATA := 1 ENABLE_AM_FIX_SHOW_DATA := 1
ENABLE_SQUELCH_MORE_SENSITIVE := 1 ENABLE_SQUELCH_MORE_SENSITIVE := 1
@ -209,10 +210,10 @@ CFLAGS =
ifeq ($(ENABLE_CLANG),0) ifeq ($(ENABLE_CLANG),0)
#CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD #CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
CFLAGS += -Os -Wall -Werror -mcpu=cortex-m0 -std=c11 -MMD CFLAGS += -Os -Werror -mcpu=cortex-m0 -std=c11 -MMD
else else
# Oz needed to make it fit on flash # Oz needed to make it fit on flash
CFLAGS += -Oz -Wall -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD CFLAGS += -Oz -Werror -mcpu=cortex-m0 -fno-builtin -fshort-enums -fno-delete-null-pointer-checks -std=c11 -MMD
endif endif
ifeq ($(ENABLE_LTO),1) ifeq ($(ENABLE_LTO),1)
@ -227,9 +228,7 @@ endif
# catch any and all warnings # catch any and all warnings
# better to bust than add new bugs # better to bust than add new bugs
#CFLAGS += -Wall CFLAGS += -Wall -Wextra -Wpedantic
#CFLAGS += -Wextra
#CFLAGS += -Wpedantic
CFLAGS += -DPRINTF_INCLUDE_CONFIG_H CFLAGS += -DPRINTF_INCLUDE_CONFIG_H
CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\" CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\"
@ -263,6 +262,9 @@ endif
ifeq ($(ENABLE_VOICE),1) ifeq ($(ENABLE_VOICE),1)
CFLAGS += -DENABLE_VOICE CFLAGS += -DENABLE_VOICE
endif endif
ifeq ($(ENABLE_MUTE_RADIO_FOR_VOICE),1)
CFLAGS += -DENABLE_MUTE_RADIO_FOR_VOICE
endif
ifeq ($(ENABLE_VOX),1) ifeq ($(ENABLE_VOX),1)
CFLAGS += -DENABLE_VOX CFLAGS += -DENABLE_VOX
endif endif
@ -275,6 +277,9 @@ endif
ifeq ($(ENABLE_PWRON_PASSWORD),1) ifeq ($(ENABLE_PWRON_PASSWORD),1)
CFLAGS += -DENABLE_PWRON_PASSWORD CFLAGS += -DENABLE_PWRON_PASSWORD
endif endif
ifeq ($(ENABLE_RESET_AES_KEY),1)
CFLAGS += -DENABLE_RESET_AES_KEY
endif
ifeq ($(ENABLE_KEEP_MEM_NAME),1) ifeq ($(ENABLE_KEEP_MEM_NAME),1)
CFLAGS += -DENABLE_KEEP_MEM_NAME CFLAGS += -DENABLE_KEEP_MEM_NAME
endif endif
@ -308,9 +313,6 @@ endif
ifeq ($(ENABLE_FREQ_CODE_SCAN_TIMEOUT),1) ifeq ($(ENABLE_FREQ_CODE_SCAN_TIMEOUT),1)
CFLAGS += -DENABLE_FREQ_CODE_SCAN_TIMEOUT CFLAGS += -DENABLE_FREQ_CODE_SCAN_TIMEOUT
endif endif
ifeq ($(ENABLE_FREQ_CODE_ROUNDING),1)
CFLAGS += -DENABLE_FREQ_CODE_ROUNDING
endif
ifeq ($(ENABLE_AM_FIX),1) ifeq ($(ENABLE_AM_FIX),1)
CFLAGS += -DENABLE_AM_FIX CFLAGS += -DENABLE_AM_FIX
endif endif

View File

@ -36,14 +36,16 @@ ENABLE_OVERLAY := 0 cpu FLASH stuff, not needed
ENABLE_LTO := 0 **experimental, reduces size of compiled firmware but might break EEPROM reads (OVERLAY will be disabled if you enable this) ENABLE_LTO := 0 **experimental, reduces size of compiled firmware but might break EEPROM reads (OVERLAY will be disabled if you enable this)
ENABLE_UART := 1 without this you can't configure radio via PC ENABLE_UART := 1 without this you can't configure radio via PC
ENABLE_UART_DEBUG := 0 just for code debugging, it sends debug info along the USB serial connection (programming lead) ENABLE_UART_DEBUG := 0 just for code debugging, it sends debug info along the USB serial connection (programming lead)
ENABLE_AIRCOPY := 0 easier to just enter frequency with butts ENABLE_AIRCOPY := 1 clone radio-to-radio via RF
ENABLE_FMRADIO := 1 WBFM VHF broadcast band receiver ENABLE_FMRADIO := 1 WBFM VHF broadcast band receiver
ENABLE_NOAA := 1 everything NOAA (only of any use in the USA) ENABLE_NOAA := 1 everything NOAA (only of any use in the USA)
ENABLE_VOICE := 0 want to hear voices ? ENABLE_VOICE := 0 want to hear voices ?
ENABLE_MUTE_RADIO_FOR_VOICE := 1 mute the radios audio when a voice is playing
ENABLE_VOX := 1 voice operated transmission ENABLE_VOX := 1 voice operated transmission
ENABLE_ALARM := 1 TX alarms ENABLE_ALARM := 1 TX alarms
ENABLE_1750HZ := 1 side key 1750Hz TX tone (older style repeater access) ENABLE_1750HZ := 1 side key 1750Hz TX tone (older style repeater access)
ENABLE_PWRON_PASSWORD := 1 power-on password stuff ENABLE_PWRON_PASSWORD := 0 '1' = allow power-on password
ENABLE_RESET_AES_KEY := 1 '1' = reset/clear the AES key stored in the eeprom
ENABLE_BIG_FREQ := 0 big font frequencies (like original QS firmware) ENABLE_BIG_FREQ := 0 big font frequencies (like original QS firmware)
ENABLE_SMALL_BOLD := 1 bold channel name/no. (when name + freq channel display mode) ENABLE_SMALL_BOLD := 1 bold channel name/no. (when name + freq channel display mode)
ENABLE_KEEP_MEM_NAME := 1 maintain channel name when (re)saving memory channel ENABLE_KEEP_MEM_NAME := 1 maintain channel name when (re)saving memory channel

View File

@ -579,9 +579,15 @@ void APP_StartListening(function_type_t Function, const bool reset_am_fix)
(g_eeprom.dac_gain << 0)); // AF DAC Gain (after Gain-1 and Gain-2) (g_eeprom.dac_gain << 0)); // AF DAC Gain (after Gain-1 and Gain-2)
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
if (g_voice_write_index == 0) // AM/FM RX mode will be set when the voice has finished #ifdef MUTE_AUDIO_FOR_VOICE
if (g_voice_write_index == 0)
BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM);
#else
BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM);
#endif
#else
BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM);
#endif #endif
BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM); // no need, set it now
FUNCTION_Select(Function); FUNCTION_Select(Function);
@ -887,14 +893,15 @@ void APP_CheckRadioInterrupts(void)
g_power_save_expired = false; g_power_save_expired = false;
} }
if (g_eeprom.dual_watch != DUAL_WATCH_OFF && (g_schedule_dual_watch || g_dual_watch_count_down_10ms < dual_watch_count_after_vox_10ms)) if (g_eeprom.dual_watch != DUAL_WATCH_OFF &&
(g_schedule_dual_watch || g_dual_watch_count_down_10ms < dual_watch_count_after_vox_10ms))
{ {
g_dual_watch_count_down_10ms = dual_watch_count_after_vox_10ms; g_dual_watch_count_down_10ms = dual_watch_count_after_vox_10ms;
g_schedule_dual_watch = false; g_schedule_dual_watch = false;
// let the user see DW is not active // let the user see DW is not active
g_dual_watch_active = false; g_dual_watch_active = false;
g_update_status = true; g_update_status = true;
} }
} }
} }
@ -1127,6 +1134,7 @@ void APP_Update(void)
{ {
NOAA_IncreaseChannel(); NOAA_IncreaseChannel();
RADIO_SetupRegisters(false); RADIO_SetupRegisters(false);
g_noaa_count_down_10ms = 7; // 70ms g_noaa_count_down_10ms = 7; // 70ms
g_schedule_noaa = false; g_schedule_noaa = false;
} }
@ -1136,17 +1144,21 @@ void APP_Update(void)
// toggle between the VFO's if dual watch is enabled // toggle between the VFO's if dual watch is enabled
if (g_screen_to_display != DISPLAY_SCANNER && g_eeprom.dual_watch != DUAL_WATCH_OFF) if (g_screen_to_display != DISPLAY_SCANNER && g_eeprom.dual_watch != DUAL_WATCH_OFF)
{ {
#ifdef ENABLE_VOICE #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
if (g_voice_write_index == 0) //UART_SendText("dual watch\r\n");
#endif #endif
#ifdef ENABLE_VOICE
if (g_voice_write_index == 0)
#endif
{ {
if (g_schedule_dual_watch) if (g_schedule_dual_watch)
{ {
if (g_scan_state_dir == SCAN_OFF && g_css_scan_mode == CSS_SCAN_MODE_OFF) if (g_scan_state_dir == SCAN_OFF && g_css_scan_mode == CSS_SCAN_MODE_OFF)
{ {
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (!g_fm_radio_mode) if (!g_fm_radio_mode)
#endif #endif
{ {
if (!g_ptt_is_pressed && if (!g_ptt_is_pressed &&
g_dtmf_call_state == DTMF_CALL_STATE_NONE && g_dtmf_call_state == DTMF_CALL_STATE_NONE &&
@ -1168,30 +1180,30 @@ void APP_Update(void)
} }
} }
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (g_schedule_fm && if (g_schedule_fm &&
g_fm_scan_state != FM_SCAN_OFF && g_fm_scan_state != FM_SCAN_OFF &&
g_current_function != FUNCTION_MONITOR && g_current_function != FUNCTION_MONITOR &&
g_current_function != FUNCTION_RECEIVE && g_current_function != FUNCTION_RECEIVE &&
g_current_function != FUNCTION_TRANSMIT) g_current_function != FUNCTION_TRANSMIT)
{ // switch to FM radio mode { // switch to FM radio mode
FM_Play(); FM_Play();
g_schedule_fm = false; g_schedule_fm = false;
} }
#endif #endif
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
if (g_eeprom.vox_switch) if (g_eeprom.vox_switch)
APP_HandleVox(); APP_HandleVox();
#endif #endif
if (g_schedule_power_save) if (g_schedule_power_save)
{ {
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
if ( if (
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
g_fm_radio_mode || g_fm_radio_mode ||
#endif #endif
g_ptt_is_pressed || g_ptt_is_pressed ||
g_key_held || g_key_held ||
g_eeprom.battery_save == 0 || g_eeprom.battery_save == 0 ||
@ -1495,7 +1507,7 @@ void APP_TimeSlice10ms(void)
UI_DisplayStatus(false); UI_DisplayStatus(false);
return; return;
} }
#ifdef ENABLE_BOOT_BEEPS #ifdef ENABLE_BOOT_BEEPS
if (g_boot_counter_10ms > 0 && (g_boot_counter_10ms % 25) == 0) if (g_boot_counter_10ms > 0 && (g_boot_counter_10ms % 25) == 0)
AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL); AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL);
@ -1641,7 +1653,7 @@ void APP_TimeSlice10ms(void)
} }
if (g_scanner_edit_state != SCAN_EDIT_STATE_NONE) if (g_scanner_edit_state != SCAN_EDIT_STATE_NONE)
{ { // waiting for user input choice
APP_CheckKeys(); APP_CheckKeys();
return; return;
} }
@ -1673,14 +1685,7 @@ void APP_TimeSlice10ms(void)
BK4819_DisableFrequencyScan(); BK4819_DisableFrequencyScan();
#ifdef ENABLE_FREQ_CODE_ROUNDING g_scan_frequency = Result;
{ // round to nearest step multiple
const uint32_t step = STEP_FREQ_TABLE[g_step_setting];
g_scan_frequency = ((Result + (step / 2)) / step) * step;
}
#else
g_scan_frequency = Result;
#endif
if (g_scan_hit_count < 3) if (g_scan_hit_count < 3)
{ // keep scanning for an RF carrier { // keep scanning for an RF carrier
@ -1736,7 +1741,7 @@ void APP_TimeSlice10ms(void)
BK4819_Disable(); BK4819_Disable();
if (ScanResult == BK4819_CSS_RESULT_CDCSS) if (ScanResult == BK4819_CSS_RESULT_CDCSS)
{ { // found a CDCSS code
const uint8_t Code = DCS_GetCdcssCode(Result); const uint8_t Code = DCS_GetCdcssCode(Result);
if (Code != 0xFF) if (Code != 0xFF)
{ {
@ -1750,7 +1755,7 @@ void APP_TimeSlice10ms(void)
} }
else else
if (ScanResult == BK4819_CSS_RESULT_CTCSS) if (ScanResult == BK4819_CSS_RESULT_CTCSS)
{ { // found a CTCSS tone
const uint8_t code = DCS_GetCtcssCode(CtcssFreq); const uint8_t code = DCS_GetCtcssCode(CtcssFreq);
if (code != 0xFF) if (code != 0xFF)
{ {
@ -1773,8 +1778,7 @@ void APP_TimeSlice10ms(void)
} }
} }
if (g_scan_css_state == SCAN_CSS_STATE_OFF || if (g_scan_css_state == SCAN_CSS_STATE_OFF || g_scan_css_state == SCAN_CSS_STATE_SCANNING)
g_scan_css_state == SCAN_CSS_STATE_SCANNING)
{ // re-start scan { // re-start scan
BK4819_SetScanFrequency(g_scan_frequency); BK4819_SetScanFrequency(g_scan_frequency);
g_scan_delay_10ms = scan_freq_css_delay_10ms; g_scan_delay_10ms = scan_freq_css_delay_10ms;
@ -1840,7 +1844,7 @@ void APP_TimeSlice500ms(void)
{ // config upload/download is running { // config upload/download is running
return; return;
} }
if (g_keypad_locked > 0) if (g_keypad_locked > 0)
if (--g_keypad_locked == 0) if (--g_keypad_locked == 0)
g_update_display = true; g_update_display = true;
@ -2269,7 +2273,7 @@ static void APP_ProcessKey(const key_code_t Key, const bool key_pressed, const b
return; return;
backlight_turn_on(); backlight_turn_on();
g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL; g_beep_to_play = BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL;
// AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL); // AUDIO_PlayBeep(BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL);
@ -2393,7 +2397,6 @@ static void APP_ProcessKey(const key_code_t Key, const bool key_pressed, const b
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
UART_printf("proc key 1 %3u %u %u %u %u\r\n", Key, key_pressed, key_held, g_fkey_pressed, flag); UART_printf("proc key 1 %3u %u %u %u %u\r\n", Key, key_pressed, key_held, g_fkey_pressed, flag);
#endif #endif
} }
if (g_fkey_pressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2)) if (g_fkey_pressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2))

View File

@ -388,6 +388,8 @@ static void FM_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
static void FM_Key_STAR(bool key_pressed, bool key_held) static void FM_Key_STAR(bool key_pressed, bool key_held)
{ {
(void)key_held; // stop compiler warning
// if (key_held) // if (key_held)
// return; // return;

View File

@ -792,7 +792,7 @@ void MENU_AcceptSetting(void)
break; break;
case MENU_F_LOCK: case MENU_F_LOCK:
g_setting_f_lock = g_sub_menu_selection; g_setting_freq_lock = g_sub_menu_selection;
break; break;
case MENU_200TX: case MENU_200TX:
@ -1226,7 +1226,7 @@ void MENU_ShowCurrentSetting(void)
break; break;
case MENU_F_LOCK: case MENU_F_LOCK:
g_sub_menu_selection = g_setting_f_lock; g_sub_menu_selection = g_setting_freq_lock;
break; break;
case MENU_200TX: case MENU_200TX:

View File

@ -19,6 +19,7 @@
#include "app/scanner.h" #include "app/scanner.h"
#include "audio.h" #include "audio.h"
#include "driver/bk4819.h" #include "driver/bk4819.h"
#include "driver/uart.h"
#include "frequencies.h" #include "frequencies.h"
#include "misc.h" #include "misc.h"
#include "radio.h" #include "radio.h"
@ -46,10 +47,10 @@ bool g_scan_keep_frequency;
static void SCANNER_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held) static void SCANNER_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
{ {
if (key_held || !key_pressed) if (key_held || key_pressed)
return; return;
if (g_scanner_edit_state == SCAN_EDIT_STATE_BUSY) if (g_scanner_edit_state == SCAN_EDIT_STATE_SAVE)
{ {
uint16_t Channel; uint16_t Channel;
@ -86,7 +87,7 @@ static void SCANNER_Key_DIGITS(key_code_t Key, bool key_pressed, bool key_held)
static void SCANNER_Key_EXIT(bool key_pressed, bool key_held) static void SCANNER_Key_EXIT(bool key_pressed, bool key_held)
{ {
if (key_held || !key_pressed) if (key_held || key_pressed)
return; return;
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL; g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
@ -106,7 +107,7 @@ static void SCANNER_Key_EXIT(bool key_pressed, bool key_held)
#endif #endif
break; break;
case SCAN_EDIT_STATE_BUSY: case SCAN_EDIT_STATE_SAVE:
if (g_input_box_index > 0) if (g_input_box_index > 0)
{ {
g_input_box[--g_input_box_index] = 10; g_input_box[--g_input_box_index] = 10;
@ -130,10 +131,7 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
{ {
uint8_t Channel; uint8_t Channel;
if (key_held) if (key_held || key_pressed)
return;
if (!key_pressed)
return; return;
if (g_scan_css_state == SCAN_CSS_STATE_OFF && !g_scan_single_frequency) if (g_scan_css_state == SCAN_CSS_STATE_OFF && !g_scan_single_frequency)
@ -164,7 +162,6 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
case SCAN_EDIT_STATE_NONE: case SCAN_EDIT_STATE_NONE:
if (!g_scan_single_frequency) if (!g_scan_single_frequency)
{ {
#if 0 #if 0
uint32_t Freq250 = FREQUENCY_FloorToStep(g_scan_frequency, 250, 0); uint32_t Freq250 = FREQUENCY_FloorToStep(g_scan_frequency, 250, 0);
uint32_t Freq625 = FREQUENCY_FloorToStep(g_scan_frequency, 625, 0); uint32_t Freq625 = FREQUENCY_FloorToStep(g_scan_frequency, 625, 0);
@ -196,7 +193,7 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
g_step_setting = STEP_2_5kHz; g_step_setting = STEP_2_5kHz;
g_scan_frequency = Freq250; g_scan_frequency = Freq250;
} }
#else #elif 0
#ifdef ENABLE_1250HZ_STEP #ifdef ENABLE_1250HZ_STEP
const step_setting_t small_step = STEP_1_25kHz; const step_setting_t small_step = STEP_1_25kHz;
@ -239,18 +236,37 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
g_step_setting = big_step; g_step_setting = big_step;
g_scan_frequency = freq_big_step; g_scan_frequency = freq_big_step;
} }
#else
#ifdef ENABLE_1250HZ_STEP
g_step_setting = STEP_1_25kHz;
#else
g_step_setting = STEP_2_5kHz;
#endif
{ // round to the nearest step size
const uint32_t step = STEP_FREQ_TABLE[g_step_setting];
g_scan_frequency = ((g_scan_frequency + (step / 2)) / step) * step;
}
#endif #endif
} }
if (g_tx_vfo->channel_save <= USER_CHANNEL_LAST) if (g_tx_vfo->channel_save <= USER_CHANNEL_LAST)
{ {
g_scanner_edit_state = SCAN_EDIT_STATE_BUSY; g_scan_channel = g_tx_vfo->channel_save;
g_scan_channel = g_tx_vfo->channel_save; g_show_chan_prefix = RADIO_CheckValidChannel(g_tx_vfo->channel_save, false, 0);
g_show_chan_prefix = RADIO_CheckValidChannel(g_tx_vfo->channel_save, false, 0); g_scanner_edit_state = SCAN_EDIT_STATE_SAVE;
} }
else else
{ {
g_scanner_edit_state = SCAN_EDIT_STATE_DONE; #if 0
// save the VFO
g_scanner_edit_state = SCAN_EDIT_STATE_DONE;
#else
// save to a desired channel
g_scan_channel = RADIO_FindNextChannel(0, SCAN_FWD, false, g_eeprom.tx_vfo);
g_show_chan_prefix = RADIO_CheckValidChannel(g_scan_channel, false, 0);
g_scanner_edit_state = SCAN_EDIT_STATE_SAVE;
#endif
} }
g_scan_css_state = SCAN_CSS_STATE_FOUND; g_scan_css_state = SCAN_CSS_STATE_FOUND;
@ -263,7 +279,7 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
g_update_status = true; g_update_status = true;
break; break;
case SCAN_EDIT_STATE_BUSY: case SCAN_EDIT_STATE_SAVE:
if (g_input_box_index == 0) if (g_input_box_index == 0)
{ {
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL; g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
@ -273,6 +289,10 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
break; break;
case SCAN_EDIT_STATE_DONE: case SCAN_EDIT_STATE_DONE:
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
//UART_SendText("edit done\r\n");
#endif
if (!g_scan_single_frequency) if (!g_scan_single_frequency)
{ {
RADIO_InitInfo(g_tx_vfo, g_tx_vfo->channel_save, g_scan_frequency); RADIO_InitInfo(g_tx_vfo, g_tx_vfo->channel_save, g_scan_frequency);
@ -280,7 +300,7 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
if (g_scan_use_css_result) if (g_scan_use_css_result)
{ {
g_tx_vfo->freq_config_rx.code_type = g_scan_css_result_type; g_tx_vfo->freq_config_rx.code_type = g_scan_css_result_type;
g_tx_vfo->freq_config_rx.code = g_scan_css_result_code; g_tx_vfo->freq_config_rx.code = g_scan_css_result_code;
} }
g_tx_vfo->freq_config_tx = g_tx_vfo->freq_config_rx; g_tx_vfo->freq_config_tx = g_tx_vfo->freq_config_rx;
@ -292,9 +312,9 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD); RADIO_ConfigureChannel(1, VFO_CONFIGURE_RELOAD);
g_tx_vfo->freq_config_rx.code_type = g_scan_css_result_type; g_tx_vfo->freq_config_rx.code_type = g_scan_css_result_type;
g_tx_vfo->freq_config_rx.code = g_scan_css_result_code; g_tx_vfo->freq_config_rx.code = g_scan_css_result_code;
g_tx_vfo->freq_config_tx.code_type = g_scan_css_result_type; g_tx_vfo->freq_config_tx.code_type = g_scan_css_result_type;
g_tx_vfo->freq_config_tx.code = g_scan_css_result_code; g_tx_vfo->freq_config_tx.code = g_scan_css_result_code;
} }
if (g_tx_vfo->channel_save <= USER_CHANNEL_LAST) if (g_tx_vfo->channel_save <= USER_CHANNEL_LAST)
@ -329,7 +349,7 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held)
static void SCANNER_Key_STAR(bool key_pressed, bool key_held) static void SCANNER_Key_STAR(bool key_pressed, bool key_held)
{ {
if (key_held || !key_pressed) if (key_held || key_pressed)
return; return;
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL; g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
@ -345,16 +365,16 @@ static void SCANNER_Key_UP_DOWN(bool key_pressed, bool pKeyHeld, int8_t Directio
} }
else else
{ {
if (!key_pressed) if (key_pressed)
return; return;
g_input_box_index = 0; g_input_box_index = 0;
g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL; g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL;
} }
if (g_scanner_edit_state == SCAN_EDIT_STATE_BUSY) if (g_scanner_edit_state == SCAN_EDIT_STATE_SAVE)
{ {
g_scan_channel = NUMBER_AddWithWraparound(g_scan_channel, Direction, 0, USER_CHANNEL_LAST); g_scan_channel = NUMBER_AddWithWraparound(g_scan_channel, Direction, 0, USER_CHANNEL_LAST);
g_show_chan_prefix = RADIO_CheckValidChannel(g_scan_channel, false, 0); g_show_chan_prefix = RADIO_CheckValidChannel(g_scan_channel, false, 0);
g_request_display_screen = DISPLAY_SCANNER; g_request_display_screen = DISPLAY_SCANNER;
} }
@ -460,9 +480,9 @@ void SCANNER_Start(void)
g_CDCSS_lost = false; g_CDCSS_lost = false;
g_CDCSS_code_type = 0; g_CDCSS_code_type = 0;
g_CTCSS_lost = false; g_CTCSS_lost = false;
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
g_vox_lost = false; g_vox_lost = false;
#endif #endif
g_squelch_lost = false; g_squelch_lost = false;
g_scanner_edit_state = SCAN_EDIT_STATE_NONE; g_scanner_edit_state = SCAN_EDIT_STATE_NONE;
g_scan_freq_css_timer_10ms = 0; g_scan_freq_css_timer_10ms = 0;

View File

@ -40,7 +40,7 @@ typedef enum scan_state_dir_e scan_state_dir_t;
enum scan_edit_state_e { enum scan_edit_state_e {
SCAN_EDIT_STATE_NONE = 0, SCAN_EDIT_STATE_NONE = 0,
SCAN_EDIT_STATE_BUSY, SCAN_EDIT_STATE_SAVE,
SCAN_EDIT_STATE_DONE SCAN_EDIT_STATE_DONE
}; };
typedef enum scan_edit_state_e scan_edit_state_t; typedef enum scan_edit_state_e scan_edit_state_t;

View File

@ -14,6 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
#define INCLUDE_AES
#include <string.h> #include <string.h>
#if !defined(ENABLE_OVERLAY) #if !defined(ENABLE_OVERLAY)
@ -43,65 +45,70 @@
#define DMA_INDEX(x, y) (((x) + (y)) % sizeof(UART_DMA_Buffer)) #define DMA_INDEX(x, y) (((x) + (y)) % sizeof(UART_DMA_Buffer))
#define EEPROM_SIZE 0x2000u // 8192 .. BL24C64 I2C eeprom chip
// ****************************************************
typedef struct { typedef struct {
uint16_t ID; uint16_t ID;
uint16_t Size; uint16_t Size;
} Header_t; } __attribute__((packed)) Header_t;
typedef struct { typedef struct {
uint8_t Padding[2]; uint8_t pad[2];
uint16_t ID; uint16_t ID;
} Footer_t; } __attribute__((packed)) Footer_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
uint32_t Timestamp; uint32_t time_stamp;
} CMD_0514_t; } __attribute__((packed)) cmd_0514_t;
// version
typedef struct { typedef struct {
Header_t Header; Header_t Header;
struct { struct {
char Version[16]; char Version[16];
bool g_has_custom_aes_key; uint8_t has_custom_aes_key;
bool g_is_in_lock_screen; uint8_t password_locked;
uint8_t Padding[2]; uint8_t pad[2];
uint32_t Challenge[4]; uint32_t Challenge[4];
} Data; } __attribute__((packed)) Data;
} REPLY_0514_t; } __attribute__((packed)) reply_0514_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
uint16_t Offset; uint16_t Offset;
uint8_t Size; uint8_t Size;
uint8_t Padding; uint8_t pad;
uint32_t Timestamp; uint32_t time_stamp;
} CMD_051B_t; } __attribute__((packed)) cmd_051B_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
struct { struct {
uint16_t Offset; uint16_t Offset;
uint8_t Size; uint8_t Size;
uint8_t Padding; uint8_t pad;
uint8_t Data[128]; uint8_t Data[128];
} Data; } __attribute__((packed)) Data;
} REPLY_051B_t; } __attribute__((packed)) reply_051B_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
uint16_t Offset; uint16_t Offset;
uint8_t Size; uint8_t Size;
bool bAllowPassword; uint8_t allow_password;
uint32_t Timestamp; uint32_t time_stamp;
uint8_t Data[0]; // uint8_t Data[0]; // new compiler strict warning settings doesn't allow zero-length arrays
} CMD_051D_t; } __attribute__((packed)) cmd_051D_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
struct { struct {
uint16_t Offset; uint16_t Offset;
} Data; } __attribute__((packed)) Data;
} REPLY_051D_t; } __attribute__((packed)) reply_051D_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
@ -109,39 +116,34 @@ typedef struct {
uint16_t RSSI; uint16_t RSSI;
uint8_t ExNoiseIndicator; uint8_t ExNoiseIndicator;
uint8_t GlitchIndicator; uint8_t GlitchIndicator;
} Data; } __attribute__((packed)) Data;
} REPLY_0527_t; } __attribute__((packed)) reply_0527_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
struct { struct {
uint16_t Voltage; uint16_t Voltage;
uint16_t Current; uint16_t Current;
} Data; } __attribute__((packed)) Data;
} REPLY_0529_t; } __attribute__((packed)) reply_0529_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
uint32_t Response[4]; uint32_t Response[4];
} CMD_052D_t; } __attribute__((packed)) cmd_052D_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
struct { struct {
bool bIsLocked; uint8_t locked;
uint8_t Padding[3]; uint8_t pad[3];
} Data; } __attribute__((packed)) Data;
} REPLY_052D_t; } __attribute__((packed)) reply_052D_t;
typedef struct { typedef struct {
Header_t Header; Header_t Header;
uint32_t Timestamp; uint32_t time_stamp;
} CMD_052F_t; } __attribute__((packed)) cmd_052F_t;
static const uint8_t Obfuscation[16] =
{
0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80
};
static union static union
{ {
@ -149,73 +151,81 @@ static union
struct struct
{ {
Header_t Header; Header_t Header;
uint8_t Data[252]; uint8_t Data[252];
}; } __attribute__((packed));
} UART_Command; } __attribute__((packed)) UART_Command;
static uint32_t Timestamp; static const uint8_t Obfuscation[16] = {
static uint16_t g_uart_write_index; 0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80
static bool bIsEncrypted = true; };
static void SendReply(void *pReply, uint16_t Size) uint32_t time_stamp = 0;
uint16_t write_index = 0;
bool is_encrypted = true;
#ifdef INCLUDE_AES
uint8_t is_locked = (uint8_t)true;
uint8_t try_count = 0;
#endif
// ****************************************************
static void SendReply(void *preply, uint16_t Size)
{ {
Header_t Header; Header_t Header;
Footer_t Footer; Footer_t Footer;
if (bIsEncrypted) if (is_encrypted)
{ {
uint8_t *pBytes = (uint8_t *)pReply; uint8_t *pBytes = (uint8_t *)preply;
unsigned int i; unsigned int i;
for (i = 0; i < Size; i++) for (i = 0; i < Size; i++)
pBytes[i] ^= Obfuscation[i % 16]; pBytes[i] ^= Obfuscation[i % 16];
} }
Header.ID = 0xCDAB; Header.ID = 0xCDAB;
Header.Size = Size; Header.Size = Size;
UART_Send(&Header, sizeof(Header)); UART_Send(&Header, sizeof(Header));
UART_Send(pReply, Size); UART_Send(preply, Size);
if (bIsEncrypted) if (is_encrypted)
{ {
Footer.Padding[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF; Footer.pad[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF;
Footer.Padding[1] = Obfuscation[(Size + 1) % 16] ^ 0xFF; Footer.pad[1] = Obfuscation[(Size + 1) % 16] ^ 0xFF;
} }
else else
{ {
Footer.Padding[0] = 0xFF; Footer.pad[0] = 0xFF;
Footer.Padding[1] = 0xFF; Footer.pad[1] = 0xFF;
} }
Footer.ID = 0xBADC; Footer.ID = 0xBADC;
UART_Send(&Footer, sizeof(Footer)); UART_Send(&Footer, sizeof(Footer));
} }
static void SendVersion(void) static void SendVersion(void)
{ {
REPLY_0514_t Reply; reply_0514_t reply;
Reply.Header.ID = 0x0515; memset(&reply, 0, sizeof(reply));
Reply.Header.Size = sizeof(Reply.Data); reply.Header.ID = 0x0515;
strcpy(Reply.Data.Version, Version); reply.Header.Size = sizeof(reply.Data);
Reply.Data.g_has_custom_aes_key = g_has_custom_aes_key; strcpy(reply.Data.Version, Version);
Reply.Data.g_is_in_lock_screen = g_is_in_lock_screen; reply.Data.has_custom_aes_key = g_has_custom_aes_key;
Reply.Data.Challenge[0] = g_challenge[0]; reply.Data.password_locked = g_password_locked;
Reply.Data.Challenge[1] = g_challenge[1]; reply.Data.Challenge[0] = g_challenge[0];
Reply.Data.Challenge[2] = g_challenge[2]; reply.Data.Challenge[1] = g_challenge[1];
Reply.Data.Challenge[3] = g_challenge[3]; reply.Data.Challenge[2] = g_challenge[2];
reply.Data.Challenge[3] = g_challenge[3];
SendReply(&Reply, sizeof(Reply)); SendReply(&reply, sizeof(reply));
} }
#ifdef INCLUDE_AES
static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse) static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint32_t *pResponse)
{ {
unsigned int i; unsigned int i;
uint32_t IV[4]; uint32_t IV[4] = {0, 0, 0, 0};
IV[0] = 0;
IV[1] = 0;
IV[2] = 0;
IV[3] = 0;
AES_Encrypt(pKey, IV, pIn, IV, true); AES_Encrypt(pKey, IV, pIn, IV, true);
@ -226,174 +236,216 @@ static bool IsBadChallenge(const uint32_t *pKey, const uint32_t *pIn, const uint
return false; return false;
} }
static void CMD_0514(const uint8_t *pBuffer) #endif
// version
static void cmd_0514(const uint8_t *pBuffer)
{ {
const CMD_0514_t *pCmd = (const CMD_0514_t *)pBuffer; const cmd_0514_t *pCmd = (const cmd_0514_t *)pBuffer;
Timestamp = pCmd->Timestamp; time_stamp = pCmd->time_stamp;
#ifdef ENABLE_FMRADIO
g_fm_radio_count_down_500ms = fm_radio_countdown_500ms;
#endif
g_serial_config_count_down_500ms = serial_config_count_down_500ms; g_serial_config_count_down_500ms = serial_config_count_down_500ms;
// turn the LCD backlight off
// GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
// show message // show message
g_request_display_screen = DISPLAY_MAIN; g_request_display_screen = DISPLAY_MAIN;
g_update_display = true; g_update_display = true;
SendVersion(); SendVersion();
} }
static void CMD_051B(const uint8_t *pBuffer) // read eeprom
static void cmd_051B(const uint8_t *pBuffer)
{ {
const CMD_051B_t *pCmd = (const CMD_051B_t *)pBuffer; const cmd_051B_t *pCmd = (const cmd_051B_t *)pBuffer;
REPLY_051B_t Reply; unsigned int addr = pCmd->Offset;
bool bLocked = false; unsigned int size = pCmd->Size;
// bool locked = false;
reply_051B_t reply;
if (pCmd->Timestamp != Timestamp) // if (pCmd->time_stamp != time_stamp)
return; // return;
g_serial_config_count_down_500ms = serial_config_count_down_500ms; g_serial_config_count_down_500ms = serial_config_count_down_500ms;
#ifdef ENABLE_FMRADIO if (addr >= EEPROM_SIZE)
g_fm_radio_count_down_500ms = fm_radio_countdown_500ms; return;
#endif
memset(&Reply, 0, sizeof(Reply)); if (size > sizeof(reply.Data.Data))
Reply.Header.ID = 0x051C; size = sizeof(reply.Data.Data);
Reply.Header.Size = pCmd->Size + 4; if (size > (EEPROM_SIZE - addr))
Reply.Data.Offset = pCmd->Offset; size = EEPROM_SIZE - addr;
Reply.Data.Size = pCmd->Size;
if (g_has_custom_aes_key) if (size == 0)
bLocked = g_is_locked; return;
if (!bLocked) memset(&reply, 0, sizeof(reply));
EEPROM_ReadBuffer(pCmd->Offset, Reply.Data.Data, pCmd->Size); reply.Header.ID = 0x051C;
reply.Header.Size = size + 4;
reply.Data.Offset = addr;
reply.Data.Size = size;
SendReply(&Reply, pCmd->Size + 8); // if (g_has_custom_aes_key)
// locked = is_locked;
// if (!locked)
EEPROM_ReadBuffer(addr, reply.Data.Data, size);
SendReply(&reply, size + 8);
} }
static void CMD_051D(const uint8_t *pBuffer) // write eeprom
static void cmd_051D(const uint8_t *pBuffer)
{ {
const CMD_051D_t *pCmd = (const CMD_051D_t *)pBuffer; const unsigned int write_size = 8;
REPLY_051D_t Reply; const cmd_051D_t *pCmd = (const cmd_051D_t *)pBuffer;
bool bReloadEeprom; unsigned int addr = pCmd->Offset;
bool bIsLocked; unsigned int size = pCmd->Size;
#ifdef INCLUDE_AES
bool reload_eeprom = false;
bool locked = g_has_custom_aes_key ? is_locked : g_has_custom_aes_key;
#endif
reply_051D_t reply;
if (pCmd->Timestamp != Timestamp) // if (pCmd->time_stamp != time_stamp)
return; // return;
g_serial_config_count_down_500ms = serial_config_count_down_500ms; g_serial_config_count_down_500ms = serial_config_count_down_500ms;
bReloadEeprom = false;
#ifdef ENABLE_FMRADIO if (addr >= EEPROM_SIZE)
g_fm_radio_count_down_500ms = fm_radio_countdown_500ms; return;
#endif
Reply.Header.ID = 0x051E; if (size > sizeof(reply.Data))
Reply.Header.Size = sizeof(Reply.Data); size = sizeof(reply.Data);
Reply.Data.Offset = pCmd->Offset; if (size > (EEPROM_SIZE - addr))
size = EEPROM_SIZE - addr;
bIsLocked = g_has_custom_aes_key ? g_is_locked : g_has_custom_aes_key; if (size == 0)
return;
if (!bIsLocked) memset(&reply, 0, sizeof(reply));
reply.Header.ID = 0x051E;
reply.Header.Size = size;
reply.Data.Offset = addr;
#ifdef INCLUDE_AES
if (!locked)
#endif
{ {
const uint8_t *data = (uint8_t *)&pCmd + sizeof(cmd_051D_t); // point to the RX'ed data to write to eeprom
unsigned int i; unsigned int i;
for (i = 0; i < (pCmd->Size / 8); i++) for (i = 0; i < (size / write_size); i++)
{ {
const uint16_t Offset = pCmd->Offset + (i * 8U); const uint16_t Offset = addr + (i * write_size);
if (Offset >= 0x0F30 && Offset < 0x0F40) if ((Offset + write_size) > EEPROM_SIZE)
if (!g_is_locked) break;
bReloadEeprom = true;
if ((Offset < 0x0E98 || Offset >= 0x0EA0) || !g_is_in_lock_screen || pCmd->bAllowPassword) #ifdef INCLUDE_AES
EEPROM_WriteBuffer(Offset, &pCmd->Data[i * 8U]); if (Offset >= 0x0F30 && Offset < 0x0F40) // AES key
if (!is_locked)
reload_eeprom = true;
#endif
#ifdef ENABLE_PWRON_PASSWORD
if ((Offset < 0x0E98 || Offset >= 0x0EA0) || !g_password_locked || pCmd->bAllowPassword)
EEPROM_WriteBuffer(Offset, &pCmd->Data[i * write_size]);
#else
EEPROM_WriteBuffer(Offset, &data[i * write_size]);
#endif
} }
if (bReloadEeprom) #ifdef INCLUDE_AES
BOARD_EEPROM_Init(); if (reload_eeprom)
BOARD_EEPROM_load();
#endif
} }
SendReply(&Reply, sizeof(Reply)); SendReply(&reply, sizeof(reply));
} }
static void CMD_0527(void) // read RSSI
static void cmd_0527(void)
{ {
REPLY_0527_t Reply; reply_0527_t reply;
Reply.Header.ID = 0x0528; memset(&reply, 0, sizeof(reply));
Reply.Header.Size = sizeof(Reply.Data); reply.Header.ID = 0x0528;
Reply.Data.RSSI = BK4819_ReadRegister(BK4819_REG_67) & 0x01FF; reply.Header.Size = sizeof(reply.Data);
Reply.Data.ExNoiseIndicator = BK4819_ReadRegister(BK4819_REG_65) & 0x007F; reply.Data.RSSI = BK4819_ReadRegister(BK4819_REG_67) & 0x01FF;
Reply.Data.GlitchIndicator = BK4819_ReadRegister(BK4819_REG_63); reply.Data.ExNoiseIndicator = BK4819_ReadRegister(BK4819_REG_65) & 0x007F;
reply.Data.GlitchIndicator = BK4819_ReadRegister(BK4819_REG_63);
SendReply(&Reply, sizeof(Reply)); SendReply(&reply, sizeof(reply));
} }
static void CMD_0529(void) // read ADC
static void cmd_0529(void)
{ {
REPLY_0529_t Reply; uint16_t voltage;
uint16_t current;
Reply.Header.ID = 0x52A; reply_0529_t reply;
Reply.Header.Size = sizeof(Reply.Data); memset(&reply, 0, sizeof(reply));
reply.Header.ID = 0x52A;
reply.Header.Size = sizeof(reply.Data);
// Original doesn't actually send current! // Original doesn't actually send current!
BOARD_ADC_GetBatteryInfo(&Reply.Data.Voltage, &Reply.Data.Current); BOARD_ADC_GetBatteryInfo(&voltage, &current);
reply.Data.Voltage = voltage;
SendReply(&Reply, sizeof(Reply)); reply.Data.Current = current;
SendReply(&reply, sizeof(reply));
} }
static void CMD_052D(const uint8_t *pBuffer) #ifdef INCLUDE_AES
static void cmd_052D(const uint8_t *pBuffer)
{ {
const CMD_052D_t *pCmd = (const CMD_052D_t *)pBuffer; cmd_052D_t *pCmd = (cmd_052D_t *)pBuffer;
REPLY_052D_t Reply; bool locked = g_has_custom_aes_key;
bool bIsLocked; uint32_t response[4];
reply_052D_t reply;
#ifdef ENABLE_FMRADIO g_serial_config_count_down_500ms = serial_config_count_down_500ms;
g_fm_radio_count_down_500ms = fm_radio_countdown_500ms;
#endif
Reply.Header.ID = 0x052E;
Reply.Header.Size = sizeof(Reply.Data);
bIsLocked = g_has_custom_aes_key; if (!locked)
if (!bIsLocked)
bIsLocked = IsBadChallenge(g_custom_aes_key, g_challenge, pCmd->Response);
if (!bIsLocked)
{ {
bIsLocked = IsBadChallenge(g_default_aes_key, g_challenge, pCmd->Response); memmove((void *)&response, &pCmd->Response, sizeof(response)); // overcome strict compiler warning settings
if (bIsLocked) locked = IsBadChallenge(g_custom_aes_key, g_challenge, response);
g_try_count++;
} }
if (g_try_count < 3) if (!locked)
{ {
if (!bIsLocked) memmove((void *)&response, &pCmd->Response, sizeof(response)); // overcome strict compiler warning settings
g_try_count = 0; locked = IsBadChallenge(g_default_aes_key, g_challenge, response);
if (locked)
try_count++;
}
if (try_count < 3)
{
if (!locked)
try_count = 0;
} }
else else
{ {
g_try_count = 3; try_count = 3;
bIsLocked = true; locked = true;
} }
g_is_locked = bIsLocked;
Reply.Data.bIsLocked = bIsLocked;
SendReply(&Reply, sizeof(Reply)); is_locked = locked;
memset(&reply, 0, sizeof(reply));
reply.Header.ID = 0x052E;
reply.Header.Size = sizeof(reply.Data);
reply.Data.locked = is_locked;
SendReply(&reply, sizeof(reply));
} }
static void CMD_052F(const uint8_t *pBuffer) #endif
static void cmd_052F(const uint8_t *pBuffer)
{ {
const CMD_052F_t *pCmd = (const CMD_052F_t *)pBuffer; const cmd_052F_t *pCmd = (const cmd_052F_t *)pBuffer;
g_eeprom.dual_watch = DUAL_WATCH_OFF; g_eeprom.dual_watch = DUAL_WATCH_OFF;
g_eeprom.cross_vfo_rx_tx = CROSS_BAND_OFF; g_eeprom.cross_vfo_rx_tx = CROSS_BAND_OFF;
@ -406,6 +458,8 @@ static void CMD_052F(const uint8_t *pBuffer)
g_eeprom.vfo_info[0].dtmf_ptt_id_tx_mode = PTT_ID_OFF; g_eeprom.vfo_info[0].dtmf_ptt_id_tx_mode = PTT_ID_OFF;
g_eeprom.vfo_info[0].dtmf_decoding_enable = false; g_eeprom.vfo_info[0].dtmf_decoding_enable = false;
g_serial_config_count_down_500ms = serial_config_count_down_500ms;
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
g_is_noaa_mode = false; g_is_noaa_mode = false;
#endif #endif
@ -413,12 +467,7 @@ static void CMD_052F(const uint8_t *pBuffer)
if (g_current_function == FUNCTION_POWER_SAVE) if (g_current_function == FUNCTION_POWER_SAVE)
FUNCTION_Select(FUNCTION_FOREGROUND); FUNCTION_Select(FUNCTION_FOREGROUND);
g_serial_config_count_down_500ms = serial_config_count_down_500ms; time_stamp = pCmd->time_stamp;
Timestamp = pCmd->Timestamp;
// turn the LCD backlight off
// GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT);
// show message // show message
g_request_display_screen = DISPLAY_MAIN; g_request_display_screen = DISPLAY_MAIN;
@ -438,35 +487,35 @@ bool UART_IsCommandAvailable(void)
while (1) while (1)
{ {
if (g_uart_write_index == DmaLength) if (write_index == DmaLength)
return false; return false;
while (g_uart_write_index != DmaLength && UART_DMA_Buffer[g_uart_write_index] != 0xABU) while (write_index != DmaLength && UART_DMA_Buffer[write_index] != 0xABU)
g_uart_write_index = DMA_INDEX(g_uart_write_index, 1); write_index = DMA_INDEX(write_index, 1);
if (g_uart_write_index == DmaLength) if (write_index == DmaLength)
return false; return false;
if (g_uart_write_index < DmaLength) if (write_index < DmaLength)
CommandLength = DmaLength - g_uart_write_index; CommandLength = DmaLength - write_index;
else else
CommandLength = (DmaLength + sizeof(UART_DMA_Buffer)) - g_uart_write_index; CommandLength = (DmaLength + sizeof(UART_DMA_Buffer)) - write_index;
if (CommandLength < 8) if (CommandLength < 8)
return 0; return 0;
if (UART_DMA_Buffer[DMA_INDEX(g_uart_write_index, 1)] == 0xCD) if (UART_DMA_Buffer[DMA_INDEX(write_index, 1)] == 0xCD)
break; break;
g_uart_write_index = DMA_INDEX(g_uart_write_index, 1); write_index = DMA_INDEX(write_index, 1);
} }
Index = DMA_INDEX(g_uart_write_index, 2); Index = DMA_INDEX(write_index, 2);
Size = (UART_DMA_Buffer[DMA_INDEX(Index, 1)] << 8) | UART_DMA_Buffer[Index]; Size = (UART_DMA_Buffer[DMA_INDEX(Index, 1)] << 8) | UART_DMA_Buffer[Index];
if ((Size + 8u) > sizeof(UART_DMA_Buffer)) if ((Size + 8u) > sizeof(UART_DMA_Buffer))
{ {
g_uart_write_index = DmaLength; write_index = DmaLength;
return false; return false;
} }
@ -478,7 +527,7 @@ bool UART_IsCommandAvailable(void)
if (UART_DMA_Buffer[TailIndex] != 0xDC || UART_DMA_Buffer[DMA_INDEX(TailIndex, 1)] != 0xBA) if (UART_DMA_Buffer[TailIndex] != 0xDC || UART_DMA_Buffer[DMA_INDEX(TailIndex, 1)] != 0xBA)
{ {
g_uart_write_index = DmaLength; write_index = DmaLength;
return false; return false;
} }
@ -492,29 +541,29 @@ bool UART_IsCommandAvailable(void)
memmove(UART_Command.Buffer, UART_DMA_Buffer + Index, TailIndex - Index); memmove(UART_Command.Buffer, UART_DMA_Buffer + Index, TailIndex - Index);
TailIndex = DMA_INDEX(TailIndex, 2); TailIndex = DMA_INDEX(TailIndex, 2);
if (TailIndex < g_uart_write_index) if (TailIndex < write_index)
{ {
memset(UART_DMA_Buffer + g_uart_write_index, 0, sizeof(UART_DMA_Buffer) - g_uart_write_index); memset(UART_DMA_Buffer + write_index, 0, sizeof(UART_DMA_Buffer) - write_index);
memset(UART_DMA_Buffer, 0, TailIndex); memset(UART_DMA_Buffer, 0, TailIndex);
} }
else else
memset(UART_DMA_Buffer + g_uart_write_index, 0, TailIndex - g_uart_write_index); memset(UART_DMA_Buffer + write_index, 0, TailIndex - write_index);
g_uart_write_index = TailIndex; write_index = TailIndex;
if (UART_Command.Header.ID == 0x0514) if (UART_Command.Header.ID == 0x0514)
bIsEncrypted = false; is_encrypted = false;
if (UART_Command.Header.ID == 0x6902) if (UART_Command.Header.ID == 0x6902)
bIsEncrypted = true; is_encrypted = true;
if (bIsEncrypted) if (is_encrypted)
{ {
unsigned int i; unsigned int i;
for (i = 0; i < (Size + 2u); i++) for (i = 0; i < (Size + 2u); i++)
UART_Command.Buffer[i] ^= Obfuscation[i % 16]; UART_Command.Buffer[i] ^= Obfuscation[i % 16];
} }
CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8); CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8);
return (CRC_Calculate(UART_Command.Buffer, Size) != CRC) ? false : true; return (CRC_Calculate(UART_Command.Buffer, Size) != CRC) ? false : true;
@ -524,41 +573,43 @@ void UART_HandleCommand(void)
{ {
switch (UART_Command.Header.ID) switch (UART_Command.Header.ID)
{ {
case 0x0514: case 0x0514: // version
CMD_0514(UART_Command.Buffer); cmd_0514(UART_Command.Buffer);
break; break;
case 0x051B: case 0x051B: // read eeprom
CMD_051B(UART_Command.Buffer); cmd_051B(UART_Command.Buffer);
break; break;
case 0x051D: case 0x051D: // write eeprom
CMD_051D(UART_Command.Buffer); cmd_051D(UART_Command.Buffer);
break; break;
case 0x051F: // Not implementing non-authentic command case 0x051F: // Not implementing non-authentic command
break; break;
case 0x0521: // Not implementing non-authentic command case 0x0521: // Not implementing non-authentic command
break; break;
case 0x0527: case 0x0527: // read RSSI
CMD_0527(); cmd_0527();
break; break;
case 0x0529: case 0x0529: // read ADC
CMD_0529(); cmd_0529();
break; break;
case 0x052D: #ifdef INCLUDE_AES
CMD_052D(UART_Command.Buffer); case 0x052D: //
cmd_052D(UART_Command.Buffer);
break; break;
#endif
case 0x052F:
CMD_052F(UART_Command.Buffer); case 0x052F: //
cmd_052F(UART_Command.Buffer);
break; break;
case 0x05DD: case 0x05DD: // reboot
#if defined(ENABLE_OVERLAY) #if defined(ENABLE_OVERLAY)
overlay_FLASH_RebootToBootloader(); overlay_FLASH_RebootToBootloader();
#else #else

249
audio.c
View File

@ -44,7 +44,7 @@
0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E, 0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E,
0x5A, 0x64, 0x5A, 0x64,
}; };
static const uint8_t VoiceClipLengthEnglish[76] = static const uint8_t VoiceClipLengthEnglish[76] =
{ {
0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37, 0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37,
@ -58,14 +58,14 @@
0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37, 0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37,
0x41, 0x32, 0x3C, 0x37, 0x41, 0x32, 0x3C, 0x37,
}; };
voice_id_t g_voice_id[8]; voice_id_t g_voice_id[8];
uint8_t g_voice_read_index; uint8_t g_voice_read_index;
uint8_t g_voice_write_index; uint8_t g_voice_write_index;
volatile uint16_t g_count_down_to_play_next_voice_10ms; volatile uint16_t g_count_down_to_play_next_voice_10ms;
volatile bool g_flag_play_queued_voice; volatile bool g_flag_play_queued_voice;
voice_id_t g_another_voice_id = VOICE_ID_INVALID; voice_id_t g_another_voice_id = VOICE_ID_INVALID;
#endif #endif
beep_type_t g_beep_to_play = BEEP_NONE; beep_type_t g_beep_to_play = BEEP_NONE;
@ -88,7 +88,7 @@ void AUDIO_PlayBeep(beep_type_t Beep)
if (g_screen_to_display == DISPLAY_AIRCOPY) if (g_screen_to_display == DISPLAY_AIRCOPY)
return; return;
#endif #endif
if (g_current_function == FUNCTION_RECEIVE) if (g_current_function == FUNCTION_RECEIVE)
return; return;
@ -103,10 +103,12 @@ void AUDIO_PlayBeep(beep_type_t Beep)
BK4819_RX_TurnOn(); BK4819_RX_TurnOn();
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (g_fm_radio_mode) #ifdef MUTE_AUDIO_FOR_VOICE
BK1080_Mute(true); if (g_fm_radio_mode)
BK1080_Mute(true);
#endif
#endif #endif
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);
switch (Beep) switch (Beep)
@ -133,7 +135,7 @@ void AUDIO_PlayBeep(beep_type_t Beep)
ToneFrequency = 880; ToneFrequency = 880;
break; break;
} }
BK4819_PlayTone(ToneFrequency, true); BK4819_PlayTone(ToneFrequency, true);
SYSTEM_DelayMs(2); SYSTEM_DelayMs(2);
@ -152,7 +154,7 @@ void AUDIO_PlayBeep(beep_type_t Beep)
SYSTEM_DelayMs(60); SYSTEM_DelayMs(60);
BK4819_EnterTxMute(); BK4819_EnterTxMute();
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);
case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL: case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL:
case BEEP_500HZ_60MS_DOUBLE_BEEP: case BEEP_500HZ_60MS_DOUBLE_BEEP:
BK4819_ExitTxMute(); BK4819_ExitTxMute();
@ -170,7 +172,7 @@ void AUDIO_PlayBeep(beep_type_t Beep)
BK4819_ExitTxMute(); BK4819_ExitTxMute();
Duration = 40; Duration = 40;
break; break;
case BEEP_880HZ_200MS: case BEEP_880HZ_200MS:
BK4819_ExitTxMute(); BK4819_ExitTxMute();
Duration = 200; Duration = 200;
@ -208,7 +210,7 @@ void AUDIO_PlayBeep(beep_type_t Beep)
if (g_fm_radio_mode) if (g_fm_radio_mode)
BK1080_Mute(false); BK1080_Mute(false);
#endif #endif
if (g_current_function == FUNCTION_POWER_SAVE && g_rx_idle_mode) if (g_current_function == FUNCTION_POWER_SAVE && g_rx_idle_mode)
BK4819_Sleep(); BK4819_Sleep();
} }
@ -218,18 +220,20 @@ void AUDIO_PlayBeep(beep_type_t Beep)
void AUDIO_PlayVoice(uint8_t VoiceID) void AUDIO_PlayVoice(uint8_t VoiceID)
{ {
unsigned int i; unsigned int i;
if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF)
return;
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTEM_DelayMs(20); SYSTEM_DelayMs(20);
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
if ((VoiceID & 0x80U) == 0) if ((VoiceID & 0x80U) == 0)
GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
else else
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1);
SYSTICK_DelayUs(1000); SYSTICK_DelayUs(1000);
GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0);
SYSTICK_DelayUs(1200); SYSTICK_DelayUs(1200);
@ -238,122 +242,123 @@ void AUDIO_PlayBeep(beep_type_t Beep)
SYSTICK_DelayUs(200); SYSTICK_DelayUs(200);
} }
} }
void AUDIO_PlaySingleVoice(bool flag) void AUDIO_PlaySingleVoice(bool flag)
{ {
uint8_t VoiceID;
uint8_t Delay; uint8_t Delay;
uint8_t VoiceID = g_voice_id[0];
VoiceID = g_voice_id[0];
if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF || g_voice_write_index == 0)
if (g_eeprom.voice_prompt != VOICE_PROMPT_OFF && g_voice_write_index > 0) goto Bailout;
{
if (g_eeprom.voice_prompt == VOICE_PROMPT_CHINESE) if (g_eeprom.voice_prompt == VOICE_PROMPT_CHINESE)
{ // Chinese { // Chinese
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese)) if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese))
goto Bailout; goto Bailout;
Delay = VoiceClipLengthChinese[VoiceID]; Delay = VoiceClipLengthChinese[VoiceID];
VoiceID += VOICE_ID_CHI_BASE; VoiceID += VOICE_ID_CHI_BASE;
} }
else else
{ // English { // English
if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish)) if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish))
goto Bailout; goto Bailout;
Delay = VoiceClipLengthEnglish[VoiceID]; Delay = VoiceClipLengthEnglish[VoiceID];
VoiceID += VOICE_ID_ENG_BASE; VoiceID += VOICE_ID_ENG_BASE;
} }
if (g_current_function == FUNCTION_RECEIVE || #ifdef MUTE_AUDIO_FOR_VOICE
g_current_function == FUNCTION_MONITOR || if (g_current_function == FUNCTION_RECEIVE || g_current_function == FUNCTION_MONITOR)
g_current_function == FUNCTION_INCOMING) // 1of11
BK4819_SetAF(BK4819_AF_MUTE); BK4819_SetAF(BK4819_AF_MUTE);
#endif
#ifdef ENABLE_FMRADIO
#ifdef ENABLE_FMRADIO
#ifdef MUTE_AUDIO_FOR_VOICE
if (g_fm_radio_mode) if (g_fm_radio_mode)
BK1080_Mute(true); BK1080_Mute(true);
#endif #endif
#endif
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
#ifdef ENABLE_VOX
g_vox_resume_count_down = 2000;
#endif
SYSTEM_DelayMs(5);
AUDIO_PlayVoice(VoiceID);
if (g_voice_write_index == 1)
Delay += 3;
if (flag)
{
SYSTEM_DelayMs(Delay * 10);
if (g_current_function == FUNCTION_RECEIVE || g_current_function == FUNCTION_MONITOR)
BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM);
#ifdef ENABLE_FMRADIO
if (g_fm_radio_mode)
BK1080_Mute(false);
#endif
if (!g_enable_speaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
g_voice_write_index = 0;
g_voice_read_index = 0;
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
g_vox_resume_count_down = 2000; g_vox_resume_count_down = 80;
#endif #endif
SYSTEM_DelayMs(5);
AUDIO_PlayVoice(VoiceID);
if (g_voice_write_index == 1)
Delay += 3;
if (flag)
{
SYSTEM_DelayMs(Delay * 10);
if (g_current_function == FUNCTION_RECEIVE ||
g_current_function == FUNCTION_MONITOR ||
g_current_function == FUNCTION_INCOMING) // 1of11
BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM);
#ifdef ENABLE_FMRADIO
if (g_fm_radio_mode)
BK1080_Mute(false);
#endif
if (!g_enable_speaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
g_voice_write_index = 0;
g_voice_read_index = 0;
#ifdef ENABLE_VOX
g_vox_resume_count_down = 80;
#endif
return;
}
g_voice_read_index = 1;
g_count_down_to_play_next_voice_10ms = Delay;
g_flag_play_queued_voice = false;
return; return;
} }
g_voice_read_index = 1;
g_count_down_to_play_next_voice_10ms = Delay;
g_flag_play_queued_voice = false;
return;
Bailout: Bailout:
g_voice_read_index = 0; g_voice_read_index = 0;
g_voice_write_index = 0; g_voice_write_index = 0;
} }
void AUDIO_SetVoiceID(uint8_t Index, voice_id_t VoiceID) void AUDIO_SetVoiceID(uint8_t Index, voice_id_t VoiceID)
{ {
if (Index >= ARRAY_SIZE(g_voice_id)) if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF || Index == 0)
return;
if (Index == 0)
{ {
g_voice_write_index = 0; g_voice_write_index = 0;
g_voice_read_index = 0; g_voice_read_index = 0;
} }
g_voice_id[Index] = VoiceID; if (g_eeprom.voice_prompt != VOICE_PROMPT_OFF && Index < ARRAY_SIZE(g_voice_id))
{
g_voice_write_index++; g_voice_id[Index] = VoiceID;
g_voice_write_index++;
}
} }
uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value) uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value)
{ {
uint16_t Remainder; uint16_t Remainder;
uint8_t Result; uint8_t Result;
uint8_t Count; uint8_t Count;
if (Index == 0) if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF || Index == 0)
{ {
g_voice_write_index = 0; g_voice_write_index = 0;
g_voice_read_index = 0; g_voice_read_index = 0;
} }
if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF)
return 0;
Count = 0; Count = 0;
Result = Value / 1000U; Result = Value / 1000U;
Remainder = Value % 1000U; Remainder = Value % 1000U;
@ -373,21 +378,26 @@ void AUDIO_PlayBeep(beep_type_t Beep)
g_voice_id[g_voice_write_index++] = (voice_id_t)Result; g_voice_id[g_voice_write_index++] = (voice_id_t)Result;
Count++; Count++;
Remainder -= Result * 10U; Remainder -= Result * 10U;
Skip: Skip:
g_voice_id[g_voice_write_index++] = (voice_id_t)Remainder; g_voice_id[g_voice_write_index++] = (voice_id_t)Remainder;
return Count + 1U; return Count + 1U;
} }
void AUDIO_PlayQueuedVoice(void) void AUDIO_PlayQueuedVoice(void)
{ {
uint8_t VoiceID; uint8_t VoiceID;
uint8_t Delay; uint8_t Delay;
bool Skip; bool Skip = false;
Skip = false; if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF)
{
g_voice_write_index = 0;
g_voice_read_index = 0;
return;
}
if (g_voice_read_index != g_voice_write_index && g_eeprom.voice_prompt != VOICE_PROMPT_OFF) if (g_voice_read_index != g_voice_write_index && g_eeprom.voice_prompt != VOICE_PROMPT_OFF)
{ {
VoiceID = g_voice_id[g_voice_read_index]; VoiceID = g_voice_id[g_voice_read_index];
@ -411,44 +421,47 @@ void AUDIO_PlayBeep(beep_type_t Beep)
else else
Skip = true; Skip = true;
} }
g_voice_read_index++; g_voice_read_index++;
if (!Skip) if (!Skip)
{ {
if (g_voice_read_index == g_voice_write_index) if (g_voice_read_index == g_voice_write_index)
Delay += 3; Delay += 3;
AUDIO_PlayVoice(VoiceID); AUDIO_PlayVoice(VoiceID);
g_count_down_to_play_next_voice_10ms = Delay; g_count_down_to_play_next_voice_10ms = Delay;
g_flag_play_queued_voice = false; g_flag_play_queued_voice = false;
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
g_vox_resume_count_down = 2000; g_vox_resume_count_down = 2000;
#endif #endif
return; return;
} }
} }
if (g_current_function == FUNCTION_RECEIVE || // ***********************
g_current_function == FUNCTION_MONITOR || // unmute the radios audio
g_current_function == FUNCTION_INCOMING) // 1of11
if (g_current_function == FUNCTION_RECEIVE || g_current_function == FUNCTION_MONITOR)
BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM); BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM);
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
if (g_fm_radio_mode) if (g_fm_radio_mode)
BK1080_Mute(false); BK1080_Mute(false);
#endif #endif
if (!g_enable_speaker) if (!g_enable_speaker)
GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH);
// **********************
#ifdef ENABLE_VOX #ifdef ENABLE_VOX
g_vox_resume_count_down = 80; g_vox_resume_count_down = 80;
#endif #endif
g_voice_write_index = 0; g_voice_write_index = 0;
g_voice_read_index = 0; g_voice_read_index = 0;
} }

39
board.c
View File

@ -516,7 +516,7 @@ void BOARD_Init(void)
CRC_Init(); CRC_Init();
} }
void BOARD_EEPROM_Init(void) void BOARD_EEPROM_load(void)
{ {
unsigned int i; unsigned int i;
uint8_t Data[16]; uint8_t Data[16];
@ -700,21 +700,21 @@ void BOARD_EEPROM_Init(void)
// 0F40..0F47 // 0F40..0F47
EEPROM_ReadBuffer(0x0F40, Data, 8); EEPROM_ReadBuffer(0x0F40, Data, 8);
g_setting_f_lock = (Data[0] < 6) ? Data[0] : F_LOCK_OFF; g_setting_freq_lock = (Data[0] < 6) ? Data[0] : F_LOCK_OFF;
g_setting_350_tx_enable = (Data[1] < 2) ? Data[1] : false; // was true g_setting_350_tx_enable = (Data[1] < 2) ? Data[1] : false; // was true
g_setting_killed = (Data[2] < 2) ? Data[2] : false; g_setting_killed = (Data[2] < 2) ? Data[2] : false;
g_setting_200_tx_enable = (Data[3] < 2) ? Data[3] : false; g_setting_200_tx_enable = (Data[3] < 2) ? Data[3] : false;
g_setting_500_tx_enable = (Data[4] < 2) ? Data[4] : false; g_setting_500_tx_enable = (Data[4] < 2) ? Data[4] : false;
g_setting_350_enable = (Data[5] < 2) ? Data[5] : true; g_setting_350_enable = (Data[5] < 2) ? Data[5] : true;
g_setting_scramble_enable = (Data[6] < 2) ? Data[6] : true; g_setting_scramble_enable = (Data[6] < 2) ? Data[6] : true;
g_setting_tx_enable = (Data[7] & (1u << 0)) ? true : false; g_setting_tx_enable = (Data[7] & (1u << 0)) ? true : false;
g_setting_live_dtmf_decoder = (Data[7] & (1u << 1)) ? true : false; g_setting_live_dtmf_decoder = (Data[7] & (1u << 1)) ? true : false;
g_setting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2; g_setting_battery_text = (((Data[7] >> 2) & 3u) <= 2) ? (Data[7] >> 2) & 3 : 2;
#ifdef ENABLE_AUDIO_BAR #ifdef ENABLE_AUDIO_BAR
g_setting_mic_bar = (Data[7] & (1u << 4)) ? true : false; g_setting_mic_bar = (Data[7] & (1u << 4)) ? true : false;
#endif #endif
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
g_setting_am_fix = (Data[7] & (1u << 5)) ? true : false; g_setting_am_fix = (Data[7] & (1u << 5)) ? true : false;
#endif #endif
g_setting_backlight_on_tx_rx = (Data[7] >> 6) & 3u; g_setting_backlight_on_tx_rx = (Data[7] >> 6) & 3u;
@ -727,7 +727,7 @@ void BOARD_EEPROM_Init(void)
// 0D60..0E27 // 0D60..0E27
EEPROM_ReadBuffer(0x0D60, g_user_channel_attributes, sizeof(g_user_channel_attributes)); EEPROM_ReadBuffer(0x0D60, g_user_channel_attributes, sizeof(g_user_channel_attributes));
// 0F30..0F3F // 0F30..0F3F .. AES key
EEPROM_ReadBuffer(0x0F30, g_custom_aes_key, sizeof(g_custom_aes_key)); EEPROM_ReadBuffer(0x0F30, g_custom_aes_key, sizeof(g_custom_aes_key));
g_has_custom_aes_key = false; g_has_custom_aes_key = false;
for (i = 0; i < ARRAY_SIZE(g_custom_aes_key); i++) for (i = 0; i < ARRAY_SIZE(g_custom_aes_key); i++)
@ -735,9 +735,20 @@ void BOARD_EEPROM_Init(void)
if (g_custom_aes_key[i] != 0xFFFFFFFFu) if (g_custom_aes_key[i] != 0xFFFFFFFFu)
{ {
g_has_custom_aes_key = true; g_has_custom_aes_key = true;
return; break;
} }
} }
#if ENABLE_RESET_AES_KEY
if (g_has_custom_aes_key)
{ // ugh :( .. wipe it
uint8_t *p_aes = (uint8_t*)&g_custom_aes_key;
memset(p_aes, 0xff, sizeof(g_custom_aes_key));
for (i = 0; i < sizeof(g_custom_aes_key); i += 8)
EEPROM_WriteBuffer(0x0F30 + i, &p_aes[i]);
g_has_custom_aes_key = false;
}
#endif
} }
void BOARD_EEPROM_LoadMoreSettings(void) void BOARD_EEPROM_LoadMoreSettings(void)

View File

@ -25,7 +25,7 @@ void BOARD_PORTCON_Init(void);
void BOARD_ADC_Init(void); void BOARD_ADC_Init(void);
void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent); void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent);
void BOARD_Init(void); void BOARD_Init(void);
void BOARD_EEPROM_Init(void); void BOARD_EEPROM_load(void);
void BOARD_EEPROM_LoadMoreSettings(void); void BOARD_EEPROM_LoadMoreSettings(void);
uint32_t BOARD_fetchChannelFrequency(const int channel); uint32_t BOARD_fetchChannelFrequency(const int channel);
void BOARD_fetchChannelName(char *s, const int channel); void BOARD_fetchChannelName(char *s, const int channel);

Binary file not shown.

Binary file not shown.

View File

@ -134,7 +134,7 @@ int TX_freq_check(const uint32_t Frequency)
if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower)
return -1; // BX chip does not work in this range return -1; // BX chip does not work in this range
switch (g_setting_f_lock) switch (g_setting_freq_lock)
{ {
case F_LOCK_OFF: case F_LOCK_OFF:
if (Frequency >= 13600000 && Frequency < 17400000) if (Frequency >= 13600000 && Frequency < 17400000)

View File

@ -31,7 +31,7 @@
#include "ui/menu.h" #include "ui/menu.h"
#include "ui/ui.h" #include "ui/ui.h"
BOOT_Mode_t BOOT_GetMode(void) boot_mode_t BOOT_GetMode(void)
{ {
unsigned int i; unsigned int i;
key_code_t Keys[2]; key_code_t Keys[2];
@ -47,7 +47,7 @@ BOOT_Mode_t BOOT_GetMode(void)
if (Keys[0] == Keys[1]) if (Keys[0] == Keys[1])
{ {
if (Keys[0] == KEY_SIDE1) if (Keys[0] == KEY_SIDE1)
return BOOT_MODE_F_LOCK; return BOOT_MODE_UNHIDE_HIDDEN;
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY
if (Keys[0] == KEY_SIDE2) if (Keys[0] == KEY_SIDE2)
@ -58,9 +58,9 @@ BOOT_Mode_t BOOT_GetMode(void)
return BOOT_MODE_NORMAL; return BOOT_MODE_NORMAL;
} }
void BOOT_ProcessMode(BOOT_Mode_t Mode) void BOOT_ProcessMode(boot_mode_t Mode)
{ {
if (Mode == BOOT_MODE_F_LOCK) if (Mode == BOOT_MODE_UNHIDE_HIDDEN)
{ {
GUI_SelectNextDisplay(DISPLAY_MENU); GUI_SelectNextDisplay(DISPLAY_MENU);
} }

View File

@ -20,19 +20,18 @@
#include <stdint.h> #include <stdint.h>
#include "driver/keyboard.h" #include "driver/keyboard.h"
enum BOOT_Mode_t enum boot_mode_e
{ {
BOOT_MODE_NORMAL = 0, BOOT_MODE_NORMAL = 0, // normal boot
BOOT_MODE_F_LOCK, BOOT_MODE_UNHIDE_HIDDEN, // unhide the hidden menu items
#ifdef ENABLE_AIRCOPY #ifdef ENABLE_AIRCOPY
BOOT_MODE_AIRCOPY BOOT_MODE_AIRCOPY // do an air-copy
#endif #endif
}; };
typedef enum boot_mode_e boot_mode_t;
typedef enum BOOT_Mode_t BOOT_Mode_t; boot_mode_t BOOT_GetMode(void);
void BOOT_ProcessMode(boot_mode_t Mode);
BOOT_Mode_t BOOT_GetMode(void);
void BOOT_ProcessMode(BOOT_Mode_t Mode);
#endif #endif

39
main.c
View File

@ -51,7 +51,7 @@ void _putchar(char c)
void Main(void) void Main(void)
{ {
unsigned int i; unsigned int i;
BOOT_Mode_t BootMode; boot_mode_t BootMode;
// Enable clock gating of blocks we need // Enable clock gating of blocks we need
SYSCON_DEV_CLK_GATE = 0 SYSCON_DEV_CLK_GATE = 0
@ -89,7 +89,7 @@ void Main(void)
BOARD_ADC_GetBatteryInfo(&g_usb_current_voltage, &g_usb_current); BOARD_ADC_GetBatteryInfo(&g_usb_current_voltage, &g_usb_current);
BOARD_EEPROM_Init(); BOARD_EEPROM_load();
BOARD_EEPROM_LoadMoreSettings(); BOARD_EEPROM_LoadMoreSettings();
@ -105,33 +105,33 @@ void Main(void)
BATTERY_GetReadings(false); BATTERY_GetReadings(false);
ST7565_SetContrast(g_setting_contrast);
#ifdef ENABLE_AM_FIX #ifdef ENABLE_AM_FIX
AM_fix_init(); AM_fix_init();
#endif #endif
BootMode = BOOT_GetMode(); BootMode = BOOT_GetMode();
g_f_lock = (BootMode == BOOT_MODE_F_LOCK); // flag to say include the hidden menu items g_unhide_hidden = (BootMode == BOOT_MODE_UNHIDE_HIDDEN); // flag to say include the hidden menu items
#if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG)
if (g_f_lock) if (g_unhide_hidden)
UART_SendText("boot_f_lock\r\n"); UART_SendText("boot_unhide_hidden\r\n");
#endif #endif
// sort the menu list // sort the menu list
UI_SortMenu(!g_f_lock); UI_SortMenu(!g_unhide_hidden);
ST7565_SetContrast(g_setting_contrast);
// wait for user to release all butts before moving on // wait for user to release all butts before moving on
if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) ||
KEYBOARD_Poll() != KEY_INVALID || KEYBOARD_Poll() != KEY_INVALID ||
BootMode != BOOT_MODE_NORMAL) BootMode != BOOT_MODE_NORMAL)
{ // keys are pressed {
UI_DisplayReleaseKeys();
backlight_turn_on(); backlight_turn_on();
UI_DisplayReleaseKeys();
i = 0; i = 0;
while (i < 50) // 500ms while (i < (500 / 10)) // 500ms
{ {
i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0; i = (GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) && KEYBOARD_Poll() == KEY_INVALID) ? i + 1 : 0;
SYSTEM_DelayMs(10); SYSTEM_DelayMs(10);
@ -156,8 +156,8 @@ void Main(void)
backlight_turn_on(); backlight_turn_on();
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
AUDIO_SetVoiceID(0, VOICE_ID_WELCOME); // AUDIO_SetVoiceID(0, VOICE_ID_WELCOME);
AUDIO_PlaySingleVoice(0); // AUDIO_PlaySingleVoice(0);
#endif #endif
if (g_eeprom.pwr_on_display_mode != PWR_ON_DISPLAY_MODE_NONE) if (g_eeprom.pwr_on_display_mode != PWR_ON_DISPLAY_MODE_NONE)
@ -179,9 +179,9 @@ void Main(void)
#ifdef ENABLE_PWRON_PASSWORD #ifdef ENABLE_PWRON_PASSWORD
if (g_eeprom.power_on_password < 1000000) if (g_eeprom.power_on_password < 1000000)
{ {
g_is_in_lock_screen = true; g_password_locked = true;
UI_DisplayLock(); UI_DisplayLock();
g_is_in_lock_screen = false; g_password_locked = false;
} }
#endif #endif
@ -192,12 +192,13 @@ void Main(void)
g_update_status = true; g_update_status = true;
#ifdef ENABLE_VOICE #ifdef ENABLE_VOICE
if (g_eeprom.voice_prompt != VOICE_PROMPT_OFF)
{ {
uint8_t Channel; const uint8_t Channel = g_eeprom.screen_channel[g_eeprom.tx_vfo];
// AUDIO_SetVoiceID(0, VOICE_ID_WELCOME); AUDIO_SetVoiceID(0, VOICE_ID_WELCOME);
AUDIO_PlaySingleVoice(0);
Channel = g_eeprom.screen_channel[g_eeprom.tx_vfo];
if (IS_USER_CHANNEL(Channel)) if (IS_USER_CHANNEL(Channel))
{ {
AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE); AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE);
@ -212,8 +213,6 @@ void Main(void)
#ifdef ENABLE_NOAA #ifdef ENABLE_NOAA
RADIO_ConfigureNOAA(); RADIO_ConfigureNOAA();
#endif #endif
// ******************
} }
while (1) while (1)

9
misc.c
View File

@ -90,7 +90,7 @@ bool g_setting_200_tx_enable;
bool g_setting_500_tx_enable; bool g_setting_500_tx_enable;
bool g_setting_350_enable; bool g_setting_350_enable;
bool g_setting_tx_enable; bool g_setting_tx_enable;
uint8_t g_setting_f_lock; uint8_t g_setting_freq_lock;
bool g_setting_scramble_enable; bool g_setting_scramble_enable;
uint8_t g_setting_backlight_on_tx_rx; uint8_t g_setting_backlight_on_tx_rx;
@ -119,7 +119,6 @@ bool g_monitor_enabled = false; // true opens the squ
uint32_t g_custom_aes_key[4]; uint32_t g_custom_aes_key[4];
bool g_has_custom_aes_key; bool g_has_custom_aes_key;
uint32_t g_challenge[4]; uint32_t g_challenge[4];
uint8_t g_try_count;
uint8_t g_eeprom_1EC0_0[8]; uint8_t g_eeprom_1EC0_0[8];
uint8_t g_eeprom_1EC0_1[8]; uint8_t g_eeprom_1EC0_1[8];
@ -161,7 +160,7 @@ bool g_enable_speaker;
uint8_t g_key_input_count_down = 0; uint8_t g_key_input_count_down = 0;
uint8_t g_key_lock_count_down_500ms; uint8_t g_key_lock_count_down_500ms;
uint8_t g_rtte_count_down; uint8_t g_rtte_count_down;
bool g_is_in_lock_screen; bool g_password_locked;
uint8_t g_update_status; uint8_t g_update_status;
uint8_t g_found_CTCSS; uint8_t g_found_CTCSS;
uint8_t g_found_CDCSS; uint8_t g_found_CDCSS;
@ -240,7 +239,7 @@ uint8_t g_fsk_wite_index;
bool g_update_display; bool g_update_display;
bool g_f_lock = false; bool g_unhide_hidden = false;
uint8_t g_show_chan_prefix; uint8_t g_show_chan_prefix;
@ -264,8 +263,6 @@ volatile uint8_t g_boot_counter_10ms;
int16_t g_current_rssi[2] = {0, 0}; // now one per VFO int16_t g_current_rssi[2] = {0, 0}; // now one per VFO
uint8_t g_is_locked = 0xFF;
unsigned int get_RX_VFO(void) unsigned int get_RX_VFO(void)
{ {
unsigned int rx_vfo = g_eeprom.tx_vfo; unsigned int rx_vfo = g_eeprom.tx_vfo;

8
misc.h
View File

@ -166,7 +166,7 @@ extern bool g_setting_200_tx_enable;
extern bool g_setting_500_tx_enable; extern bool g_setting_500_tx_enable;
extern bool g_setting_350_enable; extern bool g_setting_350_enable;
extern bool g_setting_tx_enable; extern bool g_setting_tx_enable;
extern uint8_t g_setting_f_lock; extern uint8_t g_setting_freq_lock;
extern bool g_setting_scramble_enable; extern bool g_setting_scramble_enable;
extern uint8_t g_setting_backlight_on_tx_rx; extern uint8_t g_setting_backlight_on_tx_rx;
@ -196,7 +196,6 @@ extern const uint32_t g_default_aes_key[4];
extern uint32_t g_custom_aes_key[4]; extern uint32_t g_custom_aes_key[4];
extern bool g_has_custom_aes_key; extern bool g_has_custom_aes_key;
extern uint32_t g_challenge[4]; extern uint32_t g_challenge[4];
extern uint8_t g_try_count;
extern uint8_t g_eeprom_1EC0_0[8]; extern uint8_t g_eeprom_1EC0_0[8];
extern uint8_t g_eeprom_1EC0_1[8]; extern uint8_t g_eeprom_1EC0_1[8];
@ -240,7 +239,7 @@ extern bool g_enable_speaker;
extern uint8_t g_key_input_count_down; extern uint8_t g_key_input_count_down;
extern uint8_t g_key_lock_count_down_500ms; extern uint8_t g_key_lock_count_down_500ms;
extern uint8_t g_rtte_count_down; extern uint8_t g_rtte_count_down;
extern bool g_is_in_lock_screen; extern bool g_password_locked;
extern uint8_t g_update_status; extern uint8_t g_update_status;
extern uint8_t g_found_CTCSS; extern uint8_t g_found_CTCSS;
extern uint8_t g_found_CDCSS; extern uint8_t g_found_CDCSS;
@ -313,7 +312,7 @@ extern uint8_t g_fsk_wite_index;
#endif #endif
extern volatile bool g_next_time_slice; extern volatile bool g_next_time_slice;
extern bool g_update_display; extern bool g_update_display;
extern bool g_f_lock; extern bool g_unhide_hidden;
#ifdef ENABLE_FMRADIO #ifdef ENABLE_FMRADIO
extern uint8_t g_fm_channel_position; extern uint8_t g_fm_channel_position;
#endif #endif
@ -333,7 +332,6 @@ extern volatile bool g_flag_tail_tone_elimination_complete;
extern volatile bool g_schedule_fm; extern volatile bool g_schedule_fm;
#endif #endif
extern int16_t g_current_rssi[2]; // now one per VFO extern int16_t g_current_rssi[2]; // now one per VFO
extern uint8_t g_is_locked;
extern volatile uint8_t g_boot_counter_10ms; extern volatile uint8_t g_boot_counter_10ms;
unsigned int get_TX_VFO(void); unsigned int get_TX_VFO(void);

View File

@ -283,7 +283,7 @@ void SETTINGS_SaveSettings(void)
EEPROM_WriteBuffer(0x0F18, State); EEPROM_WriteBuffer(0x0F18, State);
memset(State, 0xFF, sizeof(State)); memset(State, 0xFF, sizeof(State));
State[0] = g_setting_f_lock; State[0] = g_setting_freq_lock;
State[1] = g_setting_350_tx_enable; State[1] = g_setting_350_tx_enable;
State[2] = g_setting_killed; State[2] = g_setting_killed;
State[3] = g_setting_200_tx_enable; State[3] = g_setting_200_tx_enable;

View File

@ -50,14 +50,14 @@ const t_menu_item g_menu_list[] =
{"W/N", VOICE_ID_CHANNEL_BANDWIDTH, MENU_W_N }, {"W/N", VOICE_ID_CHANNEL_BANDWIDTH, MENU_W_N },
{"Tx PWR", VOICE_ID_POWER, MENU_TXP }, // was "TXP" {"Tx PWR", VOICE_ID_POWER, MENU_TXP }, // was "TXP"
{"Rx DCS", VOICE_ID_DCS, MENU_R_DCS }, // was "R_DCS" {"Rx DCS", VOICE_ID_DCS, MENU_R_DCS }, // was "R_DCS"
{"RxCTCS", VOICE_ID_CTCSS, MENU_R_CTCS }, // was "R_CTCS" {"Rx CTS", VOICE_ID_CTCSS, MENU_R_CTCS }, // was "R_CTCS"
{"Tx DCS", VOICE_ID_DCS, MENU_T_DCS }, // was "T_DCS" {"Tx DCS", VOICE_ID_DCS, MENU_T_DCS }, // was "T_DCS"
{"TxCTCS", VOICE_ID_CTCSS, MENU_T_CTCS }, // was "T_CTCS" {"Tx CTS", VOICE_ID_CTCSS, MENU_T_CTCS }, // was "T_CTCS"
{"Tx DIR", VOICE_ID_TX_OFFSET_FREQ_DIR, MENU_SFT_D }, // was "SFT_D" {"Tx DIR", VOICE_ID_TX_OFFSET_FREQ_DIR, MENU_SFT_D }, // was "SFT_D"
{"TxOFFS", VOICE_ID_TX_OFFSET_FREQ, MENU_OFFSET }, // was "OFFSET" {"Tx OFS", VOICE_ID_TX_OFFSET_FREQ, MENU_OFFSET }, // was "OFFSET"
{"Tx TO", VOICE_ID_TRANSMIT_OVER_TIME, MENU_TOT }, // was "TOT" {"Tx TO", VOICE_ID_TRANSMIT_OVER_TIME, MENU_TOT }, // was "TOT"
{"Tx VFO", VOICE_ID_INVALID, MENU_XB }, // was "WX" {"Tx VFO", VOICE_ID_INVALID, MENU_XB }, // was "WX"
{"2nd RX", VOICE_ID_DUAL_STANDBY, MENU_TDR }, // was "TDR" {"Dual W", VOICE_ID_DUAL_STANDBY, MENU_TDR }, // was "TDR"
{"SCRAM", VOICE_ID_SCRAMBLER_ON, MENU_SCR }, // was "SCR" {"SCRAM", VOICE_ID_SCRAMBLER_ON, MENU_SCR }, // was "SCR"
{"BCL", VOICE_ID_BUSY_LOCKOUT, MENU_BCL }, {"BCL", VOICE_ID_BUSY_LOCKOUT, MENU_BCL },
{"CH SAV", VOICE_ID_MEMORY_CHANNEL, MENU_MEM_CH }, // was "MEM-CH" {"CH SAV", VOICE_ID_MEMORY_CHANNEL, MENU_MEM_CH }, // was "MEM-CH"
@ -266,11 +266,11 @@ const char g_sub_menu_pwr_on_msg[4][8] =
"NONE" "NONE"
}; };
const char g_sub_menu_roger_mode[3][9] = const char g_sub_menu_roger_mode[3][16] =
{ {
"OFF", "OFF",
"ROGER", "TX END\nROGER",
"MDC\n1200" "TX END\nMDC\n1200"
}; };
const char g_sub_menu_RESET[2][4] = const char g_sub_menu_RESET[2][4] =
@ -549,28 +549,31 @@ void UI_DisplayMenu(void)
case MENU_R_DCS: case MENU_R_DCS:
case MENU_T_DCS: case MENU_T_DCS:
strcpy(String, "CDCSS\n");
if (g_sub_menu_selection == 0) if (g_sub_menu_selection == 0)
strcpy(String, "OFF"); strcat(String, "OFF");
else else
if (g_sub_menu_selection < 105) if (g_sub_menu_selection < 105)
sprintf(String, "D%03oN", DCS_OPTIONS[g_sub_menu_selection - 1]); sprintf(String + strlen(String), "D%03oN", DCS_OPTIONS[g_sub_menu_selection - 1]);
else else
sprintf(String, "D%03oI", DCS_OPTIONS[g_sub_menu_selection - 105]); sprintf(String + strlen(String), "D%03oI", DCS_OPTIONS[g_sub_menu_selection - 105]);
break; break;
case MENU_R_CTCS: case MENU_R_CTCS:
case MENU_T_CTCS: case MENU_T_CTCS:
{ {
strcpy(String, "CTCSS\n");
#if 1 #if 1
// set CTCSS as the user adjusts it // set CTCSS as the user adjusts it
unsigned int Code; unsigned int Code;
freq_config_t *pConfig = (g_menu_cursor == MENU_R_CTCS) ? &g_tx_vfo->freq_config_rx : &g_tx_vfo->freq_config_tx; freq_config_t *pConfig = (g_menu_cursor == MENU_R_CTCS) ? &g_tx_vfo->freq_config_rx : &g_tx_vfo->freq_config_tx;
if (g_sub_menu_selection == 0) if (g_sub_menu_selection == 0)
{ {
strcpy(String, "OFF"); strcat(String, "OFF");
if (pConfig->code_type != CODE_TYPE_CONTINUOUS_TONE) if (pConfig->code_type != CODE_TYPE_CONTINUOUS_TONE)
break; break;
Code = 0; Code = 0;
pConfig->code_type = CODE_TYPE_OFF; pConfig->code_type = CODE_TYPE_OFF;
pConfig->code = Code; pConfig->code = Code;
@ -579,7 +582,7 @@ void UI_DisplayMenu(void)
} }
else else
{ {
sprintf(String, "%u.%uHz", CTCSS_OPTIONS[g_sub_menu_selection - 1] / 10, CTCSS_OPTIONS[g_sub_menu_selection - 1] % 10); sprintf(String + strlen(String), "%u.%uHz", CTCSS_OPTIONS[g_sub_menu_selection - 1] / 10, CTCSS_OPTIONS[g_sub_menu_selection - 1] % 10);
pConfig->code_type = CODE_TYPE_CONTINUOUS_TONE; pConfig->code_type = CODE_TYPE_CONTINUOUS_TONE;
Code = g_sub_menu_selection - 1; Code = g_sub_menu_selection - 1;
@ -589,9 +592,9 @@ void UI_DisplayMenu(void)
} }
#else #else
if (g_sub_menu_selection == 0) if (g_sub_menu_selection == 0)
strcpy(String, "OFF"); strcat(String, "OFF");
else else
sprintf(String, "%u.%uHz", CTCSS_OPTIONS[g_sub_menu_selection - 1] / 10, CTCSS_OPTIONS[g_sub_menu_selection - 1] % 10); sprintf(String + strlen(String), "%u.%uHz", CTCSS_OPTIONS[g_sub_menu_selection - 1] / 10, CTCSS_OPTIONS[g_sub_menu_selection - 1] % 10);
#endif #endif
break; break;
@ -921,7 +924,7 @@ void UI_DisplayMenu(void)
break; break;
case MENU_PTT_ID: case MENU_PTT_ID:
strcpy(String, "TX ID\n"); strcpy(String, (g_sub_menu_selection > 0) ? "TX ID\n" : "");
strcat(String, g_sub_menu_PTT_ID[g_sub_menu_selection]); strcat(String, g_sub_menu_PTT_ID[g_sub_menu_selection]);
break; break;
@ -950,8 +953,7 @@ void UI_DisplayMenu(void)
break; break;
case MENU_ROGER: case MENU_ROGER:
strcpy(String, "TX END\n"); strcpy(String, g_sub_menu_roger_mode[g_sub_menu_selection]);
strcpy(String + strlen(String), g_sub_menu_roger_mode[g_sub_menu_selection]);
break; break;
case MENU_VOL: case MENU_VOL:

View File

@ -162,7 +162,7 @@ extern const char g_sub_menu_mdf[4][15];
extern const char g_sub_menu_D_RSP[4][9]; extern const char g_sub_menu_D_RSP[4][9];
extern const char g_sub_menu_PTT_ID[5][15]; extern const char g_sub_menu_PTT_ID[5][15];
extern const char g_sub_menu_pwr_on_msg[4][8]; extern const char g_sub_menu_pwr_on_msg[4][8];
extern const char g_sub_menu_roger_mode[3][9]; extern const char g_sub_menu_roger_mode[3][16];
extern const char g_sub_menu_RESET[2][4]; extern const char g_sub_menu_RESET[2][4];
extern const char g_sub_menu_f_lock[6][8]; extern const char g_sub_menu_f_lock[6][8];
extern const char g_sub_menu_backlight[8][7]; extern const char g_sub_menu_backlight[8][7];

View File

@ -18,6 +18,7 @@
#include <string.h> #include <string.h>
#include "app/scanner.h" #include "app/scanner.h"
#include "board.h"
#include "dcs.h" #include "dcs.h"
#include "driver/st7565.h" #include "driver/st7565.h"
#include "external/printf/printf.h" #include "external/printf/printf.h"
@ -161,14 +162,20 @@ void UI_DisplayScanner(void)
break; break;
case SCAN_EDIT_STATE_BUSY: case SCAN_EDIT_STATE_SAVE:
strcpy(String, "SAVE "); strcpy(String, "SAVE ");
UI_GenerateChannelStringEx(String + strlen(String), g_show_chan_prefix, g_scan_channel); {
char s[11];
BOARD_fetchChannelName(s, g_scan_channel);
if (s[0] == 0)
UI_GenerateChannelStringEx(s, g_show_chan_prefix, g_scan_channel);
strcat(String, s);
}
break; break;
case SCAN_EDIT_STATE_DONE: case SCAN_EDIT_STATE_DONE:
strcpy(String, "* repeat M save");
text_centered = true; text_centered = true;
strcpy(String, "SAVE ?");
break; break;
} }