File: ofdm_state.m

package info (click to toggle)
codec2 1.2.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 76,376 kB
  • sloc: ansic: 436,819; cpp: 2,091; objc: 1,736; sh: 1,510; python: 1,405; asm: 683; makefile: 605
file content (271 lines) | stat: -rw-r--r-- 8,192 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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
% ofdm_state.m
%
% Library of state machine functions for the OFDM modem

1;

%-------------------------------------------------------------------
% sync_state_machine - calls mode-specific sync state state_machine
%-------------------------------------------------------------------

function states = sync_state_machine(states, rx_uw)
  if strcmp(states.state_machine, "voice1")
    states = sync_state_machine_voice1(states, rx_uw);
  elseif strcmp(states.state_machine, "data")
    if strcmp(states.data_mode, "streaming")
      states = sync_state_machine_data_streaming(states, rx_uw);
    else
      states = sync_state_machine_data_burst(states, rx_uw);
    end
  elseif strcmp(states.state_machine, "voice2")
    states = sync_state_machine_voice2(states, rx_uw);
  else
    assert(0);
  endif
endfunction

%--------------------------------------------------------------------
%  Due to the low pilot symbol insertion rate and acquisition issues
%  the earlier OFDM modem waveforms (700D and 2020) need a complex
%  state machine to help them avoid false sync.
%--------------------------------------------------------------------

function states = sync_state_machine_voice1(states, rx_uw)
  ofdm_load_const;
  next_state = states.sync_state;
  states.sync_start = states.sync_end = 0;

  if strcmp(states.sync_state,'search')

    if states.timing_valid
      states.frame_count = 0;
      states.sync_counter = 0;
      states.modem_frame = 0;
      states.sync_start = 1;
      next_state = 'trial';
    end
  end

  if strcmp(states.sync_state,'synced') || strcmp(states.sync_state,'trial')

    states.frame_count++;

    % UW occurs at the start of a packet
    if states.modem_frame == 0
        states.uw_errors = sum(xor(tx_uw,rx_uw));

        if strcmp(states.sync_state,'trial')
          if states.uw_errors >= states.bad_uw_errors
            states.sync_counter++;
            states.frame_count = 0;
          end
          if states.sync_counter == 2
            next_state = "search";
            states.phase_est_bandwidth = "high";
          end
          if states.frame_count == 4
            next_state = "synced";
            % change to low bandwidth, but more accurate phase estimation
            states.phase_est_bandwidth = "low";
          end
          if states.uw_errors < 2
            next_state = "synced";
            % change to low bandwidth, but more accurate phase estimation
            states.phase_est_bandwidth = "low";
          else
            next_state = "search";
          end
        end

        if strcmp(states.sync_state,'synced')
          if states.uw_errors > 2
            states.sync_counter++;
          else
            states.sync_counter = 0;
          end

          if states.sync_counter == 6
            next_state = "search";
            states.phase_est_bandwidth = "high";
          end
        end
      end % if modem_frame == 0 ....

      % keep track of where we are up to in packet
      states.modem_frame++;
      if (states.modem_frame >= states.Np) states.modem_frame = 0; end
  end

  states.last_sync_state = states.sync_state;
  states.sync_state = next_state;
endfunction


%-------------------------------------------------------
% data (streaming mode) state machine
%-------------------------------------------------------

function states = sync_state_machine_data_streaming(states, rx_uw)
  ofdm_load_const;
  next_state = states.sync_state;
  states.sync_start = states.sync_end = 0;

  if strcmp(states.sync_state,'search')
    if states.timing_valid
      states.sync_start = 1; 
      states.sync_counter = 0;
      next_state = 'trial';
    end
  end

  states.uw_errors = sum(xor(tx_uw,rx_uw));

  if strcmp(states.sync_state,'trial')
    if states.uw_errors < states.bad_uw_errors;
      next_state = "synced";
      states.packet_count = 0;
      states.modem_frame = Nuwframes;
    else
      states.sync_counter++;
      if states.sync_counter > Np
        next_state = "search";
      end
    end
  end
 
  % Note packetsperburst==0 we don't ever lose sync, which is useful for 
  % stream based testing or external control of state machine
  
  if strcmp(states.sync_state,'synced')
    states.modem_frame++;
    if (states.modem_frame >= states.Np) 
      states.modem_frame = 0; 
      states.packet_count++;
      if (states.packetsperburst)
        if (states.packet_count >= states.packetsperburst)
          next_state = "search";
        end
      end
    end
  end
  
  states.last_sync_state = states.sync_state;
  states.sync_state = next_state;
