//==============================================================================
// Project:   <Time Domain Measurements of Oscillators’ Frequency Stability>
// -----------------------------------------------------------------------------
//! \file		<mx_gpio>.c
//! \author:	<Petr Hanel>
//! \date		11/08/2013
//! \version	rev 0.01.2
//!
//! \section History
//! \code
//! Version		    Date        Author   Description
//!  0.01.0		 11/08/2013		 HAN	First revision
//!  0.01.1		 11/15/2013		 HAN	Add function TIM_cfg, COMP_cfg and EXTI_cfg
//!  0.01.2		 11/16/2013		 HAN	Fixed COMP issue.
//!
//! \endcode
//!
//! \section Description
//! This file provides code for the configuration of all used GPIO pins.
//! This file contains other functions for initialization used peripherals.
//
//------------------------------------------------------------------------------
//
//	This project is create as dissertation thesis for Brno University of Technology
//
//	Part of GPIO configuration was created using program MicroXplorer.
//
//==============================================================================

#include "mx_gpio.h"
#include "stm32f0xx_tim.h"
#include "stm32f0xx_comp.h"
#include "stm32f0xx_exti.h"
#include "stm32f0xx_misc.h"

//==============================================================================
//								Constant
//==============================================================================

//==============================================================================
// 								Global Variables
//==============================================================================

//==============================================================================
//								LOCAL FUNCTION PROTOTYPES
//==============================================================================

//==============================================================================
//  Function: mx_pinout_config
//------------------------------------------------------------------------------
//! \param   	<void>       void
//! \return   	<void>       void
//! \brief		Function configure all GPIOs pins
//!				PA0	 ------> COMP1_INM6
//!	 			PA1	 ------> COMP1_INP
//!				PA4	 ------> GPIO_Input
//!				PA5	 ------> GPIO_Input
//!				PA6	 ------> GPIO_Output
//!				PA7	 ------> GPIO_Output
//!				PA11 ------> COMP1_OUT
//!				PB0	 ------> GPIO_Output
//!				PB1	 ------> GPIO_Output
//!				PB2	 ------> GPIO_Output
//!				PB3	 ------> GPIO_Output
//!				PB4	 ------> GPIO_Output
//!				PB5	 ------> GPIO_Output
//!				PB6	 ------> GPIO_Output
//!				PB7	 ------> GPIO_Output
//==============================================================================

void mx_pinout_config(void) {
	// Private typedef
	GPIO_InitTypeDef GPIO_InitStruct;


	// COMP1 GPIO Configuration
	//	 PA0	 ------> COMP1_INM6
	//	 PA1	 ------> COMP1_INP
	//	 PA11	 ------> COMP1_OUT


	// Enable or disable the AHB peripheral clock
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);

	// Configure GPIO pin
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	// Configure GPIO pin alternate function
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource11, GPIO_AF_7);


	// 	 Configure pins as GPIO
	//	 PA4	 ------> GPIO_Input
	//	 PA5	 ------> GPIO_Input
	//	 PA6	 ------> GPIO_Output
	//	 PA7	 ------> GPIO_Output
	//	 PB0	 ------> GPIO_Output
	//	 PB1	 ------> GPIO_Output
	//	 PB2	 ------> GPIO_Output
	//	 PB3	 ------> GPIO_Output
	//	 PB4	 ------> GPIO_Output
	//	 PB5	 ------> GPIO_Output
	//	 PB6	 ------> GPIO_Output
	//	 PB7	 ------> GPIO_Output


	// Enable or disable the AHB peripheral clock
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA|RCC_AHBPeriph_GPIOB, ENABLE);

	// Configure GPIO pin
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	// Configure GPIO pin
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStruct);

	// Configure GPIO port B
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
	GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
	GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStruct);
}

