diff --git a/README.md b/README.md index da775d761..b5bd3ef97 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Anyway, have fun. * [Main Features](#main-features) * [Manual](#manual) -* [Manual for ARDF](#manual-for-ardf) +* [Manual for ARDF](#Specific-ARDF-Features) +* {Headphones](#headphones) * [Radio Performance](#radio-performance) * [User Customization](#user-customization) * [Compiler](#compiler) @@ -68,7 +69,7 @@ Anyway, have fun. Up to date manual is available in the [Wiki section](https://github.com/egzumer/uv-k5-firmware-custom/wiki) -## Specific Manual for ARDF Features +## Specific ARDF Features Download a [precompiled release](https://github.com/reald/uv-k5-firmware-custom/releases) or compile with ENABLE_ARDF=1 and preferable with ENABLE_PREVENT_TX=1. To get enough free flash space disable some unneeded TX features (e.g. ENABLE_DTMF_CALLING=0). @@ -96,69 +97,95 @@ Gain steps should be roughly 5dB but they are completely uncalibrated. Expect su - Disable squelch (Menu: Sql = 0) - Disable dual watch (Menu: RxMode = MAIN ONLY). -- Select number of foxes in menu "NumFox" (default = 5, min = 1, max = 10). -- Choose duration time of one fox transmission in menu "FoxDur". Default is 60s. Modify with up/down in 0.1s steps or enter value as *5 digit number* in 1/100s resolution. Confirm with menu button (min = 1s, max = 999.99s). +- Adjust clock correction if necessary (menu "ClkCor", details below). -- Activate VFO 1 (long pressing key "2 A/B" toggles between both VFOs). -- Enter the frequency of the foxes using the number keys. +- Select number of foxes in menu "NumFox" (default = 5, min = 1, max = 10). +- Choose duration time of one fox transmission in menu "FoxDur". Default is 60s. +Modify with UP/DOWN key in 0.1s steps or enter value as *5 digit number* in 1/100s resolution. Confirm with menu button (min = 1s, max = 999.99s). +- Activate VFO A (long pressing key "2 A/B" toggles between both VFOs. +- Enter the frequency of the foxes using the number keys. If memory mode is active long press "3 VFO MR" to change to frequency mode. - Choose the used modulation of the foxes in menu "Demod" (e.g. AM). -- Use a narrow bandwidth mode in menu "BW W/N": "U 1K7" is 1.7 kHz, (this is the smallest possible value; shown as "U-") or "NARROWER" which is 2.5 kHz (shown as "N-" in the status bar). -- Switch to VFO 2 by long pressing "2 A/B". This VFO will mostly be used for the return beacon. -- Configure frequency, modulation and bandwidth the same way as for VFO 1. -- Change back to VFO 1 by long pressing "2 A/B". +- Select a narrow bandwidth mode in menu "BW W/N": "U 1K7" is 1.7 kHz, (this is the smallest possible value; shown as "U-") or "U 2K5" which is 2.5 kHz (shown as "N-" on the ARDF screen). +- Switch to VFO B by long pressing "2 A/B". This VFO will mostly be used for the return beacon. +- Configure frequency, modulation and bandwidth the same way as for VFO A. +- Change back to VFO A by long pressing "2 A/B". + +- Unscrew antenna and add a directional antenna with good front/back ratio. - Listen for foxes, synchronize fox number and timer in menu with "ActFox" and "TiRst" options (details below). +- Start hunting foxes and have fun! #### Main Screen #### -This is the radio screen if ARDF mode is enabled. The manual gain index value can be choosen with UP/DOWN keys from 0 to 21. RSSI_max is -the max RSSI in the last half second. This is an uncalibrated raw value. (The RSSI value next to the S-meter shows roughly dBm.) +This pictures shows the radio screen if ARDF mode is enabled. The manual gain index value can be chosen with UP/DOWN keys from 0 (silent) to 21 (max gain). +RSSI_max is the highest RSSI in the last half second. This is an uncalibrated raw value. (The RSSI value next to the S-meter shows roughly dBm.) The **bold line** below show the settings for the **active VFO**: -VFO number "1", demodulation "USB", smallest bandwidth mode "U-" (1.7kHz) and +VFO "A", demodulation "USB", smallest bandwidth mode "U-" (1.7kHz) and receiving frequency "144.001 MHz". For this VFO the gain remember mode (details below) is active so the gain index history for up to 5 foxes is shown. The active fox number is bold. -The **last line** shows the configuration for the **inactive VFO**. It is recommended to put the fox settings in VFO 1 and the return beacon on VFO 2. +The **last line** shows the configuration for the **inactive VFO**. It is recommended to put the fox settings in VFO A and the return beacon on VFO B. By long pressing "2 A/B" key can quickly be switched between both configurations. +On system boot the device starts with active fox number 1 and full duration time left. In menu "ActFox" the active fox can be changed. +The timer can be reset in menu "TiRst". Select "TiRst" with "M"-key, a triangle appears. Another press on "M"-key will reset the timer. +Use this for synchronization. Active fox and timer are shown on the top in the status bar if the menu is opened. + + #### Gain Remember Mode #### This firmware supports **gain remember** for manual gain control. If gain remember is **activated**, the -**manual gain index** is handled **for every fox seperately**. At the **beginning of a fox cycle** the **last gain +**manual gain index** is handled **for every fox separately**. At the **beginning of a fox cycle** the **last gain index for this fox** is **restored from the last cycle**. The manual gain index history for up to 5 foxes is shown in the lower part of the screen. If **gain remember** is **off**, there is only one gain index for all foxes independent from any fox cycle times. -This feature can be **configured for both VFOs separately** (menu "GainRe": Off / VFO 1 / VFO 2 / BOTH). +This feature can be **configured for both VFOs separately** (menu "GainRe": Off / VFO A / VFO B / BOTH). -A usage scenario would be to configure the fox frequency on VFO 1 with gain remember mode on. Put the return beacon -frequency on VFO 2 without gain remember on. (Because the return beacon is permanently transmitting there is no need +A usage scenario would be to configure the fox frequency on VFO A with gain remember mode on. Put the return beacon +frequency on VFO B without gain remember on. (Because the return beacon is permanently transmitting there is no need different gains in different time slots.) You can quickly switch between both VFOs by long pressing "2 (A/B)" or a configured function key (see below). If gain remember is not activated on the actual VFO, no gain index history is shown in the lower part of the screen. -On system boot the device starts with active fox number 1 and full duration time left. In menu "ActFox" the active fox can be changed. -The timer can be reset in menu "TiRst". Select "TiRst" with "M"-key, a triangle appears. Another press on "M"-key will reset the timer. -Use this for synchronization. Active fox and timer are shown on the top in the status bar if the menu is openend. +#### Clock Correction #### +The microcontroller clock of the radio seems to be not very precise. This leads to a heavily drifting clock. The firmware provides a correction +mechanism to reach acceptable ranges. Start ARDF mode and stop **how many seconds really pass** until **the radio tells 1 hour is up**. +(Useful settings: NumFox = 10, FoxDur = 60.00s, sync to reference clock.) The formula for the correction value is: + +$$ CorrectionValue = 6000 - (StoppedSeconds * 100)/60 $$ + +E.g. if the radio finished 60 one minute cycles in 59 min and 36 seconds = 59 * 60 + 36 = 3576s the calculation would be: -Unscrew antenna and add a directional antenna with good front/back ratio. Start hunting foxes and have fun. +$$ CorrectionValue = 6000 - (3576 * 100)/60 = 40 $$ + +Enter this value in menu "ClkCor" using UP/DOWN keys (allowed range: -500 ... 500). The value is stored in eeprom. #### Function keys #### Two different ARDF actions can be mapped to function keys: * Set manual gain to a medium index value (10). It is recommended to configure "ARDF Set Med.Gain" to short press on F2 key) * Enable/Disable ARDF function (e.g. for long press on F1 key). It is recommended to configure "Switch VFO" to F1 short. + +#### Chirp #### +There is a [chirp](https://chirpmyradio.com/projects/chirp/wiki/Home) driver in folder [chirp_module/](chirp_module/) for this firmware. +The radio (including ARDF settings) can be programmed with this driver only not with the standard UV-K5 driver. + +Chirp does not support separate settings for modulation and bandwidth, bandwidth is selected implicitly by the modulation. +This chirp driver uses in AM mode already "narrow" bandwidth and "U1K7" (1.7kHz) for "NAM" and "USB". #### Notes #### -* Because four bandwidth modes are available (WIDE, NARROW, NARROWER, U 1K7) they cannot programmed with chirp at the moment. Chirps default UV K5 profile only supports 1 bit for bandwidth settings. -* The lowest possible frequency of the receiver chip is 18 Mhz. So this is NOT usable on 80 m. -* If ARDF mode is active any TX functionality is disabled. However it is recommended to compile with ENABLE_PREVENT_TX=1 to permanently disable TX. ARDF receivers with a builtin TX functionality are not permitted in official competitions anyway. +* The lowest possible frequency of the receiver chip is 18 MHz. So this is NOT usable on 80 m. +* If ARDF mode is active any TX functionality is disabled. However it is recommended to compile with ENABLE_PREVENT_TX=1 to +permanently disable TX. This is done for official releases. ARDF receivers with a builtin TX functionality are not permitted +in official competitions anyway. * You can glue an arrow on the volume knob to keep the position under control (simply cut a triangle from a sticker). -* It is possible (but not recommended) to use memory mode instead of frequency mode on each VFO. If memory mode is active on the current VFO, -frequency and memory number are are displayed alternately one after each other. Number keys change the memory number (enter 3 digits) -and not the frequency. You can switch between memory mode and frequency mode by long pressing "3 VFO/MR" key. +* It is possible (but not recommended because it is more complicated) to use memory mode instead of frequency mode on each VFO. +If memory mode is active on the current VFO, frequency and memory number are are displayed alternately one after each other. +Number keys change the memory number (enter 3 digits) and not the frequency. You can switch between memory mode and +frequency mode by long pressing "3 VFO/MR" key. * If you modify settings in memory mode don´t forget to save them before switching off (menu "ChSave"). #### Troubleshooting #### @@ -168,7 +195,6 @@ and not the frequency. You can switch between memory mode and frequency mode by * Decrease frequency step in menu "Step" to desired channel raster. * Chirp does read different channel settings than in my radio. * If you changed channel settings on the radio you have to store them first (menu "ChSave"). - * Chirp does not support seperate settings for modulation and bandwidth. So bandwidth is selected implicitily by the modulation. This chirp driver uses in AM mode already "narrow" bandwidth and "U1K7" (1.7kHz) for "NAM" and "USB". ## Headphones diff --git a/app/ardf.c b/app/ardf.c index 2c2bd8cee..720366ca9 100644 --- a/app/ardf.c +++ b/app/ardf.c @@ -61,7 +61,7 @@ b=b; void ARDF_10ms(void) { - if ( gARDFTime10ms >= (gARDFFoxDuration10ms * 151 / 150) ) // time correction factor: -24s in 60min + if ( gARDFTime10ms >= gARDFFoxDuration10ms_corr ) { // new fox cycle gARDFTime10ms = 0; @@ -90,16 +90,17 @@ void ARDF_10ms(void) } else if ( (gScreenToDisplay == DISPLAY_ARDF) && ( (gARDFTime10ms % 50) == 0) ) { - // update most important values 2 times per second + // update most important values ~2 times per second UI_DisplayARDF_Timer(); UI_DisplayARDF_RSSI(); - gARDFRssiMax = 0; + gARDFRssiMax = BK4819_GetRSSI(); -#ifdef ENABLE_AGC_SHOW_DATA +#ifdef ARDF_ENABLE_SHOW_DEBUG_DATA + UI_DisplayARDF_Debug(); +#elif defined(ENABLE_AGC_SHOW_DATA) UI_MAIN_PrintAGC(true); #else - // UI_DisplayARDF_Debug(); center_line = CENTER_LINE_RSSI; DisplayRSSIBar(true); #endif @@ -115,7 +116,6 @@ void ARDF_10ms(void) } } - } @@ -140,6 +140,7 @@ void ARDF_500ms(void) if ( u8Secnd >= 2 ) { + // update status bar every second gUpdateStatus = 1; u8Secnd = 0; diff --git a/app/menu.c b/app/menu.c index 4ccda7863..b847672a0 100644 --- a/app/menu.c +++ b/app/menu.c @@ -499,6 +499,7 @@ void MENU_AcceptSetting(void) // value updated gSetting_ARDFEnable = gSubMenuSelection; RADIO_SetupAGC(gRxVfo->Modulation == MODULATION_AM, false); // if gSetting_ARDFEnable is set, AGC will be switched off + gARDFRequestSaveEEPROM = true; } @@ -510,6 +511,7 @@ void MENU_AcceptSetting(void) { // value updated gARDFNumFoxes = gSubMenuSelection; + gARDFRequestSaveEEPROM = true; } return; @@ -520,6 +522,8 @@ void MENU_AcceptSetting(void) { // value updated gARDFFoxDuration10ms = gSubMenuSelection; + gARDFFoxDuration10ms_corr = (uint32_t)( (int32_t)gARDFFoxDuration10ms + ( (int32_t)gARDFFoxDuration10ms * (int32_t)gARDFClockCorrAddTicksPerMin)/6000 ); // fixme: limit to 1s + gARDFRequestSaveEEPROM = true; } return; @@ -542,10 +546,24 @@ void MENU_AcceptSetting(void) { // value updated gARDFGainRemember = gSubMenuSelection; + gARDFRequestSaveEEPROM = true; } return; + + case MENU_ARDF_CLOCK_CORR: + + if ( gARDFClockCorrAddTicksPerMin != gSubMenuSelection ) + { + // value updated + gARDFClockCorrAddTicksPerMin = gSubMenuSelection; + gARDFFoxDuration10ms_corr = (uint32_t)( (int32_t)gARDFFoxDuration10ms + ( (int32_t)gARDFFoxDuration10ms * (int32_t)gARDFClockCorrAddTicksPerMin)/6000 ); // fixme: limit to 1s + + gARDFRequestSaveEEPROM = true; + } + return; + #endif @@ -1008,7 +1026,10 @@ void MENU_ShowCurrentSetting(void) case MENU_ARDF_GAIN_REMEMBER: gSubMenuSelection = gARDFGainRemember; break; - + + case MENU_ARDF_CLOCK_CORR: + gSubMenuSelection = gARDFClockCorrAddTicksPerMin; + break; #endif case MENU_SCR: @@ -1790,15 +1811,15 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) if (UI_MENU_GetCurrentMenuId() == MENU_ARDF_FOXDURATION) { - int32_t duration = (-Direction * 10) + gSubMenuSelection; - if (duration < 99999) + int32_t duration = (Direction * 10) + gSubMenuSelection; + if (duration <= 99999) { - if (duration < 0) + if (duration < 100) duration = 99999; } else { - duration = 0; + duration = 100; } gSubMenuSelection = duration; @@ -1806,6 +1827,24 @@ static void MENU_Key_UP_DOWN(bool bKeyPressed, bool bKeyHeld, int8_t Direction) return; } + if (UI_MENU_GetCurrentMenuId() == MENU_ARDF_CLOCK_CORR ) + { + int16_t correction = Direction + gSubMenuSelection; + if (correction <= 500) + { + if (correction < -500) + correction = -500; + } + else + { + correction = 500; + } + + gSubMenuSelection = correction; + gRequestDisplayScreen = DISPLAY_MENU; + return; + } + #endif VFO = 0; diff --git a/chirp_module/uvk5_ARDF.py b/chirp_module/uvk5_ARDF.py index 1aeea618b..0d2004b25 100644 --- a/chirp_module/uvk5_ARDF.py +++ b/chirp_module/uvk5_ARDF.py @@ -176,12 +176,12 @@ #seekto 0xf24; ul32 ARDFFoxDuration; +il16 ARDFClockCorrTicksMin; u8 __unused3:1, ARDFGainRemember:2, ARDFNumFoxes:4, ARDFEnable:1; - #seekto 0xf40; u8 int_flock; u8 int_350tx; @@ -438,7 +438,7 @@ MIC_GAIN_LIST = ["+1.1dB", "+4.0dB", "+8.0dB", "+12.0dB", "+15.1dB"] -ARDFGainRemember_LIST = ["off", "VFO 1", "VFO 2", "Both"] +ARDFGainRemember_LIST = ["off", "VFO A", "VFO B", "Both"] def min_max_def(value, min_val, max_val, default): """returns value if in bounds or default otherwise""" @@ -931,6 +931,9 @@ def set_settings(self, settings): elif elname == "ARDFEnable": _mem.ARDFEnable = element.value + elif elname == "ARDFClockCorrTicksMin": + _mem.ARDFClockCorrTicksMin = element.value + elif elname == "ARDFFoxDuration": _mem.ARDFFoxDuration = element.value @@ -1418,6 +1421,10 @@ def get_action(action_num): tmp_ARDFFoxDuration = _mem.ARDFFoxDuration val = RadioSettingValueInteger(100, 99999, tmp_ARDFFoxDuration) ARDFFoxDuration_setting = RadioSetting("ARDFFoxDuration", "ARDF Fox Transmitting Duration [1/100 s] (FoxDur)", val) + + tmp_ARDFClockCorrTicksMin = _mem.ARDFClockCorrTicksMin + val = RadioSettingValueInteger(-500, 500, tmp_ARDFClockCorrTicksMin) + ARDFClockCorrTicksMin_setting = RadioSetting("ARDFClockCorrTicksMin", "ARDF Clock Correction add. 10ms Ticks per Minute", val) val = RadioSettingValueBoolean(_mem.ARDFEnable) ARDFEnable_setting = RadioSetting("ARDFEnable", "ARDF Enable (ARDF)", val) @@ -1762,6 +1769,7 @@ def validate_int_flock(value): # ARDF ardf.append(ARDFEnable_setting) ardf.append(ARDFFoxDuration_setting) + ardf.append(ARDFClockCorrTicksMin_setting) ardf.append(ARDFNumFoxes_setting) ardf.append(ARDFGainRemember_setting) diff --git a/driver/bk4819.c b/driver/bk4819.c index af777a9f5..117fe2e5c 100644 --- a/driver/bk4819.c +++ b/driver/bk4819.c @@ -666,7 +666,7 @@ void BK4819_SetFilterBandwidth(const BK4819_FilterBandwidth_t Bandwidth, const b } break; */ - case BK4819_FILTER_BW_NARROWER: // 2.5 kHz modified for ARDF + case BK4819_FILTER_BW_NARROWER:// 2.5 kHz modified for ARDF val = (2u << 12) | // RF filter bandwidth (010 = 2.5 kHz) (2u << 9) | // RF filter bandwidth when signal is weak, same (010 = 2.5 kHz) (1u << 6) | // AFTxLPF2 filter Band Width (smallest, but we don´t care about TX) diff --git a/images/ardf_mainscreen.jpg b/images/ardf_mainscreen.jpg index a44bc1dd3..94a222a76 100644 Binary files a/images/ardf_mainscreen.jpg and b/images/ardf_mainscreen.jpg differ diff --git a/images/ardf1.jpg b/images/ardf_v01.jpg similarity index 100% rename from images/ardf1.jpg rename to images/ardf_v01.jpg diff --git a/misc.c b/misc.c index c6418b850..c8d994033 100644 --- a/misc.c +++ b/misc.c @@ -95,12 +95,14 @@ bool gSetting_ScrambleEnable; bool gSetting_ARDFEnable = ARDF_DEFAULT_ENABLE; uint32_t gARDFTime10ms = 0; uint32_t gARDFFoxDuration10ms = ARDF_DEFAULT_FOX_DURATION; /* 60s * 100 ticks per second */ +uint32_t gARDFFoxDuration10ms_corr = ARDF_DEFAULT_FOX_DURATION + (ARDF_DEFAULT_FOX_DURATION * ARDF_CLOCK_CORR_TICKS_PER_MIN)/6000; uint8_t gARDFNumFoxes = ARDF_DEFAULT_NUM_FOXES; uint8_t gARDFActiveFox = 0; uint8_t gARDFGainRemember = ARDF_DEFAULT_GAIN_REMEMBER; /* remember gain on VFO 1 by default. */ unsigned int gARDFRssiMax = 0; /* max rssi of last half second */ uint8_t gARDFMemModeFreqToggleCnt_s = 0; /* toggle memory bank/frequency display every x s */ -bool gARDFRequestSaveEEPROM = false; +bool gARDFRequestSaveEEPROM = true; +int16_t gARDFClockCorrAddTicksPerMin = ARDF_CLOCK_CORR_TICKS_PER_MIN; uint8_t ardf_gain_index[2][ARDF_NUM_FOX_MAX]; @@ -196,8 +198,8 @@ uint8_t ARDF_Get_GainIndex(uint8_t vfo) bool ARDF_ActVfoHasGainRemember(uint8_t vfo) { /* "OFF", 0 - "VFO1", 1 - "VFO2", 2 + "VFO A", 1 + "VFO B", 2 "BOTH" 3 */ if ( (vfo+1) & gARDFGainRemember ) @@ -219,6 +221,11 @@ void ARDF_ActivateGainIndex(void) } +int32_t ARDF_GetRestTime_s(void) +{ + return (int32_t)(gARDFFoxDuration10ms - gARDFTime10ms * gARDFFoxDuration10ms/gARDFFoxDuration10ms_corr )/100; +} + #endif enum BacklightOnRxTx_t gSetting_backlight_on_tx_rx; diff --git a/misc.h b/misc.h index 0aace6288..d64657d8c 100644 --- a/misc.h +++ b/misc.h @@ -162,15 +162,21 @@ extern bool gSetting_ScrambleEnable; #define ARDF_DEFAULT_FOX_DURATION 6000 #define ARDF_DEFAULT_GAIN_REMEMBER 1 +#define ARDF_CLOCK_CORR_TICKS_PER_MIN (+00) // default clock correction + +//#define ARDF_ENABLE_SHOW_DEBUG_DATA + extern bool gSetting_ARDFEnable; extern uint32_t gARDFTime10ms; extern uint32_t gARDFFoxDuration10ms; +extern uint32_t gARDFFoxDuration10ms_corr; extern uint8_t gARDFNumFoxes; extern uint8_t gARDFActiveFox; extern uint8_t gARDFGainRemember; extern unsigned int gARDFRssiMax; extern uint8_t gARDFMemModeFreqToggleCnt_s; extern bool gARDFRequestSaveEEPROM; +extern int16_t gARDFClockCorrAddTicksPerMin; typedef struct { @@ -188,6 +194,7 @@ extern void ARDF_GainDecr(void); extern uint8_t ARDF_Get_GainIndex(uint8_t vfo); extern bool ARDF_ActVfoHasGainRemember(uint8_t vfo); extern void ARDF_ActivateGainIndex(void); +extern int32_t ARDF_GetRestTime_s(void); #endif diff --git a/radio.h b/radio.h index 976ebec18..5152ac1a0 100644 --- a/radio.h +++ b/radio.h @@ -31,7 +31,7 @@ enum { enum { BANDWIDTH_WIDE = 0, BANDWIDTH_NARROW, - BANDWIDTH_NARROWER, + BANDWIDTH_U2K5, BANDWIDTH_U1K7 }; diff --git a/settings.c b/settings.c index ab366e43c..af7ea949c 100644 --- a/settings.c +++ b/settings.c @@ -230,13 +230,13 @@ void SETTINGS_InitEEPROM(void) #ifdef ENABLE_ARDF // 0F24..0F2C - EEPROM_ReadBuffer(0x0F24, Data, 5); + EEPROM_ReadBuffer(0x0F24, Data, 7); - if ( Data[4] != 0xFF ) + if ( Data[6] != 0xFF ) { - gSetting_ARDFEnable = Data[4] & 0x01; - gARDFNumFoxes = (Data[4] >> 1) & 0x0f; - gARDFGainRemember = (Data[4] >> 5) & 0x03; + gSetting_ARDFEnable = Data[6] & 0x01; + gARDFNumFoxes = (Data[6] >> 1) & 0x0f; + gARDFGainRemember = (Data[6] >> 5) & 0x03; } else { @@ -258,6 +258,24 @@ void SETTINGS_InitEEPROM(void) if ( gARDFFoxDuration10ms < 100 ) gARDFFoxDuration10ms = ARDF_DEFAULT_FOX_DURATION; + + if ( (Data[4] == 0xFF) && (Data[5] == 0xFF) ) + { + // eeprom empty + gARDFClockCorrAddTicksPerMin = ARDF_CLOCK_CORR_TICKS_PER_MIN; + } + else + { + memcpy(&gARDFClockCorrAddTicksPerMin, &Data[4], sizeof(gARDFClockCorrAddTicksPerMin)); + + if ( (gARDFClockCorrAddTicksPerMin < -500) || (gARDFClockCorrAddTicksPerMin > 500) ) + gARDFClockCorrAddTicksPerMin = ARDF_CLOCK_CORR_TICKS_PER_MIN; + + } + + gARDFFoxDuration10ms_corr = (uint32_t)( (int32_t)gARDFFoxDuration10ms + ( (int32_t)gARDFFoxDuration10ms * (int32_t)gARDFClockCorrAddTicksPerMin)/6000 ); // fixme: limit to 1s + + #endif // 0F40..0F47 @@ -485,16 +503,18 @@ void SETTINGS_SaveARDF(void) union { struct { uint32_t FoxDuration; + int16_t ARDFClockCorrTicksMin; uint8_t ARDFEnable:1; uint8_t NumFoxes:4; uint8_t GainRemember:2; }; - uint8_t __raw[5]; + uint8_t __raw[7]; } __attribute__((packed)) ARDFCfg; memset(ARDFCfg.__raw, 0xFF, sizeof(ARDFCfg.__raw)); ARDFCfg.FoxDuration = gARDFFoxDuration10ms; + ARDFCfg.ARDFClockCorrTicksMin = gARDFClockCorrAddTicksPerMin; ARDFCfg.ARDFEnable = gSetting_ARDFEnable; ARDFCfg.NumFoxes = gARDFNumFoxes; ARDFCfg.GainRemember = gARDFGainRemember; diff --git a/ui/ardf.c b/ui/ardf.c index 25b02849e..3a9ae6935 100644 --- a/ui/ardf.c +++ b/ui/ardf.c @@ -32,12 +32,21 @@ #include "ui/ui.h" - void UI_DisplayARDF_Timer(void) { char buffer[4]; - sprintf(buffer, "-%02u", (int32_t)((gARDFFoxDuration10ms * 151 / 150) - gARDFTime10ms)/100 ); // factor 151/150 is for clock correction + int32_t resttime = ARDF_GetRestTime_s(); + + if ( resttime <= 99 ) + { + sprintf(buffer, "-%02u", resttime ); + } + else + { + sprintf(buffer, "%3u", resttime ); + } + UI_DisplayFrequency(buffer, 12, 0, false); // note: ST7565_BlitLine(0/1) for this screen update is called in UI_DisplayARDF_RSSI() @@ -65,11 +74,9 @@ void UI_DisplayARDF_RSSI(void) void UI_DisplayARDF_Debug(void) { - char buffer[4]; - - UI_PrintStringSmallNormal("debug", 60, 0, 3); + char buffer[17]; - sprintf(buffer, "%03d", gScreenToDisplay); + sprintf(buffer, "Dbg: %d %d", gARDFFoxDuration10ms_corr, gARDFClockCorrAddTicksPerMin); UI_PrintStringSmallNormal(buffer, 2, 0, 3); ST7565_BlitLine(3); @@ -84,12 +91,12 @@ void UI_DisplayARDF(void) UI_DisplayClear(); - if( gLowBattery && !gLowBatteryConfirmed ) + /* if( gLowBattery && !gLowBatteryConfirmed ) { UI_DisplayPopup("LOW BATTERY"); ST7565_BlitFullScreen(); return; - } + } */ /* 1. big line */ uint8_t activefox = gARDFActiveFox + 1; @@ -109,7 +116,7 @@ void UI_DisplayARDF(void) VFO_Info_t *vfoInfo = &gEeprom.VfoInfo[vfo]; ModulationMode_t mod = vfoInfo->Modulation; - sprintf(buffer, "%d", vfo+1 ); + sprintf(buffer, "%c", 'A' + vfo ); UI_PrintStringSmallBold(buffer, 0, 0, 2); UI_PrintStringSmallBold(gModulationStr[mod], 12, 36, 2); // modulation @@ -121,7 +128,7 @@ void UI_DisplayARDF(void) UI_PrintStringSmallBold("N", 42, 58, 2); break; - case BANDWIDTH_NARROWER: + case BANDWIDTH_U2K5: UI_PrintStringSmallBold("N-", 42, 58, 2); break; @@ -175,13 +182,11 @@ void UI_DisplayARDF(void) /* 3. middle line for debug or rssi bar */ - // UI_PrintStringSmallNormal("line 3", 2, 0, 3); - // UI_DisplayARDF_Debug(); - -#ifdef ENABLE_AGC_SHOW_DATA +#ifdef ARDF_ENABLE_SHOW_DEBUG_DATA + UI_DisplayARDF_Debug(); +#elif defined(ENABLE_AGC_SHOW_DATA) UI_MAIN_PrintAGC(true); #else - // UI_DisplayARDF_Debug(); center_line = CENTER_LINE_RSSI; DisplayRSSIBar(true); #endif @@ -224,7 +229,7 @@ void UI_DisplayARDF(void) vfoInfo = &gEeprom.VfoInfo[1-vfo]; mod = vfoInfo->Modulation; - sprintf(buffer, "%d", 2-vfo ); + sprintf(buffer, "%c", 'B' - vfo ); UI_PrintStringSmallNormal(buffer, 0, 0, 6); UI_PrintStringSmallNormal(gModulationStr[mod], 12, 36, 6); // modulation @@ -236,7 +241,7 @@ void UI_DisplayARDF(void) UI_PrintStringSmallNormal("N", 42, 58, 6); break; - case BANDWIDTH_NARROWER: + case BANDWIDTH_U2K5: UI_PrintStringSmallNormal("N-", 42, 58, 6); break; diff --git a/ui/main.c b/ui/main.c index 7d803ada2..230c2f308 100644 --- a/ui/main.c +++ b/ui/main.c @@ -697,7 +697,7 @@ void UI_DisplayMain(void) if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROW) UI_PrintStringSmallNormal("N", LCD_WIDTH + 70, 0, line + 1); - if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_NARROWER) + if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_U2K5) UI_PrintStringSmallNormal("N-", LCD_WIDTH + 70, 0, line + 1); if (vfoInfo->CHANNEL_BANDWIDTH == BANDWIDTH_U1K7) diff --git a/ui/menu.c b/ui/menu.c index e59fdfbd1..466029a60 100644 --- a/ui/menu.c +++ b/ui/menu.c @@ -57,8 +57,8 @@ const t_menu_item MenuList[] = {"ActFox", VOICE_ID_INVALID, MENU_ARDF_SETFOX }, {"TiRst", VOICE_ID_INVALID, MENU_ARDF_TIME_RESET }, {"GainRe", VOICE_ID_INVALID, MENU_ARDF_GAIN_REMEMBER }, + {"ClkCor", VOICE_ID_INVALID, MENU_ARDF_CLOCK_CORR }, #endif - {"Scramb", VOICE_ID_SCRAMBLER_ON, MENU_SCR }, // was "SCR" {"BusyCL", VOICE_ID_BUSY_LOCKOUT, MENU_BCL }, // was "BCL" {"Compnd", VOICE_ID_INVALID, MENU_COMPAND }, @@ -155,11 +155,11 @@ const t_menu_item MenuList[] = const uint8_t FIRST_HIDDEN_MENU_ITEM = MENU_F_LOCK; #ifdef ENABLE_ARDF -const char gSubMenu_ARDF_Remember_Gain[][5] = +const char gSubMenu_ARDF_Remember_Gain[][6] = { "OFF", - "VFO1", - "VFO2", + "VFO A", + "VFO B", "BOTH" }; #endif @@ -178,11 +178,11 @@ const char gSubMenu_SFT_D[][4] = "-" }; -const char gSubMenu_W_N[][9] = +const char gSubMenu_W_N[][7] = { "WIDE", "NARROW", - "NARROWER", + "U 2K5", "U 1K7" }; @@ -631,6 +631,10 @@ void UI_DisplayMenu(void) strcpy(String, gSubMenu_ARDF_Remember_Gain[gSubMenuSelection]); break; + case MENU_ARDF_CLOCK_CORR: + sprintf(String, "%d", gSubMenuSelection); + break; + #endif case MENU_SCR: diff --git a/ui/menu.h b/ui/menu.h index 70efb90c6..254385d18 100644 --- a/ui/menu.h +++ b/ui/menu.h @@ -49,6 +49,7 @@ enum MENU_ARDF_SETFOX, MENU_ARDF_TIME_RESET, MENU_ARDF_GAIN_REMEMBER, + MENU_ARDF_CLOCK_CORR, #endif MENU_SCR, MENU_BCL, @@ -138,12 +139,12 @@ extern const uint8_t FIRST_HIDDEN_MENU_ITEM; extern const t_menu_item MenuList[]; #ifdef ENABLE_ARDF -extern const char gSubMenu_ARDF_Remember_Gain[4][5]; +extern const char gSubMenu_ARDF_Remember_Gain[4][6]; #endif extern const char gSubMenu_TXP[3][5]; extern const char gSubMenu_SFT_D[3][4]; -extern const char gSubMenu_W_N[4][9]; +extern const char gSubMenu_W_N[4][7]; extern const char gSubMenu_OFF_ON[2][4]; extern const char gSubMenu_SAVE[5][4]; extern const char gSubMenu_TOT[11][7]; diff --git a/ui/status.c b/ui/status.c index 5ea3440ed..a6a87b471 100644 --- a/ui/status.c +++ b/ui/status.c @@ -66,7 +66,11 @@ void UI_DisplayStatus() uint8_t activefox = gARDFActiveFox + 1; if ( activefox >= 10 ) activefox = 0; - sprintf(buf, "F%d %2d", activefox, ( -(int32_t)((gARDFFoxDuration10ms * 151 / 150) - gARDFTime10ms)/100) ); // factor 151/150 is for clock correction + + int32_t resttime = ARDF_GetRestTime_s(); + + sprintf(buf, "F%d %d", activefox, resttime); + UI_PrintStringSmallBufferBold(buf, line + 32); } else