From: drowe67 Date: Mon, 1 May 2017 01:55:56 +0000 (+0000) Subject: ofdm_tx and ofdm_rx working with no noise X-Git-Url: http://git.whiteaudio.com/gitweb/?a=commitdiff_plain;h=84620073914e465662161d4098ffc6f42355b75e;p=freetel-svn-tracking.git ofdm_tx and ofdm_rx working with no noise git-svn-id: https://svn.code.sf.net/p/freetel/code@3115 01035d8c-6547-0410-b346-abe4f91aad63 --- diff --git a/codec2-dev/octave/ofdm_dev.m b/codec2-dev/octave/ofdm_dev.m index 2cfed8af..c7553073 100644 --- a/codec2-dev/octave/ofdm_dev.m +++ b/codec2-dev/octave/ofdm_dev.m @@ -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; diff --git a/codec2-dev/octave/ofdm_lib.m b/codec2-dev/octave/ofdm_lib.m index 1004ddbb..9164b666 100644 --- a/codec2-dev/octave/ofdm_lib.m +++ b/codec2-dev/octave/ofdm_lib.m @@ -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 ---------------------------------- diff --git a/codec2-dev/octave/ofdm_load_const.m b/codec2-dev/octave/ofdm_load_const.m index 8b355623..eb13e8e7 100644 --- a/codec2-dev/octave/ofdm_load_const.m +++ b/codec2-dev/octave/ofdm_load_const.m @@ -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; + diff --git a/codec2-dev/octave/ofdm_rx.m b/codec2-dev/octave/ofdm_rx.m index 7adc63b8..97e7992b 100644 --- a/codec2-dev/octave/ofdm_rx.m +++ b/codec2-dev/octave/ofdm_rx.m @@ -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 diff --git a/codec2-dev/octave/ofdm_tx.m b/codec2-dev/octave/ofdm_tx.m index dee8d51c..57b32de1 100644 --- a/codec2-dev/octave/ofdm_tx.m +++ b/codec2-dev/octave/ofdm_tx.m @@ -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