If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

# MSP430FR5994: Applying FFT using DSPLib on MSP430FR5994

Part Number: MSP430FR5994
Other Parts Discussed in Thread: BOOSTXL-AUDIO,

Tool/software:

Hello,
I am working on The MSP430FR5994 to applu FFT on captured signal using BOOSTXL-AUDIO, so after doing the signal acquisition I am applyting the function `runFftWithLea on the voice signal Buffer `, the function is designed to perform a Fast Fourier Transform (FFT) on segments of a buffer containing 16-bit unsigned integer (uint16_t) samples. So the logic behinf this function is

•           The function processes the input buffer in segments (`taille_totale` indicates the total size of the buffer).
• For each segment, the function calculates the mean value to center the data around zero. This helps in reducing DC offset in the signal.

• Zero padding is applied symmetrically around the segment to improve FFT resolution. This involves adding zeros before and after the actual data segment.
• Data Preparation:

• The data is prepared for FFT by converting the 16-bit unsigned integers to `_q15` format, which is a fixed-point representation used in DSP. This involves centering the data around zero and scaling.
• FFT Computation:

• The complex FFT is applied to the prepared data using the LEA module. This transforms the time-domain data into the frequency domain.
• Magnitude Calculation:

• For each FFT coefficient, the magnitude is computed. This involves calculating the square of the real and imaginary parts, summing them, and then taking the square root.
• The magnitude is approximated due to the fixed-point representation constraints.
• Magnitude Conversion and Transmission:

• The magnitudes are converted from `_q15` format to `uint16_t` for easier interpretation and transmission.
• The magnitudes are then sent via UART for further processing or display.

The problem is BuffCopy1 and buffCopy are not filled and basically the FFT is not returning any values

