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