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.

TMS320F280049C: DSP FFT library functiions

Part Number: TMS320F280049C
Other Parts Discussed in Thread: C2000WARE

Final result FFT pointers don't appear to point to correct result buffer?

After running the CFFT_f32t(), fpu32_eabi library function, the resultant CurrentOutPtr looks like it is pointing to the buffer of an intermediate result but the correct output seems to be in the CurrentInPtr value.

Input data is 1024-pts of real data of a 440Hz sin wave sampled at 44.1KHz. Data is windowed, then interpreted as 512-pairs of complex data so we can use a 512-pt "CFFT_f32t()" function.

1024-pt real data windowed then interpreted as 512-pt complex data before running CFFT_f32t() function:

These data graphs are plotted as 1024 points but in the CFFT_f32t interprets them as 512-complex pairs of data,
with data in *InPtr (top: windowed input data), *OutPtr = (bottom: empty buffer):

After CFFT_f32t() is run:

But, the resultant *CurrentInPtr = (top: should be the correct output, note the ~2-fold),
and *CurrentOutPtr = (bottom: wrong, looks like an intermediate result, note the ~4-fold symmetry):

Why are the pointers apparently incorrect? Or, am I misinterpreting something, or running the CFFT_f32t() incorrectly?


thanks,
Dan

  • Hello Dan,

    Can you show me how you set up the arrays which are pointed to in the FFT object (both input and output), as well as how they are aligned in memory?

    Best regards,

    Omer Amir

  • Arrays defined as follows:

    in ".cmd" file:

    FFT_buffer_1 : > RAMGS0123, ALIGN = FFT_ALIGN
    FFT_buffer_2 : > RAMGS0123, ALIGN = FFT_ALIGN

    where FFT_ALIGN is defined in C2000 Linker->Advanced Options->Command File Preprocessing: 

    in ".c" source file:

    #pragma DATA_SECTION(cfft_input, "FFT_buffer_1")
    #pragma DATA_SECTION(cfft_output, "FFT_buffer_2")

    float cfft_input [PS_CFFT_BUFF_SIZE]; // enough to hold [512 complex 32-bit floats]
    float cfft_output [PS_CFFT_BUFF_SIZE]; // enough to hold [512 complex 32-bit floats]

    where: PS_CFFT_BUFF_SIZE = 1024

    in ".map" file:

    page address name
    ---- ------- ----
    0 0000c000 cfft_input
    0 0000c800 cfft_output

    You can see the FFT structure *(hnd_cfft) state above in the highlighted yellow regions.

    Anything else you need?

  • Hi Daniel,

    I actually needed to refresh myself on this a little bit; according to the document included with the library in C2000Ware, the CurrentInPtr/CurrentOutPtr point to the respective input/output buffer at each stage of the FFT, not the final input/output. There is also a comment in the assembly (which I know is not the most obvious place where it should be seen), that states, "Final output saved in memory pointed by CurrentInPtr". This reflects what you have observed, I will try to see if I can modify the documentation to be more clear. The existing CFFT examples do point this out as well when measuring tolerance error, I've included the note below:

        //
        // Off-Place Algorithm
        //
        // Note: In this version, input and output buffers are used in
        //       ping-pong fashion. The input data is first stored in the input
        //       buffer where the first stage of the FFT, including bit reversed
        //       ordering, is done.
        //       At each successive stage of the FFT the cfft.CurrentInPtr pointer 
        //       will point to the buffer that is the input for that stage. In this
        //       manner the "CurrentInPtr" and "CurrentOutPtr" are exchanged at the
        //       start of each stage. Depending on the number of FFT stages, the 
        //       final output will be in either test_output (#Stages is odd) or
        //       test_intput (#stages is even).
        //

    Let me know if you have further questions.

    Best regards,

    Omer Amir

  • So, text you quoted (above) shows the CurrentOutPtr should point to the result (for odd number of stages), then you say "the assembly note says the opposite"??? Where is this "secret" note because I am looking at other fft routines and I do NOT see this in my library assembly code!

    While you are correcting things,  in CFFT_f32t.asm, it says:

    ;; * MagBuf and PhaseBuf are FFTSize/2 in length
    ;; * MagBuf and PhaseBuf are not used by this function.
    ;; They are only used by the magnitude and phase calculation functions.

    This seems incorrect, because it (otherwhere) says size of mag and phase should be (FFTSize/2 +1).

  • Hello Daniel,

    The assembly file is called CFFT_f32t.asm (name of the function), and it can be found in the library source file directory: C2000Ware_4_XX_XX_XX\libraries\dsp\FPU\c28\source\fpu32\fft. I believe the note in the example is correct, because looking at the assembly the pointers do get swapped after each stage. Therefore, an even number of stages will make CurrentInPtr point back to the input.

    So, text you quoted (above) shows the CurrentOutPtr should point to the result (for odd number of stages)

    This is not quite right, CurrentInPtr should always point to the final output, but the array it's pointing to changes depending on the number of stages in the FFT (so CurrentInPtr can be pointing to either the input or the output, but it will always be pointing to the final output).

    This seems incorrect, because it (otherwhere) says size of mag and phase should be (FFTSize/2 +1).

    Can you tell me where you found where it says FFTSize/2+1? I want to double check some things.

    Best regards,

    Omer Amir

  • OK, so I am completely confused by the seemingly contradictory comments. I was just trying to follow the guides.


    "FPU DSP Software Library User's Guide, FPU_SW_LIB_UG.pdf" Sec-5.4.2.18 says:

    CurrentInPtr and CurrentOutPtr to keep track of the switching. The user can
    determine the address of the final output by looking at the CurrentOutPtr.

    The canned example fft projects always seem to check "CurrentOutPtr at the end of an FFT.

    In example project "cfft_f32", file "dsp_cfft.c", lines 168-171, it says:

    // If number of Stages is ODD,
    // currentInPtr=test_input, currentOutPtr=test_output
    // If number of Stages is EVEN,
    // currentInPtr=test_output, currentOutPtr=test_input

    Buried deep in the assembly code is your secret comment on line-158:

    ; Final output saved in memory pointed by CurrentInPtr

    So, is that ALWAYS the case and the other comments are wrong?

    As for the (FFTSize/2 + 1) issue, I thought because the unpack function seems to make a result of (N/2+1), I thought that applied to mag and phase, too, no?

    See project "rfft_f32", file: "dsp_rfft.c", lines 116-122:

    // Run the unpack function on the N/2 point complex spectrum
    // to get the N/2+1 point complex spectrum of the N point real
    // data. The unpack function will generate the complex
    // spectrum from F(0) to F(N/2).
    // The pointer, p_currOutput points to the complex spectrum
    // of the real N-point input data.
    CFFT_f32_unpack(hnd_cfft);

    lines: 127-129

    // The golden vector has the full spectrum of the real data, i.e. F(0)
    // to F(N-1) but the unpack routine however only calculates the
    // spectrum from F(0) to F(N/2)

  • Hi Daniel,

    "FPU DSP Software Library User's Guide, FPU_SW_LIB_UG.pdf" Sec-5.4.2.18 says:

    I confirmed this in the guide, but after looking at the cfft_f32t.asm file comments specifically within the functions (which is line 158 as you mentioned), I believe this may be a mistake (I will file the appropriate change).

    In example project "cfft_f32", file "dsp_cfft.c", lines 168-171, it says:

    If you read the comment prior to this within the same block, you'll see that this set of comments is specifically referring to the CFFT_f32_mag function (for calculating magnitude), which operates differently than the FFT function.

    See project "rfft_f32", file: "dsp_rfft.c", lines 116-122:

    This specific example and this function are used for converting complex FFT output into a real FFT output. Per the user guide, "Unpack the N-point complex FFT output to get the FFT of a 2N point real sequence." The cfft_f32t example is probably a more apt example to go by if you aren't looking to convert the FFT from complex to real values, but let me know if this is what you're trying to implement.

    Best regards,

    Omer Amir