From 5dc755f3019413f3053eaaf2824a6a592550e723 Mon Sep 17 00:00:00 2001 From: ismagom Date: Wed, 11 Mar 2015 17:42:36 +0100 Subject: [PATCH] Testing with amarisoft --- lte/examples/pdsch_enodeb.c | 1 + lte/examples/prach_ue.c | 365 +++++++++++------- lte/phy/include/liblte/phy/common/fft.h | 5 +- lte/phy/include/liblte/phy/ue/ue_ul.h | 5 + lte/phy/lib/ch_estimation/src/chest_dl.c | 2 +- lte/phy/lib/ch_estimation/src/refsignal_ul.c | 4 +- lte/phy/lib/common/src/fft.c | 7 +- lte/phy/lib/phch/src/pcfich.c | 2 +- lte/phy/lib/phch/src/prach.c | 4 +- lte/phy/lib/phch/src/pusch.c | 3 +- lte/phy/lib/phch/test/pusch_encode_test_mex.c | 4 + lte/phy/lib/ue/src/ue_dl.c | 5 +- lte/phy/lib/ue/src/ue_ul.c | 23 +- matlab/tests/drms_pusch_test.m | 8 +- matlab/tests/pusch_decode_test.m | 11 + matlab/tests/pusch_test.m | 6 +- matlab/tests/test_scfdma_peakamp.m | 32 ++ 17 files changed, 330 insertions(+), 157 deletions(-) create mode 100644 matlab/tests/pusch_decode_test.m create mode 100644 matlab/tests/test_scfdma_peakamp.m diff --git a/lte/examples/pdsch_enodeb.c b/lte/examples/pdsch_enodeb.c index 8c862faef..f3ed59cf0 100644 --- a/lte/examples/pdsch_enodeb.c +++ b/lte/examples/pdsch_enodeb.c @@ -220,6 +220,7 @@ void base_init() { fprintf(stderr, "Error creating iFFT object\n"); exit(-1); } + lte_fft_set_normalize(&ifft, true); if (pbch_init(&pbch, cell)) { fprintf(stderr, "Error creating PBCH object\n"); exit(-1); diff --git a/lte/examples/prach_ue.c b/lte/examples/prach_ue.c index 4021537cb..d0b7a749b 100644 --- a/lte/examples/prach_ue.c +++ b/lte/examples/prach_ue.c @@ -69,7 +69,8 @@ typedef struct { float uhd_rx_freq; float uhd_tx_freq; float uhd_tx_freq_offset; - float uhd_gain; + float uhd_tx_gain; + float uhd_rx_gain; }prog_args_t; void args_default(prog_args_t *args) { @@ -81,13 +82,15 @@ void args_default(prog_args_t *args) { args->uhd_rx_freq = 2112500000.0; args->uhd_tx_freq = 1922500000.0; args->uhd_tx_freq_offset = 8000000.0; - args->uhd_gain = 60.0; + args->uhd_tx_gain = 60.0; + args->uhd_rx_gain = 60.0; } void usage(prog_args_t *args, char *prog) { printf("Usage: %s [agfFrlnv]\n", prog); printf("\t-a UHD args [Default %s]\n", args->uhd_args); - printf("\t-g UHD TX/RX gain [Default %.2f dB]\n", args->uhd_gain); + printf("\t-g UHD TX/RX gain [Default %.2f dB]\n", args->uhd_rx_gain); + printf("\t-G UHD TX/RX gain [Default %.2f dB]\n", args->uhd_tx_gain); printf("\t-f UHD RX freq [Default %.1f MHz]\n", args->uhd_rx_freq/1000000); printf("\t-F UHD TX freq [Default %.1f MHz]\n", args->uhd_tx_freq/1000000); printf("\t-r RNTI [Default 0x%x]\n",args->rnti); @@ -99,13 +102,16 @@ void usage(prog_args_t *args, char *prog) { void parse_args(prog_args_t *args, int argc, char **argv) { int opt; args_default(args); - while ((opt = getopt(argc, argv, "agfFrlnv")) != -1) { + while ((opt = getopt(argc, argv, "agGfFrlnv")) != -1) { switch (opt) { case 'a': args->uhd_args = argv[optind]; break; case 'g': - args->uhd_gain = atof(argv[optind]); + args->uhd_rx_gain = atof(argv[optind]); + break; + case 'G': + args->uhd_tx_gain = atof(argv[optind]); break; case 'f': args->uhd_rx_freq = atof(argv[optind]); @@ -175,7 +181,7 @@ cf_t *sf_buffer = NULL; int generate_prach_sequences(){ for(int i=0;i 3) || sfn > rar_window_start) { - gettimeofday(&tdata[1], NULL); - printf("Looking for RAR in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync)); - n = ue_dl_decode_rnti(&ue_dl, sf_buffer, data_rx, ue_sync_get_sfidx(&ue_sync), ra_rnti); - if (n < 0) { - fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); - } else if (n > 0) { - - gettimeofday(&tdata[2], NULL); - get_time_interval(tdata); - printf("time exec DL: %d\n",tdata[0].tv_usec); - - gettimeofday(&tdata[1], NULL); - - rar_unpack(data_rx, &rar_msg); - rar_msg_fprint(stdout, &rar_msg); - - dci_rar_to_ra_ul(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, cell.nof_prb, &ra_pusch); - ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb); + if (state != RECV_RAR) { + /* Run FFT for all subframe data */ + lte_fft_run_sf(&ue_dl.fft, sf_buffer, ue_dl.sf_symbols); - ra_ul_alloc(&ra_pusch.prb_alloc, &ra_pusch, 0, cell.nof_prb); - - uint32_t ul_sf_idx = (ue_sync_get_sfidx(&ue_sync)+6)%10; - - //ue_ul_set_cfo(&ue_ul, sync_get_cfo(&ue_sync.strack)); - bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs); - n = ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, rar_msg.temp_c_rnti, ul_signal); + /* Get channel estimates for each port */ + chest_dl_estimate(&ue_dl.chest, ue_dl.sf_symbols, ue_dl.ce, ue_sync_get_sfidx(&ue_sync)); + } + + if (sf_cnt > 1000) { + switch (state) { + case DECODE_MIB: + if (ue_sync_get_sfidx(&ue_sync) == 0) { + pbch_decode_reset(&ue_mib.pbch); + n = ue_mib_decode(&ue_mib, sf_buffer, bch_payload_unpacked, NULL, &sfn_offset); if (n < 0) { - fprintf(stderr, "Error encoding PUSCH\n"); + fprintf(stderr, "Error decoding UE MIB\n"); exit(-1); + } else if (n == MIB_FOUND) { + bit_unpack_vector(bch_payload_unpacked, bch_payload, BCH_PAYLOAD_LEN); + bcch_bch_unpack(bch_payload, BCH_PAYLOAD_LEN, &cell, &sfn); + printf("Decoded MIB. SFN: %d, offset: %d\n", sfn, sfn_offset); + sfn = (sfn + sfn_offset)%1024; + state = SEND_PRACH; } - - gettimeofday(&tdata[2], NULL); - get_time_interval(tdata); - printf("time exec UL: %d\n",tdata[0].tv_usec); - - gettimeofday(&tdata[1], NULL); - cuhd_stop_rx_stream(uhd); - cuhd_flush_buffer(uhd); - gettimeofday(&tdata[2], NULL); - get_time_interval(tdata); - printf("time to stop RX: %d\n",tdata[0].tv_usec); - - ue_sync_get_last_timestamp(&ue_sync, &uhd_time); + } + break; + case SEND_PRACH: - uint32_t n_ta = lte_N_ta_new_rar(rar_msg.timing_adv_cmd); - printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta); - float time_adv_sec = ((float) n_ta)*LTE_TS; - - vec_sc_prod_cfc(ul_signal, 2, ul_signal, SF_LEN_PRB(cell.nof_prb)); + #ifdef kk + if (((sfn%2) == 1) && (ue_sync_get_sfidx(&ue_sync) == 1)) { + ue_sync_get_last_timestamp(&ue_sync, &uhd_time); + + 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", + sfn, timestamp_real(&uhd_time), timestamp_real(&next_tx_time)); + cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len, + next_tx_time.full_secs, next_tx_time.frac_secs); - timestamp_copy(&next_tx_time, &uhd_time); - timestamp_add(&next_tx_time, 0, 0.006 - time_adv_sec); // send after 6 sub-frames (6 ms) - printf("Send %d samples PUSCH sfn: %d. Last frame time = %.6f" - "send PUSCH time = %.6f TA: %.1f us\n", - SF_LEN_PRB(cell.nof_prb), sfn, timestamp_real(&uhd_time), - 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); - - vec_save_file("prach_example_signal", ul_signal, sizeof(cf_t)*7680); - go_exit = 1; + ra_rnti = 2; + rar_window_start = sfn+1; + rar_window_stop = sfn+3; + state = RECV_RAR; } - if (sfn >= rar_window_stop) { - state = SEND_PRACH; - rar_trials++; - if (rar_trials >= 4) { + #else + cuhd_recv_with_time(uhd, dummy, 4, 1, &rx_time.full_secs, &rx_time.frac_secs); + + timestamp_copy(&tx_time, &rx_time); + printf("Transmitting PRACH...\n"); + vec_save_file("prach_tx", prach_buffers[7], prach_buffer_len*sizeof(cf_t)); + while(1) { + timestamp_add(&tx_time, 0, 0.001); // send every (10 ms) + cuhd_send_timed(uhd, prach_buffers[7], prach_buffer_len, + tx_time.full_secs, tx_time.frac_secs); + + } + #endif + break; + case RECV_RAR: + #ifdef kk + + if ((sfn == rar_window_start && ue_sync_get_sfidx(&ue_sync) > 3) || sfn > rar_window_start) { + printf("Looking for RAR in sfn: %d sf_idx: %d\n", sfn, ue_sync_get_sfidx(&ue_sync)); + n = ue_dl_decode_rnti(&ue_dl, sf_buffer, data_rx, ue_sync_get_sfidx(&ue_sync), ra_rnti); + if (n < 0) { + fprintf(stderr, "Error decoding UE DL\n");fflush(stdout); + } else if (n > 0) { + cuhd_stop_rx_stream(uhd); + cuhd_flush_buffer(uhd); + + rar_unpack(data_rx, &rar_msg); + rar_msg_fprint(stdout, &rar_msg); + + dci_rar_to_ra_ul(rar_msg.rba, rar_msg.mcs, rar_msg.hopping_flag, cell.nof_prb, &ra_pusch); + ra_pusch_fprint(stdout, &ra_pusch, cell.nof_prb); + + ra_ul_alloc(&ra_pusch.prb_alloc, &ra_pusch, 0, cell.nof_prb); + + ue_sync_get_last_timestamp(&ue_sync, &uhd_time); + + bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs); + + uint32_t n_ta = lte_N_ta_new_rar(rar_msg.timing_adv_cmd); + printf("ta: %d, n_ta: %d\n", rar_msg.timing_adv_cmd, n_ta); + float time_adv_sec = ((float) n_ta+15)/(15000.0*lte_symbol_sz(cell.nof_prb)); +#define N_TX 5 + const uint32_t rv[N_TX]={0,2,3,1,0}; + for (int i=0; i= rar_window_stop) { + state = SEND_PRACH; + rar_trials++; + if (rar_trials >= 1) { + go_exit = 1; + } + } + } + #else + + ra_pusch.mcs.mod = LTE_QPSK; + ra_pusch.mcs.tbs = 94; + ra_pusch.rv_idx = 0; + ra_pusch.prb_alloc.freq_hopping = 0; + ra_pusch.prb_alloc.L_prb = 4; + ra_pusch.prb_alloc.n_prb[0] = 19; + ra_pusch.prb_alloc.n_prb[1] = 19; + + uint32_t ul_sf_idx = 4; + printf("L: %d\n", ra_pusch.prb_alloc.L_prb); + // ue_ul_set_cfo(&ue_ul, sync_get_cfo(&ue_sync.strack)); + bit_pack_vector((uint8_t*) conn_request_msg, data, ra_pusch.mcs.tbs); + n = ue_ul_pusch_encode_rnti(&ue_ul, &ra_pusch, data, ul_sf_idx, 111, ul_signal); + if (n < 0) { + fprintf(stderr, "Error encoding PUSCH\n"); + exit(-1); + } + + vec_save_file("pusch_tx", ul_signal, SF_LEN_PRB(cell.nof_prb)*sizeof(cf_t)); + + #ifdef use_usrp + cuhd_recv_with_time(uhd, dummy, 4, 1, &uhd_time.full_secs, &uhd_time.frac_secs); + timestamp_copy(&next_tx_time, &uhd_time); + while(1) { + timestamp_add(&next_tx_time, 0, 0.002); // send every 2 ms + cuhd_send_timed(uhd, ul_signal, SF_LEN_PRB(cell.nof_prb), + next_tx_time.full_secs, next_tx_time.frac_secs); + } + #else + exit(-1); + #endif + #endif + + break; + } + if (ue_sync_get_sfidx(&ue_sync) == 9) { + sfn++; + if (sfn == 1024) { + sfn = 0; + } + } + } + } else if (ret == 0) { printf("Finding PSS... Peak: %8.1f, FrameCnt: %d, State: %d\r", sync_get_peak_value(&ue_sync.sfind), diff --git a/lte/phy/include/liblte/phy/common/fft.h b/lte/phy/include/liblte/phy/common/fft.h index e0aebbf3e..1107fab13 100644 --- a/lte/phy/include/liblte/phy/common/fft.h +++ b/lte/phy/include/liblte/phy/common/fft.h @@ -37,8 +37,6 @@ #include "liblte/phy/common/phy_common.h" #include "liblte/phy/utils/dft.h" -#define LTE_FFT_NORMALIZE - typedef _Complex float cf_t; /* this is only a shortcut */ /* This is common for both directions */ @@ -87,4 +85,7 @@ LIBLTE_API void lte_ifft_run_sf(lte_fft_t *q, LIBLTE_API int lte_fft_set_freq_shift(lte_fft_t *q, float freq_shift); +LIBLTE_API void lte_fft_set_normalize(lte_fft_t *q, + bool normalize_enable); + #endif diff --git a/lte/phy/include/liblte/phy/ue/ue_ul.h b/lte/phy/include/liblte/phy/ue/ue_ul.h index 0f3065e6a..ec55359e7 100644 --- a/lte/phy/include/liblte/phy/ue/ue_ul.h +++ b/lte/phy/include/liblte/phy/ue/ue_ul.h @@ -54,6 +54,8 @@ typedef struct LIBLTE_API { cfo_t cfo; lte_cell_t cell; + bool normalize_en; + float current_cfo; refsignal_drms_pusch_cfg_t pusch_drms_cfg; @@ -77,6 +79,9 @@ LIBLTE_API void ue_ul_free(ue_ul_t *q); LIBLTE_API void ue_ul_set_cfo(ue_ul_t *q, float cur_cfo); +LIBLTE_API void ue_ul_set_normalization(ue_ul_t *q, + bool enabled); + LIBLTE_API 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); diff --git a/lte/phy/lib/ch_estimation/src/chest_dl.c b/lte/phy/lib/ch_estimation/src/chest_dl.c index 12c5cdd7d..8e77af263 100644 --- a/lte/phy/lib/ch_estimation/src/chest_dl.c +++ b/lte/phy/lib/ch_estimation/src/chest_dl.c @@ -129,7 +129,7 @@ int chest_dl_init(chest_dl_t *q, lte_cell_t cell) float f[5]={0.05, 0.2, 0.5, 0.2, 0.05}; chest_dl_set_filter_freq(q, f, 5); - float t[2]={0.2, 0.8}; + float t[2]={0.1, 0.9}; chest_dl_set_filter_time(q, t, 0); q->cell = cell; diff --git a/lte/phy/lib/ch_estimation/src/refsignal_ul.c b/lte/phy/lib/ch_estimation/src/refsignal_ul.c index e1199aeb9..499d148e0 100644 --- a/lte/phy/lib/ch_estimation/src/refsignal_ul.c +++ b/lte/phy/lib/ch_estimation/src/refsignal_ul.c @@ -287,8 +287,8 @@ int refsignal_dmrs_pusch_gen(refsignal_ul_t *q, refsignal_drms_pusch_cfg_t *cfg, if (verbose == VERBOSE_DEBUG) { uint32_t N_sz = largest_prime_lower_than(nof_prb*RE_X_RB); DEBUG("Generating PUSCH DRMS sequence with parameters:\n",0); - 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)); + DEBUG("\tbeta: %.1f, nof_prb: %d, u: %d, v: %d, alpha: %f, N_sc: %d, root q: %d, nprs: %d\n", + cfg->beta_pusch, nof_prb, u, v, alpha, N_sz, get_q(u,v,N_sz),q->n_prs_pusch[cfg->common.delta_ss][ns]); } // Do complex exponential and adjust amplitude diff --git a/lte/phy/lib/common/src/fft.c b/lte/phy/lib/common/src/fft.c index 4924ce799..772f4e849 100644 --- a/lte/phy/lib/common/src/fft.c +++ b/lte/phy/lib/common/src/fft.c @@ -182,6 +182,10 @@ void lte_ifft_run_slot(lte_fft_t *q, cf_t *input, cf_t *output) { } } +void lte_fft_set_normalize(lte_fft_t *q, bool normalize_enable) { + dft_plan_set_norm(&q->fft_plan, normalize_enable); +} + void lte_ifft_run_sf(lte_fft_t *q, cf_t *input, cf_t *output) { uint32_t n; for (n=0;n<2;n++) { @@ -190,7 +194,4 @@ void lte_ifft_run_sf(lte_fft_t *q, cf_t *input, cf_t *output) { if (q->freq_shift) { vec_prod_ccc(output, q->shift_buffer, output, 2*q->slot_sz); } -#ifdef LTE_FFT_NORMALIZE - vec_sc_prod_cfc(output, (float) 1.0/sqrtf(q->symbol_sz),output,2*q->slot_sz); -#endif } diff --git a/lte/phy/lib/phch/src/pcfich.c b/lte/phy/lib/phch/src/pcfich.c index 1d9a37954..c645ad347 100644 --- a/lte/phy/lib/phch/src/pcfich.c +++ b/lte/phy/lib/phch/src/pcfich.c @@ -130,7 +130,7 @@ float pcfich_cfi_decode(pcfich_t *q, uint32_t *cfi) { float max_corr = 0; for (i = 0; i < 3; i++) { - float corr = vec_dot_prod_fff(q->cfi_table_float[i], q->data_f, PCFICH_CFI_LEN); + float corr = fabsf(vec_dot_prod_fff(q->cfi_table_float[i], q->data_f, PCFICH_CFI_LEN)); if (corr > max_corr) { max_corr = corr; index = i; diff --git a/lte/phy/lib/phch/src/prach.c b/lte/phy/lib/phch/src/prach.c index b5779f36a..d9b74e397 100644 --- a/lte/phy/lib/phch/src/prach.c +++ b/lte/phy/lib/phch/src/prach.c @@ -399,9 +399,9 @@ int prach_gen(prach_t *p, for(int i=0;iN_seq;i++){ signal[p->N_cp+i] = p->ifft_out[i%p->N_ifft_prach]; } - + // Normalize - vec_sc_prod_cfc(signal, 1.0/sqrtf(p->N_ifft_ul), signal, (p->N_cp + p->N_seq)); + vec_sc_prod_cfc(signal, 1.0/sqrtf(p->N_ifft_prach*2), signal, (p->N_cp + p->N_seq)); ret = LIBLTE_SUCCESS; } diff --git a/lte/phy/lib/phch/src/pusch.c b/lte/phy/lib/phch/src/pusch.c index d3e254a5d..4411eb1f5 100644 --- a/lte/phy/lib/phch/src/pusch.c +++ b/lte/phy/lib/phch/src/pusch.c @@ -122,7 +122,8 @@ int pusch_cp(pusch_t *q, harq_t *harq, cf_t *input, cf_t *output, bool advance_i n_prb_tilde = (n_vrb_tilde+f_hop(q, hopping, i)*n_rb_sb+ (n_rb_sb-1)-2*(n_vrb_tilde%n_rb_sb)*f_m(q, hopping, i))%(n_rb_sb*hopping->n_sb); - INFO("n_prb_tilde: %d, n_vrb_tilde: %d, n_rb_sb: %d, n_sb: %d\n", n_prb_tilde, n_vrb_tilde, n_rb_sb, hopping->n_sb); + INFO("n_prb_tilde: %d, n_vrb_tilde: %d, n_rb_sb: %d, n_sb: %d\n", + n_prb_tilde, n_vrb_tilde, n_rb_sb, hopping->n_sb); if (hopping->n_sb > 1) { n_prb_tilde += (hopping->hopping_offset-1)/2+1; } 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 ed3dd06f8..a4fca1a6e 100644 --- a/lte/phy/lib/phch/test/pusch_encode_test_mex.c +++ b/lte/phy/lib/phch/test/pusch_encode_test_mex.c @@ -198,8 +198,12 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) bzero(scfdma, sizeof(cf_t) * SF_LEN_PRB(cell.nof_prb)); lte_fft_t fft; lte_ifft_init(&fft, CPNORM, cell.nof_prb); + lte_fft_set_normalize(&fft, true); lte_fft_set_freq_shift(&fft, 0.5); lte_ifft_run_sf(&fft, sf_symbols, scfdma); + + // Matlab toolbox expects further normalization + vec_sc_prod_cfc(scfdma, 1.0/sqrtf(512), scfdma, SF_LEN_PRB(cell.nof_prb)); if (nlhs >= 1) { mexutils_write_cf(scfdma, &plhs[0], SF_LEN_PRB(cell.nof_prb), 1); diff --git a/lte/phy/lib/ue/src/ue_dl.c b/lte/phy/lib/ue/src/ue_dl.c index 424d5a256..4db4b5d87 100644 --- a/lte/phy/lib/ue/src/ue_dl.c +++ b/lte/phy/lib/ue/src/ue_dl.c @@ -188,7 +188,7 @@ int ue_dl_decode_fft_estimate(ue_dl_t *q, cf_t *input, uint32_t sf_idx, uint32_t return LIBLTE_ERROR; } - INFO("Decoded CFI=%d with correlation %.2f\n", cfi, cfi_corr); + INFO("Decoded CFI=%d with correlation %.2f\n", *cfi, cfi_corr); if (regs_set_cfi(&q->regs, *cfi)) { fprintf(stderr, "Error setting CFI\n"); @@ -285,11 +285,12 @@ int ue_dl_decode_rnti_rv(ue_dl_t *q, cf_t *input, uint8_t *data, uint32_t sf_idx formats = ue_formats; nof_formats = nof_ue_formats; } - + /* For all possible locations, try to decode a DCI message */ crc_rem = 0; uint32_t found_dci = 0; for (int f=0;fpdcch, &dci_msg, &locations[i], formats[f], &crc_rem)) { fprintf(stderr, "Error decoding DCI msg\n"); diff --git a/lte/phy/lib/ue/src/ue_ul.c b/lte/phy/lib/ue/src/ue_ul.c index 6e254d640..4c0cc71a2 100644 --- a/lte/phy/lib/ue/src/ue_ul.c +++ b/lte/phy/lib/ue/src/ue_ul.c @@ -57,6 +57,9 @@ int ue_ul_init(ue_ul_t *q, goto clean_exit; } lte_fft_set_freq_shift(&q->fft, 0.5); + lte_fft_set_normalize(&q->fft, true); + + q->normalize_en = true; if (cfo_init(&q->cfo, CURRENT_SFLEN)) { fprintf(stderr, "Error creating CFO object\n"); @@ -125,6 +128,11 @@ void ue_ul_set_cfo(ue_ul_t *q, float cur_cfo) { q->current_cfo = cur_cfo; } +void ue_ul_set_normalization(ue_ul_t *q, bool enabled) +{ + q->normalize_en = enabled; +} + /* Precalculate the PDSCH scramble sequences for a given RNTI. This function takes a while * to execute, so shall be called once the final C-RNTI has been allocated for the session. * For the connection procedure, use pusch_encode_rnti() or pusch_decode_rnti() functions @@ -194,17 +202,26 @@ int ue_ul_pusch_uci_encode_rnti(ue_ul_t *q, ra_pusch_t *ra_ul, uint8_t *data, uc 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, ra_ul->prb_alloc.L_prb, 2*sf_idx+i, q->refsignal)) { + if (refsignal_dmrs_pusch_gen(&q->drms, &q->pusch_drms_cfg, + q->harq_process[0].ul_alloc.L_prb, 2*sf_idx+i, q->refsignal)) + { fprintf(stderr, "Error generating PUSCH DRMS signals\n"); return ret; } refsignal_drms_pusch_put(&q->drms, &q->pusch_drms_cfg, q->refsignal, i, - ra_ul->prb_alloc.L_prb, ra_ul->prb_alloc.n_prb_tilde[i], q->sf_symbols); + q->harq_process[0].ul_alloc.L_prb, + q->harq_process[0].ul_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)); + + if (q->normalize_en) { + float norm_factor = (float) q->cell.nof_prb/10/sqrtf(q->harq_process[0].ul_alloc.L_prb); + vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SF_LEN_PRB(q->cell.nof_prb)); + } ret = LIBLTE_SUCCESS; } diff --git a/matlab/tests/drms_pusch_test.m b/matlab/tests/drms_pusch_test.m index c6a16e783..fa290dc50 100644 --- a/matlab/tests/drms_pusch_test.m +++ b/matlab/tests/drms_pusch_test.m @@ -6,9 +6,9 @@ addpath('../../debug/lte/phy/lib/ch_estimation/test') Hopping={'Off','Sequence','Group'}; k=1; -for prb=3 - for ncell=0 - for ns=8:9 +for prb=4 + for ncell=1 + for ns=4 for h=1 for sg=0 for cs=0 @@ -20,7 +20,7 @@ for prb=3 ueConfig.SeqGroup=sg; ueConfig.CyclicShift=cs; - puschConfig.PRBSet=(0:(prb-1))'; + puschConfig.PRBSet=(19:22)'; puschConfig.DynCyclicShift=ds; [mat, info]=ltePUSCHDRS(ueConfig,puschConfig); diff --git a/matlab/tests/pusch_decode_test.m b/matlab/tests/pusch_decode_test.m new file mode 100644 index 000000000..8d3b11490 --- /dev/null +++ b/matlab/tests/pusch_decode_test.m @@ -0,0 +1,11 @@ +ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',122,'CyclicPrefixUL','Normal','NTxAnts',1); +puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',(19:22)','Modulation','QPSK','RV',0,'Shortened',0); + +subframe_rx=lteSCFDMADemodulate(ueConfig,x.*transpose(exp(-1i*2*pi*0.04*(1:length(x))/512))); +idx=ltePUSCHIndices(ueConfig,puschConfig); +pusch_rx=subframe_rx(idx); +[hest, noiseest] = lteULChannelEstimate(ueConfig,puschConfig,subframe_rx); +ce=hest(idx); +[cws,symbols] = ltePUSCHDecode(ueConfig,puschConfig,pusch_rx,ce,noiseest); +[trblkout,blkcrc,stateout] = lteULSCHDecode(ueConfig,puschConfig,88,cws); +disp(blkcrc) \ No newline at end of file diff --git a/matlab/tests/pusch_test.m b/matlab/tests/pusch_test.m index 797da49d4..28ce07255 100644 --- a/matlab/tests/pusch_test.m +++ b/matlab/tests/pusch_test.m @@ -1,6 +1,6 @@ clear -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); +ueConfig=struct('NCellID',0,'NULRB',6,'NSubframe',5,'RNTI',79,'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') @@ -10,7 +10,7 @@ addpath('../../debug/lte/phy/lib/phch/test') % rvs=0; % betas=0:3:11; -TBs=56; +TBs=88; cqilen=0; mods={'QPSK'}; rvs=0; diff --git a/matlab/tests/test_scfdma_peakamp.m b/matlab/tests/test_scfdma_peakamp.m new file mode 100644 index 000000000..211d0e45b --- /dev/null +++ b/matlab/tests/test_scfdma_peakamp.m @@ -0,0 +1,32 @@ +clear +ueConfig=struct('NCellID',0,'NULRB',25,'NSubframe',4,'RNTI',82,'CyclicPrefixUL','Normal','NTxAnts',1); +puschConfig=struct('NLayers',1,'OrthCover','Off','PRBSet',0,'Modulation','QPSK','RV',0,'Shortened',0); + +addpath('../../debug/lte/phy/lib/phch/test') + +NULRB=[6 15 25 50 100]; + +Peak=[]; +k=1; +for r=1:length(NULRB) + fprintf('NULRB: %d\n',NULRB(r)); + for l=1:NULRB(r) + trblkin=randi(2,l*5,1)-1; + + ueConfig.NULRB=NULRB(r); + puschConfig.PRBSet=(0:(l-1))'; + + [cw, info]=lteULSCH(ueConfig,puschConfig,trblkin); + 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 = waveform*sqrt(512)/sqrt(l)*NULRB(r)/10; + Peak(k)=max(max(abs(real(waveform))),max(abs(imag(waveform)))); + k=k+1; + end +end + +plot(Peak(:)') +