rx: implement squelch + symsync reset
Whenever the squelch opens, the symsync is reset to prevent lock-up in that module due to noise.
This commit is contained in:
parent
4b46d87edb
commit
91db4e1f75
|
@ -148,6 +148,49 @@ static bool acquire_preamble(layer1_rx_t *rx, const float complex sample, bool d
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum squelch_state_t {
|
||||||
|
SQUELCH_CLOSED,
|
||||||
|
SQUELCH_OPEN,
|
||||||
|
SQUELCH_JUST_OPENED,
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum squelch_state_t update_and_check_squelch(layer1_rx_t *rx, unsigned int sample_idx)
|
||||||
|
{
|
||||||
|
float level = agc_crcf_get_rssi(rx->agc);
|
||||||
|
enum squelch_state_t result = SQUELCH_CLOSED;
|
||||||
|
|
||||||
|
if((sample_idx & 0xFF) == 0) { // every 256 samples
|
||||||
|
if(level < rx->noise_floor_level) {
|
||||||
|
rx->noise_floor_level = level;
|
||||||
|
} else {
|
||||||
|
level += 1e-3; // slowly increase the measured noise floor level to compensate for drift
|
||||||
|
}
|
||||||
|
agc_crcf_squelch_set_threshold(rx->agc, rx->noise_floor_level + 3.0f); // in dB
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(agc_crcf_squelch_get_status(rx->agc)) {
|
||||||
|
case LIQUID_AGC_SQUELCH_RISE:
|
||||||
|
DEBUG_LOG("Squelch disabled at RSSI = %.3f dB\n", level);
|
||||||
|
result = SQUELCH_JUST_OPENED;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIQUID_AGC_SQUELCH_SIGNALHI:
|
||||||
|
result = SQUELCH_OPEN;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LIQUID_AGC_SQUELCH_FALL:
|
||||||
|
DEBUG_LOG("Squelch enabled at RSSI = %.3f dB\n", level);
|
||||||
|
case LIQUID_AGC_SQUELCH_SIGNALLO:
|
||||||
|
case LIQUID_AGC_SQUELCH_ENABLED:
|
||||||
|
case LIQUID_AGC_SQUELCH_TIMEOUT:
|
||||||
|
result = SQUELCH_CLOSED;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
result_t layer1_rx_process(layer1_rx_t *rx, const float complex *samples, size_t sample_count)
|
result_t layer1_rx_process(layer1_rx_t *rx, const float complex *samples, size_t sample_count)
|
||||||
{
|
{
|
||||||
static size_t symbol_counter = 0;
|
static size_t symbol_counter = 0;
|
||||||
|
@ -174,6 +217,20 @@ result_t layer1_rx_process(layer1_rx_t *rx, const float complex *samples, size_t
|
||||||
float complex agc_out;
|
float complex agc_out;
|
||||||
agc_crcf_execute(rx->agc, filtered_samples[i], &agc_out);
|
agc_crcf_execute(rx->agc, filtered_samples[i], &agc_out);
|
||||||
|
|
||||||
|
switch(update_and_check_squelch(rx, i)) {
|
||||||
|
case SQUELCH_CLOSED:
|
||||||
|
// ignore this sample
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case SQUELCH_JUST_OPENED:
|
||||||
|
symsync_crcf_reset(rx->symsync);
|
||||||
|
// fall through
|
||||||
|
case SQUELCH_OPEN:
|
||||||
|
// sample processing continues
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Mix the input signal with the carrier NCO, which oscillates at the
|
// Mix the input signal with the carrier NCO, which oscillates at the
|
||||||
// frequency coarsly estimated so far.
|
// frequency coarsly estimated so far.
|
||||||
float complex mixed_sample;
|
float complex mixed_sample;
|
||||||
|
@ -396,6 +453,11 @@ result_t layer1_rx_init(layer1_rx_t *rx, rx_callback_t callback)
|
||||||
rx->agc = agc_crcf_create();
|
rx->agc = agc_crcf_create();
|
||||||
agc_crcf_set_bandwidth(rx->agc, AGC_BW_ACQUISITION);
|
agc_crcf_set_bandwidth(rx->agc, AGC_BW_ACQUISITION);
|
||||||
|
|
||||||
|
// set up squelch
|
||||||
|
rx->noise_floor_level = 0.0f;
|
||||||
|
agc_crcf_squelch_set_threshold(rx->agc, rx->noise_floor_level + 3.0f); // in dB
|
||||||
|
agc_crcf_squelch_enable(rx->agc);
|
||||||
|
|
||||||
// create NCOs for carrier frequency compensation
|
// create NCOs for carrier frequency compensation
|
||||||
rx->carrier_coarse_nco = nco_crcf_create(LIQUID_NCO);
|
rx->carrier_coarse_nco = nco_crcf_create(LIQUID_NCO);
|
||||||
nco_crcf_set_frequency(rx->carrier_coarse_nco, 0.00f);
|
nco_crcf_set_frequency(rx->carrier_coarse_nco, 0.00f);
|
||||||
|
|
|
@ -34,6 +34,8 @@ typedef struct
|
||||||
// AGC
|
// AGC
|
||||||
agc_crcf agc;
|
agc_crcf agc;
|
||||||
|
|
||||||
|
float noise_floor_level;
|
||||||
|
|
||||||
// NCOs for carrier frequency offset correction
|
// NCOs for carrier frequency offset correction
|
||||||
nco_crcf carrier_coarse_nco;
|
nco_crcf carrier_coarse_nco;
|
||||||
nco_crcf carrier_fine_nco;
|
nco_crcf carrier_fine_nco;
|
||||||
|
|
Loading…
Reference in a new issue