File: process.m

package info (click to toggle)
uhd 3.15.0.0-4
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 202,252 kB
  • sloc: cpp: 182,756; ansic: 94,109; vhdl: 53,420; python: 45,849; xml: 12,956; tcl: 7,046; makefile: 2,248; sh: 1,741; pascal: 230; javascript: 120; csh: 94; asm: 20; perl: 11
file content (141 lines) | stat: -rw-r--r-- 5,363 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
close all;
clear all;
clc;

r = read_complex_binary('samples.dat');
#r = r(9.404e6:9.414e6);
r = r(7.315e6:7.325e6);
figure;
plot(abs(r));

#############################################################
#### Run
#############################################################
if(1)
#### returns frequency corrected input starting at the beginning edge of the plateau.
[D, f, corr, power, frame_start, d_f, sig_out, sig_out_corr] = schmidl_corr(r, 32);

figure;
hold on;
grid on;
plot(D,'r');
plot(f,'g');
plot(abs(sig_out_corr), 'b');
title('Schmidl Cox out');

long_preamble_f = [1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 1 1 -1 -1 1 1 -1 1 -1 1 1 1 1 0 1 -1 -1 1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 1 1];
long_preamble_start = 0;

##############################################################
#### Fine timing by finding correlation with long preamble 
##############################################################
if(0)
ifft_data = [long_preamble_f(27:end) 0 0 0 0 0 0 0 0 0 0 0 long_preamble_f(1:26)];
long_preamble_t = ifft(ifft_data);
correlation = conv(conj(sig_out_corr), fliplr(long_preamble_t));
[max, long_preamble_start] = max(abs(correlation));
long_preamble_start
endif
###############################################################

###############################################################
#### 160 Samples SP + 32 Samples LP CP.
#### Step a few samples back to make sure to be in CP LP1 and not in the crossover between LP1 and LP2.
#### The channel equalizer in conjuntion with the pilots will handle the introduced frequency offset (in the F domain) for us.
#### The channel equalizer can remove the f offset introduced by the timing offset completely. However,
#### due to residual f offset in t domain, which also results amongst others in f offset in F domain, the initial phase of every OFDM symbol is 
#### linearly increasing or decreasing. That results in constant rotation of the constellation between OFDM symbols. Therefore, we need to use the 
#### pilot symbols to derotate. That is why timing sync does not affect the speed of rotation observed for the pilot constellations.
###############################################################
sig_out_corr = sig_out_corr(160+32-5:end);
###############################################################

###############################################################
###################### Run channel equalizer ##################
###############################################################
fft_input = sig_out_corr(1:64);
#fft_input = sig_out(1:64);
fft_out = fft(fft_input);
fft_out = fftshift(fft_out);
fft_out = circshift(fft_out, [0 0]);
data_out = fft_out(7:end-5);

H_ls = inv(diag(circshift([0 0 0 0 0 0 long_preamble_f 0 0 0 0 0], [0 0])))*transpose([0 0 0 0 0 0 data_out 0 0 0 0 0]);
H_ls
figure;
hold on;
plot(abs(H_ls));
plot(arg(H_ls), 'r');
title('Channel response H(f)');

figure;
plot(abs(data_out));
hold on;
plot(real(data_out), 'r');
plot(imag(data_out), 'g');
plot(arg(data_out), 'b');
title('OFDM frame 1 before equalization');

figure;
plot(real(data_out), imag(data_out), '.');
axis([-1 1 -1 1], "manual");
title('OFDM frame 1 before equalization');

data_out = data_out ./ transpose(H_ls)(7:end-5);

#figure;
#plot(abs(data_out));
#hold on;
#plot(real(data_out), 'r');
#plot(imag(data_out), 'g');
#title('OFDM frame after equalization');

#figure;
#plot(real(data_out), imag(data_out), '.');
#axis([-1 1 -1 1], "manual");
#title('OFDM frame after equalization');
###########################################################

###########################################################
################ Decode, baby! ############################
###########################################################
#### Pilots can be found in bins -21, -7, 7, 21
#### For the SYMBOL symbol their values are 1, 1, 1, -1
###########################################################

fig = figure;
curr_ofdm_sym_start_index = 129;
phi = 0;
phi_log = [];
pilot_zero = [];
polarity_seq = [1 1 1 1 -1 -1 -1 1 -1 -1 -1 -1 1 1 -1 1 -1 -1 1 1 -1 1 1 -1 1 1 1 1 1 1 -1 1 1 1 -1 1 1 -1 -1 1 1 1 -1 1 -1 -1 -1 1 -1 1 -1 -1 1 -1 -1 1 1 1 1 1 -1 -1 1 1 -1 -1 1 -1 1 -1 1 1 -1 -1 -1 1 1 -1 -1 -1 -1 1 -1 -1 1 -1 1 1 1 1 -1 1 -1 1 -1 1 -1 -1 -1 -1 -1 1 -1 1 1 -1 1 -1 1 1 1 -1 -1 1 -1 -1 -1 1 1 1 -1 -1 -1 -1 -1 -1 -1];

for ii = 1:10
  curr_ofdm_sym = sig_out_corr(curr_ofdm_sym_start_index:curr_ofdm_sym_start_index+63+16);
  curr_ofdm_sym = remove_cp(curr_ofdm_sym);
  curr_ofdm_wo_eq = curr_ofdm_sym;
  [curr_ofdm_sym curr_ofdm_pilots] = decode_ofdm_symbol(curr_ofdm_sym, H_ls);
  pilot_zero = [pilot_zero curr_ofdm_pilots(1)];
  curr_ofdm_sym = derotate_ofdm_symbol(curr_ofdm_sym, curr_ofdm_pilots, polarity_seq(ii));
  curr_ofdm_sym_start_index = curr_ofdm_sym_start_index+16+64;

  ############## PLOT ##################
  plot(real(curr_ofdm_pilots), imag(curr_ofdm_pilots), 'marker', 'x', 'color', 'r');
  hold on;
  plot(real(curr_ofdm_sym), imag(curr_ofdm_sym), '.', 'color', 'b');
  axis([-2 2 -2 2], "manual");
  title('OFDM Symbols After Equalization and BB Derotation');
  legend("Pilot Symbols", "Derotated Data Symbols");
  grid on;
  drawnow;
  sleep(0.5);
  #######################################
endfor
#figure;
#plot(phi_log./(2*pi));
#title('Phi/2pi');
#mean(phi_log./(2*pi))
#figure;
#plot(arg(pilot_zero)./(2*pi));
#title('Pilot Zero Phase Data');
endif