mirror of https://github.com/PentHertz/srsLTE.git
Added PUCCH Format 1/a/b
This commit is contained in:
parent
6eb3f1f484
commit
4fed92c21c
|
@ -0,0 +1,75 @@
|
|||
clear
|
||||
ueConfig=struct('NCellID',1,'NULRB',6,'NSubframe',8,'RNTI',68,'CyclicPrefixUL','Normal','NTxAnts',1);
|
||||
puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[1:4]','Modulation','QPSK','RV',0,'Shortened',0);
|
||||
|
||||
addpath('../../debug/lte/phy/lib/phch/test')
|
||||
|
||||
% TBs=0:13:211;
|
||||
% cqilen=[0, 8, 17];
|
||||
% mods={'QPSK','16QAM','64QAM'};
|
||||
% rvs=0;
|
||||
% betas=0:3:11;
|
||||
|
||||
TBs=88;
|
||||
cqilen=0;
|
||||
mods={'QPSK'};
|
||||
rvs=0;
|
||||
betas=0;
|
||||
|
||||
for i=1:length(TBs)
|
||||
for m=1:length(mods)
|
||||
for r=1:length(rvs)
|
||||
for bcqi=1:length(betas)
|
||||
for bri=1:length(betas)
|
||||
for back=1:length(betas)
|
||||
for c=1:length(cqilen)
|
||||
|
||||
trblkin=randi(2,TBs(i),1)-1;
|
||||
|
||||
puschConfig.Modulation = mods{m};
|
||||
puschConfig.RV = rvs(r);
|
||||
puschConfig.BetaCQI = 2+betas(bcqi);
|
||||
puschConfig.BetaRI = 2+betas(bri);
|
||||
puschConfig.BetaACK = 2+betas(back);
|
||||
|
||||
if (betas(bri)>0)
|
||||
ri_bit=randi(2,1,1)-1;
|
||||
else
|
||||
ri_bit=[];
|
||||
end
|
||||
if (betas(back)>0)
|
||||
ack_bit=randi(2,1,1)-1;
|
||||
else
|
||||
ack_bit=[];
|
||||
end
|
||||
|
||||
if (cqilen(c)>0 || TBs(i)>0)
|
||||
[cw, info]=lteULSCH(ueConfig,puschConfig,trblkin,ones(1,cqilen(c)),ri_bit,ack_bit,[]);
|
||||
cw_mat=ltePUSCH(ueConfig,puschConfig,cw);
|
||||
idx=ltePUSCHIndices(ueConfig,puschConfig);
|
||||
subframe_mat = lteULResourceGrid(ueConfig);
|
||||
subframe_mat(idx)=cw_mat;
|
||||
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);
|
||||
err=mean(abs(waveform-waveform_lib));
|
||||
if (err > 10^-6)
|
||||
disp(err)
|
||||
error('Error!');
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if (length(TBs) == 1)
|
||||
%disp(info)
|
||||
%n=1:length(mat);
|
||||
%plot(abs(double(mat)-double(lib)))
|
||||
%plot(n,real(lib(n)),n,real(mat(n)))
|
||||
plot(abs(waveform_lib-waveform))
|
||||
end
|
|
@ -379,16 +379,16 @@ int main(int argc, char **argv) {
|
|||
|
||||
srslte_pusch_hopping_cfg_t hop_cfg;
|
||||
bzero(&hop_cfg, sizeof(srslte_pusch_hopping_cfg_t));
|
||||
srslte_refsignal_drms_pusch_cfg_t drms_cfg;
|
||||
bzero(&drms_cfg, sizeof(srslte_refsignal_drms_pusch_cfg_t));
|
||||
drms_cfg.beta_pusch = 1.0;
|
||||
drms_cfg.group_hopping_en = false;
|
||||
drms_cfg.sequence_hopping_en = false;
|
||||
drms_cfg.delta_ss = 0;
|
||||
drms_cfg.cyclic_shift = 0;
|
||||
drms_cfg.cyclic_shift_for_drms = 0;
|
||||
drms_cfg.en_drms_2 = false;
|
||||
srslte_ue_ul_set_pusch_cfg(&ue_ul, &drms_cfg, &hop_cfg);
|
||||
srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg;
|
||||
bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t));
|
||||
dmrs_cfg.beta_pusch = 1.0;
|
||||
dmrs_cfg.group_hopping_en = false;
|
||||
dmrs_cfg.sequence_hopping_en = false;
|
||||
dmrs_cfg.delta_ss = 0;
|
||||
dmrs_cfg.cyclic_shift = 0;
|
||||
dmrs_cfg.cyclic_shift_for_dmrs = 0;
|
||||
dmrs_cfg.en_dmrs_2 = false;
|
||||
srslte_ue_ul_set_pusch_cfg(&ue_ul, &dmrs_cfg, &hop_cfg);
|
||||
|
||||
cf_t *ul_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
if (!ul_signal) {
|
||||
|
|
|
@ -219,7 +219,7 @@ int main(int argc, char **argv) {
|
|||
/* If peak detected */
|
||||
if (peak_value[N_id_2] > corr_peak_threshold) {
|
||||
|
||||
sss_idx = peak_pos[N_id_2]-2*(symbol_sz+SRSLTE_CP(symbol_sz,SRSLTE_CP_NORM_LEN));
|
||||
sss_idx = peak_pos[N_id_2]-2*(symbol_sz+SRSLTE_CP_LEN(symbol_sz,SRSLTE_CP_NORM_LEN));
|
||||
if (sss_idx >= 0) {
|
||||
srslte_sss_synch_m0m1_diff(&sss[N_id_2], &input[sss_idx],
|
||||
&m0, &m0_value, &m1, &m1_value);
|
||||
|
|
|
@ -47,16 +47,15 @@
|
|||
|
||||
typedef struct SRSLTE_API {
|
||||
uint32_t cyclic_shift;
|
||||
uint32_t cyclic_shift_for_drms;
|
||||
uint32_t cyclic_shift_for_dmrs;
|
||||
uint32_t delta_ss;
|
||||
bool en_drms_2;
|
||||
bool en_dmrs_2;
|
||||
float beta_pusch;
|
||||
bool group_hopping_en;
|
||||
bool sequence_hopping_en;
|
||||
}srslte_refsignal_drms_pusch_cfg_t;
|
||||
}srslte_refsignal_dmrs_pusch_cfg_t;
|
||||
|
||||
typedef struct SRSLTE_API {
|
||||
float beta_pucch;
|
||||
uint32_t nof_prb;
|
||||
}srslte_refsignal_srs_cfg_t;
|
||||
|
||||
|
@ -77,29 +76,36 @@ SRSLTE_API int srslte_refsignal_ul_init(srslte_refsignal_ul_t *q,
|
|||
|
||||
SRSLTE_API void srslte_refsignal_ul_free(srslte_refsignal_ul_t *q);
|
||||
|
||||
SRSLTE_API bool srslte_refsignal_drms_pusch_cfg_isvalid(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_drms_pusch_cfg_t *cfg,
|
||||
SRSLTE_API void srslte_refsignal_r_uv_arg_1prb(float *arg,
|
||||
uint32_t u);
|
||||
|
||||
SRSLTE_API bool srslte_refsignal_dmrs_pusch_cfg_isvalid(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *cfg,
|
||||
uint32_t nof_prb);
|
||||
|
||||
SRSLTE_API void srslte_refsignal_drms_pusch_put(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_drms_pusch_cfg_t *cfg,
|
||||
SRSLTE_API int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *cfg,
|
||||
uint32_t nof_prb,
|
||||
uint32_t sf_idx,
|
||||
cf_t *r_pusch);
|
||||
|
||||
SRSLTE_API void srslte_refsignal_dmrs_pusch_put(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *cfg,
|
||||
cf_t *r_pusch,
|
||||
uint32_t nof_prb,
|
||||
uint32_t n_prb[2],
|
||||
cf_t *sf_symbols);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_dmrs_gen(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_drms_pusch_cfg_t *cfg,
|
||||
uint32_t nof_prb,
|
||||
uint32_t sf_idx,
|
||||
cf_t *r_pusch);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q,
|
||||
srslte_pucch_cfg_t *cfg,
|
||||
uint32_t sf_idx,
|
||||
uint32_t n_rb,
|
||||
cf_t *r_pucch) ;
|
||||
uint32_t sf_idx,
|
||||
cf_t *r_pucch);
|
||||
|
||||
SRSLTE_API int srslte_refsignal_dmrs_pucch_put(srslte_refsignal_ul_t* q,
|
||||
srslte_pucch_cfg_t* cfg,
|
||||
cf_t *r_pucch,
|
||||
cf_t *output);
|
||||
|
||||
SRSLTE_API void srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q,
|
||||
srslte_refsignal_srs_cfg_t *cfg,
|
||||
uint32_t sf_idx,
|
||||
|
|
|
@ -91,9 +91,9 @@ typedef enum {SRSLTE_CP_NORM, SRSLTE_CP_EXT} srslte_cp_t;
|
|||
#define SRSLTE_CP_ISEXT(cp) (cp==SRSLTE_CP_EXT)
|
||||
#define SRSLTE_CP_NSYMB(cp) (SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_NORM_NSYMB:SRSLTE_CP_EXT_NSYMB)
|
||||
|
||||
#define SRSLTE_CP(symbol_sz, c) ((int) ceil((((float) (c)*(symbol_sz))/2048)))
|
||||
#define SRSLTE_CP_NORM(symbol, symbol_sz) ((symbol==0)?SRSLTE_CP((symbol_sz),SRSLTE_CP_NORM_0_LEN):SRSLTE_CP((symbol_sz),SRSLTE_CP_NORM_LEN))
|
||||
#define SRSLTE_CP_EXT(symbol_sz) (SRSLTE_CP((symbol_sz),SRSLTE_CP_EXT_LEN))
|
||||
#define SRSLTE_CP_LEN(symbol_sz, c) ((int) ceil((((float) (c)*(symbol_sz))/2048)))
|
||||
#define SRSLTE_CP_LEN_NORM(symbol, symbol_sz) ((symbol==0)?SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_NORM_0_LEN):SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_NORM_LEN))
|
||||
#define SRSLTE_CP_LEN_EXT(symbol_sz) (SRSLTE_CP_LEN((symbol_sz),SRSLTE_CP_EXT_LEN))
|
||||
|
||||
#define SRSLTE_SLOT_LEN(symbol_sz) (480*((symbol_sz)/64))
|
||||
#define SRSLTE_SF_LEN(symbol_sz) (2*SRSLTE_SLOT_LEN(symbol_sz))
|
||||
|
@ -109,8 +109,8 @@ typedef enum {SRSLTE_CP_NORM, SRSLTE_CP_EXT} srslte_cp_t;
|
|||
|
||||
#define SRSLTE_LTE_TS 1.0/(15000.0*2048)
|
||||
|
||||
#define SRSLTE_SLOT_IDX_CPNORM(symbol_idx, symbol_sz) (symbol_idx==0?0:(symbol_sz + SRSLTE_CP(symbol_sz, SRSLTE_CP_NORM_0_LEN) + \
|
||||
(symbol_idx-1)*(symbol_sz+SRSLTE_CP(symbol_sz, SRSLTE_CP_NORM_LEN))))
|
||||
#define SRSLTE_SLOT_IDX_CPNORM(symbol_idx, symbol_sz) (symbol_idx==0?0:(symbol_sz + SRSLTE_CP_LEN(symbol_sz, SRSLTE_CP_NORM_0_LEN) + \
|
||||
(symbol_idx-1)*(symbol_sz+SRSLTE_CP_LEN(symbol_sz, SRSLTE_CP_NORM_LEN))))
|
||||
#define SRSLTE_SLOT_IDX_CPEXT(idx, symbol_sz) (idx*(symbol_sz+SRSLTE_CP(symbol_sz, SRSLTE_CP_EXT_LEN)))
|
||||
|
||||
#define SRSLTE_RE_IDX(nof_prb, symbol_idx, sample_idx) ((symbol_idx)*(nof_prb)*(SRSLTE_NRE) + sample_idx)
|
||||
|
@ -213,6 +213,9 @@ SRSLTE_API uint32_t srslte_voffset(uint32_t symbol_id,
|
|||
uint32_t cell_id,
|
||||
uint32_t nof_ports);
|
||||
|
||||
SRSLTE_API int srslte_group_hopping_f_gh(uint32_t f_gh[SRSLTE_NSLOTS_X_FRAME],
|
||||
uint32_t cell_id);
|
||||
|
||||
SRSLTE_API uint32_t srslte_N_ta_new_rar(uint32_t ta);
|
||||
|
||||
SRSLTE_API uint32_t srslte_N_ta_new(uint32_t N_ta_old,
|
||||
|
|
|
@ -38,15 +38,6 @@
|
|||
|
||||
#include "srslte/config.h"
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/mimo/precoding.h"
|
||||
#include "srslte/mimo/layermap.h"
|
||||
#include "srslte/modem/mod.h"
|
||||
#include "srslte/modem/demod_soft.h"
|
||||
#include "srslte/scrambling/scrambling.h"
|
||||
#include "srslte/phch/regs.h"
|
||||
#include "srslte/phch/sch.h"
|
||||
#include "srslte/phch/harq.h"
|
||||
#include "srslte/dft/dft_precoding.h"
|
||||
|
||||
#define SRSLTE_PUCCH_N_SEQ 12 // Only Format 1, 1a and 1b supported
|
||||
#define SRSLTE_PUCCH_MAX_BITS 2
|
||||
|
@ -66,7 +57,9 @@ typedef struct SRSLTE_API {
|
|||
float beta_pucch;
|
||||
uint32_t delta_pucch_shift;
|
||||
uint32_t n_pucch;
|
||||
uint32_t n_rb_2;
|
||||
uint32_t N_cs;
|
||||
bool group_hopping_en;
|
||||
} srslte_pucch_cfg_t;
|
||||
|
||||
/* PUSCH object */
|
||||
|
@ -75,8 +68,9 @@ typedef struct SRSLTE_API {
|
|||
srslte_pucch_cfg_t pucch_cfg;
|
||||
|
||||
uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB];
|
||||
float tmp_arg[SRSLTE_PUCCH_N_SF_MAX*SRSLTE_PUCCH_N_SEQ];
|
||||
float y[SRSLTE_PUCCH_N_SEQ];
|
||||
uint32_t f_gh[SRSLTE_NSLOTS_X_FRAME];
|
||||
float tmp_arg[SRSLTE_PUCCH_N_SEQ];
|
||||
float z[SRSLTE_PUCCH_N_SF_MAX*SRSLTE_PUCCH_N_SEQ];
|
||||
}srslte_pucch_t;
|
||||
|
||||
|
||||
|
@ -93,19 +87,25 @@ SRSLTE_API int srslte_pucch_set_rnti(srslte_pucch_t *q,
|
|||
|
||||
SRSLTE_API int srslte_pucch_encode(srslte_pucch_t *q,
|
||||
srslte_pucch_cfg_t *cfg,
|
||||
uint32_t sf_idx,
|
||||
uint8_t bits[SRSLTE_PUCCH_MAX_BITS],
|
||||
cf_t *sf_symbols);
|
||||
|
||||
SRSLTE_API float srslte_pucch_get_alpha(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB],
|
||||
srslte_pucch_cfg_t *cfg,
|
||||
srslte_cp_t cp,
|
||||
bool is_drms,
|
||||
uint32_t ns,
|
||||
uint32_t l,
|
||||
uint32_t *n_oc);
|
||||
SRSLTE_API float srslte_pucch_alpha(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB],
|
||||
srslte_pucch_cfg_t *cfg,
|
||||
srslte_cp_t cp,
|
||||
bool is_dmrs,
|
||||
uint32_t ns,
|
||||
uint32_t l,
|
||||
uint32_t *n_oc,
|
||||
uint32_t *n_prime_ns);
|
||||
|
||||
SRSLTE_API uint32_t srslte_pucch_m(srslte_pucch_cfg_t *cfg,
|
||||
srslte_cp_t cp);
|
||||
|
||||
SRSLTE_API int srslte_pucch_n_cs_cell(srslte_cell_t cell,
|
||||
uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB]);
|
||||
|
||||
SRSLTE_API int srslte_generate_n_cs_cell(srslte_cell_t cell,
|
||||
uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB]);
|
||||
|
||||
SRSLTE_API bool srslte_pucch_cfg_isvalid(srslte_pucch_cfg_t *cfg);
|
||||
|
||||
|
|
|
@ -94,6 +94,7 @@
|
|||
#include "srslte/phch/pdsch.h"
|
||||
#include "srslte/phch/phich.h"
|
||||
#include "srslte/phch/pusch.h"
|
||||
#include "srslte/phch/pucch.h"
|
||||
#include "srslte/phch/prach.h"
|
||||
#include "srslte/phch/ra.h"
|
||||
#include "srslte/phch/regs.h"
|
||||
|
|
|
@ -63,9 +63,9 @@ typedef struct SRSLTE_API {
|
|||
|
||||
float current_cfo;
|
||||
|
||||
srslte_refsignal_drms_pusch_cfg_t drms_cfg;
|
||||
srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg;
|
||||
|
||||
srslte_refsignal_ul_t drms;
|
||||
srslte_refsignal_ul_t dmrs;
|
||||
srslte_harq_t harq_process[SRSLTE_UE_UL_NOF_HARQ_PROCESSES];
|
||||
srslte_pusch_t pusch;
|
||||
|
||||
|
@ -91,7 +91,7 @@ SRSLTE_API void srslte_ue_ul_set_normalization(srslte_ue_ul_t *q,
|
|||
bool enabled);
|
||||
|
||||
SRSLTE_API void srslte_ue_ul_set_pusch_cfg(srslte_ue_ul_t *q,
|
||||
srslte_refsignal_drms_pusch_cfg_t *drms_cfg,
|
||||
srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg,
|
||||
srslte_pusch_hopping_cfg_t *pusch_hopping_cfg);
|
||||
|
||||
SRSLTE_API int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q,
|
||||
|
|
|
@ -39,11 +39,11 @@
|
|||
|
||||
#include "ul_rs_tables.h"
|
||||
|
||||
// n_drms_2 table 5.5.2.1.1-1 from 36.211
|
||||
uint32_t n_drms_2[8] = { 0, 6, 3, 4, 2, 8, 10, 9 };
|
||||
// n_dmrs_2 table 5.5.2.1.1-1 from 36.211
|
||||
uint32_t n_dmrs_2[8] = { 0, 6, 3, 4, 2, 8, 10, 9 };
|
||||
|
||||
// n_drms_1 table 5.5.2.1.1-2 from 36.211
|
||||
uint32_t n_drms_1[8] = { 0, 2, 3, 4, 6, 8, 9, 10 };
|
||||
// n_dmrs_1 table 5.5.2.1.1-2 from 36.211
|
||||
uint32_t n_dmrs_1[8] = { 0, 2, 3, 4, 6, 8, 9, 10 };
|
||||
|
||||
/* Orthogonal sequences for PUCCH formats 1a, 1b and 1c. Table 5.5.2.2.1-2
|
||||
*/
|
||||
|
@ -58,10 +58,10 @@ float w_arg_pucch_format1_cpext[3][2] = {{0, 0},
|
|||
float w_arg_pucch_format2_cpnorm[2] = {0, 0};
|
||||
float w_arg_pucch_format2_cpext[1] = {0};
|
||||
|
||||
uint32_t pucch_symbol_format1_cpnorm[3] = {2, 3, 5};
|
||||
uint32_t pucch_symbol_format1_cpext[2] = {2, 3};
|
||||
uint32_t pucch_symbol_format2_cpnorm[2] = {1, 5};
|
||||
uint32_t pucch_symbol_format2_cpext[1] = {3};
|
||||
uint32_t pucch_dmrs_symbol_format1_cpnorm[3] = {2, 3, 4};
|
||||
uint32_t pucch_dmrs_symbol_format1_cpext[2] = {2, 3};
|
||||
uint32_t pucch_dmrs_symbol_format2_cpnorm[2] = {1, 5};
|
||||
uint32_t pucch_dmrs_symbol_format2_cpext[1] = {3};
|
||||
|
||||
/** Computes n_prs values used to compute alpha as defined in 5.5.2.1.1 of 36.211 */
|
||||
static int generate_n_prs(srslte_refsignal_ul_t * q) {
|
||||
|
@ -89,25 +89,10 @@ static int generate_n_prs(srslte_refsignal_ul_t * q) {
|
|||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/** Computes sequence-group pattern f_gh according to 5.5.1.3 of 36.211 */
|
||||
static int generate_group_hopping_f_gh(srslte_refsignal_ul_t *q) {
|
||||
srslte_sequence_t seq;
|
||||
bzero(&seq, sizeof(srslte_sequence_t));
|
||||
|
||||
if (srslte_sequence_LTE_pr(&seq, 160, q->cell.id / 30)) {
|
||||
return SRSLTE_ERROR;
|
||||
void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u) {
|
||||
for (int i = 0; i < SRSLTE_NRE; i++) {
|
||||
arg[i] = phi_M_sc_12[u][i] * M_PI / 4;
|
||||
}
|
||||
|
||||
for (uint32_t ns=0;ns<SRSLTE_NSLOTS_X_FRAME;ns++) {
|
||||
uint32_t f_gh = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
f_gh += (((uint32_t) seq.c[8 * ns + i]) << i);
|
||||
}
|
||||
q->f_gh[ns] = f_gh;
|
||||
}
|
||||
|
||||
srslte_sequence_free(&seq);
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
static int generate_srslte_sequence_hopping_v(srslte_refsignal_ul_t *q) {
|
||||
|
@ -153,7 +138,7 @@ int srslte_refsignal_ul_init(srslte_refsignal_ul_t * q, srslte_cell_t cell)
|
|||
}
|
||||
|
||||
// Precompute group hopping values u.
|
||||
if (generate_group_hopping_f_gh(q)) {
|
||||
if (srslte_group_hopping_f_gh(q->f_gh, q->cell.id)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
|
@ -162,7 +147,7 @@ int srslte_refsignal_ul_init(srslte_refsignal_ul_t * q, srslte_cell_t cell)
|
|||
goto free_and_exit;
|
||||
}
|
||||
|
||||
if (srslte_generate_n_cs_cell(q->cell, q->n_cs_cell)) {
|
||||
if (srslte_pucch_n_cs_cell(q->cell, q->n_cs_cell)) {
|
||||
goto free_and_exit;
|
||||
}
|
||||
|
||||
|
@ -193,12 +178,6 @@ uint32_t largest_prime_lower_than(uint32_t x) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void arg_r_uv_1prb(float *arg, uint32_t u) {
|
||||
for (int i = 0; i < SRSLTE_NRE; i++) {
|
||||
arg[i] = phi_M_sc_12[u][i] * M_PI / 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void arg_r_uv_2prb(float *arg, uint32_t u) {
|
||||
for (int i = 0; i < 2*SRSLTE_NRE; i++) {
|
||||
arg[i] = phi_M_sc_24[u][i] * M_PI / 4;
|
||||
|
@ -232,9 +211,9 @@ static void arg_r_uv_mprb(float *arg, uint32_t M_sc, uint32_t u, uint32_t v) {
|
|||
}
|
||||
|
||||
/* Computes argument of r_u_v signal */
|
||||
static void compute_pusch_r_uv_arg(srslte_refsignal_ul_t *q, srslte_refsignal_drms_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t u, uint32_t v) {
|
||||
static void compute_pusch_r_uv_arg(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t u, uint32_t v) {
|
||||
if (nof_prb == 1) {
|
||||
arg_r_uv_1prb(q->tmp_arg, u);
|
||||
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
|
||||
} else if (nof_prb == 2) {
|
||||
arg_r_uv_2prb(q->tmp_arg, u);
|
||||
} else {
|
||||
|
@ -243,20 +222,20 @@ static void compute_pusch_r_uv_arg(srslte_refsignal_ul_t *q, srslte_refsignal_dr
|
|||
}
|
||||
|
||||
/* Calculates alpha according to 5.5.2.1.1 of 36.211 */
|
||||
static float get_alpha(srslte_refsignal_ul_t *q, srslte_refsignal_drms_pusch_cfg_t *cfg, uint32_t ns) {
|
||||
uint32_t n_drms_2_val = 0;
|
||||
if (cfg->en_drms_2) {
|
||||
n_drms_2_val = n_drms_2[cfg->cyclic_shift_for_drms];
|
||||
static float pusch_alpha(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg, uint32_t ns) {
|
||||
uint32_t n_dmrs_2_val = 0;
|
||||
if (cfg->en_dmrs_2) {
|
||||
n_dmrs_2_val = n_dmrs_2[cfg->cyclic_shift_for_dmrs];
|
||||
}
|
||||
uint32_t n_cs = (n_drms_1[cfg->cyclic_shift] + n_drms_2_val + q->n_prs_pusch[cfg->delta_ss][ns]) % 12;
|
||||
uint32_t n_cs = (n_dmrs_1[cfg->cyclic_shift] + n_dmrs_2_val + q->n_prs_pusch[cfg->delta_ss][ns]) % 12;
|
||||
|
||||
return 2 * M_PI * (n_cs) / 12;
|
||||
|
||||
}
|
||||
|
||||
bool srslte_refsignal_drms_pusch_cfg_isvalid(srslte_refsignal_ul_t *q, srslte_refsignal_drms_pusch_cfg_t *cfg, uint32_t nof_prb) {
|
||||
bool srslte_refsignal_dmrs_pusch_cfg_isvalid(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg, uint32_t nof_prb) {
|
||||
if (cfg->cyclic_shift < SRSLTE_NOF_CSHIFT &&
|
||||
cfg->cyclic_shift_for_drms < SRSLTE_NOF_CSHIFT &&
|
||||
cfg->cyclic_shift_for_dmrs < SRSLTE_NOF_CSHIFT &&
|
||||
cfg->delta_ss < SRSLTE_NOF_DELTA_SS &&
|
||||
nof_prb < q->cell.nof_prb) {
|
||||
return true;
|
||||
|
@ -265,7 +244,7 @@ bool srslte_refsignal_drms_pusch_cfg_isvalid(srslte_refsignal_ul_t *q, srslte_re
|
|||
}
|
||||
}
|
||||
|
||||
void srslte_refsignal_drms_pusch_put(srslte_refsignal_ul_t *q, srslte_refsignal_drms_pusch_cfg_t *cfg,
|
||||
void srslte_refsignal_dmrs_pusch_put(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg,
|
||||
cf_t *r_pusch,
|
||||
uint32_t nof_prb,
|
||||
uint32_t n_prb[2],
|
||||
|
@ -280,11 +259,11 @@ void srslte_refsignal_drms_pusch_put(srslte_refsignal_ul_t *q, srslte_refsignal_
|
|||
}
|
||||
|
||||
/* Generate DRMS for PUSCH signal according to 5.5.2.1 of 36.211 */
|
||||
int srslte_refsignal_dmrs_gen(srslte_refsignal_ul_t *q, srslte_refsignal_drms_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t sf_idx, cf_t *r_pusch)
|
||||
int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t sf_idx, cf_t *r_pusch)
|
||||
{
|
||||
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (srslte_refsignal_drms_pusch_cfg_isvalid(q, cfg, nof_prb)) {
|
||||
if (srslte_refsignal_dmrs_pusch_cfg_isvalid(q, cfg, nof_prb)) {
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
|
||||
|
@ -305,7 +284,7 @@ int srslte_refsignal_dmrs_gen(srslte_refsignal_ul_t *q, srslte_refsignal_drms_pu
|
|||
compute_pusch_r_uv_arg(q, cfg, nof_prb, u, v);
|
||||
|
||||
// Add cyclic prefix alpha
|
||||
float alpha = get_alpha(q, cfg, ns);
|
||||
float alpha = pusch_alpha(q, cfg, ns);
|
||||
|
||||
if (srslte_verbose == SRSLTE_VERBOSE_DEBUG) {
|
||||
uint32_t N_sz = largest_prime_lower_than(nof_prb*SRSLTE_NRE);
|
||||
|
@ -324,93 +303,160 @@ int srslte_refsignal_dmrs_gen(srslte_refsignal_ul_t *q, srslte_refsignal_drms_pu
|
|||
return ret;
|
||||
}
|
||||
|
||||
int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_cfg_t *cfg, uint32_t sf_idx, uint32_t n_rb, cf_t *r_pucch)
|
||||
/* Number of PUCCH demodulation reference symbols per slot N_rs_pucch tABLE 5.5.2.2.1-1 36.211 */
|
||||
static uint32_t get_N_rs(srslte_pucch_format_t format, srslte_cp_t cp) {
|
||||
switch (format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
return 3;
|
||||
} else {
|
||||
return 2;
|
||||
}
|
||||
case SRSLTE_PUCCH_FORMAT_2:
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
return 2;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
case SRSLTE_PUCCH_FORMAT_2A:
|
||||
case SRSLTE_PUCCH_FORMAT_2B:
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Table 5.5.2.2.2-1: Demodulation reference signal location for different PUCCH formats. 36.211 */
|
||||
static uint32_t get_pucch_dmrs_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t cp) {
|
||||
switch (format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
if (m < 4) {
|
||||
return pucch_dmrs_symbol_format1_cpnorm[m];
|
||||
}
|
||||
} else {
|
||||
if (m < 3) {
|
||||
return pucch_dmrs_symbol_format1_cpext[m];
|
||||
}
|
||||
}
|
||||
case SRSLTE_PUCCH_FORMAT_2:
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
if (m < 3) {
|
||||
return pucch_dmrs_symbol_format2_cpnorm[m];
|
||||
}
|
||||
} else {
|
||||
if (m < 2) {
|
||||
return pucch_dmrs_symbol_format2_cpext[m];
|
||||
}
|
||||
}
|
||||
case SRSLTE_PUCCH_FORMAT_2A:
|
||||
case SRSLTE_PUCCH_FORMAT_2B:
|
||||
if (m < 3) {
|
||||
return pucch_dmrs_symbol_format2_cpnorm[m];
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Generates DMRS for PUCCH according to 5.5.2.2 in 36.211 */
|
||||
int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_cfg_t *cfg, uint32_t sf_idx, cf_t *r_pucch)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (srslte_pucch_cfg_isvalid(cfg)) {
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
uint32_t N_rs=get_N_rs(cfg->format, q->cell.cp);
|
||||
|
||||
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
|
||||
uint32_t N_rs=0;
|
||||
uint32_t *pucch_symbol = NULL;
|
||||
switch (cfg->format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||
N_rs = 3;
|
||||
pucch_symbol=pucch_symbol_format1_cpnorm;
|
||||
} else {
|
||||
N_rs=2;
|
||||
pucch_symbol=pucch_symbol_format1_cpext;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_2:
|
||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||
N_rs = 2;
|
||||
pucch_symbol=pucch_symbol_format2_cpnorm;
|
||||
} else {
|
||||
N_rs=1;
|
||||
pucch_symbol=pucch_symbol_format2_cpext;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_2A:
|
||||
case SRSLTE_PUCCH_FORMAT_2B:
|
||||
N_rs = 2;
|
||||
pucch_symbol=pucch_symbol_format2_cpnorm;
|
||||
break;
|
||||
// Get group hopping number u
|
||||
uint32_t f_gh=0;
|
||||
if (cfg->group_hopping_en) {
|
||||
f_gh = q->f_gh[ns];
|
||||
}
|
||||
uint32_t u = (f_gh + (q->cell.id%30))%30;
|
||||
|
||||
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
|
||||
|
||||
for (uint32_t m=0;m<N_rs;m++) {
|
||||
uint32_t n_oc=0;
|
||||
|
||||
uint32_t l = get_pucch_dmrs_symbol(m, cfg->format, q->cell.cp);
|
||||
// Add cyclic prefix alpha
|
||||
float alpha = srslte_pucch_alpha(q->n_cs_cell, cfg, q->cell.cp, true, ns, l, &n_oc, NULL);
|
||||
|
||||
if (pucch_symbol) {
|
||||
for (uint32_t m=0;m<N_rs;m++) {
|
||||
uint32_t n_oc=0;
|
||||
|
||||
uint32_t l = pucch_symbol[m];
|
||||
// Add cyclic prefix alpha
|
||||
float alpha = srslte_pucch_get_alpha(q->n_cs_cell, cfg, q->cell.cp, true, ns, l, &n_oc);
|
||||
|
||||
// Choose number of symbols and orthogonal sequence from Tables 5.5.2.2.1-1 to -3
|
||||
float *w=NULL;
|
||||
switch (cfg->format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||
w=w_arg_pucch_format1_cpnorm[n_oc];
|
||||
} else {
|
||||
w=w_arg_pucch_format1_cpext[n_oc];
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_2:
|
||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||
w=w_arg_pucch_format2_cpnorm;
|
||||
} else {
|
||||
w=w_arg_pucch_format2_cpext;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_2A:
|
||||
case SRSLTE_PUCCH_FORMAT_2B:
|
||||
// Choose number of symbols and orthogonal sequence from Tables 5.5.2.2.1-1 to -3
|
||||
float *w=NULL;
|
||||
switch (cfg->format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||
w=w_arg_pucch_format1_cpnorm[n_oc];
|
||||
} else {
|
||||
w=w_arg_pucch_format1_cpext[n_oc];
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_2:
|
||||
if (SRSLTE_CP_ISNORM(q->cell.cp)) {
|
||||
w=w_arg_pucch_format2_cpnorm;
|
||||
break;
|
||||
}
|
||||
|
||||
if (w) {
|
||||
for (uint32_t n=0;n<SRSLTE_NRE*n_rb;n++) {
|
||||
r_pucch[(ns%2)*SRSLTE_NRE*n_rb*N_rs+m*SRSLTE_NRE*n_rb+n] = cfg->beta_pucch*cexpf(I*(w[m]+q->tmp_arg[n]+alpha*n));
|
||||
}
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
} else {
|
||||
w=w_arg_pucch_format2_cpext;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_2A:
|
||||
case SRSLTE_PUCCH_FORMAT_2B:
|
||||
w=w_arg_pucch_format2_cpnorm;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (w) {
|
||||
for (uint32_t n=0;n<SRSLTE_NRE;n++) {
|
||||
r_pucch[(ns%2)*SRSLTE_NRE*N_rs+m*SRSLTE_NRE+n] = cfg->beta_pucch*w[m]*cexpf(I*(q->tmp_arg[n]+alpha*n));
|
||||
}
|
||||
} else {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Maps PUCCH DMRS to the physical resources as defined in 5.5.2.2.2 in 36.211 */
|
||||
int srslte_refsignal_dmrs_pucch_put(srslte_refsignal_ul_t *q, srslte_pucch_cfg_t *cfg, cf_t *r_pucch, cf_t *output)
|
||||
{
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q && cfg && output) {
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
// Determine m
|
||||
uint32_t m = srslte_pucch_m(cfg, q->cell.cp);
|
||||
|
||||
uint32_t N_rs = get_N_rs(cfg->format, q->cell.cp);
|
||||
for (uint32_t ns=0;ns<2;ns++) {
|
||||
// Determine n_prb
|
||||
uint32_t n_prb = m/2;
|
||||
if ((m+ns)%2) {
|
||||
n_prb = q->cell.nof_prb-1-m/2;
|
||||
}
|
||||
|
||||
for (uint32_t i=0;i<N_rs;i++) {
|
||||
uint32_t l = get_pucch_dmrs_symbol(m, cfg->format, q->cell.cp);
|
||||
memcpy(&output[SRSLTE_RE_IDX(q->cell.nof_prb, l, n_prb*SRSLTE_NRE)],
|
||||
&r_pucch[ns*N_rs*SRSLTE_NRE+i*SRSLTE_NRE],
|
||||
SRSLTE_NRE*sizeof(cf_t));
|
||||
}
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q, srslte_refsignal_srs_cfg_t *cfg, uint32_t ns, cf_t *r_srs)
|
||||
{
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
{
|
||||
srslte_cell_t cell;
|
||||
srslte_refsignal_ul_t refs;
|
||||
srslte_refsignal_drms_pusch_cfg_t pusch_cfg;
|
||||
srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg;
|
||||
uint32_t sf_idx;
|
||||
|
||||
if (nrhs != NOF_INPUTS) {
|
||||
|
@ -73,7 +73,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
return;
|
||||
}
|
||||
|
||||
bzero(&pusch_cfg, sizeof(srslte_refsignal_drms_pusch_cfg_t));
|
||||
bzero(&pusch_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t));
|
||||
|
||||
|
||||
pusch_cfg.group_hopping_en = false;
|
||||
|
@ -104,11 +104,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
}
|
||||
uint32_t nof_prb = mexutils_read_f(p, &prbset);
|
||||
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "DynCyclicShift", &pusch_cfg.cyclic_shift_for_drms)) {
|
||||
pusch_cfg.cyclic_shift_for_drms = 0;
|
||||
pusch_cfg.en_drms_2 = false;
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "DynCyclicShift", &pusch_cfg.cyclic_shift_for_dmrs)) {
|
||||
pusch_cfg.cyclic_shift_for_dmrs = 0;
|
||||
pusch_cfg.en_dmrs_2 = false;
|
||||
} else {
|
||||
pusch_cfg.en_drms_2 = true;
|
||||
pusch_cfg.en_dmrs_2 = true;
|
||||
}
|
||||
|
||||
pusch_cfg.beta_pusch = 1.0;
|
||||
|
@ -120,7 +120,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
|
||||
mexPrintf("nof_prb: %d, ",nof_prb);
|
||||
mexPrintf("cyclic_shift: %d, ",pusch_cfg.cyclic_shift);
|
||||
mexPrintf("cyclic_shift_for_drms: %d, ",pusch_cfg.cyclic_shift_for_drms);
|
||||
mexPrintf("cyclic_shift_for_dmrs: %d, ",pusch_cfg.cyclic_shift_for_dmrs);
|
||||
mexPrintf("delta_ss: %d, ",pusch_cfg.delta_ss);
|
||||
|
||||
cf_t *signal = srslte_vec_malloc(2*SRSLTE_NRE*nof_prb*sizeof(cf_t));
|
||||
|
@ -135,11 +135,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
}
|
||||
bzero(sf_symbols, SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)*sizeof(cf_t));
|
||||
//mexPrintf("Generating DRMS for ns=%d, nof_prb=%d\n", 2*sf_idx+i,pusch_cfg.nof_prb);
|
||||
srslte_refsignal_dmrs_gen(&refs, &pusch_cfg, nof_prb, sf_idx, signal);
|
||||
srslte_refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, nof_prb, sf_idx, signal);
|
||||
uint32_t n_prb[2];
|
||||
n_prb[0] = prbset[0];
|
||||
n_prb[1] = prbset[0];
|
||||
srslte_refsignal_drms_pusch_put(&refs, &pusch_cfg, signal, nof_prb, n_prb, sf_symbols);
|
||||
srslte_refsignal_dmrs_pusch_put(&refs, &pusch_cfg, signal, nof_prb, n_prb, sf_symbols);
|
||||
if (nlhs >= 1) {
|
||||
mexutils_write_cf(sf_symbols, &plhs[0], SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), 1);
|
||||
}
|
||||
|
|
|
@ -76,7 +76,7 @@ void parse_args(int argc, char **argv) {
|
|||
|
||||
int main(int argc, char **argv) {
|
||||
srslte_refsignal_ul_t refs;
|
||||
srslte_refsignal_drms_pusch_cfg_t pusch_cfg;
|
||||
srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg;
|
||||
cf_t *signal = NULL;
|
||||
int ret = -1;
|
||||
|
||||
|
@ -100,11 +100,11 @@ int main(int argc, char **argv) {
|
|||
for (int cshift=0;cshift<SRSLTE_NOF_CSHIFT;cshift++) {
|
||||
for (int h=0;h<3;h++) {
|
||||
for (int sf_idx=0;sf_idx<SRSLTE_NSLOTS_X_FRAME;sf_idx++) {
|
||||
for (int cshift_drms=0;cshift_drms<SRSLTE_NOF_CSHIFT;cshift_drms++) {
|
||||
for (int cshift_dmrs=0;cshift_dmrs<SRSLTE_NOF_CSHIFT;cshift_dmrs++) {
|
||||
pusch_cfg.beta_pusch = 1.0;
|
||||
uint32_t nof_prb = n;
|
||||
pusch_cfg.cyclic_shift = cshift;
|
||||
pusch_cfg.cyclic_shift_for_drms = cshift_drms;
|
||||
pusch_cfg.cyclic_shift_for_dmrs = cshift_dmrs;
|
||||
pusch_cfg.delta_ss = delta_ss;
|
||||
if (!h) {
|
||||
pusch_cfg.group_hopping_en = false;
|
||||
|
@ -116,14 +116,14 @@ int main(int argc, char **argv) {
|
|||
pusch_cfg.group_hopping_en = true;
|
||||
pusch_cfg.sequence_hopping_en = false;
|
||||
}
|
||||
pusch_cfg.en_drms_2 = true;
|
||||
pusch_cfg.en_dmrs_2 = true;
|
||||
printf("Beta: %f, ",pusch_cfg.beta_pusch);
|
||||
printf("nof_prb: %d, ",nof_prb);
|
||||
printf("cyclic_shift: %d, ",pusch_cfg.cyclic_shift);
|
||||
printf("cyclic_shift_for_drms: %d, ",pusch_cfg.cyclic_shift_for_drms);
|
||||
printf("cyclic_shift_for_dmrs: %d, ",pusch_cfg.cyclic_shift_for_dmrs);
|
||||
printf("delta_ss: %d, ",pusch_cfg.delta_ss);
|
||||
printf("SF_idx: %d\n", sf_idx);
|
||||
srslte_refsignal_dmrs_gen(&refs, &pusch_cfg, nof_prb, sf_idx, signal);
|
||||
srslte_refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, nof_prb, sf_idx, signal);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/common/sequence.h"
|
||||
|
||||
const uint32_t tc_cb_sizes[SRSLTE_NOF_TC_CB_SIZES] = { 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120,
|
||||
128, 136, 144, 152, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232,
|
||||
|
@ -283,6 +284,27 @@ uint32_t srslte_voffset(uint32_t symbol_id, uint32_t cell_id, uint32_t nof_ports
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/** Computes sequence-group pattern f_gh according to 5.5.1.3 of 36.211 */
|
||||
int srslte_group_hopping_f_gh(uint32_t f_gh[SRSLTE_NSLOTS_X_FRAME], uint32_t cell_id) {
|
||||
srslte_sequence_t seq;
|
||||
bzero(&seq, sizeof(srslte_sequence_t));
|
||||
|
||||
if (srslte_sequence_LTE_pr(&seq, 160, cell_id / 30)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
for (uint32_t ns=0;ns<SRSLTE_NSLOTS_X_FRAME;ns++) {
|
||||
f_gh[ns] = 0;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
f_gh[ns] += (((uint32_t) seq.c[8 * ns + i]) << i);
|
||||
}
|
||||
}
|
||||
|
||||
srslte_sequence_free(&seq);
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
/* Returns the number of available RE per PRB */
|
||||
uint32_t srslte_re_x_prb(uint32_t ns, uint32_t symbol, uint32_t nof_ports, uint32_t nof_symbols) {
|
||||
if (symbol == 0) {
|
||||
|
|
|
@ -123,7 +123,7 @@ int srslte_ofdm_set_freq_shift(srslte_ofdm_t *q, float freq_shift) {
|
|||
cf_t *ptr = q->shift_buffer;
|
||||
for (uint32_t n=0;n<2;n++) {
|
||||
for (uint32_t i=0;i<q->nof_symbols;i++) {
|
||||
uint32_t cplen = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM(i, q->symbol_sz):SRSLTE_CP_EXT(q->symbol_sz);
|
||||
uint32_t cplen = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz);
|
||||
for (uint32_t t=0;t<q->symbol_sz+cplen;t++) {
|
||||
ptr[t] = cexpf(I*2*M_PI*((float) t-(float)cplen)*freq_shift/q->symbol_sz);
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ void srslte_ofdm_tx_free(srslte_ofdm_t *q) {
|
|||
void srslte_ofdm_rx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
|
||||
uint32_t i;
|
||||
for (i=0;i<q->nof_symbols;i++) {
|
||||
input += SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM(i, q->symbol_sz):SRSLTE_CP_EXT(q->symbol_sz);
|
||||
input += SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz);
|
||||
srslte_dft_run_c(&q->fft_plan, input, q->tmp);
|
||||
memcpy(output, &q->tmp[q->nof_guards], q->nof_re * sizeof(cf_t));
|
||||
input += q->symbol_sz;
|
||||
|
@ -173,7 +173,7 @@ void srslte_ofdm_rx_sf(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
|
|||
void srslte_ofdm_tx_slot(srslte_ofdm_t *q, cf_t *input, cf_t *output) {
|
||||
uint32_t i, cp_len;
|
||||
for (i=0;i<q->nof_symbols;i++) {
|
||||
cp_len = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM(i, q->symbol_sz):SRSLTE_CP_EXT(q->symbol_sz);
|
||||
cp_len = SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_LEN_NORM(i, q->symbol_sz):SRSLTE_CP_LEN_EXT(q->symbol_sz);
|
||||
memcpy(&q->tmp[q->nof_guards], input, q->nof_re * sizeof(cf_t));
|
||||
srslte_dft_run_c(&q->fft_plan, q->tmp, &output[cp_len]);
|
||||
input += q->nof_re;
|
||||
|
|
|
@ -33,24 +33,98 @@
|
|||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
#include <complex.h>
|
||||
|
||||
#include "srslte/phch/pucch.h"
|
||||
#include "srslte/phch/uci.h"
|
||||
#include "srslte/common/sequence.h"
|
||||
#include "srslte/common/phy_common.h"
|
||||
#include "srslte/utils/bit.h"
|
||||
#include "srslte/utils/debug.h"
|
||||
#include "srslte/utils/vector.h"
|
||||
#include "srslte/dft/dft_precoding.h"
|
||||
|
||||
#define MAX_PUSCH_RE(cp) (2 * SRSLTE_CP_NSYMB(cp) * 12)
|
||||
|
||||
uint32_t pucch_symbol_format1_cpnorm[4] = {0, 1, 5, 6};
|
||||
uint32_t pucch_symbol_format1_cpext[4] = {0, 1, 4, 5};
|
||||
uint32_t pucch_symbol_format2_cpnorm[5] = {0, 2, 3, 4, 6};
|
||||
uint32_t pucch_symbol_format2_cpext[5] = {0, 1, 2, 4, 5};
|
||||
|
||||
// Table 5.4.1-2 Orthogonal sequences w for N_sf=4
|
||||
float w_n_oc[3][4] = {{1, 1, 1, 1},
|
||||
{1,-1, 1,-1},
|
||||
{1,-1,-1,1}};
|
||||
|
||||
bool srslte_pucch_cfg_isvalid(srslte_pucch_cfg_t *cfg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32_t get_N_sf(srslte_pucch_format_t format) {
|
||||
switch (format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
return 4;
|
||||
case SRSLTE_PUCCH_FORMAT_2:
|
||||
case SRSLTE_PUCCH_FORMAT_2A:
|
||||
case SRSLTE_PUCCH_FORMAT_2B:
|
||||
return 5;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t get_pucch_symbol(uint32_t m, srslte_pucch_format_t format, srslte_cp_t cp) {
|
||||
switch (format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
if (m < 5) {
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
return pucch_symbol_format1_cpnorm[m];
|
||||
} else {
|
||||
return pucch_symbol_format1_cpext[m];
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_2:
|
||||
case SRSLTE_PUCCH_FORMAT_2A:
|
||||
case SRSLTE_PUCCH_FORMAT_2B:
|
||||
if (m < 6) {
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
return pucch_symbol_format2_cpnorm[m];
|
||||
} else {
|
||||
return pucch_symbol_format2_cpext[m];
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// Compute m according to Section 5.4.3 of 36.211
|
||||
uint32_t srslte_pucch_m(srslte_pucch_cfg_t *cfg, srslte_cp_t cp) {
|
||||
uint32_t m=0;
|
||||
switch (cfg->format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
m = cfg->n_rb_2;
|
||||
uint32_t c=SRSLTE_CP_ISNORM(cp)?3:2;
|
||||
if (cfg->n_pucch >= c*cfg->N_cs/cfg->delta_pucch_shift) {
|
||||
m = (cfg->n_pucch-c*cfg->N_cs/cfg->delta_pucch_shift)/(c*SRSLTE_NRE/cfg->delta_pucch_shift)
|
||||
+cfg->n_rb_2+(cfg->N_cs-1)/8+1;
|
||||
}
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_2:
|
||||
case SRSLTE_PUCCH_FORMAT_2A:
|
||||
case SRSLTE_PUCCH_FORMAT_2B:
|
||||
m = cfg->n_pucch/SRSLTE_NRE;
|
||||
break;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/* Generates n_cs_cell according to Sec 5.4 of 36.211 */
|
||||
int srslte_generate_n_cs_cell(srslte_cell_t cell, uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB])
|
||||
int srslte_pucch_n_cs_cell(srslte_cell_t cell, uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB])
|
||||
{
|
||||
srslte_sequence_t seq;
|
||||
bzero(&seq, sizeof(srslte_sequence_t));
|
||||
|
@ -70,12 +144,12 @@ int srslte_generate_n_cs_cell(srslte_cell_t cell, uint32_t n_cs_cell[SRSLTE_NSLO
|
|||
}
|
||||
|
||||
|
||||
/* Calculates alpha according to 5.5.2.2.2 of 36.211 */
|
||||
float srslte_pucch_get_alpha(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB],
|
||||
srslte_pucch_cfg_t *cfg,
|
||||
srslte_cp_t cp, bool is_drms,
|
||||
uint32_t ns, uint32_t l,
|
||||
uint32_t *n_oc_ptr)
|
||||
/* Calculates alpha according to 5.5.2.2.2 (is_dmrs=true) or 5.4.1 (is_dmrs=false) of 36.211 */
|
||||
float srslte_pucch_alpha(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP_NORM_NSYMB],
|
||||
srslte_pucch_cfg_t *cfg,
|
||||
srslte_cp_t cp, bool is_dmrs,
|
||||
uint32_t ns, uint32_t l,
|
||||
uint32_t *n_oc_ptr, uint32_t *n_prime_ns)
|
||||
{
|
||||
uint32_t c = SRSLTE_CP_ISNORM(cp)?3:2;
|
||||
uint32_t N_prime = (cfg->n_pucch < c*cfg->N_cs/cfg->delta_pucch_shift)?cfg->N_cs:12;
|
||||
|
@ -84,11 +158,24 @@ float srslte_pucch_get_alpha(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP
|
|||
if (cfg->n_pucch >= c*cfg->N_cs/cfg->delta_pucch_shift) {
|
||||
n_prime = (cfg->n_pucch-c*cfg->N_cs/cfg->delta_pucch_shift)%(cfg->N_cs/cfg->delta_pucch_shift);
|
||||
}
|
||||
if (ns%2) {
|
||||
if (cfg->n_pucch >= c*cfg->N_cs/cfg->delta_pucch_shift) {
|
||||
n_prime = (c*(n_prime+1))%(c*SRSLTE_NRE/cfg->delta_pucch_shift+1)-1;
|
||||
} else {
|
||||
uint32_t d=SRSLTE_CP_ISNORM(cp)?2:0;
|
||||
uint32_t h=(n_prime+d)%(c*N_prime/cfg->delta_pucch_shift);
|
||||
n_prime = (h/c)+(h%c)*N_prime/cfg->delta_pucch_shift;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t n_oc_div = (!is_drms && SRSLTE_CP_ISEXT(cp))?2:1;
|
||||
if (n_prime_ns) {
|
||||
*n_prime_ns = n_prime;
|
||||
}
|
||||
|
||||
uint32_t n_oc_div = (!is_dmrs && SRSLTE_CP_ISEXT(cp))?2:1;
|
||||
|
||||
uint32_t n_oc = n_prime*cfg->delta_pucch_shift/N_prime;
|
||||
if (!is_drms && SRSLTE_CP_ISEXT(cp)) {
|
||||
if (!is_dmrs && SRSLTE_CP_ISEXT(cp)) {
|
||||
n_oc *= 2;
|
||||
}
|
||||
if (n_oc_ptr) {
|
||||
|
@ -103,18 +190,34 @@ float srslte_pucch_get_alpha(uint32_t n_cs_cell[SRSLTE_NSLOTS_X_FRAME][SRSLTE_CP
|
|||
|
||||
return 2 * M_PI * (n_cs) / 12;
|
||||
}
|
||||
/* Map PUCCH symbols to physical resources according to 5.4.3 in 36.211 */
|
||||
static int pucch_put(srslte_pucch_t *q, srslte_pucch_cfg_t *cfg, cf_t *output) {
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q && cfg && output) {
|
||||
ret = SRSLTE_ERROR;
|
||||
|
||||
int pucch_cp(srslte_pucch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output, bool advance_input)
|
||||
{
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
int pucch_put(srslte_pucch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output) {
|
||||
return pucch_cp(q, harq, input, output, true);
|
||||
}
|
||||
|
||||
int pucch_get(srslte_pucch_t *q, srslte_harq_t *harq, cf_t *input, cf_t *output) {
|
||||
return pucch_cp(q, harq, input, output, false);
|
||||
// Determine m
|
||||
uint32_t m = srslte_pucch_m(cfg, q->cell.cp);
|
||||
|
||||
uint32_t N_sf = get_N_sf(cfg->format);
|
||||
for (uint32_t ns=0;ns<2;ns++) {
|
||||
// Determine n_prb
|
||||
uint32_t n_prb = m/2;
|
||||
if ((m+ns)%2) {
|
||||
n_prb = q->cell.nof_prb-1-m/2;
|
||||
}
|
||||
|
||||
for (uint32_t i=0;i<N_sf;i++) {
|
||||
uint32_t l = get_pucch_symbol(i, cfg->format, q->cell.cp);
|
||||
memcpy(&output[SRSLTE_RE_IDX(q->cell.nof_prb, l, n_prb*SRSLTE_NRE)],
|
||||
&q->z[i*SRSLTE_NRE+ns*N_sf*SRSLTE_NRE],
|
||||
SRSLTE_NRE*sizeof(cf_t));
|
||||
}
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -127,7 +230,12 @@ int srslte_pucch_init(srslte_pucch_t *q, srslte_cell_t cell) {
|
|||
|
||||
q->cell = cell;
|
||||
|
||||
if (srslte_generate_n_cs_cell(q->cell, q->n_cs_cell)) {
|
||||
// Precompute group hopping values u.
|
||||
if (srslte_group_hopping_f_gh(q->f_gh, q->cell.id)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
if (srslte_pucch_n_cs_cell(q->cell, q->n_cs_cell)) {
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
|
@ -140,13 +248,6 @@ void srslte_pucch_free(srslte_pucch_t *q) {
|
|||
bzero(q, sizeof(srslte_pucch_t));
|
||||
}
|
||||
|
||||
/** Decodes the PUSCH from the received symbols
|
||||
*/
|
||||
int pucch_decode(srslte_pucch_t *q, srslte_harq_t *harq, cf_t *sf_symbols, cf_t *ce, float noise_estimate, uint8_t *data)
|
||||
{
|
||||
return SRSLTE_ERROR_INVALID_INPUTS;
|
||||
}
|
||||
|
||||
static cf_t uci_encode_format1() {
|
||||
return 1.0;
|
||||
}
|
||||
|
@ -171,36 +272,84 @@ static cf_t uci_encode_format1b(uint8_t bits[2]) {
|
|||
}
|
||||
}
|
||||
|
||||
static void uci_mod_bits(srslte_pucch_t *q, srslte_pucch_cfg_t *cfg, uint8_t bits[SRSLTE_PUCCH_MAX_BITS])
|
||||
/* Encode PUCCH bits according to Table 5.4.1-1 in Section 5.4.1 of 36.211 */
|
||||
static int uci_mod_bits(srslte_pucch_t *q, srslte_pucch_cfg_t *cfg, uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t *d_0)
|
||||
{
|
||||
cf_t d_0 = 0;
|
||||
uint8_t tmp[2];
|
||||
switch(cfg->format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
d_0 = uci_encode_format1();
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
d_0 = uci_encode_format1a(bits[0]);
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
tmp[0] = bits[0];
|
||||
tmp[1] = bits[1];
|
||||
d_0 = uci_encode_format1b(tmp);
|
||||
default:
|
||||
fprintf(stderr, "PUCCH format 2 not supported\n");
|
||||
return;
|
||||
if (d_0) {
|
||||
uint8_t tmp[2];
|
||||
switch(cfg->format) {
|
||||
case SRSLTE_PUCCH_FORMAT_1:
|
||||
*d_0 = uci_encode_format1();
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_1A:
|
||||
*d_0 = uci_encode_format1a(bits[0]);
|
||||
break;
|
||||
case SRSLTE_PUCCH_FORMAT_1B:
|
||||
tmp[0] = bits[0];
|
||||
tmp[1] = bits[1];
|
||||
*d_0 = uci_encode_format1b(tmp);
|
||||
default:
|
||||
fprintf(stderr, "PUCCH format 2 not supported\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
}
|
||||
/*
|
||||
for (uint32_t n=0;n<SRSLTE_PUCCH_N_SEQ;n++) {
|
||||
q->y[n] = d_0+
|
||||
}
|
||||
*/
|
||||
return SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
int srslte_pucch_encode(srslte_pucch_t *q, srslte_pucch_cfg_t *cfg, uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t *sf_symbols)
|
||||
// Declare this here, since we can not include refsignal_ul.h
|
||||
void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u);
|
||||
|
||||
/* Encode, modulate and resource mapping of PUCCH bits according to Section 5.4.1 of 36.211 */
|
||||
int srslte_pucch_encode(srslte_pucch_t *q, srslte_pucch_cfg_t *cfg, uint32_t sf_idx, uint8_t bits[SRSLTE_PUCCH_MAX_BITS], cf_t *sf_symbols)
|
||||
{
|
||||
uci_mod_bits(q, cfg, bits);
|
||||
return SRSLTE_ERROR;
|
||||
int ret = SRSLTE_ERROR_INVALID_INPUTS;
|
||||
if (q != NULL &&
|
||||
cfg != NULL &&
|
||||
sf_symbols != NULL)
|
||||
{
|
||||
ret = SRSLTE_ERROR;
|
||||
cf_t d_0 = 0;
|
||||
if (uci_mod_bits(q, cfg, bits, &d_0)) {
|
||||
fprintf(stderr, "Error encoding PUCCH bits\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
uint32_t N_sf=get_N_sf(cfg->format);
|
||||
for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) {
|
||||
// Get group hopping number u
|
||||
uint32_t f_gh=0;
|
||||
if (cfg->group_hopping_en) {
|
||||
f_gh = q->f_gh[ns];
|
||||
}
|
||||
uint32_t u = (f_gh + (q->cell.id%30))%30;
|
||||
|
||||
srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u);
|
||||
|
||||
for (uint32_t m=0;m<N_sf;m++) {
|
||||
uint32_t l = get_pucch_symbol(m, cfg->format, q->cell.cp);
|
||||
uint32_t n_prime_ns;
|
||||
uint32_t n_oc;
|
||||
float alpha = srslte_pucch_alpha(q->n_cs_cell, cfg, q->cell.cp, true, ns, l, &n_oc, &n_prime_ns);
|
||||
|
||||
uint32_t S_ns = 0;
|
||||
if (n_prime_ns%2) {
|
||||
S_ns = M_PI/2;
|
||||
}
|
||||
|
||||
for (uint32_t n=0;n<SRSLTE_PUCCH_N_SEQ;n++) {
|
||||
q->z[(ns%2)*N_sf*SRSLTE_PUCCH_N_SEQ+m*SRSLTE_PUCCH_N_SEQ+n] = cfg->beta_pucch*d_0*w_n_oc[n_oc][m]*cexpf(I*(q->tmp_arg[n]+alpha*n+S_ns));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pucch_put(q, cfg, sf_symbols)) {
|
||||
fprintf(stderr, "Error putting PUCCH symbols\n");
|
||||
return SRSLTE_ERROR;
|
||||
}
|
||||
|
||||
ret = SRSLTE_SUCCESS;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
@ -192,7 +192,7 @@ int main(int argc, char **argv) {
|
|||
printf("Invalid received ACK: %d!=%d\n", ack[ngroup][nseq], ack_rx);
|
||||
exit(-1);
|
||||
}
|
||||
if (distance) {
|
||||
if (distance < 5) {
|
||||
printf("Error\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,223 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The libLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the libLTE library.
|
||||
*
|
||||
* libLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* libLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "srslte/srslte.h"
|
||||
#include "srslte/mex/mexutils.h"
|
||||
|
||||
/** MEX function to be called from MATLAB to test the channel estimator
|
||||
*/
|
||||
|
||||
#define UECFG prhs[0]
|
||||
#define PUSCHCFG prhs[1]
|
||||
#define TRBLKIN prhs[2]
|
||||
#define CQI prhs[3]
|
||||
#define RI prhs[4]
|
||||
#define ACK prhs[5]
|
||||
#define NOF_INPUTS 6
|
||||
|
||||
void help()
|
||||
{
|
||||
mexErrMsgTxt
|
||||
("sym=srslte_pusch_encode(ue, chs, trblkin, cqi, ri, ack)\n\n");
|
||||
}
|
||||
|
||||
/* the gateway function */
|
||||
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
||||
{
|
||||
|
||||
if (nrhs != NOF_INPUTS) {
|
||||
help();
|
||||
return;
|
||||
}
|
||||
|
||||
srslte_cell_t cell;
|
||||
bzero(&cell, sizeof(srslte_cell_t));
|
||||
cell.nof_ports = 1;
|
||||
if (mexutils_read_uint32_struct(UECFG, "NCellID", &cell.id)) {
|
||||
mexErrMsgTxt("Field NCellID not found in UE config\n");
|
||||
return;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(UECFG, "NULRB", &cell.nof_prb)) {
|
||||
mexErrMsgTxt("Field NULRB not found in UE config\n");
|
||||
return;
|
||||
}
|
||||
srslte_pusch_t pusch;
|
||||
if (srslte_pusch_init(&pusch, cell)) {
|
||||
mexErrMsgTxt("Error initiating PUSCH\n");
|
||||
return;
|
||||
}
|
||||
uint32_t rnti32=0;
|
||||
if (mexutils_read_uint32_struct(UECFG, "RNTI", &rnti32)) {
|
||||
mexErrMsgTxt("Field RNTI not found in pusch config\n");
|
||||
return;
|
||||
}
|
||||
srslte_pusch_set_rnti(&pusch, (uint16_t) (rnti32 & 0xffff));
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t sf_idx=0;
|
||||
if (mexutils_read_uint32_struct(UECFG, "NSubframe", &sf_idx)) {
|
||||
mexErrMsgTxt("Field NSubframe not found in UE config\n");
|
||||
return;
|
||||
}
|
||||
srslte_ra_mcs_t mcs;
|
||||
char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation");
|
||||
if (!strcmp(mod_str, "QPSK")) {
|
||||
mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else if (!strcmp(mod_str, "16QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_16QAM;
|
||||
} else if (!strcmp(mod_str, "64QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_64QAM;
|
||||
} else {
|
||||
mexErrMsgTxt("Unknown modulation\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mxFree(mod_str);
|
||||
|
||||
float *prbset = NULL;
|
||||
mxArray *p;
|
||||
p = mxGetField(PUSCHCFG, 0, "PRBSet");
|
||||
if (!p) {
|
||||
mexErrMsgTxt("Error field PRBSet not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
srslte_ra_ul_alloc_t prb_alloc;
|
||||
bzero(&prb_alloc, sizeof(srslte_ra_ul_alloc_t));
|
||||
prb_alloc.L_prb = mexutils_read_f(p, &prbset);
|
||||
prb_alloc.n_prb[0] = prbset[0];
|
||||
prb_alloc.n_prb[1] = prbset[0];
|
||||
free(prbset);
|
||||
|
||||
mexPrintf("L_prb: %d, n_prb: %d\n", prb_alloc.L_prb, prb_alloc.n_prb[2*sf_idx]);
|
||||
|
||||
uint8_t *trblkin = NULL;
|
||||
mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
||||
|
||||
srslte_harq_t harq_process;
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
mexErrMsgTxt("Error initiating HARQ process\n");
|
||||
return;
|
||||
}
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, 0, sf_idx, &prb_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp);
|
||||
cf_t *sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re);
|
||||
if (!sf_symbols) {
|
||||
mexErrMsgTxt("malloc");
|
||||
return;
|
||||
}
|
||||
bzero(sf_symbols, sizeof(cf_t) * nof_re);
|
||||
|
||||
|
||||
srslte_uci_data_t uci_data;
|
||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &uci_data.uci_cqi);
|
||||
uint8_t *tmp;
|
||||
uci_data.uci_ri_len = mexutils_read_uint8(RI, &tmp);
|
||||
if (uci_data.uci_ri_len > 0) {
|
||||
uci_data.uci_ri = *tmp;
|
||||
}
|
||||
free(tmp);
|
||||
uci_data.uci_ack_len = mexutils_read_uint8(ACK, &tmp);
|
||||
if (uci_data.uci_ack_len > 0) {
|
||||
uci_data.uci_ack = *tmp;
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetCQI", &uci_data.I_offset_cqi)) {
|
||||
uci_data.I_offset_cqi = 7;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetRI", &uci_data.I_offset_ri)) {
|
||||
uci_data.I_offset_ri = 2;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetACK", &uci_data.I_offset_ack)) {
|
||||
uci_data.I_offset_ack = 0;
|
||||
}
|
||||
mexPrintf("TRBL_len: %d, CQI_len: %d, ACK_len: %d (%d), RI_len: %d (%d)\n", mcs.tbs,
|
||||
uci_data.uci_cqi_len, uci_data.uci_ack_len, uci_data.uci_ack, uci_data.uci_ri_len, uci_data.uci_ri);
|
||||
|
||||
|
||||
mexPrintf("NofRE: %d, NofBits: %d, TBS: %d\n", harq_process.nof_re, harq_process.nof_bits, harq_process.mcs.tbs);
|
||||
int r = srslte_pusch_uci_encode(&pusch, &harq_process, trblkin, uci_data, sf_symbols);
|
||||
if (r < 0) {
|
||||
mexErrMsgTxt("Error encoding PUSCH\n");
|
||||
return;
|
||||
}
|
||||
uint32_t rv=0;
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &rv)) {
|
||||
mexErrMsgTxt("Field RV not found in pdsch config\n");
|
||||
return;
|
||||
}
|
||||
if (rv > 0) {
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, rv, sf_idx, &prb_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
}
|
||||
r = srslte_pusch_uci_encode(&pusch, &harq_process, trblkin, uci_data, sf_symbols);
|
||||
if (r < 0) {
|
||||
mexErrMsgTxt("Error encoding PUSCH\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
srslte_ofdm_t fft;
|
||||
srslte_ofdm_tx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb);
|
||||
srslte_ofdm_set_normalize(&fft, true);
|
||||
srslte_ofdm_set_freq_shift(&fft, 0.5);
|
||||
srslte_ofdm_tx_sf(&fft, sf_symbols, scfdma);
|
||||
|
||||
// Matlab toolbox expects further normalization
|
||||
srslte_vec_sc_prod_cfc(scfdma, 1.0/sqrtf(srslte_symbol_sz(cell.nof_prb)), scfdma, SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
|
||||
if (nlhs >= 1) {
|
||||
mexutils_write_cf(scfdma, &plhs[0], SRSLTE_SF_LEN_PRB(cell.nof_prb), 1);
|
||||
}
|
||||
if (nlhs >= 2) {
|
||||
mexutils_write_cf(sf_symbols, &plhs[1], nof_re, 1);
|
||||
}
|
||||
if (nlhs >= 3) {
|
||||
mexutils_write_cf(pusch.z, &plhs[2], harq_process.nof_re, 1);
|
||||
}
|
||||
srslte_pusch_free(&pusch);
|
||||
free(trblkin);
|
||||
free(uci_data.uci_cqi);
|
||||
free(sf_symbols);
|
||||
free(scfdma);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
@ -0,0 +1,274 @@
|
|||
/**
|
||||
*
|
||||
* \section COPYRIGHT
|
||||
*
|
||||
* Copyright 2013-2014 The srsLTE Developers. See the
|
||||
* COPYRIGHT file at the top-level directory of this distribution.
|
||||
*
|
||||
* \section LICENSE
|
||||
*
|
||||
* This file is part of the srsLTE library.
|
||||
*
|
||||
* srsLTE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* srsLTE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* A copy of the GNU Lesser General Public License can be found in
|
||||
* the LICENSE file in the top-level directory of this distribution
|
||||
* and at http://www.gnu.org/licenses/.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "srslte/srslte.h"
|
||||
|
||||
srslte_cell_t cell = {
|
||||
6, // nof_prb
|
||||
1, // nof_ports
|
||||
0, // cell_id
|
||||
SRSLTE_CP_NORM, // cyclic prefix
|
||||
SRSLTE_PHICH_SRSLTE_PHICH_R_1_6, // PHICH resources
|
||||
SRSLTE_PHICH_NORM // PHICH length
|
||||
};
|
||||
|
||||
uint32_t cfi = 2;
|
||||
uint32_t tbs = 0;
|
||||
uint32_t subframe = 1;
|
||||
srslte_mod_t modulation = SRSLTE_MOD_QPSK;
|
||||
uint32_t rv_idx = 0;
|
||||
uint32_t L_prb = 2;
|
||||
uint32_t n_prb = 0;
|
||||
int freq_hop = -1;
|
||||
int riv = -1;
|
||||
|
||||
void usage(char *prog) {
|
||||
printf("Usage: %s [csrnfvmtLNF] -l TBS \n", prog);
|
||||
printf("\t-m modulation (1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64) [Default BPSK]\n");
|
||||
printf("\t-c cell id [Default %d]\n", cell.id);
|
||||
printf("\t-s subframe [Default %d]\n", subframe);
|
||||
printf("\t-L L_prb [Default %d]\n", L_prb);
|
||||
printf("\t-N n_prb [Default %d]\n", n_prb);
|
||||
printf("\t-F frequency hopping [Default %d]\n", freq_hop);
|
||||
printf("\t-R RIV [Default %d]\n", riv);
|
||||
printf("\t-r rv_idx [Default %d]\n", rv_idx);
|
||||
printf("\t-f cfi [Default %d]\n", cfi);
|
||||
printf("\t-n cell.nof_prb [Default %d]\n", cell.nof_prb);
|
||||
printf("\t-v [set srslte_verbose to debug, default none]\n");
|
||||
}
|
||||
|
||||
void parse_args(int argc, char **argv) {
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "lcnfvmtsrLNFR")) != -1) {
|
||||
switch(opt) {
|
||||
case 'm':
|
||||
switch(atoi(argv[optind])) {
|
||||
case 1:
|
||||
modulation = SRSLTE_MOD_BPSK;
|
||||
break;
|
||||
case 2:
|
||||
modulation = SRSLTE_MOD_QPSK;
|
||||
break;
|
||||
case 4:
|
||||
modulation = SRSLTE_MOD_16QAM;
|
||||
break;
|
||||
case 6:
|
||||
modulation = SRSLTE_MOD_64QAM;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Invalid modulation %d. Possible values: "
|
||||
"(1: BPSK, 2: QPSK, 3: QAM16, 4: QAM64)\n", atoi(argv[optind]));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
subframe = atoi(argv[optind]);
|
||||
break;
|
||||
case 'L':
|
||||
L_prb = atoi(argv[optind]);
|
||||
break;
|
||||
case 'N':
|
||||
n_prb = atoi(argv[optind]);
|
||||
break;
|
||||
case 'R':
|
||||
riv = atoi(argv[optind]);
|
||||
break;
|
||||
case 'F':
|
||||
freq_hop = atoi(argv[optind]);
|
||||
break;
|
||||
case 'r':
|
||||
rv_idx = atoi(argv[optind]);
|
||||
break;
|
||||
case 'l':
|
||||
tbs = atoi(argv[optind]);
|
||||
break;
|
||||
case 'n':
|
||||
cell.nof_prb = atoi(argv[optind]);
|
||||
break;
|
||||
case 'c':
|
||||
cell.id = atoi(argv[optind]);
|
||||
break;
|
||||
case 'v':
|
||||
srslte_verbose++;
|
||||
break;
|
||||
default:
|
||||
usage(argv[0]);
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
srslte_pusch_t pusch;
|
||||
uint8_t *data = NULL;
|
||||
cf_t *sf_symbols = NULL;
|
||||
int ret = -1;
|
||||
struct timeval t[3];
|
||||
srslte_ra_mcs_t mcs;
|
||||
srslte_ra_ul_alloc_t prb_alloc;
|
||||
srslte_harq_t harq_process;
|
||||
|
||||
parse_args(argc,argv);
|
||||
|
||||
mcs.tbs = tbs;
|
||||
mcs.mod = modulation;
|
||||
|
||||
bzero(&prb_alloc, sizeof(srslte_ra_ul_alloc_t));
|
||||
|
||||
if (srslte_pusch_init(&pusch, cell)) {
|
||||
fprintf(stderr, "Error creating PDSCH object\n");
|
||||
goto quit;
|
||||
}
|
||||
srslte_pusch_set_rnti(&pusch, 1234);
|
||||
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
fprintf(stderr, "Error initiating HARQ process\n");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
printf("Encoding rv_idx=%d\n",rv_idx);
|
||||
|
||||
uint8_t tmp[20];
|
||||
for (uint32_t i=0;i<20;i++) {
|
||||
tmp[i] = 1;
|
||||
}
|
||||
srslte_uci_data_t uci_data;
|
||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
uci_data.I_offset_cqi = 7;
|
||||
uci_data.I_offset_ri = 2;
|
||||
uci_data.I_offset_ack = 0;
|
||||
|
||||
uci_data.uci_cqi_len = 0;
|
||||
uci_data.uci_ri_len = 0;
|
||||
uci_data.uci_ack_len = 0;
|
||||
|
||||
uci_data.uci_cqi = tmp;
|
||||
uci_data.uci_ri = 1;
|
||||
uci_data.uci_ack = 1;
|
||||
|
||||
srslte_ra_pusch_t dci;
|
||||
dci.freq_hop_fl = freq_hop;
|
||||
if (riv < 0) {
|
||||
dci.type2_alloc.L_crb = L_prb;
|
||||
dci.type2_alloc.RB_start = n_prb;
|
||||
} else {
|
||||
srslte_ra_type2_from_riv((uint32_t) riv, &dci.type2_alloc.L_crb, &dci.type2_alloc.RB_start, cell.nof_prb, cell.nof_prb);
|
||||
}
|
||||
srslte_ra_ul_alloc(&prb_alloc, &dci, 0, cell.nof_prb);
|
||||
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, 0, subframe, &prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
goto quit;
|
||||
}
|
||||
srslte_pusch_hopping_cfg_t ul_hopping;
|
||||
ul_hopping.n_sb = 1;
|
||||
ul_hopping.hopping_offset = 0;
|
||||
ul_hopping.hop_mode = SRSLTE_PUSCH_HOP_MODE_INTER_SF;
|
||||
ul_hopping.current_tx_nb = 0;
|
||||
|
||||
srslte_pusch_set_hopping_cfg(&pusch, &ul_hopping);
|
||||
|
||||
uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp);
|
||||
sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re);
|
||||
if (!sf_symbols) {
|
||||
perror("malloc");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
data = malloc(sizeof(uint8_t) * mcs.tbs);
|
||||
if (!data) {
|
||||
perror("malloc");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
for (uint32_t i=0;i<mcs.tbs;i++) {
|
||||
data[i] = 1;
|
||||
}
|
||||
|
||||
if (srslte_pusch_uci_encode(&pusch, &harq_process, data, uci_data, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding TB\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (rv_idx > 0) {
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, rv_idx, subframe, &prb_alloc)) {
|
||||
fprintf(stderr, "Error configuring HARQ process\n");
|
||||
goto quit;
|
||||
}
|
||||
|
||||
if (srslte_pusch_uci_encode(&pusch, &harq_process, data, uci_data, sf_symbols)) {
|
||||
fprintf(stderr, "Error encoding TB\n");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
srslte_ofdm_t fft;
|
||||
srslte_ofdm_tx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb);
|
||||
srslte_ofdm_set_freq_shift(&fft, 0.5);
|
||||
srslte_ofdm_tx_sf(&fft, sf_symbols, scfdma);
|
||||
|
||||
gettimeofday(&t[1], NULL);
|
||||
//int r = srslte_pusch_decode(&pusch, slot_symbols[0], ce, 0, data, subframe, &harq_process, rv);
|
||||
int r = 0;
|
||||
gettimeofday(&t[2], NULL);
|
||||
get_time_interval(t);
|
||||
if (r) {
|
||||
printf("Error decoding\n");
|
||||
ret = -1;
|
||||
goto quit;
|
||||
} else {
|
||||
printf("DECODED OK in %d:%d (%.2f Mbps)\n", (int) t[0].tv_sec, (int) t[0].tv_usec, (float) mcs.tbs/t[0].tv_usec);
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
quit:
|
||||
srslte_pusch_free(&pusch);
|
||||
srslte_harq_free(&harq_process);
|
||||
|
||||
if (sf_symbols) {
|
||||
free(sf_symbols);
|
||||
}
|
||||
if (data) {
|
||||
free(data);
|
||||
}
|
||||
if (ret) {
|
||||
printf("Error\n");
|
||||
} else {
|
||||
printf("Ok\n");
|
||||
}
|
||||
exit(ret);
|
||||
}
|
|
@ -33,17 +33,14 @@
|
|||
*/
|
||||
|
||||
#define UECFG prhs[0]
|
||||
#define PUSCHCFG prhs[1]
|
||||
#define TRBLKIN prhs[2]
|
||||
#define CQI prhs[3]
|
||||
#define RI prhs[4]
|
||||
#define ACK prhs[5]
|
||||
#define NOF_INPUTS 6
|
||||
#define PUCCHCFG prhs[1]
|
||||
#define ACK prhs[2]
|
||||
#define NOF_INPUTS 3
|
||||
|
||||
void help()
|
||||
{
|
||||
mexErrMsgTxt
|
||||
("sym=srslte_pusch_encode(ue, chs, trblkin, cqi, ri, ack)\n\n");
|
||||
("[subframe, subframe_with_dmrs]=srslte_pucch_encode(ue, chs, ack)\n\n");
|
||||
}
|
||||
|
||||
/* the gateway function */
|
||||
|
@ -58,6 +55,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
srslte_cell_t cell;
|
||||
bzero(&cell, sizeof(srslte_cell_t));
|
||||
cell.nof_ports = 1;
|
||||
cell.cp = SRSLTE_CP_NORM;
|
||||
if (mexutils_read_uint32_struct(UECFG, "NCellID", &cell.id)) {
|
||||
mexErrMsgTxt("Field NCellID not found in UE config\n");
|
||||
return;
|
||||
|
@ -66,157 +64,101 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
|
|||
mexErrMsgTxt("Field NULRB not found in UE config\n");
|
||||
return;
|
||||
}
|
||||
srslte_pusch_t pusch;
|
||||
if (srslte_pusch_init(&pusch, cell)) {
|
||||
srslte_pucch_t pucch;
|
||||
if (srslte_pucch_init(&pucch, cell)) {
|
||||
mexErrMsgTxt("Error initiating PUSCH\n");
|
||||
return;
|
||||
}
|
||||
uint32_t rnti32=0;
|
||||
if (mexutils_read_uint32_struct(UECFG, "RNTI", &rnti32)) {
|
||||
mexErrMsgTxt("Field RNTI not found in pusch config\n");
|
||||
return;
|
||||
}
|
||||
srslte_pusch_set_rnti(&pusch, (uint16_t) (rnti32 & 0xffff));
|
||||
|
||||
|
||||
|
||||
|
||||
uint32_t sf_idx=0;
|
||||
|
||||
uint32_t sf_idx = 0;
|
||||
if (mexutils_read_uint32_struct(UECFG, "NSubframe", &sf_idx)) {
|
||||
mexErrMsgTxt("Field NSubframe not found in UE config\n");
|
||||
return;
|
||||
}
|
||||
srslte_ra_mcs_t mcs;
|
||||
char *mod_str = mexutils_get_char_struct(PUSCHCFG, "Modulation");
|
||||
if (!strcmp(mod_str, "QPSK")) {
|
||||
mcs.mod = SRSLTE_MOD_QPSK;
|
||||
} else if (!strcmp(mod_str, "16QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_16QAM;
|
||||
} else if (!strcmp(mod_str, "64QAM")) {
|
||||
mcs.mod = SRSLTE_MOD_64QAM;
|
||||
} else {
|
||||
mexErrMsgTxt("Unknown modulation\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mxFree(mod_str);
|
||||
|
||||
float *prbset = NULL;
|
||||
mxArray *p;
|
||||
p = mxGetField(PUSCHCFG, 0, "PRBSet");
|
||||
if (!p) {
|
||||
mexErrMsgTxt("Error field PRBSet not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
srslte_ra_ul_alloc_t prb_alloc;
|
||||
bzero(&prb_alloc, sizeof(srslte_ra_ul_alloc_t));
|
||||
prb_alloc.L_prb = mexutils_read_f(p, &prbset);
|
||||
prb_alloc.n_prb[0] = prbset[0];
|
||||
prb_alloc.n_prb[1] = prbset[0];
|
||||
free(prbset);
|
||||
|
||||
mexPrintf("L_prb: %d, n_prb: %d\n", prb_alloc.L_prb, prb_alloc.n_prb[2*sf_idx]);
|
||||
|
||||
uint8_t *trblkin = NULL;
|
||||
mcs.tbs = mexutils_read_uint8(TRBLKIN, &trblkin);
|
||||
|
||||
srslte_harq_t harq_process;
|
||||
if (srslte_harq_init(&harq_process, cell)) {
|
||||
mexErrMsgTxt("Error initiating HARQ process\n");
|
||||
srslte_pucch_cfg_t pucch_cfg;
|
||||
if (mexutils_read_uint32_struct(PUCCHCFG, "ResourceIdx", &pucch_cfg.n_pucch)) {
|
||||
mexErrMsgTxt("Field ResourceIdx not found in PUCCHCFG\n");
|
||||
return;
|
||||
}
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, 0, sf_idx, &prb_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
if (mexutils_read_uint32_struct(PUCCHCFG, "DeltaShift", &pucch_cfg.delta_pucch_shift)) {
|
||||
mexErrMsgTxt("Field DeltaShift not found in PUCCHCFG\n");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t nof_re = SRSLTE_NRE*cell.nof_prb*2*SRSLTE_CP_NSYMB(cell.cp);
|
||||
cf_t *sf_symbols = srslte_vec_malloc(sizeof(cf_t) * nof_re);
|
||||
if (mexutils_read_uint32_struct(PUCCHCFG, "CyclicShifts", &pucch_cfg.N_cs)) {
|
||||
mexErrMsgTxt("Field CyclicShifts not found in PUCCHCFG\n");
|
||||
return;
|
||||
}
|
||||
pucch_cfg.group_hopping_en = false;
|
||||
char *hop = mexutils_get_char_struct(PUCCHCFG, "Hopping");
|
||||
if (hop) {
|
||||
if (!strcmp(hop, "Group")) {
|
||||
pucch_cfg.group_hopping_en = true;
|
||||
}
|
||||
mxFree(hop);
|
||||
}
|
||||
|
||||
uint8_t bits[SRSLTE_PUCCH_MAX_BITS];
|
||||
float *bits_ptr;
|
||||
int n = mexutils_read_f(ACK, &bits_ptr);
|
||||
for (int i=0;i<n;i++) {
|
||||
bits[i] = bits_ptr>0?1:0;
|
||||
}
|
||||
free(bits_ptr);
|
||||
|
||||
switch(n) {
|
||||
case 0:
|
||||
pucch_cfg.format = SRSLTE_PUCCH_FORMAT_1;
|
||||
break;
|
||||
case 1:
|
||||
pucch_cfg.format = SRSLTE_PUCCH_FORMAT_1A;
|
||||
break;
|
||||
case 2:
|
||||
pucch_cfg.format = SRSLTE_PUCCH_FORMAT_1B;
|
||||
break;
|
||||
default:
|
||||
mexErrMsgTxt("Invalid number of bits in parameter ack\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cf_t *sf_symbols = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp));
|
||||
if (!sf_symbols) {
|
||||
mexErrMsgTxt("malloc");
|
||||
return;
|
||||
return;
|
||||
}
|
||||
bzero(sf_symbols, sizeof(cf_t) * nof_re);
|
||||
|
||||
|
||||
srslte_uci_data_t uci_data;
|
||||
bzero(&uci_data, sizeof(srslte_uci_data_t));
|
||||
uci_data.uci_cqi_len = mexutils_read_uint8(CQI, &uci_data.uci_cqi);
|
||||
uint8_t *tmp;
|
||||
uci_data.uci_ri_len = mexutils_read_uint8(RI, &tmp);
|
||||
if (uci_data.uci_ri_len > 0) {
|
||||
uci_data.uci_ri = *tmp;
|
||||
}
|
||||
free(tmp);
|
||||
uci_data.uci_ack_len = mexutils_read_uint8(ACK, &tmp);
|
||||
if (uci_data.uci_ack_len > 0) {
|
||||
uci_data.uci_ack = *tmp;
|
||||
}
|
||||
free(tmp);
|
||||
|
||||
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetCQI", &uci_data.I_offset_cqi)) {
|
||||
uci_data.I_offset_cqi = 7;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetRI", &uci_data.I_offset_ri)) {
|
||||
uci_data.I_offset_ri = 2;
|
||||
}
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "OffsetACK", &uci_data.I_offset_ack)) {
|
||||
uci_data.I_offset_ack = 0;
|
||||
}
|
||||
mexPrintf("TRBL_len: %d, CQI_len: %d, ACK_len: %d (%d), RI_len: %d (%d)\n", mcs.tbs,
|
||||
uci_data.uci_cqi_len, uci_data.uci_ack_len, uci_data.uci_ack, uci_data.uci_ri_len, uci_data.uci_ri);
|
||||
|
||||
|
||||
mexPrintf("NofRE: %d, NofBits: %d, TBS: %d\n", harq_process.nof_re, harq_process.nof_bits, harq_process.mcs.tbs);
|
||||
int r = srslte_pusch_uci_encode(&pusch, &harq_process, trblkin, uci_data, sf_symbols);
|
||||
if (r < 0) {
|
||||
mexErrMsgTxt("Error encoding PUSCH\n");
|
||||
return;
|
||||
}
|
||||
uint32_t rv=0;
|
||||
if (mexutils_read_uint32_struct(PUSCHCFG, "RV", &rv)) {
|
||||
mexErrMsgTxt("Field RV not found in pdsch config\n");
|
||||
return;
|
||||
}
|
||||
if (rv > 0) {
|
||||
if (srslte_harq_setup_ul(&harq_process, mcs, rv, sf_idx, &prb_alloc)) {
|
||||
mexErrMsgTxt("Error configuring HARQ process\n");
|
||||
return;
|
||||
}
|
||||
r = srslte_pusch_uci_encode(&pusch, &harq_process, trblkin, uci_data, sf_symbols);
|
||||
if (r < 0) {
|
||||
mexErrMsgTxt("Error encoding PUSCH\n");
|
||||
return;
|
||||
}
|
||||
bzero(sf_symbols, SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t));
|
||||
if (srslte_pucch_encode(&pucch, &pucch_cfg, sf_idx, bits, sf_symbols)) {
|
||||
mexErrMsgTxt("Error encoding PUCCH\n");
|
||||
return;
|
||||
}
|
||||
|
||||
cf_t *scfdma = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
bzero(scfdma, sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
srslte_ofdm_t fft;
|
||||
srslte_ofdm_tx_init(&fft, SRSLTE_CP_NORM, cell.nof_prb);
|
||||
srslte_ofdm_set_normalize(&fft, true);
|
||||
srslte_ofdm_set_freq_shift(&fft, 0.5);
|
||||
srslte_ofdm_tx_sf(&fft, sf_symbols, scfdma);
|
||||
|
||||
// Matlab toolbox expects further normalization
|
||||
srslte_vec_sc_prod_cfc(scfdma, 1.0/sqrtf(srslte_symbol_sz(cell.nof_prb)), scfdma, SRSLTE_SF_LEN_PRB(cell.nof_prb));
|
||||
|
||||
if (nlhs >= 1) {
|
||||
mexutils_write_cf(scfdma, &plhs[0], SRSLTE_SF_LEN_PRB(cell.nof_prb), 1);
|
||||
mexutils_write_cf(sf_symbols, &plhs[0], SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), 1);
|
||||
}
|
||||
|
||||
if (nlhs >= 2) {
|
||||
mexutils_write_cf(sf_symbols, &plhs[1], nof_re, 1);
|
||||
srslte_refsignal_ul_t pucch_dmrs;
|
||||
if (srslte_refsignal_ul_init(&pucch_dmrs, cell)) {
|
||||
mexErrMsgTxt("Error initiating PUCCH DMRS\n");
|
||||
return;
|
||||
}
|
||||
cf_t *dmrs_pucch = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_NRE*3);
|
||||
if (!dmrs_pucch) {
|
||||
return;
|
||||
}
|
||||
if (srslte_refsignal_dmrs_pucch_gen(&pucch_dmrs, &pucch_cfg, sf_idx, dmrs_pucch)) {
|
||||
mexErrMsgTxt("Error generating PUCCH DMRS\n");
|
||||
return;
|
||||
}
|
||||
if (srslte_refsignal_dmrs_pucch_put(&pucch_dmrs, &pucch_cfg, dmrs_pucch, sf_symbols)) {
|
||||
mexErrMsgTxt("Error generating PUCCH DMRS\n");
|
||||
return;
|
||||
}
|
||||
mexutils_write_cf(sf_symbols, &plhs[0], SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), 1);
|
||||
srslte_refsignal_ul_free(&pucch_dmrs);
|
||||
free(dmrs_pucch);
|
||||
}
|
||||
if (nlhs >= 3) {
|
||||
mexutils_write_cf(pusch.z, &plhs[2], harq_process.nof_re, 1);
|
||||
}
|
||||
srslte_pusch_free(&pusch);
|
||||
free(trblkin);
|
||||
free(uci_data.uci_cqi);
|
||||
|
||||
srslte_pucch_free(&pucch);
|
||||
free(sf_symbols);
|
||||
free(scfdma);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -192,8 +192,8 @@ srslte_cp_t srslte_sync_detect_cp(srslte_sync_t *q, cf_t *input, uint32_t peak_p
|
|||
float R_norm, R_ext, C_norm, C_ext;
|
||||
float M_norm=0, M_ext=0;
|
||||
|
||||
uint32_t cp_norm_len = SRSLTE_CP_NORM(7, q->fft_size);
|
||||
uint32_t cp_ext_len = SRSLTE_CP_EXT(q->fft_size);
|
||||
uint32_t cp_norm_len = SRSLTE_CP_LEN_NORM(7, q->fft_size);
|
||||
uint32_t cp_ext_len = SRSLTE_CP_LEN_EXT(q->fft_size);
|
||||
|
||||
cf_t *input_cp_norm = &input[peak_pos-2*(q->fft_size+cp_norm_len)];
|
||||
cf_t *input_cp_ext = &input[peak_pos-2*(q->fft_size+cp_ext_len)];
|
||||
|
@ -240,7 +240,7 @@ int sync_sss(srslte_sync_t *q, cf_t *input, uint32_t peak_pos, srslte_cp_t cp) {
|
|||
srslte_sss_synch_set_N_id_2(&q->sss, q->N_id_2);
|
||||
|
||||
/* Make sure we have enough room to find SSS sequence */
|
||||
sss_idx = (int) peak_pos-2*q->fft_size-SRSLTE_CP(q->fft_size, (SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM_LEN:SRSLTE_CP_EXT_LEN));
|
||||
sss_idx = (int) peak_pos-2*q->fft_size-SRSLTE_CP_LEN(q->fft_size, (SRSLTE_CP_ISNORM(q->cp)?SRSLTE_CP_NORM_LEN:SRSLTE_CP_EXT_LEN));
|
||||
if (sss_idx < 0) {
|
||||
INFO("Not enough room to decode CP SSS (sss_idx=%d, peak_pos=%d)\n", sss_idx, peak_pos);
|
||||
return SRSLTE_ERROR;
|
||||
|
@ -325,7 +325,7 @@ int srslte_sync_find(srslte_sync_t *q, cf_t *input, uint32_t find_offset, uint32
|
|||
}
|
||||
|
||||
if (q->detect_cp) {
|
||||
if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_EXT(q->fft_size))) {
|
||||
if (peak_pos + find_offset >= 2*(q->fft_size + SRSLTE_CP_LEN_EXT(q->fft_size))) {
|
||||
q->cp = srslte_sync_detect_cp(q, input, peak_pos + find_offset);
|
||||
} else {
|
||||
INFO("Not enough room to detect CP length. Peak position: %d\n", peak_pos);
|
||||
|
|
|
@ -231,7 +231,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Find SSS
|
||||
int sss_idx = peak_idx-2*fft_size-(SRSLTE_CP_ISNORM(cp)?SRSLTE_CP(fft_size, SRSLTE_CP_NORM_LEN):SRSLTE_CP(fft_size, SRSLTE_CP_EXT_LEN));
|
||||
int sss_idx = peak_idx-2*fft_size-(SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN(fft_size, SRSLTE_CP_NORM_LEN):SRSLTE_CP_LEN(fft_size, SRSLTE_CP_EXT_LEN));
|
||||
if (sss_idx >= 0 && sss_idx < flen-fft_size) {
|
||||
srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value);
|
||||
if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) {
|
||||
|
@ -251,7 +251,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Estimate CP
|
||||
if (peak_idx > 2*(fft_size + SRSLTE_CP_EXT(fft_size))) {
|
||||
if (peak_idx > 2*(fft_size + SRSLTE_CP_LEN_EXT(fft_size))) {
|
||||
srslte_cp_t cp = srslte_sync_detect_cp(&ssync, buffer, peak_idx);
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
cp_is_norm++;
|
||||
|
|
|
@ -241,7 +241,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Find SSS
|
||||
int sss_idx = peak_idx-2*fft_size-(SRSLTE_CP_ISNORM(cp)?SRSLTE_CP(fft_size, SRSLTE_CP_NORM_LEN):SRSLTE_CP(fft_size, SRSLTE_CP_EXT_LEN));
|
||||
int sss_idx = peak_idx-2*fft_size-(SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN(fft_size, SRSLTE_CP_NORM_LEN):SRSLTE_CP_LEN(fft_size, SRSLTE_CP_EXT_LEN));
|
||||
if (sss_idx >= 0 && sss_idx < flen-fft_size) {
|
||||
srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value);
|
||||
if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) {
|
||||
|
@ -261,7 +261,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Estimate CP
|
||||
if (peak_idx > 2*(fft_size + SRSLTE_CP_EXT(fft_size))) {
|
||||
if (peak_idx > 2*(fft_size + SRSLTE_CP_LEN_EXT(fft_size))) {
|
||||
srslte_cp_t cp = srslte_sync_detect_cp(&ssync, buffer, peak_idx);
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
cp_is_norm++;
|
||||
|
|
|
@ -76,7 +76,7 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q,
|
|||
goto clean_exit;
|
||||
}
|
||||
}
|
||||
if (srslte_refsignal_ul_init(&q->drms, cell)) {
|
||||
if (srslte_refsignal_ul_init(&q->dmrs, cell)) {
|
||||
fprintf(stderr, "Error initiating srslte_refsignal_ul\n");
|
||||
goto clean_exit;
|
||||
}
|
||||
|
@ -112,7 +112,7 @@ void srslte_ue_ul_free(srslte_ue_ul_t *q) {
|
|||
srslte_harq_free(&q->harq_process[i]);
|
||||
}
|
||||
srslte_cfo_free(&q->cfo);
|
||||
srslte_refsignal_ul_free(&q->drms);
|
||||
srslte_refsignal_ul_free(&q->dmrs);
|
||||
|
||||
if (q->sf_symbols) {
|
||||
free(q->sf_symbols);
|
||||
|
@ -151,9 +151,9 @@ void srslte_ue_ul_reset(srslte_ue_ul_t *q) {
|
|||
srslte_harq_reset(&q->harq_process[0]);
|
||||
}
|
||||
|
||||
void srslte_ue_ul_set_pusch_cfg(srslte_ue_ul_t *q, srslte_refsignal_drms_pusch_cfg_t *drms_cfg, srslte_pusch_hopping_cfg_t *pusch_hopping_cfg)
|
||||
void srslte_ue_ul_set_pusch_cfg(srslte_ue_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg, srslte_pusch_hopping_cfg_t *pusch_hopping_cfg)
|
||||
{
|
||||
memcpy(&q->drms_cfg, drms_cfg, sizeof(srslte_refsignal_drms_pusch_cfg_t));
|
||||
memcpy(&q->dmrs_cfg, dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t));
|
||||
srslte_pusch_set_hopping_cfg(&q->pusch, pusch_hopping_cfg);
|
||||
}
|
||||
|
||||
|
@ -206,13 +206,13 @@ int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, srslte_ra_pusch_t *ra_
|
|||
}
|
||||
|
||||
// FIXME: Pregenerate for all possible number of prb
|
||||
if (srslte_refsignal_dmrs_gen(&q->drms, &q->drms_cfg,
|
||||
if (srslte_refsignal_dmrs_pusch_gen(&q->dmrs, &q->dmrs_cfg,
|
||||
q->harq_process[0].ul_alloc.L_prb, sf_idx, q->refsignal))
|
||||
{
|
||||
fprintf(stderr, "Error generating PUSCH DRMS signals\n");
|
||||
return ret;
|
||||
}
|
||||
srslte_refsignal_drms_pusch_put(&q->drms, &q->drms_cfg, q->refsignal,
|
||||
srslte_refsignal_dmrs_pusch_put(&q->dmrs, &q->dmrs_cfg, q->refsignal,
|
||||
q->harq_process[0].ul_alloc.L_prb,
|
||||
q->harq_process[0].ul_alloc.n_prb_tilde,
|
||||
q->sf_symbols);
|
||||
|
|
|
@ -79,14 +79,14 @@ bool ul_buffer::generate_pusch(sched_grant pusch_grant,
|
|||
return false;
|
||||
}
|
||||
|
||||
srslte_refsignal_drms_pusch_cfg_t drms_cfg;
|
||||
bzero(&drms_cfg, sizeof(srslte_refsignal_drms_pusch_cfg_t));
|
||||
srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg;
|
||||
bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t));
|
||||
|
||||
drms_cfg.beta_pusch = (float) params_db->get_param(params::PUSCH_BETA)/10;
|
||||
drms_cfg.group_hopping_en = params_db->get_param(params::PUSCH_RS_GROUP_HOPPING_EN);
|
||||
drms_cfg.sequence_hopping_en = params_db->get_param(params::PUSCH_RS_SEQUENCE_HOPPING_EN);
|
||||
drms_cfg.cyclic_shift = params_db->get_param(params::PUSCH_RS_CYCLIC_SHIFT);
|
||||
drms_cfg.delta_ss = params_db->get_param(params::PUSCH_RS_GROUP_ASSIGNMENT);
|
||||
dmrs_cfg.beta_pusch = (float) params_db->get_param(params::PUSCH_BETA)/10;
|
||||
dmrs_cfg.group_hopping_en = params_db->get_param(params::PUSCH_RS_GROUP_HOPPING_EN);
|
||||
dmrs_cfg.sequence_hopping_en = params_db->get_param(params::PUSCH_RS_SEQUENCE_HOPPING_EN);
|
||||
dmrs_cfg.cyclic_shift = params_db->get_param(params::PUSCH_RS_CYCLIC_SHIFT);
|
||||
dmrs_cfg.delta_ss = params_db->get_param(params::PUSCH_RS_GROUP_ASSIGNMENT);
|
||||
|
||||
srslte_pusch_hopping_cfg_t pusch_hopping;
|
||||
pusch_hopping.n_sb = params_db->get_param(params::PUSCH_HOPPING_N_SB);
|
||||
|
@ -96,7 +96,7 @@ bool ul_buffer::generate_pusch(sched_grant pusch_grant,
|
|||
pusch_hopping.hopping_offset = params_db->get_param(params::PUSCH_HOPPING_OFFSET);
|
||||
pusch_hopping.current_tx_nb = pusch_grant.get_current_tx_nb();
|
||||
|
||||
srslte_ue_ul_set_pusch_cfg(&ue_ul, &drms_cfg, &pusch_hopping);
|
||||
srslte_ue_ul_set_pusch_cfg(&ue_ul, &dmrs_cfg, &pusch_hopping);
|
||||
|
||||
int n = srslte_ue_ul_pusch_uci_encode_rnti(&ue_ul, (srslte_ra_pusch_t*) pusch_grant.get_grant_ptr(),
|
||||
payload, uci_data,
|
||||
|
|
|
@ -242,7 +242,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Find SSS
|
||||
int sss_idx = peak_idx-2*fft_size-(SRSLTE_CP_ISNORM(cp)?SRSLTE_CP(fft_size, SRSLTE_CP_NORM_LEN):SRSLTE_CP(fft_size, SRSLTE_CP_EXT_LEN));
|
||||
int sss_idx = peak_idx-2*fft_size-(SRSLTE_CP_ISNORM(cp)?SRSLTE_CP_LEN(fft_size, SRSLTE_CP_NORM_LEN):SRSLTE_CP_LEN(fft_size, SRSLTE_CP_EXT_LEN));
|
||||
if (sss_idx >= 0 && sss_idx < flen-fft_size) {
|
||||
srslte_sss_synch_m0m1_partial(&sss, &buffer[sss_idx], 3, NULL, &m0, &m0_value, &m1, &m1_value);
|
||||
if (srslte_sss_synch_N_id_1(&sss, m0, m1) != N_id_1) {
|
||||
|
@ -262,7 +262,7 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
|
||||
// Estimate CP
|
||||
if (peak_idx > 2*(fft_size + SRSLTE_CP_EXT(fft_size))) {
|
||||
if (peak_idx > 2*(fft_size + SRSLTE_CP_LEN_EXT(fft_size))) {
|
||||
srslte_cp_t cp = srslte_sync_detect_cp(&ssync, buffer, peak_idx);
|
||||
if (SRSLTE_CP_ISNORM(cp)) {
|
||||
cp_is_norm++;
|
||||
|
|
Loading…
Reference in New Issue