


#define INTERVAL 0x135AFD  // interval definuje rychlost provadeni hlavni smycky
#define OTACKOMER 3000000  //konstanta prevodu otacek. 3000000 = 4valec jednobodove vstrikovani
//#define OTACKOMER 12000000  //12000000 = 4valec vicebodove vstrikovani nebo sonda na jednom valci
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x.h"
#include "stdio.h"
#include "STM32vldiscovery.h"
#include "lcd.h"
#include "font_arial.h"
#include <string.h>
#include <stdlib.h>
#include "gps.h"
#include "DS18B20.h"
#include "buttons.h"
#include "stm32f10x_usart.h"
#include "ff.h"



/* Globalni promenne ------------------------------------------------------------------*/
volatile char exitmenu,zaznam;
uint8_t horni,spodni;
uint8_t tmp_pole[7];
int16_t teploty[3];
uint16_t casovac[3];
uint32_t dly;
 
char datum[7]={0,0,0,0,0,0,0};
char cas[7]={0,0,0,0,0,0,0};
char lat[10]={0,0,0,0,0,0,0,0,0,0};
char lon[11]={0,0,0,0,0,0,0,0,0,0,0};

FATFS Fatfs;		/* File system object */
FIL Fil;			/* File object */
BYTE Buff[128];		/* File read buffer */
char WBuff[740];	 // buffer pro zapis na kartu
volatile unsigned int offset=0;
volatile unsigned int fileoffset=0;
FRESULT rc;				/* Result code */
UINT bw;

GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
 

/* Funkce ------------------------------------------------------------------*/

void Delay(__IO uint32_t nCount);

