gusucode.com > wlan工具箱matlab源码程序 > wlan/wlan/+wlan/+internal/s1gOFDMConfig.m

    function [ofdmCfg,varargout] = s1gOFDMConfig(chanBW,CPType,field,varargin)
%s1gOFDMConfig S1G OFDM configuration
%
%   Note: This is an internal undocumented function and its API and/or
%   functionality may change in subsequent releases.
%
%   OFDMCFG = s1gOFDMConfig(CHANBW,CPTYPE,FIELD,NUMSTSTX) returns a
%   structure containing the OFDM configuration.
%
%   CHANBW is a string representing the channel bandwidth
%
%   CPTYPE is a string representing the CP length used for data field
%   processing and must be 'Long' or 'Short'.
%
%   FIELD is a string specifying which field to return the OFDM
%   configuration for. It must be one of: 'STF', 'DSTF', 'LTF', 'LTF1',
%   'DLTF', 'SIG', 'SIG-A', 'SIG-B', 'Data'
%
%   NUMSTSTX is the number of space-time streams or transmit antennas used.
%   The number of transmit antennas should be used if the field is in the
%   omni-portion of the packet, e.g. >2MHz Long preamble STF, LTF1, SIGA.
%   Otherwise the number of space-time streams should be used.
%
%   OFDMCFG = s1gOFDMConfig(... TRAVELINGPILOTS,NSYM) additionally
%   specifies if traveling pilots are used as true or false and the number
%   of symbols required for the pilots. The default TRAVELINGPILOTS if not
%   specified is false and the default NSYM if not specified is 1.
%
%   [OFDMCFG,DATAIND,PILOTIND] additionally returns the indices of data and
%   pilot subcarriers within occupied subcarriers.

%   Copyright 2016 The MathWorks, Inc.

%#codegen

narginchk(3,6);
nargoutchk(0,3);

numSTSTx = 1;
Nsym = 1;
travelingPilots = false;
if nargin>3
    numSTSTx = varargin{1};
    if nargin>4
        travelingPilots = logical(varargin{2}); % true or false
        if nargin>5
            Nsym = varargin{3};
        end
    end
end

% S1G; different gamma for every 32/64 subcarrier group, IEEE
% P802.11ah/D5.0 Section 24.3.7
switch chanBW
    case {'CBW1','CBW2'}
        GammaPhase = 1;  % Eqn 24-5/24-6
    case 'CBW4'
        GammaPhase = [1 1i];  % Eqn 24-7                
    case 'CBW8'
        GammaPhase = [1 -1 -1 -1]; % Eqn 24-8
    otherwise % 'CBW16'
        GammaPhase = [1 -1 -1 -1 1 -1 -1 -1]; % Eqn 24-9
end

Nsubchan = numel(GammaPhase); % Number of 2MHz subchannels
if strcmp(chanBW,'CBW1')
    subchanFFTLen = 32; % FFT length for a sub channel
else
    subchanFFTLen = 64;
end
FFTLen = subchanFFTLen*Nsubchan;

% Tone rotation: Section 24.3.7. (gamma)
toneRotation = reshape(repmat(GammaPhase,[subchanFFTLen,1]),[],1);

% Guard interval timing related constants (Table 24-4)
if strcmp(CPType,'Long')
    CPLenField = FFTLen/4;  % Guard interval duration
else % strcmp(CPType,'Short')
    CPLenField = FFTLen/8; % Short guard interval
end

% Calculate indices of data and pilot carrying subcarriers
if any(strcmp(field,{'SIG','SIG-A'}))
% SIG and SIG-A fields are different in terms of construction to others as
% specified for 2 MHz segments then duplicated.
    if strcmp(chanBW,'CBW1')
        KPilot = wlan.internal.s1gKPilotFix('CBW1');
        [Nsd,Nsp,Nsr] = wlan.internal.s1gSubcarriersPerSymbol(field,'CBW1');
    else % CBW2,CBW4,CBW8,CBW16
        KPilot = wlan.internal.s1gKPilotFix('CBW2');
        [Nsd,Nsp,Nsr] = wlan.internal.s1gSubcarriersPerSymbol(field,'CBW2');
    end
    KData = setdiff((-Nsr:Nsr).',sort([KPilot; 0])); % Data excludes pilots and DC (no custom nulls)
    dataIdx = reshape(bsxfun(@plus,KData,(0:(Nsubchan-1))*subchanFFTLen), ...
        Nsd*Nsubchan,1)+subchanFFTLen/2+1;
    pilotIdx = reshape(bsxfun(@plus,KPilot,(0:(Nsubchan-1))*subchanFFTLen), ...
        Nsp*Nsubchan,1)+subchanFFTLen/2+1;
else %SIG-B, Data
    % Section 24.3.7, exclude subcarriers from carrying data or pilots
    % Get the number of occupied subcarriers
    [Nsd,~,Nsr] = wlan.internal.s1gSubcarriersPerSymbol(field,chanBW);
    switch chanBW
        case {'CBW1','CBW2'}
            customNullIdx = [];
        case {'CBW4','CBW8'}
            customNullIdx = [-1; 1];
        otherwise % 'CBW16'
            customNullIdx = [(-129:-127)'; (-5:-1)'; (1:5)'; (127:129)'];
    end
    % Calculate data and pilot indices
    if strcmp(field,'Data') && travelingPilots==true
        KPilot = wlan.internal.s1gKPilotTravel(chanBW,numSTSTx,Nsym);
        KData = zeros(Nsd,Nsym);
        for isym = 1:Nsym
            % Data excludes pilots, custom nulls and DC
            KData(:,isym) = setdiff((-Nsr:Nsr).',sort([KPilot(:,isym); customNullIdx; 0]));
        end
    else % Fixed pilots
        KPilot = wlan.internal.s1gKPilotFix(chanBW);
        % Data excludes pilots, custom nulls and DC
        KData = setdiff((-Nsr:Nsr).',sort([KPilot; customNullIdx; 0]));
    end
    dataIdx = KData+FFTLen/2+1;
    pilotIdx = KPilot+FFTLen/2+1;
end

% The tone scaling factor in Table 24-7 is created for all fields except
% the STF with the following
Ntone = size(dataIdx,1)+size(pilotIdx,1);

% numSTS or numTX depending on field. NumTX for long preamble, fields STF,
% LTF1 or SIGA
normFactor = FFTLen/sqrt(Ntone*numSTSTx); 

ofdmCfg = struct( ...
    'FFTLength',           FFTLen, ...
    'CyclicPrefixLength',  CPLenField, ...
    'DataIndices',         dataIdx, ...
    'PilotIndices',        pilotIdx, ...
    'CarrierRotations',    toneRotation, ...
    'NormalizationFactor', normFactor);

if nargout>1
    % Transform indices addressing whole FFT length, to indices addressing
    % occupied subcarriers
    allIndices = [dataIdx; pilotIdx];
    Nsd = size(dataIdx,1);
    [~,idxOccupiedSubcarriers] = ismember(allIndices,sort(allIndices));
    dataIndNst = idxOccupiedSubcarriers(1:Nsd,:); % Data indices within occupied subcarriers
    varargout{1} = dataIndNst;
    if nargout>2
        pilotIndNst = idxOccupiedSubcarriers(Nsd+1:end,:); % Pilot indices within occupied subcarriers
        varargout{2} = pilotIndNst;
    end
end
end