Commit b70eba44 authored by francescomani's avatar francescomani

fix for computing ssb subcarrier offset

parent 513f060f
...@@ -755,11 +755,25 @@ void SLIV2SL(int SLIV,int *S,int *L) { ...@@ -755,11 +755,25 @@ void SLIV2SL(int SLIV,int *S,int *L) {
} }
} }
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA) int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA, int scs)
{ {
uint32_t absolute_diff = (absoluteFrequencySSB - absoluteFrequencyPointA); // for FR1 k_SSB expressed in terms of 15kHz SCS
const int scaling_5khz = absoluteFrequencyPointA < 600000 ? 3 : 1; // for FR2 k_SSB expressed in terms of the subcarrier spacing provided by the higher-layer parameter subCarrierSpacingCommon
return ((absolute_diff / scaling_5khz) % 24); // absoluteFrequencySSB and absoluteFrequencyPointA are ARFCN
// NR-ARFCN delta frequency is 5kHz if f < 3 GHz, 15kHz for other FR1 freq and 60kHz for FR2
const uint32_t absolute_diff = absoluteFrequencySSB - absoluteFrequencyPointA;
int scaling = 1;
if (absoluteFrequencyPointA < 600000) // correspond to 3GHz
scaling = 3;
if (scs > 2) // FR2
scaling <<= (scs - 2);
int sco_limit = scs == 1 ? 24 : 12;
int subcarrier_offset = (absolute_diff / scaling) % sco_limit;
// 30kHz is the only case where k_SSB is expressed in terms of a different SCS (15kHz)
// the assertion is to avoid having an offset of half a subcarrier
if (scs == 1)
AssertFatal(subcarrier_offset % 2 == 0, "ssb offset %d invalid for scs %d\n", subcarrier_offset, scs);
return subcarrier_offset;
} }
uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB, uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
...@@ -767,16 +781,16 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB, ...@@ -767,16 +781,16 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
int ssbSubcarrierSpacing, int ssbSubcarrierSpacing,
int frequency_range) int frequency_range)
{ {
// offset to pointA is expressed in terms of 15kHz SCS for FR1 and 60kHz for FR2
// only difference wrt NR-ARFCN is delta frequency 5kHz if f < 3 GHz for ARFCN
uint32_t absolute_diff = (absoluteFrequencySSB - absoluteFrequencyPointA); uint32_t absolute_diff = (absoluteFrequencySSB - absoluteFrequencyPointA);
const int scaling_5khz = absoluteFrequencyPointA < 600000 ? 3 : 1; const int scaling_5khz = absoluteFrequencyPointA < 600000 ? 3 : 1;
int sco = get_ssb_subcarrier_offset(absoluteFrequencySSB, absoluteFrequencyPointA); const int scaling = frequency_range == FR2 ? 1 << (ssbSubcarrierSpacing - 2) : 1 << ssbSubcarrierSpacing;
const int scs_scaling = frequency_range == FR2 ? 1 << (ssbSubcarrierSpacing - 2) : 1 << ssbSubcarrierSpacing; const int scaled_abs_diff = absolute_diff / (scaling_5khz * scaling);
const int scaled_abs_diff = absolute_diff / scaling_5khz; // absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total
const int ssb_offset_point_a = const int ssb_offset_point_a = ((scaled_abs_diff / 12) - 10) * scaling;
(scaled_abs_diff - sco) / 12 // Offset to point A needs to be divisible by scaling
- 10 * scs_scaling; // absoluteFrequencySSB is the central frequency of SSB which is made by 20RBs in total AssertFatal(ssb_offset_point_a % scaling == 0, "PRB offset %d not valid for scs %d\n", ssb_offset_point_a, ssbSubcarrierSpacing);
AssertFatal(ssb_offset_point_a % scs_scaling == 0, "PRB offset %d can create frequency offset\n", ssb_offset_point_a);
AssertFatal(sco % scs_scaling == 0, "ssb offset %d can create frequency offset\n", sco);
return ssb_offset_point_a; return ssb_offset_point_a;
} }
......
...@@ -202,7 +202,7 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB, ...@@ -202,7 +202,7 @@ uint32_t get_ssb_offset_to_pointA(uint32_t absoluteFrequencySSB,
uint32_t absoluteFrequencyPointA, uint32_t absoluteFrequencyPointA,
int ssbSubcarrierSpacing, int ssbSubcarrierSpacing,
int frequency_range); int frequency_range);
int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA); int get_ssb_subcarrier_offset(uint32_t absoluteFrequencySSB, uint32_t absoluteFrequencyPointA, int scs);
int get_delay_idx(int delay, int max_delay_comp); int get_delay_idx(int delay, int max_delay_comp);
void freq2time(uint16_t ofdm_symbol_size, void freq2time(uint16_t ofdm_symbol_size,
......
...@@ -347,10 +347,12 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp, ...@@ -347,10 +347,12 @@ int nr_init_frame_parms_ue(NR_DL_FRAME_PARMS *fp,
fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2; fp->freq_range = (fp->dl_CarrierFreq < 6e9)? nr_FR1 : nr_FR2;
uint8_t sco = 0; uint8_t sco = 0;
if (((fp->freq_range == nr_FR1) && (config->ssb_table.ssb_subcarrier_offset<24)) || if (((fp->freq_range == nr_FR1) && (config->ssb_table.ssb_subcarrier_offset < 24)) ||
((fp->freq_range == nr_FR2) && (config->ssb_table.ssb_subcarrier_offset<12)) ) { ((fp->freq_range == nr_FR2) && (config->ssb_table.ssb_subcarrier_offset < 12))) {
if (fp->freq_range == nr_FR1) if (fp->freq_range == nr_FR1)
sco = config->ssb_table.ssb_subcarrier_offset>>config->ssb_config.scs_common; sco = config->ssb_table.ssb_subcarrier_offset>>config->ssb_config.scs_common;
else
sco = config->ssb_table.ssb_subcarrier_offset;
} }
fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco); fp->ssb_start_subcarrier = (12 * config->ssb_table.ssb_offset_point_a + sco);
......
...@@ -639,7 +639,8 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant ...@@ -639,7 +639,8 @@ static void config_common(gNB_MAC_INST *nrmac, nr_pdsch_AntennaPorts_t pdsch_Ant
cfg->num_tlv++; cfg->num_tlv++;
cfg->ssb_table.ssb_subcarrier_offset.value = cfg->ssb_table.ssb_subcarrier_offset.value =
get_ssb_subcarrier_offset(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB, get_ssb_subcarrier_offset(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
*scc->ssbSubcarrierSpacing);
AssertFatal(cfg->ssb_table.ssb_subcarrier_offset.value < 16, AssertFatal(cfg->ssb_table.ssb_subcarrier_offset.value < 16,
"cannot handle ssb_subcarrier_offset %d resulting from Point A %ld SSB %ld: please increase dl_absoluteFrequencyPointA " "cannot handle ssb_subcarrier_offset %d resulting from Point A %ld SSB %ld: please increase dl_absoluteFrequencyPointA "
......
...@@ -1768,7 +1768,8 @@ NR_BCCH_BCH_Message_t *get_new_MIB_NR(const NR_ServingCellConfigCommon_t *scc) ...@@ -1768,7 +1768,8 @@ NR_BCCH_BCH_Message_t *get_new_MIB_NR(const NR_ServingCellConfigCommon_t *scc)
int ssb_subcarrier_offset = 31; // default value for NSA int ssb_subcarrier_offset = 31; // default value for NSA
if (get_softmodem_params()->sa) { if (get_softmodem_params()->sa) {
ssb_subcarrier_offset = get_ssb_subcarrier_offset(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB, ssb_subcarrier_offset = get_ssb_subcarrier_offset(*scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencySSB,
scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA); scc->downlinkConfigCommon->frequencyInfoDL->absoluteFrequencyPointA,
*scc->ssbSubcarrierSpacing);
} }
mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset & 15; mib->message.choice.mib->ssb_SubcarrierOffset = ssb_subcarrier_offset & 15;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment