diff --git a/nanovna.h b/nanovna.h index 3a5e1d2..674c7cb 100644 --- a/nanovna.h +++ b/nanovna.h @@ -215,7 +215,8 @@ int is_paused(void); void set_actual_power(float); void SetGenerate(int); void set_RBW(uint32_t rbw_x10); -void set_drive(int d); +void set_lo_drive(int d); +void set_rx_drive(int d); void set_IF(int f); void set_IF2(int f); void set_R(int f); @@ -739,7 +740,8 @@ typedef struct setting int average; int show_stored; int subtract_stored; - int drive; // 0-7 , 7=+20dBm, 3dB steps + int lo_drive; // 0-3 , 3dB steps + int rx_drive; // 0-15 , 7=+20dBm, 3dB steps int agc; int lna; int auto_reflevel; @@ -790,6 +792,7 @@ typedef struct setting float normalize_level; // Level to set normalize to, zero if not doing anything int modulation_frequency; uint32_t checksum; + int ultra; }setting_t; extern setting_t setting; diff --git a/sa_cmd.c b/sa_cmd.c index 2a4afa7..85c7250 100644 --- a/sa_cmd.c +++ b/sa_cmd.c @@ -460,7 +460,7 @@ VNA_SHELL_FUNCTION(cmd_d) (void) argc; (void) argv; int32_t a = my_atoi(argv[0]); - setting.drive=a; + setting.lo_drive=a; dirty = true; } diff --git a/sa_core.c b/sa_core.c index 61a7509..a7f3e76 100644 --- a/sa_core.c +++ b/sa_core.c @@ -66,7 +66,7 @@ void update_min_max_freq(void) switch(setting.mode) { case M_LOW: minFreq = 0; - maxFreq = DEFAULT_MAX_FREQ; + maxFreq = 3000000000; // DEFAULT_MAX_FREQ; <---------------- TODO break; #ifdef __ULTRA__ case M_ULTRA: @@ -83,8 +83,8 @@ void update_min_max_freq(void) maxFreq = HIGH_MAX_FREQ_MHZ * 1000000; break; case M_GENHIGH: - minFreq = 240000000; - maxFreq = 960000000; + minFreq = 135000000; + maxFreq = 4290000000U; break; } } @@ -108,7 +108,8 @@ void reset_settings(int m) setting.auto_attenuation = false; setting.subtract_stored = 0; setting.normalize_level = 0.0; - setting.drive=13; + setting.lo_drive=1; + setting.rx_drive=13; setting.atten_step = 0; // Only used in low output mode setting.agc = S_AUTO_ON; setting.lna = S_AUTO_OFF; @@ -152,6 +153,7 @@ void reset_settings(int m) setting.attenuate = 0.0; // <---------------- WARNING ----------------- setting.auto_attenuation = false; // <---------------- WARNING ----------------- setting.sweep_time_us = 0; + setting.lo_drive=1; break; #ifdef __ULTRA__ case M_ULTRA: @@ -162,7 +164,8 @@ void reset_settings(int m) break; #endif case M_GENLOW: - setting.drive=8; + setting.rx_drive=8; + setting.lo_drive=1; set_sweep_frequency(ST_CENTER, 10000000); set_sweep_frequency(ST_SPAN, 0); setting.sweep_time_us = 10*ONE_SECOND_TIME; @@ -173,7 +176,7 @@ void reset_settings(int m) setting.sweep_time_us = 0; break; case M_GENHIGH: - setting.drive=8; + setting.lo_drive=1; set_sweep_frequency(ST_CENTER, 300000000); set_sweep_frequency(ST_SPAN, 0); setting.sweep_time_us = 10*ONE_SECOND_TIME; @@ -276,9 +279,15 @@ void set_measurement(int m) } dirty = true; } -void set_drive(int d) +void set_lo_drive(int d) +{ + setting.lo_drive = d; + dirty = true; +} + +void set_rx_drive(int d) { - setting.drive = d; + setting.rx_drive = d; dirty = true; } @@ -433,7 +442,7 @@ float get_attenuation(void) if (setting.atten_step) return ( -(POWER_OFFSET + setting.attenuate - (setting.atten_step-1)*POWER_STEP + SWITCH_ATTENUATION)); else - return ( -POWER_OFFSET - setting.attenuate + (setting.drive & 7) * 3); + return ( -POWER_OFFSET - setting.attenuate + (setting.rx_drive & 7) * 3); } else if (setting.atten_step) { if (setting.mode == M_LOW) return setting.attenuate + RECEIVE_SWITCH_ATTENUATION; @@ -448,9 +457,9 @@ static pureRSSI_t get_signal_path_loss(void){ if (setting.mode == M_ULTRA) return float_TO_PURE_RSSI(-15); // Loss in dB, -9.5 for v0.1, -12.5 for v0.2 #endif - if (setting.mode == M_LOW) - return float_TO_PURE_RSSI(-5.5); // Loss in dB, -9.5 for v0.1, -12.5 for v0.2 - return float_TO_PURE_RSSI(+7); // Loss in dB (+ is gain) +// if (setting.mode == M_LOW) +// return float_TO_PURE_RSSI(-5.5); // Loss in dB, -9.5 for v0.1, -12.5 for v0.2 + return float_TO_PURE_RSSI(0); // Loss in dB (+ is gain) } static const int drive_dBm [16] = {-38,-35,-33,-30,-27,-24,-21,-19,-7,-4,-2, 1, 4, 7, 10, 13}; @@ -463,7 +472,7 @@ void set_level(float v) // Set the drive level of the LO d++; if (d == 8 && v < -12) // Round towards closest level d = 7; - set_drive(d); + set_rx_drive(d); } else { setting.level = v; set_attenuation((int)v); @@ -476,16 +485,16 @@ void set_attenuation(float a) // Is used both in output mode and input mod if (setting.mode == M_GENLOW) { a = a + POWER_OFFSET; if (a > 6) { // +9dB - setting.drive = 11; // Maximum save drive for SAW filters. + setting.rx_drive = 11; // Maximum save drive for SAW filters. a = a - 9; } else if (a > 3) { // +6dB - setting.drive = 10; + setting.rx_drive = 10; a = a - 6; } else if (a > 0) { // +3dB - setting.drive = 9; + setting.rx_drive = 9; a = a - 3; } else - setting.drive = 8; // defined as 0dB level + setting.rx_drive = 8; // defined as 0dB level if (a > 0) a = 0; if( a > - SWITCH_ATTENUATION) { @@ -1116,7 +1125,12 @@ void setupSA(void) #endif ADF4351_Setup(); -#if 0 // Measure fast scan time + enable_lna(false); + enable_ultra(false); + enable_rx_output(false); + enable_high(false); + + #if 0 // Measure fast scan time setting.sweep_time_us = 0; setting.additional_step_delay_us = 0; START_PROFILE // measure 90 points to get overhead @@ -1216,10 +1230,10 @@ void set_freq(int V, unsigned long freq) // translate the requested frequency } #endif if (freq) { - real_old_freq[V] = ADF4351_set_frequency(V-ADF4351_LO,freq,setting.drive-12); + real_old_freq[V] = ADF4351_set_frequency(V-ADF4351_LO,freq); } } else if (V==ADF4351_LO2){ - real_old_freq[V] = ADF4351_set_frequency(V-ADF4351_LO,freq,setting.drive-12); + real_old_freq[V] = ADF4351_set_frequency(V-ADF4351_LO, freq); } else if (V==SI4463_RX) { SI4463_set_freq(freq); @@ -1275,6 +1289,10 @@ case M_ULTRA: SI4463_init_rx(); // Must be before ADF4351_setup!!!! #endif set_AGC_LNA(); + ADF4351_enable(true); + ADF4351_drive(setting.lo_drive); + ADF4351_enable_aux_out(false); + ADF4351_enable_out(true); #ifdef __SI4432__ SI4432_Sel = SI4432_LO ; @@ -1286,6 +1304,10 @@ case M_ULTRA: SI4432_Transmit(setting.drive); // set_calibration_freq(setting.refer); #endif + enable_rx_output(false); + enable_high(false); + enable_lna(setting.lna); + enable_ultra(setting.ultra); break; case M_HIGH: // Direct into 1 mute: @@ -1307,6 +1329,14 @@ mute: SI4463_init_rx(); #endif set_AGC_LNA(); + ADF4351_enable_aux_out(false); + ADF4351_enable_out(false); + ADF4351_enable(false); + + enable_rx_output(false); + enable_high(true); + enable_lna(false); + enable_ultra(false); break; case M_GENLOW: // Mixed output from 0 @@ -1333,6 +1363,20 @@ case M_GENLOW: // Mixed output from 0 #ifdef __SI4468__ SI4463_init_tx(); #endif + ADF4351_enable_out(true); + ADF4351_drive(setting.lo_drive); + ADF4351_enable(true); + ADF4351_enable_aux_out(false); + + if (setting.atten_step) { // use switch as attenuator + enable_rx_output(false); + } else { + enable_rx_output(true); + } + SI4463_set_output_level(setting.rx_drive); + enable_high(false); + enable_lna(false); + enable_ultra(false); break; case M_GENHIGH: // Direct output from 1 if (setting.mute) @@ -1351,8 +1395,21 @@ case M_GENHIGH: // Direct output from 1 SI4432_Transmit(setting.drive); #endif #ifdef __SI4468__ - SI4463_init_tx(); + SI4463_init_rx(); #endif + ADF4351_enable(true); +#ifndef TINYSA4_PROTO + ADF4351_enable_aux_out(false); + ADF4351_enable_out(true); +#else + ADF4351_enable_aux_out(true); + ADF4351_enable_out(false); +#endif + ADF4351_aux_drive(setting.lo_drive); + enable_rx_output(false); + enable_high(true); + enable_lna(false); + enable_ultra(false); break; } @@ -1823,10 +1880,10 @@ modulation_again: if (MODE_HIGH(setting.mode)) { local_IF = 0; } else if (MODE_LOW(setting.mode)){ // All low mode - if (!setting.auto_IF) { + if (!setting.auto_IF) local_IF = setting.frequency_IF; - } - local_IF = DEFAULT_IF; + else + local_IF = DEFAULT_IF; if (setting.mode == M_LOW) { if (tracking) { // VERY SPECIAL CASE!!!!! Measure BPF local_IF += lf - reffer_freq[setting.refer]; // Offset so fundamental of reffer is visible @@ -1943,8 +2000,10 @@ modulation_again: local_IF += error_f; } #endif - } else if (MODE_HIGH(setting.mode)) { + } else if (setting.mode == M_HIGH) { set_freq (SI4463_RX, lf); // sweep RX, local_IF = 0 in high mode + } else if (setting.mode == M_GENHIGH) { + set_freq (ADF4351_LO, lf); // sweep LO, local_IF = 0 in high mode } // STOP_PROFILE; #endif diff --git a/si4432.c b/si4432.c index 9eebdac..3d04426 100644 --- a/si4432.c +++ b/si4432.c @@ -51,19 +51,6 @@ static uint32_t old_port_moder; static uint32_t new_port_moder; #endif - -#define CS_SI0_HIGH palSetPad(GPIO_RX_SEL_PORT, GPIO_RX_SEL) -#define CS_SI1_HIGH palSetPad(GPIO_RX_SEL_PORT, GPIOB_LO_SEL) -//#define CS_PE_HIGH palSetPad(GPIOA, GPIOA_PE_SEL) - -#define RF_POWER_HIGH palSetPad(GPIOB, GPIOB_RF_PWR) -//#define SPI2_CLK_HIGH palSetPad(GPIOB, GPIO_SPI2_CLK) -//#define SPI2_CLK_LOW palClearPad(GPIOB, GPIO_SPI2_CLK) - -#define CS_SI0_LOW palClearPad(GPIO_RX_SEL_PORT, GPIO_RX_SEL) -#define CS_SI1_LOW palClearPad(GPIO_RX_SEL_PORT, GPIOB_LO_SEL) -//#define CS_PE_LOW palClearPad(GPIOA, GPIOA_PE_SEL) - #define SPI1_CLK_HIGH palSetPad(GPIOB, GPIOB_SPI_SCLK) #define SPI1_CLK_LOW palClearPad(GPIOB, GPIOB_SPI_SCLK) @@ -944,7 +931,7 @@ void ADF4351_Setup(void) - ADF4351_set_frequency(0,2000000000,0); + ADF4351_set_frequency(0,2000000000); // ADF4351_set_frequency(1,150000000,0); @@ -983,17 +970,19 @@ void ADF4351_Set(int channel) } } +#if 0 void ADF4351_disable_output(void) { - bitClear (registers[4], 5); // digital lock + bitClear (registers[4], 5); // main output ADF4351_Set(0); } void ADF4351_enable_output(void) { - bitSet (registers[4], 5); // digital lock + bitSet (registers[4], 5); // main output ADF4351_Set(0); } +#endif static uint32_t prev_actual_freq = 0; @@ -1001,14 +990,14 @@ void ADF4351_force_refresh(void) { prev_actual_freq = 0; } -uint32_t ADF4351_set_frequency(int channel, uint32_t freq, int drive) // freq / 10Hz +uint32_t ADF4351_set_frequency(int channel, uint32_t freq) // freq / 10Hz { // freq -= 71000; // SI4463_set_gpio(3,GPIO_HIGH); // uint32_t offs = ((freq / 1000)* ( 0) )/ 1000; uint32_t offs = 0; - uint32_t actual_freq = ADF4351_prep_frequency(channel,freq + offs, drive); + uint32_t actual_freq = ADF4351_prep_frequency(channel,freq + offs); // SI4463_set_gpio(3,GPIO_LOW); if (actual_freq != prev_actual_freq) { //START_PROFILE; @@ -1031,6 +1020,7 @@ void ADF4351_spur_mode(int S) bitSet (registers[2], 30); // R set to 8 else bitClear (registers[2], 30); // R set to 8 + ADF4351_Set(0); } void ADF4351_R_counter(int R) @@ -1056,18 +1046,28 @@ static int old_R; } registers[2] &= ~ (((unsigned long)0x3FF) << 14); registers[2] |= (((unsigned long)R) << 14); + ADF4351_Set(0); } void ADF4351_CP(int p) { registers[2] &= ~ (((unsigned long)0xF) << 9); registers[2] |= (((unsigned long)p) << 9); + ADF4351_Set(0); } -void ADF4351_level(int p) +void ADF4351_drive(int p) { registers[4] &= ~ (((unsigned long)0x3) << 3); registers[4] |= (((unsigned long)p) << 3); + ADF4351_Set(0); +} + +void ADF4351_aux_drive(int p) +{ + registers[4] &= ~ (((unsigned long)0x3) << 6); + registers[4] |= (((unsigned long)p) << 6); + ADF4351_Set(0); } static uint32_t gcd(uint32_t x, uint32_t y) @@ -1081,7 +1081,7 @@ static uint32_t gcd(uint32_t x, uint32_t y) return x; } -uint32_t ADF4351_prep_frequency(int channel, unsigned long freq, int drive) // freq / 10Hz +uint32_t ADF4351_prep_frequency(int channel, unsigned long freq) // freq / 10Hz { if (freq >= 2200000000) { OutputDivider = 1; @@ -1147,34 +1147,39 @@ uint32_t ADF4351_prep_frequency(int channel, unsigned long freq, int drive) // registers[1] = MOD << 3; registers[1] = registers[1] + 1 ; // restore address "001" bitSet (registers[1], 27); // Prescaler at 8/9 - - if (drive == 0) { - bitClear (registers[4], 3); // +5dBm + out - bitClear (registers[4], 4); // +5dBm - bitClear (registers[4], 6); // +5dBm - out - bitClear (registers[4], 7); // +5dBm - } else if (drive == 1) { - bitSet (registers[4], 6); // +5dBm - bitClear (registers[4], 7); // +5dBm - out - bitSet (registers[4], 3); // +5dBm - bitClear (registers[4], 4); // +5dBm + out - } else if (drive == 2) { - bitClear (registers[4], 6); // +5dBm - out - bitSet (registers[4], 7); // +5dBm - bitClear (registers[4], 3); // +5dBm + out - bitSet (registers[4], 4); // +5dBm - } - else { - bitSet (registers[4], 6); // +5dBm - out - bitSet (registers[4], 7); // +5dBm - bitSet (registers[4], 3); // +5dBm + out - bitSet (registers[4], 4); // +5dBm - } return actual_freq; } #endif +void ADF4351_enable(int s) +{ + if (s) + bitClear(registers[4], 11); // Inverse logic!!!!! + else + bitSet(registers[4], 11); + ADF4351_Set(0); +} + +void ADF4351_enable_aux_out(int s) +{ + if (s) + bitSet(registers[4], 8); + else + bitClear(registers[4], 8); + ADF4351_Set(0); +} + +void ADF4351_enable_out(int s) +{ + if (s) + bitSet(registers[4], 5); + else + bitClear(registers[4], 5); + ADF4351_Set(0); +} + + // ------------------------------ SI4463 ------------------------------------- @@ -1212,22 +1217,22 @@ int SI4463_wait_for_cts(void) void SI4463_write_byte(uint8_t ADR, uint8_t DATA) { set_SPI_mode(SPI_MODE_SI); - palClearLine(LINE_RX_SEL); + SI_CS_LOW; ADR |= 0x80 ; // RW = 1 shiftOut( ADR ); shiftOut( DATA ); - palSetLine(LINE_RX_SEL); + SI_CS_HIGH; } void SI4463_write_buffer(uint8_t ADR, uint8_t *DATA, int len) { set_SPI_mode(SPI_MODE_SI); - palClearLine(LINE_RX_SEL); + SI_CS_LOW; ADR |= 0x80 ; // RW = 1 shiftOut( ADR ); while (len-- > 0) shiftOut( *(DATA++) ); - palSetLine(LINE_RX_SEL); + SI_CS_HIGH; } @@ -1236,10 +1241,10 @@ uint8_t SI4463_read_byte( uint8_t ADR ) set_SPI_mode(SPI_MODE_SI); uint8_t DATA ; set_SPI_mode(SPI_MODE_SI); - palClearLine(LINE_RX_SEL); + SI_CS_LOW; shiftOut( ADR ); DATA = shiftIn(); - palSetLine(LINE_RX_SEL); + SI_CS_HIGH; return DATA ; } @@ -1251,7 +1256,7 @@ uint8_t SI4463_get_response(void* buff, uint8_t len) if (!cts) { return false; } - palClearLine(LINE_RX_SEL); + SI_CS_LOW; shiftOut( SI446X_CMD_READ_CMD_BUFF ); cts = (shiftIn() == 0xFF); if (cts) @@ -1261,7 +1266,7 @@ uint8_t SI4463_get_response(void* buff, uint8_t len) ((uint8_t*)buff)[i] = shiftIn(); } } - palSetLine(LINE_RX_SEL); + SI_CS_HIGH; return cts; } @@ -1289,11 +1294,11 @@ void SI4463_do_api(void* data, uint8_t len, void* out, uint8_t outLen) if (SI4463_wait_for_cts()) #endif { - palClearLine(LINE_RX_SEL); + SI_CS_LOW; for(uint8_t i=0;iparam_1.i = menu_drive_value[data]; - b->icon = data == setting.drive ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP; + b->icon = data == setting.rx_drive ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP; return; } //Serial.println(item); - set_drive(data); + set_rx_drive(data); + menu_move_back(); +// ui_mode_normal(); +// draw_cal_status(); +} + +const int8_t menu_lo_drive_value[]={4,7,10,13}; +static UI_FUNCTION_ADV_CALLBACK(menu_lo_drive_acb) +{ + (void)item; + if(b){ + b->param_1.i = menu_lo_drive_value[data]; + b->icon = data == setting.lo_drive ? BUTTON_ICON_GROUP_CHECKED : BUTTON_ICON_GROUP; + return; + } +//Serial.println(item); + set_lo_drive(data); menu_move_back(); // ui_mode_normal(); // draw_cal_status(); @@ -718,7 +734,7 @@ static UI_FUNCTION_ADV_CALLBACK(menu_sdrive_acb){ (void)item; (void)data; if(b){ - b->param_1.i = menu_drive_value[setting.drive]; + b->param_1.i = menu_drive_value[setting.lo_drive]; return; } menu_push_submenu(menu_drive_wide); @@ -1378,11 +1394,11 @@ static const menuitem_t menu_load_preset[] = { MT_NONE, 0, NULL, NULL } // sentinel }; -static const menuitem_t menu_drive[] = { - { MT_ADV_CALLBACK, 15, "%+ddBm", menu_drive_acb}, - { MT_ADV_CALLBACK, 14, "%+ddBm", menu_drive_acb}, - { MT_ADV_CALLBACK, 13, "%+ddBm", menu_drive_acb}, - { MT_ADV_CALLBACK, 12, "%+ddBm", menu_drive_acb}, +static const menuitem_t menu_lo_drive[] = { + { MT_ADV_CALLBACK, 3, "%+ddBm", menu_lo_drive_acb}, + { MT_ADV_CALLBACK, 2, "%+ddBm", menu_lo_drive_acb}, + { MT_ADV_CALLBACK, 1, "%+ddBm", menu_lo_drive_acb}, + { MT_ADV_CALLBACK, 0, "%+ddBm", menu_lo_drive_acb}, { MT_CANCEL, 255, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel }; @@ -1709,7 +1725,7 @@ static const menuitem_t menu_settings[] = { MT_KEYPAD | MT_LOW, KM_IF, "IF FREQ", "Set to zero for auto IF"}, { MT_SUBMENU,0, "SCAN SPEED", menu_scanning_speed}, { MT_KEYPAD, KM_REPEAT, "SAMPLE\nREPEAT", "1..100"}, - { MT_SUBMENU | MT_LOW,0, "MIXER\nDRIVE", menu_drive}, + { MT_SUBMENU | MT_LOW,0, "MIXER\nDRIVE", menu_lo_drive}, { MT_SUBMENU, 0, S_RARROW" MORE", menu_settings2}, { MT_CANCEL, 0, S_LARROW" BACK", NULL }, { MT_NONE, 0, NULL, NULL } // sentinel @@ -2024,7 +2040,7 @@ static void fetch_numeric_target(void) plot_printf(uistat.text, sizeof uistat.text, "%2d", ((int32_t)uistat.value)); break; case KM_DRIVE: - uistat.value = setting.drive; + uistat.value = setting.rx_drive; plot_printf(uistat.text, sizeof uistat.text, "%3ddB", ((int32_t)uistat.value)); break; case KM_LOWOUTLEVEL: @@ -2159,7 +2175,7 @@ set_numeric_value(void) set_repeat(uistat.value); break; case KM_DRIVE: - set_drive(uistat.value); + set_rx_drive(uistat.value); break; case KM_LOWOUTLEVEL: set_level(uistat.value);