endfunction

%-------------------------------------------------------
% data (burst mode) state machine
%-------------------------------------------------------

function states = sync_state_machine_data_burst(states, rx_uw)
  ofdm_load_const;
  next_state = states.sync_state;
  states.sync_start = states.sync_end = 0;

  if strcmp(states.sync_state,'search')
    if states.timing_valid
      states.sync_start = 1; 
      states.sync_counter = 0;
      next_state = 'trial';
    end
  end

  states.uw_errors = sum(xor(tx_uw,rx_uw));

  % pre or post-amble has told us this is the start of the packet.  Confirm we 
  % have a valid frame by checking the UW after the modem frames containing
  % the UW have been received 
  if strcmp(states.sync_state,'trial')
    states.sync_counter++;
    if states.sync_counter == Nuwframes
      if states.uw_errors < states.bad_uw_errors;
        next_state = "synced";
        states.packet_count = 0;                          % number of packets in this burst
        states.modem_frame = Nuwframes;                   % which modem frame we are up to in packet
      else
        next_state = "search";
        % reset rxbuf to make sure we only ever do a postamble loop once through same samples
        states.rxbufst = states.Nrxbufhistory;
        states.rxbuf = zeros(1, states.Nrxbuf);
      end
    end
  end
  
  if strcmp(states.sync_state,'synced')
    states.modem_frame++;
    if (states.modem_frame >= states.Np) 
      states.modem_frame = 0;                           % start of new packet
      states.packet_count++;
      if (states.packetsperburst)
        if (states.packet_count >= states.packetsperburst)
          next_state = "search";                        % we've finished this burst
          % reset rxbuf to make sure we only ever do a postamble loop once through same samples
          states.rxbufst = states.Nrxbufhistory;
          states.rxbuf = zeros(1, states.Nrxbuf);
        end
      end
    end
  end
  
  states.last_sync_state = states.sync_state;
  states.sync_state = next_state;
endfunction

%-------------------------------------------------------
% fast sync voice state state_machine
%-------------------------------------------------------

function states = sync_state_machine_voice2(states, rx_uw)
  ofdm_load_const;
  next_state = states.sync_state;
  states.sync_start = states.sync_end = 0;

  if strcmp(states.sync_state,'search')

    if states.timing_valid
      states.frame_count = 0;
      states.sync_counter = 0;
      states.modem_frame = 0;
      states.sync_start = 1;
      next_state = 'trial';
    end
  end

  if strcmp(states.sync_state,'synced') || strcmp(states.sync_state,'trial')

    states.frame_count++;

    % UW occurs at the start of a packet
    if states.modem_frame == 0
        states.uw_errors = sum(xor(tx_uw,rx_uw));

        if strcmp(states.sync_state,'trial')
          if states.uw_errors <= states.bad_uw_errors
            next_state = "synced";
          else
            next_state = "search";
          end
        end

        if strcmp(states.sync_state,'synced')
          if states.uw_errors > states.bad_uw_errors
            states.sync_counter++;
          else
            states.sync_counter = 0;
          end

          if states.sync_counter == 6
            next_state = "search";
          end
        end
      end

      % keep track of where we are up to in packet
      states.modem_frame++;
      if (states.modem_frame >= states.Np) states.modem_frame = 0; end
  end

  states.last_sync_state = states.sync_state;
  states.sync_state = next_state;
endfunction