SRSENB: Added PUSCH TA and EVM measurement. Some more PHY cleanup.

This commit is contained in:
Xavier Arteaga 2020-03-02 17:51:00 +01:00 committed by Xavier Arteaga
parent 47cbbcbd57
commit da701cd82b
24 changed files with 158 additions and 72 deletions

View File

@ -144,6 +144,16 @@ public:
*/ */
virtual int snr_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, float snr_db) = 0; virtual int snr_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, float snr_db) = 0;
/**
* PHY callback for giving MAC the Time Aligment information in microseconds of a given RNTI during a TTI processing
*
* @param tti The measurement was made
* @param rnti The UE identifier in the eNb
* @param ta_us The actual time alignment in microseconds
* @return SRSLTE_SUCCESS if no error occurs, SRSLTE_ERROR* if an error occurs
*/
virtual int ta_info(uint32_t tti, uint16_t rnti, float ta_us) = 0;
/** /**
* PHY callback for giving MAC the HARQ DL ACK/NACK feedback information for a given RNTI, TTI, eNb cell/carrier and * PHY callback for giving MAC the HARQ DL ACK/NACK feedback information for a given RNTI, TTI, eNb cell/carrier and
* Transport block. * Transport block.

View File

@ -53,6 +53,7 @@ typedef struct SRSLTE_API {
float snr; float snr;
float snr_db; float snr_db;
float cfo; float cfo;
float ta_us;
} srslte_chest_ul_res_t; } srslte_chest_ul_res_t;
typedef struct { typedef struct {

View File

@ -32,7 +32,7 @@ typedef struct {
uint32_t srate_max_hz; uint32_t srate_max_hz;
uint32_t srate_hz; uint32_t srate_hz;
float delay_us; float delay_us;
float delay_nsamples; uint32_t delay_nsamples;
srslte_ringbuffer_t rb; srslte_ringbuffer_t rb;
cf_t* zero_buffer; cf_t* zero_buffer;

View File

@ -25,6 +25,7 @@
#include <srslte/config.h> #include <srslte/config.h>
#include <srslte/phy/phch/ra.h> #include <srslte/phy/phch/ra.h>
#include <srslte/phy/utils/debug.h> #include <srslte/phy/utils/debug.h>
#include <srslte/phy/utils/vector.h>
/** @struct srslte_evm_buffer_t /** @struct srslte_evm_buffer_t
* This structure carries the necessary temporary data required for calculating the EVM. * This structure carries the necessary temporary data required for calculating the EVM.

View File

@ -49,19 +49,15 @@ typedef struct {
cf_t symbol[2]; cf_t symbol[2];
} qam16_packed_t; } qam16_packed_t;
typedef struct {
cf_t symbol[256];
} qam256_packed_t;
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
cf_t* symbol_table; // bit-to-symbol mapping cf_t* symbol_table; // bit-to-symbol mapping
uint32_t nsymbols; // number of modulation symbols uint32_t nsymbols; // number of modulation symbols
uint32_t nbits_x_symbol; // number of bits per symbol uint32_t nbits_x_symbol; // number of bits per symbol
bool byte_tables_init; bool byte_tables_init;
bpsk_packed_t* symbol_table_bpsk; bpsk_packed_t* symbol_table_bpsk;
qpsk_packed_t* symbol_table_qpsk; qpsk_packed_t* symbol_table_qpsk;
qam16_packed_t* symbol_table_16qam; qam16_packed_t* symbol_table_16qam;
} srslte_modem_table_t; } srslte_modem_table_t;
SRSLTE_API void srslte_modem_table_init(srslte_modem_table_t* q); SRSLTE_API void srslte_modem_table_init(srslte_modem_table_t* q);

View File

@ -37,6 +37,7 @@
#include "srslte/phy/mimo/layermap.h" #include "srslte/phy/mimo/layermap.h"
#include "srslte/phy/mimo/precoding.h" #include "srslte/phy/mimo/precoding.h"
#include "srslte/phy/modem/demod_soft.h" #include "srslte/phy/modem/demod_soft.h"
#include "srslte/phy/modem/evm.h"
#include "srslte/phy/modem/mod.h" #include "srslte/phy/modem/mod.h"
#include "srslte/phy/phch/dci.h" #include "srslte/phy/phch/dci.h"
#include "srslte/phy/phch/pusch_cfg.h" #include "srslte/phy/phch/pusch_cfg.h"
@ -72,13 +73,16 @@ typedef struct SRSLTE_API {
void* g; void* g;
/* tx & rx objects */ /* tx & rx objects */
srslte_modem_table_t mod[4]; srslte_modem_table_t mod[SRSLTE_MOD_NITEMS];
srslte_sch_t ul_sch; srslte_sch_t ul_sch;
// This is to generate the scrambling seq for multiple CRNTIs // This is to generate the scrambling seq for multiple CRNTIs
srslte_pusch_user_t** users; srslte_pusch_user_t** users;
srslte_sequence_t tmp_seq; srslte_sequence_t tmp_seq;
// EVM buffer
srslte_evm_buffer_t* evm_buffer;
} srslte_pusch_t; } srslte_pusch_t;
typedef struct SRSLTE_API { typedef struct SRSLTE_API {
@ -91,6 +95,7 @@ typedef struct SRSLTE_API {
srslte_uci_value_t uci; srslte_uci_value_t uci;
bool crc; bool crc;
float avg_iterations_block; float avg_iterations_block;
float evm;
} srslte_pusch_res_t; } srslte_pusch_res_t;
SRSLTE_API int srslte_pusch_init_ue(srslte_pusch_t* q, uint32_t max_prb); SRSLTE_API int srslte_pusch_init_ue(srslte_pusch_t* q, uint32_t max_prb);
@ -131,6 +136,10 @@ SRSLTE_API uint32_t srslte_pusch_tx_info(srslte_pusch_cfg_t* cfg,
char* str, char* str,
uint32_t str_len); uint32_t str_len);
SRSLTE_API uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg, srslte_pusch_res_t* res, char* str, uint32_t str_len); SRSLTE_API uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg,
srslte_pusch_res_t* res,
srslte_chest_ul_res_t* chest_res,
char* str,
uint32_t str_len);
#endif // SRSLTE_PUSCH_H #endif // SRSLTE_PUSCH_H

