Implement CRC check and phase tracking
This commit is contained in:
parent
947615f5cd
commit
87b844a2da
|
@ -3,12 +3,14 @@
|
||||||
|
|
||||||
#include <liquid/liquid.h>
|
#include <liquid/liquid.h>
|
||||||
|
|
||||||
#define CHANNEL_CODE LIQUID_FEC_CONV_V27P34
|
#define PAYLOAD_CHANNEL_CODE LIQUID_FEC_CONV_V27P34
|
||||||
#define MODULATION LIQUID_MODEM_QAM16
|
#define PAYLOAD_MODULATION LIQUID_MODEM_QAM16
|
||||||
|
|
||||||
#define HEADER_CHANNEL_CODE LIQUID_FEC_NONE
|
#define HEADER_CHANNEL_CODE LIQUID_FEC_NONE
|
||||||
#define HEADER_MODULATION LIQUID_MODEM_QPSK
|
#define HEADER_MODULATION LIQUID_MODEM_QPSK
|
||||||
|
|
||||||
|
#define PAYLOAD_CRC_SCHEME LIQUID_CRC_16
|
||||||
|
|
||||||
#define PREAMBLE_MSEQ_M 6
|
#define PREAMBLE_MSEQ_M 6
|
||||||
#define PREAMBLE_MSEQ_POLY LIQUID_MSEQUENCE_GENPOLY_M6
|
#define PREAMBLE_MSEQ_POLY LIQUID_MSEQUENCE_GENPOLY_M6
|
||||||
#define PREAMBLE_MSEQ_INIT 0x00000001
|
#define PREAMBLE_MSEQ_INIT 0x00000001
|
||||||
|
|
|
@ -30,6 +30,16 @@ void print_complex_array(const char *varname, float complex const *array, size_t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void update_nco_pll(nco_crcf nco, float phase_error)
|
||||||
|
{
|
||||||
|
static const float pll_alpha = 0.05f; // phase adjustment factor
|
||||||
|
static const float pll_beta = (pll_alpha * pll_alpha) / 2.0f; // frequency adjustment factor
|
||||||
|
|
||||||
|
nco_crcf_adjust_phase(nco, pll_alpha * phase_error);
|
||||||
|
nco_crcf_adjust_frequency(nco, pll_beta * phase_error);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(void)
|
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...";
|
||||||
|
@ -37,14 +47,14 @@ int main(void)
|
||||||
uint8_t header[4];
|
uint8_t header[4];
|
||||||
|
|
||||||
fec hdr_fec = fec_create(HEADER_CHANNEL_CODE, NULL);
|
fec hdr_fec = fec_create(HEADER_CHANNEL_CODE, NULL);
|
||||||
fec payload_fec = fec_create(CHANNEL_CODE, NULL);
|
fec payload_fec = fec_create(PAYLOAD_CHANNEL_CODE, NULL);
|
||||||
|
|
||||||
modem hdr_demod = modem_create(HEADER_MODULATION);
|
modem hdr_demod = modem_create(HEADER_MODULATION);
|
||||||
modem payload_demod = modem_create(MODULATION);
|
modem payload_demod = modem_create(PAYLOAD_MODULATION);
|
||||||
|
|
||||||
channel_cccf channel = channel_cccf_create();
|
channel_cccf channel = channel_cccf_create();
|
||||||
|
|
||||||
float snr = 12.0f;
|
float snr = 7.0f;
|
||||||
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);
|
||||||
|
|
||||||
|
@ -210,7 +220,11 @@ int main(void)
|
||||||
if(symbol_counter < hdr_len_symbols) {
|
if(symbol_counter < hdr_len_symbols) {
|
||||||
unsigned int sym_demod;
|
unsigned int sym_demod;
|
||||||
modem_demodulate(hdr_demod, mixed_sample, &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));
|
|
||||||
|
float phase_error = modem_get_demodulator_phase_error(hdr_demod);
|
||||||
|
printf("Sym: %d; Phase error: %f\n", sym_demod, phase_error);
|
||||||
|
|
||||||
|
update_nco_pll(carrier_fine_nco, phase_error);
|
||||||
|
|
||||||
symbols_cpx[symbol_counter] = mixed_sample;
|
symbols_cpx[symbol_counter] = mixed_sample;
|
||||||
symbols_int[symbol_counter] = sym_demod;
|
symbols_int[symbol_counter] = sym_demod;
|
||||||
|
@ -230,7 +244,7 @@ int main(void)
|
||||||
payload_len_bytes = ((uint16_t)header[0] << 8) | header[1];
|
payload_len_bytes = ((uint16_t)header[0] << 8) | header[1];
|
||||||
payload_crc = ((uint16_t)header[2] << 8) | header[3];
|
payload_crc = ((uint16_t)header[2] << 8) | header[3];
|
||||||
|
|
||||||
payload_len_enc_bytes = fec_get_enc_msg_length(CHANNEL_CODE, payload_len_bytes);
|
payload_len_enc_bytes = fec_get_enc_msg_length(PAYLOAD_CHANNEL_CODE, payload_len_bytes);
|
||||||
payload_len_symbols = (payload_len_enc_bytes * 8 + payload_bps - 1) / payload_bps;
|
payload_len_symbols = (payload_len_enc_bytes * 8 + payload_bps - 1) / payload_bps;
|
||||||
|
|
||||||
printf("=== DECODED HEADER ===\n");
|
printf("=== DECODED HEADER ===\n");
|
||||||
|
@ -250,7 +264,11 @@ int main(void)
|
||||||
if(symbol_counter < payload_len_symbols) {
|
if(symbol_counter < payload_len_symbols) {
|
||||||
unsigned int sym_demod;
|
unsigned int sym_demod;
|
||||||
modem_demodulate(payload_demod, mixed_sample, &sym_demod);
|
modem_demodulate(payload_demod, mixed_sample, &sym_demod);
|
||||||
printf("Sym: %d; Phase error: %f\n", sym_demod, modem_get_demodulator_phase_error(payload_demod));
|
|
||||||
|
float phase_error = modem_get_demodulator_phase_error(payload_demod);
|
||||||
|
printf("Sym: %d; Phase error: %f\n", sym_demod, phase_error);
|
||||||
|
|
||||||
|
update_nco_pll(carrier_fine_nco, phase_error);
|
||||||
|
|
||||||
symbols_cpx[symbol_counter] = mixed_sample;
|
symbols_cpx[symbol_counter] = mixed_sample;
|
||||||
symbols_int[symbol_counter] = sym_demod;
|
symbols_int[symbol_counter] = sym_demod;
|
||||||
|
@ -268,11 +286,13 @@ int main(void)
|
||||||
|
|
||||||
fec_decode(payload_fec, payload_len_bytes, payload_enc, payload);
|
fec_decode(payload_fec, payload_len_bytes, payload_enc, payload);
|
||||||
|
|
||||||
|
int valid = crc_validate_message(PAYLOAD_CRC_SCHEME, payload, payload_len_bytes, payload_crc);
|
||||||
|
|
||||||
payload[payload_len_bytes] = '\0';
|
payload[payload_len_bytes] = '\0';
|
||||||
|
|
||||||
printf("=== DECODED PAYLOAD ===\n");
|
printf("=== DECODED PAYLOAD (valid: %d) ===\n", valid);
|
||||||
printf("%s\n", payload);
|
printf("%s\n", payload);
|
||||||
printf("=======================\n");
|
printf("==================================\n");
|
||||||
|
|
||||||
dump_array_cf(symbols_cpx, symbol_counter, 1.0f, "/tmp/payload.cpx");
|
dump_array_cf(symbols_cpx, symbol_counter, 1.0f, "/tmp/payload.cpx");
|
||||||
rx_state = RX_STATE_ACQUISITION;
|
rx_state = RX_STATE_ACQUISITION;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <liquid/liquid.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "preamble.h"
|
#include "preamble.h"
|
||||||
|
@ -12,8 +13,8 @@ result_t packet_mod_init(packet_mod_ctx_t *ctx)
|
||||||
|
|
||||||
ctx->length = 0;
|
ctx->length = 0;
|
||||||
|
|
||||||
ctx->fec = fec_create(CHANNEL_CODE, NULL);
|
ctx->fec = fec_create(PAYLOAD_CHANNEL_CODE, NULL);
|
||||||
ctx->modem = modem_create(MODULATION);
|
ctx->modem = modem_create(PAYLOAD_MODULATION);
|
||||||
|
|
||||||
ctx->hdr_fec = fec_create(HEADER_CHANNEL_CODE, NULL);
|
ctx->hdr_fec = fec_create(HEADER_CHANNEL_CODE, NULL);
|
||||||
ctx->hdr_modem = modem_create(HEADER_MODULATION);
|
ctx->hdr_modem = modem_create(HEADER_MODULATION);
|
||||||
|
@ -72,6 +73,7 @@ result_t packet_mod_set_data(packet_mod_ctx_t *ctx, const unsigned char *data, s
|
||||||
memcpy(ctx->pkt_bytes, data, length);
|
memcpy(ctx->pkt_bytes, data, length);
|
||||||
ctx->length = length;
|
ctx->length = length;
|
||||||
|
|
||||||
|
ctx->raw_data_crc = crc_generate_key(PAYLOAD_CRC_SCHEME, data, length);
|
||||||
ctx->raw_data_len = length;
|
ctx->raw_data_len = length;
|
||||||
|
|
||||||
ctx->state = DATA_RAW;
|
ctx->state = DATA_RAW;
|
||||||
|
@ -86,7 +88,7 @@ result_t packet_mod_encode(packet_mod_ctx_t *ctx)
|
||||||
return ERR_INVALID_STATE;
|
return ERR_INVALID_STATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int enc_length = fec_get_enc_msg_length(CHANNEL_CODE, ctx->length);
|
unsigned int enc_length = fec_get_enc_msg_length(PAYLOAD_CHANNEL_CODE, ctx->length);
|
||||||
|
|
||||||
unsigned char *enc_msg = malloc(enc_length);
|
unsigned char *enc_msg = malloc(enc_length);
|
||||||
if(!enc_msg) {
|
if(!enc_msg) {
|
||||||
|
|
Loading…
Reference in a new issue