126 lines
4.8 KiB
Matlab
126 lines
4.8 KiB
Matlab
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)); % double转int16
|
|
% 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
|