First of all, it would be good to know what you want to do with the FFT!? Then it would be easier to decide whether you need a real FFT or a complex FFT.
Regarding the code you posted:
* you should NOT use the deprecated function "arm_cfft_radix4_q15" any more, use "arm_cfft_q15" instead!
* if you use a real FFT, the ARM function computes a complex FFT internally, BUT with half the number of FFT points and uses the conjugate symmetric property in order to process your real input data (it outputs complex data however). It seems that the ARM function arm_rfft_q15 nonetheless requires a double sized buffer (of size fftLength*2), although it internally uses a complex FFT of size fftLength/2
* I got the code running with the recently used and recommended functions by changing the following in your code:
Code:
#include "arm_math.h"
#include <arm_const_structs.h>
#define forward 0
#define bitReverse 1
#define fftLength 4096
//
const static arm_rfft_instance_q15 rfft_inst;
// deprecated, do not use!
//arm_cfft_radix4_instance_q15 cfft_inst;
const static arm_cfft_instance_q15 *cfft_inst;
// strange as it seems, the rfft_buffer has to be twice the size of the FFT !?
int16_t rdata[fftLength], rfft_buffer[fftLength * 2];
int16_t cdata[2*fftLength];
//---------------------------------------------------
void setup() {
Serial.println("start");
Serial.begin(9600);
while(!Serial){}
if(arm_rfft_init_q15(&rfft_inst,fftLength, forward, bitReverse) == ARM_MATH_SUCCESS) Serial.println("Successful: init rfft");
// deprecated, do not use !
// if(arm_cfft_radix4_init_q15(&cfft_inst, fftLength, forward, bitReverse) == ARM_MATH_SUCCESS) Serial.println("Successful: init cfft");
switch (fftLength) {
case 16:
cfft_inst = &arm_cfft_sR_q15_len16;
break;
case 32:
cfft_inst = &arm_cfft_sR_q15_len32;
break;
case 64:
cfft_inst = &arm_cfft_sR_q15_len64;
break;
case 128:
cfft_inst = &arm_cfft_sR_q15_len128;
break;
case 256:
cfft_inst = &arm_cfft_sR_q15_len256;
break;
case 512:
cfft_inst = &arm_cfft_sR_q15_len512;
break;
case 1024:
cfft_inst = &arm_cfft_sR_q15_len1024;
break;
case 2048:
cfft_inst = &arm_cfft_sR_q15_len2048;
break;
case 4096:
cfft_inst = &arm_cfft_sR_q15_len4096;
break;
}
Serial.print("CFFT init done with size "); Serial.println (fftLength);
}
//-----------------------------
void loop() {
for (int i=0; i<fftLength; i++) {
rdata[i] = (int16_t)(20000 + 4096*cos(2*3.1415926*i/16) + 6788*sin(2*3.1415926*i/4)); // real
cdata[2*i] = (int16_t)(20000 + 4096*cos(2*3.1415926*i/16) + 6788*sin(2*3.1415926*i/4)); // complex
cdata[2*i+1] = 0;
}
Serial.println("wave generated");
delay(100);
uint32_t t0 = micros();
arm_rfft_q15(&rfft_inst, rdata, rfft_buffer);
Serial.println("q15 real done");
Serial.print("\t"); Serial.println(micros() - t0);
t0 = micros();
// deprecated, do not use !
// arm_cfft_radix4_q15(&cfft_inst, cdata);
arm_cfft_q15(cfft_inst, cdata, forward, bitReverse);
Serial.println("q15 complex done");
Serial.print("\t"); Serial.println(micros() - t0);
delay(2000);
However I did not check whether the FFT delivered nice results, that would be your task :-)
P.S.: for the real FFT, the maximum FFT length is 8192 (because it computes a 4096 point complex FFT internally), for the complex FFT the maximum size is 4096
P.P.S.: BTW, here is the documentation for the FFT functions: https://www.keil.com/pack/doc/CMSIS/...ransforms.html