//******************************************************************************
//  Секция include: здесь подключается заголовочный файл к модулю
//******************************************************************************
#include  <stdint.h>
#include "RCC_32_Init.h"      // Включаем файл заголовка для нашего модуля

//******************************************************************************
//  Секция определения переменных, используемых в модуле
//******************************************************************************

//------------------------------------------------------------------------------
// Глобальные
//------------------------------------------------------------------------------

//char GlobalVar1;
//char GlobalVar2;

//------------------------------------------------------------------------------
// Локальные
//------------------------------------------------------------------------------
//******************************************************************************
//  Секция прототипов локальных функций
//******************************************************************************

//******************************************************************************
//  Секция описания глобальных функций
//******************************************************************************

/*
 * Настройка внутреннего генератора на масимальную частоту.
 * Запуск идёт от внешнего кварцевого резонатора на 8 МГц
 */
void SystemClock_Config(uint8_t Quartz)
{
  uint32_t  StartUpCounter;
  uint8_t   _PLL_Mul, _PLL_Div;

//
  SET_BIT(RCC->APB1ENR, RCC_APB1ENR_COMPEN);                // Подача тактов на компараторы (Зачем это делается сразу, не знаю. Но пока оставлю)
  SET_BIT(RCC->APB2ENR, RCC_APB2ENR_SYSCFGEN);              // Подача тактов на контроллер конфигурации системы
  SET_BIT(RCC->APB1ENR, RCC_APB1ENR_PWREN);                 // Подача тактов на контроллер питания
  MODIFY_REG(PWR->CR, PWR_CR_VOS, PWR_CR_VOS_0);            // Переключение управления питанием на Range1. Питание 1.8в и выше

  if(Quartz == Quartz_None)                                 // Ветка запуска тактового генератора без кварца. На максимальную частоту
  {
    _PLL_Mul = PLL_MUL_6;                                   // Множитель PLL для внутреннего тактового генератора 16МГц
    _PLL_Div = PLL_DIV_3;                                   // Делитель PLL

    RCC->CFGR &= ~RCC_CFGR_PLLSRC;                          // Устанавливаем тактирование от HSI

    RCC->CR |= RCC_CR_HSION;                                // Запускаем HSI
    for (StartUpCounter = 0;; StartUpCounter++)
    {
      if(RCC->CR & RCC_CR_HSIRDY) break;                    // Запустился, вываливаемся из цикла
      if(StartUpCounter > 0x1000)                           // Не запустился гад
      {
        RCC->CR &= ~RCC_CR_HSION;                           //Останавливаем HSI
        return;
      }
    }
  }
  else                                                      // Ветка запуска тактового генратора с кварцем. На максимальную частоту
  {
    switch (Quartz)
    {
      case Quartz_4:
        _PLL_Mul = PLL_MUL_24;
        _PLL_Div = PLL_DIV_3;
        HSE_Value = 4000000;
        break;
      case Quartz_6:
        _PLL_Mul = PLL_MUL_16;
        _PLL_Div = PLL_DIV_3;
        HSE_Value = 6000000;
        break;
      case Quartz_8:
        _PLL_Mul = PLL_MUL_12;
        _PLL_Div = PLL_DIV_3;
        HSE_Value = 8000000;
        break;
      case Quartz_12:
        _PLL_Mul = PLL_MUL_8;
        _PLL_Div = PLL_DIV_3;
        HSE_Value = 12000000;
        break;
      case Quartz_16:
        _PLL_Mul = PLL_MUL_6;
        _PLL_Div = PLL_DIV_3;
        HSE_Value = 16000000;
        break;
      default:
        break;
    }
    RCC->CFGR |= RCC_CFGR_PLLSRC;                           // Устанавливаем тактирование от HSE
    RCC->CR |= RCC_CR_HSEON;                                // Запускаем HSI
    for (StartUpCounter = 0;; StartUpCounter++)
    {
      if(RCC->CR & RCC_CR_HSERDY) break;                    // Запустился, вываливаемся из цикла
      if(StartUpCounter > 0x1000)                           // Не запустился гад
      {
        RCC->CR &= ~RCC_CR_HSEON;                           //Останавливаем HSE
        return;
      }
    }
 }

  // Основной алгоритм запуска тактирования от PLL
  RCC->CFGR |= (_PLL_Mul << RCC_CFGR_PLLMUL_Pos);           // Устанавливаем множитель PLL
  RCC->CFGR |= (_PLL_Div << RCC_CFGR_PLLDIV_Pos);           // Устанавливаем делитель PLL

  // Запускаем PLL
  RCC->CR     |= RCC_CR_PLLON;                              // Включаем PLL
  for (StartUpCounter = 0;; StartUpCounter++)
  {
    if(RCC->CR & RCC_CR_PLLRDY) break;                      // Запустился, вываливаемся из цикла
    if(StartUpCounter > 0x1000)                             // Не запустился гад
    {
      RCC->CR &= ~RCC_CR_PLLON;                             //Останавливаем PLL
      return;
    }
  }

  FLASH->ACR  |= FLASH_ACR_ACC64;                           // Доступ к FLASH 64 битный
  FLASH->ACR  |= (0x1<<FLASH_ACR_LATENCY_Pos);              // Таймаут FLASH=1, т.к. частота задающего генератора 32 МГц
  RCC->CFGR   |= (0x03<<RCC_CFGR_SW_Pos);                   // Переключаемся на работу от PLL

  SysTickConfig();                                          // Вызываем настройку системного таймера SysTick
}

//******************************************************************************
//  Секция описания локальных функций
//******************************************************************************
//******************************************************************************
//  ENF OF FILE
//******************************************************************************

