//*----------------------------------------------------------------------------
//*         SanJaaC Electronics
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : main.c
//* Object              : Main application written in C
//*----------------------------------------------------------------------------
// Include Standard LIB  files
#include "Drivers.h"
#include "SJ-AT91SAM7SBoard.h"
#include "Dbgu.h"
#include "math.h"


#define     WAIT_TIME       MCK

int menu=0;
int P3,P4,p;


void LCDSendInt(int a);
void delay (int divisor);
void LCDSendTxt(char* a);
void LCDSendChar(unsigned long a);
void LCDSendCommand(unsigned long a);
void LCDInit();
void E_Pulse();
void LCDSendtesla(float a);
#define   BIT16       0x00010000
#define   BIT17       0x00020000
#define   BIT18       0x00040000
#define   BIT19       0x00080000
#define   BIT20       0x00100000
#define   BIT21       0x00200000
#define   BIT22       0x00400000
#define		CLR_DISP	0x00000001	
#define		DISP_ON		0x0000000C	
#define		DISP_OFF	0x00000008	
#define		CUR_HOME        0x00000002
#define		CUR_OFF 	0x0000000C
#define         CUR_ON_UNDER    0x0000000E
#define         CUR_ON_BLINK    0x0000000F
#define         CUR_LEFT        0x00000010
#define         CUR_RIGHT       0x00000014
#define		CUR_UP  	0x00000080	
#define		CUR_DOWN	0x000000C0
#define         ENTER           0x000000C0
#define		DD_RAM_ADDR	0x00000080	
#define		DD_RAM_ADDR2	0x000000C0	

unsigned long data;
AT91PS_PIO    l_pPio   = AT91C_BASE_PIOA;

struct cmpx
 {
  float real;
  float imag;
 };
 
typedef struct cmpx COMPLEX;

COMPLEX w[]={ 1.00000, 0.00000,
        0.99880,-0.04907,
        0.99518,-0.09802,
        0.98918,-0.14673,
        0.98079,-0.19509,
        0.97003,-0.24298,
        0.95694,-0.29028,
        0.94154,-0.33689,
        0.92388,-0.38268,
        0.90399,-0.42756,
        0.88192,-0.47140,
        0.85773,-0.51410,
        0.83147,-0.55557,
        0.80321,-0.59570,
        0.77301,-0.63439,
        0.74095,-0.67156,
        0.70711,-0.70711,
        0.67156,-0.74095,
        0.63439,-0.77301,
        0.59570,-0.80321,
        0.55557,-0.83147,
        0.51410,-0.85773,
        0.47140,-0.88192,
        0.42756,-0.90399,
        0.38268,-0.92388,
        0.33689,-0.94154,
        0.29028,-0.95694,
        0.24298,-0.97003,
        0.19509,-0.98079,
        0.14673,-0.98918,
        0.09802,-0.99518,
        0.04907,-0.99880,
       -0.00000,-1.00000,
       -0.04907,-0.99880,
       -0.09802,-0.99518,
       -0.14673,-0.98918,
       -0.19509,-0.98079,
       -0.24298,-0.97003,
       -0.29028,-0.95694,
       -0.33689,-0.94154,
       -0.38268,-0.92388,
       -0.42756,-0.90399,
       -0.47140,-0.88192,
       -0.51410,-0.85773,
       -0.55557,-0.83147,
       -0.59570,-0.80321,
       -0.63439,-0.77301,
       -0.67156,-0.74095,
       -0.70711,-0.70711,
       -0.74095,-0.67156,
       -0.77301,-0.63439,
       -0.80321,-0.59570,
       -0.83147,-0.55557,
       -0.85773,-0.51410,
       -0.88192,-0.47140,
       -0.90399,-0.42756,
       -0.92388,-0.38268,
       -0.94154,-0.33689,
       -0.95694,-0.29028,
       -0.97003,-0.24298,
       -0.98079,-0.19509,
       -0.98918,-0.14673,
       -0.99518,-0.09802,
       -0.99880,-0.04907,
 };

void FFT(COMPLEX *Y, int N, int signo);
      



