diff --git a/Makefile b/Makefile index c1ac82a..9035bc3 100644 --- a/Makefile +++ b/Makefile @@ -1,27 +1,25 @@ # compile options (see README.md for descriptions) +# # 0 = remove code # 1 = include code -# When testing the extra options, be careful not to exceed the -# 64 kB flash memory limit. - ENABLE_CLANG := 0 ENABLE_SWD := 0 ENABLE_OVERLAY := 0 ENABLE_LTO := 1 # UART Programming 2.9 kB ENABLE_UART := 1 -ENABLE_UART_DEBUG := 1 +ENABLE_UART_DEBUG := 0 # AirCopy 2.5 kB -ENABLE_AIRCOPY := 1 +ENABLE_AIRCOPY := 0 ENABLE_AIRCOPY_REMEMBER_FREQ := 1 ENABLE_AIRCOPY_RX_REBOOT := 0 # FM Radio 4.2 kB ENABLE_FMRADIO_64_76 := 0 ENABLE_FMRADIO_76_90 := 0 ENABLE_FMRADIO_76_108 := 0 -ENABLE_FMRADIO_875_108 := 0 +ENABLE_FMRADIO_875_108 := 1 ENABLE_FMRADIO_64_108 := 0 # NOAA 1.2 kB ENABLE_NOAA := 0 @@ -29,14 +27,14 @@ ENABLE_NOAA := 0 ENABLE_VOICE := 0 ENABLE_MUTE_RADIO_FOR_VOICE := 0 # Tx on Voice 1.0 kB -ENABLE_VOX := 0 +ENABLE_VOX := 1 ENABLE_VOX_MORE_SENSITIVE := 1 ENABLE_REDUCE_LOW_MID_TX_POWER := 1 # Tx Alarm 600 B ENABLE_ALARM := 0 ENABLE_TX1750 := 0 # MDC1200 2.8 kB -ENABLE_MDC1200 := 1 +ENABLE_MDC1200 := 0 ENABLE_MDC1200_SHOW_OP_ARG := 1 ENABLE_MDC1200_SIDE_BEEP := 1 ENABLE_PWRON_PASSWORD := 0 @@ -58,13 +56,14 @@ ENABLE_CTCSS_TAIL_PHASE_SHIFT := 1 ENABLE_CONTRAST := 0 ENABLE_BOOT_BEEPS := 0 ENABLE_DTMF_CALL_FLASH_LIGHT := 1 -ENABLE_FLASH_LIGHT_SOS_TONE := 1 +ENABLE_FLASH_LIGHT_SOS_TONE := 0 ENABLE_SHOW_CHARGE_LEVEL := 0 ENABLE_REVERSE_BAT_SYMBOL := 1 ENABLE_FREQ_SEARCH_LNA := 1 ENABLE_FREQ_SEARCH_TIMEOUT := 0 ENABLE_CODE_SEARCH_TIMEOUT := 0 ENABLE_SCAN_IGNORE_LIST := 1 +ENABLE_SCAN_RANGES := 1 # Kill and Revive 400 B ENABLE_KILL_REVIVE := 0 # AM Fix 800 B @@ -76,7 +75,7 @@ ENABLE_SQ_OPEN_WITH_UP_DN_BUTTS := 1 ENABLE_FASTER_CHANNEL_SCAN := 1 ENABLE_COPY_CHAN_TO_VFO_TO_CHAN := 1 # Rx Signal Bar 400 B -ENABLE_RX_SIGNAL_BAR := 1 +ENABLE_RX_SIGNAL_BAR := 0 # Tx Audio Bar 300 B ENABLE_TX_AUDIO_BAR := 0 # Side Button Menu 300 B @@ -415,6 +414,9 @@ endif ifeq ($(ENABLE_SCAN_IGNORE_LIST),1) CFLAGS += -DENABLE_SCAN_IGNORE_LIST endif +ifeq ($(ENABLE_SCAN_RANGES),1) + CFLAGS += -DENABLE_SCAN_RANGES +endif ifeq ($(ENABLE_KILL_REVIVE),1) CFLAGS += -DENABLE_KILL_REVIVE endif diff --git a/README.md b/README.md index 5b6e8fd..51d7b9b 100644 --- a/README.md +++ b/README.md @@ -5,28 +5,21 @@ This repository is a cloned and customized version of DualTachyon's open firmwar https://github.com/DualTachyon/uv-k5-firmware .. a cool achievement ! Use this firmware/code ENTIRELY at your own risk. This firmware is totally experimental, and at -times will go completely tits up (ie, break your radio) - an entirely common occurance when playing -around with experimental code. +times will go completely tits up (break your radio). There is absolutely no guarantee that it will work in any way shape or form on your radio(s), it may -even brick your radio(s), at which point, maybe find a quiet corner to sob your hert out in. +even brick your radio(s). -NO REFUNDS, ever ! +You're on your own. +NO REFUNDS, ever ! + ## Radio performance Please note that the Quansheng UV-Kx radios are not professional quality transceivers, their performance is strictly limited. The RX front end has no track-tuned band pass filtering at all, and so are wide band/wide open to any and all signals over a large frequency range. -Using the radio in high intensity RF environments will most likely make reception anything but -easy (AM mode will suffer far more than FM ever will), the receiver simply doesn't have a -great dynamic range, which results in distorted AM audio with stronger RX'ed signals. -There is nothing more anyone can do in firmware/software to improve that, once the RX gain -adjustment I do (AM fix) reaches the hardwares limit, your AM RX audio will be all but -non-existant (just like Quansheng's firmware). -On the other hand, FM RX audio will/should be fine. - But, they are nice toys for the price, fun to play with. # User customization @@ -81,7 +74,8 @@ ENABLE_REVERSE_BAT_SYMBOL := 1 mirror the battery symbol on the sta ENABLE_FREQ_SEARCH_LNA := 0 keep this disabled ENABLE_FREQ_SEARCH_TIMEOUT := 0 timeout if FREQ not found when using F+4 search function ENABLE_CODE_SEARCH_TIMEOUT := 0 timeout if CTCSS/CDCSS not found when using F+* search function -ENABLE_SCAN_IGNORE_LIST := 0 ignore selected frequencies when scanning - add freqs to list with short */scan button when scanning, remove freq from list with long press MENU when not scanning +ENABLE_SCAN_IGNORE_LIST := 1 ignore selected frequencies when scanning - add freqs to list with short */scan button when scanning, remove freq from list with long press MENU when not scanning +ENABLE_SCAN_RANGES := 0 auto select frequency scan range depending on your initial frequency ENABLE_KILL_REVIVE := 0 include kill and revive code ENABLE_AM_FIX := 1 dynamically adjust the front end gains when in AM mode to help prevent AM demodulator saturation, ignore the on-screen RSSI level (for now) ENABLE_AM_FIX_SHOW_DATA := 1 show debug data for the AM fix (still tweaking it) diff --git a/app/action.c b/app/action.c index 0498f42..5d31167 100644 --- a/app/action.c +++ b/app/action.c @@ -201,6 +201,9 @@ void ACTION_Scan(bool bRestart) if (g_current_display_screen != DISPLAY_SEARCH) { // not in freq/ctcss/cdcss search mode + if (IS_NOAA_CHANNEL(g_tx_vfo->channel_save)) + return; + g_monitor_enabled = false; GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER); @@ -211,70 +214,82 @@ void ACTION_Scan(bool bRestart) RADIO_select_vfos(); - if (IS_NOT_NOAA_CHANNEL(g_rx_vfo->channel_save)) - { - GUI_SelectNextDisplay(DISPLAY_MAIN); - - if (g_scan_state_dir != SCAN_STATE_DIR_OFF) - { // currently scanning + GUI_SelectNextDisplay(DISPLAY_MAIN); - if (g_scan_next_channel <= USER_CHANNEL_LAST) - { // channel mode - - if (g_eeprom.config.setting.scan_list_default < 2) - { // keep scanning but toggle between scan lists - - //g_eeprom.config.setting.scan_list_default = (g_eeprom.config.setting.scan_list_default + 1) % 3; - g_eeprom.config.setting.scan_list_default++; - - // jump to the next channel - APP_channel_next(true, g_scan_state_dir); - - g_scan_tick_10ms = 0; - g_scan_pause_time_mode = false; - - g_update_status = true; - return; - } - - g_eeprom.config.setting.scan_list_default = 0; // back to scan list 1 - the next time we start scanning + if (g_scan_state_dir != SCAN_STATE_DIR_OFF) + { // currently scanning + + if (g_scan_next_channel <= USER_CHANNEL_LAST) + { // channel mode + + if (g_eeprom.config.setting.scan_list_default < 2) + { // keep scanning but toggle between scan lists + + //g_eeprom.config.setting.scan_list_default = (g_eeprom.config.setting.scan_list_default + 1) % 3; + g_eeprom.config.setting.scan_list_default++; + + // jump to the next channel + APP_channel_next(true, g_scan_state_dir); + + g_scan_tick_10ms = 0; + g_scan_pause_time_mode = false; + + g_update_status = true; + return; } - - // stop scanning - - APP_stop_scan(); - - g_request_display_screen = DISPLAY_MAIN; - return; + + g_eeprom.config.setting.scan_list_default = 0; // back to scan list 1 - the next time we start scanning } + + // ***************** + // stop scanning + + APP_stop_scan(); + + g_request_display_screen = DISPLAY_MAIN; - // start scanning - - #ifdef ENABLE_SCAN_IGNORE_LIST -// FI_clear_freq_ignored(); - #endif + return; + } - g_monitor_enabled = false; - GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER); - - RADIO_setup_registers(true); - - APP_channel_next(true, SCAN_STATE_DIR_FORWARD); - - g_scan_tick_10ms = 0; // go NOW - g_scan_pause_time_mode = false; - - #ifdef ENABLE_VOICE - AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); - AUDIO_PlaySingleVoice(true); - #endif - - // clear the other vfo's rssi level (to hide the antenna symbol) - g_vfo_rssi_bar_level[(g_rx_vfo_num + 1) & 1u] = 0; - - g_update_status = true; + // ********************** + // start scanning + + { + const uint32_t freq = g_tx_vfo->freq_config_rx.frequency; + const frequency_band_t band = FREQUENCY_GetBand(freq); + g_scan_initial_upper = FREQ_BAND_TABLE[band].upper; + g_scan_initial_lower = FREQ_BAND_TABLE[band].lower; + g_scan_initial_step_size = g_tx_vfo->step_freq; } + #ifdef ENABLE_SCAN_RANGES + if (IS_FREQ_CHANNEL(g_tx_vfo->channel_save)) + { + const uint32_t freq = g_tx_vfo->freq_config_rx.frequency; + FREQUENCY_scan_range(freq, &g_scan_initial_lower, &g_scan_initial_upper, &g_scan_initial_step_size); + } + #endif + + g_monitor_enabled = false; + GPIO_ClearBit(&GPIOC->DATA, GPIOC_PIN_SPEAKER); + + RADIO_setup_registers(true); + + APP_channel_next(true, SCAN_STATE_DIR_FORWARD); + + g_scan_tick_10ms = 0; // go NOW + g_scan_pause_time_mode = false; + + #ifdef ENABLE_VOICE + AUDIO_SetVoiceID(0, VOICE_ID_SCANNING_BEGIN); + AUDIO_PlaySingleVoice(true); + #endif + + // clear the other vfo's rssi level (to hide the antenna symbol) + g_vfo_rssi_bar_level[(g_rx_vfo_num + 1) & 1u] = 0; + + g_update_status = true; + return; } diff --git a/app/app.c b/app/app.c index 3989e32..3c73175 100644 --- a/app/app.c +++ b/app/app.c @@ -115,7 +115,7 @@ static void APP_check_for_new_receive(void) if (g_css_scan_mode != CSS_SCAN_MODE_OFF && g_rx_reception_mode == RX_MODE_NONE) { // CTCSS/DTS scanning - g_scan_tick_10ms = scan_pause_code_10ms; + g_scan_tick_10ms = scan_pause_code_10ms; g_scan_pause_time_mode = false; g_rx_reception_mode = RX_MODE_DETECTED; } @@ -647,33 +647,23 @@ void APP_stop_scan(void) static void APP_next_freq(void) { - uint32_t freq = g_tx_vfo->freq_config_rx.frequency; - const uint32_t step = g_tx_vfo->step_freq; - const frequency_band_t band = FREQUENCY_GetBand(freq); - uint32_t upper = FREQ_BAND_TABLE[band].upper; - uint32_t lower = FREQ_BAND_TABLE[band].lower; - - if (band == BAND2_108MHz) - { // air band - if (freq < 11800000) - upper = 11800000; // lower airband half - else - lower = 11800000; // upper airband half - } + uint32_t freq = g_tx_vfo->freq_config_rx.frequency; #ifdef ENABLE_SCAN_IGNORE_LIST do { #endif - freq += step * g_scan_state_dir; + freq += g_scan_initial_step_size * g_scan_state_dir; // wrap-a-round - while (freq >= upper) - freq -= upper - lower; - while (freq < lower) - freq += upper - lower; + while (freq >= g_scan_initial_upper) + freq -= g_scan_initial_upper - g_scan_initial_lower; + while (freq < g_scan_initial_lower) + freq += g_scan_initial_upper - g_scan_initial_lower; - if (band == BAND2_108MHz) // air band uses set channels - freq = lower + ((((freq - lower) + (step / 2)) / step) * step); + // round + #ifdef ENABLE_SCAN_RANGES + freq = g_scan_initial_lower + ((((freq - g_scan_initial_lower) + (g_scan_initial_step_size / 2)) / g_scan_initial_step_size) * g_scan_initial_step_size); + #endif #ifdef ENABLE_SCAN_IGNORE_LIST } while (FI_freq_ignored(freq) >= 0); diff --git a/app/main.c b/app/main.c index bc0b8ab..be94821 100644 --- a/app/main.c +++ b/app/main.c @@ -1007,30 +1007,37 @@ void MAIN_Key_UP_DOWN(bool key_pressed, bool key_held, scan_state_dir_t directio if (IS_FREQ_CHANNEL(Channel)) { // frequency mode - uint32_t freq = g_tx_vfo->freq_config_rx.frequency; - const uint32_t step = g_tx_vfo->step_freq; - const frequency_band_t band = FREQUENCY_GetBand(freq); - uint32_t upper = FREQ_BAND_TABLE[band].upper; - uint32_t lower = FREQ_BAND_TABLE[band].lower; + uint32_t freq = g_tx_vfo->freq_config_rx.frequency; - if (band == BAND2_108MHz) - { // air band - if (freq < 11800000) - upper = 11800000; // lower airband half - else - lower = 11800000; // upper airband half + if (key_pressed && !key_held) + { // just pressed + const frequency_band_t band = FREQUENCY_GetBand(freq); + + g_scan_initial_upper = FREQ_BAND_TABLE[band].upper; + g_scan_initial_lower = FREQ_BAND_TABLE[band].lower; + g_scan_initial_step_size = g_tx_vfo->step_freq; + + #ifdef ENABLE_SCAN_RANGES + //FREQUENCY_scan_range(freq, &g_scan_initial_lower, &g_scan_initial_upper, &g_scan_initial_step_size); + #endif } - freq += step * direction; + freq += g_scan_initial_step_size * direction; // wrap-a-round - while (freq >= upper) - freq -= upper - lower; - while (freq < lower) - freq += upper - lower; + if (key_held) + { // key is held down + while (freq >= g_scan_initial_upper) + freq -= g_scan_initial_upper - g_scan_initial_lower; + while (freq < g_scan_initial_lower) + freq += g_scan_initial_upper - g_scan_initial_lower; + } - if (band == BAND2_108MHz) // air band uses set channels - freq = lower + ((((freq - lower) + (step / 2)) / step) * step); + // round + #ifdef ENABLE_SCAN_RANGES + //if (key_held) + // freq = g_scan_initial_lower + ((((freq - g_scan_initial_lower) + (g_scan_initial_step_size / 2)) / g_scan_initial_step_size) * g_scan_initial_step_size); + #endif if (FREQUENCY_rx_freq_check(freq) < 0) { // frequency not allowed diff --git a/firmware.bin b/firmware.bin index a677562..10687c8 100644 Binary files a/firmware.bin and b/firmware.bin differ diff --git a/firmware.packed.bin b/firmware.packed.bin index 15bfaec..8b85d16 100644 Binary files a/firmware.packed.bin and b/firmware.packed.bin differ diff --git a/frequencies.c b/frequencies.c index 0f1be4e..01a6954 100644 --- a/frequencies.c +++ b/frequencies.c @@ -199,6 +199,55 @@ uint32_t FREQUENCY_wrap_to_step_band(uint32_t freq, const uint32_t step_size, co return freq; } +#ifdef ENABLE_SCAN_RANGES + const freq_scan_range_table_t FREQ_SCAN_RANGE_TABLE[] = + { + { 2696500, 2785600, 1000}, + { 2760125, 2800000, 1000}, + { 2600000, 2800000, 1000}, + { 2800000, 2970000, 1000}, + { 5000000, 5200000, 1000}, + { 5000000, 5400000, 1000}, + { 7000000, 7050000, 1250}, + {10800000, 11800000, 2500}, + {11800000, 13700000, 2500}, + {14400000, 14600000, 1250}, + {14400000, 14800000, 1250}, + {15600000, 15800000, 2500}, + {16200000, 17400000, 1250}, + {21900000, 22500000, 1500}, + {24000000, 39000000, 2500}, + {43000000, 44000000, 1250}, + {44600625, 44619376, 1250}, +// {42000000, 45000000, 1500}, + {44000000, 47000000, 1250} + }; + + void FREQUENCY_scan_range(const uint32_t freq, uint32_t *lower, uint32_t *upper, uint32_t *step_size) + { + const frequency_band_t band = FREQUENCY_GetBand(freq); + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(FREQ_SCAN_RANGE_TABLE); i++) + { + const uint32_t _upper = FREQ_SCAN_RANGE_TABLE[i].upper; + const uint32_t _lower = FREQ_SCAN_RANGE_TABLE[i].lower; + if (freq >= _lower && freq < _upper) + { + if (upper) *upper = _upper; + if (lower) *lower = _lower; + if (step_size) *step_size = FREQ_SCAN_RANGE_TABLE[i].step_size; + return; + } + } + + if (upper) *upper = FREQ_BAND_TABLE[band].upper; + if (lower) *lower = FREQ_BAND_TABLE[band].lower; +// if (step_size) *step_size = FREQ_BAND_TABLE[band].step_size; + } + +#endif + int FREQUENCY_tx_freq_check(const uint32_t Frequency) { // return '0' if TX frequency is allowed // otherwise return '-1' diff --git a/frequencies.h b/frequencies.h index a697851..7e0e566 100644 --- a/frequencies.h +++ b/frequencies.h @@ -39,6 +39,12 @@ typedef struct { const uint32_t upper; } freq_band_table_t; +typedef struct { + const uint32_t lower; + const uint32_t upper; + const uint16_t step_size; +} __attribute__((packed)) freq_scan_range_table_t; + extern uint32_t g_aircopy_freq; extern const freq_band_table_t AIR_BAND; @@ -96,6 +102,10 @@ uint32_t FREQUENCY_wrap_to_step_band(uint32_t freq, const uint32_t step_ int FREQUENCY_tx_freq_check(const uint32_t Frequency); int FREQUENCY_rx_freq_check(const uint32_t Frequency); +#ifdef ENABLE_SCAN_RANGES + void FREQUENCY_scan_range(const uint32_t freq, uint32_t *lower, uint32_t *upper, uint32_t *step_size); +#endif + // *********** #endif diff --git a/functions.c b/functions.c index f08fb4f..099a773 100644 --- a/functions.c +++ b/functions.c @@ -134,13 +134,13 @@ void FUNCTION_Select(function_type_t Function) case FUNCTION_NEW_RECEIVE: #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) - UART_SendText("func new receive\r\n"); + UART_printf("func new receive %u\r\n", g_rx_vfo->freq_config_rx.frequency); #endif break; case FUNCTION_RECEIVE: #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) - UART_SendText("func receive\r\n"); + UART_printf("func receive %u\r\n", g_rx_vfo->freq_config_rx.frequency); #endif break; @@ -172,7 +172,7 @@ void FUNCTION_Select(function_type_t Function) case FUNCTION_TRANSMIT: #if defined(ENABLE_UART) && defined(ENABLE_UART_DEBUG) - UART_SendText("func transmit\r\n"); + UART_printf("func transmit %u\r\n", g_tx_vfo->freq_config_tx.frequency); #endif g_tx_timer_tick_500ms = 0; diff --git a/misc.c b/misc.c index a31a186..3f9ad31 100644 --- a/misc.c +++ b/misc.c @@ -180,6 +180,9 @@ uint16_t g_low_battery_tick_10ms; reception_mode_t g_rx_reception_mode; +uint32_t g_scan_initial_lower; +uint32_t g_scan_initial_upper; +uint32_t g_scan_initial_step_size; uint8_t g_scan_next_channel; scan_next_chan_t g_scan_current_scan_list; uint8_t g_scan_restore_channel; diff --git a/misc.h b/misc.h index 54558dc..9a54466 100644 --- a/misc.h +++ b/misc.h @@ -274,12 +274,15 @@ extern bool g_flag_end_tx; extern uint16_t g_low_battery_tick_10ms; extern reception_mode_t g_rx_reception_mode; +extern uint32_t g_scan_initial_lower; +extern uint32_t g_scan_initial_upper; +extern uint32_t g_scan_initial_step_size; extern uint8_t g_scan_next_channel; // extern scan_next_chan_t g_scan_current_scan_list; // extern uint8_t g_scan_restore_channel; // the channel we were on before starting the RF scan extern uint32_t g_scan_restore_frequency; // the frequency we were on before starting the RF scan extern bool g_scan_pause_time_mode; // set if we stopped in SCAN_RESUME_TIME mode -extern volatile uint16_t g_scan_tick_10ms; // ticks till we move to next channel/frequency +extern volatile uint16_t g_scan_tick_10ms; // ticks till we move to next channel/frequency extern scan_state_dir_t g_scan_state_dir; // the direction we're scanning in extern uint8_t g_rx_vfo_num;