Tool/software: TI C/C++ Compiler
I am trying to implement the fix_fft algorithm , most specifically fix_fftr by Tom Roberts on the Tiva launchpad but I'm having trouble getting the correct outputs... See code below
#include <stdbool.h>// #include <stdio.h> #include <stdint.h>// #include <float.h> #include "inc/hw_memmap.h"// #include "driverlib/debug.h" #include "driverlib/gpio.h"// #include "driverlib/rom.h" #include "driverlib/sysctl.h"// #include "driverlib/pin_map.h" #include "driverlib/ssi.h" #include "driverlib/pwm.h" #include "driverlib/pwm.c" #include "driverlib/adc.h" #include "driverlib/adc.c" #include "fix_fft.h" ///////////////Register definitions////////////////////////////////// #define GPIO_PORTF_DATA_R (*((volatile unsigned long *)0x400253FC)) #define GPIO_PORTF_DIR_R (*((volatile unsigned long *)0x40025400)) #define GPIO_PORTF_AFSEL_R (*((volatile unsigned long *)0x40025420)) #define GPIO_PORTF_PUR_R (*((volatile unsigned long *)0x40025510)) #define GPIO_PORTF_DEN_R (*((volatile unsigned long *)0x4002551C)) #define GPIO_PORTF_LOCK_R (*((volatile unsigned long *)0x40025520)) #define GPIO_PORTF_CR_R (*((volatile unsigned long *)0x40025524)) #define GPIO_PORTF_AMSEL_R (*((volatile unsigned long *)0x40025528)) #define GPIO_PORTF_PCTL_R (*((volatile unsigned long *)0x4002552C)) #define SYSCTL_RCGC2_R (*((volatile unsigned long *)0x400FE108)) #define GPIO_PORTF_PDR_R (*((volatile unsigned long *)0x40025514)) /////////////// #define GPIO_PORTA_AMSEL_R (*((volatile unsigned long *)0x40004528)) #define GPIO_PORTA_PCTL_R (*((volatile unsigned long *)0x4000452C)) #define GPIO_PORTA_DIR_R (*((volatile unsigned long *)0x40004400)) #define GPIO_PORTA_AFSEL_R (*((volatile unsigned long *)0x40004420)) #define GPIO_PORTA_DEN_R (*((volatile unsigned long *)0x4000451C)) */ //////////////////////////////////////////////////////////////////////// #define true 1 #define false 0 #define GPIO_PORTF_LOCK_R (*((volatile unsigned long *)0x40025520)) /* void PWM_RGB_Init(void); void ADC0_Init(void); void UnlockPortF(void); unsigned int ADC_CH0_Sample(void); //enum color{red,blue,green}; unsigned int Green_ColorTempConvert(unsigned int ADCValue); unsigned int Blue_ColorTempConvert(unsigned int ADCValue); unsigned int Red_ColorTempConvert(unsigned int ADCValue); void processOnTimes(unsigned int* redAddress,unsigned int* blueAddress, unsigned int* greenAddress); void PF0Pushbutton_Init(void); */ short sine20[128]={0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281,-755,-989,-909,-540,0,541,910,990,756,282,-281}; short sine40[128]={0,909,755,-282,-990,-541,540,989,281,-756,-910,-1,909,755,-282,-990,-541,540,989,281,-756,-910,-1,0,909,755,-282,-990,-541,540,989,281,-756,-910,-1,909,755,-282,-990,-541,540,989,281,-756,-910,-1,0,909,755,-282,-990,-541,540,989,281,-756,-910,-1,909,755,-282,-990,-541,540,989,281,-756,-910,-1,0,909,755,-282,-990,-541,540,989,281,-756,-910,-1,909,755,-282,-990,-541,540,989,281,-756,-910,-1,0,909,755,-282,-990,-541,540,989,281,-756,-910,-1,909,755,-282,-990,-541,540,989,281,-756,-910,-1,0,909,755,-282,-990,-541,540,989,281,-756,-910,-1,909}; short cosine22[128]={1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310,309,809,1000,809,309,-310,-810,-1000,-810,-310}; volatile long FFT_power[64]; int FFT_result[128]; int main(void) { //Fix_FFT Attempt //fix_fftr(short f[], int m, int inverse) //Notes: N(number of samples)=2^m, therefore if I want 128, log2(128)=7 so m =7 int i; fix_fftr(cosine22, 7, 0); volatile long max=0; volatile int maxIndex=0; for(i=0;i<64;i++){ //capture Power^2 FFT_power[i]=((long)cosine22[i]*(long)cosine22[i])+((long)cosine22[i+64]*(long)cosine22[i+64]); //capture max if(FFT_power[i]>max){ max=FFT_power[i]; maxIndex=i; } } return(0); }
My understanding of fix_fftr is that it as arguments are:
1. An array of size N (in my case 128)
2. An "m" factor which is just log2(N) which in my case is 7
3. A flag that tells the function whether I want forward or reverse FFT, in my case should be 0.
And that it simply replaces the array you input with an array containing N/2 real elements (at indices 0 to N/2-1) l and N/2 imaginary elements (at indices N/2 to N).
I started by inserting a cosine function and trying to get back a spike at the frequency of choice. My sampling frequency is 220Hz and the frequency of the wave I am trying to capture is 22Hz. Then, I tried to capture the relative power in each frequency bin (I know you're supposed to sqrt for true power but I skipped that part, sue me). Based on my input in the time domain which is 1/10 the sampling frequency, one would expect the N/10th bin to have the largest peak. However when I run in debug and check my numbers I get a drastically different result than what we expect with strange spikes at various locations:
FFT_power | long[64] | [245,340,629,1305,3152...] | 0x20000918 | ||
0 | 0 | [0] | long | 245 | 0x20000918 |
1.71875 | 1 | [1] | long | 340 | 0x2000091C |
3.4375 | 2 | [2] | long | 629 | 0x20000920 |
5.15625 | 3 | [3] | long | 1305 | 0x20000924 |
6.875 | 4 | [4] | long | 3152 | 0x20000928 |
8.59375 | 5 | [5] | long | 10937 | 0x2000092C |
10.3125 | 6 | [6] | long | 148733 | 0x20000930 |
12.03125 | 7 | [7] | long | 75065 | 0x20000934 |
13.75 | 8 | [8] | long | 11545 | 0x20000938 |
15.46875 | 9 | [9] | long | 4930 | 0x2000093C |
17.1875 | 10 | [10] | long | 2842 | 0x20000940 |
18.90625 | 11 | [11] | long | 1961 | 0x20000944 |
20.625 | 12 | [12] | long | 1489 | 0x20000948 |
22.34375 | 13 | [13] | long | 1145 | 0x2000094C |
24.0625 | 14 | [14] | long | 976 | 0x20000950 |
25.78125 | 15 | [15] | long | 800 | 0x20000954 |
27.5 | 16 | [16] | long | 730 | 0x20000958 |
29.21875 | 17 | [17] | long | 637 | 0x2000095C |
30.9375 | 18 | [18] | long | 629 | 0x20000960 |
32.65625 | 19 | [19] | long | 640 | 0x20000964 |
34.375 | 20 | [20] | long | 692 | 0x20000968 |
36.09375 | 21 | [21] | long | 738 | 0x2000096C |
37.8125 | 22 | [22] | long | 905 | 0x20000970 |
39.53125 | 23 | [23] | long | 1573 | 0x20000974 |
41.25 | 24 | [24] | long | 4045 | 0x20000978 |
42.96875 | 25 | [25] | long | 30920 | 0x2000097C |
44.6875 | 26 | [26] | long | 84825 | 0x20000980 |
46.40625 | 27 | [27] | long | 9010 | 0x20000984 |
48.125 | 28 | [28] | long | 4505 | 0x20000988 |
49.84375 | 29 | [29] | long | 3016 | 0x2000098C |
51.5625 | 30 | [30] | long | 2740 | 0x20000990 |
53.28125 | 31 | [31] | long | 2610 | 0x20000994 |
55 | 32 | [32] | long | 2809 | 0x20000998 |
56.71875 | 33 | [33] | long | 3280 | 0x2000099C |
58.4375 | 34 | [34] | long | 4285 | 0x200009A0 |
60.15625 | 35 | [35] | long | 6185 | 0x200009A4 |
61.875 | 36 | [36] | long | 10916 | 0x200009A8 |
63.59375 | 37 | [37] | long | 28561 | 0x200009AC |
65.3125 | 38 | [38] | long | 309905 | 0x200009B0 |
67.03125 | 39 | [39] | long | 124577 | 0x200009B4 |
68.75 | 40 | [40] | long | 15925 | 0x200009B8 |
70.46875 | 41 | [41] | long | 5186 | 0x200009BC |
72.1875 | 42 | [42] | long | 2578 | 0x200009C0 |
73.90625 | 43 | [43] | long | 1417 | 0x200009C4 |
75.625 | 44 | [44] | long | 929 | 0x200009C8 |
77.34375 | 45 | [45] | long | 569 | 0x200009CC |
79.0625 | 46 | [46] | long | 464 | 0x200009D0 |
80.78125 | 47 | [47] | long | 340 | 0x200009D4 |
82.5 | 48 | [48] | long | 290 | 0x200009D8 |
84.21875 | 49 | [49] | long | 265 | 0x200009DC |
85.9375 | 50 | [50] | long | 305 | 0x200009E0 |
87.65625 | 51 | [51] | long | 296 | 0x200009E4 |
89.375 | 52 | [52] | long | 288 | 0x200009E8 |
91.09375 | 53 | [53] | long | 458 | 0x200009EC |
92.8125 | 54 | [54] | long | 745 | 0x200009F0 |
94.53125 | 55 | [55] | long | 1233 | 0x200009F4 |
96.25 | 56 | [56] | long | 2929 | 0x200009F8 |
97.96875 | 57 | [57] | long | 19172 | 0x200009FC |
99.6875 | 58 | [58] | long | 39145 | 0x20000A00 |
101.40625 | 59 | [59] | long | 2858 | 0x20000A04 |
103.125 | 60 | [60] | long | 809 | 0x20000A08 |
104.84375 | 61 | [61] | long | 360 | 0x20000A0C |
106.5625 | 62 | [62] | long | 180 | 0x20000A10 |
108.28125 | 63 | [63] | long | 202 | 0x20000A14 |
Needless to say I'm a little stumped right now. If anyone has any tips about fftr or what I'm doing wrong, I'd appreciate it.
Cheers,
Jim