From: drowe67 Date: Sun, 8 Apr 2018 03:22:06 +0000 (+0000) Subject: moved sync state machine into ofdm_lib function, ready for C port. Falling out of... X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=d866d1f3e7eb1b3541095d9bf0ba796a5274f89d;p=freetel-svn-tracking.git moved sync state machine into ofdm_lib function, ready for C port. Falling out of sync on some HF fades, cld possibly need tuning git-svn-id: https://svn.code.sf.net/p/freetel/code@3453 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/ofdm_lib.m b/codec2-dev/octave/ofdm_lib.m index 7011adbf..27cae0a3 100644 --- a/codec2-dev/octave/ofdm_lib.m +++ b/codec2-dev/octave/ofdm_lib.m @@ -136,6 +136,7 @@ function states = ofdm_init(bps, Rs, Tcp, Ns, Nc) states.Nbitsperframe = (Ns-1)*Nc*bps; states.Nrowsperframe = states.Nbitsperframe/(Nc*bps); states.Nsamperframe = (states.Nrowsperframe+1)*(states.M+states.Ncp); + states.uw_len = (Ns-1)*bps; % generate same pilots each time @@ -524,3 +525,63 @@ function test_bits_ofdm_file fclose(f); endfunction + + +% iterate state machine ------------------------------------ + +function states = sync_state_machine(states, rx_uw) + ofdm_load_const; + next_state = states.sync_state; + states.sync_start = states.sync_end = 0; + + if strcmp(states.sync_state,'searching') + + if states.timing_valid + + % freq offset est has some bias, but this refinement step fixes bias + + st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe; + woff_est = 2*pi*states.foff_est_hz/Fs; + [ct_est foff_est timing_valid timing_mx] = coarse_sync(states, states.rxbuf(st:en) .* exp(-j*woff_est*(st:en)), states.rate_fs_pilot_samples); + if verbose + printf(" coarse_foff: %4.1f refine: %4.1f combined: %4.1f\n", states.foff_est_hz, foff_est, states.foff_est_hz+foff_est); + end + states.foff_est_hz += foff_est; + states.frame_count = 0; + states.sync_counter = 0; + states.sync_start = 1; + next_state = 'trial_sync'; + end + end + + if strcmp(states.sync_state,'synced') || strcmp(states.sync_state,'trial_sync') + + states.frame_count++; + + % during trial sync we don't tolerate errors so much + + if states.frame_count == 3 + next_state = 'synced'; + end + if strcmp(states.sync_state,'synced') + sync_counter_thresh = 6; + else + sync_counter_thresh = 3; + end + + % freq offset est may be too far out, and has aliases every 1/Ts + + states.uw_errors = sum(rx_uw); + if (states.uw_errors > 3) + states.sync_counter++; + if states.sync_counter == sync_counter_thresh + next_state = 'searching'; + end + else + states.sync_counter = 0; + end + end + + states.last_sync_state = states.sync_state; + states.sync_state = next_state; +endfunction diff --git a/codec2-dev/octave/ofdm_rx.m b/codec2-dev/octave/ofdm_rx.m index fc4d11b4..868251ce 100644 --- a/codec2-dev/octave/ofdm_rx.m +++ b/codec2-dev/octave/ofdm_rx.m @@ -27,7 +27,8 @@ function ofdm_rx(filename, error_pattern_filename) rand('seed', 1); tx_bits = round(rand(1,Nbitsperframe)); - + tx_bits(1:states.uw_len) = 0; % insert UW + % init logs and BER stats rx_bits = []; rx_np_log = []; timing_est_log = []; delta_t_log = []; foff_est_hz_log = []; @@ -44,8 +45,16 @@ function ofdm_rx(filename, error_pattern_filename) %states.rxbuf(Nrxbuf-nin+1:Nrxbuf) = rx(prx:nin); %prx += nin; - state = 'searching'; frame_count = 0; Nerrs = 0; sync_counter = 0; uw_errors = 0; - states.timing_mx1 = states.timing_mx2 = 1; + states.sync_state = states.last_sync_state = 'searching'; + states.uw_errors = 0; + states.sync_counter = 0; + states.sync_frame_count = 0; + states.sync_start = 0; + states.sync_end = 0; + + states.verbose = 1; + + Nerrs = 0; rx_uw = zeros(1,states.uw_len); % main loop ---------------------------------------------------------------- @@ -63,31 +72,14 @@ function ofdm_rx(filename, error_pattern_filename) end prx += states.nin; - % iterate state machine ------------------------------------ - - next_state = state; - - if strcmp(state,'searching') + if strcmp(states.sync_state,'searching') [timing_valid states] = ofdm_sync_search(states, rxbuf_in); - - if states.timing_valid - st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe; - woff_est = 2*pi*states.foff_est_hz/Fs; - [ct_est foff_est timing_valid timing_mx] = coarse_sync(states, states.rxbuf(st:en) .* exp(-j*woff_est*(st:en)), states.rate_fs_pilot_samples); - printf(" coarse_foff: %4.1f refine: %4.1f combined: %4.1f\n", states.foff_est_hz, foff_est, states.foff_est_hz+foff_est); - states.foff_est_hz += foff_est; - - Nerrs_log = []; - Terrs = Tbits = frame_count = 0; - sync_counter = 0; - next_state = 'trial_sync'; - end end - - if strcmp(state,'synced') || strcmp(state,'trial_sync') - + + if strcmp(states.sync_state,'synced') || strcmp(states.sync_state,'trial_sync') [rx_bits states aphase_est_pilot_log arx_np arx_amp] = ofdm_demod(states, rxbuf_in); - + rx_uw = rx_bits(1:states.uw_len); + errors = xor(tx_bits, rx_bits); Nerrs = sum(errors); aber = Nerrs/Nbitsperframe; @@ -107,35 +99,21 @@ function ofdm_rx(filename, error_pattern_filename) Tbits += Nbitsperframe; frame_count++; + end + + states = sync_state_machine(states, rx_uw); - % during trial sync we don't tolerate errors so much - - if frame_count == 3 - next_state = 'synced'; - end - if strcmp(state,'synced') - sync_counter_thresh = 6; - else - sync_counter_thresh = 3; - end - - % freq offset est may be too far out, and has aliases every 1/Ts - - uw_len = (Ns-1)*bps; - uw_errors = sum(xor(tx_bits(1:uw_len), rx_bits(1:uw_len))); - if (uw_errors > 3) - sync_counter++; - if sync_counter == sync_counter_thresh - next_state = 'searching'; - sync_counter = Nerrs = 0; - end - else - sync_counter = 0; - end + if states.verbose + printf("f: %2d state: %-10s uw_errors: %2d %1d Nerrs: %3d foff: %3.1f\n", + f, states.last_sync_state, states.uw_errors, states.sync_counter, Nerrs, states.foff_est_hz); end + + % act on any events returned by state machine - printf("f: %2d state: %-10s uw_errors: %2d %1d nin: %d Nerrs: %3d foff: %3.1f\n", f, state, uw_errors, sync_counter, nin, Nerrs,states.foff_est_hz); - state = next_state; + if states.sync_start + Nerrs_log = []; + Terrs = Tbits = frame_count = 0; + end end printf("\nBER..: %5.4f Tbits: %5d Terrs: %5d\n", Terrs/Tbits, Tbits, Terrs); diff --git a/codec2-dev/octave/ofdm_tx.m b/codec2-dev/octave/ofdm_tx.m index 4241f031..10a167db 100644 --- a/codec2-dev/octave/ofdm_tx.m +++ b/codec2-dev/octave/ofdm_tx.m @@ -17,7 +17,7 @@ #} -function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0) +function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0, dfoff_hz_per_sec = 0) ofdm_lib; % init modem @@ -32,7 +32,8 @@ function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0) Nframes = floor((Nrows-1)/Ns); rand('seed', 1); tx_bits = round(rand(1,Nbitsperframe)); - + tx_bits(1:states.uw_len) = 0; % insert UW + tx = []; for f=1:Nframes tx = [tx ofdm_mod(states, tx_bits)]; @@ -45,7 +46,8 @@ function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0) EsNo = rate * bps * (10 .^ (EbNodB/10)); variance = 1/(M*EsNo/2); woffset = 2*pi*freq_offset_Hz/Fs; - + dwoffset = 2*pi*dfoff_hz_per_sec/(Fs*Fs); + SNRdB = EbNodB + 10*log10(Nc*bps*Rs/3000); printf("EbNo: %3.1f dB SNR(3k) est: %3.1f dB foff: %3.1fHz ", EbNodB, SNRdB, freq_offset_Hz); @@ -88,7 +90,8 @@ function ofdm_tx(filename, Nsec, EbNodB=100, channel='awgn', freq_offset_Hz=0) rx *= sqrt(nom_rx_pwr/rx_pwr); end - rx = rx .* exp(j*woffset*(1:Nsam)); + phase_offset = woffset*(1:Nsam) + 0.5*dwoffset*((1:Nsam).^2); + rx = rx .* exp(j*phase_offset); % note variance/2 as we are using real() operator, mumble, % reflection of -ve freq to +ve, mumble, hand wave