From 9761d1a3a1191cae44f6a2f9d28eb4bdda483813 Mon Sep 17 00:00:00 2001 From: ismagom Date: Mon, 15 Jun 2015 01:56:33 +0200 Subject: [PATCH] Matlab tests working for SRS. --- matlab/tests/pucch_test.m | 2 +- matlab/tests/srs_test.m | 44 +++++ srsapps/ue/mac/test/mac_test.cc | 5 +- .../phy/include/srsapps/ue/phy/phy_params.h | 5 +- .../ue/phy/include/srsapps/ue/phy/ul_buffer.h | 1 + srsapps/ue/phy/src/phy.cc | 11 +- srsapps/ue/phy/src/ul_buffer.cc | 61 +++++-- srsapps/ue/phy/test/ue_itf_test_prach.cc | 4 +- srslte/examples/prach_ue.c | 6 +- .../srslte/ch_estimation/refsignal_ul.h | 21 +-- srslte/include/srslte/phch/pucch.h | 5 +- srslte/include/srslte/phch/pusch_cfg.h | 1 + srslte/include/srslte/ue/ue_ul.h | 15 +- srslte/lib/ch_estimation/src/refsignal_ul.c | 171 ++++++++++-------- srslte/lib/ch_estimation/test/CMakeLists.txt | 2 +- .../ch_estimation/test/refsignal_pusch_mex.c | 10 +- .../ch_estimation/test/refsignal_srs_mex.c | 164 +++++++++++++++++ .../ch_estimation/test/refsignal_ul_test.c | 19 +- srslte/lib/phch/src/pucch.c | 6 +- srslte/lib/phch/src/pusch.c | 1 + srslte/lib/phch/test/pucch_encode_test_mex.c | 13 +- srslte/lib/phch/test/pucch_test.c | 6 +- srslte/lib/ue/src/ue_ul.c | 79 +++++++- 23 files changed, 491 insertions(+), 161 deletions(-) create mode 100644 matlab/tests/srs_test.m create mode 100644 srslte/lib/ch_estimation/test/refsignal_srs_mex.c diff --git a/matlab/tests/pucch_test.m b/matlab/tests/pucch_test.m index 6af61f088..baa3092d3 100644 --- a/matlab/tests/pucch_test.m +++ b/matlab/tests/pucch_test.m @@ -1,5 +1,5 @@ clear -ueConfig=struct('NCellID',25,'RNTI',11,'NULRB',6,'NSubframe',1,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Off'); +ueConfig=struct('NCellID',1,'RNTI',11,'NULRB',6,'NSubframe',1,'CyclicPrefixUL','Normal','NTxAnts',1,'Hopping','Group'); pucchConfig=struct('NLayers',1,'OrthCover','Off','Shortened',1,'ResourceSize',0); addpath('../../build/srslte/lib/phch/test') diff --git a/matlab/tests/srs_test.m b/matlab/tests/srs_test.m new file mode 100644 index 000000000..3c03f0b9e --- /dev/null +++ b/matlab/tests/srs_test.m @@ -0,0 +1,44 @@ +clear +ueConfig=struct('NCellID',1,'NULRB',25,'DuplexMode','FDD','NSubframe',0,'NFrame',0,'CyclicPrefixUL','Normal','NTxAnts',1); +srsConfig=struct('NTxAnts',1,'ConfigIdx',0,'SeqGroup',1,'SeqIdx',0,'TxComb',0); + +addpath('../../build/srslte/lib/ch_estimation/test') + +for csbw=2:7 + for uebw=0:3 + for hop=0:3 + for ncs=0:7 + for n_rrc=1:23 + srsConfig.BWConfig = csbw; + srsConfig.BW = uebw; + srsConfig.CyclicShift = ncs; + srsConfig.HoppingBW = hop; + srsConfig.FreqPosition = n_rrc; + fprintf('Testing SRS: CSBW=%d, UEBW=%d, b_hop=%d n_rrc=%d, CyclicShift=%d\n',csbw, uebw, hop, n_rrc, ncs); + + [sym_mat, info]=lteSRS(ueConfig,srsConfig); + [idx, info2]=lteSRSIndices(ueConfig,srsConfig); + subframe_mat = lteULResourceGrid(ueConfig); + subframe_mat(idx)=sym_mat; + + [sym, subframe]=srslte_refsignal_srs(ueConfig,srsConfig); + + error_sym=max(abs(sym-sym_mat)); + error_sf=max(abs(subframe_mat(:)-subframe)); + + if (error_sym > 1e-3) + disp(info) + plot(1:length(sym),sym,1:length(sym_mat),sym_mat) + legend('srsLTE','Matlab') + error('Error in symbols'); + end + if (error_sf > 1e-3) + disp(info2) + plot(abs(subframe-subframe_mat(:))) + error('Error in subframe'); + end + end + end + end + end +end diff --git a/srsapps/ue/mac/test/mac_test.cc b/srsapps/ue/mac/test/mac_test.cc index 26e142219..b78d20431 100644 --- a/srsapps/ue/mac/test/mac_test.cc +++ b/srsapps/ue/mac/test/mac_test.cc @@ -160,9 +160,9 @@ void setup_mac_phy_sib2(LIBLTE_RRC_SYS_INFO_BLOCK_TYPE_2_STRUCT *sib2, srslte::u sib2->rr_config_common_sib.pusch_cnfg.n_sb); phy->set_param(srslte::ue::phy_params::PUSCH_HOPPING_INTRA_SF, sib2->rr_config_common_sib.pusch_cnfg.hopping_mode == LIBLTE_RRC_HOPPING_MODE_INTRA_AND_INTER_SUBFRAME?1:0); - phy->set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_HOPPING_EN, + phy->set_param(srslte::ue::phy_params::DMRS_GROUP_HOPPING_EN, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.group_hopping_enabled?1:0); - phy->set_param(srslte::ue::phy_params::PUSCH_RS_SEQUENCE_HOPPING_EN, + phy->set_param(srslte::ue::phy_params::DMRS_SEQUENCE_HOPPING_EN, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.sequence_hopping_enabled?1:0); phy->set_param(srslte::ue::phy_params::PUSCH_RS_CYCLIC_SHIFT, sib2->rr_config_common_sib.pusch_cnfg.ul_rs.cyclic_shift); @@ -244,6 +244,7 @@ void process_connsetup(LIBLTE_RRC_CONNECTION_SETUP_STRUCT *msg, srslte::ue::mac phy->set_param(srslte::ue::phy_params::SRS_UE_BW, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_bandwidth); phy->set_param(srslte::ue::phy_params::SRS_UE_CONFIGINDEX, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_cnfg_idx); phy->set_param(srslte::ue::phy_params::SRS_UE_HOP, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.srs_hopping_bandwidth); + phy->set_param(srslte::ue::phy_params::SRS_UE_CYCLICSHIFT, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.cyclic_shift); phy->set_param(srslte::ue::phy_params::SRS_UE_TXCOMB, msg->rr_cnfg.phy_cnfg_ded.srs_ul_cnfg_ded.tx_comb); phy->set_param(srslte::ue::phy_params::SRS_BETA, 10); } diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/phy_params.h b/srsapps/ue/phy/include/srsapps/ue/phy/phy_params.h index 104800ce2..0a77a10db 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/phy_params.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/phy_params.h @@ -56,10 +56,10 @@ namespace ue { PUSCH_BETA, PUSCH_EN_64QAM, - PUSCH_RS_GROUP_HOPPING_EN, - PUSCH_RS_SEQUENCE_HOPPING_EN, PUSCH_RS_CYCLIC_SHIFT, PUSCH_RS_GROUP_ASSIGNMENT, + DMRS_GROUP_HOPPING_EN, + DMRS_SEQUENCE_HOPPING_EN, PUSCH_HOPPING_N_SB, PUSCH_HOPPING_INTRA_SF, @@ -87,6 +87,7 @@ namespace ue { SRS_UE_BW, SRS_UE_HOP, SRS_UE_CS, + SRS_UE_CYCLICSHIFT, SRS_IS_UE_CONFIGURED, SRS_CS_BWCFG, SRS_CS_SFCFG, diff --git a/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h b/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h index 16b178350..31ddb2f7e 100644 --- a/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h +++ b/srsapps/ue/phy/include/srsapps/ue/phy/ul_buffer.h @@ -56,6 +56,7 @@ namespace ue { bool generate_sr(); bool generate_cqi_report(); bool uci_ready(); + bool srs_is_ready_to_send(); bool generate_data(); bool generate_data(ul_sched_grant *pusch_grant, uint8_t *payload); bool generate_data(ul_sched_grant *pusch_grant, srslte_softbuffer_tx_t *softbuffer, uint8_t *payload); diff --git a/srsapps/ue/phy/src/phy.cc b/srsapps/ue/phy/src/phy.cc index fec5b8b2b..e32a7bf76 100644 --- a/srsapps/ue/phy/src/phy.cc +++ b/srsapps/ue/phy/src/phy.cc @@ -528,7 +528,7 @@ void phy::run_rx_tx_state() if (sr_is_ready_to_send(current_tti+ul_buffer::tx_advance_sf)) { get_ul_buffer_adv(current_tti)->generate_sr(); } - + // Every subframe, TX a PRACH or a PUSCH/PUCCH if (prach_buffer.is_ready_to_send(current_tti)) { // send prach if we have to @@ -539,11 +539,14 @@ void phy::run_rx_tx_state() Info("Restoring AGC. Set TX gain to %.1f dB\n", old_gain); // If we don't transmit PRACH, check if need to transmit PUSCH/PUCCH - } else if (get_ul_buffer_adv(current_tti)->is_released() || get_ul_buffer_adv(current_tti)->uci_ready()) { - // If the packet was not generated by a call from MAC, means it's PUCCH. Generate now the signal + } else if (get_ul_buffer_adv(current_tti)->is_released() || + get_ul_buffer_adv(current_tti)->uci_ready() || + get_ul_buffer_adv(current_tti)->srs_is_ready_to_send()) + { + // If the packet was not generated by a call from MAC, means it's PUCCH or SRS. Generate now the signal if (!get_ul_buffer_adv(current_tti)->is_released()) { get_ul_buffer_adv(current_tti)->generate_data(); - } + } // And transmit get_ul_buffer_adv(current_tti)->send(radio_handler, time_adv_sec, cfo, last_rx_time); is_first_of_burst = false; diff --git a/srsapps/ue/phy/src/ul_buffer.cc b/srsapps/ue/phy/src/ul_buffer.cc index 8b6093322..082e70a00 100644 --- a/srsapps/ue/phy/src/ul_buffer.cc +++ b/srsapps/ue/phy/src/ul_buffer.cc @@ -121,6 +121,20 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, //int nof_tx=0; +bool ul_buffer::srs_is_ready_to_send() { + + if (params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED) && + params_db->get_param(phy_params::SRS_IS_UE_CONFIGURED)) + { + if (srslte_refsignal_srs_send_cs(params_db->get_param(phy_params::SRS_CS_SFCFG), tti%10) == 1 && + srslte_refsignal_srs_send_ue(params_db->get_param(phy_params::SRS_UE_CONFIGINDEX), tti) == 1) + { + Info("SRS ready to send at TTI=%d\n", tti); + return true; + } + } + return false; +} bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *softbuffer, uint8_t *payload) { if (is_ready()) { @@ -129,11 +143,11 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof srslte_refsignal_dmrs_pusch_cfg_t dmrs_cfg; bzero(&dmrs_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); - dmrs_cfg.beta_pusch = (float) params_db->get_param(phy_params::PUSCH_BETA)/10; - dmrs_cfg.group_hopping_en = params_db->get_param(phy_params::PUSCH_RS_GROUP_HOPPING_EN); - dmrs_cfg.sequence_hopping_en = params_db->get_param(phy_params::PUSCH_RS_SEQUENCE_HOPPING_EN); - dmrs_cfg.cyclic_shift = params_db->get_param(phy_params::PUSCH_RS_CYCLIC_SHIFT); - dmrs_cfg.delta_ss = params_db->get_param(phy_params::PUSCH_RS_GROUP_ASSIGNMENT); + dmrs_cfg.beta_pusch = (float) params_db->get_param(phy_params::PUSCH_BETA)/10; + bool group_hopping_en = params_db->get_param(phy_params::DMRS_GROUP_HOPPING_EN); + bool sequence_hopping_en = params_db->get_param(phy_params::DMRS_SEQUENCE_HOPPING_EN); + dmrs_cfg.cyclic_shift = params_db->get_param(phy_params::PUSCH_RS_CYCLIC_SHIFT); + dmrs_cfg.delta_ss = params_db->get_param(phy_params::PUSCH_RS_GROUP_ASSIGNMENT); // Get cyclic shift for DMRS if PUSCH is not for RAR or (TODO) is not SPS if (grant) { @@ -158,7 +172,6 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof bzero(&pucch_cfg, sizeof(srslte_pucch_cfg_t)); pucch_cfg.beta_pucch = (float) params_db->get_param(phy_params::PUCCH_BETA)/10; pucch_cfg.delta_pucch_shift = params_db->get_param(phy_params::PUCCH_DELTA_SHIFT); - pucch_cfg.group_hopping_en = dmrs_cfg.group_hopping_en; pucch_cfg.N_cs = params_db->get_param(phy_params::PUCCH_CYCLIC_SHIFT); pucch_cfg.n_rb_2 = params_db->get_param(phy_params::PUCCH_N_RB_2); pucch_cfg.srs_cs_configured = params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED)?true:false; @@ -175,8 +188,22 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof pucch_sched.N_pucch_1 = params_db->get_param(phy_params::PUCCH_N_PUCCH_1); pucch_sched.n_pucch_2 = params_db->get_param(phy_params::PUCCH_N_PUCCH_2); pucch_sched.n_pucch_sr = params_db->get_param(phy_params::PUCCH_N_PUCCH_SR); + + srslte_refsignal_srs_cfg_t srs_cfg; + bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); + srs_cfg.cs_configured = params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED)?true:false; + srs_cfg.ue_configured = params_db->get_param(phy_params::SRS_IS_UE_CONFIGURED)?true:false; + srs_cfg.subframe_config = (uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG); + srs_cfg.bw_cfg = (uint32_t) params_db->get_param(phy_params::SRS_CS_BWCFG); + srs_cfg.I_srs = (uint32_t) params_db->get_param(phy_params::SRS_UE_CONFIGINDEX); + srs_cfg.B = (uint32_t) params_db->get_param(phy_params::SRS_UE_BW); + srs_cfg.b_hop = (uint32_t) params_db->get_param(phy_params::SRS_UE_HOP); + srs_cfg.n_rrc = (uint32_t) params_db->get_param(phy_params::SRS_UE_NRRC); + srs_cfg.k_tc = (uint32_t) params_db->get_param(phy_params::SRS_UE_TXCOMB); + srs_cfg.n_srs = (uint32_t) params_db->get_param(phy_params::SRS_UE_CYCLICSHIFT); - srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, &pucch_cfg, &pucch_sched); + srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, &pucch_cfg, &srs_cfg, &pucch_sched, + group_hopping_en, sequence_hopping_en); uci_data.I_offset_ack = params_db->get_param(phy_params::UCI_I_OFFSET_ACK); uci_data.I_offset_cqi = params_db->get_param(phy_params::UCI_I_OFFSET_CQI); @@ -186,9 +213,7 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof // Transmit on PUSCH if UL grant available, otherwise in PUCCH if (grant) { srslte_pusch_hopping_cfg_t pusch_hopping_cfg; - srslte_refsignal_srs_cfg_t srs_cfg; bzero(&pusch_hopping_cfg, sizeof(srslte_pusch_hopping_cfg_t)); - bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); pusch_hopping_cfg.n_sb = params_db->get_param(phy_params::PUSCH_HOPPING_N_SB); pusch_hopping_cfg.hop_mode = params_db->get_param(phy_params::PUSCH_HOPPING_INTRA_SF) ? @@ -197,12 +222,6 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof pusch_hopping_cfg.hopping_offset = params_db->get_param(phy_params::PUSCH_HOPPING_OFFSET); pusch_hopping_cfg.current_tx_nb = grant->get_current_tx_nb(); - srs_cfg.cs_configured = params_db->get_param(phy_params::SRS_IS_CS_CONFIGURED)?true:false; - srs_cfg.ue_configured = params_db->get_param(phy_params::SRS_IS_UE_CONFIGURED)?true:false; - srs_cfg.subframe_config = (uint32_t) params_db->get_param(phy_params::SRS_CS_SFCFG); - srs_cfg.bw_cfg = (uint32_t) params_db->get_param(phy_params::SRS_CS_BWCFG); - srs_cfg.I_srs = (uint32_t) params_db->get_param(phy_params::SRS_UE_CONFIGINDEX); - grant->to_pusch_cfg(&pusch_hopping_cfg, &srs_cfg, tti, &ue_ul); n = srslte_ue_ul_pusch_encode_rnti_softbuffer(&ue_ul, @@ -219,11 +238,15 @@ bool ul_buffer::generate_data(ul_sched_grant *grant, srslte_softbuffer_tx_t *sof } else { - - n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti%10, signal_buffer); + if (uci_data.scheduling_request || uci_data.uci_cqi_len > 0 || uci_data.uci_ack_len) { + n = srslte_ue_ul_pucch_encode(&ue_ul, uci_data, tti%10, signal_buffer); - Info("PUCCH: TTI=%d n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, last_n_cce, - uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no", ue_ul.pucch.shortened?"yes":"no"); + Info("PUCCH: TTI=%d n_cce=%d, ack=%s, sr=%s, shortened=%s\n", tti, last_n_cce, + uci_data.uci_ack_len>0?(uci_data.uci_ack?"1":"0"):"no",uci_data.scheduling_request?"yes":"no", + ue_ul.pucch.shortened?"yes":"no"); + } else { + n = srslte_ue_ul_srs_encode(&ue_ul, tti, signal_buffer); + } } // Reset UCI data diff --git a/srsapps/ue/phy/test/ue_itf_test_prach.cc b/srsapps/ue/phy/test/ue_itf_test_prach.cc index 88f6a0526..c9dc0e0e2 100644 --- a/srsapps/ue/phy/test/ue_itf_test_prach.cc +++ b/srsapps/ue/phy/test/ue_itf_test_prach.cc @@ -212,8 +212,8 @@ void config_phy() { phy.set_param(srslte::ue::phy_params::PRACH_ZC_CONFIG, 1); phy.set_param(srslte::ue::phy_params::PUSCH_BETA, 10); - phy.set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_HOPPING_EN, 0); - phy.set_param(srslte::ue::phy_params::PUSCH_RS_SEQUENCE_HOPPING_EN, 0); + phy.set_param(srslte::ue::phy_params::DMRS_GROUP_HOPPING_EN, 0); + phy.set_param(srslte::ue::phy_params::DMRS_SEQUENCE_HOPPING_EN, 0); phy.set_param(srslte::ue::phy_params::PUSCH_RS_CYCLIC_SHIFT, 0); phy.set_param(srslte::ue::phy_params::PUSCH_RS_GROUP_ASSIGNMENT, 0); phy.set_param(srslte::ue::phy_params::PUSCH_HOPPING_OFFSET, 0); diff --git a/srslte/examples/prach_ue.c b/srslte/examples/prach_ue.c index c6eff8065..6f29b6544 100644 --- a/srslte/examples/prach_ue.c +++ b/srslte/examples/prach_ue.c @@ -386,13 +386,13 @@ cell.nof_ports = 1; 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; + bool group_hopping_en = false; + bool 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_cfg(&ue_ul, &dmrs_cfg, NULL, NULL); + srslte_ue_ul_set_cfg(&ue_ul, &dmrs_cfg, NULL, NULL, NULL, group_hopping_en, sequence_hopping_en); cf_t *ul_signal = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_PRB(cell.nof_prb)); if (!ul_signal) { diff --git a/srslte/include/srslte/ch_estimation/refsignal_ul.h b/srslte/include/srslte/ch_estimation/refsignal_ul.h index 0dd66aa17..5ace6a8d8 100644 --- a/srslte/include/srslte/ch_estimation/refsignal_ul.h +++ b/srslte/include/srslte/ch_estimation/refsignal_ul.h @@ -51,8 +51,6 @@ typedef struct SRSLTE_API { uint32_t delta_ss; bool en_dmrs_2; float beta_pusch; - bool group_hopping_en; - bool sequence_hopping_en; }srslte_refsignal_dmrs_pusch_cfg_t; typedef struct SRSLTE_API { @@ -72,6 +70,8 @@ typedef struct SRSLTE_API { /** Uplink DeModulation Reference Signal (DMRS) */ typedef struct SRSLTE_API { srslte_cell_t cell; + bool group_hopping_en; + bool sequence_hopping_en; srslte_refsignal_dmrs_pusch_cfg_t pusch_cfg; srslte_pucch_cfg_t pucch_cfg; srslte_refsignal_srs_cfg_t srs_cfg; @@ -90,14 +90,12 @@ 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 void srslte_refsignal_ul_set_pusch_cfg(srslte_refsignal_ul_t *q, - srslte_refsignal_dmrs_pusch_cfg_t *cfg); - -SRSLTE_API bool srslte_refsignal_ul_set_pucch_cfg(srslte_refsignal_ul_t *q, - srslte_pucch_cfg_t *cfg); - -SRSLTE_API bool srslte_refsignal_ul_set_srs_cfg(srslte_refsignal_ul_t *q, - srslte_refsignal_srs_cfg_t *cfg); +SRSLTE_API void srslte_refsignal_ul_set_cfg(srslte_refsignal_ul_t *q, + srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, + srslte_pucch_cfg_t *pucch_cfg, + srslte_refsignal_srs_cfg_t *srs_cfg, + bool group_hopping_en, + bool sequence_hopping_en); SRSLTE_API void srslte_refsignal_r_uv_arg_1prb(float *arg, uint32_t u); @@ -135,7 +133,7 @@ SRSLTE_API int srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q, cf_t *r_srs); SRSLTE_API int srslte_refsignal_srs_put(srslte_refsignal_ul_t *q, - uint32_t sf_idx, + uint32_t tti, cf_t *r_srs, cf_t *sf_symbols); @@ -151,5 +149,6 @@ SRSLTE_API uint32_t srslte_refsignal_srs_rb_start_cs(uint32_t bw_cfg, SRSLTE_API uint32_t srslte_refsignal_srs_rb_L_cs(uint32_t bw_cfg, uint32_t nof_prb); +SRSLTE_API uint32_t srslte_refsignal_M_sc(srslte_refsignal_ul_t *q); #endif diff --git a/srslte/include/srslte/phch/pucch.h b/srslte/include/srslte/phch/pucch.h index de44285e1..27dad1e95 100644 --- a/srslte/include/srslte/phch/pucch.h +++ b/srslte/include/srslte/phch/pucch.h @@ -69,7 +69,6 @@ typedef struct SRSLTE_API { uint32_t delta_pucch_shift; uint32_t n_rb_2; uint32_t N_cs; - bool group_hopping_en; bool srs_cs_configured; uint32_t srs_cs_subf_cfg; bool srs_simul_ack; @@ -90,6 +89,7 @@ typedef struct SRSLTE_API { cf_t z[SRSLTE_PUCCH_MAX_SYMBOLS]; bool rnti_is_set; bool shortened; + bool group_hopping_en; }srslte_pucch_t; @@ -99,7 +99,8 @@ SRSLTE_API int srslte_pucch_init(srslte_pucch_t *q, SRSLTE_API void srslte_pucch_free(srslte_pucch_t *q); SRSLTE_API bool srslte_pucch_set_cfg(srslte_pucch_t* q, - srslte_pucch_cfg_t* cfg); + srslte_pucch_cfg_t* cfg, + bool group_hopping_en); SRSLTE_API int srslte_pucch_set_crnti(srslte_pucch_t *q, uint16_t c_rnti); diff --git a/srslte/include/srslte/phch/pusch_cfg.h b/srslte/include/srslte/phch/pusch_cfg.h index 6f53ea09e..ae133a97d 100644 --- a/srslte/include/srslte/phch/pusch_cfg.h +++ b/srslte/include/srslte/phch/pusch_cfg.h @@ -46,6 +46,7 @@ typedef struct SRSLTE_API { srslte_ra_nbits_t nbits; uint32_t rv; uint32_t sf_idx; + uint32_t tti; srslte_cp_t cp; } srslte_pusch_cfg_t; diff --git a/srslte/include/srslte/ue/ue_ul.h b/srslte/include/srslte/ue/ue_ul.h index e8b34c0fe..2c2f73b83 100644 --- a/srslte/include/srslte/ue/ue_ul.h +++ b/srslte/include/srslte/ue/ue_ul.h @@ -78,6 +78,7 @@ typedef struct SRSLTE_API { cf_t *refsignal; + cf_t *srs_signal; cf_t *sf_symbols; uint16_t current_rnti; @@ -101,7 +102,10 @@ SRSLTE_API void srslte_ue_ul_set_normalization(srslte_ue_ul_t *q, SRSLTE_API void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg, srslte_pucch_cfg_t *pucch_cfg, - srslte_pucch_sched_t *pucch_sched); + srslte_refsignal_srs_cfg_t *srs_cfg, + srslte_pucch_sched_t *pucch_sched, + bool group_hopping_en, + bool sequence_hopping_en); SRSLTE_API int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_dci_msg_t *dci_msg, @@ -112,7 +116,7 @@ SRSLTE_API int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, SRSLTE_API int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, - uint32_t sf_idx, + uint32_t tti, cf_t *output_signal); SRSLTE_API int srslte_ue_ul_pusch_encode(srslte_ue_ul_t *q, @@ -142,6 +146,10 @@ SRSLTE_API int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, uint16_t rnti, cf_t *output_signal); +SRSLTE_API int srslte_ue_ul_srs_encode(srslte_ue_ul_t *q, + uint32_t tti, + cf_t *output_signal); + SRSLTE_API void srslte_ue_ul_reset(srslte_ue_ul_t *q); SRSLTE_API void srslte_ue_ul_set_rnti(srslte_ue_ul_t *q, @@ -152,4 +160,7 @@ SRSLTE_API void srslte_ue_ul_set_rnti(srslte_ue_ul_t *q, SRSLTE_API int srslte_ue_ul_sr_send_tti(uint32_t I_sr, uint32_t current_tti); +SRSLTE_API bool srslte_ue_ul_srs_tx_enabled(srslte_refsignal_srs_cfg_t *srs_cfg, + uint32_t tti); + #endif diff --git a/srslte/lib/ch_estimation/src/refsignal_ul.c b/srslte/lib/ch_estimation/src/refsignal_ul.c index c36aa60e8..de3861ed0 100644 --- a/srslte/lib/ch_estimation/src/refsignal_ul.c +++ b/srslte/lib/ch_estimation/src/refsignal_ul.c @@ -68,6 +68,56 @@ uint32_t T_sfc[15] = {1, 2, 2, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10}; uint32_t Delta_sfc1[7] = {0, 0, 1, 0, 1, 2, 3}; uint32_t Delta_sfc2[4] = {0, 1, 2, 3}; + +uint32_t m_srs_b[4][4][8] = {{ + /* m_srs for 6pusch_cfg, cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); + q->group_hopping_en = group_hopping_en; + q->sequence_hopping_en = sequence_hopping_en; + if (pusch_cfg) { + memcpy(&q->pusch_cfg, pusch_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); } -} - -bool srslte_refsignal_ul_set_pucch_cfg(srslte_refsignal_ul_t *q, srslte_pucch_cfg_t *cfg) -{ - if (srslte_pucch_cfg_isvalid(cfg, q->cell.nof_prb)) { - memcpy(&q->pucch_cfg, cfg, sizeof(srslte_pucch_cfg_t)); - return true; - } else { - return false; + if (pucch_cfg) { + if (srslte_pucch_cfg_isvalid(pucch_cfg, q->cell.nof_prb)) { + memcpy(&q->pucch_cfg, pucch_cfg, sizeof(srslte_pucch_cfg_t)); + } + } + if (srs_cfg) { + memcpy(&q->srs_cfg, srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); } } @@ -227,7 +281,7 @@ static void arg_r_uv_mprb(float *arg, uint32_t M_sc, uint32_t u, uint32_t v) { uint32_t N_sz = largest_prime_lower_than(M_sc); float q = get_q(u,v,N_sz); float n_sz = (float) N_sz; - + for (uint32_t i = 0; i < M_sc; i++) { float m = (float) (i%N_sz); arg[i] = -M_PI * q * m * (m + 1) / n_sz; @@ -279,17 +333,17 @@ void srslte_refsignal_dmrs_pusch_put(srslte_refsignal_ul_t *q, cf_t *r_pusch, ui } /* Computes r sequence */ -void compute_r(srslte_refsignal_ul_t *q, uint32_t nof_prb, uint32_t ns) { +void compute_r(srslte_refsignal_ul_t *q, uint32_t nof_prb, uint32_t ns, uint32_t delta_ss) { // Get group hopping number u uint32_t f_gh=0; - if (q->pusch_cfg.group_hopping_en) { + if (q->group_hopping_en) { f_gh = q->f_gh[ns]; } - uint32_t u = (f_gh + (q->cell.id%30)+q->pusch_cfg.delta_ss)%30; + uint32_t u = (f_gh + (q->cell.id%30)+delta_ss)%30; // Get sequence hopping number v uint32_t v = 0; - if (nof_prb >= 6 && q->pusch_cfg.sequence_hopping_en) { + if (nof_prb >= 6 && q->sequence_hopping_en) { v = q->v_pusch[ns][q->pusch_cfg.delta_ss]; } @@ -308,7 +362,7 @@ int srslte_refsignal_dmrs_pusch_gen(srslte_refsignal_ul_t *q, uint32_t nof_prb, for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) { - compute_r(q, nof_prb, ns); + compute_r(q, nof_prb, ns, q->pusch_cfg.delta_ss); // Add cyclic prefix alpha float alpha = pusch_alpha(q, &q->pusch_cfg, ns); @@ -399,7 +453,7 @@ int srslte_refsignal_dmrs_pucch_gen(srslte_refsignal_ul_t *q, srslte_pucch_forma for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) { // Get group hopping number u uint32_t f_gh=0; - if (q->pucch_cfg.group_hopping_en) { + if (q->group_hopping_en) { f_gh = q->f_gh[ns]; } uint32_t u = (f_gh + (q->cell.id%30))%30; @@ -606,54 +660,6 @@ int srslte_refsignal_srs_send_cs(uint32_t subframe_config, uint32_t sf_idx) { } } -uint32_t m_srs_b[4][4][8] = {{ - /* m_srs for 6bw_cfg < 8 && cfg->B < 4 && cfg->k_tc < 2) { - uint32_t m_srs = m_srs_b[srsbwtable_idx(nof_prb)][cfg->B][cfg->bw_cfg]; - uint32_t nb = (4*cfg->n_rrc/m_srs)%Nb[srsbwtable_idx(nof_prb)][cfg->B][cfg->bw_cfg]; - if (cfg->b_hop < cfg->B) { - nb += srs_Fb(cfg, nof_prb, tti); - } uint32_t k0p = srslte_refsignal_srs_rb_start_cs(cfg->bw_cfg, nof_prb)*SRSLTE_NRE + cfg->k_tc; - uint32_t m_sc = m_srs*SRSLTE_NRE/2; uint32_t k0 = k0p; - for (int b=0;bB;b++) { + uint32_t nb = 0; + for (int b=0;b<=cfg->B;b++) { + uint32_t m_srs = m_srs_b[srsbwtable_idx(nof_prb)][b][cfg->bw_cfg]; + uint32_t m_sc = m_srs*SRSLTE_NRE/2; + if (b <= cfg->b_hop) { + nb = (4*cfg->n_rrc/m_srs)%Nb[srsbwtable_idx(nof_prb)][b][cfg->bw_cfg]; + } else { + nb = ((4*cfg->n_rrc/m_srs)+srs_Fb(cfg, nof_prb, tti))%Nb[srsbwtable_idx(nof_prb)][b][cfg->bw_cfg]; + } + printf("nb[%d]=%d\n",b,nb); k0 += 2*m_sc*nb; } return k0; @@ -717,6 +726,10 @@ uint32_t srs_k0_ue(srslte_refsignal_srs_cfg_t *cfg, uint32_t nof_prb, uint32_t t return 0; } +uint32_t srslte_refsignal_M_sc(srslte_refsignal_ul_t *q) { + return m_srs_b[srsbwtable_idx(q->cell.nof_prb)][q->srs_cfg.B][q->srs_cfg.bw_cfg]*SRSLTE_NRE/2; +} + /* Genearte SRS signal as defined in Section 5.5.3.1 */ int srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q, uint32_t sf_idx, cf_t *r_srs) { @@ -724,11 +737,12 @@ int srslte_refsignal_srs_gen(srslte_refsignal_ul_t *q, uint32_t sf_idx, cf_t *r_ if (r_srs && q) { ret = SRSLTE_ERROR; - uint32_t M_sc = srslte_refsignal_srs_rb_L_cs(q->srs_cfg.bw_cfg, q->cell.nof_prb)*SRSLTE_NRE/2; + uint32_t M_sc = srslte_refsignal_M_sc(q); for (uint32_t ns=2*sf_idx;ns<2*(sf_idx+1);ns++) { - compute_r(q, M_sc/SRSLTE_NRE, ns); + compute_r(q, M_sc/SRSLTE_NRE, ns, 0); float alpha = 2*M_PI*q->srs_cfg.n_srs/8; + // Do complex exponential and adjust amplitude for (int i=0;isrs_cfg.beta_srs * cexpf(I*(q->tmp_arg[i] + alpha*i)); @@ -747,8 +761,9 @@ int srslte_refsignal_srs_put(srslte_refsignal_ul_t *q, uint32_t tti, cf_t *r_srs if (srslte_refsignal_srs_send_ue(q->srs_cfg.I_srs, tti) == 1 && srslte_refsignal_srs_send_cs(q->srs_cfg.subframe_config, tti) == 1) { - uint32_t M_sc = srslte_refsignal_srs_rb_L_cs(q->srs_cfg.bw_cfg, q->cell.nof_prb)*SRSLTE_NRE/2; + uint32_t M_sc = srslte_refsignal_M_sc(q); uint32_t k0 = srs_k0_ue(&q->srs_cfg, q->cell.nof_prb, tti); + printf("k0=%d, n_rrc=%d\n", k0, q->srs_cfg.n_rrc); for (int i=0;icell.nof_prb, 2*SRSLTE_CP_NSYMB(q->cell.cp)-1, k0 + 2*i)] = r_srs[i]; } diff --git a/srslte/lib/ch_estimation/test/CMakeLists.txt b/srslte/lib/ch_estimation/test/CMakeLists.txt index f8238469b..24fc9f509 100644 --- a/srslte/lib/ch_estimation/test/CMakeLists.txt +++ b/srslte/lib/ch_estimation/test/CMakeLists.txt @@ -48,9 +48,9 @@ BuildMex(MEXNAME chest SOURCES chest_test_dl_mex.c LIBRARIES srslte) ADD_EXECUTABLE(refsignal_ul_test_all refsignal_ul_test.c) TARGET_LINK_LIBRARIES(refsignal_ul_test_all srslte) - BuildMex(MEXNAME refsignal_pusch SOURCES refsignal_pusch_mex.c LIBRARIES srslte srslte_mex) +BuildMex(MEXNAME refsignal_srs SOURCES refsignal_srs_mex.c LIBRARIES srslte srslte_mex) diff --git a/srslte/lib/ch_estimation/test/refsignal_pusch_mex.c b/srslte/lib/ch_estimation/test/refsignal_pusch_mex.c index 806ad0cba..9438b3cb1 100644 --- a/srslte/lib/ch_estimation/test/refsignal_pusch_mex.c +++ b/srslte/lib/ch_estimation/test/refsignal_pusch_mex.c @@ -76,14 +76,14 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) bzero(&pusch_cfg, sizeof(srslte_refsignal_dmrs_pusch_cfg_t)); - pusch_cfg.group_hopping_en = false; - pusch_cfg.sequence_hopping_en = false; + bool group_hopping_en = false; + bool sequence_hopping_en = false; char *tmp = mexutils_get_char_struct(UECFG, "Hopping"); if (tmp) { if (!strcmp(tmp, "Group")) { - pusch_cfg.group_hopping_en = true; + group_hopping_en = true; } else if (!strcmp(tmp, "Sequence")) { - pusch_cfg.sequence_hopping_en = true; + sequence_hopping_en = true; } mxFree(tmp); } @@ -135,7 +135,7 @@ 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)); - srslte_refsignal_ul_set_pusch_cfg(&refs, &pusch_cfg); + srslte_refsignal_ul_set_cfg(&refs, &pusch_cfg, NULL, NULL, group_hopping_en, sequence_hopping_en); //mexPrintf("Generating DRMS for ns=%d, nof_prb=%d\n", 2*sf_idx+i,pusch_cfg.nof_prb); srslte_refsignal_dmrs_pusch_gen(&refs, nof_prb, sf_idx, signal); diff --git a/srslte/lib/ch_estimation/test/refsignal_srs_mex.c b/srslte/lib/ch_estimation/test/refsignal_srs_mex.c new file mode 100644 index 000000000..d6d939175 --- /dev/null +++ b/srslte/lib/ch_estimation/test/refsignal_srs_mex.c @@ -0,0 +1,164 @@ +/** + * + * \section COPYRIGHT + * + * Copyright 2013-2015 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 Affero 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 Affero General Public License for more details. + * + * A copy of the GNU Affero 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 +#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 SRSCFG prhs[1] +#define NOF_INPUTS 2 + +void help() +{ + mexErrMsgTxt + ("[sym, subframe]=srslte_refsignal_srs(ue, chs)\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; + cell.cp = SRSLTE_CP_NORM; + 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; + } + + uint32_t sf_idx = 0; + if (mexutils_read_uint32_struct(UECFG, "NSubframe", &sf_idx)) { + mexErrMsgTxt("Field NSubframe not found in UE config\n"); + return; + } + uint32_t nf = 0; + if (mexutils_read_uint32_struct(UECFG, "NFrame", &nf)) { + mexErrMsgTxt("Field NFrame not found in UE config\n"); + return; + } + uint32_t tti = nf*10+sf_idx; + + srslte_refsignal_srs_cfg_t srs_cfg; + bzero(&srs_cfg, sizeof(srslte_refsignal_srs_cfg_t)); + srs_cfg.beta_srs = 1.0; + if (mexutils_read_uint32_struct(SRSCFG, "BWConfig", &srs_cfg.bw_cfg)) { + mexErrMsgTxt("Field BWConfig not found in SRSCFG\n"); + return; + } + if (mexutils_read_uint32_struct(SRSCFG, "BW", &srs_cfg.B)) { + mexErrMsgTxt("Field BW not found in SRSCFG\n"); + return; + } + if (mexutils_read_uint32_struct(SRSCFG, "ConfigIdx", &srs_cfg.I_srs)) { + mexErrMsgTxt("Field ConfigIdx not found in SRSCFG\n"); + return; + } + if (mexutils_read_uint32_struct(SRSCFG, "FreqPosition", &srs_cfg.n_rrc)) { + mexErrMsgTxt("Field FreqPosition not found in SRSCFG\n"); + return; + } + if (mexutils_read_uint32_struct(SRSCFG, "HoppingBW", &srs_cfg.b_hop)) { + mexErrMsgTxt("Field HoppingBW not found in SRSCFG\n"); + return; + } + if (mexutils_read_uint32_struct(SRSCFG, "TxComb", &srs_cfg.k_tc)) { + mexErrMsgTxt("Field TxComb not found in SRSCFG\n"); + return; + } + if (mexutils_read_uint32_struct(SRSCFG, "CyclicShift", &srs_cfg.n_srs)) { + mexErrMsgTxt("Field CyclicShift not found in SRSCFG\n"); + return; + } + bool group_hopping_en = false; + char *hop = mexutils_get_char_struct(UECFG, "Hopping"); + if (hop) { + if (!strcmp(hop, "Group")) { + group_hopping_en = true; + } + mxFree(hop); + } + + cf_t *r_srs = srslte_vec_malloc(sizeof(cf_t) * cell.nof_prb * 12); + if (!r_srs) { + return; + } + bzero(r_srs, cell.nof_prb * 12 * sizeof(cf_t)); + + cf_t *sf_symbols = srslte_vec_malloc(sizeof(cf_t) * SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp)); + if (!sf_symbols) { + return; + } + bzero(sf_symbols, SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp) * sizeof(cf_t)); + + srslte_refsignal_ul_t refsignal; + if (srslte_refsignal_ul_init(&refsignal, cell)) { + mexErrMsgTxt("Error initiating UL refsignal\n"); + return; + } + + srslte_refsignal_ul_set_cfg(&refsignal, NULL, NULL, &srs_cfg, group_hopping_en, false); + + if (srslte_refsignal_srs_gen(&refsignal, sf_idx, r_srs)) { + mexErrMsgTxt("Error generating SRS\n"); + return; + } + + if (srslte_refsignal_srs_put(&refsignal, tti, r_srs, sf_symbols)) { + mexErrMsgTxt("Error allocating SRS\n"); + return; + } + + if (nlhs >= 1) { + uint32_t M_sc = srslte_refsignal_M_sc(&refsignal); ; + mexutils_write_cf(r_srs, &plhs[0], M_sc, 1); + } + + if (nlhs >= 2) { + mexutils_write_cf(sf_symbols, &plhs[1], SRSLTE_SF_LEN_RE(cell.nof_prb, cell.cp), 1); + } + + srslte_refsignal_ul_free(&refsignal); + free(sf_symbols); + free(r_srs); + + return; +} + diff --git a/srslte/lib/ch_estimation/test/refsignal_ul_test.c b/srslte/lib/ch_estimation/test/refsignal_ul_test.c index a94dd258d..30dc82091 100644 --- a/srslte/lib/ch_estimation/test/refsignal_ul_test.c +++ b/srslte/lib/ch_estimation/test/refsignal_ul_test.c @@ -105,16 +105,19 @@ int main(int argc, char **argv) { uint32_t nof_prb = n; pusch_cfg.cyclic_shift = cshift; pusch_cfg.cyclic_shift_for_dmrs = cshift_dmrs; - pusch_cfg.delta_ss = delta_ss; + pusch_cfg.delta_ss = delta_ss; + bool group_hopping_en = false; + bool sequence_hopping_en = false; + if (!h) { - pusch_cfg.group_hopping_en = false; - pusch_cfg.sequence_hopping_en = false; + group_hopping_en = false; + sequence_hopping_en = false; } else if (h == 1) { - pusch_cfg.group_hopping_en = false; - pusch_cfg.sequence_hopping_en = true; + group_hopping_en = false; + sequence_hopping_en = true; } else if (h == 2) { - pusch_cfg.group_hopping_en = true; - pusch_cfg.sequence_hopping_en = false; + group_hopping_en = true; + sequence_hopping_en = false; } pusch_cfg.en_dmrs_2 = true; printf("Beta: %f, ",pusch_cfg.beta_pusch); @@ -123,7 +126,7 @@ int main(int argc, char **argv) { 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_ul_set_pusch_cfg(&refs, &pusch_cfg); + srslte_refsignal_ul_set_cfg(&refs, &pusch_cfg, NULL, NULL, group_hopping_en, sequence_hopping_en); srslte_refsignal_dmrs_pusch_gen(&refs, nof_prb, sf_idx, signal); exit(0); } diff --git a/srslte/lib/phch/src/pucch.c b/srslte/lib/phch/src/pucch.c index d54c48b63..1094f92d7 100644 --- a/srslte/lib/phch/src/pucch.c +++ b/srslte/lib/phch/src/pucch.c @@ -370,8 +370,9 @@ int srslte_pucch_set_crnti(srslte_pucch_t *q, uint16_t c_rnti) { return SRSLTE_SUCCESS; } -bool srslte_pucch_set_cfg(srslte_pucch_t *q, srslte_pucch_cfg_t *cfg) +bool srslte_pucch_set_cfg(srslte_pucch_t *q, srslte_pucch_cfg_t *cfg, bool group_hopping_en) { + q->group_hopping_en = group_hopping_en; if (cfg) { if (srslte_pucch_cfg_isvalid(cfg, q->cell.nof_prb)) { memcpy(&q->pucch_cfg, cfg, sizeof(srslte_pucch_cfg_t)); @@ -506,10 +507,11 @@ int srslte_pucch_encode(srslte_pucch_t* q, srslte_pucch_format_t format, uint32_t N_sf = get_N_sf(format, ns%2, q->shortened); // Get group hopping number u uint32_t f_gh=0; - if (q->pucch_cfg.group_hopping_en) { + if (q->group_hopping_en) { f_gh = q->f_gh[ns]; } uint32_t u = (f_gh + (q->cell.id%30))%30; + printf("u=%d\n", u); srslte_refsignal_r_uv_arg_1prb(q->tmp_arg, u); uint32_t N_sf_widx = N_sf==3?1:0; diff --git a/srslte/lib/phch/src/pusch.c b/srslte/lib/phch/src/pusch.c index ddb0b3fbf..796562c01 100644 --- a/srslte/lib/phch/src/pusch.c +++ b/srslte/lib/phch/src/pusch.c @@ -365,6 +365,7 @@ int srslte_pusch_cfg(srslte_pusch_t *q, srslte_pusch_cfg_t *cfg, srslte_dci_msg_ srslte_ra_ul_grant_to_nbits(&cfg->grant, q->cell.cp, q->shortened?1:0, &cfg->nbits); cfg->sf_idx = tti%10; + cfg->tti = tti; cfg->rv = rvidx; cfg->cp = q->cell.cp; diff --git a/srslte/lib/phch/test/pucch_encode_test_mex.c b/srslte/lib/phch/test/pucch_encode_test_mex.c index d836ad97b..1e774778f 100644 --- a/srslte/lib/phch/test/pucch_encode_test_mex.c +++ b/srslte/lib/phch/test/pucch_encode_test_mex.c @@ -100,11 +100,11 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) mexErrMsgTxt("Field CyclicShifts not found in PUCCHCFG\n"); return; } - pucch_cfg.group_hopping_en = false; - char *hop = mexutils_get_char_struct(PUCCHCFG, "Hopping"); + bool group_hopping_en = false; + char *hop = mexutils_get_char_struct(UECFG, "Hopping"); if (hop) { if (!strcmp(hop, "Group")) { - pucch_cfg.group_hopping_en = true; + group_hopping_en = true; } mxFree(hop); } @@ -166,7 +166,7 @@ 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)); - srslte_pucch_set_cfg(&pucch, &pucch_cfg); + srslte_pucch_set_cfg(&pucch, &pucch_cfg, group_hopping_en); if (srslte_pucch_encode(&pucch, format, n_pucch, sf_idx, bits, sf_symbols)) { mexErrMsgTxt("Error encoding PUCCH\n"); @@ -190,10 +190,7 @@ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) } bzero(dmrs_pucch, sizeof(cf_t)*SRSLTE_NRE*3*2); - if (!srslte_refsignal_ul_set_pucch_cfg(&pucch_dmrs, &pucch_cfg)) { - mexErrMsgTxt("Error setting PUCCH config\n"); - return; - } + srslte_refsignal_ul_set_cfg(&pucch_dmrs, NULL, &pucch_cfg, NULL, group_hopping_en, false); if (srslte_refsignal_dmrs_pucch_gen(&pucch_dmrs, format, n_pucch, sf_idx, pucch2_bits, dmrs_pucch)) { mexErrMsgTxt("Error generating PUCCH DMRS\n"); diff --git a/srslte/lib/phch/test/pucch_test.c b/srslte/lib/phch/test/pucch_test.c index fee71d6c6..2cb20b178 100644 --- a/srslte/lib/phch/test/pucch_test.c +++ b/srslte/lib/phch/test/pucch_test.c @@ -125,11 +125,11 @@ int main(int argc, char **argv) { INFO("format %d, n_pucch: %d, ncs: %d, d: %d\n", format, n_pucch, ncs, d); pucch_cfg.beta_pucch = 1.0; pucch_cfg.delta_pucch_shift = d; - pucch_cfg.group_hopping_en = false; + bool group_hopping_en = false; pucch_cfg.N_cs = ncs; pucch_cfg.n_rb_2 = 0; - if (!srslte_pucch_set_cfg(&pucch, &pucch_cfg)) { + if (!srslte_pucch_set_cfg(&pucch, &pucch_cfg, group_hopping_en)) { fprintf(stderr, "Error setting PUCCH config\n"); goto quit; } @@ -138,7 +138,7 @@ int main(int argc, char **argv) { fprintf(stderr, "Error encoding PUCCH\n"); goto quit; } - srslte_refsignal_ul_set_pucch_cfg(&dmrs, &pucch_cfg); + srslte_refsignal_ul_set_cfg(&dmrs, NULL, &pucch_cfg, NULL, group_hopping_en, false); if (srslte_refsignal_dmrs_pucch_gen(&dmrs, format, n_pucch, subframe, pucch2_bits, pucch_dmrs)) { fprintf(stderr, "Error encoding PUCCH\n"); diff --git a/srslte/lib/ue/src/ue_ul.c b/srslte/lib/ue/src/ue_ul.c index a0646d61b..5f45cc2d9 100644 --- a/srslte/lib/ue/src/ue_ul.c +++ b/srslte/lib/ue/src/ue_ul.c @@ -93,6 +93,12 @@ int srslte_ue_ul_init(srslte_ue_ul_t *q, goto clean_exit; } + q->srs_signal = srslte_vec_malloc(SRSLTE_NRE * q->cell.nof_prb * sizeof(cf_t)); + if (!q->srs_signal) { + perror("malloc"); + goto clean_exit; + } + ret = SRSLTE_SUCCESS; } else { fprintf(stderr, "Invalid cell properties: Id=%d, Ports=%d, PRBs=%d\n", @@ -122,6 +128,9 @@ void srslte_ue_ul_free(srslte_ue_ul_t *q) { if (q->refsignal) { free(q->refsignal); } + if (q->srs_signal) { + free(q->srs_signal); + } bzero(q, sizeof(srslte_ue_ul_t)); } } @@ -155,20 +164,23 @@ void srslte_ue_ul_reset(srslte_ue_ul_t *q) { } void srslte_ue_ul_set_cfg(srslte_ue_ul_t *q, - srslte_refsignal_dmrs_pusch_cfg_t *dmrs_cfg, + srslte_refsignal_dmrs_pusch_cfg_t *pusch_cfg, srslte_pucch_cfg_t *pucch_cfg, - srslte_pucch_sched_t *pucch_sched) + srslte_refsignal_srs_cfg_t *srs_cfg, + srslte_pucch_sched_t *pucch_sched, + bool group_hopping_en, + bool sequence_hopping_en) { - srslte_refsignal_ul_set_pusch_cfg(&q->dmrs, dmrs_cfg); - srslte_refsignal_ul_set_pucch_cfg(&q->dmrs, pucch_cfg); - srslte_pucch_set_cfg(&q->pucch, pucch_cfg); + srslte_refsignal_ul_set_cfg(&q->dmrs, pusch_cfg, pucch_cfg, srs_cfg, group_hopping_en, sequence_hopping_en); + srslte_pucch_set_cfg(&q->pucch, pucch_cfg, group_hopping_en); if (pucch_sched) { memcpy(&q->pucch_sched, pucch_sched, sizeof(srslte_pucch_sched_t)); } } int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_dci_msg_t *dci_msg, - srslte_pusch_hopping_cfg_t *hopping_cfg, srslte_refsignal_srs_cfg_t *srs_cfg, + srslte_pusch_hopping_cfg_t *hopping_cfg, + srslte_refsignal_srs_cfg_t *srs_cfg, uint32_t tti, uint32_t rvidx) { return srslte_pusch_cfg(&q->pusch, &q->pusch_cfg, dci_msg, hopping_cfg, srs_cfg, tti, rvidx); @@ -177,7 +189,7 @@ int srslte_ue_ul_cfg_grant(srslte_ue_ul_t *q, srslte_dci_msg_t *dci_msg, /* Choose PUCCH format as in Sec 10.1 of 36.213 and generate PUCCH signal */ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, - uint32_t sf_idx, + uint32_t tti, cf_t *output_signal) { int ret = SRSLTE_ERROR_INVALID_INPUTS; @@ -186,6 +198,7 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, output_signal != NULL) { + uint32_t sf_idx = tti%10; ret = SRSLTE_ERROR; bzero(q->sf_symbols, sizeof(cf_t)*SRSLTE_SF_LEN_RE(q->cell.nof_prb, q->cell.cp)); @@ -270,6 +283,11 @@ int srslte_ue_ul_pucch_encode(srslte_ue_ul_t *q, srslte_uci_data_t uci_data, } srslte_refsignal_dmrs_pucch_put(&q->dmrs, format, n_pucch, q->refsignal, q->sf_symbols); + if (srslte_ue_ul_srs_tx_enabled(&q->dmrs.srs_cfg, tti) && q->pucch.shortened) { + srslte_refsignal_srs_gen(&q->dmrs, tti%10, q->srs_signal); + srslte_refsignal_srs_put(&q->dmrs, tti, q->srs_signal, q->sf_symbols); + } + srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal); if (q->cfo_en) { @@ -325,7 +343,33 @@ int srslte_ue_ul_pusch_uci_encode_rnti(srslte_ue_ul_t *q, } return ret; } - + +int srslte_ue_ul_srs_encode(srslte_ue_ul_t *q, uint32_t tti, cf_t *output_signal) { + int ret = SRSLTE_ERROR_INVALID_INPUTS; + if (q && output_signal) { + ret = SRSLTE_ERROR; + + if (srslte_ue_ul_srs_tx_enabled(&q->dmrs.srs_cfg, q->pusch_cfg.tti) && q->pusch.shortened) { + srslte_refsignal_srs_gen(&q->dmrs, q->pusch_cfg.sf_idx, q->srs_signal); + srslte_refsignal_srs_put(&q->dmrs, q->pusch_cfg.tti, q->srs_signal, q->sf_symbols); + } + + srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal); + + if (q->cfo_en) { + srslte_cfo_correct(&q->cfo, output_signal, output_signal, q->current_cfo / srslte_symbol_sz(q->cell.nof_prb)); + } + + if (q->normalize_en) { + float norm_factor = (float) q->cell.nof_prb/10/sqrtf(q->pusch_cfg.grant.L_prb); + srslte_vec_sc_prod_cfc(output_signal, norm_factor, output_signal, SRSLTE_SF_LEN_PRB(q->cell.nof_prb)); + } + + ret = SRSLTE_SUCCESS; + } + return ret; +} + int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, uint8_t *data, srslte_uci_data_t uci_data, srslte_softbuffer_tx_t *softbuffer, @@ -355,6 +399,11 @@ int srslte_ue_ul_pusch_encode_rnti_softbuffer(srslte_ue_ul_t *q, q->pusch_cfg.grant.L_prb, q->pusch_cfg.grant.n_prb_tilde, q->sf_symbols); + + if (srslte_ue_ul_srs_tx_enabled(&q->dmrs.srs_cfg, q->pusch_cfg.tti)) { + srslte_refsignal_srs_gen(&q->dmrs, q->pusch_cfg.sf_idx, q->srs_signal); + srslte_refsignal_srs_put(&q->dmrs, q->pusch_cfg.tti, q->srs_signal, q->sf_symbols); + } srslte_ofdm_tx_sf(&q->fft, q->sf_symbols, output_signal); @@ -411,4 +460,18 @@ int srslte_ue_ul_sr_send_tti(uint32_t I_sr, uint32_t current_tti) { } +bool srslte_ue_ul_srs_tx_enabled(srslte_refsignal_srs_cfg_t *srs_cfg, uint32_t tti) { + if (srs_cfg->cs_configured) { + if (srs_cfg->ue_configured) { + if (srslte_refsignal_srs_send_cs(srs_cfg->subframe_config, tti%10) == 1 && + srslte_refsignal_srs_send_ue(srs_cfg->I_srs, tti) == 1) + { + printf("SRS UE transmission\n"); + return true; + } + } + } + return false; +} +