//------------------------------
//arrancamos un nuevo programa
//-------------------------------
int main (void){
		Usart_init_0 (9600);
		char* dataBuff = NULL;	
				int i,o,pata,j,mag,calibrar,porcentaje,r,escala,s;
				int prueba[1280];
				float l,tesla,real,imag,componentes[11],porcentajes[10];
				COMPLEX senal[128];
		// Initialize system
		System_init ();
		// Init digital IO
		DigitalIO_init (PB3|AT91C_PIO_PA28, LED1|LED3);			// LED1 as output
		DigitalIO_init (PB4, LED2);
		DigitalIO_clear (PB3);
		// Init ADC
		ADC_init ( 18000, AT91C_ADC_CH4 );	// Sample ADC_CH_4 at 18000 Hz
		LCDInit();                          //LCD Initialization
		 LCDSendCommand(CLR_DISP);           
						     LCDSendCommand(DD_RAM_ADDR);        
						    
						     DigitalIO_clear (LED3);
						 
							 LCDSendCommand(CLR_DISP);  				  		   								 
							 LCDSendTxt(" Bienvenido");
							 delay(50);
							 pata=0;	
							 
							 
							 
							while(1)
							 {	 
								 LCDSendCommand(CLR_DISP);  				  		   								 
								 LCDSendTxt("P1.Campo Magnetico");
								 LCDSendCommand(DD_RAM_ADDR2);
								 LCDSendTxt("P2.Analisis");
								 delay(10);
							
							if(!((l_pPio->PIO_PDSR) & PB3))
							  {
								 delay(50);
								  menu=1;					 																	 				  
								  
							  }
			
							 		 				 
							  if(!((l_pPio->PIO_PDSR) & PB4))
							  {
								  delay(50);
								  menu=2;						  
							  }					  
							  		
							
						  
					 
				  
				  switch(menu){
				  		   			case 1:
				  		   			      LCDSendCommand(CLR_DISP); 
				  		   			      LCDSendTxt("Campo Magnetico");
				  		   			      s=0;
			  		   					  while(s==0)
			  		   					  {
			  		   						if (rx_adc_buff_full)
			  		   						{
			  		   							rx_adc_buff_full = 0;									// Clear buffer full flag
			  		   							  		   							
			  		   							if (adcRxBuffer == ADC_BUFF_0) 
			  		   							{
			  		   								
			  		   								mag=0;
			  		   								for(i=500;i<600;i++)
			  		   								{
			  		   									mag=adcBuff_0[i]+mag;
			  		   								}
			  		   							  		   							                 
			  		   								mag=mag/100;	
			  		   								escala=0;
			  		   								LCDSendCommand(CLR_DISP); 
			  		   								LCDSendTxt("P1.Escala 1");
			  		   								LCDSendCommand(DD_RAM_ADDR2);
			  		   							    LCDSendTxt("P2.Escala 2");
			  		   								
			  		   								
			  		   								while(escala==0)
			  		   								{
			  		   									if(!((l_pPio->PIO_PDSR) & PB3))
			  		   									{				  		   														 
			  		   										escala=37;					 																	 				  			     														  
			  		   									}
			  		   									if(!((l_pPio->PIO_PDSR) & PB4))
			  		   									{				  		   														 
			  		   										escala=16;					 																	 				  			     														  
			  		   									}
			  		   									
			  		   								}
			  		   								l=mag*5000/(1023*escala);
			  		   								tesla=l/800; 
			  		   							    LCDSendCommand(CLR_DISP);
			  		   							    LCDSendTxt("Campo Magnetico");
			  		   								LCDSendCommand(DD_RAM_ADDR2);	  		   							                
			  		   								LCDSendtesla(tesla);
			  		   								delay(15);
			  		   							if(!((l_pPio->PIO_PDSR) & PB3))
			  		   							{
			  		   							  delay(500);
			  		   							  s=1;					 																	 				  
			  		   															  
			  		   							}
			  		   								menu=0;
			  		   							  		   							                 
			  		   							}
			  		   							  		   							
			  		   						}
			  		   					}	
			  		   	
				  		   				    return 0;	
				  		   				    break;
				  		   		case 2:
  		   							LCDSendCommand(CLR_DISP); 				   				    
  		   							if(rx_adc_buff_full==1)
  		   							{   
  		   								LCDSendTxt("Mirar motor");   
  		   								rx_adc_buff_full=0;				
  		   								delay(10);	
  		   								calibrar=0;
  		   								o=0;
  		   								LCDSendCommand(CLR_DISP);
  		   								LCDSendTxt("Pulsar P2 para");
  		   							    LCDSendCommand(DD_RAM_ADDR2);
  		   								LCDSendTxt("empezar");
  		   								delay(1000);
  		   						
  		   								while(calibrar==0)
  		   								{
  		   									if(!((l_pPio->PIO_PDSR) & PB4)) // chequea el pulsador 4
  		   									{
  		   										LCDSendCommand(CLR_DISP);
  		   										LCDSendTxt("Calibrando..."); 
  		   										delay(10);
  		   										calibrar=1;
  		   									}
  		   								}
  		   					    
  		   						
  		   								while(calibrar==1)
  		   								{
  		   									for(i=0;i<1280;i++)
  		   									{
  		   										o=adcBuff_0[i]+o;
  		   									}
  		   									o=o/1280;
  		   									if(o!=0)
  		   									{
	  		   									while(calibrar!=10)
	  		   									{
	  		   									    LCDSendCommand(CLR_DISP);
	  		   										LCDSendTxt("Pulsar P2 para"); 
	  		   									    LCDSendCommand(DD_RAM_ADDR2);
	  		   		     							LCDSendTxt("continuar");
	  		   		     						    delay(10);
	  		   		     						    r=0;
	  		   		     						   while(r!=1) 
	  		   									   if(!((l_pPio->PIO_PDSR) & PB4)) // chequea el pulsador 4
	  		   								       {
	  		   										 		  		  
	  		   										 calibrar=10;
	  		   										 r=1;
	  		   										 
	  		   												  		   									
	  		   									   }	
	  		   									}
  		   										
  		   										calibrar=0;			 		   							
  		   										
  		   							
  		   									}		  		   						
  		   								}
  		   								for (i=0; i<128; i++)
  		   								{
  		   									// senal[i].real = prueba[j];
  		   									senal[i].real = adcBuff_0[j]-o;
  		   									j = j+10;
  		   									senal[i].imag=0;
  		   								}    	
  		   								i=0;
  		   								j=0;		  		   						
  		   								FFT(senal,128,1);
  		   						
  		   								for(i=0;i<11;i++)
  		   								{
  		   									real=senal[i].real;
  		   									imag=senal[i].imag;
  		   									componentes[i]=sqrt((real*real)+(imag*imag));
  		   									
  		   								}
  		   						
  		   								LCDSendCommand(CLR_DISP);
  		   								LCDSendTxt("P1 al 3%");
  		   								LCDSendCommand(DD_RAM_ADDR2);
  		   								LCDSendTxt("P1 al 1%");
  		   								porcentaje=0;
  		   								while(porcentaje==0)
  		   								{
  		   									if(!((l_pPio->PIO_PDSR) & PB3))
  		   									{
  		   										porcentaje=103;
  		   									}
  		   									if(!((l_pPio->PIO_PDSR) & PB4))
  		   									{
  		   										porcentaje=101;
  		   									}
  		   								}
  		   							    
  		   								for(i=0;i<10;i++)
  		   								{   LCDSendCommand(CLR_DISP);
		   								        LCDSendTxt("Analizando");
  		   									porcentajes[i]=(componentes[i+1]/componentes[0])*100;	
  		   									delay(10);		  		   								   
  		   								}
  		   								if(porcentajes[0]>=porcentaje)
  		   								{
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   									LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 2");
  		   									delay(10);
  		   								}
  		   							    if(porcentajes[1]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 3");
  		   									delay(10);
  		   								}
  		   								
  		   							    if(porcentajes[2]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 4");
  		   									delay(10);
  		   								}
  		   							    
  		   							    if(porcentajes[3]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 4");
  		   									delay(10);
  		   								}
  		   							    if(porcentajes[4]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 5");
  		   									delay(10);
  		   								}
  		   							    if(porcentajes[5]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 6");
  		   									delay(10);
  		   								}
  		   							    if(porcentajes[6]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 7");
  		   									delay(10);
  		   								}
  		   							    if(porcentajes[7]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 8");
  		   									delay(10);
  		   								}
  		   							    if(porcentajes[8]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 9");
  		   									delay(10);
  		   								}
  		   							    if(porcentajes[9]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 10");
  		   									delay(10);
  		   								}
  		   							    if(porcentajes[10]>=porcentaje)
  		   							    {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Problema en ");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("armonico 11");
  		   									delay(10);
  		   								}
  		   							    r=0;
		   									LCDSendCommand(CLR_DISP);
		   									LCDSendTxt("Pulsar P2 para");
		   								    LCDSendCommand(DD_RAM_ADDR2);
		   									LCDSendTxt("mostrar reporte");
		   									
  		   							    
  		   							   while(r!=10)
  		   							   {
  		   								 
  		   								 if(!((l_pPio->PIO_PDSR) & PB4))
  		   								{
  		   								   r=10;
  		   								   delay(10);
  		   								} 
  		   								 
  		   							   }
  		   							   pata=0;
  		   							   if((porcentajes[7]>=porcentaje)&(porcentajes[10]>=porcentaje))
  		   							   {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Posible Problema");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("Desbalance");
  		   									delay(5);
  		   									pata=1;
  		   							   }
  		   							   if((porcentajes[2]>=porcentaje)&(porcentajes[7]>=porcentaje)&(porcentajes[9]>=porcentaje))
  		   							   {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Posible Problema");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("Rodamiento");
  		   									delay(5);
  		   								    pata=1;
  		   							   }
  		   							   if((porcentajes[2]>=porcentaje)&(porcentajes[7]>=porcentaje)&(porcentajes[10]>=porcentaje))
  		   							   {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Posible Problema");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("Excentricidad");
  		   									delay(5);	
  		   								    pata=1;
  		   							   }
  		   							   if((porcentajes[2]>=porcentaje)&(porcentajes[5]>=porcentaje))
  		   							   {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Posible Problema");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("Aislamiento");
  		   									delay(5);	
  		   								    pata=1;
  		   							   }
  		   							   if((porcentajes[5]>=porcentaje)&(porcentajes[7]>=porcentaje))
  		   							   {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Posible Problema");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("Envejecimiento");
  		   									delay(5);	
  		   								    pata=1;
  		   							   }
  		   							   if((porcentajes[3]>=porcentaje)&(porcentajes[7]>=porcentaje))
  		   							   {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("Posible Problema");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("Estator");
  		   									delay(5);
  		   								    pata=1;
  		   							   }
  		   							   if(pata==0)
  		   							   {
  		   									LCDSendCommand(CLR_DISP);
  		   									LCDSendTxt("No hay ningun");
  		   								    LCDSendCommand(DD_RAM_ADDR2);
  		   									LCDSendTxt("Problema");
  		   									delay(5);
  		   								    pata=1;
  		   								   
  		   							   }   							     		   							  		  		   			  		   			  		   			  		   			  		   			  		   			  		   			  		   			  		   			  		   			  		   							    
  		   								menu=0;
  		   						   /* while(r!=11)
  		   						   {
  		   							  		   								 
  		   							  if(!((l_pPio->PIO_PDSR) & PB4))
  		   							  {
  		   							     r=11;
  		   							  	 delay(10);
  		   							  } 
  		   							  		   								 
  		   							}*/
  		   							Usart_puts_0("Prueba\n\r",8);
  		   								delay(10);
  		   						
  		   							}		
  		   							menu=0;
				  		   		break;
				  		   		
				  		   												  		   		
				  		   						  		   
				  		   			
				  					default:
				  		   				break;
				  		   		}
				  		   		
				
	
}
}

