%% Basic VHT Data Recovery Steps
% This example shows how to perform basic VHT data recovery. It also shows how to recover VHT data when the received signal has a carrier frequency offset. Similar procedures can be used to recover data with the HT and non-HT formats.
%% Basic Data Recovery
% The WLAN Toolbox™ provides functions to generate and recover IEEE® 802.11ac™ standards compliant waveforms. Data recovery is accomplished by these steps:
% Generate a VHT waveform
% Pass the waveform through a channel
% Extract the VHT-LTF and demodulate
% Estimate the channel by using the demodulated VHT-LTF
% Extract the data field
% Recover the data by using the channel and noise variance estimates
% The block diagram shows these steps, along with their corresponding commands.
%
% Create VHT format configuration object.

vht = wlanVHTConfig;

%
% Create a VHT transmit waveform by using the VHT configuration object. Set the data sequence to [1;0;1;1]. The data sequence is repeated to generate the specified number of packets.

txSig = wlanWaveformGenerator([1;0;1;1],vht);

%
% Pass the received signal through an AWGN channel.

rxSig = awgn(txSig,10);

%
% Determine the field indices of the waveform.

ind = wlanFieldIndices(vht);

%
% Extract the VHT-LTF from the received signal.

rxVHTLTF = rxSig(ind.VHTLTF(1):ind.VHTLTF(2),:);

%
% Demodulate the VHT-LTF. Estimate the channel response by using the demodulated signal.

demodVHTLTF = wlanVHTLTFDemodulate(rxVHTLTF,vht);
chEst = wlanVHTLTFChannelEstimate(demodVHTLTF,vht);

%
% Extract the VHT data field.

rxData = rxSig(ind.VHTData(1):ind.VHTData(2),:);

%
% Recover the information bits by using the channel and noise variance estimates. Confirm that the first 8 bits match two repetitions of the input data sequence of [1;0;1;1].

rxBits = wlanVHTDataRecover(rxData,chEst,0.1,vht);

rxBits(1:8)

%
%% Data Recovery with Frequency Correction
% Data recovery when a carrier frequency offset is present is accomplished by these steps:
% Generate a VHT waveform
% Pass the waveform through a channel
% Extract the L-STF and perform a coarse frequency offset estimate
% Correct for the offset by using the coarse estimate
% Extract the L-LTF and perform a fine frequency offset estimate
% Correct for the offset by using the fine estimate
% Extract the VHT-LTF and demodulate
% Estimate the channel by using the demodulated VHT-LTF
% Extract the data field
% Recover the data by using the channel and noise variance estimates
% The block diagram shows these steps, along with their corresponding commands.
%
% Set the channel bandwidth and sample rate.

cbw = 'CBW160';
fs = 160e6;

%
% Create a VHT configuration object that supports a 2x2 MIMO transmission.

vht = wlanVHTConfig('ChannelBandwidth',cbw, ...
    'NumTransmitAntennas',2,'NumSpaceTimeStreams',2);

%
% Generate a VHT waveform containing a random PSDU.

txPSDU = randi([0 1],vht.PSDULength*8,1);
txSig = wlanWaveformGenerator(txPSDU,vht);

%
% Create a 2x2 TGac channel.

tgacChan = wlanTGacChannel('SampleRate',fs,'ChannelBandwidth',cbw, ...
    'NumTransmitAntennas',2,'NumReceiveAntennas',2);

%
% Create a phase and frequency offset object.

pfOffset = comm.PhaseFrequencyOffset('SampleRate',fs,'FrequencyOffsetSource','Input port');

%
% Pass the transmitted waveform through the noisy TGac channel.

rxSigNoNoise = tgacChan(txSig);
rxSig = awgn(rxSigNoNoise,15);

%
% Introduce a frequency offset of 500 Hz to the received signal.

rxSigFreqOffset = pfOffset(rxSig,500);

%
% Find the start and stop indices for all component fields of the PPDU.

ind = wlanFieldIndices(vht);

%
% Extract the L-STF. Estimate and correct for the carrier frequency offset.

rxLSTF = rxSigFreqOffset(ind.LSTF(1):ind.LSTF(2),:);

foffset1 = wlanCoarseCFOEstimate(rxLSTF,cbw);
rxSig1 = pfOffset(rxSigFreqOffset,-foffset1);

%
% Extract the L-LTF from the corrected signal. Estimate and correct for the residual frequency offset.

rxLLTF = rxSig1(ind.LLTF(1):ind.LLTF(2),:);

foffset2 = wlanFineCFOEstimate(rxLLTF,cbw);
rxSig2 = pfOffset(rxSig1,-foffset2);

%
% Extract and demodulate the VHT-LTF. Estimate the channel coefficients.

rxVHTLTF = rxSig2(ind.VHTLTF(1):ind.VHTLTF(2),:);
demodVHTLTF = wlanVHTLTFDemodulate(rxVHTLTF,vht);
chEst = wlanVHTLTFChannelEstimate(demodVHTLTF,vht);

%
% Extract the VHT data field from the received and frequency-corrected PPDU. Recover the data field.

rxData = rxSig2(ind.VHTData(1):ind.VHTData(2),:);
rxPSDU = wlanVHTDataRecover(rxData,chEst,0.03,vht);

%
% Calculate the number of bit errors in the received packet.

numErr = biterr(txPSDU,rxPSDU)

% Copyright 2012 The MathWorks, Inc.