
#include <STDIO.H>

#include <C8051F040M.H>  //8051C040
//#include <C8051F040M2.H>	//8051C023 pro simulaci

#include <math.H>

//#include <I2c.h>


const int posedge=0x21, negedge=0x11; //definice nastaveni pro pole citacu
	
unsigned int a=50;//a - z kolika hodnot podle Archive_Base se bere do archivu
unsigned int valsend=1; //valsend z kolika ZMERENYCH max na com, mereno cca 500/s, 
						 //minimalne 1, port to stiha ale je toho MOC	
unsigned int Lcd_tm=1525; //citac 1 dava preruseni za 3050/s
unsigned int Archive_Base=305; 

unsigned char com_RDY;*i2cpointer,adresa,j[4],stop,archive,comindex,comlenght,odeslat,k,values;	  
int fall[2],rise[2],fallold[2],per[2],act[2],s,s2,h,p=450,i;//kdyz zmenis pocet hodnot k archovaci					
																	// "p" zmen i rozmer zrychleni
float maxacc[2],maxacclcd[2],maxaccold[2],zrychlenix [450],zrychleniy [450],tmp,aacc[2],corr[2],maxCOM[2];

unsigned char tx_buf[16];
unsigned char slave_i2c=0x14;   // Adresa slave zarizeni na I2C sbernici

bit SM_BUSY;
unsigned char WORD, Byte_Number;
#define  EIEEN  0x0A 	//extended interrupt enable



#include <LCD.c>



float pocitej () 
	{
	per[i]=fall[i]-fallold[i];
	if (per[i]<0)
		per[i]+=32576;
	act[i]=rise[i]-fall[i];
	if (act[i]<0)
		act[i]+=32576;
	
	fallold[i]=fall[i];
	tmp=(20*((float)act[i]/per[i]-0.5)-corr[i]);
	if(fabs(tmp)>15)
		{
		if (tmp>0)  tmp=15;
			else	tmp=-15;
		}
	
	return  tmp;
	}









void posliCOM(float c, float d)
{
		com_RDY=0;
		sprintf (tx_buf,"%-.2f %-.2f;  ",c,d);
		//tx_buf[14]=0x0D;
		//tx_buf[15]=0x0A;
		
		comindex	=	0; //nulovani indexu COM portu
		SFRPAGE	=	0x01;
		TI1		=	1;		//start prenosu pres COM
		SFRPAGE	=	0x00;
		comlenght=16;
		
}
void com() interrupt 20 
{

//EIE1=0x00;		//aby se preruseni neprerusovaly..
if (59==tx_buf[comindex]) // strednik ynamena konec radku
	{ 
	tx_buf[comindex+1]=0x0D;
	tx_buf[comindex+2]=0x0A;
	comlenght=comindex+3;	//delka retezce
	
	}
	//po enteru nastavit ready

SFRPAGE	=	0x01;

if (comindex<comlenght) SBUF1=tx_buf[comindex];
comindex++;
TI1 =	0;
SFRPAGE	=	0x00;

if (comindex==comlenght) com_RDY=1;
//EIE1=EIEEN;	//tady zase muze, obsluha COM je kratka, nevadi...
}

//#include <nacti.c>
void nacti() interrupt 9 
{

unsigned char pocitat[2];

	if 	(1==CCF0)  //preruseni z counteru0
	{
		i=0;
		if (posedge==PCA0C0) //reakce  na nabeznou hranu
		   	{
			
			rise[i]=PCA0L0;
			rise[i]+=PCA0H0<<8;	  // nacteni 2 8bit reg
			PCA0C0=negedge;	//prepnuti na cekani na sestupnou
			
			pocitat[i]=1;
			values++;
			} 
				
		else 		//reakce na sestupnou hranu
			{
		
			fall[i]=PCA0L0;
			fall[i]+=PCA0H0<<8;
			PCA0C0=posedge;
		
			};
		
	

	CCF0=0;
	};
 ///////////////////////////////////////////////////

	if 	(1==CCF1)  //preruseni z counteru1 DEJ i=1
	{
	i=1;
	if (posedge==PCA0C1) //reakce  na nabeznou hranu
		   	{
		
			rise[i]=PCA0L1;
			rise[i]+=PCA0H1<<8;
			
			PCA0C1=negedge;	//prepnuti na cekani na sestupnou
			
			pocitat[i]=1;
			} 
				
		else 		//reakce na sestupnou hranu
			{
		
			fall[i]=PCA0L1;
			fall[i]+=PCA0H1<<8;
						
			PCA0C1=posedge;
		
			};
		
 //////////////////////////////////////////////////////



	CCF1=0;

	};
for (i=0;i<2;i++)
	{
	if (1==pocitat[i])
		{
		pocitat[i]=0;
		
		tmp=pocitej();
		aacc[i]=tmp;
		if (s<0) aacc[i]=0;
			if (fabs(maxacc[i])<fabs(tmp))
				{
				maxacc[i]=tmp;  //maximalni zrychleni
				}
			if (fabs(maxCOM[i])<fabs(tmp))
				{
				maxCOM[i]=tmp;  //maximalni zrychleni
				}
		}
	
	}





 //EA=1;  //enable  int.


}



