Library 62- Fast Fourier Transform (FFT) for STM32F4xx

Hereย is an example of Fast Fourier Transform on STM32F4xx devices. Today, I was looking something on ARM DSP documentation and I saw that some functions for FFT used in my example are deprecated and will be removed in future.

That was the main reason I decided to make a library for FFT on STM32F4xx.

To use this library, some third-party libraries are also required. All these required files can be found in STM32F4xx Standard peripheral drivers and DSP instructions provided from ST.com from their website. Now is version 1.5.1 of these drivers and also .lib file is included for ARM MATH for Cortex-M4 Little-Endian with Floating point instructions.

Point of this library is that user don’t actually need to know how FFT works in real life. You just have to know, that calculated FFT is always half of size in length than data, which are used for calculation, because ARM DSP library uses real and imaginary part in input array, so input array is twice of size of output array.

Library

Features

  • Calculate FFT result with float 32 type of variable
  • Calculate max value of your FFT result
  • Works with highly optimized ARM DSP library
  • Support for variable FFT size
  • Allows 16, 32, 64, 128, 256, 512, 1024, 2048 or 4096 samples for FFT size

Dependencies

  • CMSIS
    • STM32F4xx
  • TM
    • defines.h
  • ARM DSP
    • arm_const_structs.c, available in “CMSIS\DSP_Lib\Source\CommonTables”
    • arm_cortexM4lf_math.lib for ARM compiler, available in “CMSIS\Lib\ARM”

CMSIS folder can be found if you download these libraries directly from ARM.com or if you download Standard Perihperal Drivers for STM32F4xx from ST.com site.

ARM MATH

ARM MATH is a library provided from ARM and is the same for all Cortex families, except that you have to provide some informations to library.

In your global compiler defines, you should add these 2 lines:

FFT Samples count

ARM FFT library allows you to use specific number of samples for data calculation.

These values can be every number which is power of 2 from 2^4 and 2^12. So, 9 different FFT length options. These number are passed into function when you initialize FFT with my library.

FFT input/output buffers

FFT works in a way that you first fill input buffer with samples and then you process them and you got samples in output buffer. Complex (CFFT) Fast Fourier Transform, which is also used behind the scenes in my library so uses real and imaginary part in input buffer and only real part is calculated to output buffer.

For this reason, input buffer HAVE TO be 2 * FFT_Size in length and output buffer HAVE TO be FFT_Size in length where FFT_Size is the same as FFT_Samples count explained above.

Library is able to use malloc() to allocate memory for you. You just need to enable this feature when you initialize FFT module and everything will be done for you. You just have to make sure that you have enough HEAP memory available for malloc, otherwise malloc will fail and you will not get anything.

For example, if you have 512 length FFT size, then input buffer must be 2 * 512 = 1024 samples of float 32 and output buffer is 512 samples of float 32. In common, this is 1536 samples of float32 which is 4-bytes long in memory. So, together this would be 6144 Bytes of HEAP memory.

Functions and enumerations

Example

The example works the same as my first FFT example provided on link at the beginning of post. Only library is here and everything looks more nicer.

Project is available on Github, download library below.

Icon
TM STM32F4 FFT Library

tilz0R

Owner of this site. Also electronic enthusiasts, web developer, 3D printer fan, handball player and more. Big fan of STM32F4 devices. In anticipation of the new Discovery board for STM32F7 lines.

You may also like...

Read before commenting!

Before you make a new comment, make sure you agree with things listed below:

  • - Read post to make sure if it is already posted what you are asking for,
  • - Make sure you have the latest version of libraries used in your project,
  • - Make a clean and grammatically correct written message,
  • - Report as many details as possible, including what have you done so far,
  • - Do NOT post any code here. Use Pastebin,
  • - Do NOT post any error codes here. Use Pastebin,
  • - Specify STM32Fxxx family and used Discovery/EVAL/Nucleo or custom made board,
  • - Make sure your clock is set correct for PLL,
  • - If you are using my HAL drivers, please check this post how to start.
