/*
**
**                           Main.c
**
**
**********************************************************************/
/*
   Last committed:     $Revision: 00 $
   Last changed by:    $Author: $
   Last changed date:  $Date:  $
   ID:                 $Id:  $

**********************************************************************/


#include "stm32f10x_conf.h"
//#include <core_cm3.h>
#include <math.h>

void SysTick_Init(void);
void TimeTick_Decrement(void);
void delay_Nus(uint32_t n);
void delay_10us(void);
void delay_1ms(void);
void VFD_Init(void);
void VFD_Clear(void);
void init_SPI1(void);
void delay_Nms(uint32_t n);
void init_MCU();
void RTC_Init();
void EXTI15_10_IRQHandler(void);
uint8_t SPI1_send(uint8_t data);
static  __IO uint32_t sysTickCounter ;

#define But_OK GPIO_Pin_12
#define But_Do GPIO_Pin_13
#define But_Up GPIO_Pin_14
#define VFD_SEL GPIO_Pin_0  // Low Active
#define VFD_RES GPIO_Pin_1  // Low Active

#define VFD_Port GPIOA
#define Built_in_LED GPIO_Pin_13

    volatile uint8_t push=0;
    volatile uint8_t gomb=0;
    volatile uint8_t refresh=0;

volatile int mp=0;
int perc=0;
int ora=0;

void RTC_IRQHandler(void)
{
  if (RTC->CRL & (1<<0) )           // check second flag
      {
        RTC->CRL &= ~(1<<0);        // clear second flag
        mp++;

        if (mp==60)
            {
                mp=0;
                perc++;
            }
        if (perc==60)
            {
                perc=0;
                ora++;
            }
        if (ora==24)
            {
                ora=0;
            }
      }
      refresh=1;
} // end RTC_IRQHandler


void Time_kiir()
    {
        uint8_t sec=0,tiz_sec=0,prc=0,tiz_perc=0,hour=0,tiz_hour=0;
        uint8_t ment_mp,ment_perc,ment_ora;
        asm("nop");
        ment_mp=mp;
        ment_perc=perc;
        ment_ora=ora;

        //ora=trunc(ment_ora/10);

        while(ment_mp>=10)
            {
                ment_mp=ment_mp-10;
                tiz_sec++;
            }
        sec=ment_mp;

        while(ment_perc>=10)
            {
                ment_perc=ment_perc-10;
                tiz_perc++;
            }
        prc=ment_perc;

        while(ment_ora>=10)
            {
                ment_ora=ment_ora-10;
                tiz_hour++;
            }
        hour=ment_ora;

        GPIO_ResetBits(VFD_Port,VFD_SEL);   // VFD_Data_Transfer_Enable
            delay_Nus(1);
        SPI1_send(0x10);                    // pozíció beállítása
            delay_Nus(1);
        SPI1_send(0x20);
            delay_Nus(1);
        if (tiz_hour==0)            // tíz órák kiírása
                SPI1_send(0x20);
            else
                {
                 if(tiz_hour==3)
                 tiz_hour=0x84;
                 SPI1_send(tiz_hour+48);
                }
            delay_Nus(1);
        if(hour==3)                 // órák kiírása
            hour=0x84;
        SPI1_send(hour+48);
            delay_Nus(1);

        SPI1_send(0x3A);            // elválasztó karakter
        delay_Nus(1);

        if(tiz_perc==3)             // tíz percek kiírása
                 tiz_perc=0x84;
                 SPI1_send(tiz_perc+48);
            delay_Nus(1);
        if(prc==3)                 // percek kiírása
            prc=0x84;
        SPI1_send(prc+48);
            delay_Nus(1);

        SPI1_send(0x3A);            // elválasztó karakter
        delay_Nus(1);

        if(tiz_sec==3)             // tíz mp kiírása
                 tiz_sec=0x84;
                 SPI1_send(tiz_sec+48);
            delay_Nus(1);
        if(sec==3)                 // mp kiírása
            sec=0x84;
        SPI1_send(sec+48);
            delay_Nus(1);

        uint8_t x=0;
        while(x<=6)
            {
                SPI1_send(0x20);
                delay_Nus(1);
                x++;
            }
        GPIO_SetBits(VFD_Port,VFD_SEL);     // VFD_Data_Transfer_Disable*/

    }

int main(void)
{

init_MCU();
SysTick_Init();
init_SPI1();
VFD_Init();
VFD_Clear();
RTC_Init();
ora=5;
perc=15;
mp=0;

Time_kiir();


int Gomb_OK=0;
int Gomb_UP=0;
int Gomb_DO=0;

while(1)
  {
    if(push==1)
        {
            delay_Nms(20);
            Gomb_OK= GPIO_ReadInputDataBit(GPIOB,But_OK);
            Gomb_UP= GPIO_ReadInputDataBit(GPIOB,But_Up);
            Gomb_DO= GPIO_ReadInputDataBit(GPIOB,But_Do);

            if (gomb==1 && Gomb_OK==1)
                    {
                        //refresh=1;
                    }
            if (gomb==2 && Gomb_DO==1)
                    {
                        refresh=1;
                        perc++;
                        if(perc>=60)
                            perc=0;
                        mp=0;
                    }
            if (gomb==3 && Gomb_UP==1)
                    {
                        refresh=1;
                        ora++;
                        if(ora>=24)
                            ora=0;
                        mp=0;
                    }
        push=0;
        }

    if(refresh==1)
        {
            Time_kiir();
            refresh=0;
        }

 }
}

