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

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

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

//char GlobalVar1; 
//char GlobalVar2; 

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

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

/*
 * Настройка внутреннего генератора на масимальную частоту
 * Запускаемся от внутреннего RC генератора
 */
void SystemClock_Config(void)
{
  uint32_t StartUpCounter;
  uint8_t  PLL_Mul;
  uint8_t  PLL_Div;
//  uint32_t HSE_Value;
  MODIFY_REG(PWR->CR, PWR_CR_VOS, PWR_CR_VOS_0);
//  PWR->CR &= ~(PWR_CR_VOS ^ PWR_CR_VOS_0);                                                      // Выбор диапазона напряжения 1.8в
// Пока не понятно поможет или нет, но включим.
  RCC->APB2ENR  |= RCC_APB2ENR_DBGEN;
  RCC->APB1ENR  |= RCC_APB1ENR_PWREN;
  SYSCFG->CFGR2 |= SYSCFG_CFGR2_FWDISEN;
  SYSCFG->CFGR3 |= SYSCFG_CFGR3_VREFINT_RDYF;
  // Шаг 1. Если кварц есть, запускаем HSE
/*  if(Quartz)
  {
    RCC->CR      |= RCC_CR_HSEON;                                                 // Запускаем HSE
    for (StartUpCounter = 0;; StartUpCounter++)
    {
      if(RCC->CR & RCC_CR_HSERDY) break;                                          // Запустился, вываливаемся из цикла
      if(StartUpCounter > 0x1000)                                                 // Не запустился гад
      {
        RCC->CR &= ~RCC_CR_HSEON;                                                 //Останавливаем HSE
        return;
      }
    }
  }
*/

  // Здесь у нас безкварцевый вариант чипа.

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

  // При надобности можно запустить предделитель. Только кому он нужен.
/*  RCC->CR   |= RCC_CR_HSIDIVEN;                                                 // Запускаем предделитель HSI
  for (StartUpCounter = 0;; StartUpCounter++)
  {
    if(RCC->CR & RCC_CR_HSIDIVF) break;                                          // Запустился, вываливаемся из цикла
    if(StartUpCounter > 0x1000)                                                 // Не запустился гад
    {
      RCC->CR &= ~RCC_CR_HSIDIVEN;
      RCC->CR &= ~RCC_CR_HSION;                                                 //Останавливаем HSE
      return;
    }
  }
*/

  // Шаг 2. Запускаем PLL
//  switch (Quartz)
//  {
//    case Quartz_4:
//      PLL_Mul = PLL_MUL_12;
//      HSE_Value = 4000000;
//      break;
//    case Quartz_6:
//      PLL_Mul = PLL_MUL_8;
//      HSE_Value = 6000000;
//      break;
//    case Quartz_8:
//      PLL_Mul = PLL_MUL_6;
//      HSE_Value = 8000000;
//      break;
//    case Quartz_12:
//      PLL_Mul = PLL_MUL_4;
//      HSE_Value = 12000000;
//      break;
//    case Quartz_16:
//      PLL_Mul = PLL_MUL_3;
//      HSE_Value = 16000000;
//      break;
//    default:
//      PLL_Mul = PLL_MUL_6;
//      PLL_Div = PLL_DIV_3;
//      break;
//  }

  PLL_Mul = PLL_MUL_6;
  PLL_Div = PLL_DIV_3;

  RCC->CFGR |= (PLL_Mul << RCC_CFGR_PLLMUL_Pos);                                // Устанавливаем умножитель и делитель
  RCC->CFGR |= (PLL_Div << RCC_CFGR_PLLDIV_Pos);

  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  |= (0x1UL << FLASH_ACR_LATENCY_Pos);                                 // Таймаут FLASH=2, т.к. частота задающего генератора 48 МГц
  RCC->CFGR   |= (0x3UL << RCC_CFGR_SW_Pos);                                       // Переключаемся на работу от PLL
  SysTickConfig();                                                              // Вызываем настройку системного таймера SysTick
}

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

