#include "hwinit.h"

void HW_Init(void){


	GPIO_Configuration();
	I2C_Configuration();
	EXTI_Configuration();
	NVIC_Configuration();
	SERIAL_Configuration();
	TIMERS_Configuration();
	ADC_Configuration();

	//EXTI_Configuration();



}
void Clock_Init(void){

	RCC_Configuration();
	SysTick_Configuration();


}

void GPIO_Configuration(void)
{

	  /* SWITCH ALL PORTS ON*/
	  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_AFIO, ENABLE);
	  /* LED PINS */
	  GPIO_ResetBits(EXT_OUT1_PORT,EXT_OUT1_PIN);
	  GPIO_ResetBits(EXT_OUT2_PORT,EXT_OUT2_PIN);
	  GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);
	  GPIO_ResetBits(EXT_OUT1_PORT,EXT_OUT1_PIN);
	  GPIO_ResetBits(EXT_OUT2_PORT,EXT_OUT2_PIN);
	  /* DISABLE JTAG */

	  GPIO_ResetBits(EXT_OUT1_PORT,EXT_OUT1_PIN);
	  GPIO_ResetBits(EXT_OUT2_PORT,EXT_OUT2_PIN);

	  GPIO_InitStructure.GPIO_Pin = LED_G_PIN | LED_R_PIN;
	  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
	  GPIO_Init(LED_R_PORT,&GPIO_InitStructure);

	  /* REALY OUTPUTS */
	  GPIO_InitStructure.GPIO_Pin = EXT_OUT1_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
	  GPIO_Init(EXT_OUT1_PORT,&GPIO_InitStructure);
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
	  GPIO_InitStructure.GPIO_Pin = EXT_OUT2_PIN ;
	  GPIO_Init(EXT_OUT2_PORT,&GPIO_InitStructure);
	  //Switch off them


	  /* BINARY INPUTS */
	  GPIO_InitStructure.GPIO_Pin = EXT_IN1_PIN | EXT_IN2_PIN | EXT_IN3_PIN | EXT_IN4_PIN;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
	  GPIO_Init(EXT_IN1_PORT,&GPIO_InitStructure);

	  /* ANALOG INPUTS */
	  GPIO_InitStructure.GPIO_Pin = SUPPLY_MES_PIN | BATT_MES_PIN;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN ;
	  GPIO_Init(SUPPLY_MES_PORT,&GPIO_InitStructure);

	  /* OTHER OUTPUTS ON PORT A */
	  //GPIO_InitStructure.GPIO_Pin = AMP_EN_PIN | FPR_EN_PIN;
	  //Batt smoked up
	  GPIO_InitStructure.GPIO_Pin = BATT_POWER_EN_PIN | AMP_EN_PIN | FPR_EN_PIN;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
	  GPIO_Init(BATT_POWER_EN_PORT,&GPIO_InitStructure);
	  GPIO_ResetBits(BATT_POWER_EN_PORT,FPR_EN_PIN);
	  GPIO_ResetBits(BATT_POWER_EN_PORT,BATT_POWER_EN_PIN);

	  /* BUZZER PWM OUTPUT */
	  GPIO_InitStructure.GPIO_Pin = BUZZ_OUT_PIN;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	  GPIO_Init(BUZZ_OUT_PORT,&GPIO_InitStructure);

	  /* OTHER OUTPUTS ON PORT C */
	  GPIO_InitStructure.GPIO_Pin = BATT_MES_EN_PIN ;
	//  GPIO_InitStructure.GPIO_Pin =  BATT_CHRG_EN_PIN | BATT_MES_EN_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;
	  GPIO_Init(BATT_CHRG_EN_PORT,&GPIO_InitStructure);

	  /* CHARGER STATUS INPUTS */
	  GPIO_InitStructure.GPIO_Pin =  BATT_CHRG_ST1_PIN | BATT_CHRG_ST2_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
	  GPIO_Init(BATT_CHRG_ST2_PORT,&GPIO_InitStructure);


	  /* I2C FOR KEYBOARD DRIVER (pull-ups are external)*/
	  GPIO_InitStructure.GPIO_Pin =  KEYB_SCL_PIN | KEYB_SDA_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD ;
	  GPIO_Init(KEYB_SCL_PORT,&GPIO_InitStructure);

	  /* USART1 - TO HOST */
	  GPIO_InitStructure.GPIO_Pin =  HOST_UART_RX_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
	  GPIO_Init(HOST_UART_RX_PORT,&GPIO_InitStructure);

	  GPIO_InitStructure.GPIO_Pin =  HOST_UART_TX_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD ;
	  GPIO_Init(HOST_UART_TX_PORT,&GPIO_InitStructure);

	  /* USART2 - TO FINGERPRINT */
	  GPIO_InitStructure.GPIO_Pin =  FPR_UART_RX_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
	  GPIO_Init(FPR_UART_RX_PORT,&GPIO_InitStructure);

	  GPIO_InitStructure.GPIO_Pin =  FPR_UART_TX_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP ;
	  GPIO_Init(FPR_UART_TX_PORT,&GPIO_InitStructure);

	  /* UART5 - TO RFID */
	  GPIO_InitStructure.GPIO_Pin =  RFID_UART_RX_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
	  GPIO_Init(RFID_UART_RX_PORT,&GPIO_InitStructure);

	  /* PIR Motion sensor */
	  GPIO_InitStructure.GPIO_Pin =  PIR_IN_PIN ;
	  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING ;
	  GPIO_Init(PIR_IN_PORT,&GPIO_InitStructure);

}

