diff --git a/Makefile b/Makefile index ccae5b4..7ce3a44 100644 --- a/Makefile +++ b/Makefile @@ -13,10 +13,12 @@ ENABLE_AIRCOPY := 1 ENABLE_FMRADIO := 1 ENABLE_NOAA := 0 ENABLE_VOICE := 1 +ENABLE_MUTE_RADIO_FOR_VOICE := 0 ENABLE_VOX := 1 ENABLE_ALARM := 1 ENABLE_TX1750 := 1 ENABLE_PWRON_PASSWORD := 0 +ENABLE_RESET_AES_KEY := 1 ENABLE_BIG_FREQ := 0 ENABLE_SMALL_BOLD := 1 ENABLE_KEEP_MEM_NAME := 1 @@ -30,7 +32,6 @@ ENABLE_SHOW_CHARGE_LEVEL := 0 ENABLE_REVERSE_BAT_SYMBOL := 1 ENABLE_CODE_SCAN_TIMEOUT := 0 ENABLE_FREQ_CODE_SCAN_TIMEOUT := 1 -ENABLE_FREQ_CODE_ROUNDING := 0 ENABLE_AM_FIX := 1 ENABLE_AM_FIX_SHOW_DATA := 1 ENABLE_SQUELCH_MORE_SENSITIVE := 1 @@ -209,10 +210,10 @@ CFLAGS = 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 -std=c11 -MMD + CFLAGS += -Os -Werror -mcpu=cortex-m0 -std=c11 -MMD else # 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 ifeq ($(ENABLE_LTO),1) @@ -227,9 +228,7 @@ endif # catch any and all warnings # better to bust than add new bugs -#CFLAGS += -Wall -#CFLAGS += -Wextra -#CFLAGS += -Wpedantic +CFLAGS += -Wall -Wextra -Wpedantic CFLAGS += -DPRINTF_INCLUDE_CONFIG_H CFLAGS += -DGIT_HASH=\"$(GIT_HASH)\" @@ -263,6 +262,9 @@ endif ifeq ($(ENABLE_VOICE),1) CFLAGS += -DENABLE_VOICE endif +ifeq ($(ENABLE_MUTE_RADIO_FOR_VOICE),1) + CFLAGS += -DENABLE_MUTE_RADIO_FOR_VOICE +endif ifeq ($(ENABLE_VOX),1) CFLAGS += -DENABLE_VOX endif @@ -275,6 +277,9 @@ endif ifeq ($(ENABLE_PWRON_PASSWORD),1) CFLAGS += -DENABLE_PWRON_PASSWORD endif +ifeq ($(ENABLE_RESET_AES_KEY),1) + CFLAGS += -DENABLE_RESET_AES_KEY +endif ifeq ($(ENABLE_KEEP_MEM_NAME),1) CFLAGS += -DENABLE_KEEP_MEM_NAME endif @@ -308,9 +313,6 @@ endif ifeq ($(ENABLE_FREQ_CODE_SCAN_TIMEOUT),1) CFLAGS += -DENABLE_FREQ_CODE_SCAN_TIMEOUT endif -ifeq ($(ENABLE_FREQ_CODE_ROUNDING),1) - CFLAGS += -DENABLE_FREQ_CODE_ROUNDING -endif ifeq ($(ENABLE_AM_FIX),1) CFLAGS += -DENABLE_AM_FIX endif diff --git a/README.md b/README.md index e228ffd..e04acf0 100644 --- a/README.md +++ b/README.md @@ -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_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_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_NOAA := 1 everything NOAA (only of any use in the USA) 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_ALARM := 1 TX alarms 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_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 diff --git a/app/app.c b/app/app.c index 2233463..ee4c722 100644 --- a/app/app.c +++ b/app/app.c @@ -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) #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 - BK4819_SetAF(g_rx_vfo->am_mode ? BK4819_AF_AM : BK4819_AF_FM); // no need, set it now FUNCTION_Select(Function); @@ -887,14 +893,15 @@ void APP_CheckRadioInterrupts(void) 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_schedule_dual_watch = false; // let the user see DW is not active g_dual_watch_active = false; - g_update_status = true; + g_update_status = true; } } } @@ -1127,6 +1134,7 @@ void APP_Update(void) { NOAA_IncreaseChannel(); RADIO_SetupRegisters(false); + g_noaa_count_down_10ms = 7; // 70ms g_schedule_noaa = false; } @@ -1136,17 +1144,21 @@ void APP_Update(void) // toggle between the VFO's if dual watch is enabled if (g_screen_to_display != DISPLAY_SCANNER && g_eeprom.dual_watch != DUAL_WATCH_OFF) { - #ifdef ENABLE_VOICE - if (g_voice_write_index == 0) + #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) + //UART_SendText("dual watch\r\n"); #endif + + #ifdef ENABLE_VOICE + if (g_voice_write_index == 0) + #endif { if (g_schedule_dual_watch) { if (g_scan_state_dir == SCAN_OFF && g_css_scan_mode == CSS_SCAN_MODE_OFF) { - #ifdef ENABLE_FMRADIO - if (!g_fm_radio_mode) - #endif + #ifdef ENABLE_FMRADIO + if (!g_fm_radio_mode) + #endif { if (!g_ptt_is_pressed && g_dtmf_call_state == DTMF_CALL_STATE_NONE && @@ -1168,30 +1180,30 @@ void APP_Update(void) } } - #ifdef ENABLE_FMRADIO - if (g_schedule_fm && - g_fm_scan_state != FM_SCAN_OFF && - g_current_function != FUNCTION_MONITOR && - g_current_function != FUNCTION_RECEIVE && - g_current_function != FUNCTION_TRANSMIT) - { // switch to FM radio mode - FM_Play(); - g_schedule_fm = false; - } - #endif +#ifdef ENABLE_FMRADIO + if (g_schedule_fm && + g_fm_scan_state != FM_SCAN_OFF && + g_current_function != FUNCTION_MONITOR && + g_current_function != FUNCTION_RECEIVE && + g_current_function != FUNCTION_TRANSMIT) + { // switch to FM radio mode + FM_Play(); + g_schedule_fm = false; + } +#endif - #ifdef ENABLE_VOX - if (g_eeprom.vox_switch) - APP_HandleVox(); - #endif +#ifdef ENABLE_VOX + if (g_eeprom.vox_switch) + APP_HandleVox(); +#endif if (g_schedule_power_save) { #ifdef ENABLE_NOAA if ( - #ifdef ENABLE_FMRADIO - g_fm_radio_mode || - #endif + #ifdef ENABLE_FMRADIO + g_fm_radio_mode || + #endif g_ptt_is_pressed || g_key_held || g_eeprom.battery_save == 0 || @@ -1495,7 +1507,7 @@ void APP_TimeSlice10ms(void) UI_DisplayStatus(false); return; } - + #ifdef ENABLE_BOOT_BEEPS if (g_boot_counter_10ms > 0 && (g_boot_counter_10ms % 25) == 0) AUDIO_PlayBeep(BEEP_880HZ_40MS_OPTIONAL); @@ -1641,7 +1653,7 @@ void APP_TimeSlice10ms(void) } if (g_scanner_edit_state != SCAN_EDIT_STATE_NONE) - { + { // waiting for user input choice APP_CheckKeys(); return; } @@ -1673,14 +1685,7 @@ void APP_TimeSlice10ms(void) BK4819_DisableFrequencyScan(); - #ifdef ENABLE_FREQ_CODE_ROUNDING - { // 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 + g_scan_frequency = Result; if (g_scan_hit_count < 3) { // keep scanning for an RF carrier @@ -1736,7 +1741,7 @@ void APP_TimeSlice10ms(void) BK4819_Disable(); if (ScanResult == BK4819_CSS_RESULT_CDCSS) - { + { // found a CDCSS code const uint8_t Code = DCS_GetCdcssCode(Result); if (Code != 0xFF) { @@ -1750,7 +1755,7 @@ void APP_TimeSlice10ms(void) } else if (ScanResult == BK4819_CSS_RESULT_CTCSS) - { + { // found a CTCSS tone const uint8_t code = DCS_GetCtcssCode(CtcssFreq); if (code != 0xFF) { @@ -1773,8 +1778,7 @@ void APP_TimeSlice10ms(void) } } - if (g_scan_css_state == SCAN_CSS_STATE_OFF || - g_scan_css_state == SCAN_CSS_STATE_SCANNING) + if (g_scan_css_state == SCAN_CSS_STATE_OFF || g_scan_css_state == SCAN_CSS_STATE_SCANNING) { // re-start scan BK4819_SetScanFrequency(g_scan_frequency); g_scan_delay_10ms = scan_freq_css_delay_10ms; @@ -1840,7 +1844,7 @@ void APP_TimeSlice500ms(void) { // config upload/download is running return; } - + if (g_keypad_locked > 0) if (--g_keypad_locked == 0) g_update_display = true; @@ -2269,7 +2273,7 @@ static void APP_ProcessKey(const key_code_t Key, const bool key_pressed, const b return; backlight_turn_on(); - + g_beep_to_play = 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) UART_printf("proc key 1 %3u %u %u %u %u\r\n", Key, key_pressed, key_held, g_fkey_pressed, flag); #endif - } if (g_fkey_pressed && (Key == KEY_PTT || Key == KEY_EXIT || Key == KEY_SIDE1 || Key == KEY_SIDE2)) diff --git a/app/fm.c b/app/fm.c index e985216..6fc7402 100644 --- a/app/fm.c +++ b/app/fm.c @@ -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) { + (void)key_held; // stop compiler warning + // if (key_held) // return; diff --git a/app/menu.c b/app/menu.c index b13081a..77fb175 100644 --- a/app/menu.c +++ b/app/menu.c @@ -792,7 +792,7 @@ void MENU_AcceptSetting(void) break; case MENU_F_LOCK: - g_setting_f_lock = g_sub_menu_selection; + g_setting_freq_lock = g_sub_menu_selection; break; case MENU_200TX: @@ -1226,7 +1226,7 @@ void MENU_ShowCurrentSetting(void) break; case MENU_F_LOCK: - g_sub_menu_selection = g_setting_f_lock; + g_sub_menu_selection = g_setting_freq_lock; break; case MENU_200TX: diff --git a/app/scanner.c b/app/scanner.c index d59af5b..f983a53 100644 --- a/app/scanner.c +++ b/app/scanner.c @@ -19,6 +19,7 @@ #include "app/scanner.h" #include "audio.h" #include "driver/bk4819.h" +#include "driver/uart.h" #include "frequencies.h" #include "misc.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) { - if (key_held || !key_pressed) + if (key_held || key_pressed) return; - if (g_scanner_edit_state == SCAN_EDIT_STATE_BUSY) + if (g_scanner_edit_state == SCAN_EDIT_STATE_SAVE) { 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) { - if (key_held || !key_pressed) + if (key_held || key_pressed) return; g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL; @@ -106,7 +107,7 @@ static void SCANNER_Key_EXIT(bool key_pressed, bool key_held) #endif break; - case SCAN_EDIT_STATE_BUSY: + case SCAN_EDIT_STATE_SAVE: if (g_input_box_index > 0) { 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; - if (key_held) - return; - - if (!key_pressed) + if (key_held || key_pressed) return; 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: if (!g_scan_single_frequency) { - #if 0 uint32_t Freq250 = FREQUENCY_FloorToStep(g_scan_frequency, 250, 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_scan_frequency = Freq250; } - #else + #elif 0 #ifdef ENABLE_1250HZ_STEP 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_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 } 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_show_chan_prefix = RADIO_CheckValidChannel(g_tx_vfo->channel_save, false, 0); + g_scan_channel = g_tx_vfo->channel_save; + g_show_chan_prefix = RADIO_CheckValidChannel(g_tx_vfo->channel_save, false, 0); + g_scanner_edit_state = SCAN_EDIT_STATE_SAVE; } 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; @@ -263,7 +279,7 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held) g_update_status = true; break; - case SCAN_EDIT_STATE_BUSY: + case SCAN_EDIT_STATE_SAVE: if (g_input_box_index == 0) { g_beep_to_play = BEEP_1KHZ_60MS_OPTIONAL; @@ -273,6 +289,10 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held) break; 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) { 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) { 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; @@ -292,9 +312,9 @@ static void SCANNER_Key_MENU(bool key_pressed, bool key_held) 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 = 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 = 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) @@ -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) { - if (key_held || !key_pressed) + if (key_held || key_pressed) return; 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 { - if (!key_pressed) + if (key_pressed) return; g_input_box_index = 0; 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_request_display_screen = DISPLAY_SCANNER; } @@ -460,9 +480,9 @@ void SCANNER_Start(void) g_CDCSS_lost = false; g_CDCSS_code_type = 0; g_CTCSS_lost = false; - #ifdef ENABLE_VOX + #ifdef ENABLE_VOX g_vox_lost = false; - #endif + #endif g_squelch_lost = false; g_scanner_edit_state = SCAN_EDIT_STATE_NONE; g_scan_freq_css_timer_10ms = 0; diff --git a/app/scanner.h b/app/scanner.h index 65fee6e..4f9014b 100644 --- a/app/scanner.h +++ b/app/scanner.h @@ -40,7 +40,7 @@ typedef enum scan_state_dir_e scan_state_dir_t; enum scan_edit_state_e { SCAN_EDIT_STATE_NONE = 0, - SCAN_EDIT_STATE_BUSY, + SCAN_EDIT_STATE_SAVE, SCAN_EDIT_STATE_DONE }; typedef enum scan_edit_state_e scan_edit_state_t; diff --git a/app/uart.c b/app/uart.c index e46e0a6..127e24d 100644 --- a/app/uart.c +++ b/app/uart.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#define INCLUDE_AES + #include #if !defined(ENABLE_OVERLAY) @@ -43,65 +45,70 @@ #define DMA_INDEX(x, y) (((x) + (y)) % sizeof(UART_DMA_Buffer)) +#define EEPROM_SIZE 0x2000u // 8192 .. BL24C64 I2C eeprom chip + +// **************************************************** + typedef struct { uint16_t ID; uint16_t Size; -} Header_t; +} __attribute__((packed)) Header_t; typedef struct { - uint8_t Padding[2]; + uint8_t pad[2]; uint16_t ID; -} Footer_t; +} __attribute__((packed)) Footer_t; typedef struct { Header_t Header; - uint32_t Timestamp; -} CMD_0514_t; + uint32_t time_stamp; +} __attribute__((packed)) cmd_0514_t; +// version typedef struct { Header_t Header; struct { char Version[16]; - bool g_has_custom_aes_key; - bool g_is_in_lock_screen; - uint8_t Padding[2]; + uint8_t has_custom_aes_key; + uint8_t password_locked; + uint8_t pad[2]; uint32_t Challenge[4]; - } Data; -} REPLY_0514_t; + } __attribute__((packed)) Data; +} __attribute__((packed)) reply_0514_t; typedef struct { Header_t Header; uint16_t Offset; uint8_t Size; - uint8_t Padding; - uint32_t Timestamp; -} CMD_051B_t; + uint8_t pad; + uint32_t time_stamp; +} __attribute__((packed)) cmd_051B_t; typedef struct { Header_t Header; struct { uint16_t Offset; uint8_t Size; - uint8_t Padding; + uint8_t pad; uint8_t Data[128]; - } Data; -} REPLY_051B_t; + } __attribute__((packed)) Data; +} __attribute__((packed)) reply_051B_t; typedef struct { Header_t Header; uint16_t Offset; uint8_t Size; - bool bAllowPassword; - uint32_t Timestamp; - uint8_t Data[0]; -} CMD_051D_t; + uint8_t allow_password; + uint32_t time_stamp; +// uint8_t Data[0]; // new compiler strict warning settings doesn't allow zero-length arrays +} __attribute__((packed)) cmd_051D_t; typedef struct { Header_t Header; struct { uint16_t Offset; - } Data; -} REPLY_051D_t; + } __attribute__((packed)) Data; +} __attribute__((packed)) reply_051D_t; typedef struct { Header_t Header; @@ -109,39 +116,34 @@ typedef struct { uint16_t RSSI; uint8_t ExNoiseIndicator; uint8_t GlitchIndicator; - } Data; -} REPLY_0527_t; + } __attribute__((packed)) Data; +} __attribute__((packed)) reply_0527_t; typedef struct { Header_t Header; struct { uint16_t Voltage; uint16_t Current; - } Data; -} REPLY_0529_t; + } __attribute__((packed)) Data; +} __attribute__((packed)) reply_0529_t; typedef struct { Header_t Header; uint32_t Response[4]; -} CMD_052D_t; +} __attribute__((packed)) cmd_052D_t; typedef struct { Header_t Header; struct { - bool bIsLocked; - uint8_t Padding[3]; - } Data; -} REPLY_052D_t; + uint8_t locked; + uint8_t pad[3]; + } __attribute__((packed)) Data; +} __attribute__((packed)) reply_052D_t; typedef struct { Header_t Header; - uint32_t Timestamp; -} 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 -}; + uint32_t time_stamp; +} __attribute__((packed)) cmd_052F_t; static union { @@ -149,73 +151,81 @@ static union struct { Header_t Header; - uint8_t Data[252]; - }; -} UART_Command; + uint8_t Data[252]; + } __attribute__((packed)); +} __attribute__((packed)) UART_Command; -static uint32_t Timestamp; -static uint16_t g_uart_write_index; -static bool bIsEncrypted = true; +static const uint8_t Obfuscation[16] = { + 0x16, 0x6C, 0x14, 0xE6, 0x2E, 0x91, 0x0D, 0x40, 0x21, 0x35, 0xD5, 0x40, 0x13, 0x03, 0xE9, 0x80 +}; -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; Footer_t Footer; - if (bIsEncrypted) + if (is_encrypted) { - uint8_t *pBytes = (uint8_t *)pReply; + uint8_t *pBytes = (uint8_t *)preply; unsigned int i; for (i = 0; i < Size; i++) pBytes[i] ^= Obfuscation[i % 16]; } - Header.ID = 0xCDAB; + Header.ID = 0xCDAB; Header.Size = Size; 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.Padding[1] = Obfuscation[(Size + 1) % 16] ^ 0xFF; + Footer.pad[0] = Obfuscation[(Size + 0) % 16] ^ 0xFF; + Footer.pad[1] = Obfuscation[(Size + 1) % 16] ^ 0xFF; } else { - Footer.Padding[0] = 0xFF; - Footer.Padding[1] = 0xFF; + Footer.pad[0] = 0xFF; + Footer.pad[1] = 0xFF; } Footer.ID = 0xBADC; - UART_Send(&Footer, sizeof(Footer)); } static void SendVersion(void) { - REPLY_0514_t Reply; + reply_0514_t reply; - Reply.Header.ID = 0x0515; - Reply.Header.Size = sizeof(Reply.Data); - strcpy(Reply.Data.Version, Version); - Reply.Data.g_has_custom_aes_key = g_has_custom_aes_key; - Reply.Data.g_is_in_lock_screen = g_is_in_lock_screen; - Reply.Data.Challenge[0] = g_challenge[0]; - Reply.Data.Challenge[1] = g_challenge[1]; - Reply.Data.Challenge[2] = g_challenge[2]; - Reply.Data.Challenge[3] = g_challenge[3]; + memset(&reply, 0, sizeof(reply)); + reply.Header.ID = 0x0515; + reply.Header.Size = sizeof(reply.Data); + strcpy(reply.Data.Version, Version); + reply.Data.has_custom_aes_key = g_has_custom_aes_key; + reply.Data.password_locked = g_password_locked; + reply.Data.Challenge[0] = g_challenge[0]; + reply.Data.Challenge[1] = g_challenge[1]; + 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) { unsigned int i; - uint32_t IV[4]; - - IV[0] = 0; - IV[1] = 0; - IV[2] = 0; - IV[3] = 0; + uint32_t IV[4] = {0, 0, 0, 0}; 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; } -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; - - #ifdef ENABLE_FMRADIO - g_fm_radio_count_down_500ms = fm_radio_countdown_500ms; - #endif + time_stamp = pCmd->time_stamp; 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 g_request_display_screen = DISPLAY_MAIN; - g_update_display = true; + g_update_display = true; 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; - REPLY_051B_t Reply; - bool bLocked = false; + const cmd_051B_t *pCmd = (const cmd_051B_t *)pBuffer; + unsigned int addr = pCmd->Offset; + unsigned int size = pCmd->Size; +// bool locked = false; + reply_051B_t reply; - if (pCmd->Timestamp != Timestamp) - return; +// if (pCmd->time_stamp != time_stamp) +// return; g_serial_config_count_down_500ms = serial_config_count_down_500ms; - #ifdef ENABLE_FMRADIO - g_fm_radio_count_down_500ms = fm_radio_countdown_500ms; - #endif + if (addr >= EEPROM_SIZE) + return; - memset(&Reply, 0, sizeof(Reply)); - Reply.Header.ID = 0x051C; - Reply.Header.Size = pCmd->Size + 4; - Reply.Data.Offset = pCmd->Offset; - Reply.Data.Size = pCmd->Size; + if (size > sizeof(reply.Data.Data)) + size = sizeof(reply.Data.Data); + if (size > (EEPROM_SIZE - addr)) + size = EEPROM_SIZE - addr; - if (g_has_custom_aes_key) - bLocked = g_is_locked; + if (size == 0) + return; - if (!bLocked) - EEPROM_ReadBuffer(pCmd->Offset, Reply.Data.Data, pCmd->Size); + memset(&reply, 0, sizeof(reply)); + 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; - REPLY_051D_t Reply; - bool bReloadEeprom; - bool bIsLocked; + const unsigned int write_size = 8; + const cmd_051D_t *pCmd = (const cmd_051D_t *)pBuffer; + unsigned int addr = pCmd->Offset; + 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) - return; +// if (pCmd->time_stamp != time_stamp) +// return; g_serial_config_count_down_500ms = serial_config_count_down_500ms; - - bReloadEeprom = false; - #ifdef ENABLE_FMRADIO - g_fm_radio_count_down_500ms = fm_radio_countdown_500ms; - #endif + if (addr >= EEPROM_SIZE) + return; - Reply.Header.ID = 0x051E; - Reply.Header.Size = sizeof(Reply.Data); - Reply.Data.Offset = pCmd->Offset; + if (size > sizeof(reply.Data)) + size = sizeof(reply.Data); + 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; - 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 (!g_is_locked) - bReloadEeprom = true; + if ((Offset + write_size) > EEPROM_SIZE) + break; - if ((Offset < 0x0E98 || Offset >= 0x0EA0) || !g_is_in_lock_screen || pCmd->bAllowPassword) - EEPROM_WriteBuffer(Offset, &pCmd->Data[i * 8U]); + #ifdef INCLUDE_AES + 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) - BOARD_EEPROM_Init(); + #ifdef INCLUDE_AES + 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; - Reply.Header.Size = sizeof(Reply.Data); - Reply.Data.RSSI = BK4819_ReadRegister(BK4819_REG_67) & 0x01FF; - Reply.Data.ExNoiseIndicator = BK4819_ReadRegister(BK4819_REG_65) & 0x007F; - Reply.Data.GlitchIndicator = BK4819_ReadRegister(BK4819_REG_63); + memset(&reply, 0, sizeof(reply)); + reply.Header.ID = 0x0528; + reply.Header.Size = sizeof(reply.Data); + reply.Data.RSSI = BK4819_ReadRegister(BK4819_REG_67) & 0x01FF; + 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; - - Reply.Header.ID = 0x52A; - Reply.Header.Size = sizeof(Reply.Data); - + uint16_t voltage; + uint16_t current; + reply_0529_t reply; + memset(&reply, 0, sizeof(reply)); + reply.Header.ID = 0x52A; + reply.Header.Size = sizeof(reply.Data); // Original doesn't actually send current! - BOARD_ADC_GetBatteryInfo(&Reply.Data.Voltage, &Reply.Data.Current); - - SendReply(&Reply, sizeof(Reply)); + BOARD_ADC_GetBatteryInfo(&voltage, ¤t); + reply.Data.Voltage = voltage; + 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; - REPLY_052D_t Reply; - bool bIsLocked; + cmd_052D_t *pCmd = (cmd_052D_t *)pBuffer; + bool locked = g_has_custom_aes_key; + uint32_t response[4]; + reply_052D_t reply; - #ifdef ENABLE_FMRADIO - g_fm_radio_count_down_500ms = fm_radio_countdown_500ms; - #endif - Reply.Header.ID = 0x052E; - Reply.Header.Size = sizeof(Reply.Data); + g_serial_config_count_down_500ms = serial_config_count_down_500ms; - bIsLocked = g_has_custom_aes_key; - - if (!bIsLocked) - bIsLocked = IsBadChallenge(g_custom_aes_key, g_challenge, pCmd->Response); - - if (!bIsLocked) + if (!locked) { - bIsLocked = IsBadChallenge(g_default_aes_key, g_challenge, pCmd->Response); - if (bIsLocked) - g_try_count++; + memmove((void *)&response, &pCmd->Response, sizeof(response)); // overcome strict compiler warning settings + locked = IsBadChallenge(g_custom_aes_key, g_challenge, response); } - if (g_try_count < 3) + if (!locked) { - if (!bIsLocked) - g_try_count = 0; + memmove((void *)&response, &pCmd->Response, sizeof(response)); // overcome strict compiler warning settings + locked = IsBadChallenge(g_default_aes_key, g_challenge, response); + if (locked) + try_count++; + } + + if (try_count < 3) + { + if (!locked) + try_count = 0; } else { - g_try_count = 3; - bIsLocked = true; + try_count = 3; + 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.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_decoding_enable = false; + g_serial_config_count_down_500ms = serial_config_count_down_500ms; + #ifdef ENABLE_NOAA g_is_noaa_mode = false; #endif @@ -413,12 +467,7 @@ static void CMD_052F(const uint8_t *pBuffer) if (g_current_function == FUNCTION_POWER_SAVE) FUNCTION_Select(FUNCTION_FOREGROUND); - g_serial_config_count_down_500ms = serial_config_count_down_500ms; - - Timestamp = pCmd->Timestamp; - - // turn the LCD backlight off -// GPIO_ClearBit(&GPIOB->DATA, GPIOB_PIN_BACKLIGHT); + time_stamp = pCmd->time_stamp; // show message g_request_display_screen = DISPLAY_MAIN; @@ -438,35 +487,35 @@ bool UART_IsCommandAvailable(void) while (1) { - if (g_uart_write_index == DmaLength) + if (write_index == DmaLength) return false; - while (g_uart_write_index != DmaLength && UART_DMA_Buffer[g_uart_write_index] != 0xABU) - g_uart_write_index = DMA_INDEX(g_uart_write_index, 1); + while (write_index != DmaLength && UART_DMA_Buffer[write_index] != 0xABU) + write_index = DMA_INDEX(write_index, 1); - if (g_uart_write_index == DmaLength) + if (write_index == DmaLength) return false; - if (g_uart_write_index < DmaLength) - CommandLength = DmaLength - g_uart_write_index; + if (write_index < DmaLength) + CommandLength = DmaLength - write_index; else - CommandLength = (DmaLength + sizeof(UART_DMA_Buffer)) - g_uart_write_index; + CommandLength = (DmaLength + sizeof(UART_DMA_Buffer)) - write_index; if (CommandLength < 8) 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; - 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]; if ((Size + 8u) > sizeof(UART_DMA_Buffer)) { - g_uart_write_index = DmaLength; + write_index = DmaLength; return false; } @@ -478,7 +527,7 @@ bool UART_IsCommandAvailable(void) if (UART_DMA_Buffer[TailIndex] != 0xDC || UART_DMA_Buffer[DMA_INDEX(TailIndex, 1)] != 0xBA) { - g_uart_write_index = DmaLength; + write_index = DmaLength; return false; } @@ -492,29 +541,29 @@ bool UART_IsCommandAvailable(void) memmove(UART_Command.Buffer, UART_DMA_Buffer + Index, TailIndex - Index); 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); } 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) - bIsEncrypted = false; + is_encrypted = false; if (UART_Command.Header.ID == 0x6902) - bIsEncrypted = true; + is_encrypted = true; - if (bIsEncrypted) + if (is_encrypted) { unsigned int i; for (i = 0; i < (Size + 2u); i++) UART_Command.Buffer[i] ^= Obfuscation[i % 16]; } - + CRC = UART_Command.Buffer[Size] | (UART_Command.Buffer[Size + 1] << 8); return (CRC_Calculate(UART_Command.Buffer, Size) != CRC) ? false : true; @@ -524,41 +573,43 @@ void UART_HandleCommand(void) { switch (UART_Command.Header.ID) { - case 0x0514: - CMD_0514(UART_Command.Buffer); + case 0x0514: // version + cmd_0514(UART_Command.Buffer); break; - - case 0x051B: - CMD_051B(UART_Command.Buffer); + + case 0x051B: // read eeprom + cmd_051B(UART_Command.Buffer); break; - - case 0x051D: - CMD_051D(UART_Command.Buffer); + + case 0x051D: // write eeprom + cmd_051D(UART_Command.Buffer); break; - + case 0x051F: // Not implementing non-authentic command break; - + case 0x0521: // Not implementing non-authentic command break; - - case 0x0527: - CMD_0527(); + + case 0x0527: // read RSSI + cmd_0527(); break; - - case 0x0529: - CMD_0529(); + + case 0x0529: // read ADC + cmd_0529(); break; - - case 0x052D: - CMD_052D(UART_Command.Buffer); + +#ifdef INCLUDE_AES + case 0x052D: // + cmd_052D(UART_Command.Buffer); break; - - case 0x052F: - CMD_052F(UART_Command.Buffer); +#endif + + case 0x052F: // + cmd_052F(UART_Command.Buffer); break; - - case 0x05DD: + + case 0x05DD: // reboot #if defined(ENABLE_OVERLAY) overlay_FLASH_RebootToBootloader(); #else diff --git a/audio.c b/audio.c index 4a64d64..7c6083b 100644 --- a/audio.c +++ b/audio.c @@ -44,7 +44,7 @@ 0x5A, 0x4B, 0x4B, 0x46, 0x46, 0x69, 0x64, 0x6E, 0x5A, 0x64, }; - + static const uint8_t VoiceClipLengthEnglish[76] = { 0x50, 0x32, 0x2D, 0x2D, 0x2D, 0x37, 0x37, 0x37, @@ -58,14 +58,14 @@ 0x55, 0x4B, 0x4B, 0x32, 0x32, 0x32, 0x32, 0x37, 0x41, 0x32, 0x3C, 0x37, }; - + voice_id_t g_voice_id[8]; uint8_t g_voice_read_index; uint8_t g_voice_write_index; volatile uint16_t g_count_down_to_play_next_voice_10ms; volatile bool g_flag_play_queued_voice; voice_id_t g_another_voice_id = VOICE_ID_INVALID; - + #endif 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) return; #endif - + if (g_current_function == FUNCTION_RECEIVE) return; @@ -103,10 +103,12 @@ void AUDIO_PlayBeep(beep_type_t Beep) BK4819_RX_TurnOn(); #ifdef ENABLE_FMRADIO - if (g_fm_radio_mode) - BK1080_Mute(true); + #ifdef MUTE_AUDIO_FOR_VOICE + if (g_fm_radio_mode) + BK1080_Mute(true); + #endif #endif - + SYSTEM_DelayMs(20); switch (Beep) @@ -133,7 +135,7 @@ void AUDIO_PlayBeep(beep_type_t Beep) ToneFrequency = 880; break; } - + BK4819_PlayTone(ToneFrequency, true); SYSTEM_DelayMs(2); @@ -152,7 +154,7 @@ void AUDIO_PlayBeep(beep_type_t Beep) SYSTEM_DelayMs(60); BK4819_EnterTxMute(); SYSTEM_DelayMs(20); - + case BEEP_500HZ_60MS_DOUBLE_BEEP_OPTIONAL: case BEEP_500HZ_60MS_DOUBLE_BEEP: BK4819_ExitTxMute(); @@ -170,7 +172,7 @@ void AUDIO_PlayBeep(beep_type_t Beep) BK4819_ExitTxMute(); Duration = 40; break; - + case BEEP_880HZ_200MS: BK4819_ExitTxMute(); Duration = 200; @@ -208,7 +210,7 @@ void AUDIO_PlayBeep(beep_type_t Beep) if (g_fm_radio_mode) BK1080_Mute(false); #endif - + if (g_current_function == FUNCTION_POWER_SAVE && g_rx_idle_mode) BK4819_Sleep(); } @@ -218,18 +220,20 @@ void AUDIO_PlayBeep(beep_type_t Beep) void AUDIO_PlayVoice(uint8_t VoiceID) { unsigned int i; - + + if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF) + return; + GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); SYSTEM_DelayMs(20); GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); - + for (i = 0; i < 8; i++) { if ((VoiceID & 0x80U) == 0) GPIO_ClearBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); else GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_1); - SYSTICK_DelayUs(1000); GPIO_SetBit(&GPIOA->DATA, GPIOA_PIN_VOICE_0); SYSTICK_DelayUs(1200); @@ -238,122 +242,123 @@ void AUDIO_PlayBeep(beep_type_t Beep) SYSTICK_DelayUs(200); } } - + void AUDIO_PlaySingleVoice(bool flag) { - uint8_t VoiceID; uint8_t Delay; - - 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_CHINESE) - { // Chinese - if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese)) - goto Bailout; - - Delay = VoiceClipLengthChinese[VoiceID]; - VoiceID += VOICE_ID_CHI_BASE; - } - else - { // English - if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish)) - goto Bailout; - - Delay = VoiceClipLengthEnglish[VoiceID]; - VoiceID += VOICE_ID_ENG_BASE; - } - - if (g_current_function == FUNCTION_RECEIVE || - g_current_function == FUNCTION_MONITOR || - g_current_function == FUNCTION_INCOMING) // 1of11 + uint8_t VoiceID = g_voice_id[0]; + + if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF || g_voice_write_index == 0) + goto Bailout; + + if (g_eeprom.voice_prompt == VOICE_PROMPT_CHINESE) + { // Chinese + if (VoiceID >= ARRAY_SIZE(VoiceClipLengthChinese)) + goto Bailout; + + Delay = VoiceClipLengthChinese[VoiceID]; + VoiceID += VOICE_ID_CHI_BASE; + } + else + { // English + if (VoiceID >= ARRAY_SIZE(VoiceClipLengthEnglish)) + goto Bailout; + + Delay = VoiceClipLengthEnglish[VoiceID]; + VoiceID += VOICE_ID_ENG_BASE; + } + + #ifdef MUTE_AUDIO_FOR_VOICE + if (g_current_function == FUNCTION_RECEIVE || g_current_function == FUNCTION_MONITOR) BK4819_SetAF(BK4819_AF_MUTE); - - #ifdef ENABLE_FMRADIO + #endif + + #ifdef ENABLE_FMRADIO + #ifdef MUTE_AUDIO_FOR_VOICE if (g_fm_radio_mode) BK1080_Mute(true); #endif - - GPIO_SetBit(&GPIOC->DATA, GPIOC_PIN_AUDIO_PATH); + #endif + + 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 - g_vox_resume_count_down = 2000; + g_vox_resume_count_down = 80; #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; } - + + g_voice_read_index = 1; + g_count_down_to_play_next_voice_10ms = Delay; + g_flag_play_queued_voice = false; + + return; + Bailout: g_voice_read_index = 0; g_voice_write_index = 0; } - + void AUDIO_SetVoiceID(uint8_t Index, voice_id_t VoiceID) { - if (Index >= ARRAY_SIZE(g_voice_id)) - return; - - if (Index == 0) + if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF || Index == 0) { g_voice_write_index = 0; g_voice_read_index = 0; } - - g_voice_id[Index] = VoiceID; - - g_voice_write_index++; + + if (g_eeprom.voice_prompt != VOICE_PROMPT_OFF && Index < ARRAY_SIZE(g_voice_id)) + { + g_voice_id[Index] = VoiceID; + g_voice_write_index++; + } } - + uint8_t AUDIO_SetDigitVoice(uint8_t Index, uint16_t Value) { uint16_t Remainder; uint8_t Result; uint8_t Count; - - if (Index == 0) + + if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF || Index == 0) { g_voice_write_index = 0; g_voice_read_index = 0; } - + + if (g_eeprom.voice_prompt == VOICE_PROMPT_OFF) + return 0; + Count = 0; Result = 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; Count++; Remainder -= Result * 10U; - + Skip: g_voice_id[g_voice_write_index++] = (voice_id_t)Remainder; - + return Count + 1U; } - + void AUDIO_PlayQueuedVoice(void) { uint8_t VoiceID; uint8_t Delay; - bool Skip; - - Skip = false; - + bool 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) { VoiceID = g_voice_id[g_voice_read_index]; @@ -411,44 +421,47 @@ void AUDIO_PlayBeep(beep_type_t Beep) else Skip = true; } - + g_voice_read_index++; - + if (!Skip) { if (g_voice_read_index == g_voice_write_index) Delay += 3; - + AUDIO_PlayVoice(VoiceID); - + g_count_down_to_play_next_voice_10ms = Delay; g_flag_play_queued_voice = false; #ifdef ENABLE_VOX g_vox_resume_count_down = 2000; #endif - + return; } } - - if (g_current_function == FUNCTION_RECEIVE || - g_current_function == FUNCTION_MONITOR || - g_current_function == FUNCTION_INCOMING) // 1of11 + + // *********************** + // unmute the radios audio + + 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); - + + // ********************** + #ifdef ENABLE_VOX g_vox_resume_count_down = 80; #endif - + g_voice_write_index = 0; g_voice_read_index = 0; } diff --git a/board.c b/board.c index 4007a27..fd16771 100644 --- a/board.c +++ b/board.c @@ -516,7 +516,7 @@ void BOARD_Init(void) CRC_Init(); } -void BOARD_EEPROM_Init(void) +void BOARD_EEPROM_load(void) { unsigned int i; uint8_t Data[16]; @@ -700,21 +700,21 @@ void BOARD_EEPROM_Init(void) // 0F40..0F47 EEPROM_ReadBuffer(0x0F40, Data, 8); - g_setting_f_lock = (Data[0] < 6) ? Data[0] : F_LOCK_OFF; - g_setting_350_tx_enable = (Data[1] < 2) ? Data[1] : false; // was true - g_setting_killed = (Data[2] < 2) ? Data[2] : 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_350_enable = (Data[5] < 2) ? Data[5] : true; + 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_killed = (Data[2] < 2) ? Data[2] : 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_350_enable = (Data[5] < 2) ? Data[5] : true; g_setting_scramble_enable = (Data[6] < 2) ? Data[6] : true; - g_setting_tx_enable = (Data[7] & (1u << 0)) ? 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_tx_enable = (Data[7] & (1u << 0)) ? 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; #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 #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 g_setting_backlight_on_tx_rx = (Data[7] >> 6) & 3u; @@ -727,7 +727,7 @@ void BOARD_EEPROM_Init(void) // 0D60..0E27 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)); g_has_custom_aes_key = false; 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) { 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) diff --git a/board.h b/board.h index 74e60d2..e07cae2 100644 --- a/board.h +++ b/board.h @@ -25,7 +25,7 @@ void BOARD_PORTCON_Init(void); void BOARD_ADC_Init(void); void BOARD_ADC_GetBatteryInfo(uint16_t *pVoltage, uint16_t *pCurrent); void BOARD_Init(void); -void BOARD_EEPROM_Init(void); +void BOARD_EEPROM_load(void); void BOARD_EEPROM_LoadMoreSettings(void); uint32_t BOARD_fetchChannelFrequency(const int channel); void BOARD_fetchChannelName(char *s, const int channel); diff --git a/firmware.bin b/firmware.bin index 20565b3..9cc687a 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index ef39381..806f0f5 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/frequencies.c b/frequencies.c index 7b9667d..53e2072 100644 --- a/frequencies.c +++ b/frequencies.c @@ -134,7 +134,7 @@ int TX_freq_check(const uint32_t Frequency) if (Frequency >= BX4819_band1.upper && Frequency < BX4819_band2.lower) return -1; // BX chip does not work in this range - switch (g_setting_f_lock) + switch (g_setting_freq_lock) { case F_LOCK_OFF: if (Frequency >= 13600000 && Frequency < 17400000) diff --git a/helper/boot.c b/helper/boot.c index 40055b9..b048988 100644 --- a/helper/boot.c +++ b/helper/boot.c @@ -31,7 +31,7 @@ #include "ui/menu.h" #include "ui/ui.h" -BOOT_Mode_t BOOT_GetMode(void) +boot_mode_t BOOT_GetMode(void) { unsigned int i; key_code_t Keys[2]; @@ -47,7 +47,7 @@ BOOT_Mode_t BOOT_GetMode(void) if (Keys[0] == Keys[1]) { if (Keys[0] == KEY_SIDE1) - return BOOT_MODE_F_LOCK; + return BOOT_MODE_UNHIDE_HIDDEN; #ifdef ENABLE_AIRCOPY if (Keys[0] == KEY_SIDE2) @@ -58,9 +58,9 @@ BOOT_Mode_t BOOT_GetMode(void) 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); } diff --git a/helper/boot.h b/helper/boot.h index fd6c96e..5abb5d9 100644 --- a/helper/boot.h +++ b/helper/boot.h @@ -20,19 +20,18 @@ #include #include "driver/keyboard.h" -enum BOOT_Mode_t +enum boot_mode_e { - BOOT_MODE_NORMAL = 0, - BOOT_MODE_F_LOCK, + BOOT_MODE_NORMAL = 0, // normal boot + BOOT_MODE_UNHIDE_HIDDEN, // unhide the hidden menu items #ifdef ENABLE_AIRCOPY - BOOT_MODE_AIRCOPY + BOOT_MODE_AIRCOPY // do an air-copy #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 diff --git a/main.c b/main.c index 77c31dc..6ce05bc 100644 --- a/main.c +++ b/main.c @@ -51,7 +51,7 @@ void _putchar(char c) void Main(void) { unsigned int i; - BOOT_Mode_t BootMode; + boot_mode_t BootMode; // Enable clock gating of blocks we need SYSCON_DEV_CLK_GATE = 0 @@ -89,7 +89,7 @@ void Main(void) BOARD_ADC_GetBatteryInfo(&g_usb_current_voltage, &g_usb_current); - BOARD_EEPROM_Init(); + BOARD_EEPROM_load(); BOARD_EEPROM_LoadMoreSettings(); @@ -105,33 +105,33 @@ void Main(void) BATTERY_GetReadings(false); + ST7565_SetContrast(g_setting_contrast); + #ifdef ENABLE_AM_FIX AM_fix_init(); #endif 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 (g_f_lock) - UART_SendText("boot_f_lock\r\n"); + if (g_unhide_hidden) + UART_SendText("boot_unhide_hidden\r\n"); #endif // sort the menu list - UI_SortMenu(!g_f_lock); - - ST7565_SetContrast(g_setting_contrast); + UI_SortMenu(!g_unhide_hidden); // wait for user to release all butts before moving on if (!GPIO_CheckBit(&GPIOC->DATA, GPIOC_PIN_PTT) || KEYBOARD_Poll() != KEY_INVALID || BootMode != BOOT_MODE_NORMAL) - { // keys are pressed - UI_DisplayReleaseKeys(); + { backlight_turn_on(); + UI_DisplayReleaseKeys(); 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; SYSTEM_DelayMs(10); @@ -156,8 +156,8 @@ void Main(void) backlight_turn_on(); #ifdef ENABLE_VOICE - AUDIO_SetVoiceID(0, VOICE_ID_WELCOME); - AUDIO_PlaySingleVoice(0); +// AUDIO_SetVoiceID(0, VOICE_ID_WELCOME); +// AUDIO_PlaySingleVoice(0); #endif if (g_eeprom.pwr_on_display_mode != PWR_ON_DISPLAY_MODE_NONE) @@ -179,9 +179,9 @@ void Main(void) #ifdef ENABLE_PWRON_PASSWORD if (g_eeprom.power_on_password < 1000000) { - g_is_in_lock_screen = true; + g_password_locked = true; UI_DisplayLock(); - g_is_in_lock_screen = false; + g_password_locked = false; } #endif @@ -192,12 +192,13 @@ void Main(void) g_update_status = true; #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)) { AUDIO_SetVoiceID(1, VOICE_ID_CHANNEL_MODE); @@ -212,8 +213,6 @@ void Main(void) #ifdef ENABLE_NOAA RADIO_ConfigureNOAA(); #endif - - // ****************** } while (1) diff --git a/misc.c b/misc.c index f270e05..c21e709 100644 --- a/misc.c +++ b/misc.c @@ -90,7 +90,7 @@ bool g_setting_200_tx_enable; bool g_setting_500_tx_enable; bool g_setting_350_enable; bool g_setting_tx_enable; -uint8_t g_setting_f_lock; +uint8_t g_setting_freq_lock; bool g_setting_scramble_enable; 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]; bool g_has_custom_aes_key; uint32_t g_challenge[4]; -uint8_t g_try_count; uint8_t g_eeprom_1EC0_0[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_lock_count_down_500ms; uint8_t g_rtte_count_down; -bool g_is_in_lock_screen; +bool g_password_locked; uint8_t g_update_status; uint8_t g_found_CTCSS; uint8_t g_found_CDCSS; @@ -240,7 +239,7 @@ uint8_t g_fsk_wite_index; bool g_update_display; -bool g_f_lock = false; +bool g_unhide_hidden = false; 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 -uint8_t g_is_locked = 0xFF; - unsigned int get_RX_VFO(void) { unsigned int rx_vfo = g_eeprom.tx_vfo; diff --git a/misc.h b/misc.h index 9c07516..7210056 100644 --- a/misc.h +++ b/misc.h @@ -166,7 +166,7 @@ extern bool g_setting_200_tx_enable; extern bool g_setting_500_tx_enable; extern bool g_setting_350_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 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 bool g_has_custom_aes_key; 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_1[8]; @@ -240,7 +239,7 @@ extern bool g_enable_speaker; extern uint8_t g_key_input_count_down; extern uint8_t g_key_lock_count_down_500ms; 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_found_CTCSS; extern uint8_t g_found_CDCSS; @@ -313,7 +312,7 @@ extern uint8_t g_fsk_wite_index; #endif extern volatile bool g_next_time_slice; extern bool g_update_display; -extern bool g_f_lock; +extern bool g_unhide_hidden; #ifdef ENABLE_FMRADIO extern uint8_t g_fm_channel_position; #endif @@ -333,7 +332,6 @@ extern volatile bool g_flag_tail_tone_elimination_complete; extern volatile bool g_schedule_fm; #endif 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; unsigned int get_TX_VFO(void); diff --git a/settings.c b/settings.c index 5682679..0ba3c5e 100644 --- a/settings.c +++ b/settings.c @@ -283,7 +283,7 @@ void SETTINGS_SaveSettings(void) EEPROM_WriteBuffer(0x0F18, 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[2] = g_setting_killed; State[3] = g_setting_200_tx_enable; diff --git a/ui/menu.c b/ui/menu.c index 2b8c56f..7011ddf 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -50,14 +50,14 @@ const t_menu_item g_menu_list[] = {"W/N", VOICE_ID_CHANNEL_BANDWIDTH, MENU_W_N }, {"Tx PWR", VOICE_ID_POWER, MENU_TXP }, // was "TXP" {"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" - {"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" - {"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 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" {"BCL", VOICE_ID_BUSY_LOCKOUT, MENU_BCL }, {"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" }; -const char g_sub_menu_roger_mode[3][9] = +const char g_sub_menu_roger_mode[3][16] = { "OFF", - "ROGER", - "MDC\n1200" + "TX END\nROGER", + "TX END\nMDC\n1200" }; const char g_sub_menu_RESET[2][4] = @@ -549,28 +549,31 @@ void UI_DisplayMenu(void) case MENU_R_DCS: case MENU_T_DCS: + strcpy(String, "CDCSS\n"); if (g_sub_menu_selection == 0) - strcpy(String, "OFF"); + strcat(String, "OFF"); else 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 - 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; case MENU_R_CTCS: case MENU_T_CTCS: { + strcpy(String, "CTCSS\n"); #if 1 // set CTCSS as the user adjusts it 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; if (g_sub_menu_selection == 0) { - strcpy(String, "OFF"); + strcat(String, "OFF"); if (pConfig->code_type != CODE_TYPE_CONTINUOUS_TONE) break; + Code = 0; pConfig->code_type = CODE_TYPE_OFF; pConfig->code = Code; @@ -579,7 +582,7 @@ void UI_DisplayMenu(void) } 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; Code = g_sub_menu_selection - 1; @@ -589,9 +592,9 @@ void UI_DisplayMenu(void) } #else if (g_sub_menu_selection == 0) - strcpy(String, "OFF"); + strcat(String, "OFF"); 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 break; @@ -921,7 +924,7 @@ void UI_DisplayMenu(void) break; 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]); break; @@ -950,8 +953,7 @@ void UI_DisplayMenu(void) break; case MENU_ROGER: - strcpy(String, "TX END\n"); - strcpy(String + strlen(String), g_sub_menu_roger_mode[g_sub_menu_selection]); + strcpy(String, g_sub_menu_roger_mode[g_sub_menu_selection]); break; case MENU_VOL: diff --git a/ui/menu.h b/ui/menu.h index 0ddc282..fe90bf0 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -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_PTT_ID[5][15]; 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_f_lock[6][8]; extern const char g_sub_menu_backlight[8][7]; diff --git a/ui/scanner.c b/ui/scanner.c index 57c12ed..1cef95e 100644 --- a/ui/scanner.c +++ b/ui/scanner.c @@ -18,6 +18,7 @@ #include #include "app/scanner.h" +#include "board.h" #include "dcs.h" #include "driver/st7565.h" #include "external/printf/printf.h" @@ -161,14 +162,20 @@ void UI_DisplayScanner(void) break; - case SCAN_EDIT_STATE_BUSY: + case SCAN_EDIT_STATE_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; case SCAN_EDIT_STATE_DONE: + strcpy(String, "* repeat M save"); text_centered = true; - strcpy(String, "SAVE ?"); break; }