diff --git a/src/UpperPHY/ChannelEstimation/arm_channel_estimation.cpp b/src/UpperPHY/ChannelEstimation/arm_channel_estimation.cpp index e31b12fc85b19868b1dd4d916effc85dd089cef6..f4039fe705252aeff646c44ad9f6dc89eb6b3c78 100644 --- a/src/UpperPHY/ChannelEstimation/arm_channel_estimation.cpp +++ b/src/UpperPHY/ChannelEstimation/arm_channel_estimation.cpp @@ -361,26 +361,32 @@ lmmse_f32(armral_cmplx_f32_t *p_src_x, armral_cmplx_f32_t *p_src_y, return ARMRAL_SUCCESS; } +// Interpolate values for the target symbol from pilot symbols void linear_interpolation_f32(armral_cmplx_f32_t *pilot_1, armral_cmplx_f32_t *pilot_2, armral_cmplx_f32_t *target_re, uint16_t rows, uint16_t cols, uint16_t pilot_1_idx, uint16_t pilot_2_idx, uint16_t target_idx) { - for (uint16_t i = 0; i < rows * cols; i++) { - float32_t slope_re = - (pilot_2[i].re - pilot_1[i].re) / (pilot_2_idx - pilot_1_idx); - float32_t slope_im = - (pilot_2[i].im - pilot_1[i].im) / (pilot_2_idx - pilot_1_idx); - target_re[i].re = pilot_1[i].re + slope_re * (target_idx - pilot_1_idx); - target_re[i].im = pilot_1[i].im + slope_im * (target_idx - pilot_1_idx); + float32_t m_denom = 1.0 / (pilot_2_idx - pilot_1_idx); + float32_t t_x = (target_idx - pilot_1_idx); + uint16_t idx = 0; + + for (uint16_t i = (rows * cols); i > 0; i--) { + float32_t slope_re = (pilot_2[idx].re - pilot_1[idx].re) * m_denom; + float32_t slope_im = (pilot_2[idx].im - pilot_1[idx].im) * m_denom; + target_re[idx].re = pilot_1[idx].re + slope_re * t_x; + target_re[idx].im = pilot_1[idx].im + slope_im * t_x; + idx++; } } // If there is only one pilot symbol copy it to the rest of the REs void copy_pilot_f32(armral_cmplx_f32_t *pilot_re, armral_cmplx_f32_t *target_re, uint16_t rows, uint16_t cols) { - for (uint16_t i = 0; i < rows * cols; i++) { + uint16_t i = 0; + for (uint16_t j = rows * cols; j > 0; j--) { target_re[i] = pilot_re[i]; + i++; } } @@ -393,11 +399,13 @@ void linear_interpolation_per_dimension_f32( uint16_t pilot_idx; uint32_t pilot1_re_idx = pilot_indices[0] * re_idx_stride + re_idx_offset; uint32_t pilot2_re_idx = pilot_indices[1] * re_idx_stride + re_idx_offset; - for (uint16_t idx = 0; idx < pilot_indices[0]; idx++) { + uint16_t idx = 0; + for (uint16_t j = pilot_indices[0]; j > 0; j--) { uint32_t re_idx = idx * re_idx_stride + re_idx_offset; linear_interpolation_f32(p_dst_h + pilot1_re_idx, p_dst_h + pilot2_re_idx, p_dst_h + re_idx, rows, cols, pilot_indices[0], pilot_indices[1], idx); + idx++; } // Interpolation between first and last pilot @@ -405,8 +413,8 @@ void linear_interpolation_per_dimension_f32( pilot1_re_idx = pilot_indices[pilot_idx] * re_idx_stride + re_idx_offset; pilot2_re_idx = pilot_indices[pilot_idx + 1] * re_idx_stride + re_idx_offset; - for (uint16_t idx = pilot_indices[pilot_idx] + 1; - idx < pilot_indices[pilot_idx + 1]; idx++) { + for (idx = pilot_indices[pilot_idx] + 1; idx < pilot_indices[pilot_idx + 1]; + idx++) { uint32_t re_idx = idx * re_idx_stride + re_idx_offset; linear_interpolation_f32(p_dst_h + pilot1_re_idx, p_dst_h + pilot2_re_idx, p_dst_h + re_idx, rows, cols, @@ -418,12 +426,15 @@ void linear_interpolation_per_dimension_f32( // Extrapolation after last pilots pilot1_re_idx = pilot_indices[pilot_idx - 1] * re_idx_stride + re_idx_offset; pilot2_re_idx = pilot_indices[pilot_idx] * re_idx_stride + re_idx_offset; - for (uint16_t idx = pilot_indices[pilot_idx] + 1; idx < max_idx; idx++) { + idx = pilot_indices[pilot_idx] + 1; + uint16_t loop_count = max_idx - (pilot_indices[pilot_idx] + 1); + for (uint16_t j = loop_count; j > 0; j--) { uint32_t re_idx = idx * re_idx_stride + re_idx_offset; linear_interpolation_f32(p_dst_h + pilot1_re_idx, p_dst_h + pilot2_re_idx, p_dst_h + re_idx, rows, cols, pilot_indices[pilot_idx - 1], pilot_indices[pilot_idx], idx); + idx++; } } @@ -436,15 +447,20 @@ void copy_pilot_per_dimension_f32(armral_cmplx_f32_t *p_dst_h, uint32_t pilot_re_idx = pilot_idx * re_idx_stride + re_idx_offset; // REs before the pilot - for (uint16_t idx = 0; idx < pilot_idx; idx++) { + uint16_t idx = 0; + for (uint16_t j = pilot_idx; j > 0; j--) { uint32_t re_idx = idx * re_idx_stride + re_idx_offset; copy_pilot_f32(p_dst_h + pilot_re_idx, p_dst_h + re_idx, rows, cols); + idx++; } // REs after the pilot - for (uint16_t idx = pilot_idx + 1; idx < max_idx; idx++) { + idx = pilot_idx + 1; + uint16_t loop_count1 = max_idx - pilot_idx - 1; + for (uint16_t j = loop_count1; j > 0; j--) { uint32_t re_idx = idx * re_idx_stride + re_idx_offset; copy_pilot_f32(p_dst_h + pilot_re_idx, p_dst_h + re_idx, rows, cols); + idx++; } }