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