This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Error Running FFT code function on Stellaris LM4F120.



Hello there I am having trouble in the code I have written for my stellaris Launchpad. The main problem I am having currently is that I cannot get the if function in my while loop to run the function in it.

The Function is a FFT Function running from CMSIS DSP lib . I Get the FFT working if I put the FFT code in the while loop. but I want it to be accessed only once when the ADC is finished sampling. Could you help me what might be the code error that does not let the if statement be to be run even if the statement is true.

Thanks

Maulik

 

#include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_ints.h" #include "inc/hw_adc.h" #include "driverlib/timer.h" #include "driverlib/debug.h" #include "driverlib/sysctl.h" #include "driverlib/adc.h" #include "driverlib/interrupt.h" #include "driverlib/gpio.h" #include "arm_math.h"

float FFTInput[256] ; float FFTOutput[128];

unsigned long ulADC0Value[4]; volatile unsigned long ulTempAvg; int fftSize = 128 ; int ifftflag = 0 ; int doBitReverse = 1 ; uint32_t testindex  = 0, refIndex = 213 ; int i = 0 ; int ulPeriod ;

int FFTFinish = 0 ; int samplingfinish = 0 ;

void ARM_FFT(void);

#ifdef DEBUG void __error__(char *pcFilename, unsigned long ulLine) { } #endif

void GPIOPinSetup(void) {  //Basic GPIO PINF Setup  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);  GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);

}

void Timer0SetUp(void) { // Basic Timer A setup  SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);  TimerConfigure(TIMER0_BASE, TIMER_CFG_PERIODIC);  TimerControlTrigger(TIMER0_BASE, TIMER_A,true);  ulPeriod = (SysCtlClockGet()/3000) ;  TimerLoadSet(TIMER0_BASE, TIMER_A, (ulPeriod -1));  IntEnable(INT_TIMER0A);  TimerIntEnable(TIMER0_BASE, TIMER_TIMA_TIMEOUT);  TimerEnable(TIMER0_BASE, TIMER_A); }

void ADC0Setup(void) {  //Basic ADC0 Setup  SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);  SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS);  ADCSequenceDisable(ADC0_BASE, 1);

 ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_TIMER, 0);  ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH1);  ADCSequenceStepConfigure(ADC0_BASE, 1, 1, ADC_CTL_CH1);  ADCSequenceStepConfigure(ADC0_BASE, 1, 2, ADC_CTL_CH1);  ADCSequenceStepConfigure(ADC0_BASE, 1, 3, ADC_CTL_CH1 | ADC_CTL_IE | ADC_CTL_END);

 ADCSequenceEnable(ADC0_BASE, 1);  ADCIntEnable(ADC0_BASE, 1); }

int main(void) {  SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);

 Timer0SetUp();  ADC0Setup();  GPIOPinSetup();

 IntEnable(INT_ADC1);

 //status = ARM_MATH_SUCCESS ;

 //status = arm_cfft_radix4_init_f32(&S, fftSize, ifftflag, doBitReverse);  while(1)  {

  if(samplingfinish)   {    /*arm_cfft_radix4_f32(&S, FFTInput);

   arm_cmplx_mag_f32(FFTInput , FFTOutput, fftSize);

   arm_max_f32(FFTOutput, fftSize, &maxvalue ,&testindex);    if(status == ARM_MATH_SUCCESS)    {     GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 14);     SysCtlDelay(80000000);    }    FFTFinish = 1 ;    samplingfinish = 0 ;*/    ARM_FFT();   }

  else;  }

}

void Timer0IntHandler(void) {

 TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);  if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))  {   GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);  }  else  {   GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 14);  }

}