View File

@ -78,6 +78,9 @@ typedef struct SRSLTE_API {
bool meas_time_en; bool meas_time_en;
uint32_t meas_time_value; uint32_t meas_time_value;
bool meas_ta_en;
bool meas_evm_en;
} srslte_pusch_cfg_t; } srslte_pusch_cfg_t;
#endif // SRSLTE_PUSCH_CFG_H #endif // SRSLTE_PUSCH_CFG_H

View File

@ -64,6 +64,6 @@ SRSLTE_API int srslte_ra_ul_dci_to_grant(srslte_cell_t* cell,
SRSLTE_API void srslte_ra_ul_compute_nof_re(srslte_pusch_grant_t* grant, srslte_cp_t cp, uint32_t N_srs); SRSLTE_API void srslte_ra_ul_compute_nof_re(srslte_pusch_grant_t* grant, srslte_cp_t cp, uint32_t N_srs);
/** Others */ /** Others */
SRSLTE_API uint32_t srslte_ra_ul_info(srslte_pusch_grant_t* grant, char* info_str, uint32_t len); SRSLTE_API uint32_t srslte_ra_ul_info(const srslte_pusch_grant_t* grant, char* info_str, uint32_t len);
#endif // SRSLTE_RA_UL_H #endif // SRSLTE_RA_UL_H

View File

@ -293,7 +293,7 @@ int srslte_chest_ul_estimate_pusch(srslte_chest_ul_t* q,
} }
int nrefs_sym = nof_prb * SRSLTE_NRE; int nrefs_sym = nof_prb * SRSLTE_NRE;
int nrefs_sf = nrefs_sym * 2; int nrefs_sf = nrefs_sym * SRSLTE_NOF_SLOTS_PER_SF;
/* Get references from the input signal */ /* Get references from the input signal */
srslte_refsignal_dmrs_pusch_get(&q->dmrs_signal, cfg, input, q->pilot_recv_signal); srslte_refsignal_dmrs_pusch_get(&q->dmrs_signal, cfg, input, q->pilot_recv_signal);
@ -302,6 +302,21 @@ int srslte_chest_ul_estimate_pusch(srslte_chest_ul_t* q,
srslte_vec_prod_conj_ccc( srslte_vec_prod_conj_ccc(
q->pilot_recv_signal, q->dmrs_pregen.r[cfg->grant.n_dmrs][sf->tti % 10][nof_prb], q->pilot_estimates, nrefs_sf); q->pilot_recv_signal, q->dmrs_pregen.r[cfg->grant.n_dmrs][sf->tti % 10][nof_prb], q->pilot_estimates, nrefs_sf);
// Calculate time alignment error
float ta_err = 0.0f;
if (cfg->meas_ta_en) {
for (int i = 0; i < SRSLTE_NOF_SLOTS_PER_SF; i++) {
ta_err += srslte_vec_estimate_frequency(&q->pilot_estimates[i * nrefs_sym], nrefs_sym) / SRSLTE_NOF_SLOTS_PER_SF;
}
}
// Average and store time aligment error
if (isnormal(ta_err)) {
res->ta_us = roundf(ta_err / 15e-3 * 10) / 10;
} else {
res->ta_us = 0.0f;
}
if (cfg->grant.n_prb[0] != cfg->grant.n_prb[1]) { if (cfg->grant.n_prb[0] != cfg->grant.n_prb[1]) {
printf("ERROR: intra-subframe frequency hopping not supported in the estimator!!\n"); printf("ERROR: intra-subframe frequency hopping not supported in the estimator!!\n");
} }

View File

@ -198,11 +198,13 @@ void channel::set_srate(uint32_t srate)
if (delay[i]) { if (delay[i]) {
srslte_channel_delay_update_srate(delay[i], srate); srslte_channel_delay_update_srate(delay[i], srate);
} }
current_srate = srate;
} }
if (hst) { if (hst) {
srslte_channel_hst_update_srate(hst, srate); srslte_channel_hst_update_srate(hst, srate);
} }
// Update sampling rate
current_srate = srate;
} }
} }

View File

@ -120,7 +120,7 @@ static int pusch_init(srslte_pusch_t* q, uint32_t max_prb, bool is_ue)
INFO("Init PUSCH: %d PRBs\n", max_prb); INFO("Init PUSCH: %d PRBs\n", max_prb);
for (i = 0; i < 4; i++) { for (i = 0; i < SRSLTE_MOD_NITEMS; i++) {
if (srslte_modem_table_lte(&q->mod[i], modulations[i])) { if (srslte_modem_table_lte(&q->mod[i], modulations[i])) {
goto clean; goto clean;
} }
@ -162,11 +162,18 @@ static int pusch_init(srslte_pusch_t* q, uint32_t max_prb, bool is_ue)
goto clean; goto clean;
} }
// Allocate eNb specific buffers
if (!q->is_ue) { if (!q->is_ue) {
q->ce = srslte_vec_malloc(sizeof(cf_t) * q->max_re); q->ce = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
if (!q->ce) { if (!q->ce) {
goto clean; goto clean;
} }
q->evm_buffer = srslte_evm_buffer_alloc(6);
if (!q->evm_buffer) {
ERROR("Allocating EVM buffer\n");
goto clean;
}
} }
q->z = srslte_vec_malloc(sizeof(cf_t) * q->max_re); q->z = srslte_vec_malloc(sizeof(cf_t) * q->max_re);
if (!q->z) { if (!q->z) {
@ -211,7 +218,9 @@ void srslte_pusch_free(srslte_pusch_t* q)
if (q->z) { if (q->z) {
free(q->z); free(q->z);
} }
if (q->evm_buffer) {
srslte_evm_free(q->evm_buffer);
}
srslte_dft_precoding_free(&q->dft_precoding); srslte_dft_precoding_free(&q->dft_precoding);
if (q->users) { if (q->users) {
@ -227,7 +236,7 @@ void srslte_pusch_free(srslte_pusch_t* q)
srslte_sequence_free(&q->tmp_seq); srslte_sequence_free(&q->tmp_seq);
for (i = 0; i < 4; i++) { for (i = 0; i < SRSLTE_MOD_NITEMS; i++) {
srslte_modem_table_free(&q->mod[i]); srslte_modem_table_free(&q->mod[i]);
} }
srslte_sch_free(&q->ul_sch); srslte_sch_free(&q->ul_sch);
@ -241,6 +250,11 @@ int srslte_pusch_set_cell(srslte_pusch_t* q, srslte_cell_t cell)
if (q != NULL && srslte_cell_isvalid(&cell)) { if (q != NULL && srslte_cell_isvalid(&cell)) {
// Resize EVM buffer, only for eNb
if (!q->is_ue && q->evm_buffer) {
srslte_evm_buffer_resize(q->evm_buffer, cell.nof_prb);
}
q->cell = cell; q->cell = cell;
q->max_re = cell.nof_prb * MAX_PUSCH_RE(cell.cp); q->max_re = cell.nof_prb * MAX_PUSCH_RE(cell.cp);
ret = SRSLTE_SUCCESS; ret = SRSLTE_SUCCESS;
@ -498,6 +512,16 @@ int srslte_pusch_decode(srslte_pusch_t* q,
srslte_demod_soft_demodulate_s(cfg->grant.tb.mod, q->d, q->q, cfg->grant.nof_re); srslte_demod_soft_demodulate_s(cfg->grant.tb.mod, q->d, q->q, cfg->grant.nof_re);
} }
if (cfg->meas_evm_en && q->evm_buffer) {
if (q->llr_is_8bit) {
out->evm = srslte_evm_run_b(q->evm_buffer, &q->mod[cfg->grant.tb.mod], q->d, q->q, cfg->grant.tb.nof_bits);
} else {
out->evm = srslte_evm_run_s(q->evm_buffer, &q->mod[cfg->grant.tb.mod], q->d, q->q, cfg->grant.tb.nof_bits);
}
} else {
out->evm = NAN;
}
// Generate scrambling sequence if not pre-generated // Generate scrambling sequence if not pre-generated
srslte_sequence_t* seq = get_user_sequence(q, cfg->rnti, sf->tti % 10, cfg->grant.tb.nof_bits); srslte_sequence_t* seq = get_user_sequence(q, cfg->rnti, sf->tti % 10, cfg->grant.tb.nof_bits);
if (!seq) { if (!seq) {
@ -563,7 +587,11 @@ uint32_t srslte_pusch_tx_info(srslte_pusch_cfg_t* cfg, srslte_uci_value_t* uci_d
return len; return len;
} }
uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg, srslte_pusch_res_t* res, char* str, uint32_t str_len) uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg,
srslte_pusch_res_t* res,
srslte_chest_ul_res_t* chest_res,
char* str,
uint32_t str_len)
{ {
uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti); uint32_t len = srslte_print_check(str, str_len, 0, "rnti=0x%x", cfg->rnti);
@ -575,6 +603,18 @@ uint32_t srslte_pusch_rx_info(srslte_pusch_cfg_t* cfg, srslte_pusch_res_t* res,
len += srslte_uci_data_info(&cfg->uci_cfg, &res->uci, &str[len], str_len - len); len += srslte_uci_data_info(&cfg->uci_cfg, &res->uci, &str[len], str_len - len);
len = srslte_print_check(str, str_len, len, ", snr=%.1f dB", chest_res->snr_db);
// Append Time Aligment information if available
if (cfg->meas_ta_en) {
len = srslte_print_check(str, str_len, len, ", ta=%.1f us", chest_res->ta_us);
}
// Append EVM measurement if available
if (cfg->meas_evm_en) {
len = srslte_print_check(str, str_len, len, ", evm=%.1f %%", res->evm * 100);
}
if (cfg->meas_time_en) { if (cfg->meas_time_en) {
len = srslte_print_check(str, str_len, len, ", t=%d us", cfg->meas_time_value); len = srslte_print_check(str, str_len, len, ", t=%d us", cfg->meas_time_value);
} }

View File

@ -319,7 +319,7 @@ int srslte_ra_ul_dci_to_grant(srslte_cell_t* cell,
} }
} }
uint32_t srslte_ra_ul_info(srslte_pusch_grant_t* grant, char* info_str, uint32_t len) uint32_t srslte_ra_ul_info(const srslte_pusch_grant_t* grant, char* info_str, uint32_t len)
{ {
return srslte_print_check(info_str, return srslte_print_check(info_str,
len, len,

View File

@ -94,7 +94,7 @@ private:
srslte_prach_cfg_t prach_cfg = {}; srslte_prach_cfg_t prach_cfg = {};
void parse_config(const phy_cfg_t& cfg); void parse_common_config(const phy_cfg_t& cfg);
}; };
} // namespace srsenb } // namespace srsenb

View File

@ -128,11 +128,8 @@ public:
return c; return c;
}; };
// Physical Uplink Config common // Common Physical Uplink DMRS configuration
srslte_ul_cfg_t ul_cfg_com = {}; srslte_refsignal_dmrs_pusch_cfg_t dmrs_pusch_cfg = {};
// Physical Downlink Config common
srslte_dl_cfg_t dl_cfg_com = {};
srslte::radio_interface_phy* radio = nullptr; srslte::radio_interface_phy* radio = nullptr;
stack_interface_phy_lte* stack = nullptr; stack_interface_phy_lte* stack = nullptr;

View File

@ -53,6 +53,8 @@ struct phy_args_t {
std::string equalizer_mode = "mmse"; std::string equalizer_mode = "mmse";
float estimator_fil_w = 1.0f; float estimator_fil_w = 1.0f;
bool pregenerate_signals = false; bool pregenerate_signals = false;
bool pusch_meas_evm = true;
bool pusch_meas_ta = true;
srslte::channel::args_t dl_channel_args; srslte::channel::args_t dl_channel_args;
srslte::channel::args_t ul_channel_args; srslte::channel::args_t ul_channel_args;

View File

@ -91,6 +91,11 @@ private:
*/ */
stack_interface_phy_lte* stack = nullptr; stack_interface_phy_lte* stack = nullptr;
/**
* PHY arguments pointer, used for loading the common UE parameters when a new configuration is set
*/
const phy_args_t* phy_args = {};
/** /**
* Cell list * Cell list
*/ */
@ -116,7 +121,7 @@ private:
* *
* @param rnti identifier of the UE (requires assertion prior to call) * @param rnti identifier of the UE (requires assertion prior to call)
*/ */
inline void _set_config_rnti(uint16_t rnti); inline void _set_common_config_rnti(uint16_t rnti);
/** /**
* Gets the SCell index for a given RNTI and a eNb cell/carrier. It returns the SCell index (0 if PCell) if the cc_idx * Gets the SCell index for a given RNTI and a eNb cell/carrier. It returns the SCell index (0 if PCell) if the cc_idx
@ -134,11 +139,7 @@ public:
* @param stack_ptr points to the stack (read/write) * @param stack_ptr points to the stack (read/write)
* @param cell_cfg_list_ points to the cell configuration list (read only) * @param cell_cfg_list_ points to the cell configuration list (read only)
*/ */
void init(stack_interface_phy_lte* stack_ptr, const phy_cell_cfg_list_t& cell_cfg_list_) void init(stack_interface_phy_lte* stack_ptr, const phy_args_t& phy_args_, const phy_cell_cfg_list_t& cell_cfg_list_);
{
stack = stack_ptr;
cell_cfg_list = &cell_cfg_list_;
}
/** /**
* Adds or modifies a user in the UE database setting. This function requires the physical layer configuration coming * Adds or modifies a user in the UE database setting. This function requires the physical layer configuration coming

View File

@ -83,6 +83,7 @@ public:
{ {
return mac.snr_info(tti, rnti, cc_idx, snr_db); return mac.snr_info(tti, rnti, cc_idx, snr_db);
} }
int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override { return mac.ta_info(tti, rnti, ta_us); }
int ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) final int ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) final
{ {
return mac.ack_info(tti, rnti, cc_idx, tb_idx, ack); return mac.ack_info(tti, rnti, cc_idx, tb_idx, ack);

View File

@ -60,6 +60,7 @@ public:
int pmi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t pmi_value) override; int pmi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t pmi_value) override;
int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi_value) override; int cqi_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t cqi_value) override;
int snr_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, float snr) override; int snr_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, float snr) override;
int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override;
int ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) override; int ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) override;
int crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) override; int crc_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t nof_bytes, bool crc_res) override;

View File

@ -120,7 +120,8 @@ void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_)
ERROR("Error initiating ENB UL\n"); ERROR("Error initiating ENB UL\n");
return; return;
} }
if (srslte_enb_ul_set_cell(&enb_ul, cell, &phy->ul_cfg_com.dmrs)) {
if (srslte_enb_ul_set_cell(&enb_ul, cell, &phy->dmrs_pusch_cfg)) {
ERROR("Error initiating ENB UL\n"); ERROR("Error initiating ENB UL\n");
return; return;
} }
@ -132,7 +133,7 @@ void cc_worker::init(phy_common* phy_, srslte::log* log_h_, uint32_t cc_idx_)
add_rnti(SRSLTE_PRNTI, false, false); add_rnti(SRSLTE_PRNTI, false, false);
/* Setup RA-RNTI in PHY */ /* Setup RA-RNTI in PHY */
for (int i = 0; i < 10; i++) { for (int i = 0; i < SRSLTE_CRNTI_START; i++) {
add_rnti(1 + i, false, false); add_rnti(1 + i, false, false);
} }
@ -348,6 +349,7 @@ int cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, u
// Notify MAC of RL status // Notify MAC of RL status
if (snr_db >= PUSCH_RL_SNR_DB_TH) { if (snr_db >= PUSCH_RL_SNR_DB_TH) {
// Notify MAC UL channel quality
phy->stack->snr_info(ul_sf.tti, rnti, cc_idx, snr_db); phy->stack->snr_info(ul_sf.tti, rnti, cc_idx, snr_db);
if (grants[i].dci.tb.rv == 0) { if (grants[i].dci.tb.rv == 0) {
@ -356,6 +358,12 @@ int cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, u
phy->stack->rl_failure(rnti); phy->stack->rl_failure(rnti);
} else { } else {
phy->stack->rl_ok(rnti); phy->stack->rl_ok(rnti);
// Notify MAC of Time Alignment only if it enabled and valid measurement, ignore value otherwise
if (ul_cfg.pusch.meas_ta_en and not std::isnan(enb_ul.chest_res.ta_us) and
not std::isinf(enb_ul.chest_res.ta_us)) {
phy->stack->ta_info(ul_sf.tti, rnti, enb_ul.chest_res.ta_us);
}
} }
} }
} }
@ -372,8 +380,8 @@ int cc_worker::decode_pusch(stack_interface_phy_lte::ul_sched_grant_t* grants, u
// Logging // Logging
char str[512]; char str[512];
srslte_pusch_rx_info(&ul_cfg.pusch, &pusch_res, str, 512); srslte_pusch_rx_info(&ul_cfg.pusch, &pusch_res, &enb_ul.chest_res, str, 512);
Info("PUSCH: cc=%d, %s, snr=%.1f dB\n", cc_idx, str, snr_db); Info("PUSCH: cc=%d, %s\n", cc_idx, str);
} }
} }
} }