void LCDInit()
{
  // First set D4, D5, D6, D7, RS, RW, E to output ports 
	DigitalIO_init (0, AT91C_PIO_PA16|AT91C_PIO_PA17|AT91C_PIO_PA18|AT91C_PIO_PA19|AT91C_PIO_PA20|AT91C_PIO_PA21|AT91C_PIO_PA22);			



  l_pPio->PIO_CODR = BIT20|BIT21|BIT22;   //clear RS, E, RW
  delay(800);                      //delay ~110ms

  l_pPio->PIO_SODR = BIT16|BIT17;         //set D4 and D5 port to 1
  E_Pulse();                              //high->low to E port (pulse)

  delay(3000);                       //delay ~10ms

  l_pPio->PIO_SODR = BIT16|BIT17;         //set D4 and D5 port to 1
  E_Pulse();                              //high->low to E port (pulse)

  delay(3000);                       //delay ~10ms

  l_pPio->PIO_SODR = BIT16|BIT17;         //set D4 and D5 port to 1
  E_Pulse();                              //high->low to E port (pulse)

  delay(3000);                       //delay ~10ms

  l_pPio->PIO_CODR = BIT16;               //set D4 port to 0
  l_pPio->PIO_SODR = BIT17;               //set D5 port to 1
  E_Pulse();                              //high->low to E port (pulse)

  delay(3000);                       //delay ~10ms
}