char putchar (char c)
{
  
	
	  if(c=='\n')
    	LCDpozice(0,1);
  		else
    	LCDdata(c);
  		return c;

}


void ctikbd()
{
int pocet;
unsigned char prvnia,prvnis;
float pom;
	{
	switch (P2)
		{
		case 0xBF:				//STOP
		 	
				 						  //priznak stop
			if 	(0==stop) 
				{
				EIE1=0x00;					//vypnuti mereni
				stop=1;
				prvnia=1;					//PRVNI VSTUPY DO NASTAVENI MNOZSTVI NEMENI NASTAVENI
				prvnis=1;
				printf("X=%.2 fG   STOP \nY=%.2 fG ",zrychlenix[j[1]],zrychleniy[j[1]]);
				LCDpozice(0,0);
				h=j[1];
				pocet=p;
				
				while (0xBF==P2);
				}
				
				else 
				{
				while (0xBF==P2);
				stop=0;
				
				
				

				PCA0C0 = negedge;
				PCA0C1 = negedge;
				CCF0=1;
				CCF1=1;
				EIE1=EIEEN;					
				maxacc[0]=0;
				maxacc[1]=0;
				aacc[0]=0;
				aacc[1]=0;
				
				s=-20;
				}
			
				
				break;
		  
		
		case 0xEF:			//ZERO
		    //if (1==stop)
		 		//	{
			
				corr[0]+=maxacc[0]*0.9;  //empiricka konstanta, aby to lip fungovalo :-)
				corr[1]+=maxacc[1]*0.9;
				s=-5;
				printf("X=%.2 fG   ZERO \nY=%.2 fG ",aacc[0],aacc[1]);
				LCDpozice(0,0);
				prvnia=1;
				prvnis=1;				

				while (0xEF==P2);
			
				
			//	}

				break;


		case 0xFB:		//LCDINIT
			//if (1==stop)
			//	{
				
				EA=0;
				LCDinicializace();
				s=-5;
				printf("X=%.2 fG   INIT \nY=%.2 fG ",maxacc[0],maxacc[1]);
				LCDpozice(0,0);
				
				prvnia=1;
				prvnis=1;
						
				while(0xFB==P2);
				EA=1;				

			//	}
				
		

				break;
		
		case 0xDF: 		//history back

			if (1==stop)
				{
				prvnia=1;
				prvnis=1;
				h--;
				if (h<0) h=p-1;
				pocet--;
				if (pocet<1) pocet=p;
				LCDpozice(0,0);
				printf("X=%.2 fG   HIST \nY=%.2 fG %i/%i  " ,zrychlenix[h],zrychleniy[h],pocet,p);
				LCDpozice(0,0);				

				while(0xDF==P2);

				}

				break;

		case 0x7F:    //history fwd

			if (1==stop)
				{
				prvnia=1;
				prvnis=1;
				h++;
				if (h>(p-1)) h=0;
				
				pocet++;
				if (pocet>p) pocet=1;
				
				LCDpozice(0,0);
				printf("X=%.2 fG   HIST \nY=%.2 fG %i/%i  ",zrychlenix[h],zrychleniy[h],pocet,p);
				LCDpozice(0,0);
				
				while(0x7F==P2);

				}

				break;
		
		case 0xF7:  // history send

			if (1==stop)

				{
				prvnia=1;
				prvnis=1;
				h=j[1];			//zacatek historie
				while (0==com_RDY);
				while(0xF7==P2);				
				printf("X=%.2 fG SENDING \nY=%.2 fG        ",zrychlenix[j[1]],zrychleniy[j[1]]);
				LCDpozice(0,0);

				for (k=0;k<p;k++)
					{
					if (0==com_RDY)
						{
						k--;  //cekani na volny port
						}	
						
						else
						{
						
						posliCOM (zrychlenix[h],zrychleniy[h]);
						h--;
						
						if (h<0) h=p-1;
						
						}

					
				
					}
												
				
				}
				h=j[1];
			
			for (k=0;k<500;k++) //pauza
				{
				k++;
				k--;
				}	
			
			if (1==stop) printf("X=%.2 fG   STOP \nY=%.2 fG ",zrychlenix[j[1]],zrychleniy[j[1]]);
			LCDpozice(0,0);

			break;

		case 0xFE:				//NASTAVENI MNOZSTVI ODESILANYCH DAT
			if (1==stop)
			if (1==prvnis)
				{
				prvnis=0;
				pom=(float)500/valsend;
				printf("Value send SPEED  \n   %.0f/s          ",pom);	
				LCDpozice(0,0);	
				}		
			else
			{

			
			switch(valsend)
				{
				case 1:
					valsend=5;
					break;

				case 5:
					valsend=10;
					break;

				case 10:
					valsend=50;
					break;

				case 50:
					valsend=100;
					break;

				case 100:
					valsend=500;
					break;
									
				case 500:
					valsend=1;
					break;
				}
			
			pom=(float)500/valsend;
			printf("Value send SPEED  \n   %.0f/s       ",pom);	
			LCDpozice(0,0);
			}		
			while (0xFE==P2);
				
			break;

		
		case 0xFd:					//NASTAVENI MNOZSTVI ARCHIVOVANYCH DAT
			if (1==stop)
			{
			if (1==prvnia)
				{
				prvnia=0;
				
				printf("Archive MAX every    \n Ta=%.1 fs          ",pom);
				LCDpozice(0,0);	
			
				}
			
			else
			{
			switch(a)
			{ 
				case 1:
					a=2;
					break;

				case 2:
					a=5;
					break;
					
				case 5:
					a=10;
					break;

				case 10:
					a=20;
					break;

				case 20:
					a=50;
					break;

				case 50:
					a=100;
					
					break;
									
				case 100:
					a=300;
					break;
				
				case 300:
					a=600;
					break;
								
				case 600:
					a=1;
					break;

				}
			}

			pom=(float)a*((float)Archive_Base/3050);
			printf("Archive MAX every    \n Ta=%.1fs          ",pom);
			LCDpozice(0,0);	
			while (0xFd==P2);
			}	
		
		default:
		
		break;
		}
	}
}





 

