gusucode.com > wlan工具箱matlab源码程序 > wlan/wlan/wlanHTSIGRecover.m

    function [bits, failCRC, eqDataSym, varargout] = wlanHTSIGRecover(...
				rxHTSIG, chanEst, noiseVarEst, chanBW, varargin)
%WLANHTSIGRECOVER Recover information bits in HT-SIG field
% 
%   [BITS, FAILCRC] = wlanHTSIGRecover(RXHTSIG, CHANEST, NOISEVAREST,
%   CHANBW) recovers the information bits in the HT-SIG field and performs
%   CRC check.
% 
%   BITS is an int8 column vector of length 48 containing the recovered
%   information bits.
%
%   FAILCRC is true if BITS fails the CRC check. It is a logical scalar.
% 
%   RXHTSIG is the received time-domain HT-SIG field signal. It is a
%   Ns-by-Nr matrix of real or complex values, where Ns represents the
%   number of time-domain samples in the HT-SIG field and Nr represents the
%   number of receive antennas. Ns can be greater than the HT-SIG field
%   length; in this case additional samples at the end of RXHTSIG are not
%   used.
% 
%   CHANEST is the estimated channel at data and pilot subcarriers based on
%   the L-LTF. It is a real or complex array of size Nst-by-1-by-Nr, where
%   Nst represents the total number of occupied subcarriers.  The singleton
%   dimension corresponds to the single transmitted stream in the L-LTF
%   which includes the combined cyclic shifts if multiple transmit antennas
%   are used.
%   
%   NOISEVAREST is the noise variance estimate. It is a real, nonnegative
%   scalar.
%
%   CHANBW is a string describing the channel bandwidth and must be 'CBW20'
%   or 'CBW40'.
% 
%   [BITS, FAILCRC] = wlanHTSIGRecover(..., CFGREC) allows different
%   algorithm options for information bit recovery via the input CFGREC,
%   which is a <a href="matlab:help('wlanRecoveryConfig')">wlanRecoveryConfig</a> configuration object. When the CFGREC
%   input is not specified, the default property values of the
%   <a href="matlab:help('wlanRecoveryConfig')">wlanRecoveryConfig</a> object are adopted in the recovery.
%
%   [..., EQDATASYM, CPE] = wlanHTSIGRecover(...) also returns the
%   equalized subcarriers and common phase error.
%
%   EQDATASYM is a 48-by-2 complex matrix containing the equalized symbols
%   at data carrying subcarriers. There are 48 data carrying subcarriers in
%   each of the 2 OFDM symbols which constitute the HT-SIG field.
%
%   CPE is a column vector of length 2 containing the common phase error
%   between each of the 2 received and expected OFDM symbols.
%
%   Example: 
%   %  Recover the information bits in HT-SIG field via channel estimation 
%   %  on L-LTF over a 2 x 4 quasi-static fading channel
%
%     % Configure a HT configuration object 
%     chanBW = 'CBW40';
%     cfgHT = wlanHTConfig('ChannelBandwidth', 'CBW40', ...
%         'NumTransmitAntennas', 2, 'NumSpaceTimeStreams', 2); 
%  
%     % Generate L-LTF and HT-SIG field signals
%     txLLTF  = wlanLLTF(cfgHT); 
%     txHTSIG = wlanHTSIG(cfgHT);
% 
%     % Pass through a 2 x 4 quasi-static fading channel with AWGN 
%     H = 1/sqrt(2)*complex(randn(2, 4), randn(2, 4));
%     rxLLTF  = awgn(txLLTF  *H, 10);
%     rxHTSIG = awgn(txHTSIG *H, 10);
% 
%     % Perform channel estimation based on L-LTF
%     demodLLTF = wlanLLTFDemodulate(rxLLTF, chanBW, 1);
%     chanEst = wlanLLTFChannelEstimate(demodLLTF, chanBW);
% 
%     % Recover information bits in HT-SIG
%     [recHTSIGBits, failCRC] = wlanHTSIGRecover(rxHTSIG, chanEst, ...
%            0.1, chanBW);
%
%     % Check CRC validation
%     failCRC
% 
%   See also wlanRecoveryConfig, wlanHTSIG, wlanLLTF, wlanLLTFDemodulate,
%   wlanLLTFChannelEstimate.

%   Copyright 2015-2016 The MathWorks, Inc.

%#codegen

narginchk(4, 5);
nargoutchk(0, 4);

% Calculate CPE if requested
if nargout>3
    calculateCPE = true;
else
    calculateCPE = false;
end

% Validate channel bandwidth input
coder.internal.errorIf(~ischar(chanBW) || ...
    ~any(strcmp(chanBW, {'CBW20','CBW40'})), ...
    'wlan:wlanHTSIGRecover:InvalidChanBW');