void ADC1IntHandler(void) {  //clear the adc interrupt  ADCIntClear(ADC0_BASE, 1) ;  // disable the timer  so that we do not get a fault ISR routine  TimerDisable(TIMER0_BASE, TIMER_A) ;

 ADCSequenceDataGet(ADC0_BASE, 1, ulADC0Value);  ulTempAvg = (ulADC0Value[0] + ulADC0Value[1] + ulADC0Value[2] + ulADC0Value[3] + 2)/4;  IntPendClear(INT_ADC0SS1);  if(i != 256 && FFTFinish == 0)  {   FFTInput[i] =(float) ulTempAvg ;   i++ ;   TimerLoadSet(TIMER0_BASE, TIMER_A, (ulPeriod -1));   TimerEnable(TIMER0_BASE, TIMER_A);  }  else  {   IntPendClear(INT_ADC0SS1);   IntPendClear(INT_TIMER0A);   TimerDisable(TIMER0_BASE, TIMER_A) ;   ADCIntDisable(ADC0_BASE, 1);   GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);   samplingfinish = 1 ;   return ;  }

}

void ARM_FFT(void) {  arm_status status ;  arm_cfft_radix4_instance_f32 S ;  float maxvalue ;

 status = arm_cfft_radix4_init_f32(&S, fftSize, ifftflag, doBitReverse);

 arm_cfft_radix4_f32(&S, FFTInput);

 arm_cmplx_mag_f32(FFTInput , FFTOutput, fftSize);

 arm_max_f32(FFTOutput, fftSize, &maxvalue ,&testindex);  if(status == ARM_MATH_SUCCESS)  {   GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 14);   SysCtlDelay(80000000);  }  FFTFinish = 1 ; }

 

  • Hi Maulik,

       It will help, if your shared code is formatted and much more readable.

       Are you referring to this code part below? Clean it up a little bit and just retain the ARM_FFT(); in the if statement, and see if it works. 

       

    while(1)

    {

         if(samplingfinish)

         {

           /*arm_cfft_radix4_f32(&S, FFTInput);

           arm_cmplx_mag_f32(FFTInput , FFTOutput, fftSize);

           arm_max_f32(FFTOutput, fftSize, &maxvalue ,&testindex);
           if(status == ARM_MATH_SUCCESS)
           {
               GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 14);
               SysCtlDelay(80000000);
           }
               FFTFinish = 1 ;
               samplingfinish = 0 ;
               */ ARM_FFT();
           }

           else; }
    }

    -kel

  • As you suggested I cleaned the unwanted code and attached the file with this post.

    I have already tried with 

    while(1)

    {  if(samplingfinish)

                { 

                         ARM_FFT();

                }

    }

    But this code get stuck forever at if(samplingfinish) line even if the value of samplingfinish is 1. It does not go into ARM_FFT(); function. That Function works if I write this in my code instead of a function for ARM_FFT(); Like this

    while(1)

    {

         if(samplingfinish)

         {

           arm_cfft_radix4_f32(&S, FFTInput);

           arm_cmplx_mag_f32(FFTInput , FFTOutput, fftSize);

           arm_max_f32(FFTOutput, fftSize, &maxvalue ,&testindex); 
           if(status == ARM_MATH_SUCCESS)
             {
               GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 14);
              } 
               
           }

           else; 
    }

    I do understand how the latter code(yellow) works but I cannot get it around my head why the former code(green) does not enter the function for when the if statement   is true. Could you help me on that.

    I did try stoping the code at the time when i = 256 and it does not enter a infinite while loop for a faultISR or any other faults. It just centers around the if statement and its main.c program counter  does not change for a Step Into (F5) in Code composer studio.

    You help will really be appreciated.

    Thanks

    Maulik 

  • Some comments:

    Do you build you project with optimization ? If so, some of you code might actually be optimized out.

    For exactly this reason, I would declare everything touched inside the interrupt handler as volatile, especially the samplingfinish flag.

    Have you tried set a breakpoint at the ADC interrupt hander, where samplingfinish is supposed to be set ? Stepping out of this function should put you into the FFT() routine soon.

    Are you aware that you continously transform the same sample ? I would reset the samplingfinish flag afterwards.

    And, I would attach the ADC sample result to a DMA channel, and have the DMA generate an interrupt when the buffer is full. This way, the sampling can run in the "time shadow" of the fft routine, and doesn't load the MCU.

  • @ f.m.

    So well analyzed/advised.   (nicely reveals why you're paid those, "big bucks/Euros")

  • (nicely reveals why you're paid those, "big bucks/Euros")

    Do I ?