void interval() interrupt 1 
{

	s++;
	s2++;
	TF0=0;
	if (0>s)
		{
		maxacc[0]=0;
		maxacc[1]=0;
		zrychlenix[j[1]]=0;
		zrychleniy[j[1]]=0;		
		archive=0;
		}
	else
	{
	if (0==stop)
	
	{
	if ((valsend-1)<values)  //redukce datoveho toku, jinak toho je fakt mega moc, values>pocet vypocitanych hodnot
		{
		if (1==com_RDY)

			{ 
			posliCOM(maxCOM[0],maxCOM[1]);
			maxCOM[0]=0;
			maxCOM[1]=0;
			values=0;
			}
		}
			
	ctikbd();
	if (Archive_Base<s2)
		{


		//zrychlenix[j[1]]=maxacc[0];	 
		//zrychleniy[j[1]]=maxacc[1];	
		if (fabs(maxacc[0])>fabs(zrychlenix[j[1]])) zrychlenix[j[1]]=maxacc[0];
		if (fabs(maxacc[1])>fabs(zrychleniy[j[1]])) zrychleniy[j[1]]=maxacc[1];	
		if (fabs(maxacc[0])>fabs(maxacclcd[0])) maxacclcd[0]=maxacc[0];
		if (fabs(maxacc[1])>fabs(maxacclcd[1])) maxacclcd[1]=maxacc[1];
		maxacc[0]=0;
		maxacc[1]=0;
		
		archive++;
		if (archive>a)
			{
			archive=0;		//maximum z kolika hodnot se zaznamena > cas zaznamu
			j[1]=j[1]+1;
			if ((p-1)<j[1]) j[1]=0;
			}
		
				

		s2=0;
		
		}
	if (Lcd_tm<s) //nastaveni intervalu vypisu na LCD, 
	{
	ET0	=	0;	


	
		printf("X=%.2 fG   RUN  \nY=%.2 fG           ",maxacclcd[0],maxacclcd[1]);
		LCDpozice(0,0);
			
		maxacclcd[0]=0;
		maxacclcd[1]=0;

		
			//uzavreny cyklus hodnot..
		s=0;
			
	ET0=1;	
	}	
	
	
}
else
  {
  ctikbd();
  }
  }
}	  



