diff --git a/ofdm/cfo_coarse_fract.m b/ofdm/cfo_coarse_fract.m new file mode 100644 index 0000000..0a37630 --- /dev/null +++ b/ofdm/cfo_coarse_fract.m @@ -0,0 +1,23 @@ +function [domega_f, Zf] = cfo_coarse_fract(x, N, Ng, L, Nd, Zi) + +if (~isfield(Zi, 'valid')) + Zi = struct('valid', 1, 'n', 0, 'xp', [], 'p', 1.0); +end +Zf = Zi; +domega_f = 0; + +Zf.xp = [Zf.xp' x']'; + +if (length(Zf.xp) < 2*(N+Ng)) + n = Zf.n; + return +end + +x1 = Zf.xp(1:L); +x2 = Zf.xp(Nd+1:Nd+L); +c = sum(x1 .* conj(x2)); + +domega_f = 1/(2*pi*N) * angle(c); + +Zf.xp = x; + diff --git a/ofdm/cfo_coarse_int.m b/ofdm/cfo_coarse_int.m index c783af2..5d68f96 100644 --- a/ofdm/cfo_coarse_int.m +++ b/ofdm/cfo_coarse_int.m @@ -1,30 +1,102 @@ -function [omega_coarse, Xm] = fdet_coarse(x, N, Ng, omega_min, omega_step, omega_max) +function [d_bin, valid, Zf] = cfo_coarse_int(x, N, carrier_pilot, bins_search, Zi) -Xm = zeros(N,1); - -if 0 - -K = fix((length(x))/(N+Ng)); - -for k=1:K, - xp = x((k-1)*(N+Ng)+1:k*(N+Ng)); - Xm = 0.5*Xm + fft(xp(Ng+1:N+Ng), N); +if (~isfield(Zi, 'valid')) + Zi = struct('valid', 1, 'Xm', zeros(N, 1), 'Xv', zeros(N, 1), 'Zk', [], 'd_bin', []); end -Nmax = ceil(omega_max*N)+1 -[v, ii] = max(abs(Xm(1:Nmax))) +alpha = 0.01; +rho = 0.999; +k_boost = 4; +noise_eps = 1e-1; -omega_coarse = (ii-1)/N; - -else +if 1 + bin_pilots = c2i(N, carrier_pilot)-1; + bin_min = max(0, min(bin_pilots)-bins_search); + bin_max = min(N-1, max(bin_pilots)+bins_search); -omega_range = (omega_min:omega_step:omega_max); + Xk = zeros(N, 1); + valid = 0; + d_bin = Zi.d_bin; + Zk = fft(x, N); + if ~isempty(Zi.Zk) + Xk = Zk .* conj(Zi.Zk); + Zi.Xm = (1-alpha)*Zi.Xm + alpha*Xk; + Zi.Xv = Zi.Xv*rho; + Zi.Xv = max(Zi.Xm, Zi.Xv); + Xt = abs(Zi.Xv(bin_min+1:bin_max+1)); -for k=1:lge(omega_range) - x_est = exp(-j*(2*pi*omega_range(k)*(0:N-1)' + 0)); - dmod(k) = sum(x(1:N).*x_est); -end; -[v maxk] = max(abs(dmod)); -omega_coarse = omega_range(maxk); + xnoise = noiseFloor(Xt, 4)+noise_eps; + bins = bin_min+find_bins(Xt, xnoise, k_boost, bins_search); + + if (~isempty(bins)) + k = 1; + for b=1:length(bins) + bin_c = bins(b); + for n=1:length(bin_pilots) + bin_p = bin_pilots(n); + if (abs(bin_c - bin_p) < bins_search) + d_bin = [d_bin (bin_c - bin_p)]; + end + end + end + h = zeros(length(bin_pilots), 1); + if length(d_bin) == length(bin_pilots) + valid = 1; + for k=1:length(d_bin) + for b=1:length(d_bin) + if d_bin(b) == d_bin(k) + h(k) = h(k) + 1; + end + end + end + end + end + + if 1 + plot(bin_min+(0:length(Xt)-1), abs(Xt), '-*', bin_min+(0:length(Xt)-1), xnoise, 'g-'); grid; + a = axis; + hold on; + if ~isempty(bins) + for b=1:length(bins) + x = [bins(b) bins(b)]; + y = [a(3) a(4)]; + plot(x,y, 'r-'); + end + end + hold off; + pause (0.01); + end + end + Zi.Zk = Zk; end +Zf = Zi; + +function bins = find_bins(x, xnoise, kboost, bins_search) + +bins = []; +for n=1:length(x) + if (x(n) > kboost*xnoise(n)) + smin = max(1, n-bins_search); + smax = min(length(x), n+bins_search); + [v, nn] = max(x(smin:smax)); + winner = nn + smin-2; + if isempty(find(bins == winner)) + bins = [bins winner]; + end + n = min(length(x), n + bins_search); + end +end +bins = bins'; + +function y = noiseFloor(x, kn) + +y(1) = x(1); +for n=2:length(x) + if (x(n) < kn*y(n-1)) + y(n) = 0.5*y(n-1) + 0.5*x(n); + else + y(n) = y(n-1); + end +end +