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)
|
||||
{
|
||||
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;
|
||||
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
|
||||
// frequency coarsly estimated so far.
|
||||
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();
|
||||
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
|
||||
rx->carrier_coarse_nco = nco_crcf_create(LIQUID_NCO);
|
||||
nco_crcf_set_frequency(rx->carrier_coarse_nco, 0.00f);
|
||||
|
|
|
@ -34,6 +34,8 @@ typedef struct
|
|||
// AGC
|
||||
agc_crcf agc;
|
||||
|
||||
float noise_floor_level;
|
||||
|
||||
// NCOs for carrier frequency offset correction
|
||||
nco_crcf carrier_coarse_nco;
|
||||
nco_crcf carrier_fine_nco;
|
||||
|
|
Loading…
Reference in a new issue