void main (void)
{
	WDTCN = 0xde;			//watchdog disable
   	WDTCN = 0xad;
	SFRPAGE = CONFIG_PAGE;                 // Switch to configuration page

//	P1MDOUT	=	0xFF;	// nastaveni portu 1 jako push-pull (asi nemusi byt, ma pull-up rezistory)
	XBR0	=	0x11;  // XBR0.0 smbus, XBR0.3>5 PCA, pro cex0 a 1 zapsat 010, zapnuty PCA, SMB
	
	XBR1	=	0x80;  // XBR2.6 Crossbar Enable !!!! jinak to nejede BLBCE :-)
	XBR2    = 	0x44;  // zapnuty UART1  a XBAR ENABLE
						//musis tady nastavit crossbar, aby vedel kde ma port!!!!!
 	
	LCDinicializace();// co nejdriv, trva to tak aby z toho nebyl binec
	LCDpodsviceni(1); //jen aby to nekricelo, stejne nebude pouzito, nechce se mi to mazat
	LCDvymaz();
	printf("X=%.2 fG   STOP \nY=%.2 fG ",maxacc[0],maxacc[1]);
													    	
	
	SFRPAGE	= 0x0f;
	OSCICN	=	0xc3;	//sysclk /1	
	P0MDOUT	=	0x04;	//COM port do push/pull
	SCON1	=	0x00;    //com port.. nema enable flag..
	SFRPAGE = 	0x00;


	PCA0C0 	=	0x11; //0010 0001 pca0 0 zachytny rezim pozitivni hrana, povoleni INT od tohoto modulu
	PCA0C1  =	0x11; //pca0 1 zachytny rezim negativni hrana 00010001, aby byl prvni vysledek normalnejsi...
	PCA0MD	= 	0x08; //counter mode pole citacu zaonuto, kmitocet oscilatoru 
	
	CCF0	=	0 ;   //vychozi inicializace, aby preruseni nevzniklo "preventivne hned pri povoleni"
	CCF1	=	0 ;
	//XBR0	= 	0x08; //nastaveni crossbar, vstupy PCA0,1 na P0.0,1
	
	
//	ENSMB	=	1;
//	SMB0CR 	=	 0x9e;// SMBus clock rate 
//	SM_BUSY = 	0;    // pripraveni SMBUS na pouziti
//	SMB0ADR	=	0x20;
//	EIP1	=	0x0A;	//priorita preruseni z PCA a SMBUS	na HIGH

	EIE1 	= 	EIEEN; //povoleni preruseni z PCA0 a SMBUS
	EIE2	=	0x40;	//UART1 interrupt enable
	EIP1	=	0x08; //PCA priority HIGH
	EIP2	=	0x40;	//com1 high priority


	maxacc[0]=0;
	maxacc[1]=0;
	stop=0;
	j[0]=0;
	j[1]=0;
	s=-20; 	// stabilizace, aby nesly prvni nejaky haluze
	corr[0]=0;
	corr[1]=0;
	
	for (i=0;i<p;i++)
		{
		zrychlenix[i]=0;
		zrychleniy[i]=0;	

		}

	CKCON 	=	0x18; //casovac 0 sysclk, casovac 1 sysclk pro tmr0 sysclk/12 10
	TMOD	=	0x20; //13bit citac TM0, auto reload TM1
	TH1		=	0x96; // reload tm1, 2B pro UART1 57kBd
	TL1		=	0x96;	
	TCON	=	0x50; //timer0,1 run
	com_RDY	=	1;     // COM port ready

	ET0		=	1;    //interrupt enable timer 0
	CR		=	1;    //counter run PCA0
	EA		=	1; 	  //globalni povoleni INT

while(1);

}