void EXTI15_10_IRQHandler(void)
{
    push=1;
//    pending_register=PR;
    if((EXTI->PR & 0x00001000) != 0)   //Check if PE12 has trigger the interrupt
        {
            gomb=1;
            EXTI_ClearITPendingBit(EXTI_Line12);
        }

    if((EXTI->PR & 0x00002000) != 0)   //Check if PE12 has trigger the interrupt
        {
            gomb=2;
            EXTI_ClearITPendingBit(EXTI_Line13);
        }

    if((EXTI->PR & 0x00004000) != 0)   //Check if PE12 has trigger the interrupt
        {
            gomb=3;
            EXTI_ClearITPendingBit(EXTI_Line14);
        }
    }


void SysTick_Init(void) {
	/****************************************
	 *SystemFrequency/1000      1ms         *
	 *SystemFrequency/100000    10us        *
	 *SystemFrequency/1000000   1us         *
	 ****************************************/
	while (SysTick_Config(SystemCoreClock / 1000000) != 0) {
	} // One SysTick interrupt now equals 1us

}

 void   delay_1ms ( void )   {
	 sysTickCounter   =   1000 ;
	 while   ( sysTickCounter   !=   0 )   {
	 }
 }

 void   delay_Nms ( u32   n )   {
	 while   ( n -- )   {
		 delay_1ms ( ) ;
	 }
 }

  void   TimeTick_Decrement ( void )   {
	 if   ( sysTickCounter   !=   0x00 )   {
		 sysTickCounter -- ;
	 }
 }

 void   SysTick_Handler ( void )   {
	 TimeTick_Decrement ( ) ;
	 //counter--;
 }



void   delay_10us ( void )   {
	 sysTickCounter   =   10;
	 while   ( sysTickCounter   !=   0 )   {
	 }
 }

 void   delay_Nus ( u32   n )   {
	 while   ( n -- )   {
		 delay_10us ( ) ;
	 }
 }

void init_MCU()
{
     GPIO_InitTypeDef GPIO_InitStruccture;
    //C Port init PC13 gyári led
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);

    GPIO_InitStruccture.GPIO_Pin=Built_in_LED;
    GPIO_InitStruccture.GPIO_Mode= GPIO_Mode_Out_PP;
    GPIO_InitStruccture.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOC,&GPIO_InitStruccture);

    // B Port init 3db Gomb
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);

    GPIO_InitStruccture.GPIO_Pin=But_OK;
    GPIO_InitStruccture.GPIO_Mode= GPIO_Mode_IPD;
    GPIO_InitStruccture.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStruccture);

    GPIO_InitStruccture.GPIO_Pin=But_Do;
    GPIO_InitStruccture.GPIO_Mode= GPIO_Mode_IPD;
    GPIO_InitStruccture.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStruccture);

    GPIO_InitStruccture.GPIO_Pin=But_Up;
    GPIO_InitStruccture.GPIO_Mode= GPIO_Mode_IPD;
    GPIO_InitStruccture.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOB,&GPIO_InitStruccture);


    // Gomb IRQ hozzárendelés
    EXTI_InitTypeDef EXTI_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource12);
    EXTI_ClearITPendingBit(EXTI_Line12);

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_Line = EXTI_Line12;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource13);
    EXTI_ClearITPendingBit(EXTI_Line13);

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_Line = EXTI_Line13;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);

    GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource14);
    EXTI_ClearITPendingBit(EXTI_Line14);

  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  EXTI_InitStructure.EXTI_Line = EXTI_Line14;
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
NVIC_InitTypeDef NVIC_InitStructure;

  NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);



}



void VFD_Init(void)
    {
    // *************************** Kijelzõ inicializálás  ***************************
    GPIO_ResetBits(VFD_Port,VFD_RES);   // VFD_Reset
    delay_Nms(2);
    GPIO_SetBits(VFD_Port,VFD_RES);     // VFD_Reset megszüntetése

    GPIO_ResetBits(VFD_Port,VFD_SEL);   // VFD_Data_Transfer_Enable
        SPI1_send(0x60);                //number of digit settings 	(16 digit)
    GPIO_SetBits(VFD_Port,VFD_SEL);     // VFD_Data_Transfer_Disable

    GPIO_ResetBits(VFD_Port,VFD_SEL);   // VFD_Data_Transfer_Enable
      SPI1_send(0x50);                  // Fényerõ beállítása
    GPIO_SetBits(VFD_Port,VFD_SEL);     // VFD_Data_Transfer_Disable

    uint8_t i=1;
    GPIO_ResetBits(VFD_Port,VFD_SEL);   // VFD_Data_Transfer_Enable
      SPI1_send(0x30);                  // Vesszõ és tizedespontok kikapcsolása
        while(i<=16)
            {
                SPI1_send(0x00);
                i++;
            }
    GPIO_SetBits(VFD_Port,VFD_SEL);     // VFD_Data_Transfer_Disable

    GPIO_ResetBits(VFD_Port,VFD_SEL);   // VFD_Data_Transfer_Enable
      SPI1_send(0x70);                  // Display Enable
    GPIO_SetBits(VFD_Port,VFD_SEL);     // VFD_Data_Transfer_Disable
    }