/**
  * @brief  Configures 24bit System Timer (core part).
  * @param  None
  * @retval None
  */
void SysTick_Configuration(void)
{
	/* configure for 1ms interrupts */
	SysTick_Config(SystemCoreClock / 1000);
}

void SERIAL_Configuration(void){




	//Configure HOST Uart
	//-----------------------------
	//Enable clock
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);

	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;

	USART_DeInit(USART1);
	USART_Cmd(HOST_UART, ENABLE);

	USART_Init(HOST_UART, &USART_InitStructure);

	USART_ITConfig(HOST_UART, USART_IT_RXNE, ENABLE);

	//Configure FPR UART
	//------------------------------
	//Enable clock
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2,ENABLE);

	USART_InitStructure.USART_BaudRate = 57600;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;

	USART_DeInit(FPR_UART);
	USART_Cmd(FPR_UART, ENABLE);

	USART_Init(FPR_UART, &USART_InitStructure);

	//USART_ITConfig(FPR_UART, USART_IT_RXNE, ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5,ENABLE);
	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;

	USART_DeInit(RFID_UART);
	USART_Cmd(RFID_UART, ENABLE);

	USART_Init(RFID_UART, &USART_InitStructure);

	USART_ITConfig(RFID_UART, USART_IT_RXNE, ENABLE);
}

void I2C_Configuration(void){
	I2C_InitTypeDef I2C_InitStructure;

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

	I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
	I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
	  I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
	  I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
	  I2C_InitStructure.I2C_ClockSpeed = 100000;

	  I2C_DeInit(I2C2);
	  I2C_Cmd(I2C2,ENABLE);
	  I2C_Init(I2C2,&I2C_InitStructure);

}

void RCC_Configuration(void)
{
 u16 StartUpCounter=0;
 uint32_t HSEStatus;

  /* Before this function calling system is working on internal HSI 16MHz */

  /* Enable HSE=8MHz */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready and if Time out is reached exit */
  do
  {
    StartUpCounter++;
  } while((RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) && (StartUpCounter != HSEStartUp_TimeOut));

  if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == SET)
  {
    HSEStatus = (uint32_t)0x01;
  }
  else
  {
    HSEStatus = (uint32_t)0x00;
  }

  if (HSEStatus == (uint32_t)0x01)
  {
    /* Enable Prefetch Buffer */
	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

    /* Flash 0 wait state */
	FLASH_SetLatency(FLASH_Latency_0);

    /* HCLK = SYSCLK = 24MHz*/
	RCC_HCLKConfig(RCC_SYSCLK_Div1);

    /* PCLK2 = HCLK = 24MHz*/
	RCC_PCLK2Config(RCC_HCLK_Div1);

    /* PCLK1 = HCLK = 24MHz*/
	RCC_PCLK1Config(RCC_HCLK_Div1);

	/* HSE=8MHz / 1 => 8MHz */
	RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE, RCC_PREDIV1_Div1);

    /* Configure PLL ------------------------------------------------------*/

    /* PLL1 configuration 8MHz * 3 = 24MHz */
	RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_3);

	/* Enable PLL1 */
    RCC_PLLCmd (ENABLE);

    /* Wait till PLL1 is ready */
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source (from HSI to HSE+PLL) */
	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
    {
    }
    SystemCoreClockUpdate();
   }
}

