merge timing_advance_offset and timing_advance_offset_ns computation

This commit is contained in:
Rakesh Mundlamuri
2026-01-09 16:58:34 +05:30
parent b378acf2e0
commit 1b974c6ab2
7 changed files with 132 additions and 58 deletions
@@ -36,52 +36,73 @@
#define I0_SKIP_DC 1
int nr_est_timing_advance_srs(const NR_DL_FRAME_PARMS *frame_parms,
const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size])
void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
uint8_t ant,
uint8_t N_ap,
uint32_t samples_per_frame,
uint16_t *ta_offset,
int16_t *ta_offset_nsec)
{
int timing_advance = 0;
int max_val = 0;
for (int i = 0; i < NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size; i++) {
int temp = 0;
for (int aa = 0; aa < frame_parms->nb_antennas_rx; aa++) {
int Re = ((c16_t*)srs_estimated_channel_time[aa])[i].r;
int Im = ((c16_t*)srs_estimated_channel_time[aa])[i].i;
temp += (Re*Re/2) + (Im*Im/2);
int64_t mean_val = 0;
int64_t max_val = 0;
int32_t max_idx = 0;
int16_t srs_toa = 0;
int16_t ofdm_os_size = NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size;
for (int k = 0; k < ofdm_os_size; k++) {
int64_t abs_val = 0;
for (int p_index = 0; p_index < N_ap; p_index++) {
abs_val += squaredMod(srs_estimated_channel_time[p_index][k]);
}
if (temp > max_val) {
timing_advance = i;
max_val = temp;
mean_val += abs_val;
if (abs_val > max_val) {
max_val = abs_val;
max_idx = k;
}
}
max_val = max_val / N_ap;
mean_val = mean_val / (N_ap * ofdm_os_size);
if (timing_advance > (NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size) / 2) {
timing_advance = timing_advance - (NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size);
}
timing_advance = timing_advance / NR_SRS_IDFT_OVERSAMP_FACTOR;
if (max_idx > ofdm_os_size >> 1)
max_idx = max_idx - ofdm_os_size;
LOG_I(NR_PHY, "Estimated SRS ToA %d\n", timing_advance);
// Check for detection threshold
if ((mean_val != 0) && (max_val / mean_val > NR_SRS_DETECTION_THRESHOLD)) {
srs_toa = max_idx / NR_SRS_IDFT_OVERSAMP_FACTOR;
// Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
const uint16_t bw_scaling = frame_parms->ofdm_symbol_size >> 7;
// restrict the computation of ta_offset to antenna 0
if (ant == 0) {
// Scale the 16 factor in N_TA calculation in 38.213 section 4.2 according to the used FFT size
const uint16_t bw_scaling = ofdm_symbol_size >> 7;
// do some integer rounding to improve TA accuracy
int sync_pos_rounded;
if (timing_advance > 0) {
sync_pos_rounded = timing_advance + (bw_scaling >> 1) - 1;
// do some integer rounding to improve TA accuracy
int sync_pos_rounded;
if (srs_toa > 0) {
sync_pos_rounded = srs_toa + (bw_scaling >> 1) - 1;
} else {
sync_pos_rounded = srs_toa - (bw_scaling >> 1) + 1;
}
*ta_offset = sync_pos_rounded / bw_scaling;
// put timing advance command in 0..63 range
*ta_offset = BOUNDED_EVAL(0, *ta_offset + 31, 63);
}
*ta_offset_nsec = (max_idx * 1e9) / (NR_SRS_IDFT_OVERSAMP_FACTOR * samples_per_frame * 100);
} else {
sync_pos_rounded = timing_advance - (bw_scaling >> 1) + 1;
*ta_offset = 0xFFFF;
*ta_offset_nsec = 0x8000;
}
int timing_advance_update = sync_pos_rounded / bw_scaling;
// put timing advance command in 0..63 range
timing_advance_update += 31;
if (timing_advance_update < 0) timing_advance_update = 0;
if (timing_advance_update > 63) timing_advance_update = 63;
return timing_advance_update;
LOG_D(NR_PHY,
"SRS estimatd ToA %d [RX ant %d]: TA offset %d, TA offset ns %d (max_val %ld, mean_val %ld, max_idx %d)\n",
srs_toa,
ant,
*ta_offset,
*ta_offset_nsec,
max_val,
mean_val,
max_idx);
}
void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB) {
@@ -59,9 +59,13 @@ void dump_nr_I0_stats(FILE *fd,PHY_VARS_gNB *gNB);
void gNB_I0_measurements(PHY_VARS_gNB *gNB, int slot, int first_symb, int num_symb, uint32_t rb_mask_ul[14][9]);
int nr_est_timing_advance_srs(
const NR_DL_FRAME_PARMS *frame_parms,
const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * frame_parms->ofdm_symbol_size]);
void nr_est_srs_timing_advance_offset(uint16_t ofdm_symbol_size,
const c16_t srs_estimated_channel_time[][NR_SRS_IDFT_OVERSAMP_FACTOR * ofdm_symbol_size],
uint8_t ant,
uint8_t N_ap,
uint32_t samples_per_frame,
uint16_t *timing_advance_offset,
int16_t *timing_advance_offset_nsec);
void nr_pusch_ptrs_processing(PHY_VARS_gNB *gNB,
NR_DL_FRAME_PARMS *frame_parms,