HE/WaveAdp/rx_preambleprocess.m

90 lines
3.1 KiB
Mathematica
Raw Normal View History

2024-03-30 16:35:40 +08:00
function [rx_datafield,MCS,PSDULength,failCheck,rec_frameNo,estNumerlogy,numeroError] = rx_preambleprocess(rx)
searchOffset = 0; % Offset from start of waveform in samples
rxWaveLen = 30000;
cfg = wlanNonHTConfig('SignalChannelBandwidth',true, ...
'BandwidthOperation','Static');
% Generate field indices
ind = wlanFieldIndices(cfg);
chanBW = cfg.ChannelBandwidth;
sr = wlanSampleRate(cfg); % Sample rate
% while (searchOffset + minPktLen) <= rxWaveLen
% Packet detection
threshold = 0.8;
[pktOffset,M] = wlanPacketDetect(rx,chanBW,searchOffset,threshold);
plot(M)
% Adjust packet offset
pktOffset = searchOffset + pktOffset;
if isempty(pktOffset) || (pktOffset + ind.LSIG(2) > rxWaveLen)
error('** No packet detected **');
end
% Coarse frequency offset estimation and correction using L-STF
rxLSTF = rx(pktOffset+(ind.LSTF(1):ind.LSTF(2)), :);
coarseFreqOffset = wlanCoarseCFOEstimate(rxLSTF,chanBW);
rx = helperFrequencyOffset(rx,sr,-coarseFreqOffset);
% Symbol timing synchronization
searchBufferLLTF = rx(pktOffset+(ind.LSTF(1):ind.LSIG(2)),:);
pktOffset = pktOffset+wlanSymbolTimingEstimate(searchBufferLLTF,chanBW);
% Fine frequency offset estimation and correction using L-STF
rxLLTF = rx(pktOffset+(ind.LLTF(1):ind.LLTF(2)),:);
fineFreqOffset = wlanFineCFOEstimate(rxLLTF,chanBW);
rx = helperFrequencyOffset(rx,sr,-fineFreqOffset);
% Scale the waveform based on L-STF power (AGC)
gain = 1./(sqrt(mean(rxLSTF.*conj(rxLSTF))));
rx = rx.*gain;
% Packet Format Detection
rxLLTF = rx(pktOffset+(ind.LLTF(1):ind.LLTF(2)),:);
lltfDemod = wlanLLTFDemodulate(rxLLTF,chanBW);
lltfChanEst = wlanLLTFChannelEstimate(lltfDemod,chanBW);
noiseVar = helperNoiseEstimate(lltfDemod);
% Recover L-SIG field bits
[rxLSIGBits, failCheck, ~] = wlanLSIGRecover(rx(pktOffset + (ind.LSIG(1):ind.LSIG(2)), :), lltfChanEst, noiseVar, chanBW);
[MCS,PSDULength] = interpretLSIG(rxLSIGBits);
rec_frameNo = bi2de(rxLSIGBits(19:24).','right-msb');
if failCheck % Skip L-STF length of samples and continue searching
disp('** L-SIG check fail **');
else
disp('L-SIG check pass');
end
% Recover Numerology field bits
rxLSTF = rx(pktOffset+(ind.LSTF(1):ind.LSTF(2)), :);
[estNumerlogy,numeroError] = STS_demod(rxLSTF);
if numeroError
disp('** Numerology check fail **');
else
disp('Numerology check pass');
end
% output data field
% rx_datafield = rx(pktOffset+(ind.NonHTData(1):ind.NonHTData(2)), :);
rx_datafield = rx(pktOffset+ind.NonHTData(1):end, :);
end
%%
function [MCS,PSDULength] = interpretLSIG(recLSIGBits)
% InterpretLSIG Interprets recovered L-SIG bits
%
% [MCS,PSDULENGTH] = interpretLSIG(RECLSIGBITS) returns the
% modulation and coding scheme and PSDU length given the recovered L-SIG
% bits
% Rate and length are determined from bits
rate = double(recLSIGBits(1:3));
length = double(recLSIGBits(5+(1:12)));
% MCS rate table, IEEE Std 802.11-2016, Table 17-6.
R = wlan.internal.nonHTRateSignalBits();
mcstmp = find(all(bsxfun(@eq,R(1:3,:),rate)))-1;
MCS = mcstmp(1); % For codegen
PSDULength = bi2de(length.');
end