HE/heSURx.m

126 lines
4.8 KiB
Mathematica
Raw Normal View History

2024-03-30 16:35:40 +08:00
function [rxPSDU,bitErrorRate,eqSymPlot,txPSDUByte] = heSURx(rx,cfgHE,userIdx,frameIdx,rxPSDU,cfgUI,SEED,bitErrorRate,eqSymPlot,txPSDUByte)
chanBW = cfgHE.ChannelBandwidth;
ind = wlanFieldIndices(cfgHE);
fs = wlanSampleRate(cfgHE);
ofdmInfo = wlanHEOFDMInfo('HE-Data',cfgHE);
% Packet detect and determine coarse packet offset
coarsePktOffset = wlanPacketDetect(rx,chanBW);
LSTF = wlanLSTF(wlanNonHTConfig);
if isempty(coarsePktOffset)
coarsePktOffset = 0;
end
% Extract L-STF and perform coarse frequency offset correction
lstf = rx(coarsePktOffset+(ind.LSTF(1):ind.LSTF(2)),:);
tmp_xcorr = abs(xcorr(LSTF,lstf));
coarseFreqOff = wlanCoarseCFOEstimate(lstf,chanBW);
rx = helperFrequencyOffset(rx,fs,-coarseFreqOff);
% Extract the non-HT fields and determine fine packet offset
nonhtfields = rx(coarsePktOffset+(ind.LSTF(1):ind.LSIG(2)),:);
finePktOffset = wlanSymbolTimingEstimate(nonhtfields,chanBW);
% Determine final packet offset
pktOffset = coarsePktOffset+finePktOffset;
if max(tmp_xcorr)>50
rxLLTF = rx(pktOffset+(ind.LLTF(1):ind.LLTF(2)),:);
lltfDemod = wlanLLTFDemodulate(rxLLTF,chanBW);
lltfChanEst = wlanLLTFChannelEstimate(lltfDemod,chanBW);
noiseVar = helperNoiseEstimate(lltfDemod);
rxSIGA = rx(pktOffset+(ind.LSIG(1):ind.HESIGA(2)),:);
pktFormat = wlanFormatDetect(rxSIGA,lltfChanEst,noiseVar,chanBW);
fprintf(' %s packet detected\n\n',pktFormat);
% If packet detected outwith the range of expected delays from
% Extract L-LTF and perform fine frequency offset correction
rxLLTF = rx(pktOffset+(ind.LLTF(1):ind.LLTF(2)),:);
fineFreqOff = wlanFineCFOEstimate(rxLLTF,chanBW);
rx = helperFrequencyOffset(rx,fs,-fineFreqOff);
% Display estimated carrier frequency offset
cfoCorrection = coarseFreqOff + fineFreqOff; % Total CFO
fprintf('Estimated CFO: %5.1f Hz\n\n',cfoCorrection);
% HE-LTF demodulation and channel estimation
rxHELTF = rx(pktOffset+(ind.HELTF(1):ind.HELTF(2)),:);
heltfDemod = wlanHEDemodulate(rxHELTF,'HE-LTF',cfgHE);
[chanEst,pilotEst] = heLTFChannelEstimate(heltfDemod,cfgHE);
% Data demodulate
rxData = rx(pktOffset+(ind.HEData(1):ind.HEData(2)),:);
demodSym = wlanHEDemodulate(rxData,'HE-Data',cfgHE);
% Pilot phase tracking
demodSym = heCommonPhaseErrorTracking(demodSym,chanEst,cfgHE);
% Estimate noise power in HE fields
nVarEst = heNoiseEstimate(demodSym(ofdmInfo.PilotIndices,:,:),pilotEst,cfgHE);
% Extract data subcarriers from demodulated symbols and channel
% estimate
demodDataSym = demodSym(ofdmInfo.DataIndices,:,:);
chanEstData = chanEst(ofdmInfo.DataIndices,:,:);
% Equalization and STBC combining
[eqDataSym,csi] = heEqualizeCombine(demodDataSym,chanEstData,nVarEst,cfgHE);
% eqDataOut = eqDataSym(1:end);
% Recover data
rxPSDUbits = wlanHEDataBitRecover(eqDataSym,nVarEst,csi,cfgHE,'LDPCDecodingMethod','layered-bp');
% [rxPSDU(:,frameIdx),~] = RX_CRC32(double(rxPSDUbits));
rxPSDU(:,frameIdx) = rxPSDUbits;
EVM = comm.EVM;
EVM.ReferenceSignalSource = 'Estimated from reference constellation';
EVM.Normalization = 'Average constellation power';
release(EVM);
EVM.ReferenceConstellation = wlanReferenceSymbols(cfgHE);
Evm = EVM(eqDataSym(:));
fprintf(' HE-Data EVM:%2.2fdB\n\n',20*log10(Evm));
rx = rx(pktOffset+ind.HEData(2):end,:);
frameIdx = frameIdx+1;
[rxPSDU,bitErrorRate,eqSymPlot] = heSURx(rx,cfgHE,userIdx,frameIdx,rxPSDU,cfgUI,SEED,bitErrorRate,eqSymPlot);
else
[~,numPkt] = size(rxPSDU);
psduLength = length(rxPSDU(:,1))/8;
switch cfgUI.DataType
case 'test'
txPSDU = DataGenerate(cfgUI,numPkt,SEED,psduLength,txPSDUByte);
txPSDU = txPSDU{1};
bitError = sum(txPSDU(1:end - 32,:)~=rxPSDU);
bitErrorRate = bitError/length(rxPSDU);
ACK = (bitErrorRate == 0);
case 'text'
case 'photo'
[~,numPkt] = size(rxPSDU);
bitstream = reshape(rxPSDU,1,[]); %
imgLen = bin2dec(num2str(bitstream(1:16)));
bit_array = reshape(bitstream,8,[])';
byte_array = num2str(bit_array);
img = bin2dec(byte_array); %
if imgLen+3 > length(img)
imgLen = length(img)-3;
end
rxPSDU = int16(img(1:imgLen+3)); % doubleint16
% rxCRC = 0;
% for i = 1:imgLen+2
% rxCRC = mod(rxCRC+rxPSDU(i),256);
% end
rxCRC = mod(sum(rxPSDU(1:length(rxPSDU)-1)),256);
if rxCRC == rxPSDU(end)
disp('Pass RX Sum Check!');
bitErrorRate = zeros(1,numPkt);
else
disp('Fail RX Sum Check!');
bitErrorRate = ones(1,numPkt);
end
ACK = (rxCRC == rxPSDU(end));
end
save(['TXPackets\ACKfeedback_for_User' num2str(userIdx) '.mat'],'ACK');
end
end