Comment will be deleted on breaking these rules without notification!
  • Pingback: STM32F4 FFT example - STM32F4 Discovery()

  • leonardo

    I’m sorry by the silly question, but I’ve install keil, download st sw pack, download your project template. Open it and everithing is ok, I could compile main.c
    Now, what do I have to do with files on this post to test FFT?

    Thk!

    • Go to my github account, find link on this site. Then download entire f4 repository and open fft project 62.

      • leonardo

        I get this error when I’m trying to build:

        linking…

        http://pastebin.com/raw.php?i=z8snwjiS

        BTW, should I copy/paste link to my pastebin or what?

        • I failed here, sorry.
          2 solutions:
          – First is to redownload github repo (I’ve fixed error)
          – Second is to download manually my DMA2D library and include in project.

          • leonardo
          • It looks like saving was not entire correct.
            I’ve updated again.

            PS: You could make a research where this function exists in project ๐Ÿ˜‰

          • leonardo

            ok, I add stm32f4xx_dma2d.c to STD_Periph_Drivers group and rebuild, but the size code limitation is here again…

          • You will need to get license ๐Ÿ˜‰

          • leonardo

            I don’t know how much does it cost, but I think that will be prohibitive. I’m thinking on how hard would be port some of your libs to SystemWorbench…
            BTW: don’t you consider work with SW? it’s the free ide by ST…

          • Why porting? This is “C” language and if you put all these libs together, any compiler would build this, even GCC based compilers. I’m just using Keil uVision for programming, but works everywhere, coocox, IAR, emblocks, you SW by ST, …etc. If compiler has C then works.

          • leonardo

            Ok, I will try to make a project with this libs on it and report back.
            Thank

          • leonardo

            well, I “buy” a licence… I can compile the program, but the licence broke the flash capability. Is there an external tool to flash the axf file into the uC? I used to use Flash Magic with NXP, it works with st?

          • I won’t say that that everyone will hear me that you “bought” license ๐Ÿ˜‰
            You can use ST-lInk utility but I don’t believe that license break your flash.

            What’s the error? Maybe you have to setup flash download protocol in options for target.

          • leonardo

            It’s a tipicall error (i saw a lot of on internet, but no solution for me).
            As soon as I press Load an error message “Internal command error”. I press Ok and then another message:
            Error: Flash Download failed – Target DLL has been cancelled.

            I go to Flash-> config flash tool->debug-> settings (on st link-debugger).
            If I plug the board and then go to that windows I see SN: 52FF6F065078515236090887, but after try to flash I go to that windows and see SN: 303030303030303030303031

            before I install the license I could load firmwares..

            Ideas?

          • Add to skype (search for my username on this site) and we can check it via teamviewer.

          • leonardo

            ok, givme a minute

  • Artur

    is anybody get error from multiply defined arm_cfft_sR_ in library and main file? Keil 5.14

    • Hi,

      are you running my example directly (downloaded from my github) or you have your custom?

      • Artur

        Thnx, all ok, it was old cmsis

  • James

    How do I make it work with STM32F411-Nucleo board without LCD? When I tried to compile, it kept giving 2 errors which are undefined symbol TM_DMA2DGRAPHIC_CopyBuffer and TM_SDRAM_Init .Furthermore, how to read the input data from a file and print the output FFT file into desktop?

    • Remove everything related to lcd from project.
      You can use usart for data transfer from nucleo to computer. Thats how I do it somewhere.

      • James

        I tried to re download your github and now it gives one error :”..0-STM32F429_LIBRARIEStm_stm32f4_dma2d_graphic.c(622): error: #20: identifier “LTDC_Pixelformat_RGB565″ is undefined”

        Can I know how to fix this?

        • You’ve must changed something here. It works OK for me when I open my project.
          Make sure you have everything setup correctly in your project.

  • Demian_Z

    Is it possible to port your project on STM32F0?

  • Kai Mittermueller

    What is the runtime of the TM_FFT_Process_F32() function? Can you provide some examples?

    • I think, example is one BIG box of code, or you don’t see it?

      • Kai Mittermueller

        I mean examples for the runtime for different input sizes / processor frequencys….

  • Dean Reading

    Why does this library only calculate the real part of the output? 99% of applications will want the FFT magnitudes.

    • It calculates all, just outputs real part.

      • Dean Reading

        That terminology is confusing, because the real part of the FFT result is not the magnitude. The magnitude is sqrt(real^2 + imag^2). The phase is atan(imag/real). I’ve attached a graph of the first 50 numbers of an FFT calculated by this library.

        • Zola

          You’re right @deanreading:disqus , every frequency component is composed from its real and imaginary part. And with those two parameters we can calculate magnitude and phase of that frequency component with the help of sqrt(real^2 + imag^2) and atan(imag/real) formulas.

    • Dean Reading

      I just printed out numbers and processed them on MATLAB, and it looks like the output of your library IS the FFT magnitude – which is great! I suggest that you update the description to tell people this. And remove the words “only real part is calculated to output buffer”.

      • Real part is magnitude meant, imagybary part is phase. This is also calculated but not on output.

  • Alex Wang

    Hey tilzOR, I’m really interested in your awesome library, it is working great of course, but what is really attracting me is the logarithmic scaling, or LOG, instead of LIN(ear)๏ผŒ which in my opinion is the BEST THING you can have in an audio spectrum analyzer :DDDD!! SO uh…maybe you can help me?? <3

    • I think this should be pretty easy. Convert all amplitudes to 20 * log10(amplitude) and that’s all ๐Ÿ™‚
      You have values in dB ready for logaritmic view.

      • Alex Wang

        hey thank you so much for your reply! That was lightning fast by the way XD

      • Alex Wang

        What i meant was that, could i divide the Frequency in a logarithmic scale though?

        • I don’t understand question anymore I would say.

          • Alex Wang

            ok so like, the frequency instead gets divided i a logarithmic matter, e.g. 100hz, 125hz, 156hz, 200hz, 250hz, 312hz, 400hz, 500hz, 625hz, 800hz, 1000hz

          • FFT itself provides linear output, so there is no “auto” way for that.
            You will have to write custom code either to remove unnecessary values from array or actually correct display mode to show them correctly,

          • Alex Wang

            Ohh alright, so i still need to do this manually, i’ll try it sometimes, just been wondering if there is like a setting on the FFT to do this automatically(or called the lazy way). thank you for your time and patient ๐Ÿ™‚

          • Alex Wang

            but wait a minute… don’t i need to combine all the amplitude values in between the two frequencies for the correct display though? i know i’m not clear enough on what i’m saying. Also wouldn’t it be wasting a lot of processing power? since most of the calculations was not used, you know, it’s like jumping, and each time there is a greater jump.

          • Everything is in your display.

          • Alex Wang

            instead of just 100hz, 200hz, 300hz…etc

  • issa93

    I have a PWM signal (composed of three PWM signals of different frequencies) read by a Timer, can I apply the FFT to distinguish included frequencies ?

    • Yes, you can do that. Just keep in mind that fft works in sinus signal not on square. You will have a lot of frequencies in fft output.

      • issa93

        How to put the signal read by the timer as input and display the frequencies obtained by FFT ? Give me the functions and configurations so I have to use them please .

        • I really wont give you that functions. But exactly this is done in example.