From a11057d4e76a55d95b49a32bfef26dfbc65f8766 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Wed, 22 Feb 2023 15:58:59 +0100 Subject: [PATCH 1/5] audio output working --- Makefile | 2 +- NANOVNA_STM32_F303/adc.c | 6 +++- NANOVNA_STM32_F303/board.h | 4 +-- NANOVNA_STM32_F303/mcuconf.h | 6 ++-- halconf.h | 2 +- main.c | 63 ++++++++++++++++++++++++++++++++++-- nanovna.h | 5 +++ sa_core.c | 8 ++--- ui.c | 4 +-- 9 files changed, 84 insertions(+), 16 deletions(-) diff --git a/Makefile b/Makefile index 4eaf747..85410be 100644 --- a/Makefile +++ b/Makefile @@ -92,7 +92,7 @@ endif ifeq ($(TARGET),F303) USE_FPU = hard - USE_PROCESS_STACKSIZE = 0x380 + USE_PROCESS_STACKSIZE = 0x480 USE_EXCEPTIONS_STACKSIZE = 0x200 endif diff --git a/NANOVNA_STM32_F303/adc.c b/NANOVNA_STM32_F303/adc.c index 5e60cf4..9f06461 100644 --- a/NANOVNA_STM32_F303/adc.c +++ b/NANOVNA_STM32_F303/adc.c @@ -64,7 +64,11 @@ static const ADCConversionGroup adcgrpcfgTouch = { NULL, // adcerrorcallback_touch // CFGR ADC_CFGR_EXTEN_0 // rising edge of external trigger - | ADC_CFGR_EXTSEL_2 // EXT4 0x1000 event (TIM3_TRGO) + + | ADC_CFGR_EXTSEL_3 | ADC_CFGR_EXTSEL_0 // EXT4 0x1001 event (TIM1_TRGO) +// | ADC_CFGR_EXTSEL_2 // EXT4 0x100 event (TIM3_TRGO) + + | ADC_CFGR_AWD1EN, // Enable Analog watchdog check interrupt ADC_TR(0, TOUCH_THRESHOLD), // Analog watchdog threshold TR1, interrupt on touch press {ADC_SMPR1_SMP_AN4(ADC_TOUCH_SMP_TIME), 0}, // SMPR[2] diff --git a/NANOVNA_STM32_F303/board.h b/NANOVNA_STM32_F303/board.h index 76e0649..71f9f9f 100644 --- a/NANOVNA_STM32_F303/board.h +++ b/NANOVNA_STM32_F303/board.h @@ -162,7 +162,7 @@ PIN_MODE_INPUT(1U) | \ PIN_MODE_INPUT(2U) | \ PIN_MODE_INPUT(3U) | \ - PIN_MODE_INPUT(GPIO_SD_DAT2) | \ + PIN_MODE_ALTERNATE(GPIO_SD_DAT2) | \ PIN_MODE_ANALOG(GPIOA_DAC2) | \ PIN_MODE_ANALOG(GPIOA_XP) | \ PIN_MODE_ANALOG(GPIOA_YP) | \ @@ -242,7 +242,7 @@ PIN_AFIO_AF(1, 0) | \ PIN_AFIO_AF(2, 0) | \ PIN_AFIO_AF(3, 0) | \ - PIN_AFIO_AF(GPIO_SD_DAT2, 0) | \ + PIN_AFIO_AF(GPIO_SD_DAT2, 2) | \ PIN_AFIO_AF(5, 0) | \ PIN_AFIO_AF(6, 0) | \ PIN_AFIO_AF(7, 0)) diff --git a/NANOVNA_STM32_F303/mcuconf.h b/NANOVNA_STM32_F303/mcuconf.h index 391e522..4dedf5d 100644 --- a/NANOVNA_STM32_F303/mcuconf.h +++ b/NANOVNA_STM32_F303/mcuconf.h @@ -153,9 +153,9 @@ /* * GPT driver system settings. */ -#define STM32_GPT_USE_TIM1 FALSE +#define STM32_GPT_USE_TIM1 TRUE #define STM32_GPT_USE_TIM2 FALSE -#define STM32_GPT_USE_TIM3 TRUE +#define STM32_GPT_USE_TIM3 FALSE #define STM32_GPT_USE_TIM4 TRUE #define STM32_GPT_TIM1_IRQ_PRIORITY 2 #define STM32_GPT_TIM2_IRQ_PRIORITY 2 @@ -210,7 +210,7 @@ #define STM32_PWM_USE_ADVANCED FALSE #define STM32_PWM_USE_TIM1 FALSE #define STM32_PWM_USE_TIM2 FALSE -#define STM32_PWM_USE_TIM3 FALSE +#define STM32_PWM_USE_TIM3 TRUE #define STM32_PWM_TIM1_IRQ_PRIORITY 3 #define STM32_PWM_TIM2_IRQ_PRIORITY 3 #define STM32_PWM_TIM3_IRQ_PRIORITY 3 diff --git a/halconf.h b/halconf.h index 9d34c41..c42c81f 100644 --- a/halconf.h +++ b/halconf.h @@ -115,7 +115,7 @@ * @brief Enables the PWM subsystem. */ #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) -#define HAL_USE_PWM FALSE +#define HAL_USE_PWM TRUE #endif /** diff --git a/main.c b/main.c index cf2e39c..bb94623 100644 --- a/main.c +++ b/main.c @@ -2529,6 +2529,60 @@ THD_FUNCTION(myshellThread, p) #pragma GCC pop_options +#ifdef __PWM__ + + +static void audio_toggle(void) +{ + static volatile int h = 0; + if (h) { + DAC->DHR12R1 = 0; + h = 0; + } else { + DAC->DHR12R1 = 4095; + h = 1; + } +} + +static PWMConfig pwmcfg = { + 400000, /* 400kHz PWM clock frequency. */ + 100, /* Initial PWM frequency is 4kHz */ + NULL, + { + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_ACTIVE_HIGH, audio_toggle}, + {PWM_OUTPUT_DISABLED, NULL}, + {PWM_OUTPUT_DISABLED, NULL} + }, + 0, + 0 +}; + +#define PWM_TIMER PWMD3 +#define PWM_CHANNEL 1 // Channel 2 +void pwm_init(void) { + palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(6)); // PA9 + palSetPadMode(GPIOA, 4, PAL_MODE_ALTERNATE(2)); // PA4 Time 3 channel 2 + pwmStart(&PWM_TIMER, &pwmcfg); + pwmEnableChannel(&PWM_TIMER, PWM_CHANNEL, PWM_PERCENTAGE_TO_WIDTH(&PWM_TIMER, 5000)); + pwmEnableChannelNotification(&PWM_TIMER, PWM_CHANNEL); +} + +void pwm_start(int f) +{ + pwmcfg.frequency = f*100; + pwmStart(&PWM_TIMER, &pwmcfg); +// pwmChangePeriod(&PWM_TIMER, f); + pwmEnableChannel(&PWM_TIMER, PWM_CHANNEL, PWM_PERCENTAGE_TO_WIDTH(&PWM_TIMER, 5000)); +} + +void pwm_stop(void) +{ + pwmDisableChannel(&PWM_TIMER, PWM_CHANNEL); +} +#endif + + static const GPTConfig gpt4cfg = { 8000000, // 8 MHz timer clock. NULL, // No callback @@ -2646,14 +2700,19 @@ int main(void) spi_init(); PULSE - +#ifdef __PWM__ + pwm_init(); + pwm_start(2000); + pwm_stop(); +#endif /* * Set LCD display brightness (use DAC2 for control) * Starting DAC1 driver, setting up the output pin as analog as suggested by the Reference Manual. */ dac_init(); PULSE - DAC->CR|= DAC_CR_EN1 | DAC_CR_EN2; // Use DAC: CH1 and CH2 +// DAC->CR|= DAC_CR_EN1 | DAC_CR_EN2; // Use DAC: CH1 and CH2 + DAC->CR|= DAC_CR_EN2; // Use DAC: CH1 and CH2 #ifdef __LCD_BRIGHTNESS__ lcd_setBrightness(DEFAULT_BRIGHTNESS); #endif diff --git a/nanovna.h b/nanovna.h index a7582ce..1959ce0 100644 --- a/nanovna.h +++ b/nanovna.h @@ -119,6 +119,11 @@ //#define __USE_FREQ_TABLE__ // Enable use table for frequency list #endif +#ifdef __GUARD__ +#define __PWM__ +#endif + + #ifdef TINYSA3 #define VARIANT(X,Y) (X) #define DEFAULT_IF 433800000 diff --git a/sa_core.c b/sa_core.c index 4f22808..c1109fc 100644 --- a/sa_core.c +++ b/sa_core.c @@ -4872,14 +4872,14 @@ static bool sweep(bool break_on_operation) if (current_guard > GUARDS_MAX) current_guard = 0; } - while(!setting.guards[current_guard].enabled); + while(!(setting.guards[current_guard].enabled)); if (setting.guards[current_guard].end > setting.guards[current_guard].start) { set_sweep_frequency(ST_START, setting.guards[current_guard].start); set_sweep_frequency(ST_STOP, setting.guards[current_guard].end); set_rbw(8000); set_sweep_points((setting.guards[current_guard].end - setting.guards[current_guard].start) / 800000); } - DAC->DHR12R1 = 0; + pwm_stop(); } #endif @@ -5213,7 +5213,7 @@ static volatile int dummy; if (MODE_INPUT(setting.mode)) { #ifdef __GUARD__ if (setting.measurement == M_GUARD && RSSI > setting.guards[current_guard].level) { - DAC->DHR12R1 = 4095; + pwm_start(4000); } #endif for (int t=0; t Date: Thu, 23 Feb 2023 10:33:56 +0100 Subject: [PATCH 2/5] clean --- NANOVNA_STM32_F303/board.h | 4 ++-- main.c | 9 ++++----- sa_core.c | 3 +++ 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/NANOVNA_STM32_F303/board.h b/NANOVNA_STM32_F303/board.h index 71f9f9f..1962485 100644 --- a/NANOVNA_STM32_F303/board.h +++ b/NANOVNA_STM32_F303/board.h @@ -162,7 +162,7 @@ PIN_MODE_INPUT(1U) | \ PIN_MODE_INPUT(2U) | \ PIN_MODE_INPUT(3U) | \ - PIN_MODE_ALTERNATE(GPIO_SD_DAT2) | \ + PIN_MODE_ANALOG(GPIO_SD_DAT2) | \ PIN_MODE_ANALOG(GPIOA_DAC2) | \ PIN_MODE_ANALOG(GPIOA_XP) | \ PIN_MODE_ANALOG(GPIOA_YP) | \ @@ -242,7 +242,7 @@ PIN_AFIO_AF(1, 0) | \ PIN_AFIO_AF(2, 0) | \ PIN_AFIO_AF(3, 0) | \ - PIN_AFIO_AF(GPIO_SD_DAT2, 2) | \ + PIN_AFIO_AF(GPIO_SD_DAT2, 0) | \ PIN_AFIO_AF(5, 0) | \ PIN_AFIO_AF(6, 0) | \ PIN_AFIO_AF(7, 0)) diff --git a/main.c b/main.c index bb94623..04c4058 100644 --- a/main.c +++ b/main.c @@ -2550,7 +2550,7 @@ static PWMConfig pwmcfg = { NULL, { {PWM_OUTPUT_DISABLED, NULL}, - {PWM_OUTPUT_ACTIVE_HIGH, audio_toggle}, + {PWM_OUTPUT_ACTIVE_HIGH, NULL}, {PWM_OUTPUT_DISABLED, NULL}, {PWM_OUTPUT_DISABLED, NULL} }, @@ -2561,11 +2561,10 @@ static PWMConfig pwmcfg = { #define PWM_TIMER PWMD3 #define PWM_CHANNEL 1 // Channel 2 void pwm_init(void) { - palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(6)); // PA9 palSetPadMode(GPIOA, 4, PAL_MODE_ALTERNATE(2)); // PA4 Time 3 channel 2 - pwmStart(&PWM_TIMER, &pwmcfg); - pwmEnableChannel(&PWM_TIMER, PWM_CHANNEL, PWM_PERCENTAGE_TO_WIDTH(&PWM_TIMER, 5000)); - pwmEnableChannelNotification(&PWM_TIMER, PWM_CHANNEL); +// pwmStart(&PWM_TIMER, &pwmcfg); +// pwmEnableChannel(&PWM_TIMER, PWM_CHANNEL, PWM_PERCENTAGE_TO_WIDTH(&PWM_TIMER, 5000)); +// pwmEnableChannelNotification(&PWM_TIMER, PWM_CHANNEL); } void pwm_start(int f) diff --git a/sa_core.c b/sa_core.c index c1109fc..c0c972f 100644 --- a/sa_core.c +++ b/sa_core.c @@ -4879,8 +4879,11 @@ static bool sweep(bool break_on_operation) set_rbw(8000); set_sweep_points((setting.guards[current_guard].end - setting.guards[current_guard].start) / 800000); } + pwm_init(); pwm_stop(); } + else + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT); // Back to DAC mode #endif setting.measure_sweep_time_us = 0; // start measure sweep time From 748a680fd898eee4e92e9c6abb99f596bc839076 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Thu, 23 Feb 2023 12:03:57 +0100 Subject: [PATCH 3/5] Cleanup --- NANOVNA_STM32_F303/board.h | 2 +- main.c | 29 ++++++++++++++++++++++------- nanovna.h | 11 ++++++++++- sa_core.c | 17 +++++++++++++---- ui.c | 12 ++++++++++++ 5 files changed, 58 insertions(+), 13 deletions(-) diff --git a/NANOVNA_STM32_F303/board.h b/NANOVNA_STM32_F303/board.h index 1962485..6c1432b 100644 --- a/NANOVNA_STM32_F303/board.h +++ b/NANOVNA_STM32_F303/board.h @@ -226,7 +226,7 @@ PIN_ODR_HIGH(1) | \ PIN_ODR_HIGH(2) | \ PIN_ODR_HIGH(3) | \ - PIN_ODR_HIGH(GPIO_SD_DAT2) | \ + PIN_ODR_LOW(GPIO_SD_DAT2) | \ PIN_ODR_LOW(5) | \ PIN_ODR_HIGH(6) | \ PIN_ODR_HIGH(7) | \ diff --git a/main.c b/main.c index 04c4058..25591b5 100644 --- a/main.c +++ b/main.c @@ -2582,6 +2582,22 @@ void pwm_stop(void) #endif +static uint16_t audio_mode = A_DAC; + +void set_audio_mode(uint16_t new_mode) +{ + if (new_mode == audio_mode) + return; + if (new_mode == A_PWM) { + DAC->CR&= ~DAC_CR_EN1; // Disable DAC CH1 + pwm_init(); + } else { + palSetPadMode(GPIOA, 4, PAL_MODE_INPUT); // Back to DAC mode + DAC->CR|= DAC_CR_EN1 | DAC_CR_EN2; // Use DAC: CH1 and CH2 + } + audio_mode = new_mode; +} + static const GPTConfig gpt4cfg = { 8000000, // 8 MHz timer clock. NULL, // No callback @@ -2699,19 +2715,18 @@ int main(void) spi_init(); PULSE -#ifdef __PWM__ - pwm_init(); - pwm_start(2000); - pwm_stop(); -#endif +//#ifdef __PWM__ +// pwm_init(); +// pwm_start(2000); +// pwm_stop(); +//#endif /* * Set LCD display brightness (use DAC2 for control) * Starting DAC1 driver, setting up the output pin as analog as suggested by the Reference Manual. */ dac_init(); PULSE -// DAC->CR|= DAC_CR_EN1 | DAC_CR_EN2; // Use DAC: CH1 and CH2 - DAC->CR|= DAC_CR_EN2; // Use DAC: CH1 and CH2 + DAC->CR|= DAC_CR_EN1 | DAC_CR_EN2; // Use DAC: CH1 and CH2 #ifdef __LCD_BRIGHTNESS__ lcd_setBrightness(DEFAULT_BRIGHTNESS); #endif diff --git a/nanovna.h b/nanovna.h index 1959ce0..c30bc4e 100644 --- a/nanovna.h +++ b/nanovna.h @@ -344,6 +344,14 @@ extern const char * const info_about[]; #ifdef TINYSA4 void toggle_extra_lna(void); void set_extra_lna(int t); + +enum { A_DAC, A_PWM }; +void set_audio_mode(uint16_t new_mode); +void pwm_start(int f); +void pwm_stop(void); +#ifdef __GUARD__ +void reset_guard(void); +#endif #endif // ------------------------------- sa_core.c ---------------------------------- @@ -1747,8 +1755,9 @@ void interpolate_maximum(int m); void calibrate_modulation(int modulation, int8_t *correction); enum { - M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_SNR, M_PASS_BAND, M_LINEARITY, M_AM, M_FM, M_THD, M_CP, M_NF_TINYSA, M_NF_STORE, M_NF_VALIDATE, M_NF_AMPLIFIER, M_GUARD, M_DECONV + M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_SNR, M_PASS_BAND, M_LINEARITY, M_AM, M_FM, M_THD, M_CP, M_NF_TINYSA, M_NF_STORE, M_NF_VALIDATE, M_NF_AMPLIFIER, M_GUARD, M_DECONV,M_MAX }; +#define MEASUREMENT_TEXT "OFF","IMD","OIP3","PN","SNR","PASS","LIN","AM","FM","THD","CP","NF T","NF S","NF V","NF A","GUARD","DECONF" enum { T_AUTO, T_NORMAL, T_SINGLE, T_DONE, T_UP, T_DOWN, T_MODE, T_PRE, T_POST, T_MID diff --git a/sa_core.c b/sa_core.c index c0c972f..4456562 100644 --- a/sa_core.c +++ b/sa_core.c @@ -4787,6 +4787,13 @@ again: // Spur redu static uint8_t low_count = 0; static uint8_t sweep_counter = 0; // Only used for HW refresh +#ifdef __GUARD__ +static int last_guard = -1; + +void reset_guard(void) { + last_guard = -1; +} +#endif // main loop for measurement static bool sweep(bool break_on_operation) @@ -4873,17 +4880,19 @@ static bool sweep(bool break_on_operation) current_guard = 0; } while(!(setting.guards[current_guard].enabled)); - if (setting.guards[current_guard].end > setting.guards[current_guard].start) { + if (setting.guards[current_guard].end > setting.guards[current_guard].start && last_guard != current_guard) { + last_guard = current_guard; set_sweep_frequency(ST_START, setting.guards[current_guard].start); set_sweep_frequency(ST_STOP, setting.guards[current_guard].end); set_rbw(8000); set_sweep_points((setting.guards[current_guard].end - setting.guards[current_guard].start) / 800000); } - pwm_init(); + set_audio_mode(A_PWM); pwm_stop(); + } else { + last_guard = -1; + set_audio_mode(A_DAC); } - else - palSetPadMode(GPIOA, 4, PAL_MODE_INPUT); // Back to DAC mode #endif setting.measure_sweep_time_us = 0; // start measure sweep time diff --git a/ui.c b/ui.c index 0bf17fe..6e1bb98 100644 --- a/ui.c +++ b/ui.c @@ -1497,6 +1497,9 @@ static const menuitem_t menu_settings2[]; static const menuitem_t menu_lowoutput_settings[]; extern bool dirty; char range_text[20]; +#ifdef TINYSA4 +const char * const measurement_text[] = {MEASUREMENT_TEXT}; +#endif #ifdef TINYSA4 int input_is_calibrated(void) @@ -3190,6 +3193,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_guard_select_acb) if (count == 0) setting.guards[0].enabled = true; b->icon = (setting.guards[data].enabled?BUTTON_ICON_CHECK:BUTTON_ICON_NOCHECK) ; plot_printf(b->text, sizeof(b->text), "%.6FHz\n%.6FHz", (float)setting.guards[data].start, (float)setting.guards[data].end); + reset_guard(); return; } active_guard = data; @@ -5540,6 +5544,14 @@ redraw_cal_status: quick_menu_y[max_quick_menu] = y; quick_menu[max_quick_menu++] = (menuitem_t *)NULL; +#ifdef TINYSA4 + if (setting.measurement != M_OFF){ + ili9341_set_foreground(LCD_BRIGHT_COLOR_GREEN); + lcd_printf(x, y, measurement_text[setting.measurement]); + y += 2*YSTEP + YSTEP/2; + } + +#endif // if (setting.mode == M_LOW) { // Attenuation ili9341_set_foreground(setting.auto_attenuation ? LCD_FG_COLOR : LCD_BRIGHT_COLOR_GREEN); From d291f63b25f4ab6b50f1324a35c1ab276ad92952 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 24 Feb 2023 09:53:54 +0100 Subject: [PATCH 4/5] Trigger with beep --- nanovna.h | 6 +++++- sa_core.c | 15 ++++++++++++++- ui.c | 15 +++++++++++++-- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/nanovna.h b/nanovna.h index ea16598..84be038 100644 --- a/nanovna.h +++ b/nanovna.h @@ -89,6 +89,7 @@ #endif #ifdef TINYSA4 #define __GUARD__ +#define __BEEP__ #define __MCU_CLOCK_SHIFT__ #define __ULTRA__ #define __USE_RTC__ // Enable RTC clock @@ -1195,6 +1196,9 @@ typedef struct setting uint8_t trigger; // enum uint8_t trigger_mode; // enum uint8_t trigger_direction; // enum +#ifdef __BEEP__ + uint8_t trigger_beep; +#endif uint8_t step_delay_mode; // enum uint8_t waterfall; // enum #ifdef __LEVEL_METER__ @@ -1767,7 +1771,7 @@ enum { #define MEASUREMENT_TEXT "OFF","IMD","OIP3","PN","SNR","PASS","LIN","AM","FM","THD","CP","NF T","NF S","NF V","NF A","GUARD","DECONF" enum { - T_AUTO, T_NORMAL, T_SINGLE, T_DONE, T_UP, T_DOWN, T_MODE, T_PRE, T_POST, T_MID + T_AUTO, T_NORMAL, T_SINGLE, T_DONE, T_UP, T_DOWN, T_MODE, T_PRE, T_POST, T_MID, T_BEEP, }; //!!! Warning can show not correct results on CH_CFG_ST_FREQUENCY not round by 1000 or > 1000000UL diff --git a/sa_core.c b/sa_core.c index 7d3eee2..c773c9d 100644 --- a/sa_core.c +++ b/sa_core.c @@ -4906,7 +4906,13 @@ static bool sweep(bool break_on_operation) set_audio_mode(A_DAC); } #endif - +#ifdef __BEEP__ + if (setting.trigger_beep && setting.trigger != T_AUTO) { + set_audio_mode(A_PWM); pwm_stop(); + } + else + set_audio_mode(A_DAC); +#endif setting.measure_sweep_time_us = 0; // start measure sweep time // start_of_sweep_timestamp = chVTGetSystemTimeX(); // Will be set in perform @@ -5239,6 +5245,13 @@ static volatile int dummy; if (setting.measurement == M_GUARD && RSSI > setting.guards[current_guard].level) { pwm_start(4000); } +#endif +#ifdef __BEEP__ + if (setting.trigger != T_AUTO && setting.frequency_step > 0) { // Trigger active + if (setting.trigger_beep && RSSI >= setting.trigger_level) { + pwm_start(4000); + } + } #endif for (int t=0; tparam_1.text = mode_text[setting.trigger_mode - T_PRE]; } else if (data == T_UP || data == T_DOWN) b->icon = setting.trigger_direction == data ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP; +#ifdef __BEEP__ + else if (data == T_BEEP) + b->icon = setting.trigger_beep ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK; +#endif else b->icon = setting.trigger == data ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP; return; @@ -3438,7 +3442,11 @@ static UI_FUNCTION_ADV_CALLBACK(menu_trigger_acb) if (setting.trigger_mode > T_MID) setting.trigger_mode = T_PRE; set_trigger(setting.trigger_mode); - } else if (data != T_DONE) { +#ifdef __BEEP__ + } else if (data == T_BEEP) { + setting.trigger_beep = !setting.trigger_beep; +#endif + } else if (data != T_DONE) { set_trigger(data); // menu_move_back(false); ui_mode_normal(); @@ -4720,8 +4728,11 @@ static const menuitem_t menu_trigger[] = { { MT_KEYPAD, KM_TRIGGER, "TRIGGER LEV\n\b%s", NULL}, { MT_ADV_CALLBACK, T_UP, "UP\nEDGE", menu_trigger_acb}, { MT_ADV_CALLBACK, T_DOWN, "DOWN\nEDGE", menu_trigger_acb}, - { MT_ADV_CALLBACK, T_MODE, "%s\nTRIGGER", menu_trigger_acb}, + { MT_ADV_CALLBACK, T_MODE, "TRIGGER\n\b%s", menu_trigger_acb}, { MT_KEYPAD, KM_TRIGGER_GRID, "INTERVAL\n\b%ss", NULL}, +#ifdef __BEEP__ + { MT_ADV_CALLBACK, T_BEEP, "BEEP", menu_trigger_acb}, +#endif { MT_NONE, 0, NULL, menu_back} // next-> menu_back }; From 14250c2b99e4135a5df68f2ca7838fee81d87244 Mon Sep 17 00:00:00 2001 From: erikkaashoek Date: Fri, 24 Feb 2023 13:28:47 +0100 Subject: [PATCH 5/5] Completed --- halconf.h | 4 ++ main.c | 2 +- nanovna.h | 27 ++++---- plot.c | 10 --- sa_core.c | 81 +++++++++++------------- ui.c | 171 +++++++++++++++++++++++++++----------------------- vna_browser.c | 38 +++++++++++ 7 files changed, 185 insertions(+), 148 deletions(-) diff --git a/halconf.h b/halconf.h index c42c81f..e8caf3b 100644 --- a/halconf.h +++ b/halconf.h @@ -115,7 +115,11 @@ * @brief Enables the PWM subsystem. */ #if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#ifdef TINYSA_F303 #define HAL_USE_PWM TRUE +#else +#define HAL_USE_PWM FALSE +#endif #endif /** diff --git a/main.c b/main.c index 25591b5..7a922d9 100644 --- a/main.c +++ b/main.c @@ -2579,7 +2579,6 @@ void pwm_stop(void) { pwmDisableChannel(&PWM_TIMER, PWM_CHANNEL); } -#endif static uint16_t audio_mode = A_DAC; @@ -2597,6 +2596,7 @@ void set_audio_mode(uint16_t new_mode) } audio_mode = new_mode; } +#endif static const GPTConfig gpt4cfg = { 8000000, // 8 MHz timer clock. diff --git a/nanovna.h b/nanovna.h index 84be038..c4b7908 100644 --- a/nanovna.h +++ b/nanovna.h @@ -18,7 +18,7 @@ */ #include "ch.h" -//#ifdef TINYSA_F303 +#ifdef TINYSA_F303 #ifdef TINYSA_F072 #error "Remove comment for #ifdef TINYSA_F303" #endif @@ -26,7 +26,7 @@ #define TINYSA4 #endif #define TINYSA4_PROTO -//#endif +#endif #ifdef TINYSA_F072 #ifdef TINYSA_F303 @@ -88,8 +88,9 @@ #define __MCU_CLOCK_SHIFT__ #endif #ifdef TINYSA4 -#define __GUARD__ +#define __BANDS__ #define __BEEP__ +#define __MULTI_BAND__ #define __MCU_CLOCK_SHIFT__ #define __ULTRA__ #define __USE_RTC__ // Enable RTC clock @@ -120,7 +121,7 @@ //#define __USE_FREQ_TABLE__ // Enable use table for frequency list #endif -#ifdef __GUARD__ +#ifdef __BANDS__ #define __PWM__ #endif @@ -350,8 +351,8 @@ enum { A_DAC, A_PWM }; void set_audio_mode(uint16_t new_mode); void pwm_start(int f); void pwm_stop(void); -#ifdef __GUARD__ -void reset_guard(void); +#ifdef __BANDS__ +void reset_band(void); #endif #endif @@ -1158,14 +1159,14 @@ void spi_init(void); * flash.c */ -#ifdef __GUARD__ -#define GUARDS_MAX 8 +#ifdef __BANDS__ +#define BANDS_MAX 8 typedef struct { bool enabled; freq_t start; freq_t end; float level; -} guard_t; +} band_t; #endif @@ -1183,8 +1184,8 @@ typedef struct setting bool pulse; // bool bool stored[TRACES_MAX]; // enum bool normalized[TRACES_MAX]; // enum -#ifdef __GUARD__ - guard_t guards[GUARDS_MAX]; +#ifdef __BANDS__ + band_t bands[BANDS_MAX]; #endif uint8_t mode; // enum @@ -1766,9 +1767,9 @@ void interpolate_maximum(int m); void calibrate_modulation(int modulation, int8_t *correction); enum { - M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_SNR, M_PASS_BAND, M_LINEARITY, M_AM, M_FM, M_THD, M_CP, M_NF_TINYSA, M_NF_STORE, M_NF_VALIDATE, M_NF_AMPLIFIER, M_GUARD, M_DECONV,M_MAX + M_OFF, M_IMD, M_OIP3, M_PHASE_NOISE, M_SNR, M_PASS_BAND, M_LINEARITY, M_AM, M_FM, M_THD, M_CP, M_NF_TINYSA, M_NF_STORE, M_NF_VALIDATE, M_NF_AMPLIFIER, M_BANDS, M_DECONV,M_MAX }; -#define MEASUREMENT_TEXT "OFF","IMD","OIP3","PN","SNR","PASS","LIN","AM","FM","THD","CP","NF T","NF S","NF V","NF A","GUARD","DECONF" +#define MEASUREMENT_TEXT "OFF","IMD","OIP3","PN","SNR","PASS","LIN","AM","FM","THD","CP","NF T","NF S","NF V","NF A","MULTI","DECONF" enum { T_AUTO, T_NORMAL, T_SINGLE, T_DONE, T_UP, T_DOWN, T_MODE, T_PRE, T_POST, T_MID, T_BEEP, diff --git a/plot.c b/plot.c index 33bfcee..f0e84da 100644 --- a/plot.c +++ b/plot.c @@ -1116,16 +1116,6 @@ draw_cell(int m, int n) if ((uint32_t)(x + x0 - CELLOFFSETX) <= WIDTH + CELLOFFSETX) cell_buffer[tp * CELLWIDTH + x] = c; } -#ifdef __GUARD__XX - if (setting.measurement == M_GUARD) { - int tp = get_guard_level() - y0; - if (tp>=0 && tp < h) - for (x = 0; x < w; x++) - if ((uint32_t)(x + x0 - CELLOFFSETX) <= WIDTH + CELLOFFSETX) - cell_buffer[tp * CELLWIDTH + x] = c; - - } -#endif #if 1 // Only right cells if (m >= (GRID_X_TEXT)/CELLWIDTH) diff --git a/sa_core.c b/sa_core.c index c773c9d..f4f68b5 100644 --- a/sa_core.c +++ b/sa_core.c @@ -18,7 +18,7 @@ #include "si4432.h" // comment out for simulation //#endif #include "stdlib.h" -#define TINYSA4 +//#define TINYSA4 #pragma GCC push_options #ifdef TINYSA4 @@ -67,8 +67,8 @@ freq_t maxFreq = 520000000; static float old_a = -150; // cached value to reduce writes to level registers int spur_gate = 100; -#ifdef __GUARD__ -uint16_t current_guard = 0; +#ifdef __BANDS__ +uint16_t current_band = 0; #endif #ifdef __ULTRA__ @@ -1409,11 +1409,6 @@ void limits_update(void) } #endif -#ifdef __GUARD__ -void guards_update(void) { -} -#endif - void copy_trace(int f, int t) { if (f == t) @@ -4798,11 +4793,11 @@ again: // Spur redu static uint8_t low_count = 0; static uint8_t sweep_counter = 0; // Only used for HW refresh -#ifdef __GUARD__ -static int last_guard = -1; +#ifdef __BANDS__ +static int last_band = -1; -void reset_guard(void) { - last_guard = -1; +void reset_band(void) { + last_band = -1; } #endif @@ -4881,34 +4876,38 @@ static bool sweep(bool break_on_operation) #ifdef __MARKER_CACHE__ clear_marker_cache(); #endif + uint16_t triggered = false; again: // Waiting for a trigger jumps back to here -#ifdef __GUARD__ - if (setting.measurement == M_GUARD) { +#ifdef __BANDS__ + if (setting.measurement == M_BANDS) { do { - current_guard++; - if (current_guard > GUARDS_MAX) - current_guard = 0; - } - while(!(setting.guards[current_guard].enabled)); - if (setting.guards[current_guard].end > setting.guards[current_guard].start && last_guard != current_guard) { - last_guard = current_guard; - set_sweep_frequency(ST_START, setting.guards[current_guard].start); - set_sweep_frequency(ST_STOP, setting.guards[current_guard].end); + current_band++; + if (current_band > BANDS_MAX) + current_band = 0; + } + while(!(setting.bands[current_band].enabled)); + if (setting.bands[current_band].end > setting.bands[current_band].start && last_band != current_band) { + last_band = current_band; + set_sweep_frequency(ST_START, setting.bands[current_band].start); + set_sweep_frequency(ST_STOP, setting.bands[current_band].end); set_step_delay(SD_FAST); set_rbw(8000); - set_sweep_points((setting.guards[current_guard].end - setting.guards[current_guard].start) / 800000); + set_sweep_points((setting.bands[current_band].end - setting.bands[current_band].start) / 800000); + setting.trigger_level = setting.bands[current_band].level; + setting.auto_attenuation = false; } set_audio_mode(A_PWM); pwm_stop(); } else { - last_guard = -1; + last_band = -1; set_audio_mode(A_DAC); } #endif #ifdef __BEEP__ - if (setting.trigger_beep && setting.trigger != T_AUTO) { - set_audio_mode(A_PWM); pwm_stop(); + if (setting.trigger_beep) { + set_audio_mode(A_PWM); + pwm_stop(); } else set_audio_mode(A_DAC); @@ -5241,18 +5240,13 @@ static volatile int dummy; #endif if (MODE_INPUT(setting.mode)) { -#ifdef __GUARD__ - if (setting.measurement == M_GUARD && RSSI > setting.guards[current_guard].level) { - pwm_start(4000); - } -#endif + if (RSSI >= setting.trigger_level) { + triggered = true; #ifdef __BEEP__ - if (setting.trigger != T_AUTO && setting.frequency_step > 0) { // Trigger active - if (setting.trigger_beep && RSSI >= setting.trigger_level) { - pwm_start(4000); - } - } + if (setting.trigger_beep) pwm_start(4000); #endif + } + for (int t=0; t 0) { // Trigger active - if (measured[peakTrace][peakIndex] < setting.trigger_level) { +// if (measured[peakTrace][peakIndex] < setting.trigger_level) { + if (!triggered) { goto again; // not yet, sweep again } else { if (setting.trigger == T_SINGLE) { @@ -5558,7 +5547,8 @@ static volatile int dummy; } else if (actual_max_level > target_level && setting.attenuate_x2 < 60) { delta = actual_max_level - target_level; } - if ((chVTGetSystemTimeX() - sweep_elapsed > MS2ST(1000) && ( delta < -5 || delta > +5)) || delta > 10 ) { + if (chVTGetSystemTimeX() - sweep_elapsed > MS2ST(1000)){ + if (( delta < -5 || delta > +5) || delta > 10 ) { setting.attenuate_x2 += delta + delta; if (setting.attenuate_x2 < 0) setting.attenuate_x2 = 0; @@ -5566,6 +5556,7 @@ static volatile int dummy; setting.attenuate_x2 = 60; changed = true; sweep_elapsed = chVTGetSystemTimeX(); + } } // Try update settings diff --git a/ui.c b/ui.c index 8ce6e0d..284bab7 100644 --- a/ui.c +++ b/ui.c @@ -1333,8 +1333,8 @@ enum { #ifdef __LIMITS__ KM_LIMIT_FREQ, KM_LIMIT_LEVEL, #endif -#ifdef __GUARD__ - KM_GUARD_START, KM_GUARD_END, KM_GUARD_LEVEL, +#ifdef __BANDS__ + KM_BAND_START, KM_BAND_END, KM_BAND_LEVEL, #endif KM_MARKER_TIME, // #35 @@ -1416,10 +1416,10 @@ static const struct { [KM_LIMIT_FREQ] = {keypads_freq , "FREQ"}, // KM_LIMIT_FREQ [KM_LIMIT_LEVEL] = {keypads_plusmin_unit , "LEVEL"}, // KM_LIMIT_LEVEL #endif -#ifdef __GUARD__ -[KM_GUARD_START] = {keypads_freq , "START\nFREQ"}, // KM_GUARD_START -[KM_GUARD_END] = {keypads_freq , "END\nFREQ"}, // KM_GUARD_END -[KM_GUARD_LEVEL] = {keypads_plusmin_unit , "LEVEL"}, // KM_GUARD_LEVEL +#ifdef __BANDS__ +[KM_BAND_START] = {keypads_freq , "START\nFREQ"}, // KM_BAND_START +[KM_BAND_END] = {keypads_freq , "END\nFREQ"}, // KM_BAND_END +[KM_BAND_LEVEL] = {keypads_plusmin_unit , "LEVEL"}, // KM_BAND_LEVEL #endif [KM_MARKER_TIME] = {keypads_time , "MARKER\nTIME"}, // KM_MARKER_TIME [KM_VAR] = {keypads_freq , "JOG\nSTEP"}, // jog step @@ -1467,9 +1467,9 @@ static const menuitem_t menu_subtract_trace[]; static const menuitem_t menu_limit_modify[]; static const menuitem_t menu_limit_select[]; #endif -#ifdef __GUARD__ -static const menuitem_t menu_guard_modify[]; -static const menuitem_t menu_guard_select[]; +#ifdef __BANDS__ +static const menuitem_t menu_BAND_modify[]; +static const menuitem_t menu_BAND_select[]; #endif static const menuitem_t menu_average[]; static const menuitem_t menu_reffer[]; @@ -2874,9 +2874,9 @@ validate: } break; #endif -#ifdef __GUARD__ - case M_GUARD: - menu_push_submenu(menu_guard_select); +#ifdef __BANDS__ + case M_BANDS: + menu_push_submenu(menu_BAND_select); goto leave; break; #endif @@ -3182,25 +3182,25 @@ static UI_FUNCTION_ADV_CALLBACK(menu_limit_select_acb) #endif -#ifdef __GUARD__ -uint8_t active_guard = 0; -static UI_FUNCTION_ADV_CALLBACK(menu_guard_select_acb) +#ifdef __BANDS__ +uint8_t active_band = 0; +static UI_FUNCTION_ADV_CALLBACK(menu_band_select_acb) { (void)item; if(b){ int count = 0; - for (int i=0;iicon = (setting.guards[data].enabled?BUTTON_ICON_CHECK:BUTTON_ICON_NOCHECK) ; - plot_printf(b->text, sizeof(b->text), "%.6FHz\n%.6FHz", (float)setting.guards[data].start, (float)setting.guards[data].end); - reset_guard(); + for (int i=0;iicon = (setting.bands[data].enabled?BUTTON_ICON_CHECK:BUTTON_ICON_NOCHECK) ; + plot_printf(b->text, sizeof(b->text), "%.6FHz\n%.6FHz", (float)setting.bands[data].start, (float)setting.bands[data].end); + reset_band(); return; } - active_guard = data; - setting.guards[active_guard].enabled = true; + active_band = data; + setting.bands[active_band].enabled = true; dirty = true; -// guards_update(); - menu_push_submenu(menu_guard_modify); +// BANDs_update(); + menu_push_submenu(menu_BAND_modify); } #endif @@ -3328,22 +3328,22 @@ static UI_FUNCTION_CALLBACK(menu_limit_disable_cb) #endif -#ifdef __GUARD__ -static UI_FUNCTION_CALLBACK(menu_guard_disable_cb) +#ifdef __BANDS__ +static UI_FUNCTION_CALLBACK(menu_BAND_disable_cb) { (void)item; (void)data; int count = 0; - for (int i=0;iparam_1.text = mode_text[setting.trigger_mode - T_PRE]; - } else if (data == T_UP || data == T_DOWN) + else if (data == T_UP || data == T_DOWN) +#if 0 b->icon = setting.trigger_direction == data ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP; +#else + b->param_1.text = setting.trigger_direction == T_UP ? "UP" : "DOWN"; +#endif #ifdef __BEEP__ else if (data == T_BEEP) b->icon = setting.trigger_beep ? BUTTON_ICON_CHECK : BUTTON_ICON_NOCHECK; @@ -3446,10 +3450,15 @@ static UI_FUNCTION_ADV_CALLBACK(menu_trigger_acb) } else if (data == T_BEEP) { setting.trigger_beep = !setting.trigger_beep; #endif - } else if (data != T_DONE) { - set_trigger(data); + } else if (data == T_UP || data == T_DOWN) { + if (setting.trigger_direction == T_UP) + setting.trigger_direction = T_DOWN; + else + setting.trigger_direction = T_UP; + } else if (data != T_DONE) { + set_trigger(data); // menu_move_back(false); - ui_mode_normal(); + ui_mode_normal(); } completed = true; } @@ -3869,8 +3878,8 @@ enum { FMT_CFG_FILE, FMT_PRS_FILE, FMT_TBL_FILE, -#ifdef __GUARD__ - FMT_GRD_FILE, +#ifdef __BANDS__ + FMT_BND_FILE, #endif }; @@ -3885,7 +3894,7 @@ static const char *file_ext[] = { [FMT_CFG_FILE] = "cfg", [FMT_PRS_FILE] = "prs", [FMT_TBL_FILE] = "tbl", - [FMT_GRD_FILE] = "grd", + [FMT_BND_FILE] = "bnd", }; static void sa_save_file(uint8_t format); @@ -4148,22 +4157,22 @@ static const menuitem_t menu_limit_select[] = { }; #endif -#ifdef __GUARD__ -static const menuitem_t menu_guard_modify[] = +#ifdef __BANDS__ +static const menuitem_t menu_BAND_modify[] = { - { MT_KEYPAD, KM_GUARD_START, "START\n\b%s", "Start"}, - { MT_KEYPAD, KM_GUARD_END, "END\n\b%s", "End"}, - { MT_KEYPAD, KM_GUARD_LEVEL, "LEVEL\n\b%s", "Level"}, - { MT_CALLBACK,0, "DISABLE", menu_guard_disable_cb}, + { MT_KEYPAD, KM_BAND_START, "START\n\b%s", "Start"}, + { MT_KEYPAD, KM_BAND_END, "END\n\b%s", "End"}, + { MT_KEYPAD, KM_BAND_LEVEL, "LEVEL\n\b%s", "Level"}, + { MT_CALLBACK,0, "DISABLE", menu_BAND_disable_cb}, { MT_NONE, 0, NULL, menu_back} // next-> menu_back }; -static const menuitem_t menu_guard_select[] = { - { MT_ADV_CALLBACK | MT_REPEATS, DATA_STARTS_REPEATS(0,GUARDS_MAX), MT_CUSTOM_LABEL, menu_guard_select_acb }, +static const menuitem_t menu_BAND_select[] = { + { MT_ADV_CALLBACK | MT_REPEATS, DATA_STARTS_REPEATS(0,BANDS_MAX), MT_CUSTOM_LABEL, menu_band_select_acb }, #ifdef __USE_SD_CARD__ - { MT_CALLBACK, FMT_GRD_FILE, "GUARD"S_RARROW"\nSD", menu_sdcard_cb}, + { MT_CALLBACK, FMT_BND_FILE, "BANDS"S_RARROW"\nSD", menu_sdcard_cb}, #ifdef __SD_FILE_BROWSER__ - { MT_CALLBACK, FMT_GRD_FILE, "SD"S_RARROW"\nGUARD", menu_sdcard_browse_cb }, + { MT_CALLBACK, FMT_BND_FILE, "SD"S_RARROW"\nBANDS", menu_sdcard_browse_cb }, #endif #endif { MT_NONE, 0, NULL, menu_back} // next-> menu_back @@ -4500,8 +4509,8 @@ static const menuitem_t menu_measure2[] = { #ifdef __NOISE_FIGURE__ { MT_SUBMENU | MT_LOW, 0, "NOISE\nFIGURE", menu_measure_noise_figure}, #endif -#ifdef __GUARD__ -{ MT_ADV_CALLBACK, M_GUARD, "GUARD", menu_measure_acb}, +#ifdef __BANDS__ +{ MT_ADV_CALLBACK, M_BANDS, "MULTI\nBAND", menu_measure_acb}, #endif #ifdef __FFT_DECONV__ { MT_ADV_CALLBACK, M_DECONV, "DECONV", menu_measure_acb}, @@ -4725,9 +4734,13 @@ static const menuitem_t menu_trigger[] = { { MT_ADV_CALLBACK, T_NORMAL, "NORMAL", menu_trigger_acb}, { MT_ADV_CALLBACK, T_SINGLE, "SINGLE", menu_trigger_acb}, // { MT_ADV_CALLBACK, T_DONE, "READY", menu_trigger_acb}, - { MT_KEYPAD, KM_TRIGGER, "TRIGGER LEV\n\b%s", NULL}, - { MT_ADV_CALLBACK, T_UP, "UP\nEDGE", menu_trigger_acb}, - { MT_ADV_CALLBACK, T_DOWN, "DOWN\nEDGE", menu_trigger_acb}, + { MT_KEYPAD, KM_TRIGGER, "LEVEL\n\b%s", NULL}, +#if 0 + { MT_ADV_CALLBACK, T_UP, "EDGE\nUP", menu_trigger_acb}, + { MT_ADV_CALLBACK, T_DOWN, "EDGE\nDOWN", menu_trigger_acb}, +#else + { MT_ADV_CALLBACK, T_UP, "EDGE\n\b%s", menu_trigger_acb}, +#endif { MT_ADV_CALLBACK, T_MODE, "TRIGGER\n\b%s", menu_trigger_acb}, { MT_KEYPAD, KM_TRIGGER_GRID, "INTERVAL\n\b%ss", NULL}, #ifdef __BEEP__ @@ -4999,17 +5012,17 @@ static void fetch_numeric_target(uint8_t mode) plot_printf(uistat.text, sizeof uistat.text, "%.1f", uistat.value); break; #endif -#ifdef __GUARD__ - case KM_GUARD_START: - uistat.freq_value = setting.guards[active_guard].start; +#ifdef __BANDS__ + case KM_BAND_START: + uistat.freq_value = setting.bands[active_band].start; plot_printf(uistat.text, sizeof uistat.text, "%.3QHz", uistat.freq_value); break; - case KM_GUARD_END: - uistat.freq_value = setting.guards[active_guard].end; + case KM_BAND_END: + uistat.freq_value = setting.bands[active_band].end; plot_printf(uistat.text, sizeof uistat.text, "%.3QHz", uistat.freq_value); break; - case KM_GUARD_LEVEL: - uistat.value = value(setting.guards[active_guard].level); + case KM_BAND_LEVEL: + uistat.value = value(setting.bands[active_band].level); plot_printf(uistat.text, sizeof uistat.text, "%.1f", uistat.value); break; #endif @@ -5238,21 +5251,21 @@ set_numeric_value(void) limits_update(); break; #endif -#ifdef __GUARD__ - case KM_GUARD_START: - setting.guards[active_guard].start = uistat.freq_value - (setting.frequency_offset - FREQUENCY_SHIFT); +#ifdef __BANDS__ + case KM_BAND_START: + setting.bands[active_band].start = uistat.freq_value - (setting.frequency_offset - FREQUENCY_SHIFT); dirty = true; -// guards_update(); +// BANDs_update(); break; - case KM_GUARD_END: - setting.guards[active_guard].end = uistat.freq_value - (setting.frequency_offset - FREQUENCY_SHIFT); + case KM_BAND_END: + setting.bands[active_band].end = uistat.freq_value - (setting.frequency_offset - FREQUENCY_SHIFT); dirty = true; -// guards_update(); +// BANDs_update(); break; - case KM_GUARD_LEVEL: - setting.guards[active_guard].level = to_dBm(uistat.value); + case KM_BAND_LEVEL: + setting.bands[active_band].level = to_dBm(uistat.value); dirty = true; -// guards_update(); +// BANDs_update(); break; #endif case KM_NOISE: @@ -5705,7 +5718,7 @@ redraw_cal_status: y += YSTEP; if (rounding) - lcd_printf(x, y, "%6.3f", value(setting.trigger_level)); + lcd_printf(x, y, "%6.1f", value(setting.trigger_level)); else lcd_printf(x, y, "%6.4F", value(setting.trigger_level)); // lcd_printf(x, y, "%4f", value(setting.trigger_level)/setting.unit_scale); @@ -7233,14 +7246,14 @@ static void sa_save_file(uint8_t format) { } } break; -#ifdef __GUARD__ - case FMT_GRD_FILE: - for (i = 0; i < GUARDS_MAX && res == FR_OK; i++) { - if (setting.guards[i].enabled) { +#ifdef __BANDS__ + case FMT_BND_FILE: + for (i = 0; i < BANDS_MAX && res == FR_OK; i++) { + if (setting.bands[i].enabled) { char *buf = (char *)spi_buffer; - buf += plot_printf(buf, 100, "%U, ", setting.guards[i].start); - buf += plot_printf(buf, 100, "%U, ", setting.guards[i].end); - buf += plot_printf(buf, 100, "%f ", setting.guards[i].level); + buf += plot_printf(buf, 100, "%U, ", setting.bands[i].start); + buf += plot_printf(buf, 100, "%U, ", setting.bands[i].end); + buf += plot_printf(buf, 100, "%f ", setting.bands[i].level); buf += plot_printf(buf, 100, "\r\n"); res = f_write(fs_file, (char *)spi_buffer, buf - (char *)spi_buffer, &size); } diff --git a/vna_browser.c b/vna_browser.c index b53635f..fc07995 100644 --- a/vna_browser.c +++ b/vna_browser.c @@ -147,6 +147,44 @@ finish2: } break; } +#ifdef __BANDS__ + case FMT_BND_FILE: + { + const int buffer_size = 256; + const int line_size = 128; + char *buf_8 = (char *)spi_buffer; // must be greater then buffer_size + line_size + char *line = buf_8 + buffer_size; + uint16_t j = 0, i, count = 0; + while (f_read(fs_file, buf_8, buffer_size, &size) == FR_OK && size > 0) { + for (i = 0; i < size; i++) { + uint8_t c = buf_8[i]; + if (c == '\r') { // New line (Enter) + line[j] = 0; j = 0; + char *args[16]; + int nargs = parse_line(line, args, 16); // Parse line to 16 args + if (nargs < 2 || args[0][0] == '#' || args[0][0] == '!') continue; // No data or comment or settings + if (count >= BANDS_MAX) {error = "Format err"; goto finish3;} + setting.bands[count].start = my_atoui(args[0]);// Get frequency + setting.bands[count].end = my_atoui(args[1]);// Get frequency + setting.bands[count].level = my_atof(args[2]); // Get frequency + setting.bands[count].enabled = true; // Get frequency + count++; + } + else if (c < 0x20) continue; // Others (skip) + else if (j < line_size) line[j++] = (char)c; // Store + } + } +finish3: + for (; count < BANDS_MAX; i++) { + setting.bands[count].start = 0; + setting.bands[count].end = 0; + setting.bands[count].level = 0; + setting.bands[count].enabled = false; + count++; + } + break; + } +#endif case FMT_CSV_FILE: { const int buffer_size = 256;