main: restructure state management; evaluate a found preamble

This commit is contained in:
Thomas Kolb 2022-02-03 22:18:24 +01:00
parent 423f1d6416
commit 465d9a1c26

View file

@ -18,6 +18,17 @@ typedef enum {
RX_STATE_DATA, RX_STATE_DATA,
} rx_state_t; } rx_state_t;
void print_complex_array(const char *varname, float complex const *array, size_t len)
{
printf("%s=np.array([%f%+fj", varname, crealf(array[0]), cimagf(array[0]));
for(size_t k = 1; k < len; k++) {
printf(", %f%+fj", crealf(array[k]), cimagf(array[k]));
}
printf("])\n");
}
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...";
@ -28,7 +39,7 @@ int main(void)
channel_cccf channel = channel_cccf_create(); channel_cccf channel = channel_cccf_create();
float snr = 50.0f; float snr = 20.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);
@ -119,9 +130,46 @@ int main(void)
unsigned int out_len; unsigned int out_len;
symsync_crcf_execute(symsync, &mixed_sample, 1, symsync_out + symsync_out_len, &out_len); symsync_crcf_execute(symsync, &mixed_sample, 1, symsync_out + symsync_out_len, &out_len);
switch(rx_state) {
case RX_STATE_ACQUISITION:
if(out_len != 0) { if(out_len != 0) {
float complex corr_out;
switch(rx_state) {
// Try to acquire packets by synchronizing the frequency
// (symbol-independent search) and correlating the preamble.
case RX_STATE_ACQUISITION:
// preamble search
corr_out = correlator_step(&preamble_correlator, symsync_out[symsync_out_len]);
if(cabsf(corr_out) > 0.5f * preamble_get_symbol_count()) {
// Preamble found!
printf("Preamble found at symbol %u: %.3f > %.3f\n", i/RRC_SPS, cabsf(corr_out), 0.5f * preamble_get_symbol_count());
float mean_phase_error = correlator_get_mean_phase_deviation(&preamble_correlator);
float mean_frequency_error = correlator_get_mean_frequency_deviation(&preamble_correlator);
printf("Preamble phase deviation: %.6f rad\n", mean_phase_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
nco_crcf_adjust_frequency(carrier_nco, -mean_frequency_error / RRC_SPS);
nco_crcf_adjust_phase(carrier_nco, mean_phase_error);
printf("New estimated carrier frequency: %.6f\n", nco_crcf_get_frequency(carrier_nco));
float complex input_history[preamble_get_symbol_count()];
correlator_get_input_history(&preamble_correlator, input_history);
printf("import numpy as np\n");
printf("import matplotlib.pyplot as pp\n");
print_complex_array("pre", preamble_get_symbols(), preamble_get_symbol_count());
print_complex_array("recv", input_history, preamble_get_symbol_count());
printf("pp.plot(recv * pre.conj())\n");
printf("pp.show()\n");
// receive and decode the header
rx_state = RX_STATE_HEADER;
} else {
// preamble not found.
// for all the output samples produced, run the frequency // for all the output samples produced, run the frequency
// estimator. This is an implementation that works with unknown // estimator. This is an implementation that works with unknown
// BPSK symbols and therefore can be used during ramp-up and // BPSK symbols and therefore can be used during ramp-up and
@ -166,7 +214,7 @@ int main(void)
float lms_phase_change = numerator / denominator; float lms_phase_change = numerator / denominator;
float freq_adjustment = (lms_phase_change / RRC_SPS / 2) * 0.3f; float freq_adjustment = (lms_phase_change / RRC_SPS / 2) * 0.5f;
nco_crcf_adjust_frequency(carrier_nco, freq_adjustment); nco_crcf_adjust_frequency(carrier_nco, freq_adjustment);
printf("Frequency adjustment: %.6f - carrier frequency: %.6f\n", freq_adjustment, nco_crcf_get_frequency(carrier_nco)); printf("Frequency adjustment: %.6f - carrier frequency: %.6f\n", freq_adjustment, nco_crcf_get_frequency(carrier_nco));
@ -187,14 +235,6 @@ int main(void)
case RX_STATE_DATA: case RX_STATE_DATA:
break; break;
} }
// preamble search
if(out_len != 0) {
float complex corr_out = correlator_step(&preamble_correlator, symsync_out[symsync_out_len]);
if(cabsf(corr_out) > 0.5f * preamble_get_symbol_count()) {
printf("Preamble found at sample %u: %.3f > %.3f\n", i/RRC_SPS, cabsf(corr_out), 0.5f * preamble_get_symbol_count());
}
} }
symsync_out_len += out_len; symsync_out_len += out_len;