@@ -161,40 +161,61 @@ static int32_t calculate_left_null_compensation_of_peak(int32_t peak_index,
161161 return compensated_peak_index ;
162162}
163163
164-
165- static void calculate_dist_ifft (float * dist , float iq_tones_comb [2 * CONFIG_BT_CS_DE_NFFT_SIZE ])
164+ static void calculate_ifft_mag (float iq_tones_comb [2 * CONFIG_BT_CS_DE_NFFT_SIZE ])
166165{
166+ /* This function calculates the magnitude of the IFFT of the input IQ values.
167+ * Note that the result is written back to the input array.
168+ * Also note that the input array is a complex array of size CONFIG_BT_CS_DE_NFFT_SIZE
169+ * Odd indexes contain the real part and even indexes contain the imaginary part.
170+ *
171+ * To find the IFFT this the function uses FFT functions provided by the CMSIS-DSP library.
172+ * To calculate the IFFT using FFT the following steps can be used:
173+ * 1. Complex conjugate the input.
174+ * 2. Perform the FFT.
175+ * 3. Complex conjugate the output.
176+ * Since we are interested in the magnitude of the IFFT, we can skip step 3.
177+ * and directly calculate the magnitude of the output of step 2.
178+ */
167179
168180 /* Complex conjugate the input. */
169181 for (uint32_t i = 0 ; i < NUM_CHANNELS ; i ++ ) {
170182 iq_tones_comb [i * 2 + 1 ] = - iq_tones_comb [i * 2 + 1 ];
171183 }
172184
173- #if CONFIG_BT_CS_DE_NFFT_SIZE == 512
174- arm_cfft_f32 (& arm_cfft_sR_f32_len512 , iq_tones_comb , 0 , 1 );
175- #elif CONFIG_BT_CS_DE_NFFT_SIZE == 1024
176- arm_cfft_f32 (& arm_cfft_sR_f32_len1024 , iq_tones_comb , 0 , 1 );
177- #elif CONFIG_BT_CS_DE_NFFT_SIZE == 2048
178- arm_cfft_f32 (& arm_cfft_sR_f32_len2048 , iq_tones_comb , 0 , 1 );
179- #else
180- #error
181- #endif
182-
183- /* Compute the magnitude of iq_tones_comb[0:2*CONFIG_BT_CS_DE_NFFT_SIZE - 1], store output
184- * in iq_tones_comb[0:CONFIG_BT_CS_DE_NFFT_SIZE - 1]
185+ /* Perform the FFT. */
186+ #if CONFIG_BT_CS_DE_NFFT_SIZE == 512
187+ arm_cfft_f32 (& arm_cfft_sR_f32_len512 , iq_tones_comb , 0 , 1 );
188+ #elif CONFIG_BT_CS_DE_NFFT_SIZE == 1024
189+ arm_cfft_f32 (& arm_cfft_sR_f32_len1024 , iq_tones_comb , 0 , 1 );
190+ #elif CONFIG_BT_CS_DE_NFFT_SIZE == 2048
191+ arm_cfft_f32 (& arm_cfft_sR_f32_len2048 , iq_tones_comb , 0 , 1 );
192+ #else
193+ #error
194+ #endif
195+
196+ /* Compute the magnitude of complex values in
197+ * iq_tones_comb[0:2*CONFIG_BT_CS_DE_NFFT_SIZE - 1]
198+ * and scale by 1/CONFIG_BT_CS_DE_NFFT_SIZE.
199+ * Store output in iq_tones_comb[0:CONFIG_BT_CS_DE_NFFT_SIZE - 1]
185200 */
186201 for (uint32_t n = 0 ; n < CONFIG_BT_CS_DE_NFFT_SIZE ; n ++ ) {
187202 float realIn = iq_tones_comb [2 * n ] / CONFIG_BT_CS_DE_NFFT_SIZE ;
188203 float imagIn = iq_tones_comb [(2 * n ) + 1 ] / CONFIG_BT_CS_DE_NFFT_SIZE ;
189204
190205 arm_sqrt_f32 ((realIn * realIn ) + (imagIn * imagIn ), & iq_tones_comb [n ]);
191206 }
207+ }
192208
193- /* The iq_tones_comb array now contains the ifft_mag in the indices
194- * [0:CONFIG_BT_CS_DE_NFFT_SIZE-1]
209+ static uint32_t find_ifft_peak_index (float ifft_mag [2 * CONFIG_BT_CS_DE_NFFT_SIZE ])
210+ {
211+ /* This function tries to find the peak index of the input IFFT magnitude.
212+ *
213+ * The function uses the following approach:
214+ * 1. Find the index of the strongest peak,
215+ * corresponding to the maximum value in the IFFT magnitude.
216+ * 2. Search for strong peaks closer than the max peak.
217+ * 3. When applicable: Compensate peak based on left null location.
195218 */
196- float * ifft_mag = iq_tones_comb ;
197-
198219 uint32_t ifft_mag_max_index ;
199220 float ifft_mag_max ;
200221
@@ -230,7 +251,28 @@ static void calculate_dist_ifft(float *dist, float iq_tones_comb[2 * CONFIG_BT_C
230251 calculate_left_null_compensation_of_peak (shortest_path_idx , ifft_mag );
231252 }
232253
233- * dist = calculate_ifft_peak_index_to_distance (compensated_peak_index , ifft_mag );
254+ return compensated_peak_index ;
255+ }
256+
257+ static void calculate_dist_ifft (float * dist , float iq_tones_comb [2 * CONFIG_BT_CS_DE_NFFT_SIZE ])
258+ {
259+ /* This function calculates a distance estimate
260+ * based on the IFFT magnitude of the input IQ values.
261+ *
262+ * To do this the function uses the following steps:
263+ * 1. Calculate the IFFT magnitude of the input IQ values.
264+ * 2. Find index of the peak in the IFFT magnitude which is believed
265+ * to correspond to the path with the shortest propagattion time.
266+ * 3. Convert the peak index to a distance estimate.
267+ */
268+ calculate_ifft_mag (iq_tones_comb );
269+
270+ /* The input IQ values are overwritten with the IFFT magnitude. */
271+ float * ifft_mag = iq_tones_comb ;
272+
273+ uint32_t ifft_peak_index = find_ifft_peak_index (ifft_mag );
274+
275+ * dist = calculate_ifft_peak_index_to_distance (ifft_peak_index , ifft_mag );
234276}
235277
236278static void calculate_dist_rtt (cs_de_report_t * p_report )
0 commit comments