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.

TMS320F28377S: Issue while performing 256 points RFFT using 128 points complex FFT

Part Number: TMS320F28377S
Other Parts Discussed in Thread: C2000WARE

I have successfully implemented 32 & 128 point Real FFTs using the VCU2 library.  The 128 point RFFT was performed using 64 point CFFT. Now we need to increase the points to 256 so I am working on 128 points complex FFT. I have allocated an input and output buffer aligned to 256 in the RAM. The declarations are as below:

//Input buffer is allocated to 256 words aligned section in RAM
#pragma DATA_SECTION(Vgrid_FFT_in_buf,"buffer1")
int16_t Vgrid_FFT_in_buf[256];
//Output buffer is allocated to 256 words aligned section in RAM
#pragma DATA_SECTION(Vgrid_FFT_out_buf,"buffer2")
int16_t Vgrid_FFT_out_buf[256];

The sections are defined in the linker file as below:

     /* Allocate twiddle factors area: */
   twiddleFactors   : > FLASHA_N,        PAGE = 0
   /*Allocate areas for 32 points RFFT input and output buffers*/
   buffer1          : > RAMLS_PROG, ALIGN = 256, PAGE = 0
   buffer2          : > RAMLS_PROG, ALIGN = 256, PAGE = 0

The FFT handler is initialized as below:

CFFT.pInBuffer = Vgrid_FFT_in_buf;
    CFFT.pOutBuffer = Vgrid_FFT_out_buf;
    CFFT.init = (void (*)(void*)) CFFT_init128Pt;
    CFFT.run = (void (*)(void*)) CFFT_run128Pt;
    // Step 2: Initialize the handle
    handleCFFT = &CFFT;

To test the code I have generated one complete cycle of the below signal with 256 points sampling.

x= 2000+ 1000*sin(t)+700*sin(2*t)+500*sin(3*t);

The sampled signal is stored in 256 length uint16_t array as shown below:

uint16_t matlab_sig[256] = { 2000, 2096, 2191, 2286, 2380, 2472, 2564, 2653,
                             2741, 2826, 2909, 2989, 3066, 3139, 3210, 3277,
                             3340, 3399, 3454, 3504, 3551, 3593, 3631, 3664,
                             3693, 3717, 3736, 3751, 3762, 3768, 3770, 3767,
                             3761, 3750, 3735, 3717, 3695, 3670, 3642, 3610,
                             3576, 3539, 3500, 3458, 3415, 3370, 3324, 3276,
                             3228, 3178, 3129, 3079, 3029, 2979, 2930, 2881,
                             2833, 2786, 2740, 2696, 2653, 2612, 2573, 2535,
                             2500, 2467, 2436, 2407, 2380, 2356, 2334, 2314,
                             2297, 2282, 2270, 2259, 2251, 2245, 2240, 2238,
                             2238, 2239, 2241, 2245, 2251, 2257, 2265, 2273,
                             2282, 2292, 2302, 2312, 2322, 2332, 2342, 2352,
                             2361, 2369, 2377, 2383, 2389, 2393, 2397, 2399,
                             2399, 2398, 2396, 2392, 2387, 2380, 2371, 2361,
                             2350, 2336, 2322, 2305, 2288, 2269, 2249, 2227,
                             2205, 2182, 2157, 2132, 2107, 2080, 2054, 2027,
                             2000, 1973, 1946, 1920, 1893, 1868, 1843, 1818,
                             1795, 1773, 1751, 1731, 1712, 1695, 1678, 1664,
                             1650, 1639, 1629, 1620, 1613, 1608, 1604, 1602,
                             1601, 1601, 1603, 1607, 1611, 1617, 1623, 1631,
                             1639, 1648, 1658, 1668, 1678, 1688, 1698, 1708,
                             1718, 1727, 1735, 1743, 1749, 1755, 1759, 1761,
                             1762, 1762, 1760, 1755, 1749, 1741, 1730, 1718,
                             1703, 1686, 1666, 1644, 1620, 1593, 1564, 1533,
                             1500, 1465, 1427, 1388, 1347, 1304, 1260, 1214,
                             1167, 1119, 1070, 1021, 971, 921, 871, 822, 772,
                             724, 676, 630, 585, 542, 500, 461, 424, 390, 358,
                             330, 305, 283, 265, 250, 239, 233, 230, 232, 238,
                             249, 264, 283, 307, 336, 369, 407, 449, 496, 546,
                             601, 660, 723, 790, 861, 934, 1011, 1091, 1174,
                             1259, 1347, 1436, 1528, 1620, 1714, 1809, 1904 };

So there is a dc component of 2000, first harmonic of 1000, 2nd of 700 and third of 500 Vpk.

Following is my function that performs the actual FFT.

static inline void calculate_THD(void)
{
    uint16_t i, j;
    float32_t THD;

    //NOTE:Consider using memcpy
    for (i = 0; i < 256; i++)
    {
        Vgrid_FFT_in_buf[i] = matlab_sig[i];
    }
    //running FFT on grid voltage samples
    CFFT.run(handleCFFT);
    //Unpacking is required as 128 point real FFT is performed using 64 points complex FFT.
    CFFT_unpack(handleCFFT);
    //Post processing FFT results

    magFFT[0] = CFFT.pOutBuffer[0] * 0.0313 * 5;
    //Calculating magnitude till 7th harmonic
    for (i = 1; i < 8; i++)
    {
        j = 2 * i;
        magFFT[i] =
        sqrtf(((float) CFFT.pOutBuffer[j] * (float) CFFT.pOutBuffer[j])
                + ((float) CFFT.pOutBuffer[j + 1]
                        * (float) CFFT.pOutBuffer[j + 1]));
        //scaling factor is (1/2^12)/Vgrid1_gain = 0.0313
        //furthermore the library scales the ouput result by N where 2^N = # of samples. for 32 samples N=5.
        //since we are measuring a single phase so we scale by 2 to measure line to line voltages.
        magFFT[i] = magFFT[i] * 0.02901 * 5 * 2; //0.0313 prev gain

    }

    THD = 0.0f;
    for (i = 2; i < 8; i++)
    {
        THD = magFFT[i] * magFFT[i] + THD;
    }
    THD = sqrtf(THD);
    //Updating array of harmonics effective values
    //Shifting all values one left. Discrading the oldest value.
    for (i = 15; i > 0; i--)
    {
        harm_eff_values[i] = harm_eff_values[i - 1];
    }
    harm_eff_values[0] = THD;
    //Updating array of fundamental values
    for (i = 5; i > 0; i--)
    {
        fundamental_values[i] = fundamental_values[i - 1];
    }
    fundamental_values[0] = magFFT[1];
    fft_updated = true;

}

Now coming to the problem: First call to this function gives correct results but the next call gives wrong results and this continues for all successive call i.e a call giving correct results and the next call giving incorrect results.

Please find below the results captured from the watch window of debug:

Correct results:

Incorrect results:

Note that I am calling the function every 5 seconds so that the watch window has enough time to refresh. I have been trying to troubleshoot it my self but no success so far. I am using C2000Ware 4.0.2 and the compiler version is  22.6.0.LTS. Let me know if more information is needed.

  • Asad,

    Just so I understand clearly - is it just the 1st call that gives correct results, and all future calls give incorrect results? Or alternate calls give correct results?

    Does the exact same approach that you've described above work correctly for the 64-pt CFFT case?

    Did you try running the 128-pt CFFT example present in the VCU2 DSP library in C2000Ware?

    Thanks,

    Sira