//==============================================================================
//  Function: TIM_cfg
//------------------------------------------------------------------------------
//! \param   	<void>       void
//! \return   	<void>       void
//! \brief		Function configure timers TIM 2 channel 4
//! 			Prescaler 0  1 tick = 1ms
//!				perioda   65530
//==============================================================================
void TIM_cfg(void)
{
	TIM_TimeBaseInitTypeDef TimeBaseStructure;
	TIM_ICInitTypeDef TimeICStructure;

	// connect clock to TIM2
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

	// time base configuration
	TimeBaseStructure.TIM_Prescaler = 0;
	TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
	TimeBaseStructure.TIM_Period = 65530;
	TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
	TimeBaseStructure.TIM_RepetitionCounter = 0;
	TIM_TimeBaseInit(TIM2, &TimeBaseStructure);

	// time Input Capture TIM2 channel 4
	TimeICStructure.TIM_Channel = TIM_Channel_4;
	TimeICStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;
	TimeICStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
	TimeICStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
	TimeICStructure.TIM_ICFilter = 0;
	TIM_ICInit(TIM2, &TimeICStructure);

	TIM_Cmd(TIM2, ENABLE);

}

//==============================================================================
//  Function: COMP_cfg
//------------------------------------------------------------------------------
//! \param   	<void>       void
//! \return   	<void>       void
//! \brief		Function configure comparator COMP1
//!				Input comp is pin PA1
//!				Compare with level on the pin PA0
//==============================================================================
void COMP_cfg (void)
{
	COMP_InitTypeDef COMP_Structure;

	// Deinitializes COMP peripheral
	COMP_DeInit();

	// Connect clock to COMP peripheral
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

	// Structure of Comparator COMP1
	COMP_Structure.COMP_InvertingInput = COMP_InvertingInput_1_4VREFINT;	// U ref is PA0
	COMP_Structure.COMP_Output = COMP_Output_TIM2IC4;				// Link COMP to Tim
	COMP_Structure.COMP_OutputPol = COMP_OutputPol_NonInverted;		// Non Invetring output
	COMP_Structure.COMP_Hysteresis = 0;								// none hysteresis
	COMP_Structure.COMP_Mode = COMP_Mode_HighSpeed;
	COMP_Init(COMP_Selection_COMP1, &COMP_Structure);

	//Enabled COMP1
	COMP_Cmd(COMP_Selection_COMP1, ENABLE);
}

//==============================================================================
//  Function: EXTI_cfg
//------------------------------------------------------------------------------
//! \param		<void>		void
//! \return		<void>		void
//! \brief		Function configure interrupt for COMP1
//==============================================================================
void EXTI_cfg (void)
{
	EXTI_InitTypeDef EXTI_Structure;
	NVIC_InitTypeDef NVIC_Structure;

	// Deinitializes EXTI peripheral
	EXTI_DeInit();

	// Configuration EXTI structure
	EXTI_Structure.EXTI_Line = EXTI_Line21;
	EXTI_Structure.EXTI_Mode = EXTI_Mode_Interrupt;
	EXTI_Structure.EXTI_Trigger = EXTI_Trigger_Rising;
	EXTI_Structure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_Structure);

	// Configuration NVIC Structure
	NVIC_Structure.NVIC_IRQChannel = ADC1_COMP_IRQn;
	NVIC_Structure.NVIC_IRQChannelPriority = 0x00;
	NVIC_Structure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(& NVIC_Structure);


}
//==============================================================================
//  Function: EXTI_Enable
//------------------------------------------------------------------------------
//! \param		<void>		void
//! \return		<void>		void
//! \brief		Enable Interrupt
//==============================================================================
void EXTI_Enable(void)
{
	//defines EXTI structure
	EXTI_InitTypeDef EXTI_Structure;

	// Enable EXTI line
	EXTI_Structure.EXTI_LineCmd = ENABLE;
	EXTI_Init(&EXTI_Structure);

}
//==============================================================================
//  Function: EXTI_Disable
//------------------------------------------------------------------------------
//! \param		<void>		void
//! \return		<void>		void
//! \brief		Disable Interrupt
//==============================================================================
void EXTI_Disable(void)
{
	//defines EXTI structure
	EXTI_InitTypeDef EXTI_Structure;

	// Disable EXTI line
	EXTI_Structure.EXTI_LineCmd = DISABLE;
	EXTI_Init(&EXTI_Structure);

}

