This thread has been locked.

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:

    • 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++) {
            if (i < zero_padding || i >= FFT_LENGTH + zero_padding) {
                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++) {
            if (i < zero_padding || i >= FFT_LENGTH + zero_padding) {
                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

**Attention** This is a public forum