void NVIC_Configuration(void)
{

 // NVIC_SetVectorTable(NVIC_VectTab_FLASH,0);
 // NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

  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);

  NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

  NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);

	 NVIC_InitStructure.NVIC_IRQChannel = ADC1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
		NVIC_Init(&NVIC_InitStructure);

/*
  NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
   NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
   NVIC_Init(&NVIC_InitStructure);
   */
  /* In NVIC configuration we cannot use concatenation for IRQ vector configuration */
  /* All vectors must be configured separately */

  /* Configuration of EXTI channel 0 interrupt vector */
  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}

void TIMERS_Configuration(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;


	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1 , ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

	TIM_TimeBaseStructure.TIM_Period = 2400;
	TIM_TimeBaseStructure.TIM_Prescaler = 1;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

	TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);



	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle;
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
	TIM_OCInitStructure.TIM_Pulse = 1200;
  	TIM_OC4Init(TIM1, &TIM_OCInitStructure);

  	TIM_OC4PreloadConfig(TIM1, TIM_OCPreload_Enable);
  	TIM_ARRPreloadConfig(TIM1, ENABLE);

  	/* TIM3 enable counter */
  	TIM_Cmd(TIM1, ENABLE);

  	TIM1->BDTR |= TIM_BDTR_MOE; //Pul dne prace

  	TIM_TimeBaseStructure.TIM_Period = 100;
	TIM_TimeBaseStructure.TIM_Prescaler = 24000;
	TIM_TimeBaseStructure.TIM_ClockDivision = 0;
	TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

	TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure);

	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
	TIM_Cmd(TIM2, ENABLE);

}

void EXTI_Configuration(void){
	EXTI_InitTypeDef EXTI_InitStructure;

	GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource6);

	EXTI_StructInit(&EXTI_InitStructure);
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
    EXTI_InitStructure.EXTI_Line = EXTI_Line6;
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;
    EXTI_Init(&EXTI_InitStructure);


}

void ADC_Configuration(void){
	 ADC_InitTypeDef  ADC_InitStructure;

	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);

	 ADC_InitStructure.ADC_Mode                = ADC_Mode_Independent;
	 ADC_InitStructure.ADC_ScanConvMode        = ENABLE;
	 ADC_InitStructure.ADC_ContinuousConvMode  = ENABLE;
	 ADC_InitStructure.ADC_ExternalTrigConv    = ADC_ExternalTrigConv_None;
	 ADC_InitStructure.ADC_DataAlign           = ADC_DataAlign_Right;
	 ADC_InitStructure.ADC_NbrOfChannel        = 2;

	 ADC_Init( ADC1, &ADC_InitStructure );

	  ADC_InjectedSequencerLengthConfig(ADC1,2);
	  ADC_InjectedChannelConfig(ADC1,ADC_Channel_4, 1 ,ADC_SampleTime_1Cycles5);
	  ADC_InjectedChannelConfig(ADC1,ADC_Channel_5, 2 ,ADC_SampleTime_1Cycles5);

	  ADC_AutoInjectedConvCmd(ADC1,ENABLE);

	  /* Configure high and low analog watchdog thresholds */
	   ADC_AnalogWatchdogThresholdsConfig(ADC1, 0x0FFF, 0x0A40);
	   /* Configure channel14 as the single analog watchdog guarded channel */
	   ADC_AnalogWatchdogSingleChannelConfig(ADC1, ADC_Channel_4);
	   /* Enable analog watchdog on one regular channel */
	   ADC_AnalogWatchdogCmd(ADC1, ADC_AnalogWatchdog_SingleInjecEnable);

	   /* Enable AWD interrupt */
	   ADC_ITConfig(ADC1, ADC_IT_AWD, ENABLE);



	  /* Enable ADC1 */
	    ADC_Cmd(ADC1, ENABLE);

	    /* Enable ADC1 reset calibration register */
	    ADC_ResetCalibration(ADC1);
	    /* Check the end of ADC1 reset calibration register */
	    while(ADC_GetResetCalibrationStatus(ADC1));

	    /* Start ADC1 calibration */
	    ADC_StartCalibration(ADC1);
	    /* Check the end of ADC1 calibration */
	    while(ADC_GetCalibrationStatus(ADC1));

	    /* Start ADC1 Software Conversion */
	    ADC_SoftwareStartConvCmd(ADC1, ENABLE);


}


