Initial commit of AESA implementation.
[jump.git] / aesa / src / FFT_Radix2_DIF.c
diff --git a/aesa/src/FFT_Radix2_DIF.c b/aesa/src/FFT_Radix2_DIF.c
new file mode 100644 (file)
index 0000000..2e14788
--- /dev/null
@@ -0,0 +1,169 @@
+#include "FFT_Radix2_DIF.h"
+
+/************************************************************************************/
+
+void FFT_Radix2_DIF_init(DOLProcess * p)
+{      
+       // int i,j;
+       
+       // for (i=0; i<NFFT; i=i+1) 
+       // {
+       //      p->local->Samples_Inp[i].real = 0.0;    // Buffer A of NFFT size
+       //      p->local->Samples_Inp[i].imag = 0.0;
+       //      p->local->Samples_Out[i].real = 0.0;    // Buffer B of NFFT size
+       //      p->local->Samples_Out[i].imag = 0.0;
+       // }
+       
+       p->local->pow_2[0]=1;
+       int i;
+       for (i=1; i < MAX_POW; i++)
+       {
+               p->local->pow_2[i] = p->local->pow_2[i-1]*2;
+       }
+
+       // p->local->sample_counter = 0;
+       p->local->n_ffts = 0;
+       p->local->n_fft_batches = 0;
+       p->local->n_iterations = 0;
+       p->local->excount = 0;
+
+}
+
+/************************************************************************************/
+
+int FFT_Radix2_DIF_fire(DOLProcess * p)
+{
+       // ComplexNumber next_sample;
+       ComplexNumber samples_in[NFFT];
+       // ComplexNumber samples_out[NFFT];
+       p->local->excount++;
+
+
+    int N1,N2, k1, c;
+
+       DOL_read((void*)PORT_DATA_IN, &samples_in, NFFT*sizeof(ComplexNumber), p);              
+       
+       // p->local->Samples_Inp[p->local->sample_counter] = next_sample;                                               
+       // next_sample = p->local->Samples_Out[p->local->sample_counter];
+
+       // The value is calculated, the Dol write is placed as the bottom of the fire function
+
+       // p->local->sample_counter = p->local->sample_counter + 1;
+       // if (p->local->sample_counter == NFFT) 
+       // {
+    N1 = 2;
+    N2 = NFFT/2;
+
+    // FFT_Radix2(&(p->local->Samples_Inp[0]), NFFT);  // Compute first stage
+    FFT_Radix2(&(samples_in[0]), NFFT);  // Compute first stage
+
+
+    // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+    // I don't really understand what's happening here! \/ 
+       while (N2 != 1)  // Compute log NFFT stages
+       {
+                 for (k1 = 0; k1 < N1; k1++)
+               {
+           FFT_Radix2(&(samples_in[N2*k1]), N2);
+               }
+      N2 = N2/2;
+       }
+
+         // Bit_Reverse_Reorder(&(p->local->Samples_Inp[0]), &(p->local->Samples_Out[0]), NFFT, p);  // Reorder data for output
+               
+               // p->local->sample_counter = 0;
+               p->local->n_ffts = p->local->n_ffts + 1;
+               if (p->local->n_ffts == NOF_FFT_PER_RANGE_BIN)                                                  
+               {
+                       p->local->n_ffts = 0;
+                       p->local->n_fft_batches = p->local->n_fft_batches + 1;
+                       if (p->local->n_fft_batches == NOF_FFT_BATCHES)                         
+                       {                               
+                               p->local->n_fft_batches = 0;
+                               p->local->n_iterations = p->local->n_iterations + 1; 
+                       }
+               }
+       // }
+               // printf("\n FFT batches : %d\n",p->local->n_fft_batches);
+                       
+       DOL_write((void*)PORT_DATA_OUT, &samples_in, NFFT*sizeof(ComplexNumber), p);    
+
+       // what i think is happening: is that the output is placed in sample in, but in reverse reorder,
+       // it looks at how many inputs we have got, and it switches them. not necessary anymore!
+
+       if (p->local->n_iterations == NUMBER_OF_ITERATIONS) 
+       {
+               printf("\n\n:: FFT_Radix2_DIF process finished ::\n\n");
+    // printf("\ttotal number of executions:  %d",p->local->excount);  
+               
+               DOL_detach(p);
+       }
+       
+       return 0;
+}
+
+/************************************************************************************/
+
+void FFT_Radix2(ComplexNumber * data, int N)
+{
+       int n2, k1, N1, N2;
+       ComplexNumber W, butterfly[2];
+       
+       N1=2;
+       N2=N/2;
+       
+       /** Do 2 Point DFTs */
+       for (n2 = 0; n2 < N2; n2++)
+       {
+         W.real=cos(n2*2.0*PI/(double)N);
+         W.imag=-sin(n2*2.0*PI/(double)N);
+
+               /** Compute one butterfly **/
+               butterfly[0].real = (data[n2].real + data[N2 + n2].real);
+               butterfly[0].imag = (data[n2].imag + data[N2 + n2].imag);
+               butterfly[1].real = (data[n2].real - data[N2 + n2].real) * W.real - ((data[n2].imag - data[N2 + n2].imag) * W.imag); 
+               butterfly[1].imag = (data[n2].imag - data[N2 + n2].imag) * W.real + ((data[n2].real - data[N2 + n2].real) * W.imag);
+               
+               /** In-place results */
+               for (k1 = 0; k1 < N1; k1++)
+               {
+           data[n2 + N2*k1].real = butterfly[k1].real;
+           data[n2 + N2*k1].imag = butterfly[k1].imag;
+               }
+       }
+}
+
+/************************************************************************************/
+
+void Bit_Reverse_Reorder(ComplexNumber * input, ComplexNumber * output, int N, DOLProcess * p)
+{
+       int bits, i, j, k;
+       bits = 0;
+
+       for (i=0; i<MAX_POW; i++)
+       {
+               if (p->local->pow_2[i] == N)
+               {
+                       bits=i;
+               }
+       }
+       
+       for (i=0; i<N; i++)
+       {
+               j=0;
+               for (k=0; k<bits; k++)
+               {
+           if (i & p->local->pow_2[k])
+                       {
+                               j += p->local->pow_2[bits-k-1];
+                       }
+               }
+               if (j>=i)  
+               {
+      output[i].real = input[j].real;
+      output[i].imag = input[j].imag;
+      output[j].real = input[i].real;
+      output[j].imag = input[i].imag;
+               }
+       }
+}