From 84c172abc7b18f9bc97484e12e3392e7c1ca4064 Mon Sep 17 00:00:00 2001 From: Thomas Kolb Date: Fri, 5 Jan 2024 21:28:38 +0100 Subject: [PATCH] Fixed iterative frequency refinement; count header errors --- impl/src/layer1/freq_est.c | 2 +- impl/src/layer1/rx.c | 43 +++++++++++++++++++++++++------------- impl/src/layer1/rx.h | 1 + impl/src/main.c | 7 +++++++ 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/impl/src/layer1/freq_est.c b/impl/src/layer1/freq_est.c index 51f2041..458f943 100644 --- a/impl/src/layer1/freq_est.c +++ b/impl/src/layer1/freq_est.c @@ -148,7 +148,7 @@ float freq_est_in_rampup(const float complex *recv, size_t n, float *final_phase float phase = cargf(rotated[i]); if(i > 0) { float phase_delta = phase - prev_phase; - if(fabsf(phase_delta) > 3.14159f/4.0f) { + if(fabsf(phase_delta) > 3.14159f/2.0f) { // abort because we either have the wrong signal or too much noise. if(final_phase) { *final_phase = 0.0f; diff --git a/impl/src/layer1/rx.c b/impl/src/layer1/rx.c index 293546b..7ef8054 100644 --- a/impl/src/layer1/rx.c +++ b/impl/src/layer1/rx.c @@ -102,21 +102,26 @@ static bool acquire_preamble(layer1_rx_t *rx, const float complex sample) float freq_est = freq_est_in_rampup(freq_est_history, FREQ_EST_L, NULL); - float freq_adjustment = freq_est / RRC_SPS; - nco_crcf_adjust_frequency(rx->carrier_coarse_nco, freq_adjustment); - - float actual_freq = nco_crcf_get_frequency(rx->carrier_coarse_nco); - if(actual_freq > MAX_COARSE_FREQ_OFFSET) { - //fprintf(stderr, ">"); - nco_crcf_set_frequency(rx->carrier_coarse_nco, MAX_COARSE_FREQ_OFFSET); - } else if(actual_freq < -MAX_COARSE_FREQ_OFFSET) { - //fprintf(stderr, "<"); - nco_crcf_set_frequency(rx->carrier_coarse_nco, -MAX_COARSE_FREQ_OFFSET); - } - - //freq_est_history_write_idx = 0; - + // freq_est_in_rampup will return exactly 0.0 if (and probably only if) + // the sequency quality is not good enough. We skip the adjustment in + // this case. if(freq_est != 0.0f) { + // apply the frequency adjustment + float freq_adjustment = freq_est / RRC_SPS / FREQ_EST_L; + nco_crcf_adjust_frequency(rx->carrier_coarse_nco, freq_adjustment); + + // limit the absolute frequency offset value + float actual_freq = nco_crcf_get_frequency(rx->carrier_coarse_nco); + if(actual_freq > MAX_COARSE_FREQ_OFFSET) { + //fprintf(stderr, ">"); + nco_crcf_set_frequency(rx->carrier_coarse_nco, MAX_COARSE_FREQ_OFFSET); + } else if(actual_freq < -MAX_COARSE_FREQ_OFFSET) { + //fprintf(stderr, "<"); + nco_crcf_set_frequency(rx->carrier_coarse_nco, -MAX_COARSE_FREQ_OFFSET); + } + + //freq_est_history_write_idx = 0; + DEBUG_LOG("Freq. est (x%d): %0.6f - Adj (x1): %.6f - carrier frequency (x1): %.6f\n", RRC_SPS, freq_est, freq_adjustment, nco_crcf_get_frequency(rx->carrier_coarse_nco)); @@ -227,7 +232,12 @@ result_t layer1_rx_process(layer1_rx_t *rx, const float complex *samples, size_t symbols_int, modem_get_bps(rx->hdr_demod), rx->hdr_len_symbols, header_enc, 8, sizeof(header_enc), &nsyms)); - fec_decode(rx->hdr_fec, sizeof(header), header_enc, header); + if(fec_decode(rx->hdr_fec, sizeof(header), header_enc, header) != LIQUID_OK) { + DEBUG_LOG("Header decoding failed!\n", rx->modcod); + rx->state = RX_STATE_ACQUISITION; + rx->callback(RX_EVT_HEADER_ERROR, NULL, 0); + break; + } rx->payload_len_bytes = (((uint16_t)header[0] << 8) | header[1]) & 0x07FF; rx->payload_crc = ((uint16_t)header[2] << 8) | header[3]; @@ -237,6 +247,7 @@ result_t layer1_rx_process(layer1_rx_t *rx, const float complex *samples, size_t if(!MODCOD_IS_VALID(rx->modcod)) { DEBUG_LOG("Decoded MODCOD %d is invalid!\n", rx->modcod); rx->state = RX_STATE_ACQUISITION; + rx->callback(RX_EVT_HEADER_ERROR, NULL, 0); break; } @@ -244,6 +255,7 @@ result_t layer1_rx_process(layer1_rx_t *rx, const float complex *samples, size_t if(rx->payload_len_bytes == 0) { DEBUG_LOG("Packet length %u is not supported.\n", rx->payload_len_bytes); rx->state = RX_STATE_ACQUISITION; + rx->callback(RX_EVT_HEADER_ERROR, NULL, 0); break; } @@ -256,6 +268,7 @@ result_t layer1_rx_process(layer1_rx_t *rx, const float complex *samples, size_t if(rx->payload_len_symbols > SYMBOL_BUFFER_SIZE) { DEBUG_LOG("Symbol count %u is too lange for buffer. Ignoring packet.\n", rx->payload_len_symbols); rx->state = RX_STATE_ACQUISITION; + rx->callback(RX_EVT_HEADER_ERROR, NULL, 0); break; } diff --git a/impl/src/layer1/rx.h b/impl/src/layer1/rx.h index d632346..da9d883 100644 --- a/impl/src/layer1/rx.h +++ b/impl/src/layer1/rx.h @@ -18,6 +18,7 @@ typedef enum { typedef enum { RX_EVT_PACKET_RECEIVED, RX_EVT_PREAMBLE_FOUND, + RX_EVT_HEADER_ERROR, RX_EVT_CHECKSUM_ERROR, } rx_evt_t; diff --git a/impl/src/main.c b/impl/src/main.c index 5fc5c33..e1869e2 100644 --- a/impl/src/main.c +++ b/impl/src/main.c @@ -38,6 +38,7 @@ static struct { size_t preambles_found; size_t successful_decodes; size_t failed_decodes; + size_t header_errors; } m_stats; @@ -122,6 +123,10 @@ void cb_rx(rx_evt_t evt, uint8_t *packet_data, size_t packet_len) m_stats.failed_decodes++; break; + case RX_EVT_HEADER_ERROR: + m_stats.header_errors++; + break; + case RX_EVT_PACKET_RECEIVED: //fprintf(stderr, "A message of %zu bytes was decoded successfully.\n", packet_len); //fprintf(stderr, "=== DECODED PAYLOAD (%4zu bytes) ===\n", packet_len); @@ -352,6 +357,8 @@ int main(void) fprintf(stderr, " Preambles found: %8zd\n", m_stats.preambles_found); fprintf(stderr, " Successful decodes: %8zd (%6.2f %%)\n", m_stats.successful_decodes, m_stats.successful_decodes * 100.0f / m_stats.preambles_found); + fprintf(stderr, " Header errors: %8zd (%6.2f %%)\n", + m_stats.header_errors, m_stats.header_errors * 100.0f / m_stats.preambles_found); fprintf(stderr, " Failed decodes: %8zd (%6.2f %%)\n", m_stats.failed_decodes, m_stats.failed_decodes * 100.0f / m_stats.preambles_found); next_stats_print_time += 0.5;