void LCDSendCommand(unsigned long a)
{

  l_pPio->PIO_CODR =  BIT22;                  //set RW port to 0

  delay(6000);                            //delay for LCD char ~2ms

  data = 0x0;                                 //clear data

  data = 0xffffff0f | a;                      //get high 4 bits

  l_pPio->PIO_CODR = BIT16|BIT17|BIT18|BIT19; //clear D4-D7

  data = data << 12;                          //shift data

  l_pPio->PIO_SODR = 0x000f0000 & data;       //set data

  l_pPio->PIO_CODR =  BIT20;                  //set RS port to 0 -> display set to comand mode

  E_Pulse();                                  //pulse to set d4-d7 bits

  data = 0x0;                                 //clear data

  a = a<<4;                                   //shift to get low 4 bits

  data = 0xffffff0f | a;                      //get low 4 bits

  l_pPio->PIO_CODR = BIT16|BIT17|BIT18|BIT19; //clear D4-D7

  data = data << 12;                          //shift data

  l_pPio->PIO_SODR = 0x000f0000 & data;       //set D4-D7

  l_pPio->PIO_CODR =  BIT20;                  //set RS port to 0 -> display set to comand mode

  E_Pulse();                                  //pulse to set d4-d7 bits

}

void LCDSendChar(unsigned long a)
{
  l_pPio->PIO_CODR =  BIT22;                  //set RW port to 0

  delay(6000);                              //delay for LCD char ~2ms

  data = 0x0;                                 //clear data

  data = 0xffffff0f | a;                      //get high 4 bits

  l_pPio->PIO_CODR = BIT16|BIT17|BIT18|BIT19; //clear D4-D7

  data = data << 12;                          //shift data

  l_pPio->PIO_SODR = 0x000f0000 & data;       //set data

  l_pPio->PIO_SODR =  BIT20;                  //set RS port to 1 -> display set to character mode

  E_Pulse();                                  //pulse to set d4-d7 bits

  data = 0x0;                                 //clear data

  a = a<<4;                                   //shift to get low 4 bits

  data = 0xffffff0f | a;                      //get low 4 bits

  l_pPio->PIO_CODR = BIT16|BIT17|BIT18|BIT19; //clear D4-D7

  data = data << 12;                          //shift data

  l_pPio->PIO_SODR = 0x000f0000 & data;       //set D4-D7

  l_pPio->PIO_SODR =  BIT20;                  //set RS port to 1 -> display set to character mode

  E_Pulse();                                  //pulse to set d4-d7 bits
}

