/*
 * setup.c
 *
 *  Created on: Sep 8, 2011
 *      Author: qwer1
 */

#include "setup.h"
#include "ul_timing.h"
#include "usart.h"
#include "ul_lcda.h"
#include "ind.h"
#include "adc.h"
#include "process.h"
#include "config.h"
#include "kbd.h"
#include "heaters.h"
#include "pid.h"
#include "sound.h"
#include "modbus.h"

U8 quartz_is_enabled;

// initialize system clocks
void setup_clocks(void) {
	// initialize system clock
	RCC_DeInit();                                        //reset clock system
	RCC_HSEConfig( RCC_HSE_ON );                         //enable HSE
	quartz_is_enabled = RCC_WaitForHSEStartUp() == SUCCESS; //wait for HSE start and remember HCE presence

	//start PLL. With quartz - 12M * 2, without -
	if (quartz_is_enabled) {
		RCC_PREDIV1Config(RCC_PREDIV1_Source_HSE, RCC_PREDIV1_Div1); //HSE prescaler
		RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_2);  //PLL = HSE / 1 * 2
	} else {
		RCC_DeInit();                                        //reset clock system
		RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_6);  //PLL = HSI / 2 * 6
	}

	RCC_PLLCmd(ENABLE);                                  //enable PLL
	while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); //wait for PLL to start

	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);           //switch system clock to PLL
    while (RCC_GetSYSCLKSource() != 0x08);               //wait till PLL become system clock

    //configure buses clocks
	RCC_HCLKConfig(RCC_SYSCLK_Div1);                     //configure the AHB clock (HCLK) divider
	RCC_PCLK1Config(RCC_HCLK_Div1);                      //configure the Low Speed APB clock (PCLK1) divider
	RCC_PCLK2Config(RCC_HCLK_Div1);                      //configure the High Speed APB clock (PCLK2) divider

//	FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//	FLASH_SetLatency(FLASH_Latency_0);

	// setup SysTick to 1ms reload period
//	SysTick_Config((F_CPU + 500UL) / 1000UL);
	SysTick->LOAD = ((F_CPU + 500.0) / 1000.0) - 1;      // setup reload register
	SysTick->VAL  = 0;                                   // reset SysTick counter
	SysTick->CTRL = SysTick_CTRL_CLKSOURCE | SysTick_CTRL_ENABLE; // Enable SysTick Timer, use HCLK source

	// enable peripheral clocks
    RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
    		RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);
}

void setup_gpio(void){
	GPIO_InitTypeDef  GPIO_InitStructure;

	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE); // disable JTAG pins

	// initialize GPIO
	GPIO_StructInit(&GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//SDA/SCL
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	*BITP(&GPIOB->ODR, 6) = 1;
	*BITP(&GPIOB->ODR, 7) = 1;

	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_3 | GPIO_Pin_4;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
}

void setup( U8 mode ) {
	//setup hardware
	setup_clocks();
	setup_gpio();

	//setup modules
	setup_timing();
	setup_config();
	setup_ind();
	setup_adc();
	setup_process();
	setup_kbd();
	setup_heaters();
	setup_pid();
	setup_sound();
	setup_usart();
	setup_modbus();
}