```#pragma PERSISTENT(buffCopy1);
uint16_t buffCopy1[FFT_LENGTH] = {0};
DSPLIB_DATA(buffCopy, MSP_ALIGN_CMPLX_FFT_Q15(FFT_LENGTH))
_q15 buffCopy[FFT_LENGTH * 2];

DSPLIB_DATA(magnitude_q15, 4)
_q15 magnitude_q15[FFT_LENGTH];

DSPLIB_DATA(magnitude_uint16, 4)
uint16_t magnitude_uint16[FFT_LENGTH];
/* Hamming window parameters */

int32_t real_sq, imag_sq;

msp_status status;
//static msp_mpy_q15_params mpyParams;
msp_fft_q15_params fftParams;

void runFftWithLea(uint16_t *buffer, int taille_totale) {

uint16_t i;
int position = 0;
//uint16_t shift;
//int16_t inter, real1, imag1;
_q15 real, imag, real_squared, imag_squared, sum_of_squares, magnitude;
fftParams.length = FFT_LENGTH;
fftParams.bitReverse = 1;
fftParams.twiddleTable =  msp_cmplx_twiddle_table_256_q15;

uint16_t b;

// Initialiser le module LEA et les paramètres de la FFT
msp_lea_init();

initUART();

while (position < taille_totale) {
// Calculer la moyenne des valeurs dans le segment
float moyenne = 0;
uint16_t m;
for (i = 0; i < taille_totale; i++) {
//if (position + i < taille_totale) {
moyenne += buffer[position + i];
//}
}
moyenne /= FFT_LENGTH;
m= (uint16_t)round (moyenne);

// Copier le segment de 128 échantillons dans buffCopy1 avec zero-padding symétrique
int zero_padding = 64; // Nombre de zéros à ajouter de chaque côté

for (i = 0; i < FFT_LENGTH + 2 * zero_padding; i++) {
buffCopy1[i] = 0; // Remplissage zéro
} else {
b = (buffer[position + i - zero_padding]);
buffCopy1[i] = b - m;
}
}
int j=0;
for (j = 0; j < 256; j++) {
// Convertir la valeur uint16_t en _q15
// Soustraire 2048 pour centrer autour de 0
// Multiplier par 16 pour utiliser toute la plage _q15
int32_t temp = ((int32_t)buffCopy1[i] - 2048) * 16;

// Saturer à la plage _q15 (-32768 à 32767)
if (temp > 32767) temp = 32767;
if (temp < -32768) temp = -32768;

buffCopy[i] = (int16_t)temp;
}

// Appliquer la FFT complexe sur le segment buffCopy
status = msp_cmplx_fft_fixed_q15(&fftParams, buffCopy);//la il y'a un probleme
msp_checkStatus(status);

// Calculer la magnitude pour chaque coefficient FFT
for (i = 0; i < FFT_LENGTH; i++) {
real = buffCopy[2 * i];
imag = buffCopy[2 * i + 1];

// Calculer le carré de la partie réelle et imaginaire
real_squared = __q15mpy(real, real); // Utilisation de la multiplication Q15
imag_squared = __q15mpy(imag, imag);

// Calculer la somme des carrés avec saturation
sum_of_squares = real_squared + imag_squared;

// Calculer la magnitude comme racine carrée (approximative)
// Ici, sqrt est approximée par une simple division et ajustement de la précision
magnitude = (_q15)sqrt(sum_of_squares); // Convertir en _q15

magnitude_q15[i] = magnitude;
}

// Convertir les valeurs de magnitude en uint16_t
for (i = 0; i < FFT_LENGTH; i++) {
// Convertir _q15 (plage -1 à 1) à uint16_t (plage 0 à 4096)
magnitude_uint16[i] = (uint16_t)((magnitude_q15[i] * MAX_VALUE)>>15);
}

UART_sendBuffer(magnitude_uint16, FFT_LENGTH);

position += FFT_LENGTH;

}
}

void runFftWithLea(uint16_t *buffer, int taille_totale) {

uint16_t i;
int position = 0;
//uint16_t shift;
//int16_t inter, real1, imag1;
_q15 real, imag, real_squared, imag_squared, sum_of_squares, magnitude;
fftParams.length = FFT_LENGTH;
fftParams.bitReverse = 1;
fftParams.twiddleTable =  msp_cmplx_twiddle_table_256_q15;

uint16_t b;

// Initialiser le module LEA et les paramètres de la FFT
msp_lea_init();

initUART();

while (position < taille_totale) {
// Calculer la moyenne des valeurs dans le segment
float moyenne = 0;
uint16_t m;
for (i = 0; i < taille_totale; i++) {
//if (position + i < taille_totale) {
moyenne += buffer[position + i];
//}
}
moyenne /= FFT_LENGTH;
m= (uint16_t)round (moyenne);

// Copier le segment de 128 échantillons dans buffCopy1 avec zero-padding symétrique
int zero_padding = 64; // Nombre de zéros à ajouter de chaque côté

for (i = 0; i < FFT_LENGTH + 2 * zero_padding; i++) {
buffCopy1[i] = 0; // Remplissage zéro
} else {
b = (buffer[position + i - zero_padding]);
buffCopy1[i] = b - m;
}
}
int j=0;
for (j = 0; j < 256; j++) {
// Convertir la valeur uint16_t en _q15
// Soustraire 2048 pour centrer autour de 0
// Multiplier par 16 pour utiliser toute la plage _q15
int32_t temp = ((int32_t)buffCopy1[i] - 2048) * 16;

// Saturer à la plage _q15 (-32768 à 32767)
if (temp > 32767) temp = 32767;
if (temp < -32768) temp = -32768;

buffCopy[i] = (int16_t)temp;
}

// Appliquer la FFT complexe sur le segment buffCopy
status = msp_cmplx_fft_fixed_q15(&fftParams, buffCopy);//la il y'a un probleme
msp_checkStatus(status);

// Calculer la magnitude pour chaque coefficient FFT
for (i = 0; i < FFT_LENGTH; i++) {
real = buffCopy[2 * i];
imag = buffCopy[2 * i + 1];

// Calculer le carré de la partie réelle et imaginaire
real_squared = __q15mpy(real, real); // Utilisation de la multiplication Q15
imag_squared = __q15mpy(imag, imag);

// Calculer la somme des carrés avec saturation
sum_of_squares = real_squared + imag_squared;

// Calculer la magnitude comme racine carrée (approximative)
// Ici, sqrt est approximée par une simple division et ajustement de la précision
magnitude = (_q15)sqrt(sum_of_squares); // Convertir en _q15

magnitude_q15[i] = magnitude;
}

// Convertir les valeurs de magnitude en uint16_t
for (i = 0; i < FFT_LENGTH; i++) {
// Convertir _q15 (plage -1 à 1) à uint16_t (plage 0 à 4096)
magnitude_uint16[i] = (uint16_t)((magnitude_q15[i] * MAX_VALUE)>>15);
}

UART_sendBuffer(magnitude_uint16, FFT_LENGTH);

position += FFT_LENGTH;

}
}```

Here is the code.If there is any missing configuration or error in the code could you please tell me

• >  int32_t temp = ((int32_t)buffCopy1[i] - 2048) * 16;

>  buffCopy[i] = (int16_t)temp;

I suspect you intended "[j]" rather than "[i]" here.

• Thank you!
yup this was an error that I fixed but I rectified it.
but despite of that there has been always a problem in the bufferCopy filling.

• What does your program do now that you fixed this?

The quickest way to narrow this down would be to use the debugger to step through the loops and see if your arrays are changing as you expect.

**Attention** This is a public forum