void LCDSendTxt(char* a)
{
  for(int i=0; i<strlen(a); i++)
  {
    LCDSendChar(a[i]);
  }
}

void LCDSendInt(int a)
{
  int h = 0;
  int l = 0;
  int r = 0;


  l = a%10;
  h = a/10;
  h = h%10;
  r = a/100;
  r = r%10;
  
  
  LCDSendChar(r+48);
  LCDSendChar(h+48);
  LCDSendChar(l+48);
}
void LCDSendtesla(float a)
{
  int h = 0;
  int l = 0;
  int r = 0;
  int o = 0;

  o = a*1000;
  l = o%10;
  h = o/10;
  h = h%10;
  r = o/100;
  r = r%10;
  
  LCDSendTxt("0.");
  LCDSendChar(r+48);
  LCDSendChar(h+48);
  LCDSendChar(l+48);
  LCDSendTxt("   Tesla");
}

void E_Pulse()
{
  l_pPio->PIO_SODR = BIT21;   //set E to high
  delay(9000) ;            //delay
  l_pPio->PIO_CODR = BIT21;   //set E to low
}
void delay (int divisor)
{
	//* Set in Volatile for Optimisation
    volatile unsigned int    i ;
	//* loop delay
    for ( i = 0 ;(i < WAIT_TIME/divisor );i++ ) ;
}

