272 lines
8.0 KiB
Matlab
272 lines
8.0 KiB
Matlab
% 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
|
|
|