Matlab tests working for SRS.

This commit is contained in:
ismagom 2015-06-15 01:56:33 +02:00
parent 3d1d07e7af
commit 9761d1a3a1
23 changed files with 491 additions and 161 deletions

View File

@ -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')

44
matlab/tests/srs_test.m Normal file
View File

@ -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

View File

@ -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);
}

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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

View File

@ -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 6<n_rb<40. Table 5.5.3.2-1 */
{36, 32, 24, 20, 16, 12, 8, 4},
{12, 16, 4, 4, 4, 4, 4, 4},
{ 4, 8, 4, 4, 4, 4, 4, 4},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 40<n_rb<60. Table 5.5.3.2-2 */
{48, 48, 40, 36, 32, 24, 20, 16},
{24, 16, 20, 12, 16, 4, 4, 4},
{12, 16, 4, 12, 8, 4, 4, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 60<n_rb<80. Table 5.5.3.2-3 */
{72, 64, 60, 48, 48, 40, 36, 32},
{24, 32, 20, 24, 16, 20, 12, 16},
{12, 16, 4, 12, 8, 4, 4, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 80<n_rb<110. Table 5.5.3.2-4 */
{96, 96, 80, 72, 64, 60, 48, 48},
{48, 32, 40, 24, 32, 20, 24, 16},
{24, 16, 20, 12, 16, 4, 12, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}}};
/* Same tables for Nb */
uint32_t Nb[4][4][8] = {{
{1, 1, 1, 1, 1, 1, 1, 1},
{3, 2, 6, 5, 4, 3, 2, 1},
{3, 2, 1, 1, 1, 1, 1, 1},
{1, 2, 1, 1, 1, 1, 1, 1}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 3, 2, 3, 2, 6, 5, 4},
{2, 2, 5, 3, 2, 1, 1, 1},
{3, 2, 1, 1, 2, 1, 1, 1}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{3, 2, 3, 2, 3, 2, 3, 2},
{2, 2, 5, 2, 2, 5, 3, 2},
{3, 4, 1, 3, 2, 1, 1, 2}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 3, 2, 3, 2, 3, 2, 3},
{2, 2, 2, 2, 2, 5, 2, 2},
{6, 4, 5, 3, 4, 1, 3, 2}}};
/** 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) {
/* Calculate n_prs */
@ -174,21 +224,25 @@ void srslte_refsignal_ul_free(srslte_refsignal_ul_t * q) {
bzero(q, sizeof(srslte_refsignal_ul_t));
}
void srslte_refsignal_ul_set_pusch_cfg(srslte_refsignal_ul_t *q, srslte_refsignal_dmrs_pusch_cfg_t *cfg)
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)
{
if (cfg) {
memcpy(&q->pusch_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 6<n_rb<40. Table 5.5.3.2-1 */
{36, 32, 24, 20, 16, 12, 8, 4},
{12, 16, 4, 4, 4, 4, 4, 4},
{ 4, 8, 4, 4, 4, 4, 4, 4},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 40<n_rb<60. Table 5.5.3.2-2 */
{48, 48, 40, 36, 32, 24, 20, 16},
{24, 16, 20, 12, 16, 4, 4, 4},
{12, 16, 4, 12, 8, 4, 4, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 60<n_rb<80. Table 5.5.3.2-3 */
{72, 64, 60, 48, 48, 40, 36, 32},
{24, 32, 20, 24, 16, 20, 12, 16},
{12, 16, 4, 12, 8, 4, 4, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}},
{
/* m_srs for 80<n_rb<110. Table 5.5.3.2-4 */
{96, 96, 80, 72, 64, 60, 48, 48},
{48, 32, 40, 24, 32, 20, 24, 16},
{24, 16, 20, 12, 16, 4, 12, 8},
{ 4, 4, 4, 4, 4, 4, 4, 4}}};
/* Same tables for Nb */
uint32_t Nb[4][4][8] = {{
{1, 1, 1, 1, 1, 1, 1, 1},
{3, 2, 6, 5, 4, 3, 2, 1},
{3, 2, 1, 1, 1, 1, 1, 1},
{1, 2, 1, 1, 1, 1, 1, 1}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 3, 2, 3, 2, 6, 5, 4},
{2, 2, 5, 3, 2, 1, 1, 1},
{3, 2, 1, 1, 2, 1, 1, 1}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{3, 2, 3, 2, 3, 2, 3, 2},
{2, 2, 5, 2, 2, 5, 3, 2},
{3, 4, 1, 3, 2, 1, 1, 2}},
{
{1, 1, 1, 1, 1, 1, 1, 1},
{2, 3, 2, 3, 2, 3, 2, 3},
{2, 2, 2, 2, 2, 5, 2, 2},
{6, 4, 5, 3, 4, 1, 3, 2}}};
uint32_t srsbwtable_idx(uint32_t nof_prb) {
if (nof_prb <= 40) {
return 0;
@ -701,15 +707,18 @@ uint32_t srs_Fb(srslte_refsignal_srs_cfg_t *cfg, uint32_t nof_prb, uint32_t tti)
uint32_t srs_k0_ue(srslte_refsignal_srs_cfg_t *cfg, uint32_t nof_prb, uint32_t tti) {
if (cfg->bw_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;b<cfg->B;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;i<M_sc;i++) {
r_srs[(ns%2)*M_sc+i] = q->srs_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;i<M_sc;i++) {
sf_symbols[SRSLTE_RE_IDX(q->cell.nof_prb, 2*SRSLTE_CP_NSYMB(q->cell.cp)-1, k0 + 2*i)] = r_srs[i];
}

View File

@ -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)

View File

@ -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);

View File

@ -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 <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 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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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");

View File

@ -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");

View File

@ -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;
}