endfunction
-% returns index of start of frame and fine freq offset
-
-function [next_sync cohpsk] = frame_sync_fine_freq_est(cohpsk, ch_symb, sync, next_sync)
- ct_symb_buf = cohpsk.ct_symb_buf;
- Nct_sym_buf = cohpsk.Nct_sym_buf;
- Rs = cohpsk.Rs;
- Nsymbrowpilot = cohpsk.Nsymbrowpilot;
- Nc = cohpsk.Nc;
- Nd = cohpsk.Nd;
+function ct_symb_buf = update_ct_symb_buf(ct_symb_buf, ch_symb, Nct_sym_buf, Nsymbrowpilot)
% update memory in symbol buffer
ct_symb_buf(r,:) = ch_symb(i,:);
i++;
end
+endfunction
+
+
+% returns index of start of frame and fine freq offset
+
+function [next_sync cohpsk] = frame_sync_fine_freq_est(cohpsk, ch_symb, sync, next_sync)
+ ct_symb_buf = cohpsk.ct_symb_buf;
+ Nct_sym_buf = cohpsk.Nct_sym_buf;
+ Rs = cohpsk.Rs;
+ Nsymbrowpilot = cohpsk.Nsymbrowpilot;
+ Nc = cohpsk.Nc;
+ Nd = cohpsk.Nd;
+
+ ct_symb_buf = update_ct_symb_buf(ct_symb_buf, ch_symb, Nct_sym_buf, Nsymbrowpilot);
cohpsk.ct_symb_buf = ct_symb_buf;
-
+
% sample pilots at start of this frame and start of next frame
sampling_points = [1 2 7 8];
pilot2 = [ cohpsk.pilot(1,:); cohpsk.pilot(2,:); cohpsk.pilot(1,:); cohpsk.pilot(2,:);];
- if sync == 2
+ if sync == 0
% sample correlation over 2D grid of time and fine freq points
end
end
%printf(" f: %f t: %d corr: %f %f\n", f_fine, t, real(corr), imag(corr));
- if corr > max_corr
+ if corr >= max_corr
max_corr = corr;
max_mag = mag;
cohpsk.ct = t;
end
end
- printf(" fine freq f: %f max_corr: %f max_mag: %f ct: %d\n", cohpsk.f_fine_est, abs(max_corr), max_mag, cohpsk.ct);
+ printf(" [%d] fine freq f: %f max_corr: %f max_mag: %f ct: %d\n", cohpsk.frame, cohpsk.f_fine_est, abs(max_corr), max_mag, cohpsk.ct);
if abs(max_corr/max_mag) > 0.7
- printf(" [%d] in sync!\n", cohpsk.frame);
+ printf(" [%d] encouraging sync word!\n", cohpsk.frame);
cohpsk.sync_timer = 0;
- %cohpsk.f_est -= cohpsk.f_fine_est;
- %cohpsk.f_fine_est = 0;
- %cohpsk.ff_rect = 1;
- printf(" .... adjusting to %f\n", cohpsk.f_est);
- next_sync = 4;
+ next_sync = 1;
else
next_sync = 0;
- printf(" back to coarse freq offset est...\n");
+ printf(" [%d] back to coarse freq offset est...\n", cohpsk.frame) ;
end
cohpsk.ratio = abs(max_corr/max_mag);
end
-
- if sync == 4
+ if sync == 1
% we are in sync so just sample correlation over 1D grid of fine freq points
function [sync cohpsk] = sync_state_machine(cohpsk, sync, next_sync)
if sync == 1
- next_sync = 2;
- end
- if sync == 5
- next_sync = 4;
- end
-
- if sync == 4
% check that sync is still good, fall out of sync on consecutive bad frames */
rand('state',1);
randn('state',1);
+function [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, nsymb, nin)
+ M = afdmdv.M;
+
+ for r=1:nsymb
+ % downconvert each FDM carrier to Nc separate baseband signals
+
+ [rx_baseband afdmdv] = fdm_downconvert(afdmdv, rx_fdm_frame_bb(1+(r-1)*M:r*M), nin);
+ [rx_filt afdmdv] = rx_filter(afdmdv, rx_baseband, nin);
+ [rx_onesym rx_timing env afdmdv] = rx_est_timing(afdmdv, rx_filt, nin);
+
+ ch_symb(r,:) = rx_onesym;
+ end
+endfunction
+
% Core function for testing frequency offset estimator. Performs one test
function sim_out = freq_off_est_test(sim_in)
acohpsk.coarse_mem = zeros(1,acohpsk.Ncm);
acohpsk.Ndft = 2^(ceil(log2(acohpsk.Ncm)));
+ ch_fdm_frame_buf = zeros(1, 2*acohpsk.Nsymbrowpilot*M);
+
frames = sim_in.frames;
EsNodB = sim_in.EsNodB;
foff = sim_in.foff;
% Try to achieve sync --------------------------------------------------------------------
%
- next_sync = sync;
+ % store two frames so we can rewind if we get a good candidate
+
+ ch_fdm_frame_buf(1:acohpsk.Nsymbrowpilot*M) = ch_fdm_frame_buf(acohpsk.Nsymbrowpilot*M+1:2*acohpsk.Nsymbrowpilot*M);
+ ch_fdm_frame_buf(acohpsk.Nsymbrowpilot*M+1:2*acohpsk.Nsymbrowpilot*M) = ch_fdm_frame;
+ next_sync = sync;
+ sync = 0;
if sync == 0
- next_sync = 2;
acohpsk.f_est = Fcentre;
end
- [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame, -acohpsk.f_est, Fs, afdmdv.fbb_phase_rx);
+ [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame_buf, -acohpsk.f_est, Fs, afdmdv.fbb_phase_rx);
+ [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, 2*acohpsk.Nsymbrowpilot, nin);
+ ch_symb_log = [ch_symb_log; ch_symb(acohpsk.Nsymbrowpilot+1:2*acohpsk.Nsymbrowpilot,:)];
- for r=1:acohpsk.Nsymbrowpilot
+ % coarse timing (frame sync) and initial fine freq est ---------------------------------------------
+
+ acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb, acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
+ [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb(acohpsk.Nsymbrowpilot+1:2*acohpsk.Nsymbrowpilot,:), sync, next_sync);
- % downconvert each FDM carrier to Nc separate baseband signals
+ % we've found a sync candidate
- [rx_baseband afdmdv] = fdm_downconvert(afdmdv, rx_fdm_frame_bb(1+(r-1)*M:r*M), nin);
- [rx_filt afdmdv] = rx_filter(afdmdv, rx_baseband, nin);
- [rx_onesym rx_timing env afdmdv] = rx_est_timing(afdmdv, rx_filt, nin);
+ if (next_sync == 1)
- ch_symb(r,:) = rx_onesym;
- end
- ch_symb_log = [ch_symb_log; ch_symb];
+ % rewind and re-process last few frames with f_est
- % coarse timing (frame sync) and initial fine freq est ---------------------------------------------
-
- [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb, sync, next_sync);
+ acohpsk.f_est -= acohpsk.f_fine_est;
+ printf(" [%d] trying sync cand f_est: %f\n", f, acohpsk.f_est);
+ [rx_fdm_frame_bb afdmdv.fbb_phase_rx] = freq_shift(ch_fdm_frame_buf, -acohpsk.f_est, Fs, afdmdv.fbb_phase_rx);
+ [ch_symb rx_timing rx_filt rx_baseband afdmdv] = rate_Fs_rx_processing(afdmdv, rx_fdm_frame_bb, 2*acohpsk.Nsymbrowpilot, nin);
+ acohpsk.ct_symb_buf = update_ct_symb_buf(acohpsk.ct_symb_buf, ch_symb, acohpsk.Nct_sym_buf, acohpsk.Nsymbrowpilot);
+ [next_sync acohpsk] = frame_sync_fine_freq_est(acohpsk, ch_symb(acohpsk.Nsymbrowpilot+1:2*acohpsk.Nsymbrowpilot,:), sync, next_sync);
- % if we've acheived sync gather stats
+ % candidate checks out so log stats
- if (next_sync == 4)
- freq_offset_log = [freq_offset_log acohpsk.f_fine_est+foff];
- sync_time_log = [sync_time_log f-sync_start];
- sync = 0; next_sync = 2; sync_start = f;
+ if (next_sync == 1)
+ printf(" [%d] in sync!\n", f);
+ freq_offset_log = [freq_offset_log Fcentre+foff-acohpsk.f_est,];
+ sync_time_log = [sync_time_log f-sync_start];
+ next_sync = 0; sync_start = f;
+ end
end
%printf("f: %d sync: %d next_sync: %d\n", f, sync, next_sync);
function freq_off_est_test_single
sim_in.frames = 100;
- sim_in.EsNodB = 20;
- sim_in.foff = -15;
+ sim_in.EsNodB = 12;
+ sim_in.foff = 20;
sim_in.dfoff = 0;
sim_in.fading_en = 1;
subplot(211)
plot(real(sim_out.tx_fdm_frame_log(1:2*960)))
subplot(212)
- plot(real(sim_out.ch_symb_log(1:24,:)),'+')
+ plot(real(sim_out.ch_symb_log),'+')
endfunction
function [freq_off_log EsNodBSet] = freq_off_est_test_curves
EsNodBSet = [20 12 8];
- sim_in.frames = 100;
+ sim_in.frames = 10;
sim_in.foff = -20;
sim_in.dfoff = 0;
- sim_in.fading_en = 1;
+ sim_in.fading_en = 0;
freq_off_log = 1E6*ones(sim_in.frames, length(EsNodBSet) );
sync_time_log = 1E6*ones(sim_in.frames, length(EsNodBSet) );