% Get OFDM configuration
[cfgOFDM,dataInd,pilotInd] = wlan.internal.wlanGetOFDMConfig(chanBW, 'Long', 'Legacy');

% Validate HT-SIG field signal input
validateattributes(rxHTSIG, {'double'}, ...
    {'2d','finite','nrows',cfgOFDM.FFTLength*5/2}, ...
    'rxHTSIG', 'HT-SIG field signal'); 
numRx = size(rxHTSIG, 2);

% Validate channel estimates
validateattributes(chanEst, {'double'}, {'3d','finite'}, ...
    'chanEst', 'channel estimates'); 

% Cross validate inputs
numST = numel([dataInd; pilotInd]); % Total number of occupied subcarriers
coder.internal.errorIf(size(chanEst, 1) ~= numST, ...
    'wlan:wlanHTSIGRecover:InvalidChanEst1D', numST);
coder.internal.errorIf(size(chanEst, 2) ~= 1, ...
    'wlan:wlanHTSIGRecover:InvalidChanEst2D');
coder.internal.errorIf(size(chanEst, 3) ~= numRx, ...
    'wlan:wlanHTSIGRecover:InvalidChanEst3D');

% Extract data and pilot subcarriers from channel estimate
chanEstData = chanEst(dataInd,:,:);
chanEstPilots = chanEst(pilotInd,:,:);

% Validate noise variance estimate input
validateattributes(noiseVarEst, {'double'}, ...
    {'real','scalar','nonnegative','finite'}, ...
    'noiseVarEst', 'noise variance estimate'); 

% Validate optional recovery configuration input
if nargin == 5
    validateattributes(varargin{1}, {'wlanRecoveryConfig'}, {'scalar'}, ...
        'cfgRec', 'recovery configuration object');
    symOffset = varargin{1}.OFDMSymbolOffset;
    eqMethod  = varargin{1}.EqualizationMethod; 
    pilotPhaseTracking = varargin{1}.PilotPhaseTracking;
else
    symOffset = 0.75;
    eqMethod  = 'MMSE'; 
    pilotPhaseTracking = 'PreEQ';
end

% OFDM demodulation
[ofdmOutData, ofdmOutPilots] = wlan.internal.wlanOFDMDemodulate(rxHTSIG, cfgOFDM, symOffset);

% Pilot phase tracking
if calculateCPE==true || strcmp(pilotPhaseTracking, 'PreEQ')
    % Get reference pilots, from IEEE Std 802.11-2012, Eqn 20-17
    z = 1; % Offset by 1 to account for L-SIG pilot symbol
    refPilots = wlan.internal.nonHTPilots(2, z, chanBW);
     
    % Estimate CPE and phase correct symbols
    cpe = wlan.internal.commonPhaseErrorEstimate(ofdmOutPilots, chanEstPilots, ...
        refPilots);
    if strcmp(pilotPhaseTracking, 'PreEQ')
        ofdmOutData = wlan.internal.commonPhaseErrorCorrect(ofdmOutData, cpe);
    end
    if calculateCPE==true
        varargout{1} = cpe.'; % Permute to Nsym-by-1
    end
end

% Merge num20 channel estimates and demodulated symbols together for the
% repeated subcarriers for data subcarriers
num20MHz = cfgOFDM.FFTLength/64; % Number of 20 MHz subchannels
[ofdmOutDataOne20MHz, chanEstDataOne20MHz] = wlan.internal.mergeSubchannels( ...
    ofdmOutData, chanEstData, num20MHz);
% Perform equalization
[eqDataSym, csiData] = wlan.internal.wlanEqualize(ofdmOutDataOne20MHz, ...
    chanEstDataOne20MHz, eqMethod, noiseVarEst);

% Constellation demapping
demodOut = wlan.internal.wlanConstellationDemodulate(eqDataSym, 1, noiseVarEst, pi/2);
demodOut = demodOut .* repmat(csiData, 1, 2);

% Deinterleaving
deintlvrOut = zeros(size(demodOut));
deintlvrOut(:, 1) = wlan.internal.wlanBCCDeinterleave(demodOut(:, 1), 'NON_HT', 48, 1);
deintlvrOut(:, 2) = wlan.internal.wlanBCCDeinterleave(demodOut(:, 2), 'NON_HT', 48, 1);

% BCC decoding 
bits = wlan.internal.wlanBCCDecode(deintlvrOut(:), '1/2'); 

% CRC detection
[~, failCRC] = wlan.internal.wlanCRCDetect(bits(1:42));

end

% [EOF]