mirror of https://github.com/PentHertz/srsLTE.git
Added CQI support. Restored ue_ul normalization
This commit is contained in:
parent
510e4c892e
commit
dc15e99906
|
@ -1,10 +1,10 @@
|
||||||
enbConfig=struct('NCellID',1,'CyclicPrefix','Normal','CellRefP',1);
|
enbConfig=struct('NCellID',1,'CyclicPrefix','Normal','CellRefP',1);
|
||||||
pdschConfig=struct('Modulation','QPSK','RV',0,'TxScheme','Port0');
|
pdschConfig=struct('Modulation','QPSK','RV',0,'TxScheme','Port0');
|
||||||
|
|
||||||
addpath('../../debug/srslte/lib/phch/test')
|
addpath('/home/ismael/work/srsLTE/debug/srslte/lib/phch/test')
|
||||||
|
|
||||||
TBs=1:111:15000;
|
TBs=40:8:800;
|
||||||
e_bits=10000;
|
e_bits=1000;
|
||||||
error=zeros(size(TBs));
|
error=zeros(size(TBs));
|
||||||
for i=1:length(TBs)
|
for i=1:length(TBs)
|
||||||
trblkin=randi(2,TBs(i),1)-1;
|
trblkin=randi(2,TBs(i),1)-1;
|
||||||
|
|
|
@ -51,7 +51,7 @@ cec.InterpType = 'linear'; % 2D interpolation type
|
||||||
cec.InterpWindow = 'Centered'; % Interpolation window type
|
cec.InterpWindow = 'Centered'; % Interpolation window type
|
||||||
cec.InterpWinSize = 1; % Interpolation window size
|
cec.InterpWinSize = 1; % Interpolation window size
|
||||||
|
|
||||||
addpath('../../debug/srslte/lib/phch/test')
|
addpath('../../build/srslte/lib/phch/test')
|
||||||
|
|
||||||
decoded = zeros(size(SNR_values));
|
decoded = zeros(size(SNR_values));
|
||||||
decoded_srslte = zeros(size(SNR_values));
|
decoded_srslte = zeros(size(SNR_values));
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
clear
|
clear
|
||||||
ueConfig=struct('NCellID',1,'RNTI',11,'NULRB',6,'NSubframe',1,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Group');
|
ueConfig=struct('NCellID',1,'RNTI',11,'NULRB',25,'NSubframe',0,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off');
|
||||||
pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',1,'ResourceSize',0);
|
pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',0,'ResourceSize',2);
|
||||||
|
|
||||||
addpath('../../build/srslte/lib/phch/test')
|
addpath('../../build/srslte/lib/phch/test')
|
||||||
|
|
||||||
|
@ -11,56 +11,59 @@ for f=0:5
|
||||||
for n=0:7:130
|
for n=0:7:130
|
||||||
for d=1:3
|
for d=1:3
|
||||||
for ncs=0:d:7
|
for ncs=0:d:7
|
||||||
pucchConfig.ResourceIdx= n;
|
for nsf=0:9
|
||||||
pucchConfig.DeltaShift = d;
|
pucchConfig.ResourceIdx= n;
|
||||||
pucchConfig.CyclicShifts = ncs;
|
pucchConfig.DeltaShift = d;
|
||||||
if (f >= 3)
|
pucchConfig.CyclicShifts = ncs;
|
||||||
nb=20;
|
ueConfig.NSubframe=nsf;
|
||||||
nb_ack=f-3;
|
if (f >= 3)
|
||||||
else
|
nb=20;
|
||||||
nb=f;
|
nb_ack=f-3;
|
||||||
nb_ack=0;
|
else
|
||||||
end
|
nb=f;
|
||||||
bits=randi(2,nb,1)-1;
|
nb_ack=0;
|
||||||
bits_ack=randi(2,nb_ack,1)-1;
|
end
|
||||||
fprintf('Testing PUCCH Format: %s, n_pucch=%d, DeltaShift=%d, CyclicShift=%d\n',format_str{f+1},n,d,ncs);
|
bits=mod(0:nb-1,2);
|
||||||
if (f >= 3)
|
bits_ack=randi(2,nb_ack,1)-1;
|
||||||
[sym_mat, info]=ltePUCCH2(ueConfig,pucchConfig,bits);
|
fprintf('Testing PUCCH Format: %s, n_pucch=%d, DeltaShift=%d, CyclicShift=%d, Nsf=%d\n',format_str{f+1},n,d,ncs,nsf);
|
||||||
idx=ltePUCCH2Indices(ueConfig,pucchConfig);
|
if (f >= 3)
|
||||||
[dmrs_mat, info_dmrs]=ltePUCCH2DRS(ueConfig,pucchConfig,bits_ack);
|
[sym_mat, info]=ltePUCCH2(ueConfig,pucchConfig,bits);
|
||||||
idx_dmrs=ltePUCCH2DRSIndices(ueConfig,pucchConfig);
|
idx=ltePUCCH2Indices(ueConfig,pucchConfig);
|
||||||
else
|
[dmrs_mat, info_dmrs]=ltePUCCH2DRS(ueConfig,pucchConfig,bits_ack);
|
||||||
[sym_mat, info]=ltePUCCH1(ueConfig,pucchConfig,bits);
|
idx_dmrs=ltePUCCH2DRSIndices(ueConfig,pucchConfig);
|
||||||
idx=ltePUCCH1Indices(ueConfig,pucchConfig);
|
else
|
||||||
[dmrs_mat, info_dmrs]=ltePUCCH1DRS(ueConfig,pucchConfig);
|
[sym_mat, info]=ltePUCCH1(ueConfig,pucchConfig,bits);
|
||||||
idx_dmrs=ltePUCCH1DRSIndices(ueConfig,pucchConfig);
|
idx=ltePUCCH1Indices(ueConfig,pucchConfig);
|
||||||
end
|
[dmrs_mat, info_dmrs]=ltePUCCH1DRS(ueConfig,pucchConfig);
|
||||||
subframe_mat = lteULResourceGrid(ueConfig);
|
idx_dmrs=ltePUCCH1DRSIndices(ueConfig,pucchConfig);
|
||||||
subframe_mat(idx)=sym_mat;
|
end
|
||||||
subframe_mat(idx_dmrs)=dmrs_mat;
|
subframe_mat = lteULResourceGrid(ueConfig);
|
||||||
|
subframe_mat(idx)=sym_mat;
|
||||||
|
subframe_mat(idx_dmrs)=dmrs_mat;
|
||||||
|
|
||||||
[sym, dmrs, subframe]=srslte_pucch_encode(ueConfig,pucchConfig,[bits; bits_ack]);
|
[sym, dmrs, subframe]=srslte_pucch_encode(ueConfig,pucchConfig,[bits; bits_ack]);
|
||||||
|
|
||||||
error_sym=max(abs(sym-sym_mat));
|
|
||||||
error_dmrs=max(abs(dmrs-dmrs_mat));
|
|
||||||
error_sf=max(abs(subframe_mat(:)-subframe));
|
|
||||||
k=k+1;
|
|
||||||
|
|
||||||
if (error_sym > 1e-5)
|
error_sym=max(abs(sym-sym_mat));
|
||||||
disp(info)
|
error_dmrs=max(abs(dmrs-dmrs_mat));
|
||||||
plot(1:length(sym),sym,1:length(sym_mat),sym_mat)
|
error_sf=max(abs(subframe_mat(:)-subframe));
|
||||||
legend('srsLTE','Matlab')
|
k=k+1;
|
||||||
error('Error in symbols');
|
|
||||||
end
|
if (error_sym > 1e-5)
|
||||||
if (error_dmrs > 1e-5)
|
disp(info)
|
||||||
disp(info_dmrs)
|
plot(1:length(sym),sym,1:length(sym_mat),sym_mat)
|
||||||
plot(angle(dmrs)-angle(dmrs_mat))
|
legend('srsLTE','Matlab')
|
||||||
error('Error in DMRS');
|
error('Error in symbols');
|
||||||
end
|
end
|
||||||
if (error_sf > 1e-5)
|
if (error_dmrs > 1e-5)
|
||||||
disp(info)
|
disp(info_dmrs)
|
||||||
plot(abs(subframe-subframe_mat(:)))
|
plot(angle(dmrs)-angle(dmrs_mat))
|
||||||
error('Error in subframe');
|
error('Error in DMRS');
|
||||||
|
end
|
||||||
|
if (error_sf > 1e-5)
|
||||||
|
disp(info)
|
||||||
|
plot(abs(subframe-subframe_mat(:)))
|
||||||
|
error('Error in subframe');
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
ueConfig=struct('NCellID',1,'NULRB',25,'RNTI',64,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',0);
|
ueConfig=struct('NCellID',1,'NULRB',6,'RNTI',64,'CyclicPrefixUL','Normal','NTxAnts',1,'Shortened',0,'Hopping','Off','SeqGroup',0,'CyclicShift',0);
|
||||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',(0:23)','Shortened',0);
|
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Shortened',0,'DynCyclicShift',0);
|
||||||
|
|
||||||
addpath('../../build/srslte/lib/phch/test')
|
addpath('../../debug/srslte/lib/phch/test')
|
||||||
|
|
||||||
TBs=9144;
|
TBs=336;
|
||||||
cqilen=0;
|
cqilen=20;
|
||||||
rvs=0;
|
rvs=0;
|
||||||
mods={'16QAM'};
|
mods={'16QAM'};
|
||||||
betas=0;
|
betas=5;
|
||||||
subf=5;
|
subf=0;
|
||||||
|
|
||||||
for i=1:length(TBs)
|
for i=1:length(TBs)
|
||||||
for m=1:length(mods)
|
for m=1:length(mods)
|
||||||
|
@ -19,7 +19,7 @@ for i=1:length(TBs)
|
||||||
for c=1:length(cqilen)
|
for c=1:length(cqilen)
|
||||||
for s=1:length(subf)
|
for s=1:length(subf)
|
||||||
fprintf('Subf=%d, RV=%d\n', subf(s), rvs(r));
|
fprintf('Subf=%d, RV=%d\n', subf(s), rvs(r));
|
||||||
trblkin=[0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ];
|
trblkin=mod(0:TBs(i)-1,2);
|
||||||
ueConfig.NSubframe=subf(s);
|
ueConfig.NSubframe=subf(s);
|
||||||
puschConfig.Modulation = mods{m};
|
puschConfig.Modulation = mods{m};
|
||||||
puschConfig.RV = rvs(r);
|
puschConfig.RV = rvs(r);
|
||||||
|
@ -28,7 +28,7 @@ for i=1:length(TBs)
|
||||||
puschConfig.BetaACK = betas(back);
|
puschConfig.BetaACK = betas(back);
|
||||||
|
|
||||||
if (betas(bri)>0)
|
if (betas(bri)>0)
|
||||||
ri_bit=randi(2,1,1)-1;
|
ri_bit=randi(2,1,1)-1;
|
||||||
else
|
else
|
||||||
ri_bit=[];
|
ri_bit=[];
|
||||||
end
|
end
|
||||||
|
@ -39,20 +39,25 @@ for i=1:length(TBs)
|
||||||
end
|
end
|
||||||
|
|
||||||
if (cqilen(c)>0 || TBs(i)>0)
|
if (cqilen(c)>0 || TBs(i)>0)
|
||||||
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin);
|
[enc, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
|
||||||
cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
|
cw_mat=ltePUSCH(ueConfig,puschConfig,enc);
|
||||||
[drs, infodrs]=ltePUSCHDRS(ueConfig,puschConfig);
|
%[drs, infodrs]=ltePUSCHDRS(ueConfig,puschConfig);
|
||||||
idx=ltePUSCHIndices(ueConfig,puschConfig);
|
idx=ltePUSCHIndices(ueConfig,puschConfig);
|
||||||
drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig);
|
%drs_idx=ltePUSCHDRSIndices(ueConfig,puschConfig);
|
||||||
subframe_mat = lteULResourceGrid(ueConfig);
|
subframe_mat = lteULResourceGrid(ueConfig);
|
||||||
subframe_mat(idx)=cw_mat;
|
subframe_mat(idx)=cw_mat;
|
||||||
subframe_mat(drs_idx)=drs;
|
%subframe_mat(drs_idx)=drs;
|
||||||
waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0);
|
waveform = lteSCFDMAModulate(ueConfig,subframe_mat,0);
|
||||||
|
|
||||||
[waveform_lib, subframe_lib, cwlib]=srslte_pusch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
|
cw_scram=lteULScramble(enc,0,1,64);
|
||||||
err=max(abs(waveform/0.2041-waveform_lib));
|
%
|
||||||
|
[waveform_lib, subframe_lib, cwlib, bits]=srslte_pusch_encode(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit);
|
||||||
|
err=max(abs(waveform-waveform_lib));
|
||||||
if (err > 10^-5)
|
if (err > 10^-5)
|
||||||
disp(err)
|
disp(err)
|
||||||
|
t=1:200;
|
||||||
|
%plot(t,bits(t),t,cw_scram(t))
|
||||||
|
plot(abs(double(bits)-double(cw_scram)))
|
||||||
error('Error!');
|
error('Error!');
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ blen=5184;
|
||||||
SNR_values_db=linspace(-1.3,-0.7,6);
|
SNR_values_db=linspace(-1.3,-0.7,6);
|
||||||
Nrealizations=600;
|
Nrealizations=600;
|
||||||
|
|
||||||
addpath('../../debug/lte/phy/lib/fec/test')
|
addpath('../../build/srslte/lib/fec/test')
|
||||||
|
|
||||||
errors1=zeros(1,length(SNR_values_db));
|
errors1=zeros(1,length(SNR_values_db));
|
||||||
errors2=zeros(1,length(SNR_values_db));
|
errors2=zeros(1,length(SNR_values_db));
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
clear
|
clear
|
||||||
ueConfig=struct('NCellID',1,'CyclicPrefixUL','Normal','NTxAnts',1);
|
ueConfig=struct('NCellID',1,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',22,'Shortened',1);
|
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Shortened',0);
|
||||||
|
|
||||||
addpath('../../build/srslte/lib/phch/test')
|
addpath('../../debug/srslte/lib/phch/test')
|
||||||
|
|
||||||
TBs=336;
|
TBs=336;
|
||||||
cqilen=0;
|
cqilen=0;
|
||||||
mods={'16QAM'};
|
mods={'16QAM'};
|
||||||
rvs=0;
|
rvs=0;
|
||||||
betas=0;
|
betas=5;
|
||||||
|
|
||||||
|
|
||||||
for i=1:length(TBs)
|
for i=1:length(TBs)
|
||||||
|
@ -23,7 +23,7 @@ for i=1:length(TBs)
|
||||||
|
|
||||||
puschConfig.Modulation = mods{m};
|
puschConfig.Modulation = mods{m};
|
||||||
puschConfig.RV = rvs(r);
|
puschConfig.RV = rvs(r);
|
||||||
puschConfig.BetaCQI = betas(bcqi);
|
puschConfig.BetaCQI = 5;
|
||||||
puschConfig.BetaRI = betas(bri);
|
puschConfig.BetaRI = betas(bri);
|
||||||
puschConfig.BetaACK = betas(back);
|
puschConfig.BetaACK = betas(back);
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ for i=1:length(TBs)
|
||||||
err=sum(abs(double(mat)-double(lib)));
|
err=sum(abs(double(mat)-double(lib)));
|
||||||
if (err > 0)
|
if (err > 0)
|
||||||
disp(err)
|
disp(err)
|
||||||
|
plot(abs(double(mat)-double(lib)))
|
||||||
error('Error!');
|
error('Error!');
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -109,6 +109,8 @@ SRSLTE_API int srslte_chest_dl_estimate_port(srslte_chest_dl_t *q,
|
||||||
|
|
||||||
SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q);
|
SRSLTE_API float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q);
|
||||||
|
|
||||||
|
SRSLTE_API float srslte_chest_dl_get_snr(srslte_chest_dl_t *q);
|
||||||
|
|
||||||
SRSLTE_API float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q);
|
SRSLTE_API float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q);
|
||||||
|
|
||||||
SRSLTE_API float srslte_chest_dl_get_rsrq(srslte_chest_dl_t *q);
|
SRSLTE_API float srslte_chest_dl_get_rsrq(srslte_chest_dl_t *q);
|
||||||
|
|
|
@ -41,18 +41,24 @@
|
||||||
#include "srslte/config.h"
|
#include "srslte/config.h"
|
||||||
#include "srslte/common/phy_common.h"
|
#include "srslte/common/phy_common.h"
|
||||||
|
|
||||||
|
#define SRSLTE_CQI_MAX_BITS 20
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool configured;
|
bool configured;
|
||||||
uint32_t pmi_idx;
|
uint32_t pmi_idx;
|
||||||
} srslte_cqi_cfg_t;
|
bool simul_cqi_ack;
|
||||||
|
bool format_is_subband;
|
||||||
|
uint32_t subband_size;
|
||||||
|
} srslte_cqi_periodic_cfg_t;
|
||||||
|
|
||||||
/* Table 5.2.2.6.2-1: Fields for channel quality information feedback for higher layer configured subband
|
/* Table 5.2.2.6.2-1: Fields for channel quality information feedback for higher layer configured subband
|
||||||
CQI reports
|
CQI reports
|
||||||
(transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and
|
(transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and
|
||||||
transmission mode 8 configured without PMI/RI reporting). */
|
transmission mode 8 configured without PMI/RI reporting). */
|
||||||
typedef struct SRSLTE_API {
|
typedef struct SRSLTE_API {
|
||||||
uint8_t wideband_cqi; // 4-bit width
|
uint8_t wideband_cqi; // 4-bit width
|
||||||
uint32_t subband_diff_cqi; // 2N-bit width
|
uint32_t subband_diff_cqi; // 2N-bit width
|
||||||
|
uint32_t N;
|
||||||
} srslte_cqi_hl_subband_t;
|
} srslte_cqi_hl_subband_t;
|
||||||
|
|
||||||
/* Table 5.2.2.6.3-1: Fields for channel quality information feedback for UE selected subband CQI
|
/* Table 5.2.2.6.3-1: Fields for channel quality information feedback for UE selected subband CQI
|
||||||
|
@ -60,9 +66,10 @@ reports
|
||||||
(transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and
|
(transmission mode 1, transmission mode 2, transmission mode 3, transmission mode 7 and
|
||||||
transmission mode 8 configured without PMI/RI reporting). */
|
transmission mode 8 configured without PMI/RI reporting). */
|
||||||
typedef struct SRSLTE_API {
|
typedef struct SRSLTE_API {
|
||||||
uint8_t wideband_cqi; // 4-bit width
|
uint8_t wideband_cqi; // 4-bit width
|
||||||
uint8_t subband_diff_cqi; // 2-bit width
|
uint8_t subband_diff_cqi; // 2-bit width
|
||||||
uint32_t position_subband; // L-bit width
|
uint32_t position_subband; // L-bit width
|
||||||
|
uint32_t L;
|
||||||
} srslte_cqi_ue_subband_t;
|
} srslte_cqi_ue_subband_t;
|
||||||
|
|
||||||
/* Table 5.2.3.3.1-1: Fields for channel quality information feedback for wideband CQI reports
|
/* Table 5.2.3.3.1-1: Fields for channel quality information feedback for wideband CQI reports
|
||||||
|
@ -71,34 +78,51 @@ transmission mode 8 configured without PMI/RI reporting).
|
||||||
This is for PUCCH Format 2 reports
|
This is for PUCCH Format 2 reports
|
||||||
*/
|
*/
|
||||||
typedef struct SRSLTE_API {
|
typedef struct SRSLTE_API {
|
||||||
uint8_t wideband_cqi; // 4-bit width
|
uint8_t wideband_cqi; // 4-bit width
|
||||||
} srslte_cqi_format2_wideband_t;
|
} srslte_cqi_format2_wideband_t;
|
||||||
|
|
||||||
typedef struct SRSLTE_API {
|
typedef struct SRSLTE_API {
|
||||||
uint8_t subband_cqi; // 4-bit width
|
uint8_t subband_cqi; // 4-bit width
|
||||||
uint8_t subband_label; // 1- or 2-bit width
|
uint8_t subband_label; // 1- or 2-bit width
|
||||||
|
bool subband_label_2_bits; // false, label=1-bit, true label=2-bits
|
||||||
} srslte_cqi_format2_subband_t;
|
} srslte_cqi_format2_subband_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SRSLTE_CQI_TYPE_WIDEBAND = 0,
|
||||||
|
SRSLTE_CQI_TYPE_SUBBAND,
|
||||||
|
SRSLTE_CQI_TYPE_SUBBAND_UE,
|
||||||
|
SRSLTE_CQI_TYPE_SUBBAND_HL
|
||||||
|
} srslte_cqi_type_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
union {
|
||||||
|
srslte_cqi_format2_wideband_t wideband;
|
||||||
|
srslte_cqi_format2_subband_t subband;
|
||||||
|
srslte_cqi_ue_subband_t subband_ue;
|
||||||
|
srslte_cqi_hl_subband_t subband_hl;
|
||||||
|
};
|
||||||
|
srslte_cqi_type_t type;
|
||||||
|
} srslte_cqi_value_t;
|
||||||
|
|
||||||
|
|
||||||
|
SRSLTE_API int srslte_cqi_value_pack(srslte_cqi_value_t *value,
|
||||||
|
uint8_t buff[SRSLTE_CQI_MAX_BITS]);
|
||||||
|
|
||||||
SRSLTE_API int srslte_cqi_hl_subband_pack(srslte_cqi_hl_subband_t *msg,
|
SRSLTE_API int srslte_cqi_hl_subband_pack(srslte_cqi_hl_subband_t *msg,
|
||||||
uint32_t N,
|
uint8_t buff[SRSLTE_CQI_MAX_BITS]);
|
||||||
uint8_t *buff,
|
|
||||||
uint32_t buff_len);
|
|
||||||
|
|
||||||
SRSLTE_API int srslte_cqi_ue_subband_pack(srslte_cqi_ue_subband_t *msg,
|
SRSLTE_API int srslte_cqi_ue_subband_pack(srslte_cqi_ue_subband_t *msg,
|
||||||
uint32_t L,
|
uint8_t buff[SRSLTE_CQI_MAX_BITS]);
|
||||||
uint8_t *buff,
|
|
||||||
uint32_t buff_len);
|
|
||||||
|
|
||||||
SRSLTE_API int srslte_cqi_format2_wideband_pack(srslte_cqi_format2_wideband_t *msg,
|
SRSLTE_API int srslte_cqi_format2_wideband_pack(srslte_cqi_format2_wideband_t *msg,
|
||||||
uint8_t *buff,
|
uint8_t buff[SRSLTE_CQI_MAX_BITS]);
|
||||||
uint32_t buff_len);
|
|
||||||
|
|
||||||
SRSLTE_API int srslte_cqi_format2_subband_pack(srslte_cqi_format2_subband_t *msg,
|
SRSLTE_API int srslte_cqi_format2_subband_pack(srslte_cqi_format2_subband_t *msg,
|
||||||
uint8_t *buff,
|
uint8_t buff[SRSLTE_CQI_MAX_BITS]);
|
||||||
uint32_t buff_len);
|
|
||||||
|
|
||||||
SRSLTE_API bool srslte_cqi_send(uint32_t I_cqi_pmi,
|
SRSLTE_API bool srslte_cqi_send(uint32_t I_cqi_pmi,
|
||||||
uint32_t tti);
|
uint32_t tti);
|
||||||
|
|
||||||
|
SRSLTE_API uint8_t srslte_cqi_from_snr(float snr);
|
||||||
|
|
||||||
#endif // CQI_
|
#endif // CQI_
|
||||||
|
|
|
@ -40,9 +40,10 @@
|
||||||
#include "srslte/common/phy_common.h"
|
#include "srslte/common/phy_common.h"
|
||||||
#include "srslte/common/sequence.h"
|
#include "srslte/common/sequence.h"
|
||||||
#include "srslte/modem/mod.h"
|
#include "srslte/modem/mod.h"
|
||||||
|
#include "srslte/phch/cqi.h"
|
||||||
|
|
||||||
#define SRSLTE_PUCCH_N_SEQ 12
|
#define SRSLTE_PUCCH_N_SEQ 12
|
||||||
#define SRSLTE_PUCCH_MAX_BITS 20
|
#define SRSLTE_PUCCH_MAX_BITS SRSLTE_CQI_MAX_BITS
|
||||||
#define SRSLTE_PUCCH_MAX_SYMBOLS 120
|
#define SRSLTE_PUCCH_MAX_SYMBOLS 120
|
||||||
|
|
||||||
typedef enum SRSLTE_API {
|
typedef enum SRSLTE_API {
|
||||||
|
|
|
@ -75,6 +75,7 @@ typedef struct SRSLTE_API {
|
||||||
srslte_crc_t crc_cb;
|
srslte_crc_t crc_cb;
|
||||||
|
|
||||||
srslte_uci_cqi_pusch_t uci_cqi;
|
srslte_uci_cqi_pusch_t uci_cqi;
|
||||||
|
srslte_uci_pos_t uci_pos;
|
||||||
|
|
||||||
} srslte_sch_t;
|
} srslte_sch_t;
|
||||||
|
|
||||||
|
|
|
@ -40,11 +40,15 @@
|
||||||
#include "srslte/common/phy_common.h"
|
#include "srslte/common/phy_common.h"
|
||||||
#include "srslte/phch/pusch_cfg.h"
|
#include "srslte/phch/pusch_cfg.h"
|
||||||
#include "srslte/fec/crc.h"
|
#include "srslte/fec/crc.h"
|
||||||
|
#include "srslte/phch/cqi.h"
|
||||||
|
|
||||||
#define SRSLTE_UCI_MAX_CQI_LEN_PUSCH 512
|
#define SRSLTE_UCI_MAX_CQI_LEN_PUSCH 512
|
||||||
#define SRSLTE_UCI_MAX_CQI_LEN_PUCCH 13
|
#define SRSLTE_UCI_MAX_CQI_LEN_PUCCH 13
|
||||||
#define SRSLTE_UCI_CQI_CODED_PUCCH_B 20
|
#define SRSLTE_UCI_CQI_CODED_PUCCH_B 20
|
||||||
|
|
||||||
|
#define SRSLTE_UCI_ACK_RI_PLACEHOLDER_REPETITION 0xC0
|
||||||
|
#define SRSLTE_UCI_ACK_RI_PLACEHOLDER 0x30
|
||||||
|
|
||||||
typedef struct SRSLTE_API {
|
typedef struct SRSLTE_API {
|
||||||
srslte_crc_t crc;
|
srslte_crc_t crc;
|
||||||
uint8_t tmp_cqi[SRSLTE_UCI_MAX_CQI_LEN_PUSCH];
|
uint8_t tmp_cqi[SRSLTE_UCI_MAX_CQI_LEN_PUSCH];
|
||||||
|
@ -52,7 +56,7 @@ typedef struct SRSLTE_API {
|
||||||
} srslte_uci_cqi_pusch_t;
|
} srslte_uci_cqi_pusch_t;
|
||||||
|
|
||||||
typedef struct SRSLTE_API {
|
typedef struct SRSLTE_API {
|
||||||
uint8_t *uci_cqi;
|
uint8_t uci_cqi[SRSLTE_CQI_MAX_BITS];
|
||||||
uint32_t uci_cqi_len;
|
uint32_t uci_cqi_len;
|
||||||
uint8_t uci_ri; // Only 1-bit supported for RI
|
uint8_t uci_ri; // Only 1-bit supported for RI
|
||||||
uint32_t uci_ri_len;
|
uint32_t uci_ri_len;
|
||||||
|
@ -63,6 +67,11 @@ typedef struct SRSLTE_API {
|
||||||
bool channel_selection;
|
bool channel_selection;
|
||||||
} srslte_uci_data_t;
|
} srslte_uci_data_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t idx;
|
||||||
|
uint32_t pos[SRSLTE_UCI_MAX_CQI_LEN_PUSCH];
|
||||||
|
} srslte_uci_pos_t;
|
||||||
|
|
||||||
SRSLTE_API int srslte_uci_cqi_init(srslte_uci_cqi_pusch_t *q);
|
SRSLTE_API int srslte_uci_cqi_init(srslte_uci_cqi_pusch_t *q);
|
||||||
|
|
||||||
SRSLTE_API void srslte_uci_cqi_free(srslte_uci_cqi_pusch_t *q);
|
SRSLTE_API void srslte_uci_cqi_free(srslte_uci_cqi_pusch_t *q);
|
||||||
|
@ -80,6 +89,7 @@ SRSLTE_API int srslte_uci_encode_cqi_pucch(uint8_t *cqi_data,
|
||||||
uint8_t b_bits[SRSLTE_UCI_CQI_CODED_PUCCH_B]);
|
uint8_t b_bits[SRSLTE_UCI_CQI_CODED_PUCCH_B]);
|
||||||
|
|
||||||
SRSLTE_API int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
|
SRSLTE_API int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
|
||||||
|
srslte_uci_pos_t *pos,
|
||||||
uint8_t data,
|
uint8_t data,
|
||||||
uint32_t O_cqi,
|
uint32_t O_cqi,
|
||||||
float beta,
|
float beta,
|
||||||
|
|
|
@ -49,11 +49,6 @@ SRSLTE_API void srslte_scrambling_b_offset(srslte_sequence_t *s,
|
||||||
int offset,
|
int offset,
|
||||||
int len);
|
int len);
|
||||||
|
|
||||||
SRSLTE_API void srslte_scrambling_b_offset_pusch(srslte_sequence_t *s,
|
|
||||||
uint8_t *data,
|
|
||||||
int offset,
|
|
||||||
int len);
|
|
||||||
|
|
||||||
SRSLTE_API void srslte_scrambling_f(srslte_sequence_t *s,
|
SRSLTE_API void srslte_scrambling_f(srslte_sequence_t *s,
|
||||||
float *data);
|
float *data);
|
||||||
|
|
||||||
|
@ -70,5 +65,4 @@ SRSLTE_API void srslte_scrambling_c_offset(srslte_sequence_t *s,
|
||||||
int offset,
|
int offset,
|
||||||
int len);
|
int len);
|
||||||
|
|
||||||
|
|
||||||
#endif // SCRAMBLING_
|
#endif // SCRAMBLING_
|
||||||
|
|
|
@ -380,6 +380,10 @@ float srslte_chest_dl_get_noise_estimate(srslte_chest_dl_t *q) {
|
||||||
return srslte_vec_acc_ff(q->noise_estimate, q->cell.nof_ports)/q->cell.nof_ports;
|
return srslte_vec_acc_ff(q->noise_estimate, q->cell.nof_ports)/q->cell.nof_ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float srslte_chest_dl_get_snr(srslte_chest_dl_t *q) {
|
||||||
|
return srslte_chest_dl_get_rsrp(q)/srslte_chest_dl_get_noise_estimate(q);
|
||||||
|
}
|
||||||
|
|
||||||
float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q) {
|
float srslte_chest_dl_get_rssi(srslte_chest_dl_t *q) {
|
||||||
return 4*q->rssi[0]/q->cell.nof_prb/SRSLTE_NRE;
|
return 4*q->rssi[0]/q->cell.nof_prb/SRSLTE_NRE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,38 +41,53 @@
|
||||||
#include "srslte/utils/debug.h"
|
#include "srslte/utils/debug.h"
|
||||||
|
|
||||||
|
|
||||||
int srslte_cqi_hl_subband_pack(srslte_cqi_hl_subband_t *msg, uint32_t N, uint8_t *buff, uint32_t buff_len)
|
int srslte_cqi_hl_subband_pack(srslte_cqi_hl_subband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS])
|
||||||
{
|
{
|
||||||
uint8_t *body_ptr = buff;
|
uint8_t *body_ptr = buff;
|
||||||
srslte_bit_pack(msg->wideband_cqi, &body_ptr, 4);
|
srslte_bit_pack(msg->wideband_cqi, &body_ptr, 4);
|
||||||
srslte_bit_pack(msg->subband_diff_cqi, &body_ptr, 2*N);
|
srslte_bit_pack(msg->subband_diff_cqi, &body_ptr, 2*msg->N);
|
||||||
|
|
||||||
return 4+2*N;
|
return 4+2*msg->N;
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_cqi_ue_subband_pack(srslte_cqi_ue_subband_t *msg, uint32_t L, uint8_t *buff, uint32_t buff_len)
|
int srslte_cqi_ue_subband_pack(srslte_cqi_ue_subband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS])
|
||||||
{
|
{
|
||||||
uint8_t *body_ptr = buff;
|
uint8_t *body_ptr = buff;
|
||||||
srslte_bit_pack(msg->wideband_cqi, &body_ptr, 4);
|
srslte_bit_pack(msg->wideband_cqi, &body_ptr, 4);
|
||||||
srslte_bit_pack(msg->subband_diff_cqi, &body_ptr, 2);
|
srslte_bit_pack(msg->subband_diff_cqi, &body_ptr, 2);
|
||||||
srslte_bit_pack(msg->subband_diff_cqi, &body_ptr, L);
|
srslte_bit_pack(msg->subband_diff_cqi, &body_ptr, msg->L);
|
||||||
|
|
||||||
return 4+2+L;
|
return 4+2+msg->L;
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_cqi_format2_wideband_pack(srslte_cqi_format2_wideband_t *msg, uint8_t *buff, uint32_t buff_len)
|
int srslte_cqi_format2_wideband_pack(srslte_cqi_format2_wideband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS])
|
||||||
{
|
{
|
||||||
uint8_t *body_ptr = buff;
|
uint8_t *body_ptr = buff;
|
||||||
srslte_bit_pack(msg->wideband_cqi, &body_ptr, 4);
|
srslte_bit_pack(msg->wideband_cqi, &body_ptr, 4);
|
||||||
return 4;
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
int srslte_cqi_format2_subband_pack(srslte_cqi_format2_subband_t *msg, uint8_t *buff, uint32_t buff_len)
|
int srslte_cqi_format2_subband_pack(srslte_cqi_format2_subband_t *msg, uint8_t buff[SRSLTE_CQI_MAX_BITS])
|
||||||
{
|
{
|
||||||
uint8_t *body_ptr = buff;
|
uint8_t *body_ptr = buff;
|
||||||
srslte_bit_pack(msg->subband_cqi, &body_ptr, 4);
|
srslte_bit_pack(msg->subband_cqi, &body_ptr, 4);
|
||||||
srslte_bit_pack(msg->subband_label, &body_ptr, 1);
|
srslte_bit_pack(msg->subband_label, &body_ptr, msg->subband_label_2_bits?2:1);
|
||||||
return 4+1;
|
return 4+msg->subband_label_2_bits?2:1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int srslte_cqi_value_pack(srslte_cqi_value_t *value, uint8_t buff[SRSLTE_CQI_MAX_BITS])
|
||||||
|
{
|
||||||
|
switch(value->type) {
|
||||||
|
case SRSLTE_CQI_TYPE_WIDEBAND:
|
||||||
|
return srslte_cqi_format2_wideband_pack(&value->wideband, buff);
|
||||||
|
case SRSLTE_CQI_TYPE_SUBBAND:
|
||||||
|
return srslte_cqi_format2_subband_pack(&value->subband, buff);
|
||||||
|
case SRSLTE_CQI_TYPE_SUBBAND_UE:
|
||||||
|
return srslte_cqi_ue_subband_pack(&value->subband_ue, buff);
|
||||||
|
case SRSLTE_CQI_TYPE_SUBBAND_HL:
|
||||||
|
return srslte_cqi_hl_subband_pack(&value->subband_hl, buff);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti) {
|
bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti) {
|
||||||
|
@ -123,3 +138,20 @@ bool srslte_cqi_send(uint32_t I_cqi_pmi, uint32_t tti) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* SNR-to-CQI conversion, got from "Downlink SNR to CQI Mapping for Different Multiple Antenna Techniques in LTE"
|
||||||
|
* Table III.
|
||||||
|
*/
|
||||||
|
static float cqi_to_snr_table[15] = { 1.95, 4, 6, 8, 10, 11.95, 14.05, 16, 17.9, 19.9, 21.5, 23.45, 25.0, 27.30, 29};
|
||||||
|
|
||||||
|
uint8_t srslte_cqi_from_snr(float snr)
|
||||||
|
{
|
||||||
|
for (uint8_t cqi=14;cqi>=0;cqi--) {
|
||||||
|
if (snr >= cqi_to_snr_table[cqi]) {
|
||||||
|
return cqi+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -276,8 +276,9 @@ float srslte_pucch_alpha_format2(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint32_t n_cs = (n_cs_cell[ns][l]+n_prime)%SRSLTE_NRE;
|
uint32_t n_cs = (n_cs_cell[ns][l]+n_prime)%SRSLTE_NRE;
|
||||||
DEBUG("n_pucch: %d, ns: %d, l: %d, n_prime: %d, n_cs: %d\n", n_pucch, ns, l, n_prime, n_cs);
|
float alpha = 2 * M_PI * (n_cs) / SRSLTE_NRE;
|
||||||
return 2 * M_PI * (n_cs) / SRSLTE_NRE;
|
DEBUG("n_pucch: %d, ns: %d, l: %d, n_prime: %d, n_cs: %d, alpha=%f\n", n_pucch, ns, l, n_prime, n_cs, alpha);
|
||||||
|
return alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map PUCCH symbols to physical resources according to 5.4.3 in 36.211 */
|
/* Map PUCCH symbols to physical resources according to 5.4.3 in 36.211 */
|
||||||
|
@ -358,7 +359,7 @@ void srslte_pucch_free(srslte_pucch_t *q) {
|
||||||
|
|
||||||
int srslte_pucch_set_crnti(srslte_pucch_t *q, uint16_t c_rnti) {
|
int srslte_pucch_set_crnti(srslte_pucch_t *q, uint16_t c_rnti) {
|
||||||
for (uint32_t sf_idx=0;sf_idx<SRSLTE_NSUBFRAMES_X_FRAME;sf_idx++) {
|
for (uint32_t sf_idx=0;sf_idx<SRSLTE_NSUBFRAMES_X_FRAME;sf_idx++) {
|
||||||
// Precompute scrambling sequence for pucch format 2
|
// Precompute scrambling sequence for pucch format 2
|
||||||
if (srslte_sequence_pucch(&q->seq_f2[sf_idx], c_rnti, 2*sf_idx, q->cell.id)) {
|
if (srslte_sequence_pucch(&q->seq_f2[sf_idx], c_rnti, 2*sf_idx, q->cell.id)) {
|
||||||
fprintf(stderr, "Error computing PUCCH Format 2 scrambling sequence\n");
|
fprintf(stderr, "Error computing PUCCH Format 2 scrambling sequence\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
|
@ -503,19 +504,18 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
|
||||||
uint32_t N_sf_0 = get_N_sf(format, 0, q->shortened);
|
uint32_t N_sf_0 = get_N_sf(format, 0, q->shortened);
|
||||||
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
|
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
|
||||||
uint32_t N_sf = get_N_sf(format, ns%2, q->shortened);
|
uint32_t N_sf = get_N_sf(format, ns%2, q->shortened);
|
||||||
|
DEBUG("ns=%d, N_sf=%d\n", ns, N_sf);
|
||||||
// Get group hopping number u
|
// Get group hopping number u
|
||||||
uint32_t f_gh=0;
|
uint32_t f_gh=0;
|
||||||
if (q->group_hopping_en) {
|
if (q->group_hopping_en) {
|
||||||
f_gh = q->f_gh[ns];
|
f_gh = q->f_gh[ns];
|
||||||
}
|
}
|
||||||
uint32_t u = (f_gh + (q->cell.id%30))%30;
|
uint32_t u = (f_gh + (q->cell.id%30))%30;
|
||||||
|
|
||||||
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
|
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
|
||||||
uint32_t N_sf_widx = N_sf==3?1:0;
|
uint32_t N_sf_widx = N_sf==3?1:0;
|
||||||
for (uint32_t m=0;m<N_sf;m++) {
|
for (uint32_t m=0;m<N_sf;m++) {
|
||||||
uint32_t l = get_pucch_symbol(m, format, q->cell.cp);
|
uint32_t l = get_pucch_symbol(m, format, q->cell.cp);
|
||||||
uint32_t n_prime_ns;
|
|
||||||
uint32_t n_oc;
|
|
||||||
float alpha=0;
|
float alpha=0;
|
||||||
if (format >= SRSLTE_PUCCH_FORMAT_2) {
|
if (format >= SRSLTE_PUCCH_FORMAT_2) {
|
||||||
alpha = srslte_pucch_alpha_format2(q->n_cs_cell, &q->pucch_cfg, n_pucch, ns, l);
|
alpha = srslte_pucch_alpha_format2(q->n_cs_cell, &q->pucch_cfg, n_pucch, ns, l);
|
||||||
|
@ -523,6 +523,8 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
|
||||||
q->z[(ns%2)*N_sf*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->d[(ns%2)*N_sf+m]*cexpf(I*(q->tmp_arg[n]+alpha*n));
|
q->z[(ns%2)*N_sf*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->d[(ns%2)*N_sf+m]*cexpf(I*(q->tmp_arg[n]+alpha*n));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
uint32_t n_prime_ns=0;
|
||||||
|
uint32_t n_oc=0;
|
||||||
alpha = srslte_pucch_alpha_format1(q->n_cs_cell, &q->pucch_cfg, n_pucch, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns);
|
alpha = srslte_pucch_alpha_format1(q->n_cs_cell, &q->pucch_cfg, n_pucch, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns);
|
||||||
float S_ns = 0;
|
float S_ns = 0;
|
||||||
if (n_prime_ns%2) {
|
if (n_prime_ns%2) {
|
||||||
|
@ -531,12 +533,12 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format,
|
||||||
DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n",
|
DEBUG("PUCCH d_0: %.1f+%.1fi, alpha: %.1f, n_oc: %d, n_prime_ns: %d, n_rb_2=%d\n",
|
||||||
__real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2);
|
__real__ q->d[0], __imag__ q->d[0], alpha, n_oc, n_prime_ns, q->pucch_cfg.n_rb_2);
|
||||||
for (uint32_t n=0;n<SRSLTE_PUCCH_N_SEQ;n++) {
|
for (uint32_t n=0;n<SRSLTE_PUCCH_N_SEQ;n++) {
|
||||||
q->z[(ns%2)*N_sf_0*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = q->d[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns));
|
q->z[(ns%2)*N_sf_0*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] =
|
||||||
|
q->d[0]*cexpf(I*(w_n_oc[N_sf_widx][n_oc%3][m]+q->tmp_arg[n]+alpha*n+S_ns));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pucch_put(q, format, n_pucch, sf_symbols)) {
|
if (pucch_put(q, format, n_pucch, sf_symbols)) {
|
||||||
fprintf(stderr, "Error putting PUCCH symbols\n");
|
fprintf(stderr, "Error putting PUCCH symbols\n");
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
|
|
|
@ -242,7 +242,7 @@ int srslte_pusch_init(srslte_pusch_t *q, srslte_cell_t cell) {
|
||||||
}
|
}
|
||||||
q->d = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
|
q->d = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
|
||||||
if (!q->d) {
|
if (!q->d) {
|
||||||
goto clean;
|
goto clean;
|
||||||
}
|
}
|
||||||
|
|
||||||
q->ce = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
|
q->ce = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
|
||||||
|
@ -538,11 +538,24 @@ int srslte_pusch_uci_encode_rnti(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srs
|
||||||
if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
|
if (srslte_sequence_pusch(&seq, rnti, 2 * cfg->sf_idx, q->cell.id, cfg->nbits.nof_bits)) {
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
srslte_scrambling_b_offset_pusch(&seq, (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
|
srslte_scrambling_b_offset(&seq, (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
|
||||||
srslte_sequence_free(&seq);
|
srslte_sequence_free(&seq);
|
||||||
} else {
|
} else {
|
||||||
srslte_scrambling_b_offset_pusch(&q->seq[cfg->sf_idx], (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
|
srslte_scrambling_b_offset(&q->seq[cfg->sf_idx], (uint8_t*) q->q, 0, cfg->nbits.nof_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Correct UCI placeholder bits
|
||||||
|
uint8_t *d = q->q;
|
||||||
|
for (int i = 0; i < q->dl_sch.uci_pos.idx; i++) {
|
||||||
|
if (d[q->dl_sch.uci_pos.pos[i]] & SRSLTE_UCI_ACK_RI_PLACEHOLDER) {
|
||||||
|
d[q->dl_sch.uci_pos.pos[i]] = 1;
|
||||||
|
} else if (d[q->dl_sch.uci_pos.pos[i]] & SRSLTE_UCI_ACK_RI_PLACEHOLDER_REPETITION) {
|
||||||
|
if (q->dl_sch.uci_pos.pos[i] > 1) {
|
||||||
|
d[q->dl_sch.uci_pos.pos[i]] = d[q->dl_sch.uci_pos.pos[i]-1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->q, q->d, cfg->nbits.nof_bits);
|
srslte_mod_modulate(&q->mod[cfg->grant.mcs.mod], (uint8_t*) q->q, q->d, cfg->nbits.nof_bits);
|
||||||
srslte_dft_precoding(&q->dft_precoding, q->d, q->z, cfg->grant.L_prb, cfg->nbits.nof_symb);
|
srslte_dft_precoding(&q->dft_precoding, q->d, q->z, cfg->grant.L_prb, cfg->nbits.nof_symb);
|
||||||
|
|
||||||
|
|
|
@ -274,9 +274,10 @@ static int encode_tb(srslte_sch_t *q,
|
||||||
|
|
||||||
/* Turbo Encoding */
|
/* Turbo Encoding */
|
||||||
srslte_tcod_encode(&q->encoder, q->cb_temp, (uint8_t*) q->cb_out, cb_len);
|
srslte_tcod_encode(&q->encoder, q->cb_temp, (uint8_t*) q->cb_out, cb_len);
|
||||||
|
|
||||||
if (SRSLTE_VERBOSE_ISDEBUG()) {
|
if (SRSLTE_VERBOSE_ISDEBUG()) {
|
||||||
DEBUG("CB#%d encoded: ", i);
|
DEBUG("CB#%d encoded: ", i);
|
||||||
srslte_vec_fprint_b(stdout, q->cb_out, cb_len);
|
srslte_vec_fprint_b(stdout, q->cb_out, 3*cb_len+12);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -496,7 +497,8 @@ int srslte_ulsch_decode(srslte_sch_t *q, srslte_pusch_cfg_t *cfg, srslte_softbuf
|
||||||
|
|
||||||
|
|
||||||
/* UL-SCH channel interleaver according to 5.5.2.8 of 36.212 */
|
/* UL-SCH channel interleaver according to 5.5.2.8 of 36.212 */
|
||||||
void ulsch_interleave(uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, uint8_t *q_bits)
|
void ulsch_interleave(srslte_uci_pos_t *q, uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total,
|
||||||
|
uint32_t N_pusch_symbs, uint8_t *q_bits)
|
||||||
{
|
{
|
||||||
|
|
||||||
uint32_t rows = H_prime_total/N_pusch_symbs;
|
uint32_t rows = H_prime_total/N_pusch_symbs;
|
||||||
|
@ -508,6 +510,11 @@ void ulsch_interleave(uint8_t *g_bits, uint32_t Qm, uint32_t H_prime_total, uint
|
||||||
for(uint32_t k=0; k<Qm; k++) {
|
for(uint32_t k=0; k<Qm; k++) {
|
||||||
if (q_bits[j*Qm + i*rows*Qm + k] >= 10) {
|
if (q_bits[j*Qm + i*rows*Qm + k] >= 10) {
|
||||||
q_bits[j*Qm + i*rows*Qm + k] -= 10;
|
q_bits[j*Qm + i*rows*Qm + k] -= 10;
|
||||||
|
q->pos[q->idx%SRSLTE_UCI_MAX_CQI_LEN_PUSCH] = j*Qm + i*rows*Qm + k;
|
||||||
|
q->idx++;
|
||||||
|
if (q->idx >= SRSLTE_UCI_MAX_CQI_LEN_PUSCH) {
|
||||||
|
fprintf(stderr, "Error number of UCI bits exceeds SRSLTE_UCI_MAX_CQI_LEN_PUSCH\n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
q_bits[j*Qm + i*rows*Qm + k] = g_bits[idx];
|
q_bits[j*Qm + i*rows*Qm + k] = g_bits[idx];
|
||||||
idx++;
|
idx++;
|
||||||
|
@ -569,7 +576,7 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q,
|
||||||
}
|
}
|
||||||
|
|
||||||
e_offset += Q_prime_cqi*Qm;
|
e_offset += Q_prime_cqi*Qm;
|
||||||
|
|
||||||
// Encode UL-SCH
|
// Encode UL-SCH
|
||||||
if (cfg->cb_segm.tbs > 0) {
|
if (cfg->cb_segm.tbs > 0) {
|
||||||
uint32_t G = nb_q/Qm - Q_prime_ri - Q_prime_cqi;
|
uint32_t G = nb_q/Qm - Q_prime_ri - Q_prime_cqi;
|
||||||
|
@ -580,17 +587,18 @@ int srslte_ulsch_uci_encode(srslte_sch_t *q,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interleave UL-SCH (and RI and CQI)
|
// Interleave UL-SCH (and RI and CQI)
|
||||||
ulsch_interleave(g_bits, Qm, nb_q/Qm, cfg->nbits.nof_symb, q_bits);
|
q->uci_pos.idx=0;
|
||||||
|
ulsch_interleave(&q->uci_pos, g_bits, Qm, nb_q/Qm, cfg->nbits.nof_symb, q_bits);
|
||||||
|
|
||||||
// Encode (and interleave) ACK
|
// Encode (and interleave) ACK
|
||||||
if (uci_data.uci_ack_len > 0) {
|
if (uci_data.uci_ack_len > 0) {
|
||||||
float beta = beta_harq_offset[cfg->uci_cfg.I_offset_ack];
|
float beta = beta_harq_offset[cfg->uci_cfg.I_offset_ack];
|
||||||
if (cfg->cb_segm.tbs == 0) {
|
if (cfg->cb_segm.tbs == 0) {
|
||||||
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
beta /= beta_cqi_offset[cfg->uci_cfg.I_offset_cqi];
|
||||||
}
|
}
|
||||||
ret = srslte_uci_encode_ack(cfg, uci_data.uci_ack, uci_data.uci_cqi_len, beta, nb_q/Qm, q_bits);
|
ret = srslte_uci_encode_ack(cfg, &q->uci_pos, uci_data.uci_ack, uci_data.uci_cqi_len, beta, nb_q/Qm, q_bits);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,7 +204,7 @@ int srslte_uci_encode_cqi_pucch(uint8_t *cqi_data, uint32_t cqi_len, uint8_t b_b
|
||||||
for (uint32_t i=0;i<SRSLTE_UCI_CQI_CODED_PUCCH_B;i++) {
|
for (uint32_t i=0;i<SRSLTE_UCI_CQI_CODED_PUCCH_B;i++) {
|
||||||
uint64_t x=0;
|
uint64_t x=0;
|
||||||
for (uint32_t n=0;n<cqi_len;n++) {
|
for (uint32_t n=0;n<cqi_len;n++) {
|
||||||
x += cqi_data[n]*M_basis_seq_pucch[n][i];
|
x += cqi_data[n]*M_basis_seq_pucch[i][n];
|
||||||
}
|
}
|
||||||
b_bits[i] = (uint8_t) (x%2);
|
b_bits[i] = (uint8_t) (x%2);
|
||||||
}
|
}
|
||||||
|
@ -242,7 +242,7 @@ int srslte_uci_encode_cqi_pusch(srslte_uci_cqi_pusch_t *q, srslte_pusch_cfg_t *c
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Inserts UCI-ACK bits into the correct positions in the g buffer before interleaving */
|
/* Inserts UCI-ACK bits into the correct positions in the g buffer before interleaving */
|
||||||
static int uci_ulsch_interleave_ack(uint8_t ack_coded_bits[6], uint32_t ack_q_bit_idx,
|
static int uci_ulsch_interleave_ack(srslte_uci_pos_t *q, uint8_t ack_coded_bits[6], uint32_t ack_q_bit_idx,
|
||||||
uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, srslte_cp_t cp,
|
uint32_t Qm, uint32_t H_prime_total, uint32_t N_pusch_symbs, srslte_cp_t cp,
|
||||||
uint8_t *q_bits) {
|
uint8_t *q_bits) {
|
||||||
|
|
||||||
|
@ -255,8 +255,14 @@ static int uci_ulsch_interleave_ack(uint8_t ack_coded_bits[6], uint32_t ack_q_bi
|
||||||
uint32_t colidx = (3*ack_q_bit_idx)%4;
|
uint32_t colidx = (3*ack_q_bit_idx)%4;
|
||||||
uint32_t col = SRSLTE_CP_ISNORM(cp)?ack_column_set_norm[colidx]:ack_column_set_ext[colidx];
|
uint32_t col = SRSLTE_CP_ISNORM(cp)?ack_column_set_norm[colidx]:ack_column_set_ext[colidx];
|
||||||
for(uint32_t k=0; k<Qm; k++) {
|
for(uint32_t k=0; k<Qm; k++) {
|
||||||
q_bits[row *Qm +
|
q_bits[row *Qm + (H_prime_total/N_pusch_symbs)*col*Qm + k] = ack_coded_bits[k];
|
||||||
(H_prime_total/N_pusch_symbs)*col*Qm + k] = ack_coded_bits[k];
|
|
||||||
|
// Save position for placeholder bits
|
||||||
|
q->pos[q->idx%SRSLTE_UCI_MAX_CQI_LEN_PUSCH] = row *Qm + (H_prime_total/N_pusch_symbs)*col*Qm + k;
|
||||||
|
q->idx++;
|
||||||
|
if (q->idx >= SRSLTE_UCI_MAX_CQI_LEN_PUSCH) {
|
||||||
|
fprintf(stderr, "Error number of UCI bits exceeds SRSLTE_UCI_MAX_CQI_LEN_PUSCH\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return SRSLTE_SUCCESS;
|
return SRSLTE_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
|
@ -278,7 +284,7 @@ static int uci_ulsch_interleave_ri(uint8_t ri_coded_bits[6], uint32_t ri_q_bit_i
|
||||||
uint32_t row = H_prime_total/N_pusch_symbs-1-ri_q_bit_idx/4;
|
uint32_t row = H_prime_total/N_pusch_symbs-1-ri_q_bit_idx/4;
|
||||||
uint32_t colidx = (3*ri_q_bit_idx)%4;
|
uint32_t colidx = (3*ri_q_bit_idx)%4;
|
||||||
uint32_t col = SRSLTE_CP_ISNORM(cp)?ri_column_set_norm[colidx]:ri_column_set_ext[colidx];
|
uint32_t col = SRSLTE_CP_ISNORM(cp)?ri_column_set_norm[colidx]:ri_column_set_ext[colidx];
|
||||||
printf("r=%d-%d\n",H_prime_total/N_pusch_symbs,1+ri_q_bit_idx/4);
|
|
||||||
for(uint32_t k=0; k<Qm; k++) {
|
for(uint32_t k=0; k<Qm; k++) {
|
||||||
q_bits[row *Qm + (H_prime_total/N_pusch_symbs)*col*Qm + k] = 10+ri_coded_bits[k];
|
q_bits[row *Qm + (H_prime_total/N_pusch_symbs)*col*Qm + k] = 10+ri_coded_bits[k];
|
||||||
}
|
}
|
||||||
|
@ -319,16 +325,16 @@ static uint32_t Q_prime_ri_ack(srslte_pusch_cfg_t *cfg,
|
||||||
|
|
||||||
static void encode_ri_ack(uint8_t data, uint8_t q_encoded_bits[6], uint8_t Qm) {
|
static void encode_ri_ack(uint8_t data, uint8_t q_encoded_bits[6], uint8_t Qm) {
|
||||||
q_encoded_bits[0] = data;
|
q_encoded_bits[0] = data;
|
||||||
q_encoded_bits[1] = 2;
|
q_encoded_bits[1] = SRSLTE_UCI_ACK_RI_PLACEHOLDER_REPETITION;
|
||||||
for (uint32_t i=2;i<Qm;i++) {
|
for (uint32_t i=2;i<Qm;i++) {
|
||||||
q_encoded_bits[i] = 3;
|
q_encoded_bits[i] = SRSLTE_UCI_ACK_RI_PLACEHOLDER;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Encode UCI HARQ/ACK bits as described in 5.2.2.6 of 36.212
|
/* Encode UCI HARQ/ACK bits as described in 5.2.2.6 of 36.212
|
||||||
* Currently only supporting 1-bit HARQ
|
* Currently only supporting 1-bit HARQ
|
||||||
*/
|
*/
|
||||||
int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
|
int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg, srslte_uci_pos_t *pos,
|
||||||
uint8_t data,
|
uint8_t data,
|
||||||
uint32_t O_cqi, float beta, uint32_t H_prime_total,
|
uint32_t O_cqi, float beta, uint32_t H_prime_total,
|
||||||
uint8_t *q_bits)
|
uint8_t *q_bits)
|
||||||
|
@ -344,7 +350,7 @@ int srslte_uci_encode_ack(srslte_pusch_cfg_t *cfg,
|
||||||
encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm);
|
encode_ri_ack(data, q_encoded_bits, cfg->grant.Qm);
|
||||||
|
|
||||||
for (uint32_t i=0;i<Qprime;i++) {
|
for (uint32_t i=0;i<Qprime;i++) {
|
||||||
uci_ulsch_interleave_ack(q_encoded_bits, i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, q_bits);
|
uci_ulsch_interleave_ack(pos, q_encoded_bits, i, cfg->grant.Qm, H_prime_total, cfg->nbits.nof_symb, cfg->cp, q_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (int) Qprime;
|
return (int) Qprime;
|
||||||
|
|
|
@ -45,7 +45,6 @@ void help()
|
||||||
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
{
|
{
|
||||||
srslte_sch_t dlsch;
|
srslte_sch_t dlsch;
|
||||||
uint8_t *trblkin;
|
|
||||||
srslte_pdsch_cfg_t cfg;
|
srslte_pdsch_cfg_t cfg;
|
||||||
srslte_softbuffer_tx_t softbuffer;
|
srslte_softbuffer_tx_t softbuffer;
|
||||||
|
|
||||||
|
@ -61,13 +60,18 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
srslte_cell_t cell;
|
srslte_cell_t cell;
|
||||||
cell.nof_prb = 100;
|
cell.nof_prb = 100;
|
||||||
cell.id=1;
|
cell.id=1;
|
||||||
|
srslte_verbose = SRSLTE_VERBOSE_NONE;
|
||||||
|
|
||||||
cfg.grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
uint8_t *trblkin_bits = NULL;
|
||||||
|
cfg.grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin_bits);
|
||||||
if (cfg.grant.mcs.tbs == 0) {
|
if (cfg.grant.mcs.tbs == 0) {
|
||||||
mexErrMsgTxt("Error trblklen is zero\n");
|
mexErrMsgTxt("Error trblklen is zero\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
uint8_t *trblkin = srslte_vec_malloc(cfg.grant.mcs.tbs/8);
|
||||||
|
srslte_bit_unpack_vector(trblkin_bits, trblkin, cfg.grant.mcs.tbs);
|
||||||
|
free(trblkin_bits);
|
||||||
|
|
||||||
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &cfg.rv)) {
|
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &cfg.rv)) {
|
||||||
mexErrMsgTxt("Field RV not found in dlsch config\n");
|
mexErrMsgTxt("Field RV not found in dlsch config\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -136,6 +136,8 @@ int main(int argc, char **argv) {
|
||||||
bzero(&pdsch_cfg, sizeof(srslte_pdsch_cfg_t));
|
bzero(&pdsch_cfg, sizeof(srslte_pdsch_cfg_t));
|
||||||
bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
|
bzero(ce, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
|
||||||
bzero(slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
|
bzero(slot_symbols, sizeof(cf_t*)*SRSLTE_MAX_PORTS);
|
||||||
|
bzero(&softbuffer_rx, sizeof(srslte_softbuffer_rx_t));
|
||||||
|
bzero(&softbuffer_tx, sizeof(srslte_softbuffer_tx_t));
|
||||||
|
|
||||||
srslte_ra_dl_grant_t grant;
|
srslte_ra_dl_grant_t grant;
|
||||||
grant.mcs.tbs = tbs;
|
grant.mcs.tbs = tbs;
|
||||||
|
|
|
@ -207,13 +207,17 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
noise_power = srslte_chest_dl_get_noise_estimate(&chest);
|
noise_power = srslte_chest_dl_get_noise_estimate(&chest);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *data = malloc(sizeof(uint8_t) * grant.mcs.tbs);
|
uint8_t *data_bytes = srslte_vec_malloc(sizeof(uint8_t) * grant.mcs.tbs/8);
|
||||||
if (!data) {
|
if (!data_bytes) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, data);
|
int r = srslte_pdsch_decode(&pdsch, &cfg, &softbuffer, input_fft, ce, noise_power, data_bytes);
|
||||||
|
|
||||||
|
free(data_bytes);
|
||||||
|
|
||||||
|
uint8_t *data = malloc(grant.mcs.tbs);
|
||||||
|
srslte_bit_pack_vector(data_bytes, data, grant.mcs.tbs);
|
||||||
|
|
||||||
if (nlhs >= 1) {
|
if (nlhs >= 1) {
|
||||||
plhs[0] = mxCreateLogicalScalar(r == 0);
|
plhs[0] = mxCreateLogicalScalar(r == 0);
|
||||||
|
|
|
@ -51,6 +51,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
help();
|
help();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
srslte_verbose = SRSLTE_VERBOSE_DEBUG;
|
||||||
|
|
||||||
srslte_cell_t cell;
|
srslte_cell_t cell;
|
||||||
bzero(&cell, sizeof(srslte_cell_t));
|
bzero(&cell, sizeof(srslte_cell_t));
|
||||||
|
@ -96,6 +97,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
mexErrMsgTxt("Field DeltaShift not found in PUCCHCFG\n");
|
mexErrMsgTxt("Field DeltaShift not found in PUCCHCFG\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (mexutils_read_uint32_struct(PUCCHCFG, "ResourceSize", &pucch_cfg.n_rb_2)) {
|
||||||
|
mexErrMsgTxt("Field DeltaShift not found in PUCCHCFG\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (mexutils_read_uint32_struct(PUCCHCFG, "CyclicShifts", &pucch_cfg.N_cs)) {
|
if (mexutils_read_uint32_struct(PUCCHCFG, "CyclicShifts", &pucch_cfg.N_cs)) {
|
||||||
mexErrMsgTxt("Field CyclicShifts not found in PUCCHCFG\n");
|
mexErrMsgTxt("Field CyclicShifts not found in PUCCHCFG\n");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -35,15 +35,16 @@
|
||||||
#include "srslte/srslte.h"
|
#include "srslte/srslte.h"
|
||||||
|
|
||||||
srslte_cell_t cell = {
|
srslte_cell_t cell = {
|
||||||
6, // nof_prb
|
25, // nof_prb
|
||||||
1, // nof_ports
|
1, // nof_ports
|
||||||
0, // cell_id
|
2, // bw_idx = 5 MHz
|
||||||
|
1, // cell_id
|
||||||
SRSLTE_CP_NORM, // cyclic prefix
|
SRSLTE_CP_NORM, // cyclic prefix
|
||||||
SRSLTE_PHICH_SRSLTE_PHICH_R_1_6, // PHICH resources
|
SRSLTE_PHICH_SRSLTE_PHICH_R_1_6, // PHICH resources
|
||||||
SRSLTE_PHICH_NORM // PHICH length
|
SRSLTE_PHICH_NORM // PHICH length
|
||||||
};
|
};
|
||||||
|
|
||||||
uint32_t subframe = 1;
|
uint32_t subframe = 0;
|
||||||
|
|
||||||
void usage(char *prog) {
|
void usage(char *prog) {
|
||||||
printf("Usage: %s [csNnv]\n", prog);
|
printf("Usage: %s [csNnv]\n", prog);
|
||||||
|
@ -100,14 +101,14 @@ int main(int argc, char **argv) {
|
||||||
bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t));
|
bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t));
|
||||||
|
|
||||||
for (int i=0;i<SRSLTE_PUCCH_MAX_BITS;i++) {
|
for (int i=0;i<SRSLTE_PUCCH_MAX_BITS;i++) {
|
||||||
bits[i] = rand()%2;
|
bits[i] = i%2;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0;i<2;i++) {
|
for (int i=0;i<2;i++) {
|
||||||
pucch2_bits[i] = rand()%2;
|
pucch2_bits[i] = i%2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (srslte_pucch_set_crnti(&pucch, 1234)) {
|
if (srslte_pucch_set_crnti(&pucch, 11)) {
|
||||||
fprintf(stderr, "Error setting C-RNTI\n");
|
fprintf(stderr, "Error setting C-RNTI\n");
|
||||||
goto quit;
|
goto quit;
|
||||||
}
|
}
|
||||||
|
@ -122,6 +123,12 @@ int main(int argc, char **argv) {
|
||||||
for (uint32_t d=1;d<=3;d++) {
|
for (uint32_t d=1;d<=3;d++) {
|
||||||
for (uint32_t ncs=0;ncs<8;ncs+=d) {
|
for (uint32_t ncs=0;ncs<8;ncs+=d) {
|
||||||
for (uint32_t n_pucch=1;n_pucch<130;n_pucch++) {
|
for (uint32_t n_pucch=1;n_pucch<130;n_pucch++) {
|
||||||
|
|
||||||
|
format=SRSLTE_PUCCH_FORMAT_2;
|
||||||
|
uint32_t d=2;
|
||||||
|
uint32_t ncs=0;
|
||||||
|
uint32_t n_pucch=0;
|
||||||
|
|
||||||
struct timeval t[3];
|
struct timeval t[3];
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
help();
|
help();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
srslte_verbose = SRSLTE_VERBOSE_DEBUG;
|
||||||
|
|
||||||
srslte_cell_t cell;
|
srslte_cell_t cell;
|
||||||
bzero(&cell, sizeof(srslte_cell_t));
|
bzero(&cell, sizeof(srslte_cell_t));
|
||||||
cell.nof_ports = 1;
|
cell.nof_ports = 1;
|
||||||
|
@ -123,8 +124,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
grant.n_prb[1] = prbset[0];
|
grant.n_prb[1] = prbset[0];
|
||||||
free(prbset);
|
free(prbset);
|
||||||
|
|
||||||
uint8_t *trblkin = NULL;
|
uint8_t *trblkin_bits = NULL;
|
||||||
grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin_bits);
|
||||||
|
|
||||||
|
uint8_t *trblkin = srslte_vec_malloc(grant.mcs.tbs/8);
|
||||||
|
srslte_bit_unpack_vector(trblkin_bits, trblkin, grant.mcs.tbs);
|
||||||
|
free(trblkin_bits);
|
||||||
|
|
||||||
grant.M_sc = grant.L_prb*SRSLTE_NRE;
|
grant.M_sc = grant.L_prb*SRSLTE_NRE;
|
||||||
grant.M_sc_init = grant.M_sc; // FIXME: What should M_sc_init be?
|
grant.M_sc_init = grant.M_sc; // FIXME: What should M_sc_init be?
|
||||||
|
@ -156,8 +161,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
|
|
||||||
srslte_uci_data_t uci_data;
|
srslte_uci_data_t uci_data;
|
||||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||||
uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &uci_data.uci_cqi);
|
|
||||||
uint8_t *tmp;
|
uint8_t *tmp;
|
||||||
|
uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &tmp);
|
||||||
|
memcpy(&uci_data.uci_cqi, tmp, uci_data.uci_cqi_len);
|
||||||
|
free(tmp);
|
||||||
uci_data.uci_ri_len = mexutils_read_uint8(RI, &tmp);
|
uci_data.uci_ri_len = mexutils_read_uint8(RI, &tmp);
|
||||||
if (uci_data.uci_ri_len > 0) {
|
if (uci_data.uci_ri_len > 0) {
|
||||||
uci_data.uci_ri = *tmp;
|
uci_data.uci_ri = *tmp;
|
||||||
|
@ -229,9 +236,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
if (nlhs >= 3) {
|
if (nlhs >= 3) {
|
||||||
mexutils_write_cf(pusch.z, &plhs[2], cfg.nbits.nof_re, 1);
|
mexutils_write_cf(pusch.z, &plhs[2], cfg.nbits.nof_re, 1);
|
||||||
}
|
}
|
||||||
|
if (nlhs >= 4) {
|
||||||
|
mexutils_write_uint8(pusch.q, &plhs[3], cfg.nbits.nof_bits, 1);
|
||||||
|
}
|
||||||
srslte_pusch_free(&pusch);
|
srslte_pusch_free(&pusch);
|
||||||
free(trblkin);
|
free(trblkin);
|
||||||
free(uci_data.uci_cqi);
|
|
||||||
free(sf_symbols);
|
free(sf_symbols);
|
||||||
free(scfdma);
|
free(scfdma);
|
||||||
|
|
||||||
|
|
|
@ -167,16 +167,13 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
srslte_uci_data_t uci_data;
|
srslte_uci_data_t uci_data;
|
||||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||||
uci_data.uci_cqi_len = 8;
|
uci_data.uci_cqi_len = 20;
|
||||||
uci_data.uci_ri_len = 0;
|
uci_data.uci_ri_len = 0;
|
||||||
uci_data.uci_ack_len = 1;
|
uci_data.uci_ack_len = 1;
|
||||||
|
|
||||||
uint8_t tmp[20];
|
|
||||||
for (uint32_t i=0;i<20;i++) {
|
for (uint32_t i=0;i<20;i++) {
|
||||||
tmp[i] = 1;
|
uci_data.uci_cqi [i] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uci_data.uci_cqi = tmp;
|
|
||||||
uci_data.uci_ri = 0;
|
uci_data.uci_ri = 0;
|
||||||
uci_data.uci_ack = 0;
|
uci_data.uci_ack = 0;
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ void help()
|
||||||
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
{
|
{
|
||||||
srslte_sch_t ulsch;
|
srslte_sch_t ulsch;
|
||||||
uint8_t *trblkin;
|
|
||||||
srslte_pusch_cfg_t cfg;
|
srslte_pusch_cfg_t cfg;
|
||||||
srslte_softbuffer_tx_t softbuffer;
|
srslte_softbuffer_tx_t softbuffer;
|
||||||
srslte_uci_data_t uci_data;
|
srslte_uci_data_t uci_data;
|
||||||
|
@ -74,10 +74,18 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg.grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
uint8_t *trblkin_bits = NULL;
|
||||||
|
cfg.grant.mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin_bits);
|
||||||
|
|
||||||
uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &uci_data.uci_cqi);
|
uint8_t *trblkin = srslte_vec_malloc(cfg.grant.mcs.tbs/8);
|
||||||
uint8_t *tmp;
|
srslte_bit_unpack_vector(trblkin_bits, trblkin, cfg.grant.mcs.tbs);
|
||||||
|
free(trblkin_bits);
|
||||||
|
|
||||||
|
|
||||||
|
uint8_t *tmp;
|
||||||
|
uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &tmp);
|
||||||
|
memcpy(uci_data.uci_cqi, tmp, uci_data.uci_cqi_len);
|
||||||
|
free(tmp);
|
||||||
uci_data.uci_ri_len = mexutils_read_uint8(RI, &tmp);
|
uci_data.uci_ri_len = mexutils_read_uint8(RI, &tmp);
|
||||||
if (uci_data.uci_ri_len > 0) {
|
if (uci_data.uci_ri_len > 0) {
|
||||||
uci_data.uci_ri = *tmp;
|
uci_data.uci_ri = *tmp;
|
||||||
|
@ -158,6 +166,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
|
|
||||||
mexPrintf("Q_m: %d, NPRB: %d, RV: %d, Nsrs=%d\n", srslte_mod_bits_x_symbol(cfg.grant.mcs.mod), cfg.grant.L_prb, cfg.rv, N_srs);
|
mexPrintf("Q_m: %d, NPRB: %d, RV: %d, Nsrs=%d\n", srslte_mod_bits_x_symbol(cfg.grant.mcs.mod), cfg.grant.L_prb, cfg.rv, N_srs);
|
||||||
|
|
||||||
|
mexPrintf("I_cqi: %d, I_ri: %d, I_ack=%d\n", cfg.uci_cfg.I_offset_cqi, cfg.uci_cfg.I_offset_ri, cfg.uci_cfg.I_offset_ack);
|
||||||
|
|
||||||
if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) {
|
if (srslte_cbsegm(&cfg.cb_segm, cfg.grant.mcs.tbs)) {
|
||||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||||
return;
|
return;
|
||||||
|
@ -195,7 +205,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||||
free(trblkin);
|
free(trblkin);
|
||||||
free(g_bits);
|
free(g_bits);
|
||||||
free(q_bits);
|
free(q_bits);
|
||||||
free(uci_data.uci_cqi);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,7 @@ void srslte_scrambling_b_offset(srslte_sequence_t *s, uint8_t *data, int offset,
|
||||||
int i;
|
int i;
|
||||||
assert (len + offset <= s->len);
|
assert (len + offset <= s->len);
|
||||||
// Do XOR on a word basis
|
// Do XOR on a word basis
|
||||||
|
|
||||||
if (!(len%8)) {
|
if (!(len%8)) {
|
||||||
uint64_t *x = (uint64_t*) data;
|
uint64_t *x = (uint64_t*) data;
|
||||||
uint64_t *y = (uint64_t*) &s->c[offset];
|
uint64_t *y = (uint64_t*) &s->c[offset];
|
||||||
|
@ -75,36 +76,19 @@ void srslte_scrambling_b_offset(srslte_sequence_t *s, uint8_t *data, int offset,
|
||||||
} else if (!(len%4)) {
|
} else if (!(len%4)) {
|
||||||
uint32_t *x = (uint32_t*) data;
|
uint32_t *x = (uint32_t*) data;
|
||||||
uint32_t *y = (uint32_t*) &s->c[offset];
|
uint32_t *y = (uint32_t*) &s->c[offset];
|
||||||
for (int i=0;i<len/8;i++) {
|
for (int i=0;i<len/4;i++) {
|
||||||
x[i] = (x[i] ^ y[i]);
|
x[i] = (x[i] ^ y[i]);
|
||||||
}
|
}
|
||||||
} else if (!(len%2)) {
|
} else if (!(len%2)) {
|
||||||
uint16_t *x = (uint16_t*) data;
|
uint16_t *x = (uint16_t*) data;
|
||||||
uint16_t *y = (uint16_t*) &s->c[offset];
|
uint16_t *y = (uint16_t*) &s->c[offset];
|
||||||
for (int i=0;i<len/8;i++) {
|
for (int i=0;i<len/2;i++) {
|
||||||
x[i] = (x[i] ^ y[i]);
|
x[i] = (x[i] ^ y[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
data[i] = (data[i] + s->c[i + offset]) % 2;
|
data[i] = (data[i] + s->c[i + offset]) % 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* As defined in 36.211 5.3.1 */
|
|
||||||
void srslte_scrambling_b_offset_pusch(srslte_sequence_t *s, uint8_t *data, int offset, int len) {
|
|
||||||
int i;
|
|
||||||
assert (len + offset <= s->len);
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
if (data[i] == 3) {
|
|
||||||
data[i] = 1;
|
|
||||||
} else if (data[i] == 2) {
|
|
||||||
if (i > 1) {
|
|
||||||
data[i] = data[i-1];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
data[i] = (data[i] + s->c[i + offset]) % 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q,
|
||||||
goto clean_exit;
|
goto clean_exit;
|
||||||
}
|
}
|
||||||
srslte_ofdm_set_freq_shift(&q->fft, 0.5);
|
srslte_ofdm_set_freq_shift(&q->fft, 0.5);
|
||||||
srslte_ofdm_set_normalize(&q->fft, false);
|
srslte_ofdm_set_normalize(&q->fft, true);
|
||||||
|
|
||||||
q->normalize_en = false;
|
q->normalize_en = false;
|
||||||
|
|
||||||
|
@ -215,6 +215,66 @@ int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_ra_ul_grant_t *grant,
|
||||||
return srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, grant, &q->uci_cfg, &q->hopping_cfg, &q->srs_cfg, tti, rvidx, current_tx_nb);
|
return srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, grant, &q->uci_cfg, &q->hopping_cfg, &q->srs_cfg, tti, rvidx, current_tx_nb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int pucch_encode_bits(srslte_uci_data_t *uci_data, srslte_pucch_format_t *format,
|
||||||
|
uint8_t pucch_bits[SRSLTE_PUCCH_MAX_BITS], uint8_t pucch2_bits[2],
|
||||||
|
srslte_cp_t cp)
|
||||||
|
{
|
||||||
|
int ret = SRSLTE_SUCCESS;
|
||||||
|
|
||||||
|
// No CQI data
|
||||||
|
if (uci_data->uci_cqi_len == 0) {
|
||||||
|
// 1-bit ACK + optional SR
|
||||||
|
if (uci_data->uci_ack_len == 1) {
|
||||||
|
*format = SRSLTE_PUCCH_FORMAT_1A;
|
||||||
|
pucch_bits[0] = uci_data->uci_ack;
|
||||||
|
}
|
||||||
|
// 2-bit ACK + optional SR
|
||||||
|
else if (uci_data->uci_ack_len == 2) {
|
||||||
|
*format = SRSLTE_PUCCH_FORMAT_1B;
|
||||||
|
pucch_bits[0] = uci_data->uci_ack;
|
||||||
|
pucch_bits[1] = uci_data->uci_ack_2;
|
||||||
|
}
|
||||||
|
// SR only
|
||||||
|
else if (uci_data->scheduling_request) {
|
||||||
|
*format = SRSLTE_PUCCH_FORMAT_1;
|
||||||
|
} else {
|
||||||
|
ret = SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// CQI data
|
||||||
|
else {
|
||||||
|
srslte_uci_encode_cqi_pucch(uci_data->uci_cqi, uci_data->uci_cqi_len, pucch_bits);
|
||||||
|
// CQI and no ack
|
||||||
|
if (uci_data->uci_ack_len == 0) {
|
||||||
|
*format = SRSLTE_PUCCH_FORMAT_2;
|
||||||
|
}
|
||||||
|
// CQI + 1-bit ACK
|
||||||
|
else if (uci_data->uci_cqi_len == SRSLTE_PUCCH_MAX_BITS && uci_data->uci_ack_len == 1) {
|
||||||
|
*format = SRSLTE_PUCCH_FORMAT_2A;
|
||||||
|
pucch2_bits[0] = uci_data->uci_ack;
|
||||||
|
}
|
||||||
|
// CQI + 2-bit ACK
|
||||||
|
else if (uci_data->uci_cqi_len == SRSLTE_PUCCH_MAX_BITS && uci_data->uci_ack_len == 2) {
|
||||||
|
*format = SRSLTE_PUCCH_FORMAT_2B;
|
||||||
|
pucch2_bits[0] = uci_data->uci_ack;
|
||||||
|
pucch2_bits[1] = uci_data->uci_ack_2;
|
||||||
|
}
|
||||||
|
// CQI + 2-bit ACK + cyclic prefix
|
||||||
|
else if (uci_data->uci_cqi_len == SRSLTE_PUCCH_MAX_BITS && uci_data->uci_ack_len == 1 && SRSLTE_CP_ISEXT(cp)) {
|
||||||
|
*format = SRSLTE_PUCCH_FORMAT_2B;
|
||||||
|
pucch2_bits[0] = uci_data->uci_ack;
|
||||||
|
pucch2_bits[1] = uci_data->uci_ack_2;
|
||||||
|
} else {
|
||||||
|
ret = SRSLTE_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ret) {
|
||||||
|
fprintf(stderr, "Unsupported combination of UCI parameters: ack_len=%d, cqi_len=%d\n",
|
||||||
|
uci_data->uci_ack, uci_data->uci_cqi_len);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal
|
/* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal
|
||||||
*/
|
*/
|
||||||
int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
||||||
|
@ -238,48 +298,8 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
||||||
bzero(pucch_bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
|
bzero(pucch_bits, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
|
||||||
bzero(pucch2_bits, 2*sizeof(uint8_t));
|
bzero(pucch2_bits, 2*sizeof(uint8_t));
|
||||||
|
|
||||||
// 1-bit ACK + optional SR
|
// Encode UCI information
|
||||||
if (uci_data.uci_ack_len == 1) {
|
if (pucch_encode_bits(&uci_data, &format, pucch_bits, pucch2_bits, q->cell.cp)) {
|
||||||
format = SRSLTE_PUCCH_FORMAT_1A;
|
|
||||||
pucch_bits[0] = uci_data.uci_ack;
|
|
||||||
}
|
|
||||||
// 2-bit ACK + optional SR
|
|
||||||
else if (uci_data.uci_ack_len == 2) {
|
|
||||||
format = SRSLTE_PUCCH_FORMAT_1B;
|
|
||||||
pucch_bits[0] = uci_data.uci_ack;
|
|
||||||
pucch_bits[1] = uci_data.uci_ack_2;
|
|
||||||
}
|
|
||||||
// SR only
|
|
||||||
else if (uci_data.scheduling_request) {
|
|
||||||
format = SRSLTE_PUCCH_FORMAT_1;
|
|
||||||
}
|
|
||||||
// CQI and no ack
|
|
||||||
else if (uci_data.uci_cqi_len == SRSLTE_PUCCH_MAX_BITS && uci_data.uci_ack_len == 0) {
|
|
||||||
format = SRSLTE_PUCCH_FORMAT_2;
|
|
||||||
memcpy(pucch_bits, uci_data.uci_cqi, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
|
|
||||||
}
|
|
||||||
// CQI + 1-bit ACK
|
|
||||||
else if (uci_data.uci_cqi_len == SRSLTE_PUCCH_MAX_BITS && uci_data.uci_ack_len == 1) {
|
|
||||||
format = SRSLTE_PUCCH_FORMAT_2A;
|
|
||||||
memcpy(pucch_bits, uci_data.uci_cqi, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
|
|
||||||
pucch2_bits[0] = uci_data.uci_ack;
|
|
||||||
}
|
|
||||||
// CQI + 2-bit ACK
|
|
||||||
else if (uci_data.uci_cqi_len == 20 && uci_data.uci_ack_len == 2) {
|
|
||||||
format = SRSLTE_PUCCH_FORMAT_2B;
|
|
||||||
memcpy(pucch_bits, uci_data.uci_cqi, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
|
|
||||||
pucch2_bits[0] = uci_data.uci_ack;
|
|
||||||
pucch2_bits[1] = uci_data.uci_ack_2;
|
|
||||||
}
|
|
||||||
// CQI + 2-bit ACK + cyclic prefix
|
|
||||||
else if (uci_data.uci_cqi_len == 20 && uci_data.uci_ack_len == 1 && SRSLTE_CP_ISEXT(q->cell.cp)) {
|
|
||||||
format = SRSLTE_PUCCH_FORMAT_2B;
|
|
||||||
memcpy(pucch_bits, uci_data.uci_cqi, SRSLTE_PUCCH_MAX_BITS*sizeof(uint8_t));
|
|
||||||
pucch2_bits[0] = uci_data.uci_ack;
|
|
||||||
pucch2_bits[1] = uci_data.uci_ack_2;
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "Unsupported combination of UCI parameters: ack_len=%d, cqi_len=%d\n",
|
|
||||||
uci_data.uci_ack, uci_data.uci_cqi_len);
|
|
||||||
return SRSLTE_ERROR;
|
return SRSLTE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,7 +340,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->normalize_en) {
|
if (q->normalize_en) {
|
||||||
float norm_factor = (float) 0.9*q->cell.nof_prb/5;
|
float norm_factor = (float) 0.6*q->cell.nof_prb/5;
|
||||||
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||||
}
|
}
|
||||||
ret = SRSLTE_SUCCESS;
|
ret = SRSLTE_SUCCESS;
|
||||||
|
@ -457,7 +477,7 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->normalize_en) {
|
if (q->normalize_en) {
|
||||||
float norm_factor = (float) q->cell.nof_prb/10/sqrtf(q->pusch_cfg.grant.L_prb);
|
float norm_factor = (float) q->cell.nof_prb/15/sqrtf(q->pusch_cfg.grant.L_prb);
|
||||||
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue