99 lines
3.9 KiB
Mathematica
99 lines
3.9 KiB
Mathematica
![]() |
function [] = DataDecoding(rx)
|
||
|
|
||
|
%% HE-Data Decoding
|
||
|
% The updated <matlab:edit('wlanHERecoveryConfig.m') wlanHERecoveryConfig>
|
||
|
% object for each user can then be used to recover the PSDU bits for each
|
||
|
% user in the HE-Data field.
|
||
|
|
||
|
cfgDataRec = trackingRecoveryConfig;
|
||
|
cfgDataRec.PilotTracking = pilotTracking;
|
||
|
|
||
|
fprintf('Decoding HE-Data...\n');
|
||
|
for iu = 1:numUsers
|
||
|
% Get recovery configuration object for each user
|
||
|
user = cfgUsers{iu};
|
||
|
if strcmp(pktFormat,'HE-MU')
|
||
|
fprintf(' Decoding User:%d, STAID:%d, RUSize:%d\n',iu,user.STAID,user.RUSize);
|
||
|
else
|
||
|
fprintf(' Decoding RUSize:%d\n',user.RUSize);
|
||
|
end
|
||
|
|
||
|
heInfo = wlanHEOFDMInfo('HE-Data',chanBW,user.GuardInterval,[user.RUSize user.RUIndex]);
|
||
|
|
||
|
% HE-LTF demodulation and channel estimation
|
||
|
rxHELTF = rx(pktOffset+(ind.HELTF(1):ind.HELTF(2)),:);
|
||
|
heltfDemod = wlanHEDemodulate(rxHELTF,'HE-LTF',chanBW,user.GuardInterval, ...
|
||
|
user.HELTFType,[user.RUSize user.RUIndex]);
|
||
|
[chanEst,pilotEst] = heLTFChannelEstimate(heltfDemod,user);
|
||
|
|
||
|
% Number of expected data OFDM symbols
|
||
|
symLen = heInfo.FFTLength+heInfo.CPLength;
|
||
|
numOFDMSym = (ind.HEData(2)-ind.HEData(1)+1)/symLen;
|
||
|
|
||
|
% HE-Data demodulation with pilot phase and timing tracking
|
||
|
% Account for extra samples when extracting data field from the packet
|
||
|
% for sample rate offset tracking. Extra samples may be required if the
|
||
|
% receiver clock is significantly faster than the transmitter.
|
||
|
maxSRO = 120; % Parts per million
|
||
|
Ne = ceil(numRxSamples*maxSRO*1e-6); % Number of extra samples
|
||
|
Ne = min(Ne,rxWaveLen-numRxSamples); % Limited to length of waveform
|
||
|
numRxSamplesProcess = numRxSamples+Ne;
|
||
|
rxData = rx(pktOffset+(ind.HEData(1):numRxSamplesProcess),:);
|
||
|
if user.RUSize==26
|
||
|
% Force CPE only tracking for 26-tone RU as algorithm susceptible
|
||
|
% to noise
|
||
|
cfgDataRec.PilotTracking = 'CPE';
|
||
|
else
|
||
|
cfgDataRec.PilotTracking = pilotTracking;
|
||
|
end
|
||
|
[demodSym,cpe,peg] = heTrackingOFDMDemodulate(rxData,chanEst,numOFDMSym,user,cfgDataRec);
|
||
|
|
||
|
% Estimate noise power in HE fields
|
||
|
demodPilotSym = demodSym(heInfo.PilotIndices,:,:);
|
||
|
nVarEst = heNoiseEstimate(demodPilotSym,pilotEst,user);
|
||
|
|
||
|
% Equalize
|
||
|
[eqSym,csi] = heEqualizeCombine(demodSym,chanEst,nVarEst,user);
|
||
|
|
||
|
% Discard pilot subcarriers
|
||
|
eqSymUser = eqSym(heInfo.DataIndices,:,:);
|
||
|
csiData = csi(heInfo.DataIndices,:);
|
||
|
|
||
|
% Demap and decode bits
|
||
|
rxPSDU = wlanHEDataBitRecover(eqSymUser,nVarEst,csiData,user,'LDPCDecodingMethod','layered-bp');
|
||
|
|
||
|
% Deaggregate the A-MPDU
|
||
|
[mpduList,~,status] = wlanAMPDUDeaggregate(rxPSDU,wlanHESUConfig);
|
||
|
if strcmp(status,'Success')
|
||
|
fprintf(' A-MPDU deaggregation successful \n');
|
||
|
else
|
||
|
fprintf(' A-MPDU deaggregation unsuccessful \n');
|
||
|
end
|
||
|
|
||
|
% Decode the list of MPDUs and check the FCS for each MPDU
|
||
|
for i = 1:numel(mpduList)
|
||
|
[~,~,status] = wlanMPDUDecode(mpduList{i},wlanHESUConfig,'DataFormat','octets');
|
||
|
if strcmp(status,'Success')
|
||
|
fprintf(' FCS pass for MPDU:%d\n',i);
|
||
|
else
|
||
|
fprintf(' FCS fail for MPDU:%d\n',i);
|
||
|
end
|
||
|
end
|
||
|
|
||
|
% Plot equalized constellation of the recovered HE data symbols for all
|
||
|
% spatial streams per user
|
||
|
hePlotEQConstellation(eqSymUser,user,ConstellationDiagram,iu,numUsers);
|
||
|
|
||
|
% Measure EVM of HE-Data symbols
|
||
|
release(EVM);
|
||
|
EVM.ReferenceConstellation = wlanReferenceSymbols(user);
|
||
|
rmsEVM = EVM(eqSymUser(:));
|
||
|
fprintf(' HE-Data EVM:%2.2fdB\n\n',20*log10(rmsEVM/100));
|
||
|
|
||
|
% Plot EVM per symbol of the recovered HE data symbols
|
||
|
hePlotEVMPerSymbol(eqSymUser,user,EVMPerSymbol,iu,numUsers);
|
||
|
|
||
|
% Plot EVM per subcarrier of the recovered HE data symbols
|
||
|
hePlotEVMPerSubcarrier(eqSymUser,user,EVMPerSubcarrier,iu,numUsers);
|
||
|
end
|
||
|
end
|