This commit is contained in:
NightPoem 2024-03-30 16:35:40 +08:00
commit 02f55955d5
129 changed files with 8032 additions and 0 deletions

72
Band_Mono_Parameter.m Normal file
View File

@ -0,0 +1,72 @@
%%****************************************************%%
%%================================================================%%
% J
% Power_mono
% f_mono
% Power_band
% f_wide
% f_start
% f_end
% Num_band
% data
% fs
%%========================================================================%%
function [f_mono,Power_mono,Num_band,f_start,f_end,f_wide,Power_band] = Band_Mono_Parameter(data,J,fs,NFFT)
J = sort(J,'ascend')-1;
len_J = length(J);
f_start = [];
f_end = [];
c1=1;
mono_d = cell(0,0);
mono_s = cell(0,0);
mono = [];
f_d = [];
f_s = [];
power_m = [];
power_d = [];
power_s = [];
band = cell(0,0);
while c1 < len_J
c2 = 0;
while (c1 + c2 + 1 <= len_J && J(c1) + c2 + 1==J(c1 + c2 + 1))
c2 = c2 + 1;
end
if(c2 > 2)
band = [band;(J(c1:1:c1+c2))]; %%3
end
if c2 == 2
mono_d = [mono_d;(J(c1:1:c1+c2))]; %%
end
if c2 == 1
mono_s = [mono_s;(J(c1:1:c1+c2))];
end
if c2 == 0
mono = [mono,J(c1)];
end
c1 = c1 + c2 +1;
if c1 == len_J && J(len_J-1) + 1 ~= J(len_J)
mono = [mono,J(len_J)];
end
end
for k = 1:numel(mono_d)
f_d(k) = mono_d{k}(2)*fs/NFFT/10^6;
power_d(k) = sum(abs(data(mono_d{k}+1)).^2)/NFFT^2;
end
for m = 1:numel(mono_s)
f_s(m) = 0.5*(mono_s{m}(1)+mono_s{m}(2))*fs/NFFT/10^6;
power_s(m) = sum(abs(data(mono_s{m}+1)).^2)/NFFT^2;
end
power_m = abs(data(mono+1)).^2/NFFT^2;
mono = mono*fs/NFFT/10^6;
power_mono1 = [power_m,power_d,power_s];
f_mono1 = [mono,f_d,f_s];
[f_mono,index] = sort(f_mono1,'ascend');
Power_mono = power_mono1(index);
for k = 1 : numel(band)
f_start(k) = band{k}(1)*fs/NFFT/10^6;
f_end(k) = band{k}(end)*fs/NFFT/10^6;
end
f_wide = sum(abs(f_start - f_end));
Power_band = 2*sum(abs(data(J+1)).^2)/NFFT^2;
Num_band = length(f_end);
end

74
Band_Multi_Parameter.m Normal file
View File

@ -0,0 +1,74 @@
%%****************************************************%%
%%================================================================%%
% J
% Power_multi
% f_multi
% Num_multi
% Power_band
% f_wide
% f_start
% f_end
% Num_band
% data
% fs
%%========================================================================%%
function [Num_multi,f_multi,Power_multi,Num_band,f_start,f_end,f_wide,Power_band] = Band_Multi_Parameter(data,J,fs,NFFT)
J = sort(J,'ascend')-1;
len_J = length(J);
f_start = [];
f_end = [];
c1=1;
mono_d = cell(0,0);
mono_s = cell(0,0);
mono = [];
f_d = [];
f_s = [];
power_m = [];
power_d = [];
power_s = [];
band = cell(0,0);
while c1 < len_J
c2 = 0;
while (c1 + c2 + 1 <= len_J && J(c1) + c2 + 1==J(c1 + c2 + 1))
c2 = c2 + 1;
end
if(c2 > 2)
band = [band;(J(c1:1:c1+c2))]; %%3
end
if c2 == 2
mono_d = [mono_d;(J(c1:1:c1+c2))]; %%
end
if c2 == 1
mono_s = [mono_s;(J(c1:1:c1+c2))];
end
if c2 == 0
mono = [mono,J(c1)];
end
c1 = c1 + c2 +1;
if c1 == len_J && J(len_J-1) + 1 ~= J(len_J)
mono = [mono,J(len_J)];
end
end
for k = 1:numel(mono_d)
f_d(k) = mono_d{k}(2)*fs/NFFT/10^6;
power_d(k) = sum(abs(data(mono_d{k}+1)).^2)/NFFT^2;
end
for m = 1:numel(mono_s)
f_s(m) = 0.5*(mono_s{m}(1)+mono_s{m}(2))*fs/NFFT/10^6;
power_s(m) = sum(abs(data(mono_s{m}+1)).^2)/NFFT^2;
end
power_m = abs(data(mono+1)).^2/NFFT^2;
mono = mono*fs/NFFT/10^6;
power_multi1 = [power_m,power_d,power_s];
f_multi1 = [mono,f_d,f_s];
[f_multi,index] = sort(f_multi1,'ascend');
Power_multi =power_multi1(index);
Num_multi = length(f_multi1);
for k = 1 : numel(band)
f_start(k) = band{k}(1)*fs/NFFT/10^6;
f_end(k) = band{k}(end)*fs/NFFT/10^6;
end
f_wide =sum( abs(f_start - f_end));
Power_band = 2*sum(abs(data(J+1)).^2)/NFFT^2;
Num_band = length(f_end);
end

37
Band_Parameter.m Normal file
View File

@ -0,0 +1,37 @@
%%****************************************************%%
%%================================================================%%
% J
% data
% fs
% NFFT FFT
% Power_band
% f_wide
% f_start
% f_end
% Num_band
%%========================================================================%%
function [Num_band,f_start,f_end,f_wide,Power_band] = Band_Parameter(data,J,fs,NFFT)
J = sort(J,'ascend')-1;
len_J = length(J);
f_start = [];
f_end = [];
c1=1;
band = cell(0,0);
while c1 < len_J
c2 = 0;
while (c1 + c2 + 1 <= len_J && J(c1) + c2 + 1==J(c1 + c2 + 1))
c2 = c2 + 1;
end
if(c2 > 2)
band = [band;(J(c1:1:c1+c2))]; %%3
end
c1 = c1 + c2 +1;
end
for k = 1 : numel(band)
f_start(k) = band{k}(1)*fs/NFFT/10^6;
f_end(k) = band{k}(end)*fs/NFFT/10^6;
Power_band(k) = 2*sum(abs(data(band{k}(1:end)+1)).^2)/NFFT^2;
end
f_wide = sum(abs(f_end - f_start));
Num_band = length(f_end);
end

84
Corrcoef_Calculate.m Normal file
View File

@ -0,0 +1,84 @@
function RU_avai = Corrcoef_Calculate(staFeedback,Type, jam_data)
numUsers = length(staFeedback);
[Nst,numRx,numSTS] = size(staFeedback{1});
% combine_matrix = zeros(Nst,numRx*numUsers,numSTS);
%
combine_matrix = cell(1,numRx);
Nru = 4;
RU_avai = zeros(1,Nru);
for rxIdx = 1:numRx
combine_matrix{rxIdx} = zeros(Nst,numUsers,numSTS);
for userIdx = 1:numUsers
combine_matrix{rxIdx}(:,userIdx,:) = staFeedback{userIdx}(:,rxIdx,:);
end
ru1 = combine_matrix{rxIdx}(1:52,:,:);
ru2 = combine_matrix{rxIdx}(54:105,:,:);
ru3 = combine_matrix{rxIdx}(138:190,:,:);
ru4 = combine_matrix{rxIdx}(191:end,:,:);
RU_matrix = {ru1,ru2,ru3,ru4};
for ruIdx = 1:Nru
fprintf('%dRU\n',ruIdx);
% 线
Coefs = cell(1,numSTS);
num_corr = zeros(1,numSTS);
disp('');
for stsIdx = 1:numSTS
Coef = corrcoef(abs(RU_matrix{ruIdx}(:,:,stsIdx)));
Coef(logical(eye(size(Coef)))) = -1;
Coefs{stsIdx} = Coef;
disp(Coef);
num_corr(stsIdx) = sum(Coef>0.5,'all');
end
disp('0.5线');
disp(num_corr);
if sum(num_corr) == 0
RU_avai(ruIdx) = RU_avai(ruIdx)+1;
end
end
end
% figure();
% for rxIdx = 1:numRx
% for stsIdx = 1:numSTS
% for userIdx = 1:numUsers
% plot(abs(combine_matrix{rxIdx}(:,userIdx,stsIdx)));
% hold on;
% end
% end
% end
% hold off;
% pause(0.5);
% close;
% RU
if strcmp(Type,'multi')
for Idx = 1:length(jam_data)
f_idx = jam_data{1}(Idx)/10*Nst;
if 1 < f_idx < 52
RU_avai(1) = RU_avai(1)-0.5;
elseif 54 < f_idx < 105
RU_avai(2) = RU_avai(2)-0.5;
elseif 138 < f_idx < 190
RU_avai(3) = RU_avai(3)-0.5;
elseif 191 < f_idx < Nst
RU_avai(4) = RU_avai(4)-0.5;
end
end
elseif strcmp(Type,'mono')
f_idx = jam_data/10*Nst;
if 1 < f_idx < 52
RU_avai(1) = RU_avai(1)-0.5;
elseif 54 < f_idx < 105
RU_avai(2) = RU_avai(2)-0.5;
elseif 138 < f_idx < 190
RU_avai(3) = RU_avai(3)-0.5;
elseif 191 < f_idx < Nst
RU_avai(4) = RU_avai(4)-0.5;
end
end
fprintf('4RURU');
disp(RU_avai);
end

99
DataDecoding.m Normal file
View File

@ -0,0 +1,99 @@
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

81
DataGenerate.m Normal file
View File

@ -0,0 +1,81 @@
function txPSDU = DataGenerate(cfgUI,numPkt,SEED,arg,txPSDUByteUser)
%*********************************lql03.21*********************************
numUsers = cfgUI.numUsers;
DataType = cfgUI.DataType;
if isnumeric(arg)
if cfgUI.numUsers == 1
cfgHE = wlanHESUConfig;
else
cfgHE = wlanHEMUConfig(193);
end
psduLength = ones(1,numUsers)*arg;
else
if isfield(arg,'InterleavLen')
psduLength = arg.PacketSize;
else
cfgHE = arg;
psduLength = getPSDULength(cfgHE); % PSDU length in bytes
end
end
% psduLength = getPSDULength(cfgHE); % PSDU length in bytes
%*********************************lql03.21*********************************
if numUsers==1
txPSDU = cell(1,1);
else
allocInfo = ruInfo(cfgHE);
txPSDU = cell(1,allocInfo.NumUsers);
end
% [len,width] = size(txPSDUByteUser(:,:,1));
if strcmp(cfgUI.DataType,'photo')
txPSDUBin = ones(length(txPSDUByteUser(:,1))*8,numUsers);
for userIdx = 1:numUsers
txPSDUBin(:,userIdx) = reshape(int2bit(txPSDUByteUser(:,userIdx),8),1,[]);
end
end
for i = 1:numPkt
if numUsers==1
rng(i+SEED);
switch DataType
case 'test'
txPSDU{1}(:,i) = randi([0 1],psduLength*8,1);
case 'text'
case 'photo'
% ii zjd3.26
if i*psduLength*8 <= length(txPSDUBin)
txPSDU{1}(:,i) = txPSDUBin((i-1)*psduLength*8+1:i*psduLength*8,:);
elseif i*psduLength*8 > length(txPSDUBin) && (i-1)*psduLength*8 < length(txPSDUBin)
padLength = psduLength*8-(length(txPSDUBin)-(i-1)*psduLength*8);
txPSDU{1}(:,i) = [txPSDUBin((i-1)*psduLength*8+1:length(txPSDUBin),:);randi([0 1],padLength,1)];
else
txPSDU{1}(:,i) = randi([0 1],psduLength*8,1);
end
end
else
switch DataType
case 'test'
for ii = 1:allocInfo.NumUsers
rng(i+ii+SEED);
txPSDU{ii}(:,i) = randi([0 1],psduLength(ii)*8,1); % Generate random PSDU
end
case 'text'
case 'photo'
for ii = 1:allocInfo.NumUsers
% ii zjd3.26
if i*psduLength(ii)*8 <= length(txPSDUBin)
txPSDU{ii}(:,i) = txPSDUBin((i-1)*psduLength(ii)*8+1:i*psduLength(ii)*8,ii);
elseif (i*psduLength(ii)*8 > length(txPSDUBin)) && ((i-1)*psduLength(ii)*8 < length(txPSDUBin))
padLength = psduLength(ii)*8-(length(txPSDUBin)-(i-1)*psduLength(ii)*8); %
txPSDU{ii}(:,i) = [txPSDUBin((i-1)*psduLength(ii)*8+1:length(txPSDUBin),ii);randi([0 1],padLength,1)];
else
txPSDU{ii}(:,i) = randi([0 1],psduLength(ii)*8,1);
end
end
end
end
end
end

45
FCME.m Normal file
View File

@ -0,0 +1,45 @@
%%************************FCME****************************%%
%%================================================================%%
% data
% Pf
% J
%%========================================================================%%
function J = FCME(data,Pf)
T = sqrt(-1*(4/pi)*log(Pf)); %%
J = [];
L = length(data);
fi = [];
[y_sort,index] = sort(abs(data),'ascend'); %%
%%
for k = 1:L
fi(k)=abs(data(k));
end
%%%%
J = index(round(L/10)+1:end); %%
I = index(1:round(L/10)); %%\
S = mean(fi(I));
%%
for m = 1:50 %%FCME
length_J = length(J); %%J
ii = 1;
jj = 1;
new_I = [];
new_J = [];
for j1 = 1:length_J
J1 = J(j1); %%J
if fi(J1) < T*S %%IJ
new_I(ii) = J1;
ii = ii +1;
else %%J
new_J(jj) = J1;
jj = jj + 1;
end
end
if isempty(new_I) %%new_I
break;
end
J = new_J;
I = union(I,new_I);
S = mean(fi(I)); %%
end
end

25
FCME_pro.m Normal file
View File

@ -0,0 +1,25 @@
%%***********************FCME*************************%%
%%================================================================%%
% data
% Pf
% J
%%========================================================================%%
function J = FCME_pro(data_Freuq,Pf)
T = sqrt(-1*(4/pi)*log(Pf)); %%
th = 3.432; %%
L = length(data_Freuq);
fi = [];
[y_sort,index] = sort(abs(data_Freuq),'ascend');
%%
fi = abs(data_Freuq);
I = index(1:round(L/2)); %%
E = mean(fi(I));
Aaim = T*th*E; %%
J = [];
%%
for mm = 1:L
if fi(mm) > Aaim
J = [J,mm];
end
end
end

24
HESU_gen.m Normal file
View File

@ -0,0 +1,24 @@
function byte = HESU_gen(byteIn,psduLength,userIdx)
PSDULength = psduLength(userIdx);
%Create a sequence of data bits and generate an HE SU waveform.
byteInLen=size(byteIn,1);
bits = zeros(8*PSDULength,1,'double');
%bits = randi([0 1],8*PSDULength,1,'int8');
if(byteInLen > 1)
if(byteInLen <= PSDULength)
bits(1:8*byteInLen) = int8(int2bit(byteIn,8));
else
bits = int8(int2bit(byteIn(1:PSDULength),8));
end
end
byte = int16(bit2int(bits,8));
%sr = wlanSampleRate(cfgHESU); % Sample rate
% TxWaveform = wlanWaveformGenerator(bits,cfgHESU);
%TxWaveform = wlanWaveformGenerator(bits,cfgHESU);
% TxWaveform = 0.25.*TxWaveform;
%Rx = TxWaveform;
end

71
JudgeTypeJam.m Normal file
View File

@ -0,0 +1,71 @@
%%****************************************************%%
%%================================================================%%
% J:
%Type:
%%========================================================================%%
function Type = JudgeTypeJam(J)
J = sort(J,'ascend');
len_J = length(J);
c1 = 1;
band = cell(0,0);
mono_d = cell(0,0);
mono = [];
if len_J == 0
Type = 'No jam';
elseif len_J <= 3 %&& len_J > 0 %% 3
if len_J == 1
Type = 'mono';
else
if len_J == 2
if J(2)-J(1) == 1
Type = 'mono';
else
Type = 'multi';
end
else
if J(3) - J(1) == 2
Type = 'mono';
else
Type = 'multi';
end
end
end
else
while c1 < len_J
c2 = 0;
while (c1 + c2 + 1 <= len_J && J(c1) + c2 + 1== J(c1 + c2 + 1))
c2 = c2 + 1;
end
if(c2 > 2)
band = [band;(J(c1:1:c1+c2))]; %% 3
end
if (c2 == 2 || c2 == 1)
mono_d = [mono_d;(J(c1:1:c1+c2))]; %%
end
if c2 == 0
mono = [mono,J(c1)];
end
c1 = c1 + c2 +1;
if c1 == len_J && J(len_J-1) + 1 ~= J(len_J)
mono = [mono,J(len_J)];
end
end
num_band = numel(band);
num_mono_d = numel(mono_d);
num_mono = length(mono);
num_multi = num_mono + num_mono_d;
if num_band ~= 0
if num_multi == 0
Type = 'band';
else
if num_multi >1
Type = 'band_multi';
else
Type = 'band_mono';
end
end
else
Type = 'multi';
end
end
%% end

26
MCS_sel.m Normal file
View File

@ -0,0 +1,26 @@
function [MCS, mcs_no] = MCS_sel(ModulationMode,CodeRate)
switch ModulationMode
case 'BPSK'
MCS = 0;
mcs_no = [2,2];
case 'QPSK'
if(CodeRate==1/2)
MCS = 1;mcs_no = [4,2]; end
if CodeRate==3/4
MCS = 2;mcs_no = [4,4]; end
case '16QAM'
if CodeRate==1/2
MCS = 3;mcs_no = [16,2]; end
if CodeRate==2/3
MCS = 4;mcs_no = [16,3]; end
if CodeRate==3/4
MCS = 4;mcs_no = [16,4]; end
case '64QAM'
if CodeRate==2/3
MCS = 5;mcs_no = [64,3]; end
if CodeRate==3/4
MCS = 6;mcs_no = [64,4]; end
if CodeRate==5/6
MCS = 7;mcs_no = [64,6]; end
end
end

9
MU_NDP.m Normal file
View File

@ -0,0 +1,9 @@
function txNDP = MU_NDP(cfgMUMIMO,guardInterval,ChannelBandwidth)
% NDP
cfgNDP = wlanHESUConfig('APEPLength',0,'GuardInterval',guardInterval); % No data in an NDP
cfgNDP.ChannelBandwidth = ChannelBandwidth;
cfgNDP.NumTransmitAntennas = cfgMUMIMO.NumTransmitAntennas;
cfgNDP.NumSpaceTimeStreams = cfgMUMIMO.NumTransmitAntennas;
txNDP = wlanWaveformGenerator([],cfgNDP);
txNDP = [txNDP; zeros(50,size(txNDP,2))];
end

23
Mono_Parameter.m Normal file
View File

@ -0,0 +1,23 @@
%%****************************************************%%
%%================================================================%%
% J
% data
% fs
% NFFT FFT
% Power_mono
% f_mono
%%========================================================================%%
function [f_mono,Power_mono] = Mono_Parameter(data,J,fs,NFFT)
J = sort(J,'ascend')-1;
len_J = length(J);
if len_J == 1
f_mono = J*fs/NFFT/10^6;
else
if len_J == 2
f_mono = 0.5*(J(1)+J(2))*fs/NFFT/10^6;
else
f_mono = J(2)*fs/NFFT/10^6;
end
end
Power_mono =sum(abs(data(J+1)).^2)/NFFT^2;
end

57
Multi_Parameter.m Normal file
View File

@ -0,0 +1,57 @@
%%****************************************************%%
%%================================================================%%
% J
% data
% fs
% NFFT FFT
% Power_multi
% f_multi
% Num_multi
%%========================================================================%%
function [Num_multi,f_multi,Power_multi] = Multi_Parameter(data,J,fs,NFFT)
J = sort(J,'ascend')-1;
len_J = length(J);
mono_d = cell(0,0);
mono_s = cell(0,0);
mono = [];
f_d = [];
f_s = [];
power_m = [];
power_d = [];
power_s = [];
c1 = 1;
while c1 < len_J
c2 = 0;
while (c1 + c2 + 1 <= len_J && J(c1) + c2 + 1==J(c1 + c2 + 1))
c2 = c2 + 1;
end
if c2 == 2
mono_d = [mono_d;(J(c1:1:c1+c2))]; %%
end
if c2 == 1
mono_s = [mono_s;(J(c1:1:c1+c2))];
end
if c2 == 0
mono = [mono,J(c1)];
end
c1 = c1 + c2 +1;
if c1 == len_J && J(len_J-1) + 1 ~= J(len_J)
mono = [mono,J(len_J)];
end
end
for k = 1:numel(mono_d)
f_d(k) = mono_d{k}(2)*fs/NFFT/10^6;
power_d(k) = sum(abs(data(mono_d{k}+1)).^2)/NFFT^2;
end
for m = 1:numel(mono_s)
f_s(m) = 0.5*(mono_s{m}(1)+mono_s{m}(2))*fs/NFFT/10^6;
power_s(m) = sum(abs(data(mono_s{m}+1)).^2)/NFFT^2;
end
power_m = abs(data(mono+1)).^2/NFFT^2;
mono = mono*fs/NFFT/10^6;
power_multi1 = [power_m,power_d,power_s];
f_multi1 = [mono,f_d,f_s];
[f_multi,index] = sort(f_multi1,'ascend');
Power_multi = power_multi1(index);
Num_multi = length(f_multi1);
end

125
PSD_plot.m Normal file
View File

@ -0,0 +1,125 @@
%% PSD Comparison of ADMM1, ADMM2, CFR and seperated OICF
%%% SSPA
clc;clear;
%% System Parameter
% load system_parameter.mat K1 K2 deltaK2 B N1 N2 G L Finv1 Finv2 F1 F2
global X1 X2 x_mixed
% load Index4CCDF_Comparison.mat Index X1 X2 x_mixed
M = 4;
modu = [0 0 1 1; 0 1 0 1];
% load CCDF_Comparison_ADMM_P5_5000.mat zmixed_m_A1 zmixed_m_A2
% load CCDF_Comparison_OICF_P5_5000.mat zmixed_m_O
% load CCDF_Comparison_ICF_P5_5000.mat zmixed_m_R
% save PSD_comparison.mat...
% x_mixed zmixed_m_A1 zmixed_m_A2 zmixed_m_R zmixed_m_O
% load PSD_comparison.mat...
% x_mixed zmixed_m_A1 zmixed_m_A2 zmixed_m_R zmixed_m_O
load(['TXPackets\rx_for_User' num2str(1) '.mat'],'rx'); %
x_mixed = rx;
symNum = length(x_mixed);
%% PAPR100
[PAPR_dex,MeanPower_Orignal] = calculate_PAPR(x_mixed);
symNum = 1000;
for i = 1:symNum
[a(i),b(i)] = max(PAPR_dex);
PAPR_dex(b(i)) = 0;
end
% b = randi([1 5000],1,symNum);
x_mixed = x_mixed(:,b);[PAPR_dex,~] = calculate_PAPR(x_mixed);10*log10(mean(PAPR_dex));
% zmixed_m_A1=zmixed_m_A1(:,b);[PAPR_dex,~] = calculate_PAPR(zmixed_m_A1);10*log10(mean(PAPR_dex))
% zmixed_m_A2=zmixed_m_A2(:,b);[PAPR_dex,~] = calculate_PAPR(zmixed_m_A2);10*log10(mean(PAPR_dex))
% zmixed_m_R=zmixed_m_R(:,b); [PAPR_dex,~] = calculate_PAPR(zmixed_m_R);10*log10(mean(PAPR_dex))
% zmixed_m_O=zmixed_m_O(:,b); [PAPR_dex,~] = calculate_PAPR(zmixed_m_O);10*log10(mean(PAPR_dex))
%% SSPA Model
p = 3;IBO = 5;L=4;
% Original symbol with SSPA
x_origin_out = SSPA_model(p,IBO,x_mixed);
[~,MeanPower] = calculate_PAPR(x_origin_out);
x_origin_out = x_origin_out./sqrt(MeanPower*L);
% % ADMM1 symbol with SSPA
% x_A1_out = SSPA_model(p,IBO,zmixed_m_A1);
% [~,MeanPower] = calculate_PAPR(x_A1_out);
% x_A1_out = x_A1_out./sqrt(MeanPower*L);
% % ADMM2 symbol with SSPA
% x_A2_out = SSPA_model(p,IBO,zmixed_m_A2);
% [~,MeanPower] = calculate_PAPR(x_A2_out);
% x_A2_out = x_A2_out./sqrt(MeanPower*L);
% % CFR symbol with SSPA
% x_R_out = SSPA_model(p,IBO,zmixed_m_R);
% [~,MeanPower] = calculate_PAPR(x_R_out);
% x_R_out = x_R_out./sqrt(MeanPower*L);
% % OICF symbol with SSPA
% x_O_out = SSPA_model(p,IBO,zmixed_m_O);
% [~,MeanPower] = calculate_PAPR(x_O_out);
% x_O_out = x_O_out./sqrt(MeanPower*L);
%% PSD plot
mode = 1; % 1.periodogram 2. 2.pwelch
N = (512+36)*2;shift = -N/8;
[pxx,freq] = sprectrum(x_origin_out,mode,N);
pxx = circshift(pxx,shift);
plot(freq/pi,10*log10(pxx),'k','LineWidth',1);hold on;grid on
% [pxx,freq] = sprectrum(x_A1_out,mode,N);
% pxx = circshift(pxx,shift);
% plot(freq/pi,10*log10(pxx),'r','LineWidth',1);
%
% [pxx,freq] = sprectrum(x_A2_out,mode,N);
% pxx = circshift(pxx,shift);
% plot(freq/pi,10*log10(pxx),'b','LineWidth',1);
%
% [pxx,freq] = sprectrum(x_R_out,mode,N);
% pxx = circshift(pxx,shift);
% plot(freq/pi,10*log10(pxx),'.-r','LineWidth',1);
%
% [pxx,freq] = sprectrum(x_O_out,mode,N);
% pxx = circshift(pxx,shift);
% plot(freq/pi,10*log10(pxx),'g','LineWidth',1);
%
% xlim([-1 1]);ylim([-38 0.5])
% legend('Origin','ADMM1','ADMM2','CFR','OICF')
% xlabel('Normalized Frequency')
% ylabel('PSD (dB)')
%% APPENDIX FUNCTIONS
function [x_out] = SSPA_model(p,IBO,x)
[~,Mean_Power] = calculate_PAPR(x);
% PAPR_out_O = 10*log10(PAPR_dex);
C = sqrt(Mean_Power)*10^(IBO/20);
x_out = x./ (1+(abs(x)./C).^(2*p)).^(1/(2*p));
end
function [pxx,freq] = sprectrum(x,mode,N)
switch mode
case 1
[pxx,freq] = periodogram(x *sqrt(2*pi),[],N,'centered');
case 2
[pxx,freq] = periodogram(x *sqrt(2*pi),hamming(length(x(:,1))),N,'centered');
case 3
[pxx,freq] = pwelch(x *sqrt(2*pi),[],[],N,'centered');
end
pxx = mean(pxx,2);
end
function [PAPR_dex,Mean_Power] = calculate_PAPR(x)
% PAPR_dex PAPR
% Mean_Power
Signal_Power = abs(x).^2;
Peak_Power = max(Signal_Power,[],1); % norm(x,Inf)^2
Mean_Power = mean(Signal_Power,1); % norm(x,2)^2/(K*IF)
PAPR_dex = Peak_Power./Mean_Power;
end
function [EVM1,EVM2,EVM3,EVM_sum] = calculate_EVM(s1,s2,s3,symNum)
% EVM
global X1 X2_1 X2_2
EVM1=zeros(1,symNum);EVM2=zeros(1,symNum);EVM3=zeros(1,symNum);EVM_sum=zeros(1,symNum);
for i = 1:symNum
EVM1(i) = norm(X1(:,i)-s1(:,i),2)/norm(X1(:,i),2);
EVM2(i) = norm(X2_1(:,i)-s2(:,i),2)/norm(X2_1(:,i),2);
EVM3(i) = norm(X2_2(:,i)-s3(:,i),2)/norm(X2_2(:,i),2);
EVM_sum(i) = EVM1(i) + EVM2(i) + EVM3(i);
end
end

