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
|
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;
|
ul_freq_offset = -ul_freq_offset;
|
||||||
for (int i = 0; i < fp->nb_antennas_tx; i++)
|
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);
|
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);
|
dft_size_idx_t dftsize = get_dft(frame_parms->ofdm_symbol_size);
|
||||||
// This is for misalignment issues
|
// 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 rx_offset = frame_parms->get_samples_slot_timestamp(slot, frame_parms, 0);
|
||||||
unsigned int abs_symbol = slot * frame_parms->symbols_per_slot + symbol;
|
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
|
// use OFDM symbol from within 1/8th of the CP to avoid ISI
|
||||||
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
|
rx_offset -= (nb_prefix_samples / frame_parms->ofdm_offset_divisor);
|
||||||
|
|
||||||
for (unsigned char aa=0; aa<frame_parms->nb_antennas_rx; aa++) {
|
rx_offset %= total_samples;
|
||||||
int16_t *rxdata_ptr = (int16_t *)&rxdata[aa][rx_offset];
|
|
||||||
|
|
||||||
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
|
// This happens only during initial sync
|
||||||
if (rx_offset + frame_parms->ofdm_symbol_size > total_samples) {
|
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],
|
memcpy((void *)&tmp_dft_in[total_samples - rx_offset],
|
||||||
(void *)&rxdata[aa][0],
|
(void *)&rxdata[aa][0],
|
||||||
(frame_parms->ofdm_symbol_size - (total_samples - rx_offset)) * sizeof(int32_t));
|
(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
|
} 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));
|
memcpy((void *)&tmp_dft_in[0], (void *)&rxdata[aa][rx_offset], frame_parms->ofdm_symbol_size * sizeof(int32_t));
|
||||||
|
rxdata_ptr = tmp_dft_in;
|
||||||
rxdata_ptr = (int16_t *)tmp_dft_in;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ue && ue->cont_fo_comp) {
|
if (ue && ue->cont_fo_comp) {
|
||||||
start_meas_nr_ue_phy(ue, RX_FO_COMPENSATION_STATS);
|
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);
|
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);
|
start_meas_nr_ue_phy(ue, RX_DFT_STATS);
|
||||||
|
|
||||||
dft(dftsize,
|
dft(dftsize,
|
||||||
rxdata_ptr,
|
(int16_t *)rxdata_ptr,
|
||||||
(int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
(int16_t *)&rxdataF[aa][frame_parms->ofdm_symbol_size*symbol],
|
||||||
1);
|
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 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);
|
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);
|
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
|
#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);
|
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);
|
const double phase_inc = -fo_Hz / (samples_per_ms * 1000);
|
||||||
double phase = sample_offset * phase_inc;
|
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);
|
const c16_t rot_vec = get_sin_cos(CHUNK * phase_inc);
|
||||||
while (size > CHUNK) {
|
while (size > CHUNK) {
|
||||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, CHUNK, 14);
|
mult_complex_vectors(rxdata_in, rot, rxdata_out, CHUNK, 14);
|
||||||
rxdata_ptr += CHUNK;
|
|
||||||
rotate_cpx_vector(rot, &rot_vec, rot, CHUNK, 14);
|
rotate_cpx_vector(rot, &rot_vec, rot, CHUNK, 14);
|
||||||
|
rxdata_in += CHUNK;
|
||||||
|
rxdata_out += CHUNK;
|
||||||
size -= CHUNK;
|
size -= CHUNK;
|
||||||
}
|
}
|
||||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, size, 14);
|
mult_complex_vectors(rxdata_in, rot, rxdata_out, size, 14);
|
||||||
#else
|
#else
|
||||||
// This code path computes the complex rotation values for the complete OFDM symbol using get_sin_cos().
|
// 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.
|
// 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);
|
rot[i] = get_sin_cos(phase);
|
||||||
phase += phase_inc;
|
phase += phase_inc;
|
||||||
}
|
}
|
||||||
mult_complex_vectors(rxdata_ptr, rot, rxdata_ptr, size, 14);
|
mult_complex_vectors(rxdata_in, rot, rxdata_out, size, 14);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user