%% Estimate and Correct CFO for VHT Waveform with Correlation Offset
% Estimate the frequency offset for a VHT signal passing through a noisy, TGac channel. Correct for the frequency offset.
% Create a VHT configuration object and create the L-STF.

vht = wlanVHTConfig;
txstf = wlanLSTF(vht);

%
% Set the channel bandwidth and sample rate.

cbw = 'CBW80';
fs = 80e6;

%
% Create TGac and thermal noise channel objects. Set the delay profile of the TGac channel to 'Model-C'. Set the noise figure of the thermal noise channel to 9 dB.

tgacChan = wlanTGacChannel('SampleRate',fs,'ChannelBandwidth',cbw, ...
    'DelayProfile','Model-C','LargeScaleFadingEffect','Pathloss');

noise = comm.ThermalNoise('SampleRate',fs,'NoiseMethod','Noise figure', ...
    'NoiseFigure',9);

%
% Pass the L-STF through the noisy TGac channel.

rxstfNoNoise = tgacChan(txstf);
rxstf = noise(rxstfNoNoise);

%
% Create a phase and frequency offset object and introduce a 750 Hz frequency offset.

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

%
% For the model-C delay profile, the RMS delay spread is 30 ns, which is 3/8 of the 80 ns short training symbol duration. As such, set the correlation offset to 0.375.

corrOffset = 0.375;

%
% Estimate the frequency offset. Your results may differ slightly.

fOffsetEst = wlanCoarseCFOEstimate(rxstf,cbw,corrOffset)

% The estimate is very close to the introduced CFO of 750 Hz.
%
% Change the delay profile to 'Model-E', which has an RMS delay spread of 100 ns.

release(tgacChan)
tgacChan.DelayProfile = 'Model-E';

%
% Pass the transmitted signal through the modified channel and apply the 750 Hz CFO.

rxstfNoNoise = tgacChan(txstf);
rxstf = noise(rxstfNoNoise);
rxstf = pfOffset(rxstf,750);

%
% Estimate the frequency offset.

fOffsetEst = wlanCoarseCFOEstimate(rxstf,cbw,corrOffset)

% The estimate is inaccurate because the RMS delay spread is greater than the duration of the training symbol.
%
% Set the correlation offset to the maximum value of 1 and estimate the CFO.

corrOffset = 1;
fOffsetEst = wlanCoarseCFOEstimate(rxstf,cbw,corrOffset)

% The estimate is accurate because the autocorrelation does not use the first training symbol. The channel delay renders this symbol useless.
%
% Correct for the estimated frequency offset.

rxstfCorrected = pfOffset(rxstf,-fOffsetEst);

%
% Estimate the frequency offset of the corrected signal.

fOffsetEstCorr = wlanCoarseCFOEstimate(rxstfCorrected,cbw,corrOffset)

% The corrected signal has negligible frequency offset.
% Copyright 2012 The MathWorks, Inc.