121
PassChannel.m Normal file
View File

@ -0,0 +1,121 @@
load('TXPackets\transmit_data.mat','tx_data','cfgUI');
snr = 30;
if cfgUI.numUsers == 1
CommMode = 'HE-SU';
else
CommMode = 'HE-MU';
end
%*****************************************
% number of (real + virtual) users
RU_index = RU_alloc(cfgUI);
allocInfo = wlan.internal.heAllocationInfo(RU_index);
cfgUI.numUsers = allocInfo.NumUsers;
%*****************************************
rx_data = chanPass(tx_data,cfgUI,snr,CommMode);
for i =1:cfgUI.numUsers
matName = ['rx_for_User',num2str(i),'.mat'];
if cfgUI.numUsers == 1
rx = rx_data;
save(['TXPackets\',matName],'rx');
else
rx = rx_data{i};
save(['TXPackets\',matName],'rx');
end
end
%%
function rx = chanPass(txPad,cfgUI,snr,CommMode)
numTx = cfgUI.numTx;
numRx = cfgUI.numRx;
guardInterval = 0.8;% Guard interval in Microseconds
cfgNDP = wlanHESUConfig('APEPLength',0,'GuardInterval',guardInterval); % No data in an NDP
cfgNDP.ChannelBandwidth = cfgUI.ChannelBandwidth;
cfgNDP.NumTransmitAntennas = numTx;
cfgNDP.NumSpaceTimeStreams = numRx;
if strcmp(CommMode,'HE-SU')
% Create and configure the TGax channel
chanBW = cfgNDP.ChannelBandwidth;
tgaxChannel = wlanTGaxChannel;
tgaxChannel.DelayProfile = 'Model-B';
tgaxChannel.NumTransmitAntennas = cfgNDP.NumTransmitAntennas;
tgaxChannel.NumReceiveAntennas = numRx;
tgaxChannel.TransmitReceiveDistance = 5; % Distance in meters for NLOS
tgaxChannel.ChannelBandwidth = chanBW;
tgaxChannel.LargeScaleFadingEffect = 'None';
fs = wlanSampleRate(cfgNDP);
tgaxChannel.SampleRate = fs;
tgaxChannel.RandomStream = 'mt19937ar with seed';
tgaxChannel.Seed = 5;
% Get occupied subcarrier indices and OFDM parameters
ofdmInfo = wlanHEOFDMInfo('HE-Data',cfgNDP);
stream = RandStream('combRecursive','Seed',99);
% stream.Substream = snr;
RandStream.setGlobalStream(stream);
% Create an instance of the AWGN channel per SNR point simulated
awgnChannel = comm.AWGNChannel;
awgnChannel.NoiseMethod = 'Signal to noise ratio (SNR)';
awgnChannel.SignalPower = 1/tgaxChannel.NumReceiveAntennas;
% Account for noise energy in nulls so the SNR is defined per
% active subcarrier
awgnChannel.SNR = snr-10*log10(ofdmInfo.FFTLength/ofdmInfo.NumTones);
% Pass through a fading indoor TGax channel
% reset(tgaxChannel); % Reset channel for different realization
rx = tgaxChannel(txPad);
% Pass the waveform through AWGN channel
rx = awgnChannel(rx);
elseif strcmp(CommMode,'HE-MU')
tgaxBase = wlanTGaxChannel;
tgaxBase.DelayProfile = 'Model-D'; % Delay profile
tgaxBase.NumTransmitAntennas = cfgNDP.NumTransmitAntennas; % Number of transmit antennas
tgaxBase.NumReceiveAntennas = numRx; % Each user has two receive antennas
tgaxBase.TransmitReceiveDistance = 10; % Non-line of sight distance
tgaxBase.ChannelBandwidth = cfgNDP.ChannelBandwidth;
tgaxBase.SampleRate = wlanSampleRate(cfgNDP);
% Set a fixed seed for the channel
tgaxBase.RandomStream = 'mt19937ar with seed';
% Generate per-user channels
numUsers = cfgUI.numUsers; % Number of users simulated in this example
tgax = cell(1,numUsers);
for userIdx = 1:numUsers
% tgaxBase.Seed = randi(100);
tgaxBase.Seed = userIdx;
tgax{userIdx} = clone(tgaxBase);
tgax{userIdx}.UserIndex = userIdx; % Set unique user index
end
awgnChannel = comm.AWGNChannel;
awgnChannel.NoiseMethod = 'Signal to noise ratio (SNR)';
awgnChannel.SignalPower = 1/numRx;
% Account for noise energy in nulls so the SNR is defined per
% active subcarrier
awgnChannel.SNR = snr;
rxUsers = cell(1,numUsers);
% allocInfo = ruInfo(cfgNDP);
% 使
for userIdx = 1:numUsers
tgaxClone = cloneChannels(tgax);
rxUsers{userIdx} = tgaxClone{userIdx}(txPad);
rxUsers{userIdx} = awgnChannel(rxUsers{userIdx});
end
rx = rxUsers;
end
end
function tgaxClone = cloneChannels(tgax)
% Clone the channels before running to ensure the same realization can be
% used in the next simulation
tgaxClone = cell(size(tgax));
numUsers = numel(tgax);
for i=1:numUsers
tgaxClone{i} = clone(tgax{i});
end
end

BIN
RU_Alloc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

59
RU_alloc.m Normal file
View File

@ -0,0 +1,59 @@
function RU_index = RU_alloc(cfgUI)
if cfgUI.numUsers == 1
f_occupy = strcat(num2str((cfgUI.user1.f)'));
switch f_occupy.'
case '1111'
RU_index = 192;%
case '1100'
RU_index = 96;% 106
case '0011'
RU_index = 96;% 242
case '1000'
RU_index = 112;% 52
case '0100'
RU_index = 112;% 52
case '0010'
RU_index = 112;% 52
case '0001'
RU_index = 112;% 52
otherwise
RU_index = 192;
end
RU_index = 192; %
elseif cfgUI.numUsers == 2
f_occupy = strcat(num2str((cfgUI.user1.f + cfgUI.user2.f)'));
switch f_occupy.'
case '2222'
RU_index = 193;% 242
case '1111'
RU_index = 96;% 106
case '2200'
RU_index = 100;% 242
case '0022'
RU_index = 97;% 52
case '1110'
RU_index = 24;% 52
case '1101'
RU_index = 24;% 52
case '0011'
RU_index = 24;% 52
case '1011'
RU_index = 16;% 52
case '0111'
RU_index = 16;% 52
case '1100'
RU_index = 16;% 3106
case '1001'
RU_index = 112;% 52
case '1010'
RU_index = 112;% 52
case '0101'
RU_index = 112;% 52
case '0110'
RU_index = 112;% 3106
otherwise
RU_index = 193;
end
RU_index = 193; %
end
end

45
RU_for_cfgUI.m Normal file
View File

@ -0,0 +1,45 @@
function cfgUI = RU_for_cfgUI(RU_avai,cfgUI)
mode = strrep(num2str(RU_avai),' ','');
if cfgUI.numUsers == 1
switch mode
case {'1111','1100','0011','1000','0100','0010','0001'}
cfgUI.user1.f = RU_avai;
case {'0111','1011'}
cfgUI.user1.f = [0,0,1,1];
case {'1101','1110'}
cfgUI.user1.f = [1,1,0,0];
case {'1001','1010'}
cfgUI.user1.f = [1,0,0,0];
case {'0110','0101'}
cfgUI.user1.f = [0,1,0,0];
end
elseif cfgUI.numUsers == 2
switch mode
case '1111'
cfgUI.user1.f = [1,1,1,1];
cfgUI.user2.f = [1,1,1,1];
case {'0111','1011','0011'}
cfgUI.user1.f = [0,0,1,1];
cfgUI.user2.f = [0,0,1,1];
case {'1101','1110','1100'}
cfgUI.user1.f = [1,1,0,0];
cfgUI.user2.f = [1,1,0,0];
case {'0001','0010','0100','1000'}
cfgUI.user1.f = RU_avai;
cfgUI.user2.f = RU_avai;
case '0101'
cfgUI.user1.f = [0,1,0,0];
cfgUI.user2.f = [0,0,0,1];
case '0110'
cfgUI.user1.f = [0,1,0,0];
cfgUI.user2.f = [0,0,1,0];
case '1001'
cfgUI.user1.f = [1,0,0,0];
cfgUI.user2.f = [0,0,0,1];
case '1010'
cfgUI.user1.f = [1,0,0,0];
cfgUI.user2.f = [0,0,1,0];
end
end
end

27
RX.m Normal file
View File

@ -0,0 +1,27 @@
clear;
close all;
clc;
%% LabVIEW1--
cfgUI.DataType = 'photo'; % 'test''text''photo'
cfgUI.FeedbackMode = 'feedback'; % 'openloop','feedback'
cfgUI.numTx = 2;
cfgUI.numRx = 1;
cfgUI.ChannelBandwidth = 'CBW20';
cfgUI.JamDetect = 'FCME_pro';%'AI'
cfgUI.syncSel = 'default';%'AI'
cfgUI.Estchan = 'default';%'AI-1''AI-2''AI-3'
cfgUI.decode = 'default';%'AI'
cfgUI.demod = 'default';%'AI'
cfgUI.semantic = 0; % 1
userIdx = 1; % 1 or 2
cfgUI.numUsers = 2; %
SEED = 1; % BER
load(['TXPackets\rx_for_User' num2str(userIdx) '.mat'],'rx'); %
[rxPSDU,bitErrorRate,pktFormat,pktOffset,eqSymPlot,Jam_pos,feedback_data,evm,errorMessage] = RX_function(rx,userIdx,cfgUI,SEED);

9
RX_CRC32.m Normal file
View File

@ -0,0 +1,9 @@
function [rx,frmError] = RX_CRC32(dataPacketBits)
poly = [32,26,23,22,16,12,11,10,8,7,5,4,2,1,0];
crcdetector = comm.CRCDetector(...
'Polynomial', poly, ...
'InitialConditions', 1, ...
'DirectMethod', true, ...
'FinalXOR', 1);
[rx,frmError] = crcdetector(dataPacketBits);
end

61
RX_NDPCal.m Normal file
View File

@ -0,0 +1,61 @@
function [staFeedback,PDP,rmsDelay,DopplerShift,rssi_dbm,SNR] = RX_NDPCal(rx,cfgHE,ind,pktOffset,gain)
addpath(genpath('.\sounding'));
% ****NDP
% rxNDP = txNDP(:,1:2);
%
numTx = cfgHE.numTx;
cfgNDP = wlanHESUConfig('APEPLength',0,'GuardInterval',0.8); % No data in an NDP
cfgNDP.NumTransmitAntennas = numTx;%??
cfgNDP.NumSpaceTimeStreams = numTx;%??
txNDP = wlanWaveformGenerator([],cfgNDP);
len_NDP = length(txNDP);
% PN
K = 255;
soundingSeqMod_1 = zadoffChuSeq(29,K);
soundingSeqMod_2 = zadoffChuSeq(47,K);
% Concatenate multiple sequences to sound the channel periodically.
numSeq = 10; % Number of transmitted sequences in a WSS period
soundingSeqMod = [soundingSeqMod_1, soundingSeqMod_2];
txSignal = repmat(soundingSeqMod,numSeq,1);
len_sd = length(txSignal);
% for userIdx = 1:numUsers
% NDP
% Get the full-band beamforming feedback for a user
staFeedback = heUserBeamformingFeedback(rx,cfgNDP);
sounding_seq = rx(len_NDP+1:len_NDP+len_sd);
[PDP,rmsDelay,DopplerShift] = rxChannelSounding(sounding_seq,cfgHE,numSeq,K);
% end
% RSSI
rxLSTF = rx(pktOffset+(ind.LSTF(1):ind.LSTF(2)),:)./(gain);
rssi_legancy = mean(abs(rxLSTF).^2);
rssi_legancy_dbm = 10*log10(rssi_legancy/1e-3);
rxHETF = rx(pktOffset+(ind.HESTF(1):ind.HELTF(2)),:)./(gain);
rssi = mean(abs(rxHETF).^2);
rssi_dbm = 10*log10(rssi/1e-3);
fprintf(' rssi_legancy: %f dBm\n rssi: %f dBm\n', rssi_legancy_dbm, rssi_dbm);
% SNR
LLTF = rx(ind.LLTF(1):ind.LLTF(2));
LLTF_length = length(LLTF);
LLTF1 = LLTF(1+LLTF_length/5:LLTF_length*3/5);
LLTF2 = LLTF(1+LLTF_length*3/5:end);
N = 64;
LLTF1_fft = ((abs(fftshift(fft(LLTF1)))).^2)/N;
LLTF2_fft = ((abs(fftshift(fft(LLTF2)))).^2)/N;
for i = 0:LLTF_length/160-1
power_signal = sum(LLTF1_fft(i*N+(7:32))) + sum(LLTF1_fft(i*N+(34:59))) + ...
sum(LLTF2_fft(i*N+(7:32))) + sum(LLTF2_fft(i*N+(34:59)));
power_noise = sum(LLTF1_fft(i*N+(1:6))) + sum(LLTF1_fft(i*N+(33))) + sum(LLTF1_fft(i*N+(end-4:end))) + ...
sum(LLTF2_fft(i*N+(1:6))) + sum(LLTF2_fft(i*N+(33))) + sum(LLTF2_fft(i*N+(end-4:end)));
end
SNR = 10*log10(power_signal/(power_noise*64/12));
fprintf(' SNR: %f dB\n', SNR);
rmpath(genpath('.\sounding'));
end

95
RX_function.m Normal file
View File

@ -0,0 +1,95 @@
function [rxPSDU,bitErrorRate,pktFormat,pktOffset,eqSymPlot,Jam_pos,feedback_data,evm,errorMessage] = RX_function(rx,userIdx,cfgUI,SEED)
cfgRx = wlanHERecoveryConfig;
cfgRx.ChannelBandwidth = cfgUI.ChannelBandwidth;
ind = wlanFieldIndices(cfgRx);
% --3.26
rxPSDU = [];
feedback_data = struct();
feedback_data.staFeedback = [];
feedback_data.PDP = [];
feedback_data.rmsDelay = 0;
feedback_data.DopplerShift = 0;
feedback_data.rssi = 0;
feedback_data.SNR = 0;
feedback_data.JamType = '';
feedback_data.JamData = [];
frameIdx = 1;
bitErrorRate = [];
eqSymPlot = [];
Jam_pos = [];
pktFormat = '';
pktOffset = 0;
evm = 0;
try
[Type,jam_data,Jam_pos] = SpectrumSense(rx,cfgUI); %
rxWaveLen = size(rx,1);
pktOffset = wlanPacketDetect(rx,cfgRx.ChannelBandwidth);%
% Adjust packet offset
if isempty(pktOffset) || (pktOffset + ind.LSIG(2) > rxWaveLen)
feedback_stat = 0;
else
feedback_stat = 1;
end
if feedback_stat==1
%
[rx,pktOffset,gain] = rxFrontEnd(rx,pktOffset,ind,cfgRx);
%
[cfgRx,~,ind] = pktFormatDetect(ind,pktOffset,rx,cfgRx);
%-------0324-----nonHTHE-----------
if ~isfield(ind,'HEData')
pktFormat = 'non-HT';
fprintf('%s packet detected\n\n',pktFormat);
[rxPSDU,bitErrorRate,eqSymPlot]=heSUspecial(rx,cfgRx,userIdx,frameIdx,rxPSDU,cfgUI,SEED,bitErrorRate,eqSymPlot);
else
pktFormat = cfgRx.PacketFormat;
fprintf('%s packet detected\n\n',pktFormat);
%
if strcmp(pktFormat,'HE-SU')
flag = isDataEmpty(rx,cfgUI); % 00NDP
if flag == 1 % 0NDP
% *******NDP*******
pktFormat = 'NDP';
%--------------------------------
[staFeedback,PDP,rmsDelay,DopplerShift,rssi_dbm,SNR] = RX_NDPCal(rx,cfgUI,ind,pktOffset,gain);
% feedback_data = struct();
feedback_data.staFeedback = staFeedback;
feedback_data.PDP = PDP;
feedback_data.rmsDelay = rmsDelay;
feedback_data.DopplerShift = DopplerShift;
feedback_data.rssi = rssi_dbm;
feedback_data.SNR = SNR;
feedback_data.JamType = Type;
feedback_data.JamData = jam_data;
save(['TXPackets\NDPfeedback_for_User' num2str(userIdx) '.mat'],'feedback_data');
elseif flag == 0 % SU
[rxPSDU,bitErrorRate,eqSymPlot] = heSURx(rx,cfgRx,userIdx,frameIdx,rxPSDU,cfgUI,SEED,bitErrorRate,eqSymPlot);
end
elseif strcmp(pktFormat,'HE-MU')
[rxPSDU,bitErrorRate,eqSymPlot,evm]=heMURx(rx,cfgRx,userIdx,frameIdx,rxPSDU,cfgUI,SEED,bitErrorRate,eqSymPlot);
end
end
end
rxPSDU = int16(rxPSDU);
bitErrorRate = double(bitErrorRate);
pktOffset = double(pktOffset);
eqSymPlot = double(eqSymPlot);
Jam_pos = double(Jam_pos);
feedback_data.staFeedback = double(feedback_data.staFeedback);
feedback_data.PDP = double(feedback_data.PDP);
feedback_data.DopplerShift = double(feedback_data.DopplerShift);
feedback_data.rssi = double(feedback_data.rssi);
feedback_data.SNR = double(feedback_data.SNR);
feedback_data.JamData = double(feedback_data.JamData);
evm = double(evm);
errorMessage = '';
catch ErrorInfo
errorMessage = ErrorInfo.message;
end
end

25
Select_Detection.m Normal file
View File

@ -0,0 +1,25 @@
%%*****************************************************%%
%%================================================================%%
% data_Freuq
% Pf
% PfH
% operator 使
% JJ
%%========================================================================%%
function JJ = Select_Detection(data_Freuq,Pf,PfH,Num_step,operator)
if strcmp(operator,'CME')==1
JJ = CME(data_Freuq,Pf);
elseif strcmp(operator,'FCME')==1
JJ = FCME(data_Freuq,Pf);
elseif strcmp(operator,'FCME_hard')==1
JJ = FCME_hard(data_Freuq,Pf);
elseif strcmp(operator,'Double_Th_FCME')==1
JJ = Double_Th_FCME(data_Freuq,Pf,PfH);
elseif strcmp(operator,'FCME_pro')==1
JJ = FCME_pro(data_Freuq,Pf);
elseif strcmp(operator,'DiffFCME')==1
JJ = DiffFCME_B(data_Freuq,Pf,Num_step);
else
disp('Error,please enter the correct mode of operation!');
end
end

57
SpectrumSense.m Normal file
View File

@ -0,0 +1,57 @@
function [Type,Jam_data,Jam_pos] = SpectrumSense(rx_format,cfgUI)
addpath(genpath('.\JamDetect'));
NFFT = 2048;
PfH = 0.0001;
Pf = 0.001;
fs = 20e6;
operator = cfgUI.JamDetect;
%
y = fft(rx_format(1:NFFT,:));
data_Freuq = y(1:NFFT/2,:);
J = Selecdt_Detection(data_Freuq,Pf,PfH,32,operator);
Type = JudgeTypeJam(J);
% struct jam_data;
jam_data.Num_multi = 0;
jam_data.f_multi = 0;
jam_data.Power_multi = [];
jam_data.Num_band = [];
jam_data.f_start = [];
jam_data.f_end = [];
jam_data.f_wide = [];
jam_data.Power_band = [];
if strcmp(Type,'multi')
[jam_data.Num_multi,jam_data.f_multi,jam_data.Power_multi] = Multi_Parameter(data_Freuq.',J,fs,NFFT);
elseif strcmp(Type,'mono')
[jam_data.f_multi,jam_data.Power_multi] = Mono_Parameter(data_Freuq.',J,fs,NFFT);
elseif strcmp(Type,'band')
[jam_data.Num_band,jam_data.f_start,jam_data.f_end,jam_data.f_wide,jam_data.Power_band] = Band_Parameter(data_Freuq.',J,fs,NFFT);
elseif strcmp(Type,'band_mono')
[jam_data.f_mono,jam_data.Power_mono,jam_data.Num_band,jam_data.f_start,jam_data.f_end,jam_data.f_wide,jam_data.Power_band] = Band_Mono_Parameter(data_Freuq.',J,fs,NFFT);
elseif strcmp(Type,'band_multi')
[jam_data.Num_multi,jam_data.f_multi,jam_data.Power_multi,jam_data.Num_band,jam_data.f_start,jam_data.f_end,jam_data.f_wide,jam_data.Power_band] = Band_Multi_Parameter(data_Freuq.',J,fs,NFFT);
else
disp('No jam!');
end
Jam_data = jam_data.f_multi;
dt=1/fs;
data_abs = 10*log(abs(data_Freuq(J)));
J_freuq=(J-1)/(dt*NFFT)/10^6; %
ssf=(0:NFFT/2-1)/(dt*NFFT); %
data_db=10*log(abs(data_Freuq));
Jam_pos = J_freuq*10^6;
%
%
% plot(ssf,data_db); %
% grid on;
% hold on;
% stem(Jam_pos,data_abs,'m--','filled','MarkerSize',2)
% xlabel('frequency');
% ylabel('magnitude');
% hold off;
% pause(0.5);
% close;
rmpath(genpath('.\JamDetect'));
end

227
TX.m Normal file
View File

@ -0,0 +1,227 @@
clear;
close all;
clc;
%% LabVIEW--
cfgUI.ChannelBandwidth = 'CBW20'; % 'CBW20''CBW40''CBW80'
cfgUI.NTX2_enabled = 1; %
max_run_time = 60; %
SEED = 1;
cfgUI.numUsers = 1; % 1-2
cfgUI.DataType = 'test'; % 'test''text''photo'image.png
numPkt = 5; %1~5
pktLength = 1001; % short,medium,long1001,7007,12012,APEPLength
if strcmp(cfgUI.DataType,'photo')
txPSDUByte = imread('image.png');
I_gray = im2gray(txPSDUByte);
[len,width] = size(I_gray);
binary = dec2bin(I_gray(:),8);
bitstream = reshape(binary',1,[]);%
byte_array = reshape(bitstream',8,[])';%
txPSDUByte = bin2dec(byte_array);
% zjd3.26
if numPkt*pktLength >= length(txPSDUByte) % 5
for pktNum = 1:numPkt %
if pktNum*pktLength >= length(txPSDUByte)
numPkt = pktNum;
break
end
end
else % 5
if numPkt*7007 >= length(txPSDUByte)
for pktNum = 1:numPkt %
if pktNum*7007 >= length(txPSDUByte)
numPkt = pktNum;
pktLength = 7007;
break
end
end
else
for pktNum = 1:numPkt %
if pktNum*12012 >= length(txPSDUByte)
numPkt = pktNum;
pktLength = 12012;
break
end
end
end
end
txPSDUByteUser = zeros(len*width+3,cfgUI.numUsers); %
for i = 1:cfgUI.numUsers
byteLen = length(txPSDUByte);
byteLenBit = int2bit(byteLen,16);
Len1 = bit2int(byteLenBit(1:8),8);
Len2 = bit2int(byteLenBit(9:16),8);
txPSDUByteUser(1:len*width+2,i) = [Len1;Len2;txPSDUByte];
txPSDUByteUser(end,i) = mod(sum(txPSDUByteUser(:,i)),256);
end
txPSDUByteUser = uint8(txPSDUByteUser);
save('TXPackets\txPSDUByteUser.mat','txPSDUByteUser');
elseif strcmp(cfgUI.DataType,'text')
else
txPSDUByteUser = 0;
end
cfgUI.UserMode = 'SU'; % 使'MU','SU'SU40MHzSTBCMUlxr
cfgUI.FeedbackMode = 'openloop'; % 'openloop','feedback'
SoundingMode = 0; %
cfgUI.numTx = 1; % 线1~2
cfgUI.numRx = 1; % 线1~2
cfgUI.AI.PAPR = 'PAPR'; % 'default','PAPR-Net'
cfgUI.PhySecur = 'default'; % '','CP',''
%-------------------------------------
%---
cfgUI.user1.s = 1;
cfgUI.user1.f = [1,1,1,1]; % 410
cfgUI.user1.t = ones(1,numPkt); % numPkt10
cfgUI.user1.p = 0.5; %
cfgUI.user2.s = 1;
cfgUI.user2.f = [1,1,1,1];
cfgUI.user2.t = ones(1,numPkt);
cfgUI.user2.p = 0.5;
%------user1
cfgUI.user1.ChannelCode = 'LDPC'; % BCC or LDPC
cfgUI.user1.CodeRate = 3/4; % 1/2 or 2/3 or 3/4 or 5/6
cfgUI.user1.CodeLengt = 1600; % 200*8=1600,800
cfgUI.user1.InterWeaveMode = 'random'; % random,horizontal
cfgUI.user1.InterWeaveDepth = 1024; % 2048,1024
cfgUI.user1.ScrambleLength = 6; % 32
cfgUI.user1.CPLength = '1/4'; % CP1/16 or 1/8 or 1/4
cfgUI.user1.FFTSize = 256; % FFT128 or 256 or 512
cfgUI.user1.NumSubcarrier = 242; % 128 or 256 or 512
cfgUI.user1.ModulationMode = '16QAM'; % 4QAM or 8QAM or 16QAM or 32QAM or 64QAM
cfgUI.user1.MultiAntennaMode = 'STBC'; % 线'ZF-BF','MMSE-BF', SU使STBC'STBC'
cfgUI.user1.SpatialMapping = 'Hadamard'; % 'Direct','Hadamard','Fourier','Custom'----------zjd 3.21
cfgUI.user1.APEPlength = pktLength; % short,medium,long1001,7007,12012
cfgUI.user1.pilotInterval = 5;
%------user2
cfgUI.user2.ChannelCode = 'LDPC'; % BCC or LDPC
cfgUI.user2.CodeRate = 3/4; % 1/2 or 2/3 or 3/4 or 5/6
cfgUI.user2.CodeLengt = 1600; % 200*8=1600,800
cfgUI.user2.InterWeaveMode = 'random'; % random,horizontal
cfgUI.user2.InterWeaveDepth = 1024; % 2048,1024
cfgUI.user2.ScrambleLength = 6; % 32
cfgUI.user2.CPLength = '1/4'; % CP1/16 or 1/8 or 1/4
cfgUI.user2.FFTSize = 256; % FFT128 or 256 or 512
cfgUI.user2.NumSubcarrier = 242; % 128 or 256 or 512
cfgUI.user2.ModulationMode = '16QAM'; % 4QAM or 8QAM or 16QAM or 32QAM or 64QAM
cfgUI.user2.MultiAntennaMode = 'ZF-BF'; % 线'ZF-BF','MMSE-BF','STBC'
cfgUI.user2.SpatialMapping = 'Direct'; % 'Direct','Hadamard','Fourier'
cfgUI.user2.APEPlength = pktLength; %
cfgUI.user2.pilotInterval = 5;
%% TX
if SoundingMode %%% TX
tic;
feedback_stat = false;
while feedback_stat==false && toc < max_run_time %
txNDP = channelSounding(cfgUI); % NDP
tx_data = txNDP;
save('TXPackets\transmit_data.mat','tx_data','cfgUI');% NDP
pause(1); % 5s
numUsers = cfgUI.numUsers;
feedback_data = struct(); %
stat = zeros(1,numUsers);
for uid = 1:numUsers
filename = ['TXPackets/NDPfeedback_for_User' num2str(uid) '.mat'];
stat(uid) = 1;
if exist(filename,'file') ~= 2 %
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; %
stat(uid) = 0; % 0
end
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename)); % ---snrlxr
end
feedback_stat = all(stat == 1); %
end
%
if feedback_stat==false
error("Time Out !!!");
else
disp("feedback received");
end
elseif strcmp(cfgUI.FeedbackMode,'openloop')
while(1)
%
numUsers = cfgUI.numUsers; %
feedback_data = struct(); %
for uid = 1:numUsers
filename = ['TXPackets/NDPfeedback_for_User' num2str(uid) '.mat'];
if exist(filename,'file') ~= 2 %
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; %
end
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename)); %
if eval(['isnan(sum(feedback_data.user' num2str(uid) '.staFeedback,"all")) || isempty(feedback_data.user' num2str(uid) '.staFeedback)']) % staFeedbackNaN
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; %
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename));
end
end
[paraCal,tx_data,cfgUI,errorMessage] = TX_transmit(numPkt,SEED,cfgUI,feedback_data,txPSDUByteUser);
save('TXPackets\transmit_data.mat','tx_data','cfgUI');
if cfgUI.AI.PAPR == 'PAPR'
% PAPR DPD
end
end
elseif strcmp(cfgUI.FeedbackMode,'feedback')
while(1)
tic;
feedback_stat = false;
while feedback_stat==false && toc < max_run_time
txNDP = channelSounding(cfgUI); % NDP
tx_data = txNDP;
save('TXPackets\transmit_data.mat','tx_data','cfgUI');% NDP
pause(0); % 5s
numUsers = cfgUI.numUsers; %
stat = zeros(1,numUsers); % stat
feedback_data = struct(); %
for uid = 1:numUsers
filename = ['TXPackets/NDPfeedback_for_User' num2str(uid) '.mat'];
stat(uid) = 1;
if exist(filename,'file') ~= 2 %
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; %
stat(uid) = 0; % 0
end
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename));
if eval(['isnan(sum(feedback_data.user' num2str(uid) '.staFeedback,"all")) || isempty(feedback_data.user' num2str(uid) '.staFeedback)']) % staFeedbackNaN
filename = ['TXPackets/NDPfeedback_Default_for_User' num2str(uid) '.mat']; %
feedback_data = setfield(feedback_data,['user' num2str(uid)],loadfeedback(filename));
end
end
feedback_stat = all(stat == 1); %
end
%
if feedback_stat==false
error("Time Out !!!");
else
disp("feedback received");
end
%
%
ack_feedback_stat=true;
stat = 1;
while ack_feedback_stat==true && stat==1
load('TXPackets\feedback.mat');
feedback_data = feedback;
[paraCal,tx_data,cfgUI,errorMessage] = TX_transmit(numPkt,SEED,cfgUI,feedback_data,txPSDUByteUser);
save('TXPackets\transmit_data.mat','tx_data','cfgUI');
if cfgUI.AI.PAPR == 'PAPR'
% PAPR+DPD
end
pause(1); %
ACK_feedback = cell(1,numUsers);
for uid = 1:numUsers
load(['TXPackets\ACKfeedback_for_User' num2str(uid) '.mat'])
ACK_feedback{uid} = ACK;
end
% PAPRAIreward
show2LabVIEW(); %
end
end
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
TXPackets/feedback.mat Normal file

Binary file not shown.

BIN
TXPackets/rx_for_User1.mat Normal file

Binary file not shown.

BIN
TXPackets/rx_for_User2.mat Normal file

Binary file not shown.

BIN
TXPackets/rx_for_User3.mat Normal file

Binary file not shown.

BIN
TXPackets/transmit_data.mat Normal file

Binary file not shown.

Binary file not shown.

121
TX_SU.m Normal file
View File

@ -0,0 +1,121 @@
function [txPad,cfgHE]=TX_SU(cfgHE,txPSDU)
if isfield(cfgHE,'InterleavLen')
tx = SU_Special(cfgHE,txPSDU);
% Add trailing zeros to allow for channel delay
txPad = [tx; zeros(30,1)];
else
% psduLength = getPSDULength(cfgHE); % PSDU length in bytes
% txPSDUcrc = TX_CRC32(txPSDU(1:(psduLength*8 - 32)));
txPSDUcrc = txPSDU;
tx = wlanWaveformGenerator(txPSDUcrc,cfgHE);
% Add trailing zeros to allow for channel delay
txPad = [tx; zeros(30,cfgHE.NumTransmitAntennas)];
end
end
function crcData = TX_CRC32(dataPacketBits)
poly = [32,26,23,22,16,12,11,10,8,7,5,4,2,1,0];
crcGen32 = comm.CRCGenerator(...
'Polynomial', poly, ...
'InitialConditions', 1, ... % Initial states of the internal shift register
'DirectMethod', true, ...
'FinalXOR', 1); % XOR
crcData = crcGen32(dataPacketBits);
end
%%
function tx = SU_Special(WaveformPara,txPSDU)
% tx_STF = STS_modulation(NumerologyNo); % STF
scrData = TX_CRC32_Scramble(txPSDU);
trellis = poly2trellis(7,[171 133]);
tx_encoded_bit = convenc(scrData,trellis,WaveformPara.puncpat);
tx_padded_bit = [tx_encoded_bit;zeros(WaveformPara.DataPadding,1)];
%---------------------------------------------
dataMod = qammod(tx_padded_bit,WaveformPara.Mod,'InputType','bit','UnitAveragePower',true);
WaveformPara.Power_sym = mean(abs(dataMod).^2);
dataMod = reshape(dataMod,WaveformPara.UsedSubcarrier,[]);
% %
%
% N_carriers = WaveformPara.N_FFT;
% rng(2);
% channel_response=sqrt(1/2)*(randn(1,N_carriers)+1i*randn(1,N_carriers));
% %
% N_windows = 8;
% %
% N_level = 10;
% % CPCP>
% min_len_CP = 30;
% %
% CPset = Generate_CP(channel_response,N_windows,N_level,min_len_CP);
%
% [serialOFDMsym,WaveformPara.pilot,myFrameLen] = tx_FFTSymbolGen_PilotBlockPN(dataMod,WaveformPara,CPset); % CP
[serialOFDMsym,WaveformPara.pilot] = tx_FFTSymbolGen_PilotBlockPN(dataMod,WaveformPara);
WaveformPara.Power_sig = mean(abs(serialOFDMsym).^2);
txdata = serialOFDMsym/sqrt(WaveformPara.Power_sig);
cfg = wlanNonHTConfig('SignalChannelBandwidth',true, ...
'BandwidthOperation','Static');
cfg.MCS = WaveformPara.MCS;
cfg.PSDULength = WaveformPara.PacketSize; %0-4095
% tx_STF = STS_modulation(NumerologyNo); % STF
FrameNo = WaveformPara.NumerologyNo;
tx_STF = wlanLSTF(cfg); % STF
tx_LTF = wlanLLTF(cfg); % LTF
[tx_SIG, tx_sigdata] = newLSIG(cfg,FrameNo);% SIG
tx = [tx_STF;tx_LTF;tx_SIG;serialOFDMsym;zeros(30,1)];
end
function [serialOFDMsym,pilot] = tx_FFTSymbolGen_PilotBlockPN(dataModInMatrix,WaveformPara,SysParameters)
numOfdmSymbol = WaveformPara.FrameSymNum;
N_used = WaveformPara.UsedSubcarrier;
CP_Len = WaveformPara.CP_Len;
pnSequence = comm.PNSequence('Polynomial',[8 6 5 4 0], ...
'SamplesPerFrame',N_used,'InitialConditions',[0 0 0 0 0 0 0 1]);
% pilotPower = WaveformPara.Power_sym;
% pilot = generatePilot(pnSequence,pilotPower);
pilot = generatePilot(pnSequence,1);
m = WaveformPara.PilotNum-1;
dataModAddPilot = zeros(N_used,numOfdmSymbol);
for i = 1:m
dataModAddPilot(:,(i-1)*(WaveformPara.PilotInterval+1)+1:i*(WaveformPara.PilotInterval+1)) = ...
[pilot,dataModInMatrix(:,(i-1)*WaveformPara.PilotInterval+1:i*WaveformPara.PilotInterval)];
end
dataModAddPilot(:,m*(WaveformPara.PilotInterval+1)+1:end) = ...
[pilot,dataModInMatrix(:,m*WaveformPara.PilotInterval+1:end)];
dataModAddPilot_shift = [zeros(1,WaveformPara.FrameSymNum);...
dataModAddPilot(1:(N_used-1)/2,:);...
zeros(WaveformPara.NullSubcarrier,WaveformPara.FrameSymNum);...
dataModAddPilot(1+(N_used-1)/2:end,:)];
OFDMsym = ifft(dataModAddPilot_shift,[],1)*sqrt(WaveformPara.N_FFT)/sqrt(N_used)*sqrt(WaveformPara.N_FFT);
OFDMsymAddCP = [OFDMsym(WaveformPara.N_FFT-CP_Len+1:end,:);OFDMsym];
serialOFDMsym = reshape(OFDMsymAddCP,[],1);
end
function pilot = generatePilot(pnSequence,Power)
pilot = pnSequence();
bpskModulator = comm.BPSKModulator;
pilot = bpskModulator(pilot)*sqrt(Power);
end

124
TX_transmit.m Normal file
View File

@ -0,0 +1,124 @@
%*********************************lql03.21*********************************
function [paraCal,tx_data,cfgUI,errorMessage] = TX_transmit(numPkt,SEED,cfgUI,feedback_data,txPSDUfile)
% try
if strcmp(cfgUI.DataType,'photo')
pktLength = cfgUI.user1.APEPlength;
% zjd3.26
if numPkt*pktLength >= length(txPSDUfile(:,1)) % 5
for pktNum = 1:numPkt %
if pktNum*pktLength >= length(txPSDUfile(:,1))
numPkt = pktNum;
break
end
end
else % 5
if numPkt*7007 >= length(txPSDUfile(:,1))
for pktNum = 1:numPkt %
if pktNum*7007 >= length(txPSDUfile(:,1))
numPkt = pktNum;
pktLength = 7007;
break
end
end
else
for pktNum = 1:numPkt %
if pktNum*12012 >= length(txPSDUfile(:,1))
numPkt = pktNum;
pktLength = 12012;
break
end
end
end
end
%
cfgUI.user1.APEPlength = pktLength;
cfgUI.user2.APEPlength = pktLength;
cfgUI.user1.t = ones(1,numPkt);
cfgUI.user2.t = ones(1,numPkt);
end
if strcmp(cfgUI.FeedbackMode,'feedback')
[cfgHE,RU_index,cfgUI] = parameter_fromAlgorithm(cfgUI,feedback_data);% RU
else
[cfgHE,RU_index,cfgUI] = parameter_fromUI(cfgUI); % RU
end
%*********************************lql03.21*********************************
showResourceMatrix(cfgHE,cfgUI,RU_index); %
txPSDU = DataGenerate(cfgUI,numPkt,SEED,cfgHE,txPSDUfile);
% for i = 1:length(txPSDU)
% txPSDU{i} = HESU_gen(txPSDU,cfgUI.ChannelBandwidth,cfgHE.User{1}.MCS);
% end
tx_data = [];
% HE-SU
if strcmp(cfgUI.UserMode,'SU')
txPSDU = txPSDU{1};
% --------------------------------zjd0323-----------------------
for pnum = 1 : numPkt
[txPad,cfgHE]=TX_SU(cfgHE,txPSDU(:,pnum));
tx_awgn = wgn(600,cfgHE.NumTransmitAntennas,-20,'complex');
tx_data = [tx_data;txPad;tx_awgn]; %
end
tx_data = [tx_awgn(1:50,:);tx_data]; %
elseif strcmp(cfgUI.UserMode,'MU')
% HE-MU
if strcmp(cfgUI.FeedbackMode,'feedback')
%*********************************lql03.21*********************************
% feedback_data
for nuser = 1 : length(cfgHE.User)
STAID = cfgHE.User{nuser}.STAID;
if STAID == 0
eval(['Feedback_data.user' num2str(nuser) '= feedback_data.user2']);
else
eval(['Feedback_data.user' num2str(nuser) '= feedback_data.user' num2str(STAID)]);
end
end
staFeedback = cell(1,length(cfgHE.User));
for userIdx = 1:length(cfgHE.User)
eval(['staFeedback{userIdx} = Feedback_data.user' num2str(userIdx) '.staFeedback;']);
end
%*********************************lql03.21*********************************
cfgNDP = wlanHESUConfig('APEPLength',0,'GuardInterval',0.8); % No data in an NDP
cfgNDP.NumTransmitAntennas = cfgHE.NumTransmitAntennas;%??
cfgNDP.NumSpaceTimeStreams = 1;%??
% For each RU calculate the steering matrix to apply
for ruIdx = 1:numel(cfgHE.RU)
% Calculate the steering matrix to apply to the RU given the feedback
steeringMatrix = heMUCalculateSteeringMatrix(staFeedback,cfgHE,cfgNDP,ruIdx);
% Apply the steering matrix to each RU
cfgHE.RU{ruIdx}.SpatialMapping = 'Custom';
cfgHE.RU{ruIdx}.SpatialMappingMatrix = steeringMatrix;
end
elseif strcmp(cfgUI.FeedbackMode,'openloop')
for ruIdx = 1:numel(cfgHE.RU)
% Apply the steering matrix to each RU
% cfgHE.RU{ruIdx}.SpatialMapping = cfgUI.user1.SpatialMapping;%% --???
cfgHE.RU{ruIdx}.SpatialMapping = 'Hadamard';
end
end
% Generate waveform with idle period
for pnum = 1 : numPkt
userString = '{';
for nuser = 1 : length(cfgHE.User)
userString = [userString 'txPSDU{' num2str(nuser) '}(:,pnum),'];
end
txPSDUtmp = eval([userString(1:(end-1)) '}']); %%------------CRC
tx = wlanWaveformGenerator(txPSDUtmp,cfgHE);
tx_awgn = wgn(600,cfgHE.NumTransmitAntennas,-20,'complex');
% awgn(zeros(600,cfgHE.NumTransmitAntennas),20,'linear',1,'all');
tx_data = [tx_data;tx;tx_awgn]; %
end
tx_data = [tx_awgn(1:50,:);tx_data]; %
% tx_data = awgn(tx_data,30,mean(abs(tx_data(1:1000)).^2)); %
end
paraCal = calculate_PAPR(tx_data(1500:2500,:));
errorMessage = '';
% catch ErrorInfo
% paraCal = 0;
% tx_data = [];
% cfgUI = struct();
% errorMessage = ErrorInfo.message;
% end
end

28
WaveAdp/ChanStat.m Normal file
View File

@ -0,0 +1,28 @@
function ChanPara = ChanStat(SNR, tau_d, velocity, Ts, FreqCarrier, TimeStamp)
A_dB = -15;norm_flag = 1;c = 3e8;
ChanPara.PDP = exp_PDP(tau_d,Ts,A_dB,norm_flag);
ChanPara.delay = ones(1,length(ChanPara.PDP))*Ts;
ChanPara.rmsdelay = tau_d;
ChanPara.doppler = 'Jakes';
ChanPara.Velocity = velocity;
ChanPara.epsilon = 0;
ChanPara.SNR = SNR;
ChanPara.FreqCarrier = FreqCarrier;
ChanPara.MaximumDopplerShift = FreqCarrier/c * velocity/3600 *1000;
ChanPara.SampleFs = 1/Ts;
end
function PDP = exp_PDP(tau_d,Ts,A_dB,norm_flag)
if nargin<4, norm_flag=1; end % normalizes
if nargin<3, A_dB=-20; end % 20dB below
sigma_tau = tau_d; A = 10^(A_dB/10);
lmax=ceil(-tau_d*log(A)/Ts); % get max. path index (2.8)/Ts
% Computes normalization factor for power normalization
if norm_flag
p0=(1-exp(-Ts/sigma_tau))/(1-exp(-(lmax+1)*Ts/sigma_tau)); % (2.10)
else p0=1/sigma_tau;
end
% Exponential PDP
l=0:lmax; PDP = p0*exp(-l*Ts/sigma_tau); % (2.11)
end

View File

@ -0,0 +1,61 @@
%%
function [BER,PER,SyncErr] = ExecutedMAIN0701(PacketSize, NumerologySel, MCS_no, ChanPara, FreqCarrier, FrameNo, seed_set)
[SysParameters,WaveformPara] = WaveformNumerologyCal(PacketSize,NumerologySel,MCS_no);
%% TX
rng(seed_set(1),'twister');
dataPacketBits = randi([0 1],WaveformPara.Payload,1);
scrData = TX_CRC32_Scramble(dataPacketBits);
trellis = poly2trellis(7,[171 133]);
tx_encoded_bit = convenc(scrData,trellis,WaveformPara.puncpat);
tx_padded_bit = [tx_encoded_bit;zeros(WaveformPara.DataPadding,1)];
%---------------------------------------------
dataMod = qammod(tx_padded_bit,WaveformPara.Mod,'InputType','bit');
WaveformPara.Power_sym = mean(abs(dataMod).^2);
dataMod = reshape(dataMod,WaveformPara.UsedSubcarrier,[]);
%% %
%
N_carriers = WaveformPara.N_FFT;
channel_response=sqrt(1/2)*(randn(1,N_carriers)+1i*randn(1,N_carriers));
%
N_windows = 8;
%
N_level = 10;
% CPCP>
min_len_CP = 30;
%
CPset = Generate_CP(channel_response,N_windows,N_level,min_len_CP);
%
[serialOFDMsym,WaveformPara.pilot,myFrameLen] = tx_FFTSymbolGen_PilotBlockPN(dataMod,WaveformPara,CPset); % CP
WaveformPara.Power_sig = mean(abs(serialOFDMsym).^2);
[WaveformPara.preamble,WaveformPara.c1,WaveformPara.c2] = ...
generatePreamble(WaveformPara,WaveformPara.Power_sig); % hb:
txSignal = [WaveformPara.preamble;serialOFDMsym];
% RFSignal = RFimpairment(txSignal, FreqCarrier);
%
%% Channel
[rxSignal,ChanPara] = PassChan(txSignal,WaveformPara,SysParameters,ChanPara,seed_set(2));
% SIR = InterfCal(rxSignal,ChanPara);
%% RX
[rxSignal_sync,SyncErr] = rxSyncSC(rxSignal,WaveformPara,myFrameLen);
[rxDataModLs] = rx_PilotBlockChanEst(rxSignal_sync,ChanPara,WaveformPara,CPset,SysParameters); % CP
dataDemod = qamdemod(rxDataModLs,WaveformPara.Mod,'OutputType','approxllr', ...
'UnitAveragePower',false,'NoiseVariance',ChanPara.N0);
dataDePadded = dataDemod(1:end - WaveformPara.DataPadding);
tb = 8;
decoded = vitdec(dataDePadded,trellis,tb,'trunc','unquant',WaveformPara.puncpat);
[rx,PER] = RX_CRC32_deScramble(decoded);
[numErrors,BER] = biterr(dataPacketBits,rx);
end
%%

73
WaveAdp/Generate_CP.m Normal file
View File

@ -0,0 +1,73 @@
function [len_CP] = Generate_CP(channel_response,N_windows,N_level,min_len_CP)
% CP
% OFDMH_bs
% channel_response N_windows N_level
% min_len_CPCPCP>
% CP
%
N_carriers = length(channel_response);
%
Len_windows = N_carriers / N_windows;
%
[channel_gain, sorted_indices] = sort(abs(channel_response), 'descend');%
G_max = max(channel_gain);
G_min = min(channel_gain);
%
D_L = (G_max-G_min)/N_level;
%
level_k = zeros(1,N_carriers);
for i = 1:N_carriers
%
if channel_gain(i) <= G_min
level_k(i) = 1;
elseif channel_gain(i) >= G_max
level_k(i) = N_level;
% (3)
else
level_k(i) = ceil((channel_gain(i) - G_min)/D_L);
end
end
% (2)
weight_k = 2*level_k-1;
% CP
weight_matrix = zeros(N_windows,Len_windows);
choose_matrix = zeros(N_windows,Len_windows);
len_CP = zeros(1,N_windows);
for i = 1:N_windows
weight_matrix(i,:) = weight_k((i-1)*Len_windows+1:i*Len_windows);%
current_CP = weight_matrix(i,1);%
choose_matrix(i,1) = current_CP;%
for j = 2:Len_windows
%
if current_CP <= min_len_CP
current_CP = current_CP + weight_matrix(i,j);
choose_matrix(i,j) = weight_matrix(i,j);
%
if j == Len_windows
if current_CP <= min_len_CP %
len_CP(i) = min_len_CP;
break;
else
len_CP(i) = current_CP;%
break;
end
end
% current_CP > min_len_CP
else
len_CP(i) = current_CP;
break;
end
end
end
end

BIN
WaveAdp/NumerologySet.mat Normal file

Binary file not shown.

18
WaveAdp/PassChan.m Normal file
View File

@ -0,0 +1,18 @@
function [chanOut,ChanPara] = PassChan(dataIn,WaveformPara,SysParameters,ChanPara,seed)
Chan = comm.RayleighChannel(...
'SampleRate',ChanPara.SampleFs, ...
'PathDelays', ChanPara.delay, ...
'AveragePathGains', ChanPara.PDP, ...
'NormalizePathGains',true, ...
'MaximumDopplerShift',floor(ChanPara.MaximumDopplerShift), ...
'DopplerSpectrum',doppler(ChanPara.doppler), ...
'PathGainsOutputPort',SysParameters.ShowPathGain);
[rAddMultipath,~] = Chan(dataIn);
% rAddCFO = rAddMultipath.*exp(sqrt(-1)*2*pi*(1:length(rAddMultipath))'*ChanPara.epsilon/N_FFT);
SNR = ChanPara.SNR;
ChanPara.N0 = WaveformPara.Power_sig/10^(SNR/10);
rAddAWGN = awgn(rAddMultipath,SNR,'measured');
chanOut = [sqrt(ChanPara.N0)*(randn(400,1)+1i*randn(400,1));rAddAWGN];
end

115
WaveAdp/RX.m Normal file
View File

@ -0,0 +1,115 @@
%% RX for labview
clc;
close all;
clear ;
%%
receiveAntennasNum = 1;
receiveBandwidth = 20e6;
syncAlgo = 'first';
chanEstiAlgo = 'first';
equalizeAlgo = 'first';
demodMode = 'first';
interpCodeAlgo = 'first';
%%
rxInput.receiveAntennasNum = receiveAntennasNum; % 1 or 2
rxInput.receiveBandwidth = receiveBandwidth;% 10~20M
rxInput.syncAlgo = syncAlgo;% string
rxInput.chanEstiAlgo = chanEstiAlgo;% string
rxInput.equalizeAlgo = equalizeAlgo;% string
rxInput.demodMode = demodMode;% string
rxInput.interpCodeAlgo = interpCodeAlgo;% string
%%
userNum = 1;
fileType = 'text';
encryptMode = 'encryptMode';
antennasNum = 1;
centerFreq = 2450e6;
sendBandwidth = 5e6;
fftNum = 128;
CPratio = 0.25;
pilotInterval = 3;
% MCS_set=[2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6];% CHB3.19
MCS = [16,4];
subcarriersNum = 128; %
%%
txInput.userNum = userNum; % 1 or 2
txInput.fileType = fileType; % 'text' or 'picture'
txInput.encryptMode = encryptMode; % 'encrypt' or 'not encrypt'
txInput.antennasNum = antennasNum; % 1 or 2
txInput.centerFreq = centerFreq; % 500MHz~2.4G
txInput.sendBandwidth = sendBandwidth; % 20~40MHz
txInput.fftNum = fftNum;% 128 or 256 or 512
txInput.CPratio = CPratio; % 0.25 or 0.125 or 0.0625
txInput.pilotInterval = pilotInterval; % 3 5 7
txInput.MCS = MCS; % a set [2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6]
txInput.subcarriersNum = subcarriersNum;% 52 or 106 or 242
PacketSize = 200;
NumerologySel = [txInput.fftNum,txInput.CPratio,txInput.pilotInterval];
MCS_no = txInput.MCS;
[SysParameters,WaveformPara] = WaveformNumerologyCal(PacketSize,NumerologySel,MCS_no);
seed_set = [1 2 3];
rng(seed_set(1),'twister');
dataPacketBits = randi([0 1],WaveformPara.Payload,1);
scrData = TX_CRC32_Scramble(dataPacketBits);
trellis = poly2trellis(7,[171 133]);
tx_encoded_bit = convenc(scrData,trellis,WaveformPara.puncpat);
tx_padded_bit = [tx_encoded_bit;zeros(WaveformPara.DataPadding,1)];
%---------------------------------------------
dataMod = qammod(tx_padded_bit,WaveformPara.Mod,'InputType','bit');
WaveformPara.Power_sym = mean(abs(dataMod).^2);
dataMod = reshape(dataMod,WaveformPara.UsedSubcarrier,[]);
%% %
%
N_carriers = WaveformPara.N_FFT;
channel_response=sqrt(1/2)*(randn(1,N_carriers)+1i*randn(1,N_carriers));
N_windows = 8;
N_level = 10;
min_len_CP = 30;
CPset = Generate_CP(channel_response,N_windows,N_level,min_len_CP);
[serialOFDMsym,WaveformPara.pilot,myFrameLen] = tx_FFTSymbolGen_PilotBlockPN(dataMod,WaveformPara,CPset);
WaveformPara.Power_sig = mean(abs(serialOFDMsym).^2);
[WaveformPara.preamble,WaveformPara.c1,WaveformPara.c2] = ...
generatePreamble(WaveformPara,WaveformPara.Power_sig);
%%
load('rxdata5normalized.mat')
% rxSignal = rxSignal(5382:8680)';
% rxSignal = downsample(rxSignal, 2)';%data1 part
% rxSignal = rxSignal(5128:7889)';%data2 part
rxSignal = rxSignal(8500:10500)';
[rxSignal_sync,SyncErr] = rxSyncSC(rxSignal,WaveformPara,myFrameLen);
[rxDataModLs] = rx_PilotBlockChanEstForLabview(rxSignal_sync,WaveformPara,CPset); % CP
dataDemod = qamdemod(rxDataModLs,WaveformPara.Mod,'OutputType','approxllr', ...
'UnitAveragePower',false,'NoiseVariance',0.0243);%ChanPara.N0
dataDePadded = dataDemod(1:end - WaveformPara.DataPadding);
tb = 8;
decoded = vitdec(dataDePadded,trellis,tb,'trunc','unquant',WaveformPara.puncpat);
[rxBits,PER] = RX_CRC32_deScramble(decoded);%
[numErrors,BER] = biterr(dataPacketBits,rxBits);
%%
rxOutput.delaySpread = 0; % double
rxOutput.SNR = 0;% double
rxOutput.RSSI = 0;% double
rxOutput.BER = BER;% double
rxOutput.PER = PER;% double
rxOutput.EVM = 0;% double
rxOutput.phaseNoise = 0;% double
BER
PER
SyncErr

View File

@ -0,0 +1,15 @@
function [rx,frmError] = RX_CRC32_deScramble(dataPacketBits)
descrambler = comm.Descrambler(2,[1 0 0 0 0 0 1 0 1], ...
zeros(8,1));
deScrData = descrambler(dataPacketBits);
poly = [32,26,23,22,16,12,11,10,8,7,5,4,2,1,0];
crcdetector = comm.CRCDetector(...
'Polynomial', poly, ...
'InitialConditions', 1, ...
'DirectMethod', true, ...
'FinalXOR', 1);
[rx,frmError] = crcdetector(deScrData);
end

124
WaveAdp/RX_forPreamble.m Normal file
View File

@ -0,0 +1,124 @@
%% RX for labview
clc;
close all;
clear ;
%%
receiveAntennasNum = 1;
receiveBandwidth = 20e6;
syncAlgo = 'first';
chanEstiAlgo = 'first';
equalizeAlgo = 'first';
demodMode = 'first';
interpCodeAlgo = 'first';
%%
rxInput.receiveAntennasNum = receiveAntennasNum; % 1 or 2
rxInput.receiveBandwidth = receiveBandwidth;% 10~20M
rxInput.syncAlgo = syncAlgo;% string
rxInput.chanEstiAlgo = chanEstiAlgo;% string
rxInput.equalizeAlgo = equalizeAlgo;% string
rxInput.demodMode = demodMode;% string
rxInput.interpCodeAlgo = interpCodeAlgo;% string
%%
userNum = 1;
fileType = 'text';
encryptMode = 'encryptMode';
antennasNum = 1;
centerFreq = 2450e6;
sendBandwidth = 5e6;
fftNum = 128;
CPratio = 0.25;
pilotInterval = 3;
% MCS_set=[2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6];% CHB3.19
MCS = [16,4];
subcarriersNum = 128; %
%%
txInput.userNum = userNum; % 1 or 2
txInput.fileType = fileType; % 'text' or 'picture'
txInput.encryptMode = encryptMode; % 'encrypt' or 'not encrypt'
txInput.antennasNum = antennasNum; % 1 or 2
txInput.centerFreq = centerFreq; % 500MHz~2.4G
txInput.sendBandwidth = sendBandwidth; % 20~40MHz
txInput.fftNum = fftNum;% 128 or 256 or 512
txInput.CPratio = CPratio; % 0.25 or 0.125 or 0.0625
txInput.pilotInterval = pilotInterval; % 3 5 7
txInput.MCS = MCS; % a set [2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6]
txInput.subcarriersNum = subcarriersNum;% 52 or 106 or 242
PacketSize = 200;
NumerologySel = [txInput.fftNum,txInput.CPratio,txInput.pilotInterval];
MCS_no = txInput.MCS;
[SysParameters,WaveformPara] = WaveformNumerologyCal(PacketSize,NumerologySel,MCS_no);
seed_set = [1 2 3];
rng(seed_set(1),'twister');
dataPacketBits = randi([0 1],WaveformPara.Payload,1);
scrData = TX_CRC32_Scramble(dataPacketBits);
trellis = poly2trellis(7,[171 133]);
tx_encoded_bit = convenc(scrData,trellis,WaveformPara.puncpat);
tx_padded_bit = [tx_encoded_bit;zeros(WaveformPara.DataPadding,1)];
%---------------------------------------------
dataMod = qammod(tx_padded_bit,WaveformPara.Mod,'InputType','bit');
WaveformPara.Power_sym = mean(abs(dataMod).^2);
dataMod = reshape(dataMod,WaveformPara.UsedSubcarrier,[]);
%% %
%
N_carriers = WaveformPara.N_FFT;
channel_response=sqrt(1/2)*(randn(1,N_carriers)+1i*randn(1,N_carriers));
N_windows = 8;
N_level = 10;
min_len_CP = 30;
CPset = Generate_CP(channel_response,N_windows,N_level,min_len_CP);
[serialOFDMsym,WaveformPara.pilot,serialFrameLen] = tx_FFTSymbolGen_PilotBlockPN(dataMod,WaveformPara,CPset);
WaveformPara.Power_sig = mean(abs(serialOFDMsym).^2);
[WaveformPara.preamble,WaveformPara.c1,WaveformPara.c2] = ...
generatePreamble(WaveformPara,WaveformPara.Power_sig);
%%
% load('preambleData.mat')
load('rxdata6normalizedzero.mat')
% A = 20*log10(abs(fft(rxSignal)));
% plot(A);
% rxSignal = rxSignal(5382:8680)';
% rxSignal = downsample(rxSignal, 2)';%data1 part
% rxSignal = rxSignal(5128:7889)';%data2 part
% rxSignal = rxSignal(4500+370:7000)';%data4 part
rxSignal = rxSignal(14000:17000)'/sqrt(mean(abs(rxSignal(14000:17000).^2)));
rxSignal=awgn(rxSignal,20,mean(abs(rxSignal.^2)));
% rxSignal = txSignalNormalized;
% [rxSignal_sync,SyncErr] = rxSyncSC(rxSignal,WaveformPara,myFrameLen);
[rxSignal_sync,MCS,PSDULength,failCheck,rec_frameNo,estNumerlogy,numeroError] = rx_preambleprocess(rxSignal);
rxSignal_sync = rxSignal_sync(1:serialFrameLen);
[rxDataModLs] = rx_PilotBlockChanEstForLabview(rxSignal_sync,WaveformPara,CPset); % CP
dataDemod = qamdemod(rxDataModLs,WaveformPara.Mod,'OutputType','approxllr', ...
'UnitAveragePower',false,'NoiseVariance',0.0243);%ChanPara.N0
dataDePadded = dataDemod(1:end - WaveformPara.DataPadding);
tb = 8;
decoded = vitdec(dataDePadded,trellis,tb,'trunc','unquant',WaveformPara.puncpat);
[rxBits,PER] = RX_CRC32_deScramble(decoded);%
[numErrors,BER] = biterr(dataPacketBits,rxBits);
%%
rxOutput.delaySpread = 0; % double
rxOutput.SNR = 0;% double
rxOutput.RSSI = 0;% double
rxOutput.BER = BER;% double
rxOutput.PER = PER;% double
rxOutput.EVM = 0;% double
rxOutput.phaseNoise = 0;% double
BER
PER
% SyncErr

BIN
WaveAdp/STS_M32Q16.mat Normal file

Binary file not shown.

68
WaveAdp/STS_demod.m Normal file
View File

@ -0,0 +1,68 @@
function [estNumerlogy,frmError] = STS_demod(rx_STF)
M=32;Q=16;OVR=1;
load STS_M32Q16.mat theta_mod v_mod STS_freq
STS_NUM = 9;
RX_re = reshape(rx_STF(17:end),[],STS_NUM);
STS_f = fftshift(fft(RX_re,16,1));
STS_freq_sk = STS_f([3:8,10:15],:);
theta_est = mod(angle(STS_freq_sk(2:end,:)./STS_freq_sk(1:end-1,:)),2*pi);
mmse_est = zeros(Q,STS_NUM);
for iii = 1:STS_NUM
for ii = 1:Q
mmse_tmp = abs(theta_est(:,iii)-theta_mod(ii,:).');
mmse_est(ii,iii) = norm(min([mmse_tmp,2*pi - mmse_tmp],[],2))^2;
end
end
mmse_est2 = sum(mmse_est,2);
v_est_no = find(mmse_est2==min(mmse_est2));
v_est = exp(j*v_mod(v_est_no(1)));
%%------demodulate phi
STS_freq_sk = STS_freq_sk./abs(STS_freq_sk);
% [~,STS_ref] = preamble_modu1(theta_mod(v_est_no(1),:), 0, OVR);
STS_ref = STS_freq(:,v_est_no(1),1);
STS_ref = STS_ref./abs(STS_ref);
phi_est_angle = mod(angle(sum(sum((STS_freq_sk(:,1:STS_NUM)./STS_ref)))),2*pi);
phi_est = exp(j*phi_est_angle);
% demap v and phi to Bits using pskmod
v_data_est = pskdemod(v_est,Q,0,'gray');
dePreambleQ = de2bi(v_data_est,log2(Q));
phi_data_est = pskdemod(phi_est,M,0,'gray');
dePreambleM = de2bi(phi_data_est,log2(M));
% CRC
poly = 'z4+z3+z2+z+1';
crcdetector = comm.CRCDetector(poly);
codeword = [dePreambleM,dePreambleQ];
[msg,frmError] = crcdetector(codeword.');
estNumerlogy = bi2de(msg.')+1;
end
%%
function [STS_time,STS_freq] = preamble_modu1(theta, phi, OVR)
% N_FFT =64;
s_k(1) = 1*exp(j*phi);
s_k(1) = sqrt(2)/abs(s_k(1))*s_k(1);
for i = 1:11
s_k(i+1) = s_k(i)*exp(j*theta(i));
end
STS_LOC = [9,13,17,21,25,29,37,41,45,49,53,57];
Short_preamble_slot_Frequency = zeros(1,64); % [1x64]
Short_preamble_slot_Frequency(STS_LOC) = s_k;
STS_freq = ifftshift(Short_preamble_slot_Frequency);
STS = ifft([STS_freq(1:32),zeros(1,64*(OVR-1)),STS_freq(33:64)])*sqrt(64);
STS = sqrt(1/mean(abs(STS).^2))*STS;
STS_f = fft(STS);
STS_f = [STS_f(1:32),STS_f((end-31:end))];
STS_freq = fftshift(STS_f);
STS_time = STS(1:16*OVR);
STS_freq = STS_freq(STS_LOC);
% STS_dpsk = mod(angle(STS_freq((2:end))./STS_freq((1:end-1))),2*pi);
% STS_dpsk(theta==0) = min([STS_dpsk(theta==0);2*pi - STS_dpsk(theta==0)],[],1);
end

28
WaveAdp/STS_modulation.m Normal file
View File

@ -0,0 +1,28 @@
function tx_STF = STS_modulation(Numerology)
% total 9bits 5 for Numerology 4 for crc
% input is the No. of Numerology 0~26
preamblebit = de2bi(Numerology-1,5);
% CRC
poly = 'z4+z3+z2+z+1';
crcgenerator = comm.CRCGenerator(poly);
codeword = crcgenerator(preamblebit.');
crccode = codeword(6:end).';
% preamble mod
M=32;Q=16;
theta0 = [0 0 0 pi 0 pi pi 0 pi pi pi];
phi_mod = [0:1/M*2*pi:2*pi-1/M*2*pi];
v_mod = [0:1/Q*2*pi:2*pi-1/Q*2*pi];
load STS_M32Q16.mat STS_mod
phi_data = pskmod(bi2de(preamblebit),M,0,'gray');% for M
v_data = pskmod(bi2de(crccode),Q,0,'gray');% for Q
[~,phi_no] = min(abs(phi_mod-mod(angle(phi_data),2*pi)));
[~,v_no] = min(abs(v_mod-mod(angle(v_data),2*pi)));
STF = STS_mod(:,v_no,phi_no);
tx_STF = repmat(STF,10,1);
end

110
WaveAdp/TX.m Normal file
View File

@ -0,0 +1,110 @@
%% TX for labview
clc;
close all;
clear ;
%%
userNum = 1;
fileType = 'text';
encryptMode = 'encryptMode';
antennasNum = 1;
centerFreq = 2450e6;
sendBandwidth = 5e6;
fftNum = 128;
CPratio = 0.25;
pilotInterval = 3;
% MCS_set=[2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6];% CHB3.19
MCS = [16,4];
subcarriersNum = 128; %
%%
txInput.userNum = userNum; % 1 or 2
txInput.fileType = fileType; % 'text' or 'picture'
txInput.encryptMode = encryptMode; % 'encrypt' or 'not encrypt'
txInput.antennasNum = antennasNum; % 1 or 2
txInput.centerFreq = centerFreq; % 500MHz~2.4G
txInput.sendBandwidth = sendBandwidth; % 20~40MHz
txInput.fftNum = fftNum;% 128 or 256 or 512
txInput.CPratio = CPratio; % 0.25 or 0.125 or 0.0625
txInput.pilotInterval = pilotInterval; % 3 5 7
txInput.MCS = MCS; % a set [2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6]
txInput.subcarriersNum = subcarriersNum;% 52 or 106 or 242
%%
TimeStamp = [];
FreqCarrier = txInput.centerFreq;%
Bandwidth = txInput.sendBandwidth;% 20~40e6
Ts = 1/Bandwidth;
% 仿
Delay_set = [1:20]*Ts;
Velocity_set = [5:250];
SNR_set = [0:5:35];
FrameNum = 1;
PacketSize = 200; %
% load NumerologySet.mat NumerologySet
% NumerologySel = NumerologySet(1,:); % 128 0.25 3 % N_FFT; CPratio; PilotInterval
NumerologySel = [txInput.fftNum,txInput.CPratio,txInput.pilotInterval];
MCS_no = txInput.MCS;
SNR = 25;
tau_d = Delay_set(randi([1 20]));
velocity = Velocity_set(randi([1 length(Velocity_set)]));
ChanPara = ChanStat(SNR, tau_d, velocity, Ts, FreqCarrier, TimeStamp);
% seed_set = randi([0 5000],FrameNum,3);
seed_set = [1 2 3];
[SysParameters,WaveformPara] = WaveformNumerologyCal(PacketSize,NumerologySel,MCS_no);
%% TX
rng(seed_set(1),'twister');
dataPacketBits = randi([0 1],WaveformPara.Payload,1);
scrData = TX_CRC32_Scramble(dataPacketBits);
trellis = poly2trellis(7,[171 133]);
tx_encoded_bit = convenc(scrData,trellis,WaveformPara.puncpat);
tx_padded_bit = [tx_encoded_bit;zeros(WaveformPara.DataPadding,1)];
%---------------------------------------------
dataMod = qammod(tx_padded_bit,WaveformPara.Mod,'InputType','bit');
WaveformPara.Power_sym = mean(abs(dataMod).^2);
dataMod = reshape(dataMod,WaveformPara.UsedSubcarrier,[]);
%% %
%
N_carriers = WaveformPara.N_FFT;
channel_response=sqrt(1/2)*(randn(1,N_carriers)+1i*randn(1,N_carriers));
%
N_windows = 8;
%
N_level = 10;
% CPCP>
min_len_CP = 30;
%
CPset = Generate_CP(channel_response,N_windows,N_level,min_len_CP);
%
[serialOFDMsym,WaveformPara.pilot,myFrameLen] = tx_FFTSymbolGen_PilotBlockPN(dataMod,WaveformPara,CPset); % CP
WaveformPara.Power_sig = mean(abs(serialOFDMsym).^2);
[WaveformPara.preamble,WaveformPara.c1,WaveformPara.c2] = ...
generatePreamble(WaveformPara,WaveformPara.Power_sig); % hb:
txSignal = [WaveformPara.preamble;serialOFDMsym];
txSignalNormalized = txSignal./max(abs(txSignal));
txOutput.sendSignal = txSignalNormalized;
%
txOutput.PAPR = 0;
%% Channel
% [rxSignal,ChanPara] = PassChan(txSignal,WaveformPara,SysParameters,ChanPara,seed_set(2));
% save('testInputDataForLabview.mat','rxSignal');
% SIR = InterfCal(rxSignal,ChanPara);
% A = 20*log10(abs(fft(txSignal)));
% plot(A);

View File

@ -0,0 +1,13 @@
function scrData = TX_CRC32_Scramble(dataPacketBits)
poly = [32,26,23,22,16,12,11,10,8,7,5,4,2,1,0];
crcGen32 = comm.CRCGenerator(...
'Polynomial', poly, ...
'InitialConditions', 1, ...
'DirectMethod', true, ...
'FinalXOR', 1);
dataPacket = crcGen32(dataPacketBits);
scrambler = comm.Scrambler(2,[1 0 0 0 0 0 1 0 1], ...
zeros(8,1));
scrData = scrambler(dataPacket);
end

130
WaveAdp/TX_forPreamble.m Normal file
View File

@ -0,0 +1,130 @@
%% TX for labview
clc;
close all;
clear ;
%%
userNum = 1;
fileType = 'text';
encryptMode = 'encryptMode';
antennasNum = 1;
centerFreq = 2450e6;
sendBandwidth = 5e6;
fftNum = 128;
CPratio = 0.25;
pilotInterval = 3;
% MCS_set=[2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6];% CHB3.19
MCS = [16,4];
subcarriersNum = 128; %
%%
txInput.userNum = userNum; % 1 or 2
txInput.fileType = fileType; % 'text' or 'picture'
txInput.encryptMode = encryptMode; % 'encrypt' or 'not encrypt'
txInput.antennasNum = antennasNum; % 1 or 2
txInput.centerFreq = centerFreq; % 500MHz~2.4G
txInput.sendBandwidth = sendBandwidth; % 20~40MHz
txInput.fftNum = fftNum;% 128 or 256 or 512
txInput.CPratio = CPratio; % 0.25 or 0.125 or 0.0625
txInput.pilotInterval = pilotInterval; % 3 5 7
txInput.MCS = MCS; % a set [2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6]
txInput.subcarriersNum = subcarriersNum;% 52 or 106 or 242
%%
TimeStamp = [];
FreqCarrier = txInput.centerFreq;%
Bandwidth = txInput.sendBandwidth;% 20~40e6
Ts = 1/Bandwidth;
% 仿
Delay_set = [1:20]*Ts;
Velocity_set = [5:250];
SNR_set = [0:5:35];
FrameNum = 1;
PacketSize = 200; %
% load NumerologySet.mat NumerologySet
% NumerologySel = NumerologySet(1,:); % 128 0.25 3 % N_FFT; CPratio; PilotInterval
NumerologySel = [txInput.fftNum,txInput.CPratio,txInput.pilotInterval];
MCS_no = txInput.MCS;
SNR = 25;
tau_d = Delay_set(randi([1 20]));
velocity = Velocity_set(randi([1 length(Velocity_set)]));
ChanPara = ChanStat(SNR, tau_d, velocity, Ts, FreqCarrier, TimeStamp);
% seed_set = randi([0 5000],FrameNum,3);
seed_set = [1 2 3];
[SysParameters,WaveformPara] = WaveformNumerologyCal(PacketSize,NumerologySel,MCS_no);
%% TX
rng(seed_set(1),'twister');
dataPacketBits = randi([0 1],WaveformPara.Payload,1);
scrData = TX_CRC32_Scramble(dataPacketBits);
trellis = poly2trellis(7,[171 133]);
tx_encoded_bit = convenc(scrData,trellis,WaveformPara.puncpat);
tx_padded_bit = [tx_encoded_bit;zeros(WaveformPara.DataPadding,1)];
%---------------------------------------------
dataMod = qammod(tx_padded_bit,WaveformPara.Mod,'InputType','bit');
WaveformPara.Power_sym = mean(abs(dataMod).^2);
dataMod = reshape(dataMod,WaveformPara.UsedSubcarrier,[]);
%% %
%
N_carriers = WaveformPara.N_FFT;
channel_response=sqrt(1/2)*(randn(1,N_carriers)+1i*randn(1,N_carriers));
%
N_windows = 8;
%
N_level = 10;
% CPCP>
min_len_CP = 30;
%
CPset = Generate_CP(channel_response,N_windows,N_level,min_len_CP);
%
[serialOFDMsym,WaveformPara.pilot,myFrameLen] = tx_FFTSymbolGen_PilotBlockPN(dataMod,WaveformPara,CPset); % CP
WaveformPara.Power_sig = mean(abs(serialOFDMsym).^2);
% [WaveformPara.preamble,WaveformPara.c1,WaveformPara.c2] = ...
% generatePreamble(WaveformPara,WaveformPara.Power_sig); % hb:
% txSignal = [WaveformPara.preamble;serialOFDMsym];
%% Parameter
NumerologyNo = 1; % 1~27
FrameNo = 7;
% MCS_No = 3;
cfg = wlanNonHTConfig('SignalChannelBandwidth',true, ...
'BandwidthOperation','Static');
% cfg.MCS = MCS_No;
PacketSize = 200;
cfg.PSDULength = PacketSize; %0-4095
%% preamble
tx_STF = STS_modulation(NumerologyNo); % STF
tx_LTF = wlanLLTF(cfg); % LTF
[tx_SIG, tx_sigdata] = newLSIG(cfg,FrameNo);% SIG
% load('cfg.mat')
txSignal = [zeros(500,1);tx_STF;tx_LTF;tx_SIG;serialOFDMsym];
txSignalNormalized = txSignal./max(abs(txSignal));
txOutput.sendSignal = txSignalNormalized;
%
txOutput.PAPR = 0;
%% Channel
[rxSignal,ChanPara] = PassChan(txSignal,WaveformPara,SysParameters,ChanPara,seed_set(2));
save('testInputDataForLabview.mat','rxSignal');
% SIR = InterfCal(rxSignal,ChanPara);
% A = 20*log10(abs(fft(txSignal)));
% plot(A);

68
WaveAdp/TestMAIN2022.m Normal file
View File

@ -0,0 +1,68 @@
%% -0318
% 2022.03.18
clear
%% Environment Scope
TimeStamp = [];
FreqCarrier = 2450e6;%
Bandwidth = 5e6;% 20~40e6
Ts = 1/Bandwidth;
% 仿
Delay_set = [1:20]*Ts;
Velocity_set = [5:250];
SNR_set = [0:5:35];
NodePair_num = 10;
load NumerologySet.mat NumerologySet
MCS_set=[2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6];
% isEncrypt = 1; % 1CP
% CP
% FFTCP
%% Action
FrameNum = 1;
PacketSize = 200; %
NumerologySel = NumerologySet(1,:); % 128 0.25 3 % N_FFT; CPratio; PilotInterval
MCS_no = MCS_set(7,:);
%%
seed_set = randi([0 5000],FrameNum,3);
SyncER_statis = zeros(NodePair_num,FrameNum);
BER_statis = zeros(NodePair_num,FrameNum);
PER_statis = zeros(NodePair_num,FrameNum);
SIR = zeros(NodePair_num,FrameNum);
for vv = 1:NodePair_num
%% Environment Parameterant
SNR = 25;
tau_d = Delay_set(randi([1 20]));
velocity = Velocity_set(randi([1 length(Velocity_set)]));
ChanPara = ChanStat(SNR, tau_d, velocity, Ts, FreqCarrier, TimeStamp);
%% Reward
for mont = 1:FrameNum
[BER_statis(vv,mont),PER_statis(vv,mont),SyncER_statis(vv,mont)] = ...
ExecutedMAIN0701(PacketSize, NumerologySel, MCS_no, ChanPara, FreqCarrier, mont, seed_set(mont,:));
end
end
%% TMP

View File

@ -0,0 +1,50 @@
function [SysParameters,WaveformPara] = WaveformNumerologyCal(PacketSize,NumerologySel,MCS_no)
%%
N_FFT = NumerologySel(1); CPratio = NumerologySel(2); PilotInterval = NumerologySel(3);
%%
SysParameters.ShowTiming =true;
SysParameters.ShowPAPR =false;
SysParameters.ShowFigure =true;
SysParameters.ShowPathGain =true;
SysParameters.SaveSimData =false;
WaveformPara.FrameType ='Data'; % ControlDataAudio
%
WaveformPara.PacketSize = PacketSize;
WaveformPara.Payload = WaveformPara.PacketSize*8;
WaveformPara.PayloadCRC = 32;
%--
WaveformPara.NullRatio = 1/4;
WaveformPara.N_FFT = N_FFT;
WaveformPara.CPratio = CPratio;
WaveformPara.PilotPattern = 'block';
WaveformPara.PilotInterval = PilotInterval;
WaveformPara.CP_Len = WaveformPara.N_FFT*WaveformPara.CPratio; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
WaveformPara.SymbolLen = WaveformPara.N_FFT*(WaveformPara.CPratio+1);
WaveformPara.UsedSubcarrier = (1-WaveformPara.NullRatio)*WaveformPara.N_FFT-1;
WaveformPara.NullSubcarrier = WaveformPara.NullRatio*WaveformPara.N_FFT;
%--
WaveformPara.Mod = MCS_no(1);
WaveformPara.Modulation = log2(WaveformPara.Mod);
WaveformPara.CodeRate = (MCS_no(2)-1)/MCS_no(2);
puncpat=[1,1,0,1,1,0,0,1,1,0];
WaveformPara.puncpat = puncpat(1:2*(MCS_no(2)-1));
%---------------------------------------------
WaveformPara.BitsPerSig = WaveformPara.UsedSubcarrier*WaveformPara.Modulation;
WaveformPara.DataFrame = ceil((WaveformPara.Payload+WaveformPara.PayloadCRC)/WaveformPara.CodeRate/WaveformPara.BitsPerSig);
WaveformPara.DataPadding = WaveformPara.DataFrame*WaveformPara.BitsPerSig - floor((WaveformPara.Payload+WaveformPara.PayloadCRC)/WaveformPara.CodeRate);
WaveformPara.PilotNum = ceil(WaveformPara.DataFrame/WaveformPara.PilotInterval);
WaveformPara.FrameSymNum = WaveformPara.DataFrame+WaveformPara.PilotNum;
WaveformPara.FrameConstelNum = WaveformPara.UsedSubcarrier * WaveformPara.DataFrame;
WaveformPara.FrameLen = WaveformPara.SymbolLen * WaveformPara.FrameSymNum;
WaveformPara.InterleavLen = 4080;
end

BIN
WaveAdp/cfg.mat Normal file

Binary file not shown.

View File

@ -0,0 +1,47 @@
function [preamble,c1,c2] = generatePreamble(WaveformPara,Power)
N = WaveformPara.N_FFT;
L = WaveformPara.CP_Len;
pnSequence = comm.PNSequence('Polynomial',[8 6 5 4 0], ...
'SamplesPerFrame',N,'InitialConditions',[0 0 0 0 0 0 0 1]);
pnSeq1 = pnSequence();
Modulator = comm.QPSKModulator;
dataInMatrix1 = reshape(pnSeq1,N/2,2);
dataSymbolsIn1 = bi2de(dataInMatrix1);
pnSeq1 = Modulator(dataSymbolsIn1);
c1 = sqrt(2)*kron(pnSeq1,[1,0]');
pnSequence = comm.PNSequence('Polynomial',[8 6 5 4 0], ...
'SamplesPerFrame',N,'InitialConditions',[0 1 0 0 0 0 0 1]);
pnSeq2 = pnSequence();
dataInMatrix2 = reshape(pnSeq2,N/2,2);
dataSymbolsIn2 = bi2de(dataInMatrix2);
pnSeq2 = Modulator(dataSymbolsIn2);
pnSequence = comm.PNSequence('Polynomial',[8 6 5 4 0], ...
'SamplesPerFrame',N,'InitialConditions',[1 1 0 0 1 0 0 1]);
pnSeq3 = pnSequence();
dataInMatrix3 = reshape(pnSeq3,N/2,2);
dataSymbolsIn3 = bi2de(dataInMatrix3);
pnSeq3 = Modulator(dataSymbolsIn3);
c2 = zeros(N,1);
c2(1:2:N-1) = pnSeq2;
c2(2:2:N) = pnSeq3;
ofdmSymbol = ifft(c1,N)*sqrt(N);
cp = ofdmSymbol(length(ofdmSymbol)-L+1:end);
trainingSym1 = [cp;ofdmSymbol];
ofdmSymbol = ifft(c2,N)*sqrt(N);
cp = ofdmSymbol(length(ofdmSymbol)-L+1:end);
trainingSym2 = [cp;ofdmSymbol];
preamble = sqrt(Power)/sqrt(2)*([trainingSym1;trainingSym2]);
end

View File

@ -0,0 +1,27 @@
function out = helperFrequencyOffset(in, fs, foffset)
%helperFrequencyOffset Apply a frequency offset to the input signal
%
% OUT = helperFrequencyOffset(IN, FS, FOFFSET) applies the specified
% frequency offset to the input signal.
%
% OUT is the frequency-offset output of the same size as IN.
% IN is the complex 2D array input.
% FS is the sampling rate in Hz (e.g. 80e6).
% FOFFSET is the frequency offset to apply to the input in Hz.
%
% See also comm.PhaseFrequencyOffset.
% Copyright 2015-2019 The MathWorks, Inc.
%#codegen
% Initialize output
out = complex(zeros(size(in)));
% Create vector of time samples
t = ((0:size(in,1)-1)/fs).';
% For each antenna, apply the frequency offset
for i = 1:size(in,2)
out(:,i) = in(:,i).*exp(1i*2*pi*foffset*t);
end

127
WaveAdp/mainForLabview.m Normal file
View File

@ -0,0 +1,127 @@
%% simulation for labview
clear;
clc;
TimeStamp = [];
FreqCarrier = 2450e6;%
Bandwidth = 5e6;% 20~40e6
Ts = 1/Bandwidth;
FrameNum = 1;
PacketSize = 200; %
load NumerologySet.mat NumerologySet
NumerologySel = NumerologySet(1,:); % 128 0.25 3 % N_FFT; CPratio; PilotInterval
MCS_set=[2,2;4,2;4,4;16,2;16,4;64,3;64,4;64,6];% CHB3.19;8
MCS_no = MCS_set(5,:);
% 仿
Delay_set = [1:20]*Ts;
Velocity_set = [5:250];
SNR_set = [0:5:35];
SNR = 25;
tau_d = Delay_set(randi([1 20]));
velocity = Velocity_set(randi([1 length(Velocity_set)]));
ChanPara = ChanStat(SNR, tau_d, velocity, Ts, FreqCarrier, TimeStamp);
seed_set = [1 2 3];
[SysParameters,WaveformPara] = WaveformNumerologyCal(PacketSize,NumerologySel,MCS_no);
%% TX
rng(seed_set(1),'twister');
dataPacketBits = randi([0 1],WaveformPara.Payload,1);
scrData = TX_CRC32_Scramble(dataPacketBits);
trellis = poly2trellis(7,[171 133]);
tx_encoded_bit = convenc(scrData,trellis,WaveformPara.puncpat);
tx_padded_bit = [tx_encoded_bit;zeros(WaveformPara.DataPadding,1)];
%---------------------------------------------
dataMod = qammod(tx_padded_bit,WaveformPara.Mod,'InputType','bit');
WaveformPara.Power_sym = mean(abs(dataMod).^2);
dataMod = reshape(dataMod,WaveformPara.UsedSubcarrier,[]);
%% %
%
N_carriers = WaveformPara.N_FFT;
channel_response=sqrt(1/2)*(randn(1,N_carriers)+1i*randn(1,N_carriers));
N_windows = 8;
N_level = 10;
min_len_CP = 30;
%
CPset = Generate_CP(channel_response,N_windows,N_level,min_len_CP);
%
[serialOFDMsym,WaveformPara.pilot,serialFrameLen,symbolNum] = tx_FFTSymbolGen_PilotBlockPN(dataMod,WaveformPara,CPset); % CP
WaveformPara.Power_sig = mean(abs(serialOFDMsym).^2);
serialOFDMsym = serialOFDMsym./max(abs(serialOFDMsym));
% [WaveformPara.preamble,WaveformPara.c1,WaveformPara.c2] = ...
% generatePreamble(WaveformPara,WaveformPara.Power_sig); % hb:
% txSignal = [WaveformPara.preamble;serialOFDMsym];
% RFSignal = RFimpairment(txSignal, FreqCarrier);
%% Parameter
NumerologyNo = 1; % 1~27
FrameNo = 7;
% MCS_No = 3;
% PacketSize = 200;
cfg = wlanNonHTConfig('SignalChannelBandwidth',true, ...
'BandwidthOperation','Static');
% cfg.MCS = MCS_No;
cfg.PSDULength = PacketSize; %0-4095
%% preamble
tx_STF = STS_modulation(NumerologyNo); % STF
tx_LTF = wlanLLTF(cfg); % LTF
[tx_SIG, tx_sigdata] = newLSIG(cfg,FrameNo);% SIG
% load('preambleData.mat')
txSignal = [tx_STF;tx_LTF;tx_SIG;serialOFDMsym];
txSignalNormalized = txSignal;
% A = 20*log10(abs(fft(txSignal)));
% plot(A);
%
%% Channel
% [rxSignal,ChanPara] = PassChan(txSignal,WaveformPara,SysParameters,ChanPara,seed_set(2));
len = 20000;
n = rand(len,1)+rand(len,1)*1i;
rxSignal = [n*0.1;txSignalNormalized];
% SIR = InterfCal(rxSignal,ChanPara);
%% RX
% [rxSignal_sync,SyncErr] = rxSyncSC(rxSignal,WaveformPara,serialFrameLen);
% process preamble
[rxSignal_sync,MCS,PSDULength,failCheck,rec_frameNo,estNumerlogy,numeroError] = rx_preambleprocess(rxSignal);
rxSignal_sync = rxSignal_sync(1:serialFrameLen);
[rxDataModLs] = rx_PilotBlockChanEst(rxSignal_sync,ChanPara,WaveformPara,CPset,symbolNum,SysParameters); % CP
dataDemod = qamdemod(rxDataModLs,WaveformPara.Mod,'OutputType','approxllr', ...
'UnitAveragePower',false,'NoiseVariance',0.0243);%ChanPara.N0
dataDePadded = dataDemod(1:end - WaveformPara.DataPadding);
tb = 8;
decoded = vitdec(dataDePadded,trellis,tb,'trunc','unquant',WaveformPara.puncpat);
[rx,PER] = RX_CRC32_deScramble(decoded); %
[numErrors,BER] = biterr(dataPacketBits,rx);
BER
PER
% SyncErr
%%

42
WaveAdp/newLSIG.m Normal file
View File

@ -0,0 +1,42 @@
function [y, bits] = newLSIG(cfgFormat,frameNo)
R = wlan.internal.nonHTRateSignalBits(cfgFormat.MCS);
length = cfgFormat.PSDULength;
% Construct the SIGNAL field. Length parameter with LSB first, which is 12 bits
lengthBits = de2bi(length,12,'right-msb').';
% Even parity bit
parityBit = mod(sum([R;lengthBits],1),2);
% :
frameNoBits = de2bi(frameNo,6,'right-msb').';
% The SIGNAL field (IEEE Std 802.11-2016, Section 17.3.4.2)
% bits = [R; 0; lengthBits; parityBit; zeros(6,1,'int8')];
bits = [R; 0; lengthBits; parityBit; frameNoBits];
% Process L-SIG bits
encodedBits = wlanBCCEncode(bits,'1/2');
interleavedBits = wlanBCCInterleave(encodedBits,'Non-HT',48);
modData = wlanConstellationMap(interleavedBits,1);
% Add pilot symbols, from IEEE Std 802.11-2016, Equation 19-14
Nsym = 1; % One symbol
z = 0; % No offset as first symbol is with pilots
modPilots = wlan.internal.nonHTPilots(Nsym,z);
% Map subcarriers and replicate over bandwidth
cfgOFDM = wlan.internal.wlanGetOFDMConfig(cfgFormat.ChannelBandwidth,'Long','Legacy');
sym = complex(zeros(cfgOFDM.FFTLength,1));
sym(cfgOFDM.DataIndices,1) = repmat(modData,cfgOFDM.NumSubchannels,1);
sym(cfgOFDM.PilotIndices,1) = repmat(modPilots,cfgOFDM.NumSubchannels,1);
% Apply gamma rotation, replicate over antennas and apply cyclic shifts
[lsig,scalingFactor] = wlan.internal.legacyFieldMap(sym,cfgOFDM.NumTones,cfgFormat);
% OFDM modulate
y = wlan.internal.wlanOFDMModulate(lsig,cfgOFDM.CyclicPrefixLength)*scalingFactor;
end

BIN
WaveAdp/preambleData.mat Normal file

Binary file not shown.

0
WaveAdp/rRemoveIFO.m Normal file
View File

97
WaveAdp/rxSyncSC.m Normal file
View File

@ -0,0 +1,97 @@
function [rxSignal,SyncErr] = rxSyncSC(rxSignal,WaveformPara,myFrameLen)
SyncErr = 0;
N = WaveformPara.N_FFT;
L = WaveformPara.CP_Len;
delay = 6000;
c1 = WaveformPara.c1;
c2 = WaveformPara.c2;
preamble = WaveformPara.preamble;
timing = estSymTiming(rxSignal,N,L);%%%%%%%%%
tshift = delay+L+1-timing;
if timing > WaveformPara.CP_Len+delay
SyncErr=1;
timing = delay+1;
end
rRemoveSTO = rxSignal(timing:end);%%%%%%%%%%%%%
phi = estFFO(rRemoveSTO,N,L);%%%%%%%%%%%%
rRemoveFFO = rRemoveSTO.*exp(-sqrt(-1)*2*pi*(1:length(rRemoveSTO))'*phi/N);
gEst = estIFO(rRemoveFFO,N,L,c1,c2);%%%%%%%%%%%
rRemoveIFO = rRemoveFFO.*exp(-sqrt(-1)*2*pi*(1:length(rRemoveFFO))'*(2*gEst)/N);
fshift = phi+2*gEst;
startWindow = length(preamble)-L+1;%%%%%%%%%%%%
% endWindow = startWindow+WaveformPara.FrameLen-1;%
endWindow = startWindow+myFrameLen-1;%
rxSignal = rRemoveIFO(startWindow:endWindow);
end
%% APPENDIX
function [timing,Mavg] = estSymTiming(r,N,L)
P = zeros(length(r)-2*N/2+1,1);
R = zeros(length(r)-2*N/2+1,1);
M = zeros(length(P),1);
for d = 1:length(M)
P(d) = (r(d:d+N/2-1))'*r(d+N/2:d+N-1);
R(d) = (r(d+N/2:d+N-1))'*r(d+N/2:d+N-1);
M(d) = (abs(P(d)))^2/(R(d))^2;
end
movavgWindow = dsp.MovingAverage(L-1);
Mavg = movavgWindow(M);
Mavg = Mavg(L/2:end);
[Mmax,timing] = max(Mavg);
timing=183;
figure
plot(M)
hold on;
plot(Mavg)
end
function gEst = estIFO(rRemoveFFO,N,L,c1,c2)
X = 1:2:N-1;
v = sqrt(2)*c2(X)./c1(X);
x1 = fft(rRemoveFFO(1:N))/sqrt(N);
x2 = fft(rRemoveFFO(1+N+L:2*N+L))/sqrt(N);
D = 2*(sum((abs(x2(X))).^2))^2;
gNum = N/2;
X1 = zeros(N,gNum);
X2 = zeros(N,gNum);
X1(:,1) = x1;
X2(:,1) = x2;
for i = 2:gNum
X1(:,i) = [X1(3:end,i-1);X1(1:2,i-1)];
X2(:,i) = [X2(3:end,i-1);X2(1:2,i-1)];
end
B = zeros(gNum,1);
for i = 1:gNum
B(i) = (abs(sum(...
conj(X1(X,i)).*conj(v).*X2(X,i)...
)))^2/D;
end
[Bmax,g] = max(B);
G = [0:N/4-1,-N/4:-1];
gEst = G(g);
end
function phi = estFFO(r,N,L)
P = sum(conj(r(1:N/2)).*r(N/2+1:2*N/2));
phi = angle(P)/pi;
end

View File

@ -0,0 +1,71 @@
function [rxDataModLs] = rx_PilotBlockChanEst(rAddAWGN,WaveformPara,CPset,SysParameters)
N = WaveformPara.N_FFT;
N_Used = WaveformPara.UsedSubcarrier;
L = WaveformPara.CP_Len;
m = WaveformPara.PilotNum;
pnSequence = comm.PNSequence('Polynomial',[8 6 5 4 0], ...
'SamplesPerFrame',WaveformPara.UsedSubcarrier,'InitialConditions',[0 0 0 0 0 0 0 1]);
WaveformPara.pilot = generatePilot(pnSequence,1);
pilot = WaveformPara.pilot;
% rxOFDMsym = reshape(rAddAWGN,WaveformPara.SymbolLen,WaveformPara.FrameSymNum);
% rxOFDMcore = rxOFDMsym(L+1:L+N,:); % CP
rxOFDMcore = [];
%
kk1=1;
for i = 1:length(CPset)
get_idx = kk1:(kk1 + N + CPset(i)-1);
currentSym = rAddAWGN(get_idx);
rxOFDMcore = [rxOFDMcore,currentSym(CPset(i)+1:end)];
kk1=kk1+(N+CPset(i));
end
rxDataModInMatrix = fft(rxOFDMcore,[],1)/sqrt(N);
rxDataModInMatrix_shift = [rxDataModInMatrix(2:2+(N_Used-1)/2-1,:);rxDataModInMatrix(end - (N_Used-1)/2:end,:)];
rxPilot = rxDataModInMatrix_shift(:,1:WaveformPara.PilotInterval+1:WaveformPara.FrameSymNum);
hLs = zeros(N_Used,m);
rxDataRemovPilot = zeros(N_Used,WaveformPara.DataFrame);
for i = 1:m-1
rxDataRemovPilot(:,(i-1)*WaveformPara.PilotInterval+1:i*(WaveformPara.PilotInterval)) = ...
rxDataModInMatrix_shift(:,(i-1)*(WaveformPara.PilotInterval+1)+2:i*(WaveformPara.PilotInterval+1));
hLs(:,i) = rxPilot(:,i)./pilot;
end
rxDataRemovPilot(:,(m-1)*WaveformPara.PilotInterval+1:end) = ...
rxDataModInMatrix_shift(:,(m-1)*(WaveformPara.PilotInterval+1)+2:end);
hLs(:,m) = rxPilot(:,m)./pilot;
if mod(WaveformPara.DataFrame,WaveformPara.PilotInterval)>0
hLs = [kron(hLs(:,1:m-1),ones(1,WaveformPara.PilotInterval)),kron(hLs(:,m),ones(1,mod(WaveformPara.DataFrame,WaveformPara.PilotInterval)))];
else
hLs = kron(hLs(:,1:m),ones(1,WaveformPara.PilotInterval));
end
eqDataModLs = zeros(N_Used,WaveformPara.DataFrame);
for i = 1:WaveformPara.DataFrame
eqDataModLs(:,i) = rxDataRemovPilot(:,i)./hLs(:,i);
end
rxDataModLs = reshape(eqDataModLs,[],1);
end
%%
function pilot = generatePilot(pnSequence,Power)
pilot = pnSequence();
bpskModulator = comm.BPSKModulator;
pilot = bpskModulator(pilot)*sqrt(Power);
end

View File

@ -0,0 +1,80 @@
function [rxDataModLs] = rx_PilotBlockChanEst_CPrand(rAddAWGN,ChanPara,WaveformPara,CPset,symbolNum,SysParameters)
N = WaveformPara.N_FFT;
N_Used = WaveformPara.UsedSubcarrier;
L = WaveformPara.CP_Len;
m = WaveformPara.PilotNum;
pilot = WaveformPara.pilot;
% rxOFDMsym = reshape(rAddAWGN,WaveformPara.SymbolLen,WaveformPara.FrameSymNum);
% rxOFDMcore = rxOFDMsym(L+1:L+N,:); % CP
rxOFDMcore = [];
%
kk1=1;
lenCPset = length(CPset);
if lenCPset<symbolNum
for i = 1:symbolNum
if i <= lenCPset
get_idx = kk1:(kk1 + N + CPset(i)-1);
currentSym = rAddAWGN(get_idx);
rxOFDMcore = [rxOFDMcore,currentSym(CPset(i)+1:end)];
kk1=kk1+(N+CPset(i));
else
get_idx = kk1:(kk1 + N + CPset(end)-1);
currentSym = rAddAWGN(get_idx);
rxOFDMcore = [rxOFDMcore,currentSym(CPset(end)+1:end)];
kk1=kk1+(N+CPset(end));
end
end
elseif lenCPset == symbolNum
for i = 1:symbolNum
get_idx = kk1:(kk1 + N + CPset(i)-1);
currentSym = rAddAWGN(get_idx);
rxOFDMcore = [rxOFDMcore,currentSym(CPset(i)+1:end)];
kk1=kk1+(N+CPset(i));
end
else
print('waiting for solve')
end
rxDataModInMatrix = fft(rxOFDMcore,[],1)/sqrt(N);
rxDataModInMatrix_shift = [rxDataModInMatrix(2:2+(N_Used-1)/2-1,:);rxDataModInMatrix(end - (N_Used-1)/2:end,:)];
rxPilot = rxDataModInMatrix_shift(:,1:WaveformPara.PilotInterval+1:WaveformPara.FrameSymNum);
hLs = zeros(N_Used,m);
rxDataRemovPilot = zeros(N_Used,WaveformPara.DataFrame);
for i = 1:m-1
rxDataRemovPilot(:,(i-1)*WaveformPara.PilotInterval+1:i*(WaveformPara.PilotInterval)) = ...
rxDataModInMatrix_shift(:,(i-1)*(WaveformPara.PilotInterval+1)+2:i*(WaveformPara.PilotInterval+1));
hLs(:,i) = rxPilot(:,i)./pilot;
end
rxDataRemovPilot(:,(m-1)*WaveformPara.PilotInterval+1:end) = ...
rxDataModInMatrix_shift(:,(m-1)*(WaveformPara.PilotInterval+1)+2:end);
hLs(:,m) = rxPilot(:,m)./pilot;
if mod(WaveformPara.DataFrame,WaveformPara.PilotInterval)>0
hLs = [kron(hLs(:,1:m-1),ones(1,WaveformPara.PilotInterval)),kron(hLs(:,m),ones(1,mod(WaveformPara.DataFrame,WaveformPara.PilotInterval)))];
else
hLs = kron(hLs(:,1:m),ones(1,WaveformPara.PilotInterval));
end
eqDataModLs = zeros(N_Used,WaveformPara.DataFrame);
for i = 1:WaveformPara.DataFrame
eqDataModLs(:,i) = rxDataRemovPilot(:,i)./hLs(:,i);
end
rxDataModLs = reshape(eqDataModLs,[],1);
end

View File

@ -0,0 +1,90 @@
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

BIN
WaveAdp/rxdata1.mat Normal file

Binary file not shown.

BIN
WaveAdp/rxdata2.mat Normal file

Binary file not shown.

BIN
WaveAdp/rxdata3preamble.mat Normal file

Binary file not shown.

BIN
WaveAdp/rxdata4preamble.mat Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

14
WaveAdp/temp.m Normal file
View File

@ -0,0 +1,14 @@
cfgNonHT = wlanNonHTConfig;
txWaveform = wlanWaveformGenerator([1;0;0;1],cfgNonHT,...
'WindowTransitionTime',0);
len = 30000;
n = rand(len,1)+rand(len,1)*1i;
rxWaveform = [n;txWaveform];
% 0.001*rand(100,1)
offset = 5;
threshold = 1-10*eps;
startOffset = wlanPacketDetect(rxWaveform,...
cfgNonHT.ChannelBandwidth,offset,threshold) ;
totalOffset = offset + startOffset

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,69 @@
function [serialOFDMsym,pilot,serialFrameLen,symbolNum] = tx_FFTSymbolGen_PilotBlockPN_CPrand(dataModInMatrix,WaveformPara,CPset,SysParameters)
numOfdmSymbol = WaveformPara.FrameSymNum;
N_used = WaveformPara.UsedSubcarrier;
CP_Len = WaveformPara.CP_Len;
pnSequence = comm.PNSequence('Polynomial',[8 6 5 4 0], ...
'SamplesPerFrame',N_used,'InitialConditions',[0 0 0 0 0 0 0 1]);
pilotPower = WaveformPara.Power_sym;
pilot = generatePilot(pnSequence,pilotPower);
m = WaveformPara.PilotNum-1;
dataModAddPilot = zeros(N_used,numOfdmSymbol);
for i = 1:m
dataModAddPilot(:,(i-1)*(WaveformPara.PilotInterval+1)+1:i*(WaveformPara.PilotInterval+1)) = ...
[pilot,dataModInMatrix(:,(i-1)*WaveformPara.PilotInterval+1:i*WaveformPara.PilotInterval)];
end
dataModAddPilot(:,m*(WaveformPara.PilotInterval+1)+1:end) = ...
[pilot,dataModInMatrix(:,m*WaveformPara.PilotInterval+1:end)];
dataModAddPilot_shift = [zeros(1,WaveformPara.FrameSymNum);...
dataModAddPilot(1:(N_used-1)/2,:);...
zeros(WaveformPara.NullSubcarrier,WaveformPara.FrameSymNum);...
dataModAddPilot(1+(N_used-1)/2:end,:)];
OFDMsym = ifft(dataModAddPilot_shift,[],1)*sqrt(WaveformPara.N_FFT);
[~,symNum]=size(OFDMsym);
serialOFDMsym = [];
lenCPset = length(CPset);
%
if lenCPset<symNum
for i = 1:symNum
if i <= lenCPset
serialOFDMsym = [serialOFDMsym; OFDMsym(WaveformPara.N_FFT-CPset(i)+1:end,i); OFDMsym(:,i)];
else
serialOFDMsym = [serialOFDMsym; OFDMsym(WaveformPara.N_FFT-CPset(end)+1:end,i); OFDMsym(:,i)];
end
end
elseif length(CPset) == symNum
for i = 1:symNum
serialOFDMsym = [serialOFDMsym; OFDMsym(WaveformPara.N_FFT-CPset(i)+1:end,i); OFDMsym(:,i)];
end
else
print('waiting for solve')
end
symbolNum = symNum;
serialFrameLen = length(serialOFDMsym);
% OFDMsymAddCP = [OFDMsym(WaveformPara.N_FFT-CP_Len+1:end,:);OFDMsym]; % CP
%
% serialOFDMsym = reshape(OFDMsymAddCP,[],1);
end
function pilot = generatePilot(pnSequence,Power)
pilot = pnSequence();
bpskModulator = comm.BPSKModulator;
pilot = bpskModulator(pilot)*sqrt(Power);
end

7
WaveAdp/说明.txt Normal file
View File

@ -0,0 +1,7 @@
纯仿真信道的代码:
mainForLabview
结合labview的代码
TX、RX使用的是滑动窗口的方法进行同步的
TX_forPreamble、RX_forPreamble使用的是802.11a的方法进行同步的。

223
bit2int.m Normal file
View File

@ -0,0 +1,223 @@
function y = bit2int(x, N, varargin)
%BIT2INT Convert bits to integers
%
% Y = BIT2INT(X,N) converts N column-wise bit elements in X to
% nonnegative integer values, with the first or the top-most bit
% being the MSB (most significant bit). X can be a column vector,
% matrix or an array with 3 dimensions. Number of rows in X must be
% an integer multiple of N. Y has same dimensions as X, except that
% the number of rows in Y are N times less than the number of rows in
% X. The datatype of X can be any of the built-in numeric types or
% logical. When the datatype of X is -
% - double or logical, datatype of Y is double.
% - single, datatype of Y is single.
% - a built-in integer type, Y has the same datatype as X unless the
% values in Y cannot be represented in that datatype without loss of
% data. If values in Y are larger than the intmax of the datatype of
% X, then Y is of the smallest datatype that can fit the values
% without loss of data. The datatype of Y has same signedness as that
% of X.
% - double or logical, N must be no larger than 53.
% - single, N must be no larger than 24.
% - a built-in signed integer type, N must be no larger than 63.
% - a built-in unsigned integer type, N must be no larger than 64.
%
% Y = BIT2INT(X,N,MSBFIRST) specifies MSB orientation in MSBFIRST.
% When MSBFIRST is true, the first bit in each set of N column-wise
% bits in X is the MSB; when MSBFIRST is false, the first bit in each
% set of N column-wise bits in X is the LSB (least significant bit).
%
% Y = BIT2INT(___,IsSigned=TF) specifies TF as a logical which can be
% either true or false to indicate the signed-ness of the integer.
% Default is false. When TF is true, then the first bit in each block
% of N bits is considered to be a signed bit and the output may
% contain negative values. If the datatype of X is any of the
% unsigned integer types with TF set to true, then the datatype of Y
% is the smallest signed integer type that can support the number of
% input bits.
%
% Examples:
%
% A1 = [1 0 1 0 1 0 1 0]';
% N1 = 8;
% B1 = bit2int(A1, N1);
%
% A2 = int8([1 1 0; 0 1 1]');
% N2 = 3;
% msbFirst = false;
% B2 = bit2int(A2, N2, msbFirst);
%
% A3 = randi([0,1], 32, 2, 2, 'uint8');
% N3 = 16;
% B3 = bit2int(A3, N3);
%
% A4 = [-110, 103, -103, 99];
% C4 = int2bit(A4,8);
% B4 = bit2int(C4,8,IsSigned=true);
%
% See also INT2BIT.
% Copyright 2021-2022 The MathWorks, Inc.
%#codegen
narginchk(2,5);
validateattributes(x, {'numeric','logical'}, {'3d','nonempty','binary'}, '', 'X');
if nargin == 2
MSBFirst = true;
IsSigned = false;
elseif nargin == 3
% If 3 inputs, then third argument must be MSBFirst option
IsSigned = false;
MSBFirst = varargin{1};
validateattributes(MSBFirst, {'logical','numeric'}, {'scalar','binary'}, '', 'MSBFirst');
else
% Then either 4 inputs with name-value is possible or 5 inputs with
% MSBFirst option and name-value of IsSigned is possible
if nargin == 4
signedOption = {varargin{1:2}}; % Codegen does not support cellarray(...). So use curly braces
MSBFirst = true;
else % nargin == 5
MSBFirst = varargin{1};
signedOption = {varargin{2:3}};
validateattributes(MSBFirst, {'logical','numeric'}, {'scalar','binary'}, '', 'MSBFirst');
end
defaults = struct("IsSigned",false);
res = comm.internal.utilities.nvParser(defaults, signedOption{:});
IsSigned = res.IsSigned;
validateattributes(IsSigned, {'logical','numeric'}, {'scalar','binary'}, '', 'IsSigned');
end
isSim = comm.internal.utilities.isSim();
if ~isSim
coder.internal.prefer_const(N);
end
isInputLogical = islogical(x);
% When N is equal to the max int supported (for example, N==8 for
% int8), -2^N calculation gives us -2^N + 1 because first 2^N gets
% calculated which cannot be fit into its native integer type (for
% example, int8 for N=8). To handle this corner case, subtract one
% after calculating negative value.
subone = false;
if isfloat(x) || isInputLogical
if isa(x, 'single')
maxN = 24;
else
maxN = 53;
end
validateattributes(N, {'numeric'}, {'scalar','positive','integer','<=',maxN}, '', 'N');
if isInputLogical
xNew = double(x);
isInputFloat = false;
else
xNew = x;
isInputFloat = true;
end
prototype = xNew(1);
else
% built-in integers
bitClass = class(x);
if bitClass(1) == 'u'
maxN = 64;
else
maxN = 63;
end
validateattributes(N, {'numeric'}, {'scalar','positive','integer','<=',maxN}, '', 'N');
coder.internal.errorIf(~isSim && ~coder.internal.isConst(N), ...
'comm:bit2int:NNotConst');
if bitClass(1) == 'u' && IsSigned
bitClassMax = intmax(bitClass(2:end));
else
bitClassMax = intmax(bitClass);
end
if IsSigned
c = '';
else
c = 'u';
end
if bitClass(1) == 'u' || IsSigned
if N <= 8
typeMax = intmax([c 'int8']);
subone = N==8;
elseif N <= 16
typeMax = intmax([c 'int16']);
subone = N==16;
elseif N <= 32
typeMax = intmax([c 'int32']);
subone = N==32;
else
typeMax = intmax([c 'int64']);
subone = N==64;
end
else
if N <= 7
typeMax = intmax('int8');
elseif N <= 15
typeMax = intmax('int16');
elseif N <= 31
typeMax = intmax('int32');
else
typeMax = intmax('int64');
end
end
if bitClassMax > typeMax
prototype = bitClassMax;
subone = false;
else
prototype = typeMax;
end
xNew = x;
isInputFloat = false;
end
useN = cast(N,'like',prototype);
if isInputFloat || (isSim && isInputLogical)
inSize = size(xNew);
nIntsPerCol = inSize(1)/double(N);
coder.internal.errorIf(nIntsPerCol ~= floor(nIntsPerCol), 'comm:bit2int:InvalidInputDims');
outSize = inSize;
outSize(1) = nIntsPerCol;
xMat = reshape(xNew, useN, []);
if MSBFirst
powOf2 = pow2(useN-1:-1:0);
powOf2(1) = (1-2*IsSigned)*powOf2(1);
else
powOf2 = pow2(0:useN-1);
powOf2(end) = (1-2*IsSigned)*powOf2(end);
end
y = reshape(powOf2 * xMat, outSize);
else
Nidx = coder.internal.indexInt(useN);
[nRows,nCols,nPages] = size(xNew);
nIntsPerCol = idivide(nRows, Nidx);
coder.internal.errorIf(Nidx*nIntsPerCol ~= nRows, ...
'comm:bit2int:InvalidInputDims');
y = coder.nullcopy(zeros(nIntsPerCol, nCols, nPages, 'like', prototype));
powOf2 = cast(2, 'like', y) .^ (useN-1:-1:0)';
powOf2(1) = (1-2*IsSigned)*powOf2(1)-1*subone*IsSigned;
xTmp = cast(xNew, 'like', y);
nInts = nIntsPerCol * coder.internal.indexInt(nCols) * coder.internal.indexInt(nPages);
if MSBFirst
idx = 1:Nidx;
else
idx = Nidx:-1:1;
end
for k=1:nInts
bits = xTmp(Nidx*(k-1) + idx);
y(k) = sum(bits(:) .* powOf2, 'native');
end
end
end

4
calculate_CDF.m Normal file
View File

@ -0,0 +1,4 @@
function [CDF] = calculate_CDF(data,PAPR_bin)
count = hist(data,PAPR_bin);
CDF = cumsum(count)/sum(count);
end

8
calculate_PAPR.m Normal file
View File

@ -0,0 +1,8 @@
function [PAPR_dex,Mean_Power] = calculate_PAPR(x)
% PAPR_dex PAPR
% Mean_Power
Signal_Power = abs(x).^2;
Peak_Power = max(Signal_Power,[],1); % norm(x,Inf)^2
Mean_Power = mean(Signal_Power,1); % norm(x,2)^2/(K*IF)
PAPR_dex = Peak_Power./Mean_Power;
end

28
channelSounding.m Normal file
View File

@ -0,0 +1,28 @@
function txNDP = channelSounding(cfg)
% NDP
guardInterval = 0.8;% Guard interval in Microseconds
cfgNDP = wlanHESUConfig('APEPLength',0,'GuardInterval',guardInterval); % No data in an NDP
cfgNDP.ChannelBandwidth = cfg.ChannelBandwidth;
cfgNDP.NumTransmitAntennas = cfg.numTx;
cfgNDP.NumSpaceTimeStreams = cfg.numTx;
txNDP = wlanWaveformGenerator([],cfgNDP);
% PN
soundingSeqMod_1 = zadoffChuSeq(29,255);
soundingSeqMod_2 = zadoffChuSeq(47,255);
% Concatenate multiple sequences to sound the channel periodically.
numSeq = 20; % Number of transmitted sequences in a WSS period
if cfg.numTx == 1
soundingSeqMod = [soundingSeqMod_1];
txSignal = repmat(soundingSeqMod,numSeq,1);
else
soundingSeqMod = [soundingSeqMod_1, soundingSeqMod_2];
txSignal = repmat(soundingSeqMod,numSeq,1);
end
% with 50 sample padding.
% txNDP = [txNDP; zeros(50,size(txNDP,2))];
txNDP = [txNDP; txSignal; zeros(50,size(txNDP,2))];
end

18
createMUMIMO.m Normal file
View File

@ -0,0 +1,18 @@
function cfgMUMIMO = createMUMIMO(Tx, CP, NumSpaceTimeStreams, MCS, APEPLength, numUsers)
numTx = Tx; % Number of transmit antennas
% MU-MIMO configuration - 4 users on one 242-tone RU
cfgMUMIMO = wlanHEMUConfig(191+numUsers);
guardInterval = CP; % Guard interval in Microseconds
% Configure common parameters for all users
cfgMUMIMO.NumTransmitAntennas = numTx;
cfgMUMIMO.GuardInterval = guardInterval;
% Configure per user parameters
for idx = 1:numUsers
cfgMUMIMO.User{idx}.NumSpaceTimeStreams = NumSpaceTimeStreams(idx);
cfgMUMIMO.User{idx}.MCS = MCS(idx);
cfgMUMIMO.User{idx}.APEPLength = APEPLength(idx);
end
end

219
demodSIG.m Normal file
View File

@ -0,0 +1,219 @@
%%
function [cfgRx,cfgUsers,rmsEVM,failCRC] = demodSIG(rx,rx_format,cfgUI)%% Packet Format Detection
%% L-LTF Channel Estimate
% Demodulate the L-LTF and perform channel estimation. The demodulated
% L-LTF symbols include tone rotation for each 20 MHz segment as described
% in [ <#16 2> ], section 21.3.7.5. The L-LTF channel estimates (with tone
% rotation) are used to equalize and decode the pre-HE-LTF fields.
lltfDemod = wlanHEDemodulate(rxLLTF,'L-LTF',chanBW);
lltfChanEst = wlanLLTFChannelEstimate(lltfDemod,chanBW);
%% L-SIG and RL-SIG Decoding
% The L-SIG field is used to determine the receive time, or RXTIME, of the
% packet. The RXTIME is calculated using the length bits of the L-SIG
% payload. The L-SIG and RL-SIG fields are recovered to perform the channel
% estimate on the extra subcarriers in the L-SIG and RL-SIG fields. The
% |lltfChanEst| channel estimates are updated to include the channel
% estimates on extra subcarriers in the L-SIG and RL-SIG fields. The L-SIG
% payload is decoded using an estimate of the channel and noise power
% obtained from the L-LTF field. The L-SIG length property in
% <matlab:edit('wlanHERecoveryConfig.m') wlanHERecoveryConfig> is updated after L-SIG decoding.
disp('Decoding L-SIG... ');
% Extract L-SIG and RL-SIG fields
rxLSIG = rx(pktOffset+(ind.LSIG(1):ind.RLSIG(2)),:);
% OFDM demodulate
helsigDemod = wlanHEDemodulate(rxLSIG,'L-SIG',chanBW);
% Estimate CPE and phase correct symbols
helsigDemod = preHECommonPhaseErrorTracking(helsigDemod,lltfChanEst,'L-SIG',chanBW);
% Estimate channel on extra 4 subcarriers per subchannel and create full
% channel estimate
preheInfo = wlanHEOFDMInfo('L-SIG',chanBW);
preHEChanEst = preHEChannelEstimate(helsigDemod,lltfChanEst,preheInfo.NumSubchannels);
% Average L-SIG and RL-SIG before equalization
helsigDemod = mean(helsigDemod,2);
% Equalize data carrying subcarriers, merging 20 MHz subchannels
[eqLSIGSym,csi] = preHESymbolEqualize(helsigDemod(preheInfo.DataIndices,:,:), ...
preHEChanEst(preheInfo.DataIndices,:,:),noiseVar,preheInfo.NumSubchannels);
% Decode L-SIG field
[~,failCheck,lsigInfo] = wlanLSIGBitRecover(eqLSIGSym,noiseVar,csi);
if failCheck
disp(' ** L-SIG check fail **');
else
disp(' L-SIG check pass');
end
% Get the length information from the recovered L-SIG bits and update the
% L-SIG length property of the recovery configuration object
lsigLength = lsigInfo.Length;
cfgRx.LSIGLength = lsigLength;
% Measure EVM of L-SIG symbols
EVM = comm.EVM;
EVM.ReferenceSignalSource = 'Estimated from reference constellation';
EVM.Normalization = 'Average constellation power';
EVM.ReferenceConstellation = wlanReferenceSymbols('BPSK');
rmsEVM = EVM(eqLSIGSym);
fprintf(' L-SIG EVM: %2.2fdB\n\n',20*log10(rmsEVM/100));
% Calculate the receive time and corresponding number of samples in the
% packet
RXTime = ceil((lsigLength + 3)/3) * 4 + 20; % In microseconds
numRxSamples = round(RXTime * 1e-6 * sr); % Number of samples in time
fprintf(' RXTIME: %dus\n',RXTime);
fprintf(' Number of samples in the packet: %d\n\n',numRxSamples);
%%
% The waveform and spectrum of the detected packet within |rx| is
% displayed given the calculated RXTIME and corresponding number of
% samples.
sampleOffset = max((-lstfLength + pktOffset),1); % First index to plot
sampleSpan = numRxSamples + 2*lstfLength; % Number samples to plot
% Plot as much of the packet (and extra samples) as we can
plotIdx = sampleOffset:min(sampleOffset + sampleSpan,rxWaveLen);
% Configure timeScope to display the packet
timeScope.TimeSpan = sampleSpan/sr;
timeScope.TimeDisplayOffset = sampleOffset/sr;
timeScope.YLimits = [0 max(abs(rx(:)))];
timeScope(abs(rx(plotIdx,:)));
release(timeScope);
% Display the spectrum of the detected packet
spectrumAnalyzer(rx(pktOffset + (1:numRxSamples),:));
release(spectrumAnalyzer);
%% HE-SIG-A Decoding
% The HE-SIG-A field contains the transmission configuration of an HE
% packet. An estimate of the channel and noise power obtained from the
% L-LTF is required to decode the HE-SIG-A field.
disp('Decoding HE-SIG-A...')
rxSIGA = rx(pktOffset+(ind.HESIGA(1):ind.HESIGA(2)),:);
sigaDemod = wlanHEDemodulate(rxSIGA,'HE-SIG-A',chanBW);
hesigaDemod = preHECommonPhaseErrorTracking(sigaDemod,preHEChanEst,'HE-SIG-A',chanBW);
% Equalize data carrying subcarriers, merging 20 MHz subchannels
preheInfo = wlanHEOFDMInfo('HE-SIG-A',chanBW);
[eqSIGASym,csi] = preHESymbolEqualize(hesigaDemod(preheInfo.DataIndices,:,:), ...
preHEChanEst(preheInfo.DataIndices,:,:), ...
noiseVar,preheInfo.NumSubchannels);
% Recover HE-SIG-A bits
[sigaBits,failCRC] = wlanHESIGABitRecover(eqSIGASym,noiseVar,csi);
% Perform the CRC on HE-SIG-A bits
if failCRC
disp(' ** HE-SIG-A CRC fail **');
else
disp(' HE-SIG-A CRC pass');
end
% Measure EVM of HE-SIG-A symbols
release(EVM);
if strcmp(pktFormat,'HE-EXT-SU')
% The second symbol of an HE-SIG-A field for an HE-EXT-SU packet is
% QBPSK.
EVM.ReferenceConstellation = wlanReferenceSymbols('BPSK',[0 pi/2 0 0]);
% Account for scaling of L-LTF for an HE-EXT-SU packet
rmsEVM = EVM(eqSIGASym*sqrt(2));
else
EVM.ReferenceConstellation = wlanReferenceSymbols('BPSK');
rmsEVM = EVM(eqSIGASym);
end
fprintf(' HE-SIG-A EVM: %2.2fdB\n\n',20*log10(mean(rmsEVM)/100));
%% Interpret Recovered HE-SIG-A bits
% The <matlab:edit('wlanHERecoveryConfig.m') wlanHERecoveryConfig> object
% is updated after interpreting the recovered HE-SIG-A bits.
cfgRx = interpretHESIGABits(cfgRx,sigaBits);
ind = wlanFieldIndices(cfgRx); % Update field indices
%%
% Display the common transmission configuration obtained from HE-SIG-A
% field for an HE-MU packet. The properties indicated by -1 are unknown or
% undefined. The unknown user-related properties are updated after
% successful decoding of the HE-SIG-B field.
disp(cfgRx)
%% HE-SIG-B Decoding
% For an HE-MU packet the HE-SIG-B field contains:
%
% * The RU allocation information for a non-compressed SIGB waveform is
% inferred from HE-SIG-B Common field [ <#16 1> Table. 27-23]. For a
% compressed SIGB waveform the RU allocation information is inferred from
% the recovered HE-SIG-A bits.
% * For a non-compressed SIGB waveform the number of HE-SIG-B symbols are
% updated in the <matlab:edit('wlanHERecoveryConfig.m') wlanHERecoveryConfig> object.
% The symbols are only updated if the number of HE-SIG-B symbols indicated
% in the HE-SIG-A field is set to 15 and all content channels pass the CRC.
% The number of HE-SIG-B symbols indicated in the HE-SIG-A field are not
% updated if any HE-SIG-B content channel fails the CRC.
% * The user transmission parameters for both SIGB compressed and
% non-compressed waveforms are inferred from the HE-SIG-B user field [ <#16 1>
% Table. 27-25, 27-26].
%
% An estimate of the channel and noise power obtained from the L-LTF is
% required to decode the HE-SIG-B field.
if strcmp(pktFormat,'HE-MU')
fprintf('Decoding HE-SIG-B...\n');
if ~cfgRx.SIGBCompression
fprintf(' Decoding HE-SIG-B common field...\n');
s = getSIGBLength(cfgRx);
% Get common field symbols. The start of HE-SIG-B field is known
rxSym = rx(pktOffset+(ind.HESIGA(2)+(1:s.NumSIGBCommonFieldSamples)),:);
% Decode HE-SIG-B common field
[status,cfgRx] = heSIGBCommonFieldDecode(rxSym,preHEChanEst,noiseVar,cfgRx);
% CRC on HE-SIG-B content channels
if strcmp(status,'Success')
fprintf(' HE-SIG-B (common field) CRC pass\n');
elseif strcmp(status,'ContentChannel1CRCFail')
fprintf(' ** HE-SIG-B CRC fail for content channel-1\n **');
elseif strcmp(status,'ContentChannel2CRCFail')
fprintf(' ** HE-SIG-B CRC fail for content channel-2\n **');
elseif any(strcmp(status,{'UnknownNumUsersContentChannel1','UnknownNumUsersContentChannel2'}))
error(' ** Unknown packet length, discard packet\n **');
else
% Discard the packet if all HE-SIG-B content channels fail
error(' ** HE-SIG-B CRC fail **');
end
% Update field indices as the number of HE-SIG-B symbols are
% updated
ind = wlanFieldIndices(cfgRx);
end
% Get complete HE-SIG-B field samples
rxSIGB = rx(pktOffset+(ind.HESIGB(1):ind.HESIGB(2)),:);
fprintf(' Decoding HE-SIG-B user field... \n');
% Decode HE-SIG-B user field
[failCRC,cfgUsers] = heSIGBUserFieldDecode(rxSIGB,preHEChanEst,noiseVar,cfgRx);
% CRC on HE-SIG-B users
if ~all(failCRC)
fprintf(' HE-SIG-B (user field) CRC pass\n\n');
numUsers = numel(cfgUsers);
elseif all(failCRC)
% Discard the packet if all users fail the CRC
error(' ** HE-SIG-B CRC fail for all users **');
else
fprintf(' ** HE-SIG-B CRC fail for at least one user\n **');
% Only process users with valid CRC
numUsers = numel(cfgUsers);
end
else % HE-SU, HE-EXT-SU
cfgUsers = {cfgRx};
numUsers = 1;
end
end

6
findPDF.m Normal file
View File

@ -0,0 +1,6 @@
function pdf = findPDF(range,data)
pdf = zeros(length(range)-1,1);
for i = 1:length(range)-1
pdf(i) = length(find(range(i) < data & data <= range(i+1)))/length(data);
end
end

4
findTemporalParameters.m Normal file
View File

@ -0,0 +1,4 @@
function [delay_average,delay_spread]=findTemporalParameters(PDP, T_sample, K)
delay_average = sum(PDP.*(0:K-1).'*T_sample)/sum(PDP);
delay_spread = sqrt(sum(PDP.*((0:K-1).'*T_sample-delay_average).^2)/sum(PDP));
end

32
heCPECorrection.m Normal file
View File

@ -0,0 +1,32 @@
function rx = heCPECorrection(rx,sigbPilots,chanEst,chanBW)
%heCPECorrection Estimate and correct common phase error
%
% RX = heCPECorrection(RX,SIGBPILOTS,CHANEST,CHANBW) returns the phase
% corrected OFDM symbols of HE-SIG-B field using the input, RX, HE-SIG-B
% pilot symbols, SIGBPILOTS, channel estimates, CHANEST, and channel
% bandwidth CHANBW.
%
% RX is a complex Nst-by-Nsym-by-Nr array containing the received OFDM
% symbols. Nst is the number of subcarriers and Nr is the number of
% receive antennas.
%
% SIGBPILOTS are the pilots symbols in the demodulated HE-SIG-B field.
%
% CHANEST is a complex Nst-by-1-by-Nr array containing the estimated
% channel at data and pilot subcarriers, where Nst is the number of
% occupied subcarriers and Nr is the number of receive antennas.
%
% CHANBW is a character vector or string. The allowed channel bandwidth
% are 'CBW20', 'CBW40', 'CBW80' and 'CBW160'.
% Copyright 2018 The MathWorks, Inc.
numSubchannels = wlan.internal.cbwStr2Num(chanBW)/20;
numBits = size(sigbPilots,2);
z = 4;
refPilots = repmat(wlan.internal.nonHTPilots(numBits, z),numSubchannels,1,1);
cpe = wlan.internal.commonPhaseErrorEstimate(sigbPilots,chanEst,refPilots);
rx = wlan.internal.commonPhaseErrorCorrect(rx,cpe);
end

View File

@ -0,0 +1,92 @@
function [y,cpe] = heCommonPhaseErrorTracking(x,chanEst,cfg,varargin)
%heCommonPhaseErrorTracking HE common pilot phase tracking
%
% [Y,CPE] = heCommonPhaseErrorTracking(X,CHANEST,CFGHE) performs common
% pilot error phase tracking of the single user HE format input X.
%
% Y is a complex Nst-by-Nsym-by-Nr array containing the common phase
% corrected OFDM symbols. Nst is the number of occupied subcarriers, Nsym
% is the number of symbols, and Nr is the number of receive antennas. Y
% is the common phase error corrected symbols.
%
% X is a complex Nst-by-Nsym-by-Nr array containing the received OFDM
% symbols.
%
% CHANEST is a complex Nst-by-Nsts-by-Nr array containing the channel
% gains for all active subcarriers, or a Nsp-by-Nsts-by-Nr array
% containing the channel gains for only pilot subcarriers. Nsts is the
% number of space-time streams.
%
% CFGHE is the format configuration object of type <a href="matlab:help('wlanHESUConfig')">wlanHESUConfig</a>,
% <a href="matlab:help('wlanHETBConfig')">wlanHETBConfig</a> or <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a>.
%
% [Y,CPE] = heCommonPhaseErrorTracking(X,CHANEST,CFGMU,RUNUMBER) performs
% common pilot error phase tracking of the multi-user HE format input X.
%
% CFGMU is the format configuration object of type <a href="matlab:help('wlanHEMUConfig')">wlanHEMUConfig</a>.
%
% RUNUMBER is the RU (resource unit) number.
% Copyright 2017-2019 The MathWorks, Inc.
%#codegen
validateattributes(cfg,{'wlanHESUConfig','wlanHEMUConfig','wlanHETBConfig','wlanHERecoveryConfig'},{'scalar'},mfilename,'format configuration object');
if isa(cfg,'wlanHERecoveryConfig')
pktFormat = cfg.PacketFormat;
if strcmp(pktFormat,'HE-MU')
numSpaceTimeStreamsPerRU = cfg.RUTotalSpaceTimeStreams;
s = getSIGBLength(cfg);
numHESIGB = s.NumSIGBSymbols;
else % SU or EXT_SU
numSpaceTimeStreamsPerRU = cfg.NumSpaceTimeStreams;
numHESIGB = 0;
end
ruIdx = cfg.RUIndex;
ruSize = cfg.RUSize;
else % wlanHESUConfig,wlanHEMUConfig,wlanHETBConfig
pktFormat = packetFormat(cfg);
allocInfo = ruInfo(cfg);
if strcmp(pktFormat,'HE-MU')
narginchk(4,4)
ruNumber = varargin{1};
sigbInfo = wlan.internal.heSIGBCodingInfo(cfg);
numHESIGB = sigbInfo.NumSymbols;
numSpaceTimeStreamsPerRU = allocInfo.NumSpaceTimeStreamsPerRU(ruNumber);
ruSize = allocInfo.RUSizes(ruNumber);
ruIdx = allocInfo.RUIndices(ruNumber);
else
% SU, EXT SU, TB
numHESIGB = 0;
ruIdx = allocInfo.RUIndices;
numSpaceTimeStreamsPerRU = allocInfo.NumSpaceTimeStreamsPerRU;
ruSize = allocInfo.RUSizes;
end
end
numOFDMSym = size(x,2);
n = (0:numOFDMSym-1);
if strcmp(pktFormat,'HE-EXT-SU')
numHESIGA = 4;
else % SU or MU
numHESIGA = 2;
end
z = 2+numHESIGA+numHESIGB; % Pilot symbol offset
refPilots = wlan.internal.hePilots(ruSize,numSpaceTimeStreamsPerRU,n,z);
% Estimate CPE and phase correct symbols
info = wlanHEOFDMInfo('HE-Data',cfg.ChannelBandwidth,cfg.GuardInterval,[ruSize ruIdx]);
if numel(info.PilotIndices)==size(chanEst,1)
% Assume channel estimate is only for pilots
chanEstPilots = chanEst;
else
% Otherwise extract pilots from channel estimate
chanEstPilots = chanEst(info.PilotIndices,:,:);
end
cpe = wlan.internal.commonPhaseErrorEstimate(x(info.PilotIndices,:,:),chanEstPilots,refPilots);
y = wlan.internal.commonPhaseErrorCorrect(x,cpe);
end

78
heEqualizeCombine.m Normal file
View File

@ -0,0 +1,78 @@
function [y,csi] = heEqualizeCombine(x,chanEst,nVar,cfg,varargin)
%heEqualizeCombine HE MIMO channel equalization and STBC combining
%
% [Y,CSI] = heEqualizeCombine(X,CHANEST,NOISEVAR,CFGHE) performs
% minimum-mean-square-error (MMSE) frequency domain equalization and
% optionally STBC combining using the signal input X, the channel
% estimate, CHANEST, and noise variance, NVAR.
%
% Y is an estimate of the transmitted frequency domain signal and is of
% size Nsd-by-Nsym-by-Nsts, where Nsd represents the number of carriers
% (frequency domain), Nsym represents the number of symbols (time
% domain), and Nsts represents the number of space-time streams (spatial
% domain). It is complex when either X or CHANEST is complex, or is real
% otherwise.
%
% CSI is a real matrix of size Nsd-by-Nsts containing the soft channel
% state information.
%
% X is a real or complex array containing the frequency domain signal to
% equalize. It is of size Nsd-by-Nsym-by-Nr, where Nr represents the
% number of receive antennas.
%
% CHANEST is a real or complex array containing the channel estimates for
% each carrier and symbol. It is of size Nsd-by-Nsts-by-Nr.
%
% NVAR is a nonnegative scalar representing the noise variance.
%
% CFGHE is the format configuration object of type <a href="matlab:help('wlanHESUConfig')">wlanHESUConfig</a>,
% <a href="matlab:help('wlanHETBConfig')">wlanHETBConfig</a> or <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a>.
%
% [Y,CSI] = heEqualizeCombine(X,CHANEST,NVAR,CFGMU,USERIDX) performs
% equalization of a HE multi user transmission. The user index is
% required to extract the space-time streams of interest for the user.
%
% CFGMU is the format configuration object of type <a href="matlab:help('wlanHEMUConfig')">wlanHEMUConfig</a> or,
% <a href="matlab:help('heTBSystemConfig')">heTBSystemConfig</a>, which specifies the parameters for multi user
% HE format and trigger-based (HT TB) system format configuration object
% respectively.
%
% USERIDX is the index of the user to decode within the RU.
% Copyright 2017-2019 The MathWorks, Inc.
%#codegen
validateattributes(cfg,{'wlanHESUConfig','wlanHEMUConfig','wlanHETBConfig','heTBSystemConfig','wlanHERecoveryConfig'},{'scalar'},mfilename,'format configuration object');
% Defaults
userIdx = 1;
if isa(cfg,'wlanHEMUConfig')
narginchk(5,5) % Require user index for multi-user reception
if nargin>4
userIdx = varargin{1};
end
% Get the indices of the space-time streams for this user
allSTSIdx = wlan.internal.heSpaceTimeStreamIndices(cfg);
stsIdx = allSTSIdx(1,userIdx):allSTSIdx(2,userIdx);
elseif isa(cfg,'wlanHERecoveryConfig') && strcmp(cfg.PacketFormat,'HE-MU')
% Get the indices of the space-time streams for this user
stsIdx = cfg.SpaceTimeStreamStartingIndex:(cfg.SpaceTimeStreamStartingIndex+cfg.NumSpaceTimeStreams-1);
else
stsIdx = 1; % For codegen
end
if cfg.STBC
% Only SU, get num of SS from size of channel estimate
nss = size(chanEst,2)/2;
[y,csi] = wlan.internal.wlanSTBCCombine(x,chanEst,nss,'MMSE',nVar);
else
% Equalize
[y,csi] = helperSymbolEqualize(x,chanEst,nVar);
if isa(cfg,'wlanHEMUConfig') || (isa(cfg,'wlanHERecoveryConfig') && strcmp(cfg.PacketFormat,'HE-MU'))
% Extract used STS
y = y(:,:,stsIdx);
csi = csi(:,stsIdx);
end
end
end

281
heLTFChannelEstimate.m Normal file
View File

@ -0,0 +1,281 @@
function [chanEstRU,varargout] = heLTFChannelEstimate(demodHELTFRU,cfg,varargin)
%heLTFChannelEstimate Channel estimation using HE-LTF
% CHANESTRU = heLTFChannelEstimate(RXSYM,CFGHE) returns the estimated
% channel between all space-time streams and receive antennas using
% HE-LTF of an HE single user, extended range single user, multi-user or
% trigger-based (HE TB) packet. The channel estimate includes the
% effect of the applied spatial mapping matrix and cyclic shifts at the
% transmitter. If HE-LTF compression is used, linear interpolation is
% performed to create a channel estimate for all subcarriers.
%
% CHANESTRU is an array characterizing the estimated channel for the data
% and pilot subcarriers. EST is a complex Nst-by-Nsts-by-Nr array
% characterizing the estimated channel for the data and pilot
% subcarriers, where Nst is the number of occupied subcarriers, Nsts is
% the total number of space-time streams, and Nr is the number of receive
% antennas. If CFGHE is a MU configuration, then the channel estimate for
% all RUs is returned.
%
% RXSYM is a complex Nst-by-Nsym-by-Nr array containing demodulated
% concatenated HE-LTF. Nsym is the number of demodulated HE-LTF symbols.
%
% CFGHE is a format configuration object of type <a href="matlab:help('wlanHESUConfig')">wlanHESUConfig</a>
% <a href="matlab:help('wlanHEMUConfig')">wlanHEMUConfig</a>, <a href="matlab:help('wlanHETBConfig')">wlanHETBConfig</a>, <a href="matlab:help('heTBSystemConfig')">heTBSystemConfig</a> or <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a>.
%
% CHANESTRU = heLTFChannelEstimate(RXSYM,CFGMU,RUOFINTEREST) returns the
% channel estimate for the RU of interest index RUOFINTEREST for a
% multi-user configuration. CFGMU is of type <a href="matlab:help('wlanHEMUConfig')">wlanHEMUConfig</a> or
% <a href="matlab:help('heTBSystemConfig')">heTBSystemConfig</a>. If not provided the default is 1.
%
% [...,CHANESTSSPILOTS] = heLTFChannelEstimate(...) additionally returns
% a Nsp-by-Nsym-by-Nr array characterizing the estimated channel for
% pilot subcarrier locations for each symbol, assuming one space-time
% stream at the transmitter.
%
% Examples:
% % Decode the HE data field for each user in and OFDMA and MU-MIMO
% % transmission with a fading channel model. Estimate the channel for
% % each user.
%
% % Create packet configuration
% allocationIndex = [192 193]; % Two 242 RUs, the second with 2 users
% cfg = wlanHEMUConfig(allocationIndex);
% cfg.NumTransmitAntennas = 2;
% cfg.User{1}.NumSpaceTimeStreams = 2;
%
% % Generate MU waveform
% txWaveform = wlanWaveformGenerator([1;0;0;1],cfg);
%
% % Channel and receiver per user
% ind = wlanFieldIndices(cfg);
% allocationInfo = ruInfo(cfg);
% for ruIdx = 1:allocationInfo.NumRUs
% for userIdx = 1:allocationInfo.NumUsersPerRU(ruIdx)
% % Add channel and noise
% snr = 20;
% channel = wlanTGaxChannel;
% channel.NumTransmitAntennas = 2;
% channel.NumReceiveAntennas = 2;
% channel.SampleRate = wlanSampleRate(cfg);
% rxWaveform = awgn(channel([txWaveform; zeros(10,2)]),snr);
%
% % Synchronize
% rxWaveform = rxWaveform(1+4:end,:);
%
% % Extract and OFDM demodulate the HE-LTF for the RU of
% % interest
% rxHETLF = rxWaveform(ind.HELTF(1): ind.HELTF(2),:);
% demodHELTF = wlanHEDemodulate(rxHETLF,'HE-LTF',cfg,ruIdx);
%
% % Channel estimate for RU of interest
% chanEst = heLTFChannelEstimate(demodHELTF,cfg,ruIdx);
%
% % Extract and OFDM demodulate the data field for the RU of
% % interest
% rxData = rxWaveform(ind.HEData(1):ind.HEData(2),:);
% demodData = wlanHEDemodulate(rxData,'HE-Data',cfg,ruIdx);
%
% % Equalize data symbols - extract the space-time streams for
% % the user of interest after equalization
% nVar = 10^-(snr/10);
% [eqSym,csi] = heEqualizeCombine(demodData,chanEst,nVar, ...
% cfg,userIdx);
%
% % Discard pilot carriers and decode
% info = wlanHEOFDMInfo('HE-Data',cfg,ruIdx);
% rxBits = wlanHEDataBitRecover(eqSym(info.DataIndices,:,:), ...
% nVar,csi(info.DataIndices,:),cfg,userIdx);
% end
% end
% Copyright 2017-2019 The MathWorks, Inc.
%#codegen
if nargin>2
ruOfInterest = varargin{1};
else
ruOfInterest = 1;
end
% Validate the format configuration object is a valid type
validateattributes(cfg,{'wlanHESUConfig','wlanHEMUConfig','wlanHETBConfig','heTBSystemConfig','wlanHERecoveryConfig'},{'scalar'},mfilename,'format configuration object');
% Get allocation information
if isa(cfg,'wlanHERecoveryConfig')
ruSizeRU = cfg.RUSize;
ruIndexRU = cfg.RUIndex;
pktFormat = cfg.PacketFormat;
if strcmp(pktFormat,'HE-MU')
numSTSRU = cfg.RUTotalSpaceTimeStreams;
else % SU, EXT SU
numSTSRU = cfg.NumSpaceTimeStreams;
end
else
allocInfo = ruInfo(cfg);
coder.internal.errorIf(ruOfInterest>allocInfo.NumRUs,'wlan:he:InvalidRUOfInterest',ruOfInterest,allocInfo.NumRUs);
ruSizeRU = allocInfo.RUSizes(ruOfInterest);
ruIndexRU = allocInfo.RUIndices(ruOfInterest);
numSTSRU = allocInfo.NumSpaceTimeStreamsPerRU(ruOfInterest);
pktFormat = packetFormat(cfg);
end
% Validate symbol type
validateattributes(demodHELTFRU,{'single','double'},{'3d'},mfilename,'HE-LTF OFDM symbol(s)');
[numST,numLTF,numRx] = size(demodHELTFRU);
tac = wlan.internal.heRUToneAllocationConstants(ruSizeRU);
coder.internal.errorIf(numST~=tac.NST,'wlan:wlanChannelEstimate:IncorrectNumSC',tac.NST,numST);
ofdmInfo = wlanHEOFDMInfo('HE-LTF',cfg.ChannelBandwidth,cfg.GuardInterval,[ruSizeRU ruIndexRU]);
if numLTF==0
chanEstRU = zeros(numST,numSTSRU,numRx);
varargout{1} = zeros(numel(ofdmInfo.PilotIndices),numLTF,numRx); % For codegen
return;
end
minNumLTF = wlan.internal.numVHTLTFSymbols(numSTSRU);
coder.internal.errorIf(numLTF<minNumLTF,'wlan:he:InvalidNumLTF',numLTF,minNumLTF);
% Get the HE-LTF sequence
cbw = wlan.internal.cbwStr2Num(cfg.ChannelBandwidth);
[HELTF,kHELTFSeq] = wlan.internal.heLTFSequence(cbw,cfg.HELTFType);
% Extract the RU of interest from the full-bandwidth HELTF
kRU = ofdmInfo.ActiveFrequencyIndices;
[~,ruIdx] = intersect(kHELTFSeq,kRU);
HELTFRU = HELTF(ruIdx);
switch cfg.HELTFType
% IEEE P802.11ax/D4.1, Equation 27-52
case 1
N_HE_LTF_Mode = 4; % undefined
case 2
N_HE_LTF_Mode = 2;
otherwise % 4
N_HE_LTF_Mode = 1;
end
isaTBConfig = isa(cfg,'heTBSystemConfig') || isa(cfg,'wlanHETBConfig');
if numSTSRU==1
% Single STS
% When more than one LTF we can average over the LTFs for data and
% pilots to improve the estimate. As there is only one space-time
% stream, the pilots and data essentially both use the P matrix which
% does not change per space-time stream (only per symbol), therefore
% this "MIMO" estimate performs the averaging of the number of symbols.
chanEstRU = wlan.internal.mimoChannelEstimate(demodHELTFRU,HELTFRU,numSTSRU);
% Remove orthogonal sequence across subcarriers (if used)
if isaTBConfig && cfg.SingleStreamPilots==false
chanEstRU = removeOrthogonalSequence(chanEstRU,numSTSRU,kRU,N_HE_LTF_Mode);
end
% Interpolate if HE-LTF compression used
if N_HE_LTF_Mode>1
chanEstRU = chanEstInterp(chanEstRU,cbw,N_HE_LTF_Mode,ruSizeRU,ruIndexRU);
end
else
% MIMO channel estimation as per Perahia, Eldad, and Robert Stacey.
% Next Generation Wireless LANs: 802.11 n and 802.11 ac. Cambridge
% University Press, 2013, page 100, Equation 4.39.
% Remove orthogonal sequence across subcarriers (if used)
if isaTBConfig && cfg.SingleStreamPilots==false
% Only perform channel estimate for non-pilot subcarriers as pilots
% are single stream
kMIMO = kRU; % All subcarriers MIMO estimates
mimoInd = 1:numST;
chanEstRUMIMO = wlan.internal.mimoChannelEstimate(demodHELTFRU,HELTFRU,numSTSRU);
chanEstRUMIMO = removeOrthogonalSequence(chanEstRUMIMO,numSTSRU,kRU,N_HE_LTF_Mode);
else
% Only perform channel estimate for non-pilot subcarriers as pilots
% are single stream
mimoInd = ofdmInfo.DataIndices;
kMIMO = kRU(mimoInd); % Only data subcarriers MIMO estimates
chanEstRUMIMO = wlan.internal.mimoChannelEstimate(demodHELTFRU(ofdmInfo.DataIndices,:,:),HELTFRU(mimoInd),numSTSRU);
end
% Undo cyclic shift for each STS before averaging and interpolation
nfft = (cbw/20)*256;
numSTSTotal = size(chanEstRUMIMO,2);
csh = wlan.internal.getCyclicShiftVal('VHT',numSTSTotal,cbw);
chanEstRUMIMO = wlan.internal.cyclicShiftChannelEstimate(chanEstRUMIMO,-csh,nfft,kMIMO);
% Interpolate over pilot locations, and any compressed subcarriers
chanEstRU = chanEstInterp(chanEstRUMIMO,cbw,N_HE_LTF_Mode,ruSizeRU,ruIndexRU,mimoInd);
% Re-apply cyclic shift after interpolation
chanEstRU = wlan.internal.cyclicShiftChannelEstimate(chanEstRU,csh,nfft,kRU);
end
% If extended range SU, then the HE-LTF are boosted by sqrt(2). If we
% don't remove this at demodulation then we must de-scale the channel
% estimate as the data field is not scaled.
if strcmp(pktFormat,'HE-EXT-SU')
eta = 1/sqrt(2);
else
eta = 1;
end
chanEstRU = chanEstRU*eta; % Scale for HE-EXT-SU
% Channel estimate for pilots
if nargout>1
if isaTBConfig && cfg.SingleStreamPilots==false
% Create single stream from MIMO pilot estimates by summing across
% space-time streams (2nd dimension)
varargout{1} = sum(chanEstRU(ofdmInfo.PilotIndices,:,:),2);
else
% Channel estimate for single-stream pilots
Pheltf = wlan.internal.mappingMatrix(numLTF);
R = Pheltf(1,1:numLTF); % R matrix changes pilot polarity per symbol
% Estimate the channel at pilot subcarriers accounting for polarity
chanEstSSPilots = bsxfun(@rdivide,demodHELTFRU(ofdmInfo.PilotIndices,:,:),bsxfun(@times,HELTFRU(ofdmInfo.PilotIndices),R));
varargout{1} = chanEstSSPilots*eta; % Scale for HE_EXT_SU
end
end
end
function chanEstRUInterp = chanEstInterp(chanEstRU,cbw,N_HE_LTF_Mode,ruSize,ruIndex,varargin)
% Interpolate over pilot locations and compressed subcarriers
Nfft = 256*cbw/20;
% Get the subcarrier indices within the FFT for the channel estimate
% input
kAct = wlan.internal.heRUSubcarrierIndices(cbw,ruSize,ruIndex)+Nfft/2+1;
% If the channelEstRU is not the entire RU, then we need to make sure
% we know the subcarrier indices, so use the ruInd input. For example
% this allows us to pass in only the data subcarriers.
if nargin>5
ruInd = varargin{1};
kChanEstInputs = kAct(ruInd);
else
% Assume chanEstRU is the whole RU
kChanEstInputs = kAct;
end
% Get the indices within the FFT which contain actual estimates
% (excluding the guard bands). This is how the pattern is structured
kAll = 1:N_HE_LTF_Mode:Nfft;
% Find the subcarrier indices within the FFT which contain actual data
% within the channel estimate input (kToInterp) and the indices of
% these within the chanEstDataRU input array (toInterpInd)
[kToInterp,toInterpInd] = intersect(kChanEstInputs,kAll);
% Interpolate and extrapolate over all RU subcarrier indices to
% interpolate over compressed region and pilots
magPart = interp1(kToInterp.',abs(chanEstRU(toInterpInd,:,:)),kAct,'linear','extrap');
phasePart = interp1(kToInterp.',unwrap(angle(chanEstRU(toInterpInd,:,:))),kAct,'linear','extrap');
[realPart,imagPart] = pol2cart(phasePart,magPart);
chanEstRUInterp = complex(realPart,imagPart);
end
function chanEstRUData = removeOrthogonalSequence(chanEstRUData,numSTSRU,k,N_HE_LTF_Mode)
% Remove the orthogonal sequence across subcarriers
M = 0; % Assume space-time streams of all users in estimate
m = 1:numSTSRU;
Pheltf = wlan.internal.mappingMatrix(8);
seq = Pheltf(M+m,mod(ceil(k/N_HE_LTF_Mode)-1,8)+1).'; % Nsts-by-Nst
chanEstRUData = chanEstRUData./seq;
end

View File

@ -0,0 +1,115 @@
function steeringMatBF = heMUCalculateSteeringMatrix(steeringMatFB,cfg,cfgNDP,ruIdx)
%heMUCalculateSteeringMatrix Calculate beamforming steering matrix
%
% Note: This is an internal undocumented function and its API and/or
% functionality may change in subsequent releases.
%
% STEERINGMATBF = heMUCalculateSteeringMatrix(STEERINGMATFB,CFG,CFGNDP,RUIDX)
% returns the steering matrix recommended to beamform an RU in a transmit
% beamforming, or MU-MIMO configuration. ZF precoding is used.
%
% STEERINGMATFB is a cell array containing the steering matrices fed-back
% by each user in the RU to beamform.
%
% CFG is the configuration of the HE-MU transmission and is a format
% configuration object of type
% <a href="matlab:help('wlanHEMUConfig')">wlanHEMUConfig</a>.
%
% CFGNDP is the configuration of the HE-NDP used to gather feedback and
% is a format configuration object of type
% <a href="matlab:help('wlanHESUConfig')">wlanHESUConfig</a>.
%
% RUIDX is the RU index.
% Copyright 2018 The MathWorks, Inc.
allocInfo = ruInfo(cfg);
% Indices of active subcarriers within the RU
ruOFDMInfo = wlanHEOFDMInfo('HE-Data',cfg,ruIdx);
ruInd = ruOFDMInfo.ActiveFrequencyIndices;
% Indices of active subcarriers in the NDP
ndpOFDMInfo = wlanHEOFDMInfo('HE-Data',cfgNDP);
trainingInd = ndpOFDMInfo.ActiveFrequencyIndices;
% Get the indices which overlap - use to extract from NDP
[~,scUseInd] = intersect(trainingInd,ruInd);
% Extract the RU of interest from the full bandwidth grid
numUsers = allocInfo.NumUsersPerRU(ruIdx);
steeringMatUse = cell(numUsers,1);
for i = 1:numUsers
% Only take the RU subcarriers and space-time streams of
% interest for the current RU and user
userIdx = cfg.RU{ruIdx}.UserNumbers(i);
numSTS = cfg.User{userIdx}.NumSpaceTimeStreams;
numRx = size(steeringMatFB{userIdx},2);
if numSTS>numRx
error('The number of space-time streams (%d) exceeds the number of receive antennas (%d) for user %d',numSTS,numRx,userIdx);
end
steeringMatUse{i} = steeringMatFB{userIdx}(scUseInd,1:numSTS,:);
end
% Extract steering matrix for each RU
if numUsers>1
steeringMatBF = muSteeringMatrixFromFeedback(steeringMatUse);
else
steeringMatBF = steeringMatUse{1};
end
end
function steeringMatrix = muSteeringMatrixFromFeedback(mappingMatrix,varargin)
% Q = muSteeringMatrixFromFeedback(QU) calculates the spatial mapping
% matrix for a MU transmission using the ZF algorithm.
%
% Q is an Nst-by-Nsts-by-Nt mapping matrix. Nst is the number of
% subcarriers, Nsts is the total number of space-time streams, and Nt is
% the number of transmit antennas.
%
% QU is a cell array containing the individual mapping matrix for each
% user. Each element of QU is sized Nst-by-Nstsu-by-Nt, where Nstsu is
% the number of space-time streams for the individual user.
%
% Q = muSteeringMatrixFromFeedback(QU,SNR) calculates the spatial mapping
% matrix for a MU transmission using the MMSE algorithm given the SNR.
if nargin>1
precodingType = 'MMSE';
snr = varargin{1};
else
precodingType = 'ZF';
end
numUsers = numel(mappingMatrix);
% Get the number of STS per user
numSTS = zeros(numUsers,1);
for uIdx = 1:numUsers
numSTS(uIdx) = size(mappingMatrix{uIdx},2);
end
numSTSTotal = sum(numSTS);
% Pack the per user CSI into a matrix
[numST,~,numTx] = size(mappingMatrix{1}); % Number of subcarriers
steeringMatrix = zeros(numST,numTx,numSTSTotal); % Nst-by-Nt-by-Nsts
for uIdx = 1:numUsers
stsIdx = sum(numSTS(1:uIdx-1))+(1:numSTS(uIdx));
steeringMatrix(:,:,stsIdx) = permute(mappingMatrix{uIdx},[1 3 2]); % Nst-by-Nt-by-Nsts
end
% Zero-forcing or MMSE precoding solution
if strcmp(precodingType, 'ZF')
delta = 0; % Zero-forcing
else
delta = (numTx/(10^(snr/10))) * eye(numTx); % MMSE
end
for i = 1:numST
% Channel inversion precoding
h = squeeze(steeringMatrix(i,:,:));
steeringMatrix(i,:,:) = h/(h'*h + delta);
end
steeringMatrix = permute(steeringMatrix,[1 3 2]);
end

373
heMURx.m Normal file
View File

@ -0,0 +1,373 @@
function [rxPSDU,bitErrorRate,eqSymPlot,evm] = heMURx(rx,cfg,userIdx,frameIdx,rxPSDU,cfgUI,SEED,bitErrorRate,eqSymPlot)
% [rxPSDU,eqSymUser,csiData/csi,pktFormat,evm,cfoCorrection]=heMURx(rx,cfgMUMIMO,userIdx,cfgPara);
% numBitError = 0;
% wlan ug
%% Setup Waveform Recovery Parameters
% Perform synchronization with 11ac components
chanBW = cfg.ChannelBandwidth;
fs = wlanSampleRate(cfg);
% Specify pilot tracking method for recovering the data field. This can be:
% 'Joint' - use joint common phase error and sample rate offset tracking
% 'CPE' - use only common phase error tracking
% When recovering 26-tone RUs only CPE tracking is used as the joint
% tracking algorithm is susceptible to noise.
pilotTracking = 'Joint';
% Create an HE recovery configuration object and set the channel bandwidth
cfgRx = wlanHERecoveryConfig;
cfgRx.ChannelBandwidth = chanBW;
% Get the field indices for extract fields from the PPDU
% ind = wlanFieldIndices(cfg);
ind = wlanFieldIndices(cfgRx);
% % Setup plots for the example
% [spectrumAnalyzer,timeScope,ConstellationDiagram,EVMPerSubcarrier,EVMPerSymbol] = heSigRecSetupPlots(fs);
% Minimum packet length is 10 OFDM symbols
% lstfLength = double(ind.LSTF(2));
% minPktLen = lstfLength*5; % Number of samples in L-STF
rxWaveLen = size(rx,1);
%% Front-End Processing
searchOffset = 0; % Offset from start of waveform in samples
% Packet detection
coarsePktOffset = wlanPacketDetect(rx,chanBW,searchOffset,0.8);
LSTF = wlanLSTF(wlanNonHTConfig);
% if isempty(coarsePktOffset)||(coarsePktOffset + ind.LSIG(2) > rxWaveLen) % If empty no L-STF detected; packet error
% numBitError = numBitError+numBits;%%???????????????
% userIdx = userIdx+1;
% end
% Coarse frequency offset estimation and correction using L-STF
if isempty(coarsePktOffset)
coarsePktOffset = 0;
end
rxLSTF = rx(coarsePktOffset+(ind.LSTF(1):ind.LSTF(2)), :);
tmp_xcorr = abs(xcorr(LSTF,rxLSTF));
coarseFreqOffset = wlanCoarseCFOEstimate(rxLSTF,chanBW);
rx = helperFrequencyOffset(rx,fs,-coarseFreqOffset);
% 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 pktOffset>50%%????????????????????????????///
% % numPacketErrors(userIdx) = numPacketErrors(userIdx)+1;
% numBitError = numBitError+numBits;
% userIdx = userIdx+1;
% % continue; % Go to next loop iteration
% end
% 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);
% Timing synchronization complete: packet detected
fprintf('Packet detected at index %d\n',pktOffset + 1);
% Display estimated carrier frequency offset
cfoCorrection = coarseFreqOffset + fineFreqOff; % Total CFO
fprintf('Estimated CFO: %5.1f Hz\n\n',cfoCorrection);
if max(tmp_xcorr)>50
% 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);
rxSIGA = rx(pktOffset+(ind.LSIG(1):ind.HESIGA(2)),:);
pktFormat = wlanFormatDetect(rxSIGA,lltfChanEst,noiseVar,chanBW);
fprintf(' %s packet detected\n\n',pktFormat);
% Set the packet format in the recovery object and update the field indices
cfgRx.PacketFormat = pktFormat;
ind = wlanFieldIndices(cfgRx);
%% L-LTF Channel Estimate
lltfDemod = wlanHEDemodulate(rxLLTF,'L-LTF',chanBW);
lltfChanEst = wlanLLTFChannelEstimate(lltfDemod,chanBW);
%% L-SIG and RL-SIG Decoding
% Extract L-SIG and RL-SIG fields
rxLSIG = rx(pktOffset+(ind.LSIG(1):ind.RLSIG(2)),:);
% OFDM demodulate
helsigDemod = wlanHEDemodulate(rxLSIG,'L-SIG',chanBW);
% Estimate CPE and phase correct symbols
helsigDemod = preHECommonPhaseErrorTracking(helsigDemod,lltfChanEst,'L-SIG',chanBW);
% Estimate channel on extra 4 subcarriers per subchannel and create full
% channel estimate
preheInfo = wlanHEOFDMInfo('L-SIG',chanBW);
preHEChanEst = preHEChannelEstimate(helsigDemod,lltfChanEst,preheInfo.NumSubchannels);
% Average L-SIG and RL-SIG before equalization
helsigDemod = mean(helsigDemod,2);
% Equalize data carrying subcarriers, merging 20 MHz subchannels
[eqLSIGSym,csi] = preHESymbolEqualize(helsigDemod(preheInfo.DataIndices,:,:), ...
preHEChanEst(preheInfo.DataIndices,:,:),noiseVar,preheInfo.NumSubchannels);
% Decode L-SIG field
[~,failCheck,lsigInfo] = wlanLSIGBitRecover(eqLSIGSym,noiseVar,csi);
if failCheck
disp(' ** L-SIG check fail **');
else
disp(' L-SIG check pass');
end
% Get the length information from the recovered L-SIG bits and update the
% L-SIG length property of the recovery configuration object
lsigLength = lsigInfo.Length;
cfgRx.LSIGLength = lsigLength;
% Measure EVM of L-SIG symbols
EVM = comm.EVM;
EVM.ReferenceSignalSource = 'Estimated from reference constellation';
EVM.Normalization = 'Average constellation power';
EVM.ReferenceConstellation = wlanReferenceSymbols('BPSK');
rmsEVM = EVM(eqLSIGSym);
evm = 20*log10(rmsEVM/100);
fprintf(' L-SIG EVM: %2.2fdB\n\n',20*log10(rmsEVM/100));
% Calculate the receive time and corresponding number of samples in the
% packet
RXTime = ceil((lsigLength + 3)/3) * 4 + 20; % In microseconds
numRxSamples = round(RXTime * 1e-6 * fs); % Number of samples in time
%% HE-SIG-A Decoding
rxSIGA = rx(pktOffset+(ind.HESIGA(1):ind.HESIGA(2)),:);
sigaDemod = wlanHEDemodulate(rxSIGA,'HE-SIG-A',chanBW);
hesigaDemod = preHECommonPhaseErrorTracking(sigaDemod,preHEChanEst,'HE-SIG-A',chanBW);
% Equalize data carrying subcarriers, merging 20 MHz subchannels
preheInfo = wlanHEOFDMInfo('HE-SIG-A',chanBW);
[eqSIGASym,csi] = preHESymbolEqualize(hesigaDemod(preheInfo.DataIndices,:,:), ...
preHEChanEst(preheInfo.DataIndices,:,:), ...
noiseVar,preheInfo.NumSubchannels);
% Recover HE-SIG-A bits
[sigaBits,failCRC] = wlanHESIGABitRecover(eqSIGASym,noiseVar,csi);
% Perform the CRC on HE-SIG-A bits
if failCRC
disp(' ** HE-SIG-A CRC fail **');
else
disp(' HE-SIG-A CRC pass');
end
% Measure EVM of HE-SIG-A symbols
% release(EVM);
% if strcmp(pktFormat,'HE-EXT-SU')
% % The second symbol of an HE-SIG-A field for an HE-EXT-SU packet is
% % QBPSK.
% EVM.ReferenceConstellation = wlanReferenceSymbols('BPSK',[0 pi/2 0 0]);
% % Account for scaling of L-LTF for an HE-EXT-SU packet
% rmsEVM = EVM(eqSIGASym*sqrt(2));
% else
% EVM.ReferenceConstellation = wlanReferenceSymbols('BPSK');
% rmsEVM = EVM(eqSIGASym);
% end
% fprintf(' HE-SIG-A EVM: %2.2fdB\n\n',20*log10(mean(rmsEVM)/100));
%% Interpret Recovered HE-SIG-A bits
cfgRx = interpretHESIGABits(cfgRx,sigaBits);
ind = wlanFieldIndices(cfgRx); % Update field indices
% disp(cfgRx)
%% HE-SIG-B Decoding
if strcmp(pktFormat,'HE-MU')
if ~cfgRx.SIGBCompression
s = getSIGBLength(cfgRx);
% Get common field symbols. The start of HE-SIG-B field is known
rxSym = rx(pktOffset+(ind.HESIGA(2)+(1:s.NumSIGBCommonFieldSamples)),:);
% Decode HE-SIG-B common field
[status,cfgRx] = heSIGBCommonFieldDecode(rxSym,preHEChanEst,noiseVar,cfgRx);
% CRC on HE-SIG-B content channels
if strcmp(status,'Success')
fprintf(' HE-SIG-B (common field) CRC pass\n');
elseif strcmp(status,'ContentChannel1CRCFail')
fprintf(' ** HE-SIG-B CRC fail for content channel-1\n **');
elseif strcmp(status,'ContentChannel2CRCFail')
fprintf(' ** HE-SIG-B CRC fail for content channel-2\n **');
elseif any(strcmp(status,{'UnknownNumUsersContentChannel1','UnknownNumUsersContentChannel2'}))
error(' ** Unknown packet length, discard packet\n **');
else
% Discard the packet if all HE-SIG-B content channels fail
error(' ** HE-SIG-B CRC fail **');
end
% Update field indices as the number of HE-SIG-B symbols are
% updated
ind = wlanFieldIndices(cfgRx);
end
% Get complete HE-SIG-B field samples
rxSIGB = rx(pktOffset+(ind.HESIGB(1):ind.HESIGB(2)),:);
fprintf(' Decoding HE-SIG-B user field... \n');
% Decode HE-SIG-B user field
[failCRC,cfgUsers] = heSIGBUserFieldDecode(rxSIGB,preHEChanEst,noiseVar,cfgRx);
%*********************************03.22*********************************
for ii = 1:numel(cfgUsers)
if cfgUsers{ii}.STAID == userIdx
user = cfgUsers{ii};
break;
end
end
% user = cfgUsers{1};
%*********************************03.22*********************************
% CRC on HE-SIG-B users
if ~all(failCRC)
fprintf(' HE-SIG-B (user field) CRC pass\n\n');
numUsers = numel(cfgUsers);
elseif all(failCRC)
% Discard the packet if all users fail the CRC
error(' ** HE-SIG-B CRC fail for all users **');
else
fprintf(' ** HE-SIG-B CRC fail for at least one user\n **');
% Only process users with valid CRC
numUsers = numel(cfgUsers);
end
else % HE-SU, HE-EXT-SU
cfgUsers = {cfgRx};
numUsers = 1;
end
%% HE-Data Decoding
cfgDataRec = trackingRecoveryConfig;
cfgDataRec.PilotTracking = pilotTracking;
% Get recovery configuration object for each user
user = cfgUsers{userIdx};
if strcmp(pktFormat,'HE-MU')
fprintf(' Decoding User:%d, STAID:%d, RUSize:%d\n',userIdx,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;
numOFDMSym = double(numOFDMSym);
% 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,:);
eqSymPlot = eqSymUser(1:end);
% scatterplot
% eqSymplot = eqSymUser(1:end);
% scatterplot(eqSymplot);
% Demap and decode bits
rxPSDUbits = wlanHEDataBitRecover(eqSymUser,nVarEst,csiData,user,'LDPCDecodingMethod','layered-bp');
% rxPSDU(:,frameIdx) = RX_CRC32(double(rxPSDUbits));
rxPSDU(:,frameIdx) = rxPSDUbits;
% Compare bit error
% bitError = sum(txPSDU{userIdx}~=rxPSDU);
% numBitError = numBitError+bitError;
% 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));
rx = rx(pktOffset+ind.HEData(2)+100:end,:);
% && mean(abs(rx)) > mean_power/2
% else
% if length(rx) > ind.HEData(2)
frameIdx = frameIdx+1;
[rxPSDU,bitErrorRate,eqSymPlot] = heMURx(rx,cfg,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,0);
txPSDUuser = txPSDU{userIdx};% BER 5ACK
bitError = sum(txPSDUuser(1:end,:)~=rxPSDU(1:length(txPSDUuser(1:end,:)),:));
bitErrorRate = bitError/length(rxPSDU);
ACK = (bitErrorRate == rxPSDU(end));
case 'text'
case 'photo'
[~,numPkt] = size(rxPSDU);
bitstream = reshape(rxPSDU,1,[]); %
imgLen = bin2dec(num2str(bitstream(1:16)));
% bitstream = bitstream(1:len*width*8); %
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
if rxCRC == rxPSDU(end)
disp('Pass RX Sum Check!');
bitErrorRate = zeros(1,numPkt);
else
disp('Fail RX Sum Check!');
bitErrorRate = ones(1,numPkt);
end
% img = mat2gray(rxPSDU); %
% imshow(img); %
% pause(1);
% close;
ACK = (rxCRC == rxPSDU(end));
end
save(['TXPackets\ACKfeedback_for_User' num2str(userIdx) '.mat'],'ACK');
% scatterplot(eqSymPlot(1:end));
% pause(1);
% close;
end
end

106
heNoiseEstimate.m Normal file
View File

@ -0,0 +1,106 @@
function [nest,sigest] = heNoiseEstimate(x,chanEstSSPilots,cfg,varargin)
%heNoiseEstimate Estimate noise power using HE data field pilots
%
% NEST = heNoiseEstimate(x,CHANESTSSPILOTS,CFGHE) estimates the mean
% noise power in watts using the demodulated pilot symbols in the HE data
% field and single-stream channel estimates at pilot subcarriers. The
% noise estimate is averaged over the number of symbols and receive
% antennas.
%
% X is a complex Nsp-by-Nsym-by-Nr array containing demodulated pilot
% subcarrier in HE data field. Nsym is the number of demodulated HE-Data
% symbols.
%
% CHANESTSSPILOTS is a complex Nsp-by-Nltf-by-Nr array containing the
% channel gains at pilot subcarrier locations for each symbol, assuming
% one space-time stream at the transmitter. Nltf is the number of HE-LTF
% symbols.
%
% CFGHE is a format configuration object of type <a href="matlab:help('wlanHESUConfig')">wlanHESUConfig</a>,
% <a href="matlab:help('wlanHETBConfig')">wlanHETBConfig</a> or <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a>.
%
% NEST = heNoiseEstimate(X,CHANESTSSPILOTS,CFGMU,RUIDX) performs noise
% power estimation for the multi user HE format input X.
%
% CFGMU is the format configuration object of type <a href="matlab:help('wlanHEMUConfig')">wlanHEMUConfig</a> or
% <a href="matlab:help('heTBSystemConfig')">heTBSystemConfig</a>.
%
% RUIDX is the RU (resource unit) index.
%
% [NEST,SIGEST] = heNoiseEstimate(...) additionally returns an estimate
% of the signal power.
% Copyright 2018-2019 The MathWorks, Inc.
%#codegen
validateattributes(cfg,{'wlanHESUConfig','wlanHEMUConfig','wlanHETBConfig','wlanHERecoveryConfig','heTBSystemConfig'},{'scalar'},mfilename,'format configuration object');
numOFDMSym = size(x,2);
n = (0:numOFDMSym-1);
ruIdx = 1;
if isa(cfg,'wlanHEMUConfig')
narginchk(4,4)
ruIdx = varargin{1};
sigbInfo = wlan.internal.heSIGBCodingInfo(cfg);
numHESIGB = sigbInfo.NumSymbols;
pktFormat = packetFormat(cfg);
allocInfo = ruInfo(cfg);
ruSize = allocInfo.RUSizes(ruIdx);
elseif isa(cfg,'heTBSystemConfig')
numHESIGB = 0;
ruIdx = varargin{1};
pktFormat = packetFormat(cfg);
allocInfo = ruInfo(cfg);
ruSize = allocInfo.RUSizes(ruIdx);
elseif isa(cfg,'wlanHERecoveryConfig')
ruSize = cfg.RUSize;
pktFormat = cfg.PacketFormat;
if strcmp(pktFormat,'HE-MU')
s = getSIGBLength(cfg);
numHESIGB = s.NumSIGBSymbols;
else
numHESIGB = 0;
end
else
% SU, EXT SU, TB
numHESIGB = 0;
pktFormat = packetFormat(cfg);
allocInfo = ruInfo(cfg);
ruSize = allocInfo.RUSizes(ruIdx);
end
if strcmp(pktFormat,'HE-EXT-SU')
numHESIGA = 4;
else % SU or MU
numHESIGA = 2;
end
z = 2+numHESIGA+numHESIGB; % Pilot symbol offset
% Get the reference pilots for one space-time stream, pilot sequence same
% for all space-time streams
refPilots = wlan.internal.hePilots(ruSize,1,n,z); % Nsp-by-Nsym-by-1
% Average single-stream pilot estimates over symbols (2nd dimension)
avChanEstSSPilots = mean(chanEstSSPilots,2); % Nsp-by-1-by-Nrx
% Estimate channel at pilot location using least square estimates
chanEstPilotsLoc = bsxfun(@rdivide,x,refPilots); % Nsp-by-Nsym-by-Nrx
% Subtract the noisy least squares estimates of the channel at pilot symbol
% locations from the noise averaged single stream pilot symbol estimates of
% the channel
error = bsxfun(@minus,chanEstPilotsLoc,avChanEstSSPilots); % Nsp-by-Nsym-by-Nrx
% Get power of error and average over pilot symbols, subcarriers and
% receive antennas
useIdx = ~isnan(error); % NaNs may exist in 1xHELTF
nest = real(mean(error(useIdx).*conj(error(useIdx)),'all')); % For codegen
if nargout>1
% Get power of channel estimate at pilot locations
sigest = real(mean(chanEstPilotsLoc(:).*conj(chanEstPilotsLoc(:)))); % For codegen
end
end

50
hePlotEQConstellation.m Normal file
View File

@ -0,0 +1,50 @@
function hePlotEQConstellation(eqDataSym,cfgRx,ConstellationDiagram,varargin)
% hePlotEQConstellation Plot equalized constellation for all spatial streams
%
% hePlotEQConstellation(EQDATASYM,CFGRX,CONSTELLATIONDIAGRAM) plots
% equalized constellation for all spatial streams.
%
% EQDATASYM are the demodulated HE-Data field OFDM symbols for a user,
% specified as a Nsd-by-Nsym-by-Nss matrix of real or complex values,
% where Nsd is the number of data subcarriers in the HE-Data field and
% Nsym is the number of OFDM symbols, and Nss is the number of spatial
% streams.
%
% CFGRX is the format configuration object of type <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a>.
%
% CONSTELLATIONDIAGRAM is a system object of type <a href="matlab:help('comm.ConstellationDiagram')">comm.ConstellationDiagram</a>.
%
% hePlotEQConstellation(...,USERIDX,NUMUSERS) displays user number and
% number of user information in the figure title.
% Copyright 2019 The MathWorks, Inc.
if nargin==5
userIdx = varargin{1};
numUsers = varargin{2};
elseif nargin==4
userIdx = varargin{1};
numUsers = 1;
end
[Nsd,Nsym,Nss] = size(eqDataSym);
eqDataSymPerSS = reshape(eqDataSym,Nsd*Nsym,Nss);
str = cell(Nss,1);
for iss=1:Nss
str{iss} = sprintf('Spatial stream %d',iss);
end
ConstellationDiagram.ReferenceConstellation = wlanReferenceSymbols(cfgRx);
ConstellationDiagram(eqDataSymPerSS);
show(ConstellationDiagram);
if nargin>3
ConstellationDiagram.Name = sprintf('Equalized data symbols, user #%d/%d',userIdx,numUsers);
else
ConstellationDiagram.Name = sprintf('Equalized data symbols');
end
ConstellationDiagram.ChannelNames = str;
release(ConstellationDiagram);
end

76
hePlotEVMPerSubcarrier.m Normal file
View File

@ -0,0 +1,76 @@
function rmsEVM = hePlotEVMPerSubcarrier(eqDataSym,cfgRx,evmSubcarrierPlot,varargin)
% hePlotEVMPerSubcarrier Plots EVM per subcarrier for all spatial streams
%
% RMSEVM = hePlotEVMPerSubcarrier(EQDATASYM,CFGRX,EVMSUBCARRIERPLOT)
% plots EVM per subcarriers averaged over symbols for all spatial
% streams.
%
% RMSEVM is the EVM of EQDATASYM in decibels.
%
% EQDATASYM are the demodulated HE-Data field OFDM symbols for a user,
% specified as a Nsd-by-Nsym-by-Nss matrix of real or complex values,
% where Nsd is the number of data subcarriers in the HE-Data field and
% Nsym is the number of OFDM symbols, and Nss is the number of spatial
% streams.
%
% CFGRX is the format configuration object of type <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a>,
% <a href="matlab:help('wlanHESUConfig')">wlanHESUConfig</a>, or <a href="matlab:help('wlanHETBConfig')">wlanHETBConfig</a>.
%
% EVMSUBCARRIERPLOT is a system object of type <a href="matlab:help('dsp.ArrayPlot')">dsp.ArrayPlot</a>.
%
% RMSEVM = hePlotEVMPerSubcarrier(...,USERIDX,NUMUSERS) displays user
% number and number of user information in the figure title.
% Copyright 2019-2020 The MathWorks, Inc.
[Nsd,~,Nss] = size(eqDataSym);
rmsEVMPerSC = zeros(Nsd,Nss);
if nargin == 5
userIdx = varargin{1};
numUsers = varargin{2};
elseif nargin == 4
userIdx = varargin{1};
numUsers = 1; % Number of users are unknown, prefix this to 1
end
EVM = comm.EVM;
EVM.ReferenceSignalSource = 'Estimated from reference constellation';
EVM.ReferenceConstellation = wlanReferenceSymbols(cfgRx);
for iss = 1:Nss
for isd = 1:Nsd
rmsEVMPerSC(isd,iss) = EVM(eqDataSym(isd,:,iss).');
release(EVM);
end
end
if isa(cfgRx,'wlanHERecoveryConfig')
ofdmInfo = wlanHEOFDMInfo('HE-Data',cfgRx.ChannelBandwidth,cfgRx.GuardInterval,[cfgRx.RUSize cfgRx.RUIndex]);
else
ofdmInfo = wlanHEOFDMInfo('HE-Data',cfgRx);
end
dataInd = ofdmInfo.ActiveFFTIndices(ofdmInfo.DataIndices);
Nfft = ofdmInfo.FFTLength;
evmFFT = nan(Nfft,Nss);
rmsEVM = 20*log10(rmsEVMPerSC/100);
evmFFT(dataInd,:) = rmsEVM;
evmSubcarrierPlot.XOffset = -Nfft/2;
str = cell(Nss,1);
for iss=1:Nss
str{iss} = sprintf('Spatial stream %d',iss);
end
evmSubcarrierPlot.ChannelNames = str;
if nargin>3
evmSubcarrierPlot.Name = sprintf('EVM per subcarrier, user#%d/%d',userIdx,numUsers);
else
evmSubcarrierPlot.Name = sprintf('EVM per subcarrier');
end
evmSubcarrierPlot(evmFFT)
evmSubcarrierPlot.show
release(evmSubcarrierPlot);
end

57
hePlotEVMPerSymbol.m Normal file
View File

@ -0,0 +1,57 @@
function rmsEVM = hePlotEVMPerSymbol(eqDataSym,cfgRx,evmSymPlot,varargin)
% hePlotEVMPerSymbol Plots EVM per symbols for all spatial streams
%
% RMSEVM = hePlotEVMPerSymbol(EQDATASYM,CFGRX,EVMSYMPLOT) plots EVM per
% symbol averaged over subcarriers for all spatial streams.
%
% RMSEVM is the EVM of EQDATASYM in decibels.
%
% EQDATASYM are the demodulated HE-Data field OFDM symbols for a user,
% specified as a Nsd-by-Nsym-by-Nss matrix of real or complex values,
% where Nsd is the number of data subcarriers in the HE-Data field and
% Nsym is the number of OFDM symbols, and Nss is the number of spatial
% streams.
%
% CFGRX is the format configuration object of type <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a>.
%
% EVMSYMPLOT is a system object of type <a href="matlab:help('dsp.ArrayPlot')">dsp.ArrayPlot</a>.
%
% RMSEVM = hePlotEVMPerSymbol(...,USERIDX,NUMUSERS) displays user
% number and number of user information in the figure title.
% Copyright 2019 The MathWorks, Inc.
[~,~,Nss] = size(eqDataSym);
if nargin == 5
userIdx = varargin{1};
numUsers = varargin{2};
elseif nargin == 4
userIdx = varargin{1};
numUsers = 1; % Number of users are unKnown, prefix this to 1
end
EVM = comm.EVM;
EVM.ReferenceSignalSource = 'Estimated from reference constellation';
EVM.ReferenceConstellation = wlanReferenceSymbols(cfgRx);
rmsEVMPerSym = permute(EVM(eqDataSym),[2 3 1]);
str = cell(Nss,1);
for iss=1:Nss
str{iss} = sprintf('Spatial stream %d',iss);
end
evmSymPlot.ChannelNames = str;
if nargin>3
evmSymPlot.Name = sprintf('EVM per symbol, user#%d/%d',userIdx,numUsers);
else
evmSymPlot.Name = sprintf('EVM per symbol');
end
rmsEVM = 20*log10(rmsEVMPerSym/100);
evmSymPlot(rmsEVM);
evmSymPlot.show
release(evmSymPlot);
end

91
heSIGBCommonFieldDecode.m Normal file
View File

@ -0,0 +1,91 @@
function [status,cfgRx,commonBits,eqCommonSym,failInterpretation] = heSIGBCommonFieldDecode(rx,chanEst,noiseVar,cfgRx,varargin)
%heSIGBCommonFieldDecode Decode HE-SIG-B common field
%
% [STATUS,CFGRX] = heSIGBCommonFieldDecode(RX,CHANEST,NOISEVAR,CFGRX)
% decode the HE-SIG-B common field given the HE-SIG-B common field
% samples, channel estimate, CHANEST, noise variance, NOISEVAR and
% recovery configuration object CFGRX.
%
% STATUS represents the result of content channel decoding, and is
% returned as a character vector. The STATUS output is determined by the
% combination of cyclic redundancy check (CRC) per content channel and
% the number of HE-SIG-B symbols signaled in HE-SIG-A field:
%
% Success - CRC passed for all content channels
% ContentChannel1CRCFail - CRC failed for content channel-1 and
% the number of HE-SIG-B symbols is less
% than 16.
% ContentChannel2CRCFail - CRC failed for content channel-2 and
% the number of HE-SIG-B symbols is less
% than 16.
% UnknownNumUsersContentChannel1 - CRC failed for content channel-1 and
% the number of HE-SIG-B symbols is
% equal to 16.
% UnknownNumUsersContentChannel2 - CRC failed for content channel-2 and
% the number of HE-SIG-B symbols is
% equal to 16.
% AllContentChannelCRCFail - CRC failed for all content channels.
%
% CFGRX is an updated format configuration object of type
% <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a> after HE-SIG-B common field decoding.
%
% RX are the HE-SIG-B common field samples. The number of common field
% samples depends on the channel bandwidth as defined in Table 27-23 of
% IEEE P802.11ax/D4.1.
%
% CHANEST is a complex Nst-by-1-by-Nr array containing the estimated
% channel at data and pilot subcarriers, where Nst is the number of
% occupied subcarriers and Nr is the number of receive antennas.
%
% NOISEVAR is the noise variance estimate, specified as a nonnegative
% scalar.
%
% CFGRX is the format configuration object of type <a href="matlab:help('wlanHERecoveryConfig')">wlanHERecoveryConfig</a>
% and specifies the parameters for the HE-MU format.
%
% [...,FAILINTERPRETATION] = heSIGBCommonFieldDecode(...,SUPPRESSERROR)
% controls the behavior of the function due to an unexpected value of the
% interpreted HE-SIG-B common field bits. SUPPRESSERROR is logical. When
% SUPPRESSERROR is true and the function cannot interpret the recovered
% HE-SIG-B common field bits due to an unexpected value, the function
% returns FAILINTERPRETATION as true and cfgMU is unchanged. When
% SUPPRESSERROR is false and the function cannot interpret the recovered
% HE-SIG-B common field bits due to an unexpected value, an exception is
% issued, and the function does not return an output. The default is
% false.
% Copyright 2018-2020 The MathWorks, Inc.
suppressError = false; % Control the validation of the interpreted HE-SIG-B common field bits
failInterpretation = false;
if nargin>4
suppressError = varargin{1};
end
chanBW = cfgRx.ChannelBandwidth;
% Demodulate HE-SIG-B Common field
demodCommonSym = wlanHEDemodulate(rx,'HE-SIG-B',chanBW);
% Extract data and pilots symbols
preheInfo = wlanHEOFDMInfo('HE-SIG-A',chanBW);
demodCommonData = demodCommonSym(preheInfo.DataIndices,:,:);
demodCommonPilot = demodCommonSym(preheInfo.PilotIndices,:,:);
% Estimate and correct common phase error
demodCommonData = heCPECorrection(demodCommonData,demodCommonPilot,chanEst(preheInfo.PilotIndices,:,:),chanBW);
% Merge channels
[commonOne20MHz,chanEstOne20MHz] = heSIGBMergeSubchannels(demodCommonData,chanEst(preheInfo.DataIndices,:,:),chanBW);
% Perform equalization
[eqCommonSym,csiData] = preHESymbolEqualize(commonOne20MHz,chanEstOne20MHz,noiseVar);
% Decode HE-SIG-B common field
if suppressError
[commonBits,status] = wlanHESIGBCommonBitRecover(eqCommonSym,noiseVar,csiData,cfgRx);
[cfgRx,failInterpretation] = interpretHESIGBCommonBits(cfgRx,commonBits,status);
else
[commonBits,status,cfgRx] = wlanHESIGBCommonBitRecover(eqCommonSym,noiseVar,csiData,cfgRx);
end
end

Some files were not shown because too many files have changed in this diff Show More