diff --git a/sa_core.c b/sa_core.c index af3aa73..b835e54 100644 --- a/sa_core.c +++ b/sa_core.c @@ -857,16 +857,10 @@ void calculate_step_delay(void) #endif #endif #ifdef __SI4463__ - if (actual_rbw_x10 >= 1910) { SI4432_step_delay = 300; SI4432_offset_delay = 100; } - else if (actual_rbw_x10 >= 1420) { SI4432_step_delay = 350; SI4432_offset_delay = 100; } - else if (actual_rbw_x10 >= 750) { SI4432_step_delay = 450; SI4432_offset_delay = 100; } - else if (actual_rbw_x10 >= 560) { SI4432_step_delay = 650; SI4432_offset_delay = 100; } - else if (actual_rbw_x10 >= 370) { SI4432_step_delay = 700; SI4432_offset_delay = 200; } - else if (actual_rbw_x10 >= 180) { SI4432_step_delay = 1100; SI4432_offset_delay = 300; } - else if (actual_rbw_x10 >= 90) { SI4432_step_delay = 1700; SI4432_offset_delay = 400; } - else if (actual_rbw_x10 >= 50) { SI4432_step_delay = 3300; SI4432_offset_delay = 800; } - else if (actual_rbw_x10 >= 20) { SI4432_step_delay = 7000; SI4432_offset_delay = 800; } - else { SI4432_step_delay = 20000; SI4432_offset_delay =1600; } + if (actual_rbw_x10 >= 2700) { SI4432_step_delay = 200; SI4432_offset_delay = 100; } + else if (actual_rbw_x10 >= 800) { SI4432_step_delay = 250; 150; SI4432_offset_delay = 100; } + else if (actual_rbw_x10 >= 250) { SI4432_step_delay = 600; 450; SI4432_offset_delay = 100; } + else { SI4432_step_delay = 2000; SI4432_offset_delay =1600; } #endif if (setting.step_delay_mode == SD_PRECISE) // In precise mode wait twice as long for RSSI to stabalize SI4432_step_delay *= 2; @@ -1251,6 +1245,9 @@ void update_rbw(void) // calculate the actual_rbw and the vbwSteps (# #ifdef __SI4432__ SI4432_Sel = MODE_SELECT(setting.mode); actual_rbw_x10 = SI4432_SET_RBW(actual_rbw_x10); // see what rbw the SI4432 can realize +#endif +#ifdef __SI4463__ + actual_rbw_x10 = SI4463_SET_RBW(actual_rbw_x10); // see what rbw the SI4432 can realize #endif if (setting.frequency_step > 0 && MODE_INPUT(setting.mode)) { // When doing frequency scanning in input mode vbwSteps = ((int)(2 * (setting.vbw_x10 + (actual_rbw_x10/2)) / actual_rbw_x10)); // calculate # steps in between each frequency step due to rbw being less than frequency step @@ -1707,6 +1704,7 @@ pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking) set_freq (SI4432_LO, local_IF+lf); // otherwise to above IF #endif #ifdef __ADF4351__ +// START_PROFILE; if (setting.mode == M_LOW) { if (!setting.tracking && S_STATE(setting.below_IF)) { // if in low input mode and below IF if (lf > local_IF) @@ -1718,6 +1716,7 @@ pureRSSI_t perform(bool break_on_operation, int i, uint32_t f, int tracking) } else if (setting.mode == M_HIGH) { set_freq (SI4463_RX, local_IF+lf); // sweep RX } +// STOP_PROFILE; #endif #endif } @@ -3252,7 +3251,13 @@ void self_test(int test) int i = 15; // calibrate low mode power on 30 MHz; test_prepare(i); setting.step_delay = 8000; - for (int j= 0; j < 57; j++ ) { +#ifdef __SI4432__ +#define RBW_COUNT 57 +#endif +#ifdef __SI4463__ +#define RBW_COUNT 7 +#endif + for (int j= 0; j < RBW_COUNT; j++ ) { if (setting.test_argument != 0) j = setting.test_argument; // do_again: @@ -3269,6 +3274,9 @@ void self_test(int test) setting.offset_delay = setting.step_delay / 2; #ifdef __SI4432__ setting.rbw_x10 = SI4432_force_RBW(j); +#endif +#ifdef __SI4463__ + setting.rbw_x10 = SI4463_force_RBW(j); #endif shell_printf("RBW = %f, ",setting.rbw_x10/10.0); #if 0 @@ -3315,7 +3323,7 @@ void self_test(int test) #endif setting.offset_delay = 1600; -#if 1 // Enable for offset tuning stepping +#if 0 // Enable for offset tuning stepping test_value = saved_peakLevel; if ((uint32_t)(setting.rbw_x10 * 1000) / (sweep_points) < 8000) { // fast mode possible while (setting.offset_delay > 0 && test_value != 0 && test_value > saved_peakLevel - 1.5) { diff --git a/si4432.c b/si4432.c index b751868..b9b0b9a 100644 --- a/si4432.c +++ b/si4432.c @@ -46,7 +46,7 @@ #ifdef USE_HARDWARE_SPI_MODE #define SI4432_SPI SPI1 //#define SI4432_SPI_SPEED SPI_BR_DIV8 -#define SI4432_SPI_SPEED SPI_BR_DIV32 +#define SI4432_SPI_SPEED SPI_BR_DIV16 static uint32_t old_spi_settings; #else static uint32_t old_port_moder; @@ -951,21 +951,24 @@ void ADF4351_Setup(void) void ADF4351_WriteRegister32(int channel, const uint32_t value) { - set_SPI_mode(SPI_MODE_SI); - chThdSleepMicroseconds(2); - palClearPad(GPIOB, ADF4351_LE[channel]); - chThdSleepMicroseconds(2); for (int i = 3; i >= 0; i--) shiftOut((value >> (8 * i)) & 0xFF); -// chThdSleepMicroseconds(10); +// chThdSleepMicroseconds(1); palSetPad(GPIOB, ADF4351_LE[channel]); - chThdSleepMicroseconds(2); + chThdSleepMicroseconds(1); // Must palClearPad(GPIOB, ADF4351_LE[channel]); - chThdSleepMicroseconds(2); +// chThdSleepMicroseconds(1); // Not needed } void ADF4351_Set(int channel) -{ for (int i = 5; i >= 0; i--) { +{ + set_SPI_mode(SPI_MODE_SI); + chThdSleepMicroseconds(1); + palClearPad(GPIOB, ADF4351_LE[channel]); + chThdSleepMicroseconds(1); + + for (int i = 5; i >= 0; i--) { ADF4351_WriteRegister32(channel, registers[i]); + // if (debug) Serial.println(registers[i],HEX); } } @@ -984,10 +987,11 @@ void ADF4351_enable_output(void) void ADF4351_set_frequency(int channel, unsigned long freq, int drive) // freq / 10Hz { + freq -= 76000; ADF4351_prep_frequency(channel,freq, drive); +//START_PROFILE; ADF4351_Set(channel); - if (SI4432_step_delay>10) - my_microsecond_delay(SI4432_step_delay); +//STOP_PROFILE; } void ADF4351_spur_mode(int S) @@ -1055,6 +1059,7 @@ static uint32_t gcd(uint32_t x, uint32_t y) void ADF4351_prep_frequency(int channel, unsigned long freq, int drive) // freq / 10Hz { (void)drive; +// START_PROFILE; // if (channel == 0) RFout=freq/1000000.0; // To MHz // else @@ -1198,9 +1203,9 @@ void ADF4351_prep_frequency(int channel, unsigned long freq, int drive) // freq #endif // bitSet (registers[4], 10); // Mute till lock // ADF4351_Set(channel); +// STOP_PROFILE; } - #endif // ------------------------------ SI4463 ------------------------------------- @@ -1301,7 +1306,7 @@ uint8_t SI4463_wait_response(void* buff, uint8_t len, uint8_t use_timeout) uint16_t timeout = 40000; while(!SI4463_get_response(buff, len)) { - my_microsecond_delay(5); + my_microsecond_delay(2); if(use_timeout && !--timeout) { return 0; @@ -1470,12 +1475,15 @@ int16_t Si446x_RSSI(void) 0xFF }; // volatile si446x_state_t s = getState(); - chThdSleepMicroseconds(SI4432_step_delay); +START_PROFILE; + if (SI4432_step_delay) + my_microsecond_delay(SI4432_step_delay); again: SI4463_do_api(data, 2, data, 3); if (data[2] == 255) goto again; int16_t rssi = data[2] - 120 * 2; +STOP_PROFILE; return DEVICE_TO_PURE_RSSI(rssi); } @@ -1514,19 +1522,104 @@ uint8_t SI4463_RBW_1kHz[] = 0x00 }; -// -------------- kHz ---------------------------- +// -------------- 3 kHz ---------------------------- #undef RF_MODEM_TX_RAMP_DELAY_8_1 #undef RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 #undef RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 #undef RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 -#define RF_MODEM_TX_RAMP_DELAY_8_1 0x11, 0x20, 0x08, 0x18, 0x01, 0x00, 0x08, 0x03, 0x80, 0x00, 0x00, 0x30 +#define RF_MODEM_TX_RAMP_DELAY_8_1 0x11, 0x20, 0x08, 0x18, 0x01, 0x80, 0x08, 0x03, 0x80, 0x00, 0xF0, 0x11 +#define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 0x11, 0x21, 0x0C, 0x00, 0xCC, 0xA1, 0x30, 0xA0, 0x21, 0xD1, 0xB9, 0xC9, 0xEA, 0x05, 0x12, 0x11 +#define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 0x11, 0x21, 0x0C, 0x0C, 0x0A, 0x04, 0x15, 0xFC, 0x03, 0x00, 0xCC, 0xA1, 0x30, 0xA0, 0x21, 0xD1 +#define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 0x11, 0x21, 0x0C, 0x18, 0xB9, 0xC9, 0xEA, 0x05, 0x12, 0x11, 0x0A, 0x04, 0x15, 0xFC, 0x03, 0x00 + +uint8_t SI4463_RBW_3kHz[] = +{ + 0x0C, RF_MODEM_TX_RAMP_DELAY_8_1, \ + 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1, \ + 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1, \ + 0x10, RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1, \ + 0x00 +}; + +// -------------- 10 kHz ---------------------------- + +#undef RF_MODEM_TX_RAMP_DELAY_8_1 +#undef RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 +#undef RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 +#undef RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 + +#define RF_MODEM_TX_RAMP_DELAY_8_1 0x11, 0x20, 0x08, 0x18, 0x01, 0x80, 0x08, 0x03, 0x80, 0x00, 0xB0, 0x20 +#define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 0x11, 0x21, 0x0C, 0x00, 0xCC, 0xA1, 0x30, 0xA0, 0x21, 0xD1, 0xB9, 0xC9, 0xEA, 0x05, 0x12, 0x11 +#define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 0x11, 0x21, 0x0C, 0x0C, 0x0A, 0x04, 0x15, 0xFC, 0x03, 0x00, 0xCC, 0xA1, 0x30, 0xA0, 0x21, 0xD1 +#define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 0x11, 0x21, 0x0C, 0x18, 0xB9, 0xC9, 0xEA, 0x05, 0x12, 0x11, 0x0A, 0x04, 0x15, 0xFC, 0x03, 0x00 + + +uint8_t SI4463_RBW_10kHz[] = +{ + 0x0C, RF_MODEM_TX_RAMP_DELAY_8_1, \ + 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1, \ + 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1, \ + 0x10, RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1, \ + 0x00 +}; + +// -------------- 30 kHz ---------------------------- + +#undef RF_MODEM_TX_RAMP_DELAY_8_1 +#undef RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 +#undef RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 +#undef RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 + +#define RF_MODEM_TX_RAMP_DELAY_8_1 0x11, 0x20, 0x08, 0x18, 0x01, 0x80, 0x08, 0x03, 0x80, 0x00, 0x30, 0x10 +#define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 0x11, 0x21, 0x0C, 0x00, 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01 +#define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 0x11, 0x21, 0x0C, 0x0C, 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F, 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9 +#define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 0x11, 0x21, 0x0C, 0x18, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01, 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F + +uint8_t SI4463_RBW_30kHz[] = +{ + 0x0C, RF_MODEM_TX_RAMP_DELAY_8_1, \ + 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1, \ + 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1, \ + 0x10, RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1, \ + 0x00 +}; + +// -------------- 100kHz ---------------------------- + +#undef RF_MODEM_TX_RAMP_DELAY_8_1 +#undef RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 +#undef RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 +#undef RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 + +#define RF_MODEM_TX_RAMP_DELAY_8_1 0x11, 0x20, 0x08, 0x18, 0x01, 0x80, 0x08, 0x03, 0x80, 0x00, 0x20, 0x20 #define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 0x11, 0x21, 0x0C, 0x00, 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01 #define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 0x11, 0x21, 0x0C, 0x0C, 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F, 0xFF, 0xBA, 0x0F, 0x51, 0xCF, 0xA9 #define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 0x11, 0x21, 0x0C, 0x18, 0xC9, 0xFC, 0x1B, 0x1E, 0x0F, 0x01, 0xFC, 0xFD, 0x15, 0xFF, 0x00, 0x0F -uint8_t SI4463_RBW_kHz[] = +uint8_t SI4463_RBW_100kHz[] = +{ + 0x0C, RF_MODEM_TX_RAMP_DELAY_8_1, \ + 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1, \ + 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1, \ + 0x10, RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1, \ + 0x00 +}; + +// -------------- 300kHz ---------------------------- + +#undef RF_MODEM_TX_RAMP_DELAY_8_1 +#undef RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 +#undef RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 +#undef RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 + +#define RF_MODEM_TX_RAMP_DELAY_8_1 0x11, 0x20, 0x08, 0x18, 0x01, 0x80, 0x08, 0x03, 0x80, 0x00, 0x00, 0x20 +#define RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1 0x11, 0x21, 0x0C, 0x00, 0xCC, 0xA1, 0x30, 0xA0, 0x21, 0xD1, 0xB9, 0xC9, 0xEA, 0x05, 0x12, 0x11 +#define RF_MODEM_CHFLT_RX1_CHFLT_COE1_7_0_12_1 0x11, 0x21, 0x0C, 0x0C, 0x0A, 0x04, 0x15, 0xFC, 0x03, 0x00, 0xCC, 0xA1, 0x30, 0xA0, 0x21, 0xD1 +#define RF_MODEM_CHFLT_RX2_CHFLT_COE7_7_0_12_1 0x11, 0x21, 0x0C, 0x18, 0xB9, 0xC9, 0xEA, 0x05, 0x12, 0x11, 0x0A, 0x04, 0x15, 0xFC, 0x03, 0x00 + +uint8_t SI4463_RBW_300kHz[] = { 0x0C, RF_MODEM_TX_RAMP_DELAY_8_1, \ 0x10, RF_MODEM_CHFLT_RX1_CHFLT_COE13_7_0_12_1, \ @@ -1558,6 +1651,58 @@ uint8_t SI4463_RBW_850kHz[] = 0x00 }; +// User asks for an RBW of WISH, go through table finding the last triple +// for which WISH is greater than the first entry, use those values, +// Return the first entry of the following triple for the RBW actually achieved +#define IF_BW(dwn3, ndec, filset) (((dwn3)<<7)|((ndec)<<4)|(filset)) +typedef struct { + uint8_t *reg; // IF_BW(dwn3, ndec, filset) + int16_t RSSI_correction_x_10; // Correction * 10 + int16_t RBWx10; // RBW in kHz +}RBW_t; // sizeof(RBW_t) = 8 bytes + +static RBW_t RBW_choices[] = +{ +// BW register corr freq + {SI4463_RBW_1kHz, 0,10}, + {SI4463_RBW_3kHz, 0,30}, + {SI4463_RBW_10kHz, 0,100}, + {SI4463_RBW_30kHz, 0,300}, + {SI4463_RBW_100kHz,0,1000}, + {SI4463_RBW_300kHz,0,3000}, + {SI4463_RBW_850kHz,0,8500}, +}; + +static pureRSSI_t SI4463_RSSI_correction = float_TO_PURE_RSSI(-120); + +uint16_t SI4463_force_RBW(int i) +{ + setState(SI446X_STATE_TX_TUNE); + my_microsecond_delay(200); + + uint8_t *config = RBW_choices[i].reg; + for(uint16_t i=0;i