SSS detection used PSS phase, but when signal is noisy, use the PSS phase can make a SSS slightly rotated
the code use a precomputed table of rotations: 16 steaps between -PI/3 and +PI/3 This commit replaces the precomputed table by in code computation. This version improves code understanding, while it won't make any significant difference
This commit is contained in:
@@ -61,32 +61,6 @@
|
||||
|
||||
#define SSS_METRIC_FLOOR_NR (30000)
|
||||
|
||||
/************** VARIABLES *****************************************/
|
||||
|
||||
#define PHASE_HYPOTHESIS_NUMBER (16)
|
||||
#define INDEX_NO_PHASE_DIFFERENCE (3) /* this is for no phase shift case */
|
||||
|
||||
/************** FUNCTION ******************************************/
|
||||
|
||||
static const c16_t phase_nr[PHASE_HYPOTHESIS_NUMBER] = {
|
||||
// {pi/3 ---- pi/3, -pi/3 ---- pi/3}
|
||||
{16384, -28377},
|
||||
{20173, -25821},
|
||||
{23571, -22762},
|
||||
{26509, -19260},
|
||||
{28932, -15383},
|
||||
{30791, -11207},
|
||||
{32051, -6813},
|
||||
{32687, -2286},
|
||||
{32687, 2286},
|
||||
{32051, 6813},
|
||||
{30791, 11207},
|
||||
{28932, 15383},
|
||||
{26509, 19260},
|
||||
{23571, 22762},
|
||||
{20173, 25821},
|
||||
{16384, 28377}};
|
||||
|
||||
void init_context_sss_nr(int amp);
|
||||
void free_context_sss_nr(void);
|
||||
|
||||
|
||||
@@ -161,7 +161,6 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue,
|
||||
NR_DL_FRAME_PARMS *sl_fp = &ue->SL_UE_PHY_PARAMS.sl_frame_params;
|
||||
int16_t *d;
|
||||
uint16_t Nid1 = 0;
|
||||
uint8_t phase;
|
||||
c16_t *rxF_ext;
|
||||
|
||||
for (int aarx = 0; aarx < sl_fp->nb_antennas_rx; aarx++) {
|
||||
@@ -260,15 +259,16 @@ static void sl_nr_extract_sss(PHY_VARS_NR_UE *ue,
|
||||
c16_t *sss = &sss_ext[0][0][0];
|
||||
|
||||
for (uint16_t id1 = 0; id1 < SL_NR_NUM_IDs_IN_SSS; id1++) { // all possible SSS Nid1 values
|
||||
for (phase = 0; phase < sizeofArray(phase_nr); phase++) { // phase offset between PSS and SSS
|
||||
for (int phase = -15; phase < 16; phase += 2) { // phase offset between PSS and SSS
|
||||
|
||||
int32_t metric = 0, metric_re = 0;
|
||||
|
||||
const c64_t rot = (c64_t){round(cos(M_PI / 3 / 15 * (phase)) * 32767), round(sin(M_PI / 3 / 15 * (phase)) * 32767)};
|
||||
d = (int16_t *)&ue->SL_UE_PHY_PARAMS.init_params.sl_sss_for_sync[Nid2 * SL_NR_NUM_IDs_IN_SSS + id1];
|
||||
|
||||
// This is the inner product using one particular value of each unknown parameter
|
||||
for (int i = 0; i < SL_NR_SSS_SEQUENCE_LENGTH; i++) {
|
||||
metric_re += d[i] * (((int64_t)phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i) >> 15);
|
||||
// metric is only real part because sss is a pure real signal (imaginary is 0)
|
||||
metric_re += d[i] * ((rot.r * sss[i].r - rot.i * sss[i].i) >> 15);
|
||||
}
|
||||
|
||||
metric = metric_re;
|
||||
|
||||
@@ -251,20 +251,23 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
Nid1_end = Nid1_start + 1;
|
||||
}
|
||||
|
||||
for (int n1 = Nid1_start; n1 < Nid1_end; n1++) { // all possible Nid1 values
|
||||
for (int phase = 0; phase < sizeofArray(phase_nr); phase++) { // phase offset between PSS and SSS
|
||||
const int phase_to_try[] = {0, 2, -2, 4, -4, 6, -6, 8, -8, 10, -10, 12, -12, 14, -14};
|
||||
for (int idx = 0; idx < sizeofArray(phase_to_try); idx++) { // phase offset between PSS and SSS
|
||||
const c64_t rot =
|
||||
(c64_t){round(cos(M_PI / 3 / 15 * (phase_to_try[idx])) * 32767), round(sin(M_PI / 3 / 15 * (phase_to_try[idx])) * 32767)};
|
||||
for (int n1 = Nid1_start; n1 < Nid1_end; n1++) { // all possible Nid1 values
|
||||
int64_t metric = 0;
|
||||
int16_t *d = d_sss[Nid2][n1];
|
||||
// This is the inner product using one particular value of each unknown parameter
|
||||
for (int i = 0; i < LENGTH_SSS_NR; i++) {
|
||||
metric += d[i] * (phase_nr[phase].r * sss[i].r - phase_nr[phase].i * sss[i].i);
|
||||
// metric is only real part because sss is a pure real signal (imaginary is 0)
|
||||
metric += d[i] * (rot.r * sss[i].r - rot.i * sss[i].i);
|
||||
}
|
||||
metric >>= SCALING_METRIC_SSS_NR;
|
||||
// if the current metric is better than the last save it
|
||||
if (metric > *tot_metric) {
|
||||
*tot_metric = metric;
|
||||
*Nid_cell = Nid2 + (3 * n1);
|
||||
*phase_max = phase;
|
||||
*phase_max = idx;
|
||||
|
||||
#ifdef DEBUG_SSS_NR
|
||||
LOG_D(PHY,
|
||||
@@ -277,9 +280,13 @@ bool rx_sss_nr(const NR_DL_FRAME_PARMS *frame_parms,
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// we try progressively rotation between pss and sss
|
||||
// but pss and sss are in phase at emission
|
||||
// rotation means doppler variation, or very noisy pss detection
|
||||
if (*tot_metric >= SSS_METRIC_FLOOR_NR)
|
||||
break;
|
||||
}
|
||||
|
||||
#define SSS_METRIC_FLOOR_NR (30000)
|
||||
if (*tot_metric < SSS_METRIC_FLOOR_NR) {
|
||||
LOG_D(PHY,
|
||||
"Failed to detect SSS after PSS, metric of SSS %d, threshold to consider SSS valid %d, detected PCI: %d\n",
|
||||
|
||||
Reference in New Issue
Block a user