View File

@ -59,7 +59,7 @@ phy::~phy()
stop(); stop();
} }
void phy::parse_config(const phy_cfg_t& cfg) void phy::parse_common_config(const phy_cfg_t& cfg)
{ {
// PRACH configuration // PRACH configuration
prach_cfg.config_idx = cfg.prach_cnfg.prach_cfg_info.prach_cfg_idx; prach_cfg.config_idx = cfg.prach_cnfg.prach_cfg_info.prach_cfg_idx;
@ -69,36 +69,10 @@ void phy::parse_config(const phy_cfg_t& cfg)
prach_cfg.freq_offset = cfg.prach_cnfg.prach_cfg_info.prach_freq_offset; prach_cfg.freq_offset = cfg.prach_cnfg.prach_cfg_info.prach_freq_offset;
// DMRS // DMRS
workers_common.ul_cfg_com.dmrs.cyclic_shift = cfg.pusch_cnfg.ul_ref_sigs_pusch.cyclic_shift; workers_common.dmrs_pusch_cfg.cyclic_shift = cfg.pusch_cnfg.ul_ref_sigs_pusch.cyclic_shift;
workers_common.ul_cfg_com.dmrs.delta_ss = cfg.pusch_cnfg.ul_ref_sigs_pusch.group_assign_pusch; workers_common.dmrs_pusch_cfg.delta_ss = cfg.pusch_cnfg.ul_ref_sigs_pusch.group_assign_pusch;
workers_common.ul_cfg_com.dmrs.group_hopping_en = cfg.pusch_cnfg.ul_ref_sigs_pusch.group_hop_enabled; workers_common.dmrs_pusch_cfg.group_hopping_en = cfg.pusch_cnfg.ul_ref_sigs_pusch.group_hop_enabled;
workers_common.ul_cfg_com.dmrs.sequence_hopping_en = cfg.pusch_cnfg.ul_ref_sigs_pusch.seq_hop_enabled; workers_common.dmrs_pusch_cfg.sequence_hopping_en = cfg.pusch_cnfg.ul_ref_sigs_pusch.seq_hop_enabled;
// Hopping
workers_common.ul_cfg_com.hopping.hop_mode =
cfg.pusch_cnfg.pusch_cfg_basic.hop_mode ==
asn1::rrc::pusch_cfg_common_s::pusch_cfg_basic_s_::hop_mode_e_::intra_and_inter_sub_frame
? srslte_pusch_hopping_cfg_t::SRSLTE_PUSCH_HOP_MODE_INTRA_SF
: srslte_pusch_hopping_cfg_t::SRSLTE_PUSCH_HOP_MODE_INTER_SF;
workers_common.ul_cfg_com.hopping.n_sb = cfg.pusch_cnfg.pusch_cfg_basic.n_sb;
workers_common.ul_cfg_com.hopping.hopping_offset = cfg.pusch_cnfg.pusch_cfg_basic.pusch_hop_offset;
workers_common.ul_cfg_com.pusch.max_nof_iterations = workers_common.params.pusch_max_its;
workers_common.ul_cfg_com.pusch.csi_enable = false;
workers_common.ul_cfg_com.pusch.meas_time_en = true;
// PUCCH
workers_common.ul_cfg_com.pucch.delta_pucch_shift = cfg.pucch_cnfg.delta_pucch_shift.to_number();
workers_common.ul_cfg_com.pucch.N_cs = cfg.pucch_cnfg.ncs_an;
workers_common.ul_cfg_com.pucch.n_rb_2 = cfg.pucch_cnfg.nrb_cqi;
workers_common.ul_cfg_com.pucch.N_pucch_1 = cfg.pucch_cnfg.n1_pucch_an;
workers_common.ul_cfg_com.pucch.threshold_format1 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT1;
// PDSCH configuration
workers_common.dl_cfg_com.tm = SRSLTE_TM1;
workers_common.dl_cfg_com.pdsch.rs_power = cfg.pdsch_cnfg.ref_sig_pwr;
workers_common.dl_cfg_com.pdsch.p_b = cfg.pdsch_cnfg.p_b;
workers_common.dl_cfg_com.pdsch.meas_time_en = true;
} }
int phy::init(const phy_args_t& args, int phy::init(const phy_args_t& args,
@ -139,7 +113,7 @@ int phy::init(const phy_args_t& args,
workers_common.init(cfg.phy_cell_cfg, radio, stack_); workers_common.init(cfg.phy_cell_cfg, radio, stack_);
parse_config(cfg); parse_common_config(cfg);
// Add workers to workers pool and start threads // Add workers to workers pool and start threads
for (uint32_t i = 0; i < nof_workers; i++) { for (uint32_t i = 0; i < nof_workers; i++) {

View File

@ -85,8 +85,8 @@ bool phy_common::init(const phy_cell_cfg_list_t& cell_list_,
q.resize(cell_list.size()); q.resize(cell_list.size());
} }
// Set UE PHY data-base stack // Set UE PHY data-base stack and configuration
ue_db.init(stack, cell_list); ue_db.init(stack, params, cell_list);
reset(); reset();
return true; return true;

View File

@ -23,6 +23,15 @@
using namespace srsenb; using namespace srsenb;
void phy_ue_db::init(stack_interface_phy_lte* stack_ptr,
const phy_args_t& phy_args_,
const phy_cell_cfg_list_t& cell_cfg_list_)
{
stack = stack_ptr;
phy_args = &phy_args_;
cell_cfg_list = &cell_cfg_list_;
}
inline void phy_ue_db::_add_rnti(uint16_t rnti) inline void phy_ue_db::_add_rnti(uint16_t rnti)
{ {
// Private function not mutexed // Private function not mutexed
@ -42,7 +51,7 @@ inline void phy_ue_db::_add_rnti(uint16_t rnti)
ue.scell_info[0].phy_cfg.set_defaults(); ue.scell_info[0].phy_cfg.set_defaults();
// Set constant configuration fields // Set constant configuration fields
_set_config_rnti(rnti); _set_common_config_rnti(rnti);
// PCell shall be active by default // PCell shall be active by default
ue.scell_info[0].state = scell_state_active; ue.scell_info[0].state = scell_state_active;
@ -79,7 +88,7 @@ inline void phy_ue_db::_clear_tti_pending_rnti(uint32_t tti, uint16_t rnti)
pdsch_ack.simul_cqi_ack = ue.scell_info[0].phy_cfg.ul_cfg.pucch.simul_cqi_ack; pdsch_ack.simul_cqi_ack = ue.scell_info[0].phy_cfg.ul_cfg.pucch.simul_cqi_ack;
} }
inline void phy_ue_db::_set_config_rnti(uint16_t rnti) inline void phy_ue_db::_set_common_config_rnti(uint16_t rnti)
{ {
// Private function not mutexed, no need to assert RNTI or TTI // Private function not mutexed, no need to assert RNTI or TTI
@ -91,6 +100,9 @@ inline void phy_ue_db::_set_config_rnti(uint16_t rnti)
scell_info.phy_cfg.dl_cfg.pdsch.rnti = rnti; scell_info.phy_cfg.dl_cfg.pdsch.rnti = rnti;
scell_info.phy_cfg.ul_cfg.pucch.rnti = rnti; scell_info.phy_cfg.ul_cfg.pucch.rnti = rnti;
scell_info.phy_cfg.ul_cfg.pusch.rnti = rnti; scell_info.phy_cfg.ul_cfg.pusch.rnti = rnti;
scell_info.phy_cfg.ul_cfg.pusch.meas_time_en = true;
scell_info.phy_cfg.ul_cfg.pusch.meas_ta_en = phy_args->pusch_meas_ta;
scell_info.phy_cfg.ul_cfg.pusch.meas_evm_en = phy_args->pusch_meas_evm;
scell_info.phy_cfg.ul_cfg.pucch.threshold_format1 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT1; scell_info.phy_cfg.ul_cfg.pucch.threshold_format1 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT1;
scell_info.phy_cfg.ul_cfg.pucch.threshold_data_valid_format1a = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT1A; scell_info.phy_cfg.ul_cfg.pucch.threshold_data_valid_format1a = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT1A;
scell_info.phy_cfg.ul_cfg.pucch.threshold_data_valid_format2 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT2; scell_info.phy_cfg.ul_cfg.pucch.threshold_data_valid_format2 = SRSLTE_PUCCH_DEFAULT_THRESHOLD_FORMAT2;
@ -148,7 +160,7 @@ void phy_ue_db::addmod_rnti(uint16_t
scell_info.phy_cfg = phy_rrc_dedicated.phy_cfg; scell_info.phy_cfg = phy_rrc_dedicated.phy_cfg;
// Set constant configuration fields // Set constant configuration fields
_set_config_rnti(rnti); _set_common_config_rnti(rnti);
// Set SCell state, all deactivated by default except PCell // Set SCell state, all deactivated by default except PCell
scell_info.state = scell_idx == 0 ? scell_state_active : scell_state_deactivated; scell_info.state = scell_idx == 0 ? scell_state_active : scell_state_deactivated;

View File

@ -398,6 +398,12 @@ int mac::snr_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, float snr)
return ret; return ret;
} }
int mac::ta_info(uint32_t tti, uint16_t rnti, float ta_us)
{
log_h->info("TA: tti=%d, rnti=0x%04x, ta_us=%.1f\n", tti, rnti, ta_us);
return SRSLTE_SUCCESS;
}
int mac::sr_detected(uint32_t tti, uint16_t rnti) int mac::sr_detected(uint32_t tti, uint16_t rnti)
{ {
log_h->step(tti); log_h->step(tti);

View File

@ -281,6 +281,7 @@ private:
CALLBACK(pmi_info); CALLBACK(pmi_info);
CALLBACK(cqi_info); CALLBACK(cqi_info);
CALLBACK(snr_info); CALLBACK(snr_info);
CALLBACK(ta_info);
CALLBACK(ack_info); CALLBACK(ack_info);
CALLBACK(crc_info); CALLBACK(crc_info);
CALLBACK(get_dl_sched); CALLBACK(get_dl_sched);
@ -405,6 +406,12 @@ public:
notify_snr_info(); notify_snr_info();
return 0; return 0;
} }
int ta_info(uint32_t tti, uint16_t rnti, float ta_us) override
{
log_h.info("Received TA INFO tti=%d; rnti=x%x; ta=%.1f us\n", tti, rnti, ta_us);
notify_ta_info();
return 0;
}
int ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) override int ack_info(uint32_t tti, uint16_t rnti, uint32_t cc_idx, uint32_t tb_idx, bool ack) override
{ {
// Push grant info in queue // Push grant info in queue