Fixed iterative frequency refinement; count header errors

This commit is contained in:
Thomas Kolb 2024-01-05 21:28:38 +01:00
parent 3a4be428b5
commit 84c172abc7
4 changed files with 37 additions and 16 deletions

View file

@ -148,7 +148,7 @@ float freq_est_in_rampup(const float complex *recv, size_t n, float *final_phase
float phase = cargf(rotated[i]); float phase = cargf(rotated[i]);
if(i > 0) { if(i > 0) {
float phase_delta = phase - prev_phase; 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. // abort because we either have the wrong signal or too much noise.
if(final_phase) { if(final_phase) {
*final_phase = 0.0f; *final_phase = 0.0f;

View file

@ -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_est = freq_est_in_rampup(freq_est_history, FREQ_EST_L, NULL);
float freq_adjustment = freq_est / RRC_SPS; // freq_est_in_rampup will return exactly 0.0 if (and probably only if)
nco_crcf_adjust_frequency(rx->carrier_coarse_nco, freq_adjustment); // the sequency quality is not good enough. We skip the adjustment in
// this case.
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;
if(freq_est != 0.0f) { 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", 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)); 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, symbols_int, modem_get_bps(rx->hdr_demod), rx->hdr_len_symbols,
header_enc, 8, sizeof(header_enc), &nsyms)); 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_len_bytes = (((uint16_t)header[0] << 8) | header[1]) & 0x07FF;
rx->payload_crc = ((uint16_t)header[2] << 8) | header[3]; 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)) { if(!MODCOD_IS_VALID(rx->modcod)) {
DEBUG_LOG("Decoded MODCOD %d is invalid!\n", rx->modcod); DEBUG_LOG("Decoded MODCOD %d is invalid!\n", rx->modcod);
rx->state = RX_STATE_ACQUISITION; rx->state = RX_STATE_ACQUISITION;
rx->callback(RX_EVT_HEADER_ERROR, NULL, 0);
break; 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) { if(rx->payload_len_bytes == 0) {
DEBUG_LOG("Packet length %u is not supported.\n", rx->payload_len_bytes); DEBUG_LOG("Packet length %u is not supported.\n", rx->payload_len_bytes);
rx->state = RX_STATE_ACQUISITION; rx->state = RX_STATE_ACQUISITION;
rx->callback(RX_EVT_HEADER_ERROR, NULL, 0);
break; 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) { 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); DEBUG_LOG("Symbol count %u is too lange for buffer. Ignoring packet.\n", rx->payload_len_symbols);
rx->state = RX_STATE_ACQUISITION; rx->state = RX_STATE_ACQUISITION;
rx->callback(RX_EVT_HEADER_ERROR, NULL, 0);
break; break;
} }

View file

@ -18,6 +18,7 @@ typedef enum {
typedef enum { typedef enum {
RX_EVT_PACKET_RECEIVED, RX_EVT_PACKET_RECEIVED,
RX_EVT_PREAMBLE_FOUND, RX_EVT_PREAMBLE_FOUND,
RX_EVT_HEADER_ERROR,
RX_EVT_CHECKSUM_ERROR, RX_EVT_CHECKSUM_ERROR,
} rx_evt_t; } rx_evt_t;

View file

@ -38,6 +38,7 @@ static struct {
size_t preambles_found; size_t preambles_found;
size_t successful_decodes; size_t successful_decodes;
size_t failed_decodes; size_t failed_decodes;
size_t header_errors;
} m_stats; } 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++; m_stats.failed_decodes++;
break; break;
case RX_EVT_HEADER_ERROR:
m_stats.header_errors++;
break;
case RX_EVT_PACKET_RECEIVED: case RX_EVT_PACKET_RECEIVED:
//fprintf(stderr, "A message of %zu bytes was decoded successfully.\n", packet_len); //fprintf(stderr, "A message of %zu bytes was decoded successfully.\n", packet_len);
//fprintf(stderr, "=== DECODED PAYLOAD (%4zu bytes) ===\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, " Preambles found: %8zd\n", m_stats.preambles_found);
fprintf(stderr, " Successful decodes: %8zd (%6.2f %%)\n", fprintf(stderr, " Successful decodes: %8zd (%6.2f %%)\n",
m_stats.successful_decodes, m_stats.successful_decodes * 100.0f / m_stats.preambles_found); 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", fprintf(stderr, " Failed decodes: %8zd (%6.2f %%)\n",
m_stats.failed_decodes, m_stats.failed_decodes * 100.0f / m_stats.preambles_found); m_stats.failed_decodes, m_stats.failed_decodes * 100.0f / m_stats.preambles_found);
next_stats_print_time += 0.5; next_stats_print_time += 0.5;