void FFT(COMPLEX *Y, int N, int signo) /*FFT de vector de N puntos*/
 {
  COMPLEX temp1,temp2;      /*temporary storage variables       */
  int i,j,k;                /*loop counter variables            */
  int upper_leg, lower_leg; /*index of upper/lower butterfly leg*/
  int leg_diff;             /*difference between upper/lower leg*/
  int num_stages=0;         /*number of FFT stages, or iterations*/
  int index, step;         /*index and step between twiddle factor*/
  float scale;              /*Para escalar en la ifft           */
/* log(base 2) de N puntos = M fases o estados  */
  i=1;
  do
    {
     num_stages+=1;
     i=i*2;
    } while (i!=N);
/* starting difference between upper and lower butterfly legs*/
  leg_diff=N/2;
/* step between values in twiddle factor array twid64.h     */
  step=128/N;
/* For N-point FFT                                           */
  for (i=0;i<num_stages;i++)  /*tantas iteraciones como fases*/
    {
    index=0;
    for (j=0;j<leg_diff;j++) /*tantas iteraciones como transfor-*/
      {                      /*madas en cada fase*/
        for (upper_leg=j;upper_leg<N;upper_leg+=(2*leg_diff))
        {  /*tantas iteraciones como puntos en cada transformada*/
        lower_leg=upper_leg+leg_diff;
        temp1.real=(Y[upper_leg]).real + (Y[lower_leg]).real;
        temp1.imag=(Y[upper_leg]).imag + (Y[lower_leg]).imag;
        temp2.real=(Y[upper_leg]).real - (Y[lower_leg]).real;
        temp2.imag=(Y[upper_leg]).imag - (Y[lower_leg]).imag;
        (Y[lower_leg]).real=temp2.real*(w[index]).real - temp2.imag*signo*(w[index]).imag;
        (Y[lower_leg]).imag=temp2.real*signo*(w[index]).imag + temp2.imag*(w[index]).real;
        (Y[upper_leg]).real=temp1.real;
        (Y[upper_leg]).imag=temp1.imag;
        }
      index+=step;
      }
    leg_diff=leg_diff/2;
    step*=2;
    }
/* bit reversal for resequencing data */
  j=0;
  for (i=1;i<(N-1);i++)
    {
    k=N/2;
    while (k<=j)
      {
      j=j-k;
      k=k/2;
      }
    j=j+k;
    if (i<j)
      {
      temp1.real=(Y[j]).real;
      temp1.imag=(Y[j]).imag;
      (Y[j]).real=(Y[i]).real;
      (Y[j]).imag=(Y[i]).imag;
      (Y[i]).real=temp1.real;
      (Y[i]).imag=temp1.imag;
      }
    }
  if (signo==-1)
   {
     scale = (float)(1.0/N);
     for (i = 0; i < N; i++)
      {
        (Y[i]).real = scale*(Y[i]).real;
        (Y[i]).imag = scale*(Y[i]).imag;
      };
   };
    return;
}
