ofdm_tx and ofdm_rx working with no noise
authordrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 1 May 2017 01:55:56 +0000 (01:55 +0000)
committerdrowe67 <drowe67@01035d8c-6547-0410-b346-abe4f91aad63>
Mon, 1 May 2017 01:55:56 +0000 (01:55 +0000)
git-svn-id: https://svn.code.sf.net/p/freetel/code@3115 01035d8c-6547-0410-b346-abe4f91aad63

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

index 2cfed8aff5c3f15ba101e7c542ee0d9c8a1c873b..c7553073be9fdbf6e40b453096fe3c3b49e47846 100644 (file)
@@ -231,7 +231,7 @@ function [sim_out rate_fs_pilot_samples rx] = run_sim(sim_in)
 
       figure(1); clf; 
       plot(rx_np,'+');
-      axis([-2 2 -2 2]);
+      %axis([-2 2 -2 2]);
       title('Scatter');
       
       figure(2); clf;
@@ -255,15 +255,15 @@ function [sim_out rate_fs_pilot_samples rx] = run_sim(sim_in)
       figure(5); clf;
       plot(Nerrs_log);
 
-#{
-      figure(2)
+
+      figure(6)
       Tx = abs(fft(tx(1:Nsam).*hanning(Nsam)'));
       Tx_dB = 20*log10(Tx);
       dF = Fs/Nsam;
       plot((1:Nsam)*dF, Tx_dB);
       mx = max(Tx_dB);
       axis([0 Fs/2 mx-60 mx])
-#}
+
      
 #{
       if hf_en
@@ -300,15 +300,16 @@ function run_single
   sim_in.Tcp = 0.002; 
   sim_in.Rs = 1/Ts; sim_in.bps = 2; sim_in.Nc = 16; sim_in.Ns = 8;
 
-  %sim_in.Nsec = 5*(sim_in.Ns+1)/sim_in.Rs;  % one frame
-  sim_in.Nsec = 30;
+  sim_in.Nsec = 5*(sim_in.Ns+1)/sim_in.Rs;  % one frame
+  %sim_in.Nsec = 30;
 
-  sim_in.EbNodB = 3;
+  sim_in.EbNodB = 10;
   sim_in.verbose = 1;
-  sim_in.hf_en = 1;
+  sim_in.hf_en = 0;
   sim_in.foff_hz = 0;
-  sim_in.timing_en = 1;
   sim_in.sample_clock_offset_ppm = 0;
+
+  sim_in.timing_en = 1;
   sim_in.foff_est_en = 1;
   sim_in.phase_est_en = 1;
 
index 1004ddbbacd05f990c1e25b8c713a2467b98dd51..9164b666ef6c3c26f3e3cd68a464b44546a9204b 100644 (file)
@@ -108,7 +108,9 @@ function states = ofdm_init(bps, Rs, Tcp, Ns, Nc)
 
   % carrier tables for up and down conversion
 
-  w = (0:Nc+1)*2*pi*Rs/states.Fs;
+  fcentre = 1500;
+  Nlower = floor((fcentre - Rs*Nc/2)/Rs);
+  w = (Nlower:Nlower+Nc+1)*2*pi*Rs/states.Fs;
   W = zeros(Nc+2,states.M);
   for c=1:Nc+2
     W(c,:) = exp(j*w(c)*(0:states.M-1));
@@ -118,7 +120,7 @@ function states = ofdm_init(bps, Rs, Tcp, Ns, Nc)
 
   % fine timing search +/- window_width/2 from current timing instant
 
-  states.window_width = 11; 
+  states.ftwindow_width = 11; 
  
   % Receive buffer: D P DDD P DDD P DDD P D
   %                         ^
@@ -213,18 +215,6 @@ endfunction
 function [rx_bits states aphase_est_pilot_log rx_np] = ofdm_demod(states, rxbuf_in)
   ofdm_load_const;
 
-  % extra states that are st up at run time rather than init time
-
-  timing_est = states.timing_est;
-  timing_en = states.timing_en;
-  foff_est_hz = states.foff_est_hz;
-  foff_est_gain = states.foff_est_gain;
-  foff_est_en = states.foff_est_en;
-  sample_point = states.sample_point;
-  rate_fs_pilot_samples = states.rate_fs_pilot_samples;
-  verbose = states.verbose;
-  phase_est_en = states.phase_est_en;
-
   % insert latest input samples into rxbuf
 
   rxbuf(1:Nrxbuf-states.nin) = rxbuf(states.nin+1:Nrxbuf);
@@ -234,15 +224,15 @@ function [rx_bits states aphase_est_pilot_log rx_np] = ofdm_demod(states, rxbuf_
 
   % update timing estimate --------------------------------------------------
 
-  delta_t = sample_point = 0;
+  delta_t = 0;
   if timing_en
     % update timing at start of every frame
 
-    st = M+Ncp + Nsamperframe + 1 - floor(window_width/2) + (timing_est-1);
-    en = st + Nsamperframe-1 + M+Ncp + window_width-1;
+    st = M+Ncp + Nsamperframe + 1 - floor(ftwindow_width/2) + (timing_est-1);
+    en = st + Nsamperframe-1 + M+Ncp + ftwindow_width-1;
           
     ft_est = coarse_sync(states, rxbuf(st:en) .* exp(-j*woff_est*(st:en)), rate_fs_pilot_samples);
-    timing_est += ft_est - ceil(window_width/2);
+    timing_est = timing_est + ft_est - ceil(ftwindow_width/2);
 
     if verbose > 1
       printf("  ft_est: %2d timing_est: %2d sample_point: %2d\n", ft_est, timing_est, sample_point);
@@ -250,7 +240,7 @@ function [rx_bits states aphase_est_pilot_log rx_np] = ofdm_demod(states, rxbuf_
 
     % Black magic to keep sample_point inside cyclic prefix.  Or something like that.
 
-    delta_t = ft_est - ceil(window_width/2);
+    delta_t = ft_est - ceil(ftwindow_width/2);
     sample_point = max(timing_est+Ncp/4, sample_point);
     sample_point = min(timing_est+Ncp, sample_point);
   end
@@ -262,7 +252,7 @@ function [rx_bits states aphase_est_pilot_log rx_np] = ofdm_demod(states, rxbuf_
   rx_sym = zeros(1+Ns+1+1, Nc+2);
 
   % previous pilot
-
+  
   st = M+Ncp + Nsamperframe + (-Ns)*(M+Ncp) + 1 + sample_point; en = st + M - 1;
 
   for c=1:Nc+2
@@ -293,7 +283,7 @@ function [rx_bits states aphase_est_pilot_log rx_np] = ofdm_demod(states, rxbuf_
   if foff_est_en
     freq_err_rect = sum(rx_sym(2,:))' * sum(rx_sym(2+Ns,:));
     freq_err_hz = angle(freq_err_rect)*Rs/(2*pi*Ns);
-    foff_est_hz += foff_est_gain*freq_err_hz;
+    foff_est_hz = foff_est_hz + foff_est_gain*freq_err_hz;
   end
 
   % OK - now estimate and correct phase  ----------------------------------
index 8b3556232dfb5fc4d1a843b97e4bebb4e8458680..eb13e8e7c0d4e4a79fc01c31c04f878724fcfb0e 100644 (file)
@@ -8,8 +8,30 @@ Ns = states.Ns;
 Nc = states.Nc;
 M = states.M;
 Ncp = states.Ncp;
-bps = sim_in.bps;
+bps = states.bps;
 Nbitsperframe = states.Nbitsperframe;
 Nrowsperframe = states.Nrowsperframe;
 Nsamperframe = states.Nsamperframe;
+
+W = states.W;
+w = states.w;
+
+timing_est = states.timing_est;
+sample_point = states.sample_point;
+ftwindow_width = states.ftwindow_width;
+
+Nrxbuf = states.Nrxbuf;
+rxbuf = states.rxbuf;
+
 pilots = states.pilots;
+rate_fs_pilot_samples = states.rate_fs_pilot_samples;
+
+foff_est_gain = states.foff_est_gain;
+foff_est_hz = states.foff_est_hz;
+
+timing_en = states.timing_en;
+foff_est_en = states.foff_est_en;
+phase_est_en = states.phase_est_en;
+
+verbose = states.verbose;
+
index 7adc63b8c9da047bd45b2ae394e91763e67f872a..97e7992b82e877962bfbef9067e5e85202dd625f 100644 (file)
@@ -15,14 +15,26 @@ function ofdm_rx(filename)
   rand('seed', 100);
   tx_bits = rand(1,Nbitsperframe) > 0.5;
 
-  % load real samples from file
+  % init logs and BER stats
 
-  frx=fopen(filename,"rb"); rx = fread(frx, Inf, "short"); fclose(frx);
+  rx_bits = []; rx_np = []; timing_est_log = []; delta_t_log = []; foff_est_hz_log = [];
+  phase_est_pilot_log = [];
+  Nerrs = Nbits = 0;
+
+  % load real samples from file
 
+  Ascale= 4E5;
+  frx=fopen(filename,"rb"); rx = 2*fread(frx, Inf, "short")/4E5; fclose(frx);
   Nsam = length(rx); Nframes = floor(Nsam/Nsamperframe);
   prx = 1;
-  rx_bits = []; rx_np = []; timing_est_log = []; delta_t_log = []; foff_est_hz_log = [];
-  phase_est_pilot_log = [];
+
+  % 'prime' rx buf to get correct coarse timing (for now)
+
+  prx = 1;
+  states.rxbuf(M+Ncp+2*Nsamperframe+1:Nrxbuf) = rx(prx:Nsamperframe+2*(M+Ncp));
+  prx += Nsamperframe+2*(M+Ncp);
+
+  % main loop ----------------------------------------------------------------
 
   for f=1:Nframes
 
@@ -38,18 +50,48 @@ function ofdm_rx(filename)
     end
     prx += states.nin;
 
-    [arx_bits states aphase_est_pilot_log arx_np] = ofdm_demod(states, rxbuf_in);
+    [rx_bits states aphase_est_pilot_log arx_np] = ofdm_demod(states, rxbuf_in);
 
-    rx_bits = [rx_bits arx_bits]; rx_np = [rx_np arx_np];
+    rx_np = [rx_np arx_np];
     timing_est_log = [timing_est_log states.timing_est];
     delta_t_log = [delta_t_log states.delta_t];
     foff_est_hz_log = [foff_est_hz_log states.foff_est_hz];
     phase_est_pilot_log = [phase_est_pilot_log; aphase_est_pilot_log];
+
+    % measure bit errors
+
+    errors = xor(tx_bits, rx_bits);
+    Nerrs += sum(errors);
+    Nerrs_log(f) = sum(errors);
+    Nbits += Nbitsperframe;
   end
 
+  printf("BER: %5.4f Nbits: %d Nerrs: %d\n", Nerrs/Nbits, Nbits, Nerrs);
+
   figure(1); clf; 
   plot(rx_np,'+');
-  %axis([-2 2 -2 2]);
+  axis([-2 2 -2 2]);
   title('Scatter');
 
+  figure(2); clf;
+  plot(phase_est_pilot_log(:,2:Nc+1),'g+', 'markersize', 5); 
+  title('Phase est');
+  axis([1 length(phase_est_pilot_log) -pi pi]);  
+
+  figure(3); clf;
+  subplot(211)
+  stem(delta_t_log)
+  title('delta t');
+  subplot(212)
+  plot(timing_est_log);
+  title('timing est');
+
+  figure(4); clf;
+  plot(foff_est_hz_log)
+  axis([1 max(Nframes,2) -3 3]);
+  title('Fine Freq');
+
+  figure(5); clf;
+  %plot(Nerrs_log);
+  
 endfunction
index dee8d51cbd1fc73eb217e5447746fbb13090c78d..57b32de15c066ba40e3d5b175dc25115653a24e5 100644 (file)
@@ -12,6 +12,7 @@ function ofdm_tx(filename, Nsec)
   ofdm_load_const;
 
   % generate fixed test frame of tx bits and run OFDM modulator
+  % todo: maybe extend this to 4 or 8 frames, one is a bit short
 
   Nrows = Nsec*Rs;
   Nframes = floor((Nrows-1)/Ns);
@@ -24,6 +25,6 @@ function ofdm_tx(filename, Nsec)
     tx = [tx ofdm_mod(states, tx_bits)];
   end
 
-  Ascale = 32000/max(real(tx));
+  Ascale = 4E5;
   ftx=fopen(filename,"wb"); fwrite(ftx, Ascale*real(tx), "short"); fclose(ftx);
 endfunction