//======================================================
// LED
//======================================================
// File Name : hw_config.c
// Function  : Hardware Configuration
//------------------------------------------------------
// Rev.01 2008.03.24 Takanaga Yamazaki
//------------------------------------------------------
// (C) Copyright 2008 Takanaga Yamazaki
//======================================================
// ---- License Information ----------------------------
// Anyone can FREELY use this code fully or partially
// under conditions shown below.
// 1. You should use this code under the GNU GPL.
// 2. You should remain this header text in your codes
//   including Copyright credit and License Information.
// 3. Your codes should inherit this license information.
//======================================================
// ---- Patent Notice ----------------------------------
// I have not cared whether this system (hw + sw) causes 
// infringement on the patent, copyright, trademark,
// or trade secret rights of others. You have all 
// responsibilities for determining if your designs
// and products infringe on the intellectual property
// rights of others, when you use technical information
// included in this system for your business.
//======================================================
// ---- Disclaimers ------------------------------------
// The function and reliability of this system are not 
// guaranteed. They may cause any damages to loss of
// properties, data, money, profits, life, or business.
// By adopting this sytem even partially, you assume
// all responsibility for its use.
//======================================================

#include "stm32f10x_it.h"
#include "hw_config.h"
#include "common.h"

//======================
// Global
//======================
UI16 gCCR4_Val;

//==========================================
// Initialize NVIC (Interrupt)
//==========================================
void Init_NVIC(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    #ifdef  VECT_TAB_RAM
    // Set the Vector Table base location at 0x20000000
    NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
    #else  // VECT_TAB_FLASH
    // Set the Vector Table base location at 0x08000000
    NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
    #endif

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

    // SysTick end of count event each 1ms with input clock equal to 9MHz (HCLK/8, default)
    SysTick_SetReload(9000);

    // Enable SysTick interrupt
    SysTick_ITConfig(ENABLE);

    // Enable the SysTick Counter
    SysTick_CounterCmd(SysTick_Counter_Enable);

/*    
    // Enable the TIM4 gloabal Interrupt
    NVIC_InitStructure.NVIC_IRQChannel                   = TIM4_IRQChannel;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority        = 1;
    NVIC_InitStructure.NVIC_IRQChannelCmd                = ENABLE;

    NVIC_Init(&NVIC_InitStructure);
*/
}

//==========================================
// Initialize TIM4
//==========================================
void Init_TIM4(void)
{
    TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
    TIM_OCInitTypeDef        TIM_OCInitStructure;

    // Enable Clock of TIM4 connected on APB1.
    // PCLK1 = 36MHz now.
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);

    // TIM4 Configuration: Output Compare Timing Mode:
    // TIM4CLK = 36 MHz, Prescaler = (36000 - 1), TIM2 counter clock = 1 KHz 
    // CC4 update rate = TIM4 counter clock / 1000 =  1 Hz 
      
    // Time base configuration
    TIM_TimeBaseStructure.TIM_Period        = 65535;          
    TIM_TimeBaseStructure.TIM_Prescaler     = 0;       
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;    
    TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;       
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure);

    // Prescaler configuration
    TIM_PrescalerConfig(TIM4, (36000 - 1), TIM_PSCReloadMode_Immediate);

    // Output Compare Timing Mode configuration: Channel4
    gCCR4_Val = 1000;
    TIM_OCInitStructure.TIM_OCMode     = TIM_OCMode_Inactive;          
    TIM_OCInitStructure.TIM_Channel    = TIM_Channel_4;          
    TIM_OCInitStructure.TIM_Pulse      = gCCR4_Val;  
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInit(TIM4, &TIM_OCInitStructure);

    TIM_OC4PreloadConfig(TIM4, TIM_OCPreload_Disable);

    // TIM IT enable
    TIM_ITConfig(TIM4, TIM_IT_CC4, ENABLE);

    // TIM4 enable counter */
    TIM_Cmd(TIM4, ENABLE);
}

//=================================
// Initialize System
//=================================
void Set_System(void)
{
    ErrorStatus HSEStartUpStatus;
    GPIO_InitTypeDef GPIO_InitStructure;

    // SYSCLK, HCLK, PCLK2 and PCLK1 configuration
    // RCC system reset(for debug purpose)
    RCC_DeInit();

    // Enable HSE
    RCC_HSEConfig(RCC_HSE_ON);

    // Wait till HSE is ready
    HSEStartUpStatus = RCC_WaitForHSEStartUp();

    if(HSEStartUpStatus == SUCCESS)
    {
        // Enable Prefetch Buffer
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);

        // Flash 2 wait state
        FLASH_SetLatency(FLASH_Latency_2);
 
        // HCLK = SYSCLK
        RCC_HCLKConfig(RCC_SYSCLK_Div1); 
  
        // PCLK2 = HCLK
        RCC_PCLK2Config(RCC_HCLK_Div1); 

        // PCLK1 = HCLK/2
        RCC_PCLK1Config(RCC_HCLK_Div2);

        // ADCCLK = PCLK2/6
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);

        // PLLCLK = 8MHz * 9 = 72 MHz
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);

        // Enable PLL
        RCC_PLLCmd(ENABLE);

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

        // Select PLL as system clock source
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

        // Wait till PLL is used as system clock source
        while(RCC_GetSYSCLKSource() != 0x08)
        {
        }
      }

      // Enable GPIOC clock
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
      // Configure PC.06 as output push-pull
      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_6;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOC, &GPIO_InitStructure);
}

//======================================================
// End of Program
//======================================================
