Decode the received header

This commit is contained in:
Thomas Kolb 2022-02-10 22:33:51 +01:00
parent f2c95a125d
commit 042c05f9f3

View file

@ -34,8 +34,11 @@ int main(void)
{ {
uint8_t msg_org[] = "Hello Liquid! This is the message to transmit. Hopefully it can be decoded correctly..."; uint8_t msg_org[] = "Hello Liquid! This is the message to transmit. Hopefully it can be decoded correctly...";
fec q = fec_create(CHANNEL_CODE, NULL); uint8_t header[4];
fec hdr_fec = fec_create(HEADER_CHANNEL_CODE, NULL);
modem hdr_demod = modem_create(HEADER_MODULATION);
modem demod = modem_create(MODULATION); modem demod = modem_create(MODULATION);
channel_cccf channel = channel_cccf_create(); channel_cccf channel = channel_cccf_create();
@ -44,6 +47,10 @@ int main(void)
channel_cccf_add_awgn(channel, -snr, snr); channel_cccf_add_awgn(channel, -snr, snr);
channel_cccf_add_carrier_offset(channel, 0.20f, 1.00f); channel_cccf_add_carrier_offset(channel, 0.20f, 1.00f);
// precalculate encoded header length in symbols
unsigned int hdr_len_enc_bytes = fec_get_enc_msg_length(HEADER_CHANNEL_CODE, sizeof(header));
unsigned int hdr_bps = modem_get_bps(hdr_demod);
unsigned int hdr_len_symbols = (hdr_len_enc_bytes * 8 + hdr_bps - 1) / hdr_bps;
packet_mod_ctx_t pmod; packet_mod_ctx_t pmod;
packet_mod_init(&pmod); packet_mod_init(&pmod);
@ -98,17 +105,25 @@ int main(void)
channel_cccf_execute_block(channel, whole_burst, burst_len, msg_received); channel_cccf_execute_block(channel, whole_burst, burst_len, msg_received);
dump_array_cf(msg_received, burst_len, 1.0f, "/tmp/rx.cpx"); dump_array_cf(msg_received, burst_len, 1.0f, "/tmp/rx.cpx");
// create NCO for carrier frequency compensation // create NCOs for carrier frequency compensation
nco_crcf carrier_nco = nco_crcf_create(LIQUID_NCO); nco_crcf carrier_nco = nco_crcf_create(LIQUID_NCO);
nco_crcf_set_frequency(carrier_nco, 0.00f); nco_crcf_set_frequency(carrier_nco, 0.00f);
nco_crcf_set_phase(carrier_nco, 0.0f); nco_crcf_set_phase(carrier_nco, 0.0f);
nco_crcf carrier_fine_nco = nco_crcf_create(LIQUID_NCO);
nco_crcf_set_frequency(carrier_fine_nco, 0.00f);
nco_crcf_set_phase(carrier_fine_nco, 0.0f);
// create symbol synchronizer // create symbol synchronizer
symsync_crcf symsync = symsync_crcf_create_rnyquist(LIQUID_FIRFILT_RRC, RRC_SPS, RRC_DELAY, RRC_BETA, 32); symsync_crcf symsync = symsync_crcf_create_rnyquist(LIQUID_FIRFILT_RRC, RRC_SPS, RRC_DELAY, RRC_BETA, 32);
float complex symsync_out[burst_len]; float complex symsync_out[burst_len];
unsigned int symsync_out_len = 0; unsigned int symsync_out_len = 0;
float complex symbols_cpx[16384];
unsigned char symbols_int[16384];
unsigned int symbol_counter = 0; // for demodulation
#define FREQ_EST_L 8 #define FREQ_EST_L 8
// General receiver state // General receiver state
rx_state_t rx_state = RX_STATE_ACQUISITION; rx_state_t rx_state = RX_STATE_ACQUISITION;
@ -148,10 +163,10 @@ int main(void)
printf("Preamble frequency deviation: %.6f rad/symbol\n", mean_frequency_error); printf("Preamble frequency deviation: %.6f rad/symbol\n", mean_frequency_error);
// adjust the frequency and phase of the NCO with the estimations from the preamble // adjust the frequency and phase of the NCO with the estimations from the preamble
nco_crcf_adjust_frequency(carrier_nco, mean_frequency_error / RRC_SPS * 0.5f); nco_crcf_set_frequency(carrier_fine_nco, mean_frequency_error / RRC_SPS * 0.5f);
nco_crcf_adjust_phase(carrier_nco, phase_offset); nco_crcf_set_phase(carrier_fine_nco, phase_offset);
printf("New estimated carrier frequency: %.6f\n", nco_crcf_get_frequency(carrier_nco)); printf("New estimated carrier frequency: %.6f + %.6f\n", nco_crcf_get_frequency(carrier_nco), nco_crcf_get_frequency(carrier_fine_nco));
float complex input_history[preamble_get_symbol_count()]; float complex input_history[preamble_get_symbol_count()];
correlator_get_input_history(&preamble_correlator, input_history); correlator_get_input_history(&preamble_correlator, input_history);
@ -165,6 +180,7 @@ int main(void)
// receive and decode the header // receive and decode the header
rx_state = RX_STATE_HEADER; rx_state = RX_STATE_HEADER;
symbol_counter = 0;
} else { } else {
// preamble not found. // preamble not found.
@ -183,6 +199,40 @@ int main(void)
break; break;
case RX_STATE_HEADER: case RX_STATE_HEADER:
nco_crcf_mix_down(carrier_fine_nco, symsync_out[symsync_out_len], &mixed_sample);
if(symbol_counter < hdr_len_symbols) {
unsigned int sym_demod;
modem_demodulate(hdr_demod, mixed_sample, &sym_demod);
printf("Sym: %d; Phase error: %f\n", sym_demod, modem_get_demodulator_phase_error(hdr_demod));
symbols_cpx[symbol_counter] = mixed_sample;
symbols_int[symbol_counter] = sym_demod;
symbol_counter++;
}
if(symbol_counter == hdr_len_symbols) {
unsigned int nsyms;
unsigned char header_enc[4];
ERR_CHECK_LIQUID(liquid_repack_bytes(
symbols_int, modem_get_bps(hdr_demod), hdr_len_symbols,
header_enc, 8, sizeof(header_enc), &nsyms));
fec_decode(hdr_fec, sizeof(header), header_enc, header);
uint16_t payload_len = ((uint16_t)header[0] << 8) | header[1];
uint16_t payload_crc = ((uint16_t)header[2] << 8) | header[3];
printf("=== DECODED HEADER ===\n");
printf("Payload length: %u\n", payload_len);
printf("CRC16: 0x%04x\n", payload_crc);
printf("======================\n");
dump_array_cf(symbols_cpx, symbol_counter, 1.0f, "/tmp/hdr.cpx");
rx_state = RX_STATE_DATA;
}
break;
case RX_STATE_DATA: case RX_STATE_DATA:
break; break;
} }
@ -236,9 +286,10 @@ int main(void)
symsync_crcf_destroy(symsync); symsync_crcf_destroy(symsync);
fec_destroy(q); fec_destroy(hdr_fec);
modem_destroy(demod); modem_destroy(demod);
modem_destroy(hdr_demod);
channel_cccf_destroy(channel); channel_cccf_destroy(channel);