diff --git a/nanovna.h b/nanovna.h index e393870..589db6b 100644 --- a/nanovna.h +++ b/nanovna.h @@ -138,7 +138,7 @@ enum { }; enum { - MO_NONE, MO_AM, MO_NFM, MO_WFM, MO_EXTERNAL, + MO_NONE, MO_AM_1kHz, MO_AM_10Hz, MO_NFM, MO_WFM, MO_EXTERNAL, }; #define MODE_OUTPUT(x) ((x) == M_GENLOW || (x) == M_GENHIGH ) @@ -348,6 +348,7 @@ enum unit_type { U_DBM=0, U_DBMV, U_DBUV, U_MVOLT, U_UVOLT, U_MWATT, U_UWATT }; #define UNIT_IS_LINEAR(T) ( T >= U_MVOLT ? true : false) +#define UNIT_IS_LOG(T) ( T >= U_MVOLT ? false : true) float value(float); @@ -580,13 +581,20 @@ typedef struct setting float level_sweep; float sweep_time; int test_argument; + int auto_IF; uint32_t checksum; }setting_t; extern setting_t setting; + extern int setting_frequency_10mhz; void reset_settings(int m); + +#define S_IS_AUTO(x) ((x)&2) +#define S_STATE(X) ((X)&1) +enum { S_OFF=0, S_ON=1, S_AUTO_OFF=2, S_AUTO_ON=3 }; + extern uint32_t frequencies[POINTS_COUNT]; #if 1 diff --git a/sa_cmd.c b/sa_cmd.c index cb814ed..75c97ac 100644 --- a/sa_cmd.c +++ b/sa_cmd.c @@ -35,13 +35,15 @@ VNA_SHELL_FUNCTION(cmd_modulation ) { if (argc != 1) { usage: - shell_printf("usage: modulation off|AM|NFM|WFM|extern\r\n"); + shell_printf("usage: modulation off|AM_1kHz|AM_10Hz|NFM|WFM|extern\r\n"); return; } int m = MO_NONE; if (strcmp(argv[0],"off") == 0) { - } else if (strcmp(argv[0],"AM") == 0) { - m = MO_AM; + } else if (strcmp(argv[0],"AM_1kHz") == 0) { + m = MO_AM_1kHz; + } else if (strcmp(argv[0],"AM_10Hz") == 0) { + m = MO_AM_10Hz; } else if (strcmp(argv[0],"NFM") == 0) { m = MO_NFM; } else if (strcmp(argv[0],"WFM") == 0) { diff --git a/sa_core.c b/sa_core.c index dc65419..60784cb 100644 --- a/sa_core.c +++ b/sa_core.c @@ -32,8 +32,8 @@ void reset_settings(int m) setting.subtract_stored = 0; setting.drive=13; setting.step_atten = 0; // Only used in low output mode - setting.agc = true; - setting.lna = false; + setting.agc = S_AUTO_ON; + setting.lna = S_AUTO_OFF; setting.tracking = false; setting.modulation = MO_NONE; setting.step_delay = 0; @@ -41,11 +41,12 @@ void reset_settings(int m) setting.auto_reflevel = true; // Must be after SetReflevel setting.decay=20; setting.noise=5; - setting.below_IF = false; + setting.below_IF = S_AUTO_OFF; setting.repeat = 1; setting.tracking_output = false; setting.measurement = M_OFF; setting.frequency_IF = 433800000; + setting.auto_IF = true; setting.offset = 0.0; setting.trigger = T_AUTO; setting.level_sweep = 0.0; @@ -189,9 +190,15 @@ void toggle_tracking_output(void) setting.tracking_output = !setting.tracking_output; dirty = true; } + void toggle_below_IF(void) { - setting.below_IF = !setting.below_IF; + if (S_IS_AUTO(setting.below_IF )) + setting.below_IF = false; + else if (setting.below_IF) + setting.below_IF = S_AUTO_OFF; + else + setting.below_IF = true; dirty = true; } @@ -436,7 +443,12 @@ int GetAverage(void) void toggle_LNA(void) { - setting.lna = !setting.lna; + if (S_IS_AUTO(setting.lna )) + setting.lna = false; + else if (setting.lna) + setting.lna = S_AUTO_OFF; + else + setting.lna = true; dirty = true; } @@ -458,7 +470,12 @@ int GetLNA(void) void toggle_AGC(void) { - setting.agc = !setting.agc; + if (S_IS_AUTO(setting.agc )) + setting.agc = false; + else if (setting.agc) + setting.agc = S_AUTO_OFF; + else + setting.agc = true; dirty = true; } @@ -485,10 +502,18 @@ void set_unit(int u) r = REFLEVEL_MAX; // Maximum value set_scale(r/NGRIDY); set_reflevel(setting.scale*NGRIDY); + if (S_IS_AUTO(setting.agc)) + setting.agc = S_AUTO_OFF; + if (S_IS_AUTO(setting.lna)) + setting.agc = S_AUTO_OFF; } else { r = 10 * round((r*1.2)/10.0); set_reflevel(r); set_scale(10); + if (S_IS_AUTO(setting.agc)) + setting.agc = S_AUTO_ON; + if (S_IS_AUTO(setting.lna)) + setting.agc = S_AUTO_OFF; } dirty = true; } @@ -740,8 +765,8 @@ void set_switch_off(void) { void set_AGC_LNA(void) { unsigned char v = 0x40; - if (setting.agc) v |= 0x20; - if (setting.lna) v |= 0x10; + if (S_STATE(setting.agc)) v |= 0x20; + if (S_STATE(setting.lna)) v |= 0x10; SI4432_Write_Byte(0x69, v); } @@ -1090,19 +1115,19 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) } } - if (setting.mode == M_LOW && setting.auto_attenuation) { + if (setting.mode == M_LOW && S_IS_AUTO(setting.agc) && UNIT_IS_LOG(setting.unit)) { unsigned char v; static unsigned char old_v; if (f < 1500000) v = 0x50; // Disable AGC and enable LNA else - v = 0x60; // Disable AGC and enable LNA + v = 0x60; // Enable AGC and disable LNA if (old_v != v) { SI4432_Write_Byte(0x69, v); old_v = v; } } - if (MODE_OUTPUT(setting.mode) && setting.modulation == MO_AM) { // AM modulation + if (MODE_OUTPUT(setting.mode) && (setting.modulation == MO_AM_1kHz||setting.modulation == MO_AM_10Hz)) { // AM modulation int p = setting.attenuate * 2 + am_modulation[modulation_counter]; PE4302_Write_Byte(p); if (modulation_counter == 4) { // 3dB modulation depth @@ -1110,7 +1135,10 @@ float perform(bool break_on_operation, int i, uint32_t f, int tracking) } else { modulation_counter++; } - my_microsecond_delay(200); + if (setting.modulation == MO_AM_10Hz) + my_microsecond_delay(20000); + else + my_microsecond_delay(200); // chThdSleepMicroseconds(200); } else if (MODE_OUTPUT(setting.mode) && (setting.modulation == MO_NFM || setting.modulation == MO_WFM )) { //FM modulation @@ -1170,15 +1198,19 @@ again: local_IF = spur_alternate_IF; #ifdef __SPUR__ } else if (setting.mode== M_LOW && setting.spur){ - if (lf > 150000000) // if above 150MHz use IF shift - local_IF = setting.frequency_IF + (int)(actual_rbw < 350.0 ? setting.spur*300000 : 0 ); - else { // else low/above IF - local_IF = setting.frequency_IF; + if (S_IS_AUTO(setting.below_IF) && lf < 150000000) // if below 150MHz and auto_below_IF swap IF + { // else low/above IF + if (setting.auto_IF) + local_IF = 433900000; + else + local_IF = setting.frequency_IF; if (setting.spur == 1) - setting.below_IF = true; + setting.below_IF = S_AUTO_ON; else - setting.below_IF = false; + setting.below_IF = S_AUTO_OFF; } + else + local_IF = setting.frequency_IF + (int)(actual_rbw < 350.0 ? setting.spur*300000 : 0 ); #endif } else { // local_IF = setting.frequency_IF ; @@ -1224,7 +1256,7 @@ again: set_freq (3, IF_2 - 433800000); // Down from IF2 to fixed second IF in Ultra SA mode set_freq (1, 433800000); // Second IF fixe in Ultra SA mode #else - if (setting.mode == M_LOW && !setting.tracking && setting.below_IF) + if (setting.mode == M_LOW && !setting.tracking && S_STATE(setting.below_IF)) set_freq (1, local_IF-lf); else set_freq (1, local_IF+lf); @@ -1459,7 +1491,7 @@ again: dirty = true; // Must be above if(scandirty!!!!!) } } - if (!in_selftest && MODE_INPUT(setting.mode) && setting.auto_reflevel && max_index[0] > 0) { // Auto reflevel + if (!in_selftest && MODE_INPUT(setting.mode) && setting.auto_reflevel && (max_index[0] > 0 || FREQ_IS_CW())) { // Auto reflevel if (UNIT_IS_LINEAR(setting.unit)) { // Linear scales can not have negative values float r = value(actual_t[max_index[0]]); if ((setting.reflevel > REFLEVEL_MIN && r < setting.reflevel / 2 ) || (setting.reflevel < REFLEVEL_MAX && r > setting.reflevel) ) { // ensure minimum and maximum reflevel @@ -1765,11 +1797,13 @@ void draw_cal_status(void) #define XSTEP 40 + if (MODE_OUTPUT(setting.mode)) { // No cal status during output + ili9341_fill(x, y, OFFSETX-5, HEIGHT, 0x0000); + return; + } ili9341_fill(x, y, OFFSETX, HEIGHT, 0x0000); - if (MODE_OUTPUT(setting.mode)) // No cal status during output - return; -// if (current_menu_is_form() && !in_selftest) + // if (current_menu_is_form() && !in_selftest) // return; ili9341_set_background(DEFAULT_BG_COLOR); @@ -1791,8 +1825,13 @@ void draw_cal_status(void) ili9341_set_foreground(color); ili9341_drawstring(buf, x, y); + color = DEFAULT_FG_COLOR; ili9341_set_foreground(color); + if (setting.auto_reflevel){ + y += YSTEP + YSTEP/2 ; + ili9341_drawstring("AUTO", x, y); + } y += YSTEP + YSTEP/2 ; plot_printf(buf, BLEN, "%s",unit); ili9341_drawstring(buf, x, y); @@ -1927,6 +1966,17 @@ void draw_cal_status(void) ili9341_drawstring(buf, x, y); } + if (setting.repeat != 1) { + ili9341_set_foreground(BRIGHT_COLOR_GREEN); + y += YSTEP + YSTEP/2 ; + ili9341_drawstring("Repeat:", x, y); + + y += YSTEP; + plot_printf(buf, BLEN, "%d",setting.repeat); + buf[6]=0; + ili9341_drawstring(buf, x, y); + } + if (setting.trigger != T_AUTO) { if (is_paused()) { ili9341_set_foreground(BRIGHT_COLOR_GREEN); @@ -1945,6 +1995,7 @@ void draw_cal_status(void) ili9341_drawstring(buf, x, y); } + if (level_is_calibrated()) color = BRIGHT_COLOR_GREEN; else @@ -1956,6 +2007,31 @@ void draw_cal_status(void) else ili9341_drawstring_7x13("HIGH", x, y); +// ili9341_set_background(DEFAULT_FG_COLOR); + ili9341_set_foreground(DEFAULT_FG_COLOR); + y += YSTEP + YSTEP/2 ; + strncpy(buf," ",BLEN); + if (setting.auto_attenuation) + buf[0] = 'a'; + if (setting.auto_IF) + buf[1] = 'i'; + if (setting.auto_reflevel) + buf[2] = 'r'; + if (S_IS_AUTO(setting.agc)) + buf[3] = 'g'; + else if (S_STATE(setting.agc)) + buf[3] = 'G'; + if (S_IS_AUTO(setting.lna)) + buf[4] = 'l'; + else if (S_STATE(setting.lna)) + buf[4] = 'L'; + if (S_IS_AUTO(setting.below_IF)) + buf[5] = 'b'; + else if (S_STATE(setting.below_IF)) + buf[5] = 'B'; + ili9341_drawstring(buf, x, y); + +// ili9341_set_background(DEFAULT_BG_COLOR); y = HEIGHT-7 + OFFSETY; if (rounding) diff --git a/ui_sa.c b/ui_sa.c index 7f8cce7..4f94172 100644 --- a/ui_sa.c +++ b/ui_sa.c @@ -592,14 +592,14 @@ static void menu_dfu_cb(int item, uint8_t data) } -const int menu_modulation_value[]={MO_NONE,MO_AM, MO_NFM, MO_WFM, MO_EXTERNAL}; -const char *menu_modulation_text[]={"NONE","AM","NARROW FM","WIDE FM", "EXTERNAL"}; +// const int menu_modulation_value[]={MO_NONE,MO_AM_1, MO_NFM, MO_WFM, MO_EXTERNAL}; +const char *menu_modulation_text[]={"NONE","AM 1kHz","AM 10Hz","NARROW FM","WIDE FM", "EXTERNAL"}; static void menu_modulation_cb(int item, uint8_t data) { (void)item; //Serial.println(item); - set_modulation(menu_modulation_value[data]); + set_modulation(data); menu_move_back(); // ui_mode_normal(); // Stay in menu mode // draw_cal_status(); @@ -934,21 +934,21 @@ static void menu_settings2_cb(int item, uint8_t data) { (void)item; switch(data) { - case 0: - toggle_AGC(); - break; case 1: - toggle_LNA();; + toggle_AGC(); break; case 2: - toggle_tracking(); + toggle_LNA();; break; case 3: - toggle_tracking_output(); + toggle_tracking(); break; case 4: toggle_below_IF(); break; + case 5: + toggle_tracking_output(); + break; } draw_menu(); // draw_cal_status(); @@ -1065,11 +1065,12 @@ static const menuitem_t menu_drive_wide[] = { const menuitem_t menu_modulation[] = { { MT_FORM | MT_TITLE, 0, "MODULATION",NULL}, - { MT_FORM | MT_CALLBACK, 0, "NONE", menu_modulation_cb}, - { MT_FORM | MT_CALLBACK, 1, "AM", menu_modulation_cb}, - { MT_FORM | MT_CALLBACK, 2, "NARROW FM", menu_modulation_cb}, - { MT_FORM | MT_CALLBACK, 3, "WIDE FM", menu_modulation_cb}, - { MT_FORM | MT_CALLBACK, 4, "EXTERNAL", menu_modulation_cb}, + { MT_FORM | MT_CALLBACK, MO_NONE, "NONE", menu_modulation_cb}, + { MT_FORM | MT_CALLBACK, MO_AM_1kHz, "AM 1kHz", menu_modulation_cb}, + { MT_FORM | MT_CALLBACK, MO_AM_10Hz, "AM 10Hz", menu_modulation_cb}, + { MT_FORM | MT_CALLBACK, MO_NFM, "NARROW FM", menu_modulation_cb}, + { MT_FORM | MT_CALLBACK, MO_WFM, "WIDE FM", menu_modulation_cb}, + { MT_FORM | MT_CALLBACK, MO_EXTERNAL, "EXTERNAL", menu_modulation_cb}, { MT_FORM | MT_CANCEL, 0, S_LARROW" BACK",NULL }, { MT_FORM | MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1280,9 +1281,9 @@ static const menuitem_t menu_scanning_speed[] = static const menuitem_t menu_settings2[] = { - { MT_CALLBACK, 0, "AGC", menu_settings2_cb}, - { MT_CALLBACK, 1, "LNA", menu_settings2_cb}, - { MT_CALLBACK | MT_LOW, 2, "BPF", menu_settings2_cb}, + { MT_CALLBACK, 1, "AGC", menu_settings2_cb}, + { MT_CALLBACK, 2, "LNA", menu_settings2_cb}, + { MT_CALLBACK | MT_LOW, 3, "BPF", menu_settings2_cb}, { MT_CALLBACK | MT_LOW, 4, "\2BELOW\0IF", menu_settings2_cb}, { MT_KEYPAD, KM_DECAY,"\2HOLD\0TIME", NULL}, { MT_KEYPAD, KM_NOISE,"\2NOISE\0LEVEL", NULL}, @@ -1293,7 +1294,7 @@ static const menuitem_t menu_settings2[] = { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; - +#if 0 static const menuitem_t menu_settingshigh2[] = { { MT_CALLBACK, 0, "AGC", menu_settings2_cb}, @@ -1303,10 +1304,11 @@ static const menuitem_t menu_settingshigh2[] = { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; +#endif static const menuitem_t menu_settings[] = { - { MT_CALLBACK | MT_LOW, 3, "\2LO\0OUTPUT",menu_settings2_cb}, + { MT_CALLBACK | MT_LOW, 5, "\2LO\0OUTPUT",menu_settings2_cb}, { MT_KEYPAD, KM_ACTUALPOWER, "\2ACTUAL\0POWER", NULL}, { MT_KEYPAD | MT_LOW, KM_IF, "\2IF\0FREQ", NULL}, { MT_SUBMENU,0, "\2SCAN\0SPEED", menu_scanning_speed}, @@ -1316,7 +1318,7 @@ static const menuitem_t menu_settings[] = { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; - +#if 0 static const menuitem_t menu_settingshigh[] = { { MT_KEYPAD, KM_ACTUALPOWER, "\2ACTUAL\0POWER", NULL}, @@ -1326,7 +1328,7 @@ static const menuitem_t menu_settingshigh[] = { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; - +#endif static const menuitem_t menu_measure[] = { { MT_CALLBACK, M_OFF, "OFF", menu_measure_cb}, { MT_CALLBACK, M_IMD, "HARMONIC", menu_measure_cb}, @@ -1526,6 +1528,7 @@ static void menu_item_modify_attribute( const menuitem_t *menu, int item, uint16_t *fg, uint16_t *bg) { int mark = false; + int m_auto = false; int data = menu[item].data; if (menu == menu_mode) { if (item == GetMode()) { @@ -1608,7 +1611,8 @@ static void menu_item_modify_attribute( } else if (menu == menu_settings) { if (item ==0 && setting.tracking_output){ mark = true; - } + } else if (item == 2 && setting.auto_IF) + m_auto = true; } else if (menu == menu_scanning_speed) { if (item == setting.step_delay){ mark = true; @@ -1618,19 +1622,18 @@ static void menu_item_modify_attribute( if (data == setting.harmonic) mark = true; #endif - } else if (menu == menu_settings2 || menu == menu_settingshigh2) { - if (item ==0 && setting.agc){ - mark = true; + } else if (MT_MASK(menu[item].type) == MT_CALLBACK && menu == menu_settings2) { + int v=0; + switch(data) { + case 1: v = setting.agc; break; + case 2: v = setting.lna; break; + case 3: v = setting.tracking; break; + case 4: v = setting.below_IF; break; } - if (item == 1 && setting.lna){ + if (S_IS_AUTO(v)) + m_auto = true; + else if (v == S_ON) mark = true; - } - if (item == 2 && setting.tracking){ // should not happen in high mode - mark = true; - } - if (item == 3 && setting.below_IF){ // should not happen in high mode - mark = true; - } } else if (menu == menu_marker_modify && active_marker >= 0 && markers[active_marker].enabled == M_ENABLED) { if (data & markers[active_marker].mtype) mark = true; @@ -1655,7 +1658,10 @@ static void menu_item_modify_attribute( if ((item == 0 && setting.auto_attenuation ) || (item == 1 && !setting.auto_attenuation)) mark = true; } - if (mark) { + if (m_auto) { + *bg = LIGHT_GREY; + *fg = config.menu_normal_color; + } else if (mark) { *bg = DEFAULT_MENU_TEXT_COLOR; *fg = config.menu_normal_color; } @@ -1808,7 +1814,8 @@ set_numeric_value(void) break; case KM_IF: set_IF(uistat.value); - config_save(); +// config_save(); + setting.auto_IF = false; break; case KM_SAMPLETIME: set_step_delay(uistat.value);