#include "CH32V00xxx.h"
extern "C" void SystemInit ();
enum CLKSRC : uint32_t {
  CLK_HSI = 0u,
  CLK_HSE,
  CLK_PLL,
};
// HSE i HSI mají frekvenci 24 MHz
void SystemInit(void) {
  RCC.CFGR0.R   = 0u;       // prescaler OFF
#if USE_HSE
  RCC.CTLR.modify([](RCC_Type::CTLR_DEF & r) -> auto {
    r.B.HSITRIM = 0x10u;
    r.B.HSION   = SET;
    r.B.HSEON   = SET;
    r.B.HSEBYP  = RESET;    // krystal
    r.B.CSSON   = SET;
    r.B.PLLON   = RESET;
    return r.R;
  });
  while (RCC.CTLR.B.HSERDY == RESET);
  RCC.CFGR0.modify([](RCC_Type::CFGR0_DEF & r) -> auto {
    r.B.SW      = CLK_HSE;
    r.B.PLLSRC  = SET;      // write only when PLL is off
    return r.R;
  });
  RCC.CTLR.modify([](RCC_Type::CTLR_DEF & r) -> auto {
  //r.B.HSION   = RESET;    // je možné vypnout, ale není to dobrý nápad, pak je nutný unbrick
    r.B.PLLON   = SET;
    return r.R;
  });  
#else // HSI
  RCC.CTLR.modify([](RCC_Type::CTLR_DEF & r) -> auto {
    r.B.HSITRIM = 0x10u;
    r.B.HSION   = SET;
    r.B.HSEBYP  = SET;
    r.B.CSSON   = SET;
    r.B.PLLON   = SET;
    return r.R;
  });
#endif // USE_HSE
  FLASH.ACTLR.B.LATENCY = SET;
  RCC.INTR.R = 0x009F0000u;   // clear interrupts
  while (RCC.CTLR.B.PLLRDY == RESET);
  // USE PLL - zdvojení frekvence, tj. 48 MHz
  RCC.CFGR0.B.SW          = CLK_PLL ;
  while (RCC.CFGR0.B.SWS != CLK_PLL);
}