/* konfigurace modulu NVIC (vektory preruseni) */ 
void NVIC_Configuration(void) 
{ 
  NVIC_InitTypeDef NVIC_InitStructure;
  EXTI_InitTypeDef EXTI_InitStructure; 
  /* Umisteni tabulky vektoru do FLASH */ 
  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); 
  /* Povoleni preruseni od USART1 */ 
  NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; 
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; 
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; 
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 
  NVIC_Init(&NVIC_InitStructure);

  GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource3);
    /* Configure Button EXTI line */
  EXTI_InitStructure.EXTI_Line = EXTI_Line3;
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;  
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
  NVIC_ClearPendingIRQ(EXTI3_IRQn); 
  NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
} 


  void TX(unsigned char data){
 while (USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
 USART_SendData(USART1,data);}


  void saticon(uint8_t x, uint8_t y){
  uint8_t i;
  for(i=1;i<6;i++){
  LCDSetDot(x+i,y,BLACK);
  LCDSetDot(x+i,y+1,BLACK);
  LCDSetDot(x+i,y+8,BLACK);
  LCDSetDot(x+i,y+9,BLACK);
  }
  LCDSetDot(x+3,y+2,BLACK);
  LCDSetDot(x+3,y+3,BLACK);  
  LCDSetDot(x+2,y+4,BLACK);   
  LCDSetDot(x+2,y+5,BLACK);
  LCDSetDot(x+4,y+4,BLACK);   
  LCDSetDot(x+4,y+5,BLACK);
  LCDSetDot(x+3,y+6,BLACK);
  LCDSetDot(x+3,y+7,BLACK); 
}

void rpmtostr(uint16_t in, uint8_t *out){

out[0]=(in/1000);
out[1]=((in-1000*out[0])/100);
out[2]=((in-1000*out[0]-100*out[1])/10);
out[3]=(in-1000*out[0]-100*out[1]-10*out[2]);
out[4]=0;
out[0]+=0x30;
out[1]+=0x30;
out[2]+=0x30;
out[3]+=0x30;
if(out[0] == '0' && out[1] == '0' && out[2] == '0') out[2] = ' ';
if(out[0] == '0' && out[1] == '0') out[1] = ' ';
if(out[0] == '0') out[0] = ' ';
}



void pozadiLCD(void)
{
	    LCD_Setpos(98,6);
LCD_Printf("MENU\\",&Font_System5x8);
	    LCD_Setpos(98,7);
LCD_Printf("    /",&Font_System5x8);


 LCD_Setpos(27+64-12,7);

LCD_Printf("\x23\x24\x00",&Font_System5x8); //ikonka satelitu

 LCD_Setpos(40,4);
LCD_Printf("kmh",&Font_System5x8);
 LCD_Setpos(30,6);
LCD_Printf("m",&Font_System5x8);
 LCD_Setpos(3,1);
LCD_Printf("   1   2   3   4   5   6   7",&Font_System3x6);
}

void die (		/* Stop with dying message */
	FRESULT rc	/* FatFs return value */
)
{//chyba v pristupu na kartu
  	LCDClearScreen();
	    LCD_Setpos(0,0);
LCD_Printf("CARD ERROR",&Font_System5x8);

	for (;;) ;
}

DWORD get_fattime (void)
{
	return	  ((DWORD)(2012 - 1980) << 25)	/* Year = 2012 */
			| ((DWORD)1 << 21)				/* Month = 1 */
			| ((DWORD)1 << 16)				/* Day_m = 1*/
			| ((DWORD)0 << 11)				/* Hour = 0 */
			| ((DWORD)0 << 5)				/* Min = 0 */
			| ((DWORD)0 >> 1);				/* Sec = 0 */
}


/**
  * @brief  Main program.
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f10x_xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f10x.c file
     */     


 volatile  unsigned int i;
 volatile char pos=0, j=0;
//	DIR dir;				/* Directory object */
//	FILINFO fno;			/* File information object */
//	UINT bw, br, i;
//UINT bw,br;

	 
  /* Configure all unused GPIO port pins in Analog Input mode (floating input
     trigger OFF), this will reduce the power consumption and increase the device
     immunity against EMI/EMC *************************************************/


  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
                         RCC_APB2Periph_GPIOE | RCC_APB2Periph_USART1 | RCC_APB2Periph_AFIO, ENABLE);
   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); 

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  GPIO_Init(GPIOE, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9  ;  
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //TXD
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //TXD vypnuto
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_1; //RXD a TIMER2CH2
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; 
  GPIO_Init(GPIOA, &GPIO_InitStructure);   //nastaveni pinu USART1

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_8 | GPIO_Pin_7 | GPIO_Pin_6 | GPIO_Pin_5 | GPIO_Pin_4 ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_2 | GPIO_Pin_1 | GPIO_Pin_0 ;  //tlacitka
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_6 ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_7 | GPIO_Pin_6; //input z SD karty
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
  GPIO_Init(GPIOB, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_12 | GPIO_Pin_11 | GPIO_Pin_10 | GPIO_Pin_1 | GPIO_Pin_0;
  GPIO_Init(GPIOB, &GPIO_InitStructure);

 /* RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
                         RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD |
                         RCC_APB2Periph_GPIOE, DISABLE);  */
B1Pressed();
B2Pressed();
B3Pressed();
B4Pressed();




NVIC_Configuration();  // Inicializace prerusovaciho systemu
   
   USART_InitStructure.USART_BaudRate = 4800;
   USART_InitStructure.USART_WordLength =  USART_WordLength_8b;
   USART_InitStructure.USART_StopBits =  USART_StopBits_1;
   USART_InitStructure.USART_Parity =  USART_Parity_No;
   USART_InitStructure.USART_HardwareFlowControl =  USART_HardwareFlowControl_None;
   USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
   USART_Init(USART1,&USART_InitStructure);
   USART_Cmd(USART1,ENABLE);
   USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);	/* Povoleni preruseni od USART1 */

//inicializace TIM2 CH2
TIM2->CCMR1= 0x0102;
TIM2->CCER= 0x0002;
TIM2->SMCR= 0x0064;
TIM2->CCER|=0x0011;
TIM2->PSC=240;
TIM2->CR1=1;


LCDSetReset(0);	  // Reset LCD displeje, aktivni v log 0
	Delay(0x3FFFF);	
LCDSetReset(1);		
   Delay(0x3FFFF);		
LCDInit();	// Inicializace LCD	
i=DS_18B20_Init();  // Inicializace teplotnich cidel
TX(i);
    Delay(0x4FFFF);


pozadiLCD();	// Vykresleni zakladni obrazovky na displej
Delay(0x4FFF);


 f_mount(0, &Fatfs);		// Inicializace knihovny SD karty 


//hlavni smycka zacina zde
dly=0;
DS18X20_start_meas(DS18X20_POWER_PARASITE, NULL);
 while(1){


if(dly==INTERVAL/2) {  
    
get_date();
get_time();
get_position();
 for(pos=0;pos<6;pos++)
WBuff[offset+pos]=datum[pos];
WBuff[offset+6]=0x3B; //strednik
for(pos=7;pos<13;pos++)
WBuff[offset+pos]=cas[pos-7];
WBuff[offset+13]=0x3B;  //strednik
for(pos=14;pos<23;pos++)
WBuff[offset+pos]=lat[pos-14];
WBuff[offset+23]=0x3B;  //strednik
for(pos=24;pos<34;pos++)
WBuff[offset+pos]=lon[pos-24];
WBuff[offset+34]=0x3B;  //strednik


casovac[0]=TIM2->CCR1; //doba rozepnuti
casovac[1]=TIM2->CCR2; //celkova perioda
casovac[2]=3000000/casovac[1]; //vypocitane otacky
if(	casovac[2]<200 || casovac[2]>7905) 
	{			 //omezeni mereneho rozsahu otacek
	 casovac[1]=0;
	casovac[2]=0;
	}
 bargraf(0,0, 127, (casovac[2]/31));
 rpmtostr(casovac[2],tmp_pole);
WBuff[offset+35]=tmp_pole[0]; 
WBuff[offset+36]=tmp_pole[1];  
WBuff[offset+37]=tmp_pole[2]; 
WBuff[offset+38]=tmp_pole[3]; 
WBuff[offset+39]=0x3B;  //strednik


i=(speed()/100);
temptostr(i,tmp_pole);
LCD_Setpos(10,4);
LCD_Printf(tmp_pole,&Font_Courrier8x12);
WBuff[offset+40]=tmp_pole[0];  
WBuff[offset+41]=tmp_pole[1];  
WBuff[offset+42]=tmp_pole[2]; 
WBuff[offset+43]=0x3B;  //strednik


i=(altitude()/100);
temptostr(i,tmp_pole);
LCD_Setpos(10,6);
LCD_Printf(tmp_pole,&Font_System5x8);
WBuff[offset+44]=0x20; pos++;
WBuff[offset+45]=tmp_pole[0];  
WBuff[offset+46]=tmp_pole[1];  
WBuff[offset+47]=tmp_pole[2];
WBuff[offset+48]=0x3B; pos++; //strednik

i=teploty[0]/10;
temptostr(i,tmp_pole);
if(tmp_pole[0]=='-'){
tmp_pole[4]=0x80; tmp_pole[5]='C';tmp_pole[6]=0;
WBuff[offset+49]='-'; 
WBuff[offset+50]=tmp_pole[1];
WBuff[offset+51]=tmp_pole[2];
WBuff[offset+52]=tmp_pole[3];

}
else {
tmp_pole[3]=0x80; tmp_pole[4]='C';tmp_pole[5]=' ';tmp_pole[6]=0;
WBuff[offset+49]=0x20; 
WBuff[offset+50]=tmp_pole[0];
WBuff[offset+51]=tmp_pole[1];
WBuff[offset+52]=tmp_pole[2];
}
WBuff[offset+53]=0x3B;  //strednik

LCD_Setpos(69,3);
LCD_Printf(tmp_pole,&Font_System5x8);


get_teploty(teploty);

i=teploty[1]/10;
temptostr(i,tmp_pole);
if(tmp_pole[0]=='-'){
tmp_pole[4]=0x80; tmp_pole[5]='C';
 WBuff[offset+54]='-'; 
WBuff[offset+55]=tmp_pole[1];
WBuff[offset+56]=tmp_pole[2];
WBuff[offset+57]=tmp_pole[3];
}
else {
tmp_pole[3]=0x80; tmp_pole[4]='C';
WBuff[offset+54]=0x20; 
WBuff[offset+55]=tmp_pole[0];
WBuff[offset+56]=tmp_pole[1];
WBuff[offset+57]=tmp_pole[2];
}
WBuff[offset+58]=0x0D;  //CR
WBuff[offset+59]=0x0A;  //LF
offset=offset+60;
LCD_Setpos(69,4);
LCD_Printf(tmp_pole,&Font_System5x8);

   DS18X20_start_meas(DS18X20_POWER_PARASITE, NULL);

temptostr(numsats(),tmp_pole);
LCD_Setpos(57,7);
LCD_Printf(tmp_pole,&Font_System5x8);



  
 }


if(dly++>INTERVAL){	  dly=0;
 casovac[0]=TIM2->CCR1; //doba rozepnuti
casovac[1]=TIM2->CCR2; //celkova perioda
casovac[2]=3000000/casovac[1]; //vypocitane otacky
if(	casovac[2]<200 || casovac[2]>7905) 
	{			 //omezeni mereneho rozsahu otacek
	 casovac[1]=0;
	casovac[2]=0;
	}
 bargraf(0,0, 127, (casovac[2]/31));
 rpmtostr(casovac[2],tmp_pole);
WBuff[offset]=0x3B;  //strednik
WBuff[offset+1]=0x3B;  //strednik
WBuff[offset+2]=0x3B;  //strednik
WBuff[offset+3]=0x3B;  //strednik
WBuff[offset+4]=tmp_pole[0]; 
WBuff[offset+5]=tmp_pole[1];  
WBuff[offset+6]=tmp_pole[2]; 
WBuff[offset+7]=tmp_pole[3]; 
WBuff[offset+8]=0x3B;  //strednik
WBuff[offset+9]=0x3B;  //strednik
WBuff[offset+10]=0x3B;  //strednik
WBuff[offset+11]=0x3B;  //strednik
WBuff[offset+12]=0x0D;  //CR
WBuff[offset+13]=0x0A;  //LF
offset=offset+14;

	if(offset==740) 
 	{
 	offset=0;
 //zapis dalsiho bloku na kartu
 if(zaznam)
 {	
	rc = f_write(&Fil, WBuff, 740, &bw);
	if (rc) die(rc);
	fileoffset=fileoffset+740;
     rc = f_lseek(&Fil, fileoffset);
  	if (rc) die(rc);
   
  }
  	 
	

 	}
}


}




}
/**
  * @brief  Inserts a delay time.
  * @param  nCount: specifies the delay time length.
  * @retval None
  */