void VFD_Clear(void)
    {
        int i=1;
        GPIO_ResetBits(VFD_Port,VFD_SEL);   // VFD_Data_Transfer_Enable
        delay_Nus(1);
            SPI1_send(0x10);                // pozíció beállítása
            delay_Nus(1);
            while(i<=16)
                {
                    SPI1_send(0x20);
                    delay_Nus(1);
                    i++;
                }
        GPIO_SetBits(VFD_Port,VFD_SEL);     // VFD_Data_Transfer_Disable
    }

void init_SPI1(void)
{

	GPIO_InitTypeDef GPIO_InitStruccture;
	SPI_InitTypeDef SPI_InitStruct;

	// enable clock for used IO pins
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	/* configure pins used by SPI1
	 * PA5 = SCK
	 * PA6 = MISO
	 * PA7 = MOSI  */

	GPIO_InitStruccture.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_5;
	GPIO_InitStruccture.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruccture.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruccture);

	GPIO_InitStruccture.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStruccture.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_InitStruccture.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruccture);

	// enable clock for used IO pins
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitStruccture.GPIO_Pin = VFD_SEL;
	GPIO_InitStruccture.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruccture.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(VFD_Port, &GPIO_InitStruccture);
	GPIO_SetBits(VFD_Port,VFD_SEL);

	GPIO_InitStruccture.GPIO_Pin = VFD_RES;
	GPIO_InitStruccture.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruccture.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(VFD_Port, &GPIO_InitStruccture);
    GPIO_ResetBits(VFD_Port,VFD_RES);
    // enable peripheral clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);

	/* configure SPI1 in Mode 0
	 * CPOL = 0 --> clock is low when idle
	 * CPHA = 0 --> data is sampled at the first edge  */

	SPI_InitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex; // set to full duplex mode, seperate MOSI and MISO lines
	SPI_InitStruct.SPI_Mode = SPI_Mode_Master;     // transmit in master mode, NSS pin has to be always high
	SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; // one packet of data is 8 bits wide
	SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low;        // clock is low when idle
	SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge;      // data sampled at first edge
	SPI_InitStruct.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set; // set the NSS management to internal and pull internal NSS high
	SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128; // SPI frequency is APB2 frequency / 256
	SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_LSB;// data is transmitted LSB first
	SPI_Init(SPI1, &SPI_InitStruct);

	SPI_Cmd(SPI1, ENABLE); // enable SPI1
}

uint8_t SPI1_send(uint8_t data)
{
    while( !(SPI1->SR & SPI_I2S_FLAG_TXE) ); // wait until transmit complete
	SPI1->DR = data; // write data to be transmitted to the SPI data register

	while( !(SPI1->SR & SPI_I2S_FLAG_RXNE) ); // wait until receive complete
	//while( SPI1->SR & SPI_I2S_FLAG_BSY ); // wait until SPI is not busy anymore
	return SPI1->DR; // return received data from SPI data register
}

void RTC_Init(void)
{
  RCC->APB1ENR |= RCC_APB1ENR_PWREN;                            // enable clock for Power interface

  PWR->CR      |= PWR_CR_DBP;                                   // enable access to RTC, BDC registers


RCC_RTCCLKConfig(RCC_RTCCLKSource_LSE);
RCC_RTCCLKConfig(RCC_LSE_ON);
while((RCC->BDCR & RCC_FLAG_LSERDY) == 0);

RCC_RTCCLKCmd(ENABLE);
//RTC_WaitForSynchro();


RTC_SetPrescaler(32767);
RTC_WaitForLastTask();
RTC_SetCounter(1);
RTC_WaitForLastTask();

RTC_ITConfig(RTC_IT_SEC,ENABLE);
RTC_WaitForLastTask();
//NVIC->ISER[0] |= (1 << (RTC_IRQChannel & 0x1F));            // enable interrupt
//int time=0;
//time=RTC_GetCounter();

    NVIC_InitTypeDef nvicStructure;
    nvicStructure.NVIC_IRQChannel = RTC_IRQn;
    nvicStructure.NVIC_IRQChannelPreemptionPriority = 1;
    nvicStructure.NVIC_IRQChannelSubPriority = 15;
    nvicStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&nvicStructure);
}








