@ -1042,7 +1042,7 @@ void set_AGC_LNA(void) {
uint8_t v = 0 ;
if ( ! S_STATE ( setting . agc ) )
v | = 0x80 + 0x20 ; // Inverse!!!!
if ( ! S_STATE ( setting . lna ) )
if ( S_STATE ( setting . lna ) )
v | = 0x08 ; // Inverse!!!!
SI446x_set_AGC_LNA ( v ) ;
SI4432_old_v [ 0 ] = v ;
@ -1069,18 +1069,22 @@ void set_unit(int u)
r = REFLEVEL_MAX ; // Maximum value
set_scale ( r / NGRIDY ) ;
set_reflevel ( setting . scale * NGRIDY ) ;
# ifdef __SI4432__
if ( S_IS_AUTO ( setting . agc ) )
setting . agc = S_AUTO_ON ;
if ( S_IS_AUTO ( setting . lna ) )
setting . lna = S_AUTO_OFF ;
# endif
} else {
r = 10 * roundf ( ( r * 1.2 ) / 10.0 ) ;
set_reflevel ( r ) ;
set_scale ( 10 ) ;
# ifdef __SI4432__
if ( S_IS_AUTO ( setting . agc ) )
setting . agc = S_AUTO_ON ;
if ( S_IS_AUTO ( setting . lna ) )
setting . lna = S_AUTO_OFF ;
# endif
}
plot_into_index ( measured ) ;
redraw_request | = REDRAW_AREA ;
@ -1281,8 +1285,8 @@ static const struct {
} step_delay_table [ ] = {
// RBWx10 step_delay offset_delay spur_gate (value divided by 1000)
{ 6000 , 80 , 50 , 400 } ,
{ 3000 , 8 0, 50 , 200 } ,
{ 1000 , 1 00, 100 , 100 } ,
{ 3000 , 40 0, 50 , 200 } ,
{ 1000 , 4 00, 100 , 100 } ,
{ 300 , 400 , 120 , 100 } ,
{ 100 , 400 , 120 , 100 } ,
{ 30 , 900 , 300 , 100 } ,
@ -2235,10 +2239,22 @@ void clock_below_48MHz(void)
}
}
void clock_at_48MHz ( void )
{
if ( hsical = = - 1 )
hsical = ( ( RCC - > CR & 0xff00 ) > > 8 ) ;
if ( hsical ! = - 1 ) {
RCC - > CR & = RCC_CR_HSICAL ;
RCC - > CR | = ( ( hsical ) < < 8 ) ;
RCC - > CR & = RCC_CR_HSITRIM | RCC_CR_HSION ; /* CR Reset value. */
}
}
pureRSSI_t perform ( bool break_on_operation , int i , freq_t f , int tracking ) // Measure the RSSI for one frequency, used from sweep and other measurement routines. Must do all HW setup
{
int modulation_delay = 0 ;
int modulation_index = 0 ;
int modulation_count_iter = 0 ;
int spur_second_pass = false ;
if ( i = = 0 & & dirty ) { // if first point in scan and dirty
# ifdef __ADF4351__
@ -2276,7 +2292,9 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) /
calculate_static_correction ( ) ;
if ( ! in_selftest ) clock_above_48MHz ( ) ;
is_below = false ;
}
correct_RSSI_freq = get_frequency_correction ( f ) ; // for i == 0 and freq_step == 0;
} else
clock_at_48MHz ( ) ;
// if (MODE_OUTPUT(setting.mode) && setting.additional_step_delay_us < 500) // Minimum wait time to prevent LO from lockup during output frequency sweep
// setting.additional_step_delay_us = 500;
// Update grid and status after
@ -2408,7 +2426,7 @@ pureRSSI_t perform(bool break_on_operation, int i, freq_t f, int tracking) /
# endif
// Calculate the RSSI correction for later use
if ( MODE_INPUT ( setting . mode ) ) { // only cases where the value can change on 0 point of sweep
if ( i = = 0 | | setting. frequency_step ! = 0 )
if ( setting. frequency_step ! = 0 )
correct_RSSI_freq = get_frequency_correction ( f ) ;
}
int * current_fm_modulation = 0 ;
@ -2662,13 +2680,13 @@ modulation_again:
if ( setting . R = = 0 ) {
if ( lf < LOW_MAX_FREQ & & lf > = TXCO_DIV3 & & MODE_INPUT ( setting . mode ) ) {
freq_t tf = ( ( lf + actual_rbw_x10 * 100 ) / TCXO ) * TCXO ;
if ( tf + actual_rbw_x10 * 100 > = lf & & tf < lf + actual_rbw_x10 * 100 ) {
freq_t tf = ( ( lf + actual_rbw_x10 * 100 0 ) / TCXO ) * TCXO ;
if ( tf + actual_rbw_x10 * 100 > = lf & & tf < lf + actual_rbw_x10 * 100 ) { // 30MHz
ADF4351_R_counter ( 6 ) ;
} else {
if ( setting . frequency_step < 100000 ) {
freq_t tf = ( ( lf + actual_rbw_x10 * 100 ) / TXCO_DIV3 ) * TXCO_DIV3 ;
if ( tf + actual_rbw_x10 * 100 > = lf & & tf < lf + actual_rbw_x10 * 100 )
freq_t tf = ( ( lf + actual_rbw_x10 * 100 0 ) / TXCO_DIV3 ) * TXCO_DIV3 ;
if ( tf + actual_rbw_x10 * 100 > = lf & & tf < lf + actual_rbw_x10 * 100 ) // 10MHz
ADF4351_R_counter ( 4 ) ;
else
ADF4351_R_counter ( 3 ) ;
@ -2844,6 +2862,11 @@ modulation_again:
return ( 0 ) ; // abort
if ( i = = 1 & & MODE_OUTPUT ( setting . mode ) & & setting . modulation ! = MO_NONE & & setting . modulation ! = MO_EXTERNAL ) { // if in output mode with modulation and LO setup done
// i = 1; // Everything set so skip LO setting
# define MODULATION_CYCLES_TEST 10000
if ( in_selftest & & modulation_count_iter + + > = 10000 ) {
start_of_sweep_timestamp = ( chVTGetSystemTimeX ( ) - start_of_sweep_timestamp ) * MODULATION_STEPS * 100 / MODULATION_CYCLES_TEST ; // uS per cycle
return 0 ;
}
goto modulation_again ; // Keep repeating sweep loop till user aborts by input
}
return ( 0 ) ;
@ -2861,7 +2884,7 @@ modulation_again:
# endif
# ifdef __SI4463__
if ( i = = 0 & & setting . frequency_step = = 0 & & setting . trigger = = T_AUTO & & S_STATE ( setting . spur_removal ) = = 0 & & SI4432_step_delay = = 0 & & setting . repeat = = 1 & & setting . sweep_time_us < 100 * ONE_MS_TIME ) {
SI446x_Fill ( MODE_SELECT ( setting . mode ) , 0 ) ;
SI446x_Fill ( MODE_SELECT ( setting . mode ) , - 1 ) ; // First get_RSSI will fail
}
# endif
# endif
@ -2953,6 +2976,10 @@ modulation_again:
# endif
# endif
}
// if (pureRSSI < 400) {
// volatile int i = 0;
// i = i + 1;
// }
# ifdef __SPUR__
static pureRSSI_t spur_RSSI = - 1 ; // Initialization only to avoid warning.
if ( setting . mode = = M_LOW & & S_STATE ( setting . spur_removal ) ) {
@ -3242,9 +3269,10 @@ sweep_again: // stay in sweep loop when output mo
} // end of input specific processing
} // ---------------------- end of sweep loop -----------------------------
if ( MODE_OUTPUT ( setting . mode ) & & setting . modulation ! = MO_NONE ) // if in output mode with modulation
if ( MODE_OUTPUT ( setting . mode ) & & setting . modulation ! = MO_NONE ) { // if in output mode with modulation
if ( ! in_selftest )
goto sweep_again ; // Keep repeating sweep loop till user aborts by input
}
// --------------- check if maximum is above trigger level -----------------
if ( setting . trigger ! = T_AUTO & & setting . frequency_step > 0 ) { // Trigger active
@ -3345,7 +3373,7 @@ sweep_again: // stay in sweep loop when output mo
# endif
// -------------------------- auto attenuate ----------------------------------
# ifdef TINYSA4
# define AUTO_TARGET_LEVEL -3 5
# define AUTO_TARGET_LEVEL -3 0
# else
# define AUTO_TARGET_LEVEL -25
# endif
@ -3534,6 +3562,21 @@ sweep_again: // stay in sweep loop when output mo
markers [ 1 ] . enabled = search_maximum ( 1 , frequencies [ markers [ 0 ] . index ] * 2 , 8 ) ;
markers [ 2 ] . enabled = search_maximum ( 2 , frequencies [ markers [ 0 ] . index ] * 3 , 12 ) ;
markers [ 3 ] . enabled = search_maximum ( 3 , frequencies [ markers [ 0 ] . index ] * 4 , 16 ) ;
# ifdef TINYSA4
} else if ( setting . measurement = = M_AM & & markers [ 0 ] . index > 10 ) { // ----------IOP measurement
int l = markers [ 1 ] . index ;
int r = markers [ 2 ] . index ;
if ( r < l ) {
l = markers [ 2 ] . index ;
r = markers [ 1 ] . index ;
markers [ 1 ] . index = l ;
markers [ 2 ] . index = r ;
}
freq_t lf = frequencies [ l ] ;
freq_t rf = frequencies [ r ] ;
markers [ 1 ] . frequency = lf ;
markers [ 2 ] . frequency = rf ;
# endif
} else if ( setting . measurement = = M_OIP3 & & markers [ 0 ] . index > 10 & & markers [ 1 ] . index > 10 ) { // ----------IOP measurement
int l = markers [ 0 ] . index ;
int r = markers [ 1 ] . index ;
@ -3578,6 +3621,7 @@ sweep_again: // stay in sweep loop when output mo
}
} else if ( setting . measurement = = M_AM ) { // ----------------AM measurement
if ( S_IS_AUTO ( setting . agc ) ) {
# ifdef __SI4432__
int actual_level = actual_t [ max_index [ 0 ] ] - get_attenuation ( ) ; // no need for float
if ( actual_level > - 20 ) {
setting . agc = S_AUTO_OFF ;
@ -3590,6 +3634,7 @@ sweep_again: // stay in sweep loop when output mo
setting . lna = S_AUTO_ON ;
}
set_AGC_LNA ( ) ;
# endif
}
}
@ -4529,6 +4574,37 @@ void self_test(int test)
reset_settings ( M_LOW ) ;
setting . step_delay_mode = SD_NORMAL ;
setting . step_delay = 0 ;
} else if ( test = = 4 ) {
reset_settings ( M_LOW ) ;
set_mode ( M_GENLOW ) ;
set_sweep_frequency ( ST_CENTER , ( freq_t ) 30000000 ) ;
set_sweep_frequency ( ST_SPAN , ( freq_t ) 0 ) ;
setting . modulation = MO_AM ;
setting . modulation_frequency = 5000 ;
in_selftest = true ;
config . cor_am = 0 ;
perform ( false , 0 , 30000000 , false ) ;
perform ( false , 1 , 30000000 , false ) ;
config . cor_am = - ( start_of_sweep_timestamp - ( ONE_SECOND_TIME / setting . modulation_frequency ) ) / 8 ;
setting . modulation = MO_NFM ;
setting . modulation_frequency = 5000 ;
in_selftest = true ;
config . cor_nfm = 0 ;
perform ( false , 0 , 30000000 , false ) ;
perform ( false , 1 , 30000000 , false ) ;
config . cor_nfm = - ( start_of_sweep_timestamp - ( ONE_SECOND_TIME / setting . modulation_frequency ) ) / 8 ;
setting . modulation = MO_WFM ;
setting . modulation_frequency = 5000 ;
in_selftest = true ;
config . cor_wfm = 0 ;
perform ( false , 0 , 30000000 , false ) ;
perform ( false , 1 , 30000000 , false ) ;
config . cor_wfm = - ( start_of_sweep_timestamp - ( ONE_SECOND_TIME / setting . modulation_frequency ) ) / 8 ;
// shell_printf("\n\rCycle time = %d\n\r", start_of_sweep_timestamp);
reset_settings ( M_LOW ) ;
} else if ( test = = 5 ) {
// reset_settings(M_LOW); // Make sure we are in a defined state
in_selftest = true ;
@ -4616,7 +4692,7 @@ void calibrate(void)
test_prepare ( TEST_POWER ) ;
setting . step_delay_mode = SD_PRECISE ;
# ifndef TINYSA4
setting . agc = S_O FF ;
setting . agc = S_O N ;
setting . lna = S_OFF ;
# endif
test_acquire ( TEST_POWER ) ; // Acquire test