void Delay(__IO uint32_t nCount)
{
  for(; nCount != 0; nCount--);
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{ 
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */

/**
  * @}
  */

/* Obsluha preruseni od USART1 */ 
void USART1_IRQHandler(void) 
{ 

parse(USART_ReceiveData(USART1));  

} 

void EXTI3_IRQHandler(void)
 {	u8 i;
	static uint8_t filename[13]={'Z','a','z','n','a','m','0','0','.','c','s','v',0};
	uint8_t temp[6];
   if(!exitmenu)
   {
		LCDClearScreen();
	    LCD_Setpos(98,0);
LCD_Printf("ZPET\\",&Font_System5x8);
	    LCD_Setpos(98,1);
LCD_Printf("    /",&Font_System5x8);
	    LCD_Setpos(0,0);
LCD_Printf("Karta:",&Font_System5x8);



 while (1)
 { 
if (((GPIOB->IDR & (1<<7)) == 0 ))	 //detekce vlozene karty
	{	 
		    LCD_Setpos(0,1);
LCD_Printf("Vlozena  ",&Font_System5x8);
	}else
	{
		    LCD_Setpos(0,1);
LCD_Printf("Nevlozena",&Font_System5x8);
	}


if(zaznam)
{
	    LCD_Setpos(92,2);
LCD_Printf(" STOP\\",&Font_System5x8);
	    LCD_Setpos(98,3);
LCD_Printf("ZAZN/",&Font_System5x8);
		LCD_Setpos(0,6);
LCD_Printf(filename,&Font_System5x8);
	    LCD_Setpos(0,7);
LCD_Printf("aktivovan",&Font_System5x8);
}else{
	    LCD_Setpos(92,2);
LCD_Printf("START\\",&Font_System5x8);
	    LCD_Setpos(98,3);
LCD_Printf("ZAZN/",&Font_System5x8);
LCD_Setpos(0,6);
LCD_Printf(filename,&Font_System5x8);
	    LCD_Setpos(0,7);
LCD_Printf("         ",&Font_System5x8);
}

if (B2Pressed()){
zaznam=zaznam^1;
	if (!((GPIOB->IDR & (1<<7)) == 0 ))	 //detekce vlozene karty
   {
   zaznam=0; //karta neni vlozena, nespustit zaznam
   }
	if(zaznam)
	{
	 
	 for(i=0;i<100;i++)
	 {
	 temptostr(i,temp);
	 if(i<10) filename[6]='0'; else filename[6]=temp[1];
	 filename[7]=temp[2];
	 rc = f_open(&Fil, filename, FA_OPEN_EXISTING);
	 if(rc) //nalezen dalsi volny nazev
	 	{															  
		 	rc = f_open(&Fil, filename, FA_WRITE | FA_CREATE_ALWAYS);
			if (rc) die(rc);
			fileoffset=0;
			
		    LCD_Setpos(0,6);
            LCD_Printf(filename,&Font_System5x8);
			break;
		}
	 if(i==99)
	 	{
		LCDClearScreen();
	    LCD_Setpos(0,0);
        LCD_Printf("NO FREE FILENAME",&Font_System5x8);
	    for (;;) ;
		}
	 }


	}else  //zaznam = 0, uzavrit soubor
	{
	 f_close(&Fil);
	}
} 
                                   
	Delay(0x1FFF);

    if (B1Pressed()) {
	LCDClearScreen();
	pozadiLCD();
	exitmenu=1;                           
    EXTI_ClearITPendingBit(EXTI_Line3);
	break;                 
    }
  
}

   }else
  {
  exitmenu=0;
  }
        

    }
