From ad17253246796f92b3f255a5360e3f060ec6e3fc Mon Sep 17 00:00:00 2001 From: Klaus Kuehnhammer Date: Fri, 6 Oct 2023 16:20:39 +0200 Subject: [PATCH] Support for SCS 2.5kHz --- lib/include/srsran/phy/common/phy_common.h | 4 ++- lib/src/phy/ch_estimation/chest_dl.c | 10 +++++- lib/src/phy/ch_estimation/refsignal_dl.c | 36 +++++++++++++++++++--- lib/src/phy/dft/ofdm.c | 1 + 4 files changed, 45 insertions(+), 6 deletions(-) diff --git a/lib/include/srsran/phy/common/phy_common.h b/lib/include/srsran/phy/common/phy_common.h index b11d53679b..e1d28f94e8 100644 --- a/lib/include/srsran/phy/common/phy_common.h +++ b/lib/include/srsran/phy/common/phy_common.h @@ -132,7 +132,9 @@ typedef enum { SRSRAN_SCS_15KHZ = 0, SRSRAN_SCS_7KHZ5, SRSRAN_SCS_2KHZ5, SRSRAN_ #define SRSRAN_CP_SCS_1KHZ25_NSYMB 1 #define SRSRAN_CP_SCS_2KHZ5_NSYMB 1 #define SRSRAN_CP_SCS_0KHZ37_NSYMB 1 -#define SRSRAN_CP_MBSFN_LEN(scs) (scs == SRSRAN_SCS_1KHZ25 ? 6144 : (scs == SRSRAN_SCS_7KHZ5 ? 1024 : SRSRAN_CP_EXT_LEN)) +#define SRSRAN_CP_MBSFN_LEN(scs) (scs == SRSRAN_SCS_1KHZ25 ? 6144 : (scs == SRSRAN_SCS_7KHZ5 ? 1024 : \ + (scs == SRSRAN_SCS_2KHZ5 ? 3072 : \ + SRSRAN_CP_EXT_LEN))) #define SRSRAN_MBSFN_NOF_SLOTS(scs) ((scs == SRSRAN_SCS_1KHZ25 || scs == SRSRAN_SCS_0KHZ37) ? 1 : 2) #define SRSRAN_MBSFN_NOF_SYMBOLS(scs) (scs == SRSRAN_SCS_1KHZ25 ? SRSRAN_CP_SCS_1KHZ25_NSYMB : \ diff --git a/lib/src/phy/ch_estimation/chest_dl.c b/lib/src/phy/ch_estimation/chest_dl.c index 8b2218eedb..35427d1f04 100644 --- a/lib/src/phy/ch_estimation/chest_dl.c +++ b/lib/src/phy/ch_estimation/chest_dl.c @@ -492,6 +492,13 @@ static void interpolate_pilots(srsran_chest_dl_t* q, &ce[srsran_refsignal_mbsfn_nsymbol(l, scs) * q->cell.nof_prb * SRSRAN_NRE_SCS(scs)], fidx_offset, l==1 ? 2 : 4 ); + } else if (sf->subcarrier_spacing == SRSRAN_SCS_2KHZ5) { + fidx_offset = srsran_refsignal_mbsfn_fidx(l, sf->subcarrier_spacing); + srsran_interp_linear_offset(&q->srsran_interp_lin_mbsfn, + &pilot_estimates[srsran_refsignal_mbsfn_rs_per_symbol(scs) * q->cell.nof_prb * l], + &ce[srsran_refsignal_mbsfn_nsymbol(l, scs) * q->cell.nof_prb * SRSRAN_NRE_SCS(scs)], + fidx_offset, + l==1 ? 2 : 4 ); } else { // SRSRAN_SCS_1KHZ25 fidx_offset = sf->tti%2==0 ? 0 : 3; srsran_interp_linear_offset(&q->srsran_interp_lin_mbsfn, @@ -523,7 +530,8 @@ static void interpolate_pilots(srsran_chest_dl_t* q, fidx_offset, SRSRAN_NRE / 2 - fidx_offset); } else { - fidx_offset = srsran_refsignal_cs_fidx(q->cell, l, port_id, 0); + fidx_offset = + srsran_refsignal_cs_fidx(q->cell, l, port_id, 0); srsran_interp_linear_offset( &q->srsran_interp_lin, &pilot_estimates[2 * q->cell.nof_prb * l], diff --git a/lib/src/phy/ch_estimation/refsignal_dl.c b/lib/src/phy/ch_estimation/refsignal_dl.c index 540a0072a8..41efc1264c 100644 --- a/lib/src/phy/ch_estimation/refsignal_dl.c +++ b/lib/src/phy/ch_estimation/refsignal_dl.c @@ -410,8 +410,14 @@ inline uint32_t srsran_refsignal_mbsfn_fidx(uint32_t l, srsran_scs_t scs) ret = 0; } break; - case SRSRAN_SCS_1KHZ25: case SRSRAN_SCS_2KHZ5: + if (l == 0) { + ret = 0; + } else { + ret = 2; + } + break; + case SRSRAN_SCS_1KHZ25: case SRSRAN_SCS_0KHZ37: ret = 0; break; @@ -475,8 +481,10 @@ inline uint32_t srsran_refsignal_mbsfn_nsymbol(uint32_t l, srsran_scs_t scs) ret = 5; } break; - case SRSRAN_SCS_1KHZ25: case SRSRAN_SCS_2KHZ5: + ret = l; + break; + case SRSRAN_SCS_1KHZ25: case SRSRAN_SCS_0KHZ37: ret = 0; break; @@ -504,16 +512,33 @@ int srsran_refsignal_mbsfn_gen_seq(srsran_refsignal_t* q, srsran_cell_t cell, ui for (l = 0; l < nsymbols; l++) { uint32_t lp = (srsran_refsignal_mbsfn_nsymbol(l, scs)) % srsran_symbols_per_mbsfn_subframe(scs); uint32_t slot = (l) ? (ns * 2 + 1) : (ns * 2); + + if (scs == SRSRAN_SCS_1KHZ25) { + slot = ns; + lp = l; + } else if (scs == SRSRAN_SCS_2KHZ5) { + slot = ns; + lp = l; + } + c_init = 512 * - (7 * ( ( scs == SRSRAN_SCS_1KHZ25 ? ns : slot ) + 1) + ( scs == SRSRAN_SCS_1KHZ25 ? l : lp ) + 1) * + (7 * (slot + 1) + lp + 1) * (2 * N_mbsfn_id + 1) + N_mbsfn_id; srsran_sequence_set_LTE_pr(&seq_mbsfn, 10 * SRSRAN_REFSIGNAL_NUM_SF_MBSFN(SRSRAN_MAX_PRB, scs), c_init); for (i = 0; i < srsran_refsignal_mbsfn_rs_per_symbol(scs) * q->cell.nof_prb; i++) { uint32_t idx = SRSRAN_REFSIGNAL_PILOT_IDX_MBSFN(i, l, q->cell, scs); - mp = i + 3 * (SRSRAN_MAX_PRB - cell.nof_prb); + float delta = (SRSRAN_MAX_PRB - cell.nof_prb) / 2.0; + if (scs == SRSRAN_SCS_2KHZ5) { + mp = i + ((float)SRSRAN_NRE_SCS(scs) / 4.0) * delta; + } else { + mp = i + 3 * (SRSRAN_MAX_PRB - cell.nof_prb); + } __real__ q->pilots[p][ns][idx] = (1 - 2 * (float)seq_mbsfn.c[2 * mp + 0]) * M_SQRT1_2; __imag__ q->pilots[p][ns][idx] = (1 - 2 * (float)seq_mbsfn.c[2 * mp + 1]) * M_SQRT1_2; + //TRACE("p %d ns %d idx %d (l %d, i %d, mp %d): %f + %f i", p, ns, idx, l, i, mp, + // creal(q->pilots[p][ns][idx]), + // cimag(q->pilots[p][ns][idx])); } } } @@ -609,6 +634,9 @@ int srsran_refsignal_mbsfn_get_sf(srsran_cell_t cell, uint32_t port_id, cf_t* sf for (i = 0; i < srsran_refsignal_mbsfn_rs_per_symbol(scs) * cell.nof_prb; i++) { pilots[SRSRAN_REFSIGNAL_PILOT_IDX_MBSFN(i, l, cell, scs) + nonmbsfn_offset] = sf_symbols[SRSRAN_RE_IDX_MBSFN(cell.nof_prb, nsymbol, fidx, scs)]; + //ERROR("Reading RS %d from sf %d %d,%d: %f + %f i", i, sf_idx, nsymbol, fidx, + // creal(sf_symbols[SRSRAN_RE_IDX_MBSFN(cell.nof_prb, nsymbol, fidx, scs)]), + // cimag(sf_symbols[SRSRAN_RE_IDX_MBSFN(cell.nof_prb, nsymbol, fidx, scs)])); fidx += SRSRAN_NRE_SCS(scs) / srsran_refsignal_mbsfn_rs_per_symbol(scs); } } diff --git a/lib/src/phy/dft/ofdm.c b/lib/src/phy/dft/ofdm.c index 8cb4937669..18ba4e22b3 100644 --- a/lib/src/phy/dft/ofdm.c +++ b/lib/src/phy/dft/ofdm.c @@ -572,6 +572,7 @@ static void ofdm_rx_slot_mbsfn(srsran_ofdm_t* q, cf_t* input, cf_t* output) input += SRSRAN_NON_MBSFN_REGION_GUARD_LENGTH(q->non_mbsfn_region, q->cfg.symbol_sz); } if (q->cfg.subcarrier_spacing != SRSRAN_SCS_15KHZ) { + // input += SRSRAN_CP_LEN_MBSFN_SCS(q->cfg.symbol_sz, q->cfg.subcarrier_spacing); input += q->cfg.symbol_sz / 4U; } else { if (SRSRAN_CP_ISNORM(q->cfg.cp)) {