diff --git a/lib/include/srslte/phy/common/phy_common.h b/lib/include/srslte/phy/common/phy_common.h index 828015f67..c747a4448 100644 --- a/lib/include/srslte/phy/common/phy_common.h +++ b/lib/include/srslte/phy/common/phy_common.h @@ -38,7 +38,8 @@ #include "srslte/config.h" #define SRSLTE_NOF_SF_X_FRAME 10 -#define SRSLTE_NSLOTS_X_FRAME (2 * SRSLTE_NOF_SF_X_FRAME) +#define SRSLTE_NOF_SLOTS_PER_SF 2 +#define SRSLTE_NSLOTS_X_FRAME (SRSLTE_NOF_SLOTS_PER_SF * SRSLTE_NOF_SF_X_FRAME) #define SRSLTE_NSOFT_BITS 250368 // Soft buffer size for Category 1 UE @@ -323,6 +324,10 @@ typedef struct SRSLTE_API { #define SRSLTE_DEFAULT_MAX_FRAMES_NPSS 20 #define SRSLTE_DEFAULT_NOF_VALID_NPSS_FRAMES 20 +#define SRSLTE_NBIOT_NPBCH_NOF_TOTAL_BITS (1600) ///< Number of bits for the entire NPBCH (See 36.211 Sec 10.2.4.1) +#define SRSLTE_NBIOT_NPBCH_NOF_BITS_SF \ + (SRSLTE_NBIOT_NPBCH_NOF_TOTAL_BITS / 8) ///< The NPBCH is transmitted in 8 blocks (See 36.211 Sec 10.2.4.4) + SRSLTE_API bool srslte_cell_isvalid(srslte_cell_t *cell); SRSLTE_API void srslte_cell_fprint(FILE *stream, diff --git a/lib/include/srslte/phy/phch/npbch.h b/lib/include/srslte/phy/phch/npbch.h index f1bd94af6..9f78ce775 100644 --- a/lib/include/srslte/phy/phch/npbch.h +++ b/lib/include/srslte/phy/phch/npbch.h @@ -81,6 +81,7 @@ typedef struct SRS_API { // tx & rx objects srslte_modem_table_t mod; srslte_sequence_t seq; + srslte_sequence_t seq_r14[SRSLTE_NPBCH_NUM_BLOCKS]; srslte_viterbi_t decoder; srslte_crc_t crc; srslte_convcoder_t encoder; diff --git a/lib/src/phy/ch_estimation/chest_dl_nbiot.c b/lib/src/phy/ch_estimation/chest_dl_nbiot.c index 591d5cd31..3a65aee1f 100644 --- a/lib/src/phy/ch_estimation/chest_dl_nbiot.c +++ b/lib/src/phy/ch_estimation/chest_dl_nbiot.c @@ -170,7 +170,7 @@ static float estimate_noise_pilots(srslte_chest_dl_nbiot_t* q, uint32_t port_id) return power; } -#define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.base.nof_prb, i, 0)] +#define cesymb(i) ce[SRSLTE_RE_IDX(q->cell.base.nof_prb, (i), 0)] static void interpolate_pilots(srslte_chest_dl_nbiot_t* q, cf_t* pilot_estimates, cf_t* ce, uint32_t port_id) { diff --git a/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c b/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c index 0896d5274..85b4dc6c3 100644 --- a/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c +++ b/lib/src/phy/ch_estimation/refsignal_dl_nbiot.c @@ -131,7 +131,7 @@ int srslte_refsignal_dl_nbiot_set_cell(srslte_refsignal_dl_nbiot_t* q, srslte_nb srslte_sequence_t seq; bzero(&seq, sizeof(srslte_sequence_t)); - if (srslte_sequence_init(&seq, 2 * 2 * SRSLTE_MAX_PRB)) { + if (srslte_sequence_init(&seq, SRSLTE_NOF_SLOTS_PER_SF * SRSLTE_NBIOT_MAX_PORTS * SRSLTE_MAX_PRB)) { goto free_and_exit; } @@ -145,7 +145,7 @@ int srslte_refsignal_dl_nbiot_set_cell(srslte_refsignal_dl_nbiot_t* q, srslte_nb uint32_t c_init = 1024 * (7 * (ns + 1) + lp + 1) * (2 * cell.n_id_ncell + 1) + 2 * cell.n_id_ncell + N_cp; /* generate sequence for this symbol and slot */ - srslte_sequence_set_LTE_pr(&seq, 2 * 2 * SRSLTE_MAX_PRB, c_init); + srslte_sequence_set_LTE_pr(&seq, SRSLTE_NOF_SLOTS_PER_SF + SRSLTE_NBIOT_MAX_PORTS * SRSLTE_MAX_PRB, c_init); /* Compute signal */ for (uint32_t i = 0; i < 2; i++) { diff --git a/lib/src/phy/phch/npbch.c b/lib/src/phy/phch/npbch.c index 31c290e00..437f364aa 100644 --- a/lib/src/phy/phch/npbch.c +++ b/lib/src/phy/phch/npbch.c @@ -151,6 +151,10 @@ void srslte_npbch_free(srslte_npbch_t* q) if (q->rm_b) { free(q->rm_b); } + for (uint32_t i = 0; i < SRSLTE_NPBCH_NUM_BLOCKS; i++) { + srslte_sequence_free(&q->seq_r14[i]); + } + srslte_sequence_free(&q->seq); srslte_modem_table_free(&q->mod); srslte_viterbi_free(&q->decoder); @@ -175,6 +179,15 @@ int srslte_npbch_set_cell(srslte_npbch_t* q, srslte_nbiot_cell_t cell) fprintf(stderr, "Error initiating NPBCH sequence.\n"); return SRSLTE_ERROR; } + + // pre-compute the 8 rotation sequences for R14 + if (q->cell.is_r14) { + for (uint32_t i = 0; i < SRSLTE_NPBCH_NUM_BLOCKS; i++) { + if (srslte_sequence_npbch_r14(&q->seq_r14[i], q->cell.n_id_ncell, i)) { + return SRSLTE_ERROR; + } + } + } } ret = SRSLTE_SUCCESS; @@ -258,7 +271,6 @@ int srslte_npbch_encode(srslte_npbch_t* q, cf_t* sf[SRSLTE_MAX_PORTS], uint32_t frame_idx) { - int nof_bits; int block_idx = (frame_idx / SRSLTE_NPBCH_NUM_REP) % SRSLTE_NPBCH_NUM_BLOCKS; cf_t* x[SRSLTE_MAX_LAYERS]; @@ -269,7 +281,7 @@ int srslte_npbch_encode(srslte_npbch_t* q, } } // Set pointers for layermapping & precoding - nof_bits = 2 * q->nof_symbols; + int nof_bits = 2 * q->nof_symbols; // number of layers equals number of ports for (int i = 0; i < q->cell.nof_ports; i++) { @@ -310,7 +322,7 @@ int srslte_npbch_encode(srslte_npbch_t* q, // Write exactly SRSLTE_NPBCH_NUM_RE (assumes symbols have been modulated before) for (int i = 0; i < q->cell.nof_ports; i++) { if (q->cell.is_r14) { - DEBUG("Applying phase rotattion on port %d in frame %d.\n", i, frame_idx); + DEBUG("Applying phase rotation on port %d in frame %d.\n", i, frame_idx); srslte_npbch_rotate(q, frame_idx, q->symbols[i], q->symbols[i], q->nof_symbols, false); } DEBUG("Putting MIB-NB block %d on port %d in frame %d.\n", block_idx, i, frame_idx); @@ -336,14 +348,9 @@ int srslte_npbch_rotate(srslte_npbch_t* q, // Generate frame specific scrambling sequence for symbol rotation DEBUG("%sotating NPBCH in SFN=%d\n", back ? "De-R" : "R", nf); - srslte_sequence_t seq; - if (srslte_sequence_npbch_r14(&seq, q->cell.n_id_ncell, nf)) { - return SRSLTE_ERROR; - } - for (int i = 0; i < num_samples; i++) { - int c_2i = seq.c[2 * i]; - int c_2ip1 = seq.c[2 * i + 1]; + int c_2i = q->seq_r14[nf % 8].c[2 * i]; + int c_2ip1 = q->seq_r14[nf % 8].c[2 * i + 1]; #if 1 cf_t phi_f = 0; @@ -374,7 +381,6 @@ int srslte_npbch_rotate(srslte_npbch_t* q, } } - srslte_sequence_free(&seq); return SRSLTE_SUCCESS; } diff --git a/lib/src/phy/phch/ra_nbiot.c b/lib/src/phy/phch/ra_nbiot.c index caab20820..2fab8d479 100644 --- a/lib/src/phy/phch/ra_nbiot.c +++ b/lib/src/phy/phch/ra_nbiot.c @@ -36,8 +36,6 @@ #define MAX_I_SF_VAL 7 #define EUTRA_CONTROL_REGION_SIZE 3 // FIXME: Needs to be set by SIB1 -#define min(a, b) (a < b ? a : b) - /// Number of repetitions according to Table 16.4.1.3-2 in TS 36.213 13.2.0 const int n_rep_table[16] = {1, 2, 4, 8, 16, 32, 64, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048}; @@ -139,9 +137,9 @@ static int nbiot_dl_dci_to_grant_mcs(srslte_ra_nbiot_dl_dci_t* dci, srslte_ra_nb grant->mcs[0].mod = SRSLTE_MOD_QPSK; // limit config values in DCI - dci->alloc.sched_info_sib1 = min(dci->alloc.sched_info_sib1, MAX_I_TBS_VAL_SIB); - dci->mcs_idx = min(dci->mcs_idx, MAX_I_TBS_VAL); - dci->alloc.i_sf = min(dci->alloc.i_sf, MAX_I_SF_VAL); + dci->alloc.sched_info_sib1 = SRSLTE_MIN(dci->alloc.sched_info_sib1, MAX_I_TBS_VAL_SIB); + dci->mcs_idx = SRSLTE_MIN(dci->mcs_idx, MAX_I_TBS_VAL); + dci->alloc.i_sf = SRSLTE_MIN(dci->alloc.i_sf, MAX_I_SF_VAL); if (dci->alloc.has_sib1) { i_tbs = dci->alloc.sched_info_sib1; @@ -173,7 +171,7 @@ int srslte_ra_n_rep_sib1_nb(srslte_mib_nb_t* mib) int srslte_ra_nbiot_get_sib1_tbs(srslte_mib_nb_t* mib) { - uint32_t i_tbs = min(mib->sched_info_sib1, MAX_I_TBS_VAL_SIB); + uint32_t i_tbs = SRSLTE_MIN(mib->sched_info_sib1, MAX_I_TBS_VAL_SIB); return tbs_table_nbiot_sib1[i_tbs]; } diff --git a/lib/src/phy/phch/sequences.c b/lib/src/phy/phch/sequences.c index f9b78ca79..1ea7f51df 100644 --- a/lib/src/phy/phch/sequences.c +++ b/lib/src/phy/phch/sequences.c @@ -84,7 +84,7 @@ int srslte_sequence_pmch(srslte_sequence_t* seq, uint32_t nslot, uint32_t mbsfn_ */ int srslte_sequence_npbch(srslte_sequence_t *seq, srslte_cp_t cp, uint32_t cell_id) { bzero(seq, sizeof(srslte_sequence_t)); - return srslte_sequence_LTE_pr(seq, 1600, cell_id); + return srslte_sequence_LTE_pr(seq, SRSLTE_NBIOT_NPBCH_NOF_TOTAL_BITS, cell_id); } /** @@ -93,7 +93,10 @@ int srslte_sequence_npbch(srslte_sequence_t *seq, srslte_cp_t cp, uint32_t cell_ int srslte_sequence_npbch_r14(srslte_sequence_t *seq, uint32_t n_id_ncell, uint32_t nf) { bzero(seq, sizeof(srslte_sequence_t)); - return srslte_sequence_LTE_pr(seq, 200, (n_id_ncell + 1) * (((nf % 8) + 1) * ((nf % 8) + 1) * ((nf % 8) + 1)) * 512 + n_id_ncell); + return srslte_sequence_LTE_pr(seq, + SRSLTE_NBIOT_NPBCH_NOF_BITS_SF, + (n_id_ncell + 1) * (((nf % 8) + 1) * ((nf % 8) + 1) * ((nf % 8) + 1)) * 512 + + n_id_ncell); } /**