moved sync state machine into ofdm_lib function, ready for C port. Falling out of...
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 8 Apr 2018 03:22:06 +0000 (03:22 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Sun, 8 Apr 2018 03:22:06 +0000 (03:22 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3453 01035d8c-6547-0410-b346-abe4f91aad63

codec2-dev/octave/ofdm_lib.m
codec2-dev/octave/ofdm_rx.m
codec2-dev/octave/ofdm_tx.m

index 7011adbfeacd8f71546b3b784e0b3d5d9ebfe8ee..27cae0a3c166ab065c34c589d7978da04557fe00 100644 (file)
@@ -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
index fc4d11b4f140db7f22b49c776d06ba7a33f89592..868251cec23320e5f1ba86f1be677f86993a8c5a 100644 (file)
@@ -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);
index 4241f031a3aae2adbb1d268410d5d05a9239727b..10a167dbd0a76738461e12ccb71de86bdb22a009 100644 (file)
@@ -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