RISC-V/V203F6P6/ch32v203/system.cpp

165 lines
4.7 KiB
C++
Raw Normal View History

2025-01-25 10:55:11 +01:00
//#include "CH32V20xxx.h"
#include "system.h"
extern "C" void SystemInit ();
enum CLKSRC : uint32_t {
CLK_HSI = 0u,
CLK_HSE,
CLK_PLL,
};
static constexpr unsigned HSI_VALUE = 8000000u; /* Value of the Internal oscillator in Hz */
static constexpr unsigned HSE_VALUE = 8000000u; /* Value of the External oscillator in Hz */
/* In the following line adjust the External High Speed oscillator (HSE) Startup Timeout value */
static constexpr unsigned HSE_STARTUP_TIMEOUT = 0x1000u; /* Time out for HSE start up */
// HSE i HSI mají frekvenci 8 MHz
static constexpr uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
uint32_t SystemCoreClock = SYSTEM_CORE_CLOCK; /* System Clock Frequency (Core Clock) */
static void SetSysClock_HSE(void) {
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
RCC.CTLR.B.HSEON = SET;
/* Wait till HSE is ready and if Time out is reached exit */
do {
HSEStatus = RCC.CTLR.B.HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));
if ((RCC.CTLR.B.HSERDY) != RESET) {
HSEStatus = (uint32_t)0x01;
} else {
HSEStatus = (uint32_t)0x00;
}
if (HSEStatus == (uint32_t)0x01) {
RCC.CFGR0.modify([](RCC_Type::CFGR0_DEF & r) -> auto {
r.B.HPRE = 0u; /* HCLK = SYSCLK */
r.B.PPRE2 = 0u; /* PCLK2 = HCLK */
r.B.PPRE1 = 4u; /* PCLK1 = HCLK */
/* CH32V20x_D6-PLL configuration: PLLCLK = HSE * 12 = 96 MHz (HSE=8MHZ)
* CH32V20x_D8-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
* CH32V20x_D8W-PLL configuration: PLLCLK = HSE/4 * 12 = 96 MHz (HSE=32MHZ)
*/
r.B.PLLSRC = SET;
r.B.PLLXTPRE = RESET;
r.B.PLLMUL = 15u; // or 10u for 96 MHz
return r.R;
});
/* Enable PLL */
RCC.CTLR.B.PLLON = SET;
/* Wait till PLL is ready */
while((RCC.CTLR.B.PLLRDY) == RESET) {}
/* Select PLL as system clock source */
RCC.CFGR0.B.SW = CLK_PLL;
/* Wait till PLL is used as system clock source */
while (RCC.CFGR0.B.SWS != CLK_PLL) {}
} else {
/*
* If HSE fails to start-up, the application will have wrong clock
* configuration. User can add here some code to deal with this error
*/
}
}
void SystemInit(void) {
RCC.CTLR.R |= 0x00000001u;
RCC.CFGR0.R &= 0xF0FF0000u;
RCC.CTLR.R &= 0xFEF6FFFFu;
RCC.CTLR.R &= 0xFFFBFFFFu;
RCC.CFGR0.R &= 0xFF00FFFFu;
RCC.INTR.R = 0x009F0000u;
SetSysClock_HSE();
}
/*********************************************************************
* @fn SystemCoreClockUpdate
*
* @brief Update SystemCoreClock variable according to Clock Register Values.
*
* @return none
*/
void SystemCoreClockUpdate (void) {
uint32_t tmp = 0, pllmull = 0, pllsource = 0;
tmp = RCC.CFGR0.B.SWS;
switch (tmp) {
case 0x00:
SystemCoreClock = HSI_VALUE;
break;
case 0x01:
SystemCoreClock = HSE_VALUE;
break;
case 0x02:
pllmull = RCC.CFGR0.B.PLLMUL;
pllsource = RCC.CFGR0.B.PLLSRC;
pllmull += 2u;
if(pllmull == 17) pllmull = 18;
if (pllsource == 0u) {
if(EXTEND.EXTEND_CTR.B.PLL_HSI_PRE){
SystemCoreClock = HSI_VALUE * pllmull;
} else {
SystemCoreClock = (HSI_VALUE >> 1) * pllmull;
}
} else {
if (RCC.CFGR0.B.PLLXTPRE) {
SystemCoreClock = (HSE_VALUE >> 1) * pllmull;
} else {
SystemCoreClock = HSE_VALUE * pllmull;
}
}
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
tmp = AHBPrescTable[RCC.CFGR0.B.HPRE];
SystemCoreClock >>= tmp;
}
static uint32_t p_us = 0u;
static bool timeout;
void delay_init () {
// default clock is HCLK / 8
p_us = SystemCoreClock / 8000000;
}
void delay_us (const unsigned dly) {
const uint32_t i = (uint32_t) dly * p_us;
SysTick.SR &= ~(1 << 0);
SysTick.CMPLR = i;
SysTick.CTLR.modify([](SysTick_Type::CTLR_DEF & r) -> uint32_t {
r.B.MODE = SET;
r.B.INIT = SET;
return r.R;
});
SysTick.CTLR.B.STE = SET;
while((SysTick.SR & (1u << 0)) != (1u << 0));
SysTick.CTLR.B.STE = RESET;
}
void set_timeout_us (const uint32_t time) {
SysTick.CTLR.B.STE = RESET;
timeout = false;
const uint32_t i = (uint32_t) time * p_us;
SysTick.SR &= ~(1 << 0);
SysTick.CMPLR = i;
SysTick.CTLR.modify([](SysTick_Type::CTLR_DEF & r) -> uint32_t {
r.B.MODE = SET;
r.B.INIT = SET;
return r.R;
});
SysTick.CTLR.B.STE = SET;
}
bool is_timeout () {
if (SysTick.SR & (1u << 0)) {
SysTick.CTLR.B.STE = RESET;
timeout = true;
} else {
}
return timeout;
}