diff --git a/lte/examples/prach_ue.c b/lte/examples/prach_ue.c index 41a375119..357875438 100644 --- a/lte/examples/prach_ue.c +++ b/lte/examples/prach_ue.c @@ -427,6 +427,10 @@ int main(int argc, char **argv) { if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) { ue_sync_get_last_timestamp(&ue_sync, &uhd_time); + cfo_correct(&ue_sync.sfind.cfocorr, + prach_buffers[7], prach_buffers[7], + -ue_sync_get_cfo(&ue_sync) / lte_symbol_sz(cell.nof_prb)); + timestamp_copy(&next_tx_time, &uhd_time); timestamp_add(&next_tx_time, 0, 0.01); // send next frame (10 ms) printf("Send prach sfn: %d. Last frame time = %.6f, send prach time = %.6f\n", @@ -490,7 +494,7 @@ int main(int argc, char **argv) { printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta); float time_adv_sec = ((float) n_ta)*TS_PRB(cell.nof_prb); - vec_sc_prod_cfc(ul_signal, 2, ul_signal, SF_LEN_PRB(cell.nof_prb)); + vec_sc_prod_cfc(ul_signal, 20, ul_signal, SF_LEN_PRB(cell.nof_prb)); timestamp_copy(&next_tx_time, &uhd_time); @@ -501,7 +505,7 @@ int main(int argc, char **argv) { timestamp_real(&next_tx_time), time_adv_sec*1000000); cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb), next_tx_time.full_secs, next_tx_time.frac_secs); - + go_exit = 1; } if (sfn >= rar_window_stop) { diff --git a/lte/phy/include/liblte/phy/ch_estimation/refsignal_ul.h b/lte/phy/include/liblte/phy/ch_estimation/refsignal_ul.h index 0c20a0576..3be2bea31 100644 --- a/lte/phy/include/liblte/phy/ch_estimation/refsignal_ul.h +++ b/lte/phy/include/liblte/phy/ch_estimation/refsignal_ul.h @@ -52,8 +52,8 @@ typedef struct LIBLTE_API { typedef struct LIBLTE_API { refsignal_ul_cfg_t common; float beta_pusch; - lte_hopping_method_t hopping_method; - uint32_t nof_prb; + bool group_hopping_en; + bool sequence_hopping_en; }refsignal_drms_pusch_cfg_t; typedef struct LIBLTE_API { @@ -86,19 +86,31 @@ LIBLTE_API int refsignal_ul_init(refsignal_ul_t *q, LIBLTE_API void refsignal_ul_free(refsignal_ul_t *q); LIBLTE_API bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, - refsignal_drms_pusch_cfg_t *cfg); + refsignal_drms_pusch_cfg_t *cfg, + uint32_t nof_prb); LIBLTE_API void refsignal_drms_pusch_put(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, cf_t *r_pusch, uint32_t ns_idx, + uint32_t nof_prb, uint32_t n_prb, cf_t *sf_symbols); -LIBLTE_API int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t ns, cf_t *r_pusch); +LIBLTE_API int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, + refsignal_drms_pusch_cfg_t *cfg, + uint32_t nof_prb, + uint32_t ns, + cf_t *r_pusch); -LIBLTE_API void refsignal_dmrs_pucch_gen(refsignal_ul_t *q, refsignal_drms_pucch_cfg_t *cfg, uint32_t ns, cf_t *r_pucch); +LIBLTE_API void refsignal_dmrs_pucch_gen(refsignal_ul_t *q, + refsignal_drms_pucch_cfg_t *cfg, + uint32_t ns, + cf_t *r_pucch); -LIBLTE_API void refsignal_srs_gen(refsignal_ul_t *q, refsignal_srs_cfg_t *cfg, uint32_t ns, cf_t *r_srs); +LIBLTE_API void refsignal_srs_gen(refsignal_ul_t *q, + refsignal_srs_cfg_t *cfg, + uint32_t ns, + cf_t *r_srs); #endif diff --git a/lte/phy/include/liblte/phy/common/phy_common.h b/lte/phy/include/liblte/phy/common/phy_common.h index 7381f0871..7f847a548 100644 --- a/lte/phy/include/liblte/phy/common/phy_common.h +++ b/lte/phy/include/liblte/phy/common/phy_common.h @@ -144,10 +144,6 @@ typedef enum LIBLTE_API { LTE_BPSK = 0, LTE_QPSK = 1, LTE_QAM16 = 2, LTE_QAM64 = 3 } lte_mod_t; -typedef enum LIBLTE_API { - HOPPING_OFF = 0, HOPPING_GROUP = 1, HOPPING_SEQUENCE = 2 -} lte_hopping_method_t; - typedef struct LIBLTE_API { int id; float fd; diff --git a/lte/phy/lib/ch_estimation/src/refsignal_ul.c b/lte/phy/lib/ch_estimation/src/refsignal_ul.c index 1fff84404..e1199aeb9 100644 --- a/lte/phy/lib/ch_estimation/src/refsignal_ul.c +++ b/lte/phy/lib/ch_estimation/src/refsignal_ul.c @@ -210,13 +210,13 @@ 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(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t u, uint32_t v) { - if (cfg->nof_prb == 1) { +static void compute_pusch_r_uv_arg(refsignal_ul_t *q, refsignal_drms_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); - } else if (cfg->nof_prb == 2) { + } else if (nof_prb == 2) { arg_r_uv_2prb(q->tmp_arg, u); } else { - arg_r_uv_mprb(q->tmp_arg, RE_X_RB*cfg->nof_prb, u, v); + arg_r_uv_mprb(q->tmp_arg, RE_X_RB*nof_prb, u, v); } } @@ -232,11 +232,11 @@ static float get_alpha(refsignal_ul_t *q, refsignal_ul_cfg_t *cfg, uint32_t ns) } -bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg) { +bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t nof_prb) { if (cfg->common.cyclic_shift < NOF_CSHIFT && cfg->common.cyclic_shift_for_drms < NOF_CSHIFT && cfg->common.delta_ss < NOF_DELTA_SS && - cfg->nof_prb < q->cell.nof_prb) { + nof_prb < q->cell.nof_prb) { return true; } else { return false; @@ -245,25 +245,28 @@ bool refsignal_drms_pusch_cfg_isvalid(refsignal_ul_t *q, refsignal_drms_pusch_cf void refsignal_drms_pusch_put(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, cf_t *r_pusch, - uint32_t ns_idx, uint32_t n_prb, + uint32_t ns_idx, + uint32_t nof_prb, + uint32_t n_prb, cf_t *sf_symbols) { if (ns_idx < 2) { + DEBUG("Putting DRMS to n_prb: %d, L: %d, ns_idx: %d\n", n_prb, nof_prb, ns_idx); uint32_t L = (ns_idx+1)*CP_NSYMB(q->cell.cp)-4; - memcpy(&sf_symbols[RE_IDX(q->cell.nof_prb, L, n_prb*RE_X_RB)], r_pusch, cfg->nof_prb*RE_X_RB*sizeof(cf_t)); + memcpy(&sf_symbols[RE_IDX(q->cell.nof_prb, L, n_prb*RE_X_RB)], r_pusch, nof_prb*RE_X_RB*sizeof(cf_t)); } } /* Generate DRMS for PUSCH signal according to 5.5.2.1 of 36.211 */ -int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t ns, cf_t *r_pusch) { +int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, uint32_t nof_prb, uint32_t ns, cf_t *r_pusch) { int ret = LIBLTE_ERROR_INVALID_INPUTS; - if (refsignal_drms_pusch_cfg_isvalid(q, cfg)) { + if (refsignal_drms_pusch_cfg_isvalid(q, cfg, nof_prb)) { ret = LIBLTE_ERROR; // Get group hopping number u uint32_t f_gh=0; - if (cfg->hopping_method == HOPPING_GROUP) { + if (cfg->group_hopping_en) { f_gh = q->f_gh[ns]; } uint32_t u = (f_gh + (q->cell.id%30)+cfg->common.delta_ss)%30; @@ -271,25 +274,25 @@ int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, // Get sequence hopping number v uint32_t v = 0; - if (cfg->nof_prb >= 6 && cfg->hopping_method == HOPPING_SEQUENCE) { + if (nof_prb >= 6 && cfg->sequence_hopping_en) { v = q->v_pusch[ns][cfg->common.delta_ss]; } // Compute signal argument - compute_pusch_r_uv_arg(q, cfg, u, v); + compute_pusch_r_uv_arg(q, cfg, nof_prb, u, v); // Add cyclic prefix alpha float alpha = get_alpha(q, &cfg->common, ns); if (verbose == VERBOSE_DEBUG) { - uint32_t N_sz = largest_prime_lower_than(cfg->nof_prb*RE_X_RB); + uint32_t N_sz = largest_prime_lower_than(nof_prb*RE_X_RB); DEBUG("Generating PUSCH DRMS sequence with parameters:\n",0); - DEBUG("\tu: %d, v: %d, alpha: %f, N_sc: %d, root q: %d\n", - u, v, alpha, N_sz, get_q(u,v,N_sz)); + DEBUG("\tnof_prb: %d, u: %d, v: %d, alpha: %f, N_sc: %d, root q: %d\n", + nof_prb, u, v, alpha, N_sz, get_q(u,v,N_sz)); } // Do complex exponential and adjust amplitude - for (int i=0;inof_prb;i++) { + for (int i=0;ibeta_pusch * cexpf(I*(q->tmp_arg[i] + alpha*i)); } ret = 0; diff --git a/lte/phy/lib/ch_estimation/test/refsignal_pusch_mex.c b/lte/phy/lib/ch_estimation/test/refsignal_pusch_mex.c index 8706bd21e..037a4f4b3 100644 --- a/lte/phy/lib/ch_estimation/test/refsignal_pusch_mex.c +++ b/lte/phy/lib/ch_estimation/test/refsignal_pusch_mex.c @@ -76,18 +76,16 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) bzero(&pusch_cfg, sizeof(refsignal_drms_pusch_cfg_t)); + pusch_cfg.group_hopping_en = false; + pusch_cfg.sequence_hopping_en = false; char *tmp = mexutils_get_char_struct(UECFG, "Hopping"); if (tmp) { if (!strcmp(tmp, "Group")) { - pusch_cfg.hopping_method = HOPPING_GROUP; + pusch_cfg.group_hopping_en = true; } else if (!strcmp(tmp, "Sequence")) { - pusch_cfg.hopping_method = HOPPING_SEQUENCE; - } else { - pusch_cfg.hopping_method = HOPPING_OFF; + pusch_cfg.sequence_hopping_en = true; } mxFree(tmp); - } else { - pusch_cfg.hopping_method = HOPPING_OFF; } @@ -104,7 +102,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Error field PRBSet not found in PUSCH config\n"); return; } - pusch_cfg.nof_prb = mexutils_read_f(p, &prbset); + uint32_t nof_prb = mexutils_read_f(p, &prbset); if (mexutils_read_uint32_struct(PUSCHCFG, "DynCyclicShift", &pusch_cfg.common.cyclic_shift_for_drms)) { pusch_cfg.common.cyclic_shift_for_drms = 0; @@ -120,13 +118,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) return; } - mexPrintf("nof_prb: %d, ",pusch_cfg.nof_prb); + mexPrintf("nof_prb: %d, ",nof_prb); mexPrintf("cyclic_shift: %d, ",pusch_cfg.common.cyclic_shift); mexPrintf("cyclic_shift_for_drms: %d, ",pusch_cfg.common.cyclic_shift_for_drms); mexPrintf("delta_ss: %d, ",pusch_cfg.common.delta_ss); - mexPrintf("hopping_method: %d\n, ",pusch_cfg.hopping_method); - cf_t *signal = vec_malloc(2*RE_X_RB*pusch_cfg.nof_prb*sizeof(cf_t)); + cf_t *signal = vec_malloc(2*RE_X_RB*nof_prb*sizeof(cf_t)); if (!signal) { perror("malloc"); return; @@ -139,10 +136,10 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) bzero(sf_symbols, SF_LEN_RE(cell.nof_prb, cell.cp)*sizeof(cf_t)); for (uint32_t i=0;i<2;i++) { //mexPrintf("Generating DRMS for ns=%d, nof_prb=%d\n", 2*sf_idx+i,pusch_cfg.nof_prb); - refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, 2*sf_idx+i, &signal[i*RE_X_RB*pusch_cfg.nof_prb]); + refsignal_dmrs_pusch_gen(&refs, &pusch_cfg, nof_prb, 2*sf_idx+i, &signal[i*RE_X_RB*nof_prb]); } for (uint32_t i=0;i<2;i++) { - refsignal_drms_pusch_put(&refs, &pusch_cfg, &signal[i*RE_X_RB*pusch_cfg.nof_prb], i, prbset[0], sf_symbols); + refsignal_drms_pusch_put(&refs, &pusch_cfg, &signal[i*RE_X_RB*nof_prb], i, nof_prb, prbset[0], sf_symbols); } if (nlhs >= 1) { mexutils_write_cf(sf_symbols, &plhs[0], SF_LEN_RE(cell.nof_prb, cell.cp), 1); diff --git a/lte/phy/lib/ch_estimation/test/refsignal_ul_test.c b/lte/phy/lib/ch_estimation/test/refsignal_ul_test.c index 1f078497e..122fa6e50 100644 --- a/lte/phy/lib/ch_estimation/test/refsignal_ul_test.c +++ b/lte/phy/lib/ch_estimation/test/refsignal_ul_test.c @@ -74,8 +74,6 @@ void parse_args(int argc, char **argv) { } } -lte_hopping_method_t hopping_modes[3]={HOPPING_OFF, HOPPING_SEQUENCE, HOPPING_GROUP}; - int main(int argc, char **argv) { refsignal_ul_t refs; refsignal_drms_pusch_cfg_t pusch_cfg; @@ -100,25 +98,33 @@ int main(int argc, char **argv) { for (int n=6;nsf_idx, lte_mod_string(harq->mcs.mod), harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); + INFO("Encoding PUSCH SF: %d, Mod %s, RNTI: %d, TBS: %d, NofSymbols: %d, NofBitsE: %d, rv_idx: %d\n", + harq->sf_idx, lte_mod_string(harq->mcs.mod), rnti, harq->mcs.tbs, harq->nof_re, harq->nof_bits, harq->rv); bzero(q->pusch_q, harq->nof_bits); if (ulsch_uci_encode(&q->dl_sch, harq, data, uci_data, q->pusch_g, q->pusch_q)) { diff --git a/lte/phy/lib/phch/test/pusch_encode_test_mex.c b/lte/phy/lib/phch/test/pusch_encode_test_mex.c index 9db626df2..ed3dd06f8 100644 --- a/lte/phy/lib/phch/test/pusch_encode_test_mex.c +++ b/lte/phy/lib/phch/test/pusch_encode_test_mex.c @@ -112,8 +112,8 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) ra_ul_alloc_t prb_alloc; bzero(&prb_alloc, sizeof(ra_ul_alloc_t)); prb_alloc.L_prb = mexutils_read_f(p, &prbset); - prb_alloc.n_prb[2*sf_idx] = prbset[0]; - prb_alloc.n_prb[2*sf_idx+1] = prbset[0]; + 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]); diff --git a/lte/phy/lib/ue/src/ue_ul.c b/lte/phy/lib/ue/src/ue_ul.c index 48a9f79ba..6e254d640 100644 --- a/lte/phy/lib/ue/src/ue_ul.c +++ b/lte/phy/lib/ue/src/ue_ul.c @@ -140,7 +140,7 @@ void ue_ul_reset(ue_ul_t *q) { void ue_ul_set_pusch_cfg(ue_ul_t *q, refsignal_drms_pusch_cfg_t *pusch_drms_cfg, pusch_hopping_cfg_t *pusch_hopping_cfg) { - memcpy(&q->pusch_drms_cfg, pusch_drms_cfg, sizeof(refsignal_drms_pucch_cfg_t)); + memcpy(&q->pusch_drms_cfg, pusch_drms_cfg, sizeof(refsignal_drms_pusch_cfg_t)); pusch_set_hopping_cfg(&q->pusch, pusch_hopping_cfg); } @@ -186,27 +186,25 @@ int ue_ul_pusch_uci_encode_rnti(ue_ul_t *q, ra_pusch_t *ra_ul, uint8_t *data, uc fprintf(stderr, "Error configuring HARQ process\n"); return ret; } - + printf("sf_idx: %d, rnti: %d\n", sf_idx, rnti); if (pusch_encode_rnti(&q->pusch, &q->harq_process[0], data, rnti, q->sf_symbols)) { fprintf(stderr, "Error encoding TB\n"); return ret; } - q->pusch_drms_cfg.nof_prb = ra_ul->prb_alloc.L_prb; for (uint32_t i=0;i<2;i++) { // FIXME: Pregenerate for all possible number of prb - if (refsignal_dmrs_pusch_gen(&q->drms, &q->pusch_drms_cfg, 2*sf_idx+i, q->refsignal)) { + if (refsignal_dmrs_pusch_gen(&q->drms, &q->pusch_drms_cfg, ra_ul->prb_alloc.L_prb, 2*sf_idx+i, q->refsignal)) { fprintf(stderr, "Error generating PUSCH DRMS signals\n"); return ret; } - printf("n_prb_tilde[%d] = %d\n", i, ra_ul->prb_alloc.n_prb_tilde[i]); refsignal_drms_pusch_put(&q->drms, &q->pusch_drms_cfg, q->refsignal, i, - ra_ul->prb_alloc.n_prb_tilde[i], q->sf_symbols); + ra_ul->prb_alloc.L_prb, ra_ul->prb_alloc.n_prb_tilde[i], q->sf_symbols); } lte_ifft_run_sf(&q->fft, q->sf_symbols, output_signal); - // cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / lte_symbol_sz(q->cell.nof_prb)); + cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / lte_symbol_sz(q->cell.nof_prb)); ret = LIBLTE_SUCCESS; } diff --git a/lte/phy/lib/utils/src/vector.c b/lte/phy/lib/utils/src/vector.c index d695a4de6..989eef1f8 100644 --- a/lte/phy/lib/utils/src/vector.c +++ b/lte/phy/lib/utils/src/vector.c @@ -96,7 +96,7 @@ void vec_sub_fff(float *x, float *y, float *z, uint32_t len) { } void vec_sub_ccc(cf_t *x, cf_t *y, cf_t *z, uint32_t len) { - return vec_sub_fff((float*) x,(float*) y,(float*) z,2*len); + return vec_sub_fff((float*) x,(float*) y,(float*) z, 2*len); } void vec_sum_fff(float *x, float *y, float *z, uint32_t len) { diff --git a/matlab/tests/drms_pusch_test.m b/matlab/tests/drms_pusch_test.m index c5859af27..c6a16e783 100644 --- a/matlab/tests/drms_pusch_test.m +++ b/matlab/tests/drms_pusch_test.m @@ -35,7 +35,6 @@ for prb=3 if (error(k) > 10^-3) k=1; end - read_real k=k+1; end end @@ -49,5 +48,5 @@ plot(error); disp(info) disp(length(subframe_mat)) n=1:length(subframe_mat(:)); -plot(n,real(subframe_mat(:)),n,real(subframe_lib(:))) - +%plot(n,real(subframe_mat(:)),n,real(subframe_lib(:))) +plot(abs(subframe_mat(:)-subframe_lib(:))) diff --git a/matlab/tests/pusch_test.m b/matlab/tests/pusch_test.m index 2b4bc92f1..797da49d4 100644 --- a/matlab/tests/pusch_test.m +++ b/matlab/tests/pusch_test.m @@ -1,6 +1,6 @@ clear -ueConfig=struct('NCellID',1,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1); -puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[21:24]','Modulation','QPSK','RV',0,'Shortened',0); +ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1); +puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',[0:2]','Modulation','QPSK','RV',0,'Shortened',0); addpath('../../debug/lte/phy/lib/phch/test') @@ -10,7 +10,7 @@ addpath('../../debug/lte/phy/lib/phch/test') % rvs=0; % betas=0:3:11; -TBs=88; +TBs=56; cqilen=0; mods={'QPSK'}; rvs=0; @@ -68,7 +68,8 @@ end if (length(TBs) == 1) %disp(info) - n=1:length(mat); + %n=1:length(mat); %plot(abs(double(mat)-double(lib))) - plot(n,real(lib(n)),n,real(mat(n))) + %plot(n,real(lib(n)),n,real(mat(n))) + plot(abs(waveform_lib-waveform)) end