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

    function format = wlanFormatDetect(rx,chanEst,noiseVarEst,chanBW,varargin)
%wlanFormatDetect Packet format detection
% 
%   FORMAT = wlanFormatDetect(RX, CHANEST, NOISEVAREST, CHANBW) detects the
%   format of a packet as one of the following: Non-HT, HT-MF, HT-GF, or
%   VHT.
%
%   FORMAT is a string specifying the detected format of the packet and is
%   one of: 'Non-HT', 'HT-MF', 'HT-GF', 'VHT'.
%
%   RX is the time domain signal containing the three OFDM symbols
%   immediately following the L-LTF. It is a complex matrix of size
%   Ns-by-Nr, where Ns represents the number of time-domain samples in 3
%   OFDM symbols and Nr represents the number of receive antennas.
%
%   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 one of
%   the following: 'CBW5', 'CBW10', 'CBW20', 'CBW40', 'CBW80', 'CBW160'.
%
%   FORMAT = wlanFormatDetect(..., 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. 
%
%   Example: 
%   %  Generate an HT-MF waveform, add noise and detect the format
%
%     % Transmitter
%     chanBW = 'CBW20';
%     cfgTx = wlanHTConfig('ChannelBandwidth',chanBW);
%     tx = wlanWaveformGenerator([1;0;0;1],cfgTx);
%     snr = 10; % dB
%     rx = awgn(tx,snr); 
%   
%     sr = 20e6;    % Sample rate in Hz for CBW20
%     Tlstf = 8e-6; % L-STF duration in seconds
%     Tlltf = 8e-6; % L-LTF duration in seconds
%   
%     % Channel estimation using L-LTF
%     lltfDemod = wlanLLTFDemodulate(rx(Tlstf*sr+(1:Tlltf*sr),:),chanBW);
%     chanEst = wlanLLTFChannelEstimate(lltfDemod,chanBW);
%     noiseVarEst = 10^(-snr/20);
%   
%     % Format detection using 12 us following L-LTF
%     in = rx((Tlstf+Tlltf)*sr+(1:12e-6*sr),:); % 12 us/3 OFDM symbols
%     format = wlanFormatDetect(in,chanEst,noiseVarEst,chanBW);
%     disp(format);
% 
%   See also wlanRecoveryConfig, wlanLLTFChannelEstimate, wlanLSIGRecover, 
%   wlanVHTSIGARecover, wlanHTSIGRecover.

%   Copyright 2016 The MathWorks, Inc.

%#codegen

narginchk(4,5)

% Validate channel bandwidth input
coder.internal.errorIf(~ischar(chanBW) || ...
    ~any(strcmp(chanBW,{'CBW5','CBW10','CBW20','CBW40','CBW80','CBW160'})), ...
    'wlan:wlanFormatDetect:InvalidChBandwidth');

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

% Validate signal input
validateattributes(rx,{'double'},{'2d','finite'},'rx','signal'); 
% Validate length of signal input
minInputLength = 3*5/4*cfgOFDM.FFTLength; % 3 standard OFDM symbols
coder.internal.errorIf(size(rx,1)<minInputLength, ...
    'wlan:wlanFormatDetect:ShortDataInput',minInputLength);

% Format is always Non-HT for 5 and 10 MHz
if any(strcmp(chanBW,{'CBW5','CBW10'}))
   format = 'Non-HT'; 
   return;
end

num20MHz = cfgOFDM.FFTLength/64; % Number of 20 MHz segments (64pt FFT @ 20 MHz)
Ns = num20MHz*80; % OFDM symbol duration in samples (80 samples @ 20 MHz)

% Recover L-SIG field bits from symbol 0
[lsigBits,lsigFail,lsigSym] = wlanLSIGRecover(rx(1:Ns,:),chanEst, ...
    noiseVarEst,chanBW,varargin{:});

% HT-GF detection
if any(strcmp(chanBW,{'CBW20','CBW40'})) && isqbpsk(lsigSym)
    format = 'HT-GF';
    return;
end

% Warn if L-SIG check fails
if lsigFail
    coder.internal.warning('wlan:wlanFormatDetect:LSIGCheckFail');
end

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

% Demodulate and equalize symbol 1 and symbol 2 
sym = demodulateSymbols(rx(Ns+(1:2*Ns),:),chanEstData,chanEstPilots, ...
    noiseVarEst,chanBW,cfgOFDM,varargin{:});

% Determine format from MCS and QBPSK detection
if getMCS(lsigBits)==0
    if any(strcmp(chanBW,{'CBW20','CBW40'})) && isqbpsk(sym(:,1))
        format = 'HT-MF';
    elseif isqbpsk(sym(:,2))
        format = 'VHT';
    else
        format = 'Non-HT';
    end
else
    format = 'Non-HT';
end
end

% Return true if the symbol is QBPSK and false if BPSK
function result = isqbpsk(sym)
    threshold = 0.5;
    Ns = size(sym,1); % Number of subcarriers
    metric = sum(imag(sym(:)).^2>real(sym(:)).^2);
    result = metric>=(Ns*threshold);
end

% Return the MCS encoded in L-SIG bits
function mcs = getMCS(lsigBits)
    % Rate LUT
    R = wlan.internal.nonHTRateSignalBits();
    tableBits = R(1:3,:); % Only bits R1...R3 are required
    rateBits = lsigBits(1:3);
    if all(rateBits==tableBits(:,1))
        mcs = 0;
    elseif all(rateBits==tableBits(:,2))
        mcs = 1;
    elseif all(rateBits==tableBits(:,3))
        mcs = 2;
    elseif all(rateBits==tableBits(:,4))
        mcs = 3;
    elseif all(rateBits==tableBits(:,5))
        mcs = 4;  
    elseif all(rateBits==tableBits(:,6))
        mcs = 5;
    elseif all(rateBits==tableBits(:,7))
        mcs = 6;
    else
        mcs = 7;
    end
end

% Demodulate and equalize symbols
function sym = demodulateSymbols(rx,chanEstData,chanEstPilots,noiseVarEst, ...
    chanBW,cfgOFDM,varargin)
    % Optional recovery configuration input
    if nargin>6
        symOffset = varargin{1}.OFDMSymbolOffset;
        eqMethod  = varargin{1}.EqualizationMethod;
        pilotPhaseTracking = varargin{1}.PilotPhaseTracking;
    else
        symOffset = 0.75;
        eqMethod  = 'MMSE';
        pilotPhaseTracking = 'PreEQ';
    end

    % OFDM demodulation, data is [48*num20MHz, 2, numRx]
    [ofdmOutData,ofdmOutPilots] = wlan.internal.wlanOFDMDemodulate(rx,cfgOFDM,symOffset);

    % Pilot phase tracking
    if strcmp(pilotPhaseTracking,'PreEQ')
        % Get reference pilots, from Eqn 22-28, IEEE Std 802.11ac-2013
        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);
        ofdmOutData = wlan.internal.commonPhaseErrorCorrect(ofdmOutData,cpe);
    end

    % Merge num20MHz; channel estimates and demodulated symbols together
    % for the repeated subcarriers
    num20MHz = cfgOFDM.FFTLength/64; % Number of 20 MHz subchannels
    [ofdmOutData20MHz,chanEstData20MHz] = wlan.internal.mergeSubchannels( ...
        ofdmOutData,chanEstData,num20MHz);
    % Perform equalization, sym is [48, 2]
    sym = wlan.internal.wlanEqualize(ofdmOutData20MHz,chanEstData20MHz,eqMethod,noiseVarEst);
end