% Symbol rate processing for rx side (demodulator) -------------------------------------------------------
-function [rx_symb rx_bits rx_symb_linear amp_linear amp_ phi_ EsNo_ prev_sym_rx sim_in] = symbol_rate_rx(sim_in, s_ch, prev_sym_rx)
+function [rx_symb rx_bits rx_symb_linear amp_linear amp_ phi_ EsNo_ prev_sym_rx sim_in] = qpsk_symbols_to_bits(sim_in, s_ch, prev_sym_rx)
framesize = sim_in.framesize;
Nsymb = sim_in.Nsymb;
Nsymbrow = sim_in.Nsymbrow;
tx_bits = round(rand(1,framesize));
tx_bits_log = [];
tx_symb_log = [];
+rx_amp_log = [];
+rx_phi_log = [];
+rx_symb_log = [];
+rx_bits_log = [];
for i=1:frames
- tx_bits_log = [tx_bits_log tx_bits];
+ tx_bits_log = [tx_bits_log tx_bits];
[tx_symb tx_bits prev_tx_sym] = bits_to_qpsk_symbols(sim_in, tx_bits, [], []);
- tx_symb_log = [tx_symb_log; tx_symb];
+ tx_symb_log = [tx_symb_log; tx_symb];
+ [rx_symb rx_bits rx_symb_linear amp_linear amp_ phi_ EsNo_ prev_sym_rx sim_in] = qpsk_symbols_to_bits(sim_in, tx_symb, []);
+ rx_symb_log = [rx_symb_log; rx_symb];
+ rx_amp_log = [rx_amp_log; amp_];
+ rx_phi_log = [rx_phi_log; phi_];
+ rx_bits_log = [rx_bits_log; rx_bits];
end
stem_sig_and_error(1, 111, tx_bits_log_c(1:n), tx_bits_log(1:n) - tx_bits_log_c(1:n), 'tx bits', [1 n -1.5 1.5])
stem_sig_and_error(2, 211, real(tx_symb_log_c(1:n)), real(tx_symb_log(1:n) - tx_symb_log_c(1:n)), 'tx symb re', [1 n -1.5 1.5])
stem_sig_and_error(2, 212, imag(tx_symb_log_c(1:n)), imag(tx_symb_log(1:n) - tx_symb_log_c(1:n)), 'tx symb im', [1 n -1.5 1.5])
+stem_sig_and_error(3, 211, rx_amp_log_c(1:n), rx_amp_log(1:n) - rx_amp_log_c(1:n), 'Amp Est', [1 n -1.5 1.5])
+stem_sig_and_error(3, 212, rx_phi_log_c(1:n), rx_phi_log(1:n) - rx_phi_log_c(1:n), 'Phase Est', [1 n -4 4])
+stem_sig_and_error(4, 211, real(rx_symb_log_c(1:n)), real(rx_symb_log(1:n) - rx_symb_log_c(1:n)), 'rx symb re', [1 n -1.5 1.5])
+stem_sig_and_error(4, 212, imag(rx_symb_log_c(1:n)), imag(rx_symb_log(1:n) - rx_symb_log_c(1:n)), 'rx symb im', [1 n -1.5 1.5])
+
check(tx_bits_log, tx_bits_log_c, 'tx_bits');
check(tx_symb_log, tx_symb_log_c, 'tx_symb');
+check(rx_amp_log, rx_amp_log_c, 'rx_amp_log');
+check(rx_phi_log, rx_phi_log_c, 'rx_phi_log');
+check(rx_symb_log, rx_symb_log_c, 'rx_symb');
DATE CREATED: March 2015
Functions that implement a coherent PSK FDM modem.
-
- TODO:
- [ ] matching octave function bits_to_dqpsk_symbols()
- [ ] framework for test program and octave UT
- [ ] testframe used by both Octave and C
-
+
\*---------------------------------------------------------------------------*/
/*
struct COHPSK *cohpsk_create(void)
{
struct COHPSK *coh;
+ int r,c;
coh = (struct COHPSK*)malloc(sizeof(struct COHPSK));
if (coh == NULL)
memcpy(&coh->tx_pilot_buf[NPILOTSFRAME][0], pilots_coh, sizeof(pilots_coh));
memcpy(&coh->tx_pilot_buf[2*NPILOTSFRAME][0], pilots_coh, sizeof(pilots_coh));
+ for(r=0; r<3*NSYMROW; r++) {
+ for(c=0; c<PILOTS_NC; c++) {
+ coh->rx_symb_buf[r][c].real = 0.0;
+ coh->rx_symb_buf[r][c].imag = 0.0;
+ }
+ }
+
return coh;
}
for (r=0, p_r=2*NPILOTSFRAME, data_r=2*NSYMROW; r<NSYMROWPILOT; p_r++) {
- printf("r: %d data_r: %d\n", r, data_r);
+ // printf("r: %d data_r: %d\n", r, data_r);
/* copy row of pilots onto end of pilot buffer */
for(c=0; c<PILOTS_NC; c++) {
/* copy NS rows of data symbols onto end of data symbol buffer */
for(i=0; i<NS; data_r++,r++,i++) {
- for(c=0; c<PILOTS_NC; c++)
+ for(c=0; c<PILOTS_NC; c++) {
coh->rx_symb_buf[data_r][c] = rx_symb[r][c];
+ //printf("r: %d c: %d %f %f\n", r,c, rx_symb[r][c].real, rx_symb[r][c].imag);
+ }
}
}
+
/* estimate channel amplitude and phase and correct data symbols in middle of buffer */
- for (r=0, data_r=NSYMROW; r<NSYMROW; r++, data_r) {
+ for (r=0, data_r=NSYMROW; r<NSYMROW; r++, data_r++) {
/* pilots to use for correcting data_r-th symbol */
assert(st >= 0);
assert(en < 3*NPILOTSFRAME);
- printf("r: %d data_r: %d st: %d en: %d\n", r, data_r, st, en);
+ //printf("r: %d data_r: %d st: %d en: %d\n", r, data_r, st, en);
/* iterate over all of the carriers */
rx_bits[2*i] = rot.real < 0;
rx_bits[2*i+1] = rot.imag < 0;
- printf(" c: %d ch_est: %f %f phi_: %f amp_: %f\n",c, ch_est.real, ch_est.imag, coh->phi_[r][c], coh->amp_[r][c]);
+ //printf(" c: %d ch_est: %f %f phi_: %f amp_: %f\n",c, ch_est.real, ch_est.imag, coh->phi_[r][c], coh->amp_[r][c]);
}
//exit(0);
}
- /* shift buffers */
+ r = NSYMROW+19; c = 0;
+ //printf("%d %d %f %f\n", r,c, coh->rx_symb_buf[r][c].real, coh->rx_symb_buf[r][c].imag);
- memcpy(&coh->rx_pilot_buf[0][0], &coh->rx_pilot_buf[NPILOTSFRAME][0], sizeof(COMP)*2*NPILOTSFRAME*PILOTS_NC);
- memcpy(&coh->rx_symb_buf[0][0], &coh->rx_symb_buf[NSYMROW][0], sizeof(COMP)*2*NSYMROW*PILOTS_NC);
+ /* shift buffers */
+
+ for(r=0; r<2*NSYMROW; r++) {
+ for(c=0; c<PILOTS_NC; c++) {
+ coh->rx_symb_buf[r][c] = coh->rx_symb_buf[r+NSYMROW][c];
+ }
+ }
+ for(r=0; r<2*NPILOTSFRAME; r++) {
+ for(c=0; c<PILOTS_NC; c++) {
+ coh->rx_pilot_buf[r][c] = coh->rx_pilot_buf[r+NPILOTSFRAME][c];
+ }
+ }
+ r = 19; c = 0;
+ //printf("%d %d %f %f\n", r,c, coh->rx_symb_buf[r][c].real, coh->rx_symb_buf[r][c].imag);
}
float rx_amp_log[NSYMROW*FRAMES][PILOTS_NC];
float rx_phi_log[NSYMROW*FRAMES][PILOTS_NC];
+ COMP rx_symb_log[NSYMROW*FRAMES][PILOTS_NC];
int rx_bits_log[COHPSK_BITS_PER_FRAME*FRAMES];
FILE *fout;
bits_to_qpsk_symbols(tx_symb, (int*)tx_bits, COHPSK_BITS_PER_FRAME);
qpsk_symbols_to_bits(coh, rx_bits, tx_symb);
-
+
/* --------------------------------------------------------*\
Log each vector
\*---------------------------------------------------------*/
for(c=0; c<PILOTS_NC; c++) {
rx_amp_log[log_data_r][c] = coh->amp_[r][c];
rx_phi_log[log_data_r][c] = coh->phi_[r][c];
+ rx_symb_log[log_data_r][c] = coh->rx_symb_buf[r][c];
}
}
memcpy(&rx_bits_log[COHPSK_BITS_PER_FRAME*f], rx_bits, sizeof(int)*COHPSK_BITS_PER_FRAME);
fprintf(fout, "# Created by tcohpsk.c\n");
octave_save_int(fout, "tx_bits_log_c", tx_bits_log, 1, COHPSK_BITS_PER_FRAME*FRAMES);
octave_save_complex(fout, "tx_symb_log_c", (COMP*)tx_symb_log, NSYMROWPILOT*FRAMES, PILOTS_NC, PILOTS_NC);
- octave_save_complex(fout, "rx_amp_log_c", (COMP*)rx_amp_log, NSYMROW*FRAMES, PILOTS_NC, PILOTS_NC);
- octave_save_complex(fout, "rx_phi_log_c", (COMP*)rx_phi_log, NSYMROW*FRAMES, PILOTS_NC, PILOTS_NC);
+ octave_save_float(fout, "rx_amp_log_c", (float*)rx_amp_log, NSYMROW*FRAMES, PILOTS_NC, PILOTS_NC);
+ octave_save_float(fout, "rx_phi_log_c", (float*)rx_phi_log, NSYMROW*FRAMES, PILOTS_NC, PILOTS_NC);
+ octave_save_complex(fout, "rx_symb_log_c", (COMP*)rx_symb_log, NSYMROW*FRAMES, PILOTS_NC, PILOTS_NC);
+ octave_save_int(fout, "rx_bits_log_c", rx_bits_log, 1, COHPSK_BITS_PER_FRAME*FRAMES);
fclose(fout);
cohpsk_destroy(coh);