NR UE: in nr_slot_fep() perform FO compensation in local tmp_dft_in array instead of global rxdata array
This avoids problems if nr_slot_fep() is called more than once for an OFDM symbol.
This commit is contained in:
+1
-1
@@ -563,7 +563,7 @@ static void RU_write(nr_rxtx_thread_data_t *rxtxD, bool sl_tx_action)
|
||||
if (get_nrUE_params()->cont_fo_comp == 2) // different from LO frequency error compensation, Doppler UL pre-compensation has to be negative
|
||||
ul_freq_offset = -ul_freq_offset;
|
||||
for (int i = 0; i < fp->nb_antennas_tx; i++)
|
||||
nr_fo_compensation(ul_freq_offset, fp->samples_per_subframe, writeTimestamp, txp[i], writeBlockSize);
|
||||
nr_fo_compensation(ul_freq_offset, fp->samples_per_subframe, writeTimestamp, txp[i], txp[i], writeBlockSize);
|
||||
}
|
||||
|
||||
int tmp = openair0_write_reorder(&UE->rfdevice, writeTimestamp, txp, writeBlockSize, fp->nb_antennas_tx, flags);
|
||||
|
||||
@@ -60,7 +60,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
|
||||
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
|
||||
// This is for misalignment issues
|
||||
int32_t tmp_dft_in[8192] __attribute__ ((aligned (32)));
|
||||
c16_t tmp_dft_in[frame_parms->ofdm_symbol_size] __attribute__ ((aligned (32)));
|
||||
|
||||
unsigned int rx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||
unsigned int abs_symbol = slot * frame_parms->symbols_per_slot + symbol;
|
||||
@@ -73,10 +73,10 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
// use OFDM symbol from within 1/8th of the CP to avoid ISI
|
||||
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
|
||||
|
||||
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
int16_t *rxdata_ptr = (int16_t *)&rxdata[aa][rx_offset];
|
||||
rx_offset %= total_samples;
|
||||
|
||||
rx_offset %= total_samples;
|
||||
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
||||
c16_t *rxdata_ptr = &rxdata[aa][rx_offset];
|
||||
|
||||
// This happens only during initial sync
|
||||
if (rx_offset + frame_parms->ofdm_symbol_size > total_samples) {
|
||||
@@ -87,17 +87,17 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
memcpy((void *)&tmp_dft_in[total_samples - rx_offset],
|
||||
(void *)&rxdata[aa][0],
|
||||
(frame_parms->ofdm_symbol_size - (total_samples - rx_offset)) * sizeof(int32_t));
|
||||
rxdata_ptr = (int16_t *)tmp_dft_in;
|
||||
rxdata_ptr = tmp_dft_in;
|
||||
|
||||
} else if ((rx_offset & 7) != 0) { // if input to dft is not 256-bit aligned
|
||||
memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size * sizeof(int32_t));
|
||||
|
||||
rxdata_ptr = (int16_t *)tmp_dft_in;
|
||||
rxdata_ptr = tmp_dft_in;
|
||||
}
|
||||
|
||||
if (ue && ue->cont_fo_comp) {
|
||||
start_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS);
|
||||
nr_fo_compensation(ue->freq_offset, frame_parms->samples_per_subframe, rx_offset, (c16_t *)rxdata_ptr, frame_parms->ofdm_symbol_size);
|
||||
nr_fo_compensation(ue->freq_offset, frame_parms->samples_per_subframe, rx_offset, rxdata_ptr, tmp_dft_in, frame_parms->ofdm_symbol_size);
|
||||
rxdata_ptr = tmp_dft_in;
|
||||
stop_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ int nr_slot_fep(PHY_VARS_NR_UE *ue,
|
||||
start_meas_nr_ue_phy(ue, RX_DFT_STATS);
|
||||
|
||||
dft(dftsize,
|
||||
rxdata_ptr,
|
||||
(int16_t *)rxdata_ptr,
|
||||
(int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||
1);
|
||||
|
||||
|
||||
@@ -80,6 +80,6 @@ void nr_256qam_llr(int32_t *rxdataF_comp, int32_t *ch_mag, int32_t *ch_mag2, int
|
||||
void freq2time(uint16_t ofdm_symbol_size, int16_t *freq_signal, int16_t *time_signal);
|
||||
void nr_est_delay(int ofdm_symbol_size, const c16_t *ls_est, c16_t *ch_estimates_time, delay_t *delay);
|
||||
unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, int nb_rb);
|
||||
void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, c16_t *rxdata_ptr, int size);
|
||||
void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, const c16_t *rxdata_in, c16_t *rxdata_out, int size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -454,7 +454,7 @@ unsigned int nr_get_tx_amp(int power_dBm, int power_max_dBm, int total_nb_rb, in
|
||||
return (0);
|
||||
}
|
||||
|
||||
void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, c16_t *rxdata_ptr, int size)
|
||||
void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, const c16_t *rxdata_in, c16_t *rxdata_out, int size)
|
||||
{
|
||||
const double phase_inc = -fo_Hz / (samples_per_ms * 1000);
|
||||
double phase = sample_offset * phase_inc;
|
||||
@@ -473,12 +473,13 @@ void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, c16
|
||||
}
|
||||
const c16_t rot_vec = get_sin_cos(CHUNK * phase_inc);
|
||||
while (size > CHUNK) {
|
||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, CHUNK, 14);
|
||||
rxdata_ptr += CHUNK;
|
||||
mult_complex_vectors(rxdata_in, rot, rxdata_out, CHUNK, 14);
|
||||
rotate_cpx_vector(rot, &rot_vec, rot, CHUNK, 14);
|
||||
rxdata_in += CHUNK;
|
||||
rxdata_out += CHUNK;
|
||||
size -= CHUNK;
|
||||
}
|
||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, size, 14);
|
||||
mult_complex_vectors(rxdata_in, rot, rxdata_out, size, 14);
|
||||
#else
|
||||
// This code path computes the complex rotation values for the complete OFDM symbol using get_sin_cos().
|
||||
// This is more accurate, but also slower than the code path above.
|
||||
@@ -487,6 +488,6 @@ void nr_fo_compensation(double fo_Hz, int samples_per_ms, int sample_offset, c16
|
||||
rot[i] = get_sin_cos(phase);
|
||||
phase += phase_inc;
|
||||
}
|
||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, size, 14);
|
||||
mult_complex_vectors(rxdata_in, rot, rxdata_out, size, 14);
|
||||
#endif
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user