Initial bootloader implementation

Took a publicly available XMODEM bootloader and made it work on HK32F.

Known issues:
- Erase is super slow on this MCU. The upload routine erases all flash before loading, which means the first packet seems to hang. This also erases possibly persistent data stored in unused pages on flash.
This commit is contained in:
true
2023-06-25 01:41:36 -07:00
parent 861caf8bce
commit a47cfa7fa5
83 changed files with 39624 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,37 @@
/**
******************************************************************************
* @file system_hk32f030m.h
* @author Rakan.Z/laura.C
* @version V1.0
* @brief API file of system clk config
* @changelist
******************************************************************************
*/
#ifndef __SYSTEM_HK32F030M_H
#define __SYSTEM_HK32F030M_H
#ifdef __cplusplus
extern "C" {
#endif
/** hk32f030m_System_Exported_types */
extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */
extern const uint16_t AHBPrescTable[16]; /*!< AHB prescalers table values */
extern const uint8_t APBPrescTable[8]; /*!< APB prescalers table values */
extern void SystemInit(void);
extern void SystemCoreClockUpdate(void);
#ifdef __cplusplus
}
#endif
#endif /*__SYSTEM_HK32F030M_H */

View File

@@ -0,0 +1,246 @@
/**
******************************************************************************
* @file startup_hk32f030mf4p6.s
* @brief HK32F030MF4P6 devices vector table for GCC toolchain.
* This module performs:
* - Set the initial SP
* - Set the initial PC == Reset_Handler,
* - Set the vector table entries with the exceptions ISR address
* - Branches to main in the C library (which eventually calls main()).
* After Reset the Cortex-M0 processor is in Thread mode,
* priority is Privileged, and the Stack is set to Main.
******************************************************************************
*/
.syntax unified
.cpu cortex-m0
.fpu softvfp
.thumb
.global g_pfnVectors
.global Default_Handler
/* start address for the initialization values of the .data section.
defined in linker script */
.word _sidata
/* start address for the .data section. defined in linker script */
.word _sdata
/* end address for the .data section. defined in linker script */
.word _edata
/* start address for the .bss section. defined in linker script */
.word _sbss
/* end address for the .bss section. defined in linker script */
.word _ebss
.section .text.Reset_Handler
.weak Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
ldr r0, =_estack
mov sp, r0 /* set stack pointer */
/* Copy the data segment initializers from flash to SRAM */
ldr r0, =_sdata
ldr r1, =_edata
ldr r2, =_sidata
movs r3, #0
b LoopCopyDataInit
CopyDataInit:
ldr r4, [r2, r3]
str r4, [r0, r3]
adds r3, r3, #4
LoopCopyDataInit:
adds r4, r0, r3
cmp r4, r1
bcc CopyDataInit
/* Zero fill the bss segment. */
ldr r2, =_sbss
ldr r4, =_ebss
movs r3, #0
b LoopFillZerobss
FillZerobss:
str r3, [r2]
adds r2, r2, #4
LoopFillZerobss:
cmp r2, r4
bcc FillZerobss
SystemStartup:
/* Call the clock system intitialization function.*/
bl SystemInit
/* Call static constructors. Remove this line if compile with `-nostartfiles` reports error */
bl __libc_init_array
/* Call the application's entry point.*/
bl main
LoopForever:
b LoopForever
.size Reset_Handler, .-Reset_Handler
/**
* @brief This is the code that gets called when the processor receives an
* unexpected interrupt. This simply enters an infinite loop, preserving
* the system state for examination by a debugger.
*
* @param None
* @retval : None
*/
.section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
b Infinite_Loop
.size Default_Handler, .-Default_Handler
/******************************************************************************
*
* The minimal vector table for a Cortex M0. Note that the proper constructs
* must be placed on this to ensure that it ends up at physical address
* 0x0000.0000.
*
******************************************************************************/
.section .isr_vector,"a",%progbits
.type g_pfnVectors, %object
.size g_pfnVectors, .-g_pfnVectors
g_pfnVectors:
.word _estack
.word Reset_Handler
.word NMI_Handler
.word HardFault_Handler
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word 0
.word SVC_Handler
.word 0
.word 0
.word PendSV_Handler
.word SysTick_Handler
.word WWDG_IRQHandler /* Window WatchDog */
.word 0 /* Reserved */
.word EXTI11_IRQHandler /* EXTI Line 11 interrupt(AWU_WKP) */
.word FLASH_IRQHandler /* FLASH */
.word RCC_IRQHandler /* RCC */
.word EXTI0_IRQHandler /* EXTI Line 0 */
.word EXTI1_IRQHandler /* EXTI Line 1 */
.word EXTI2_IRQHandler /* EXTI Line 2 */
.word EXTI3_IRQHandler /* EXTI Line 3 */
.word EXTI4_IRQHandler /* EXTI Line 4 */
.word EXTI5_IRQHandler /* EXTI Line 5 */
.word TIM1_BRK_IRQHandler /* TIM1 break interrupt */
.word ADC1_IRQHandler /* ADC1 interrupt, combined with EXTI line 8 */
.word TIM1_UP_TRG_COM_IRQHandler /* TIM1 Update, Trigger and Commutation */
.word TIM1_CC_IRQHandler /* TIM1 Capture Compare */
.word TIM2_IRQHandler /* TIM2 */
.word 0 /* Reserved */
.word TIM6_IRQHandler /* TIM6 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word EXTI6_IRQHandler /* EXTI Line 6 */
.word EXTI7_IRQHandler /* EXTI Line 7 */
.word I2C1_IRQHandler /* I2C1 global interrupt, combined with EXTI Line 10 */
.word 0 /* Reserved */
.word SPI1_IRQHandler /* SPI1 */
.word 0 /* Reserved */
.word USART1_IRQHandler /* USART1 global interrupt, combined with EXTI Line 9 */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
.word 0 /* Reserved */
/*******************************************************************************
*
* Provide weak aliases for each Exception handler to the Default_Handler.
* As they are weak aliases, any function with the same name will override
* this definition.
*
*******************************************************************************/
.weak NMI_Handler
.thumb_set NMI_Handler,Default_Handler
.weak HardFault_Handler
.thumb_set HardFault_Handler,Default_Handler
.weak SVC_Handler
.thumb_set SVC_Handler,Default_Handler
.weak PendSV_Handler
.thumb_set PendSV_Handler,Default_Handler
.weak SysTick_Handler
.thumb_set SysTick_Handler,Default_Handler
.weak WWDG_IRQHandler
.thumb_set WWDG_IRQHandler,Default_Handler
.weak EXTI11_IRQHandler
.thumb_set EXTI11_IRQHandler,Default_Handler
.weak FLASH_IRQHandler
.thumb_set FLASH_IRQHandler,Default_Handler
.weak RCC_IRQHandler
.thumb_set RCC_IRQHandler,Default_Handler
.weak EXTI0_IRQHandler
.thumb_set EXTI0_IRQHandler,Default_Handler
.weak EXTI1_IRQHandler
.thumb_set EXTI1_IRQHandler,Default_Handler
.weak EXTI2_IRQHandler
.thumb_set EXTI2_IRQHandler,Default_Handler
.weak EXTI3_IRQHandler
.thumb_set EXTI3_IRQHandler,Default_Handler
.weak EXTI4_IRQHandler
.thumb_set EXTI4_IRQHandler,Default_Handler
.weak EXTI5_IRQHandler
.thumb_set EXTI5_IRQHandler,Default_Handler
.weak TIM1_BRK_IRQHandler
.thumb_set TIM1_BRK_IRQHandler,Default_Handler
.weak ADC1_IRQHandler
.thumb_set ADC1_IRQHandler,Default_Handler
.weak TIM1_UP_TRG_COM_IRQHandler
.thumb_set TIM1_UP_TRG_COM_IRQHandler,Default_Handler
.weak TIM1_CC_IRQHandler
.thumb_set TIM1_CC_IRQHandler,Default_Handler
.weak TIM2_IRQHandler
.thumb_set TIM2_IRQHandler,Default_Handler
.weak TIM6_IRQHandler
.thumb_set TIM6_IRQHandler,Default_Handler
.weak EXTI6_IRQHandler
.thumb_set EXTI6_IRQHandler,Default_Handler
.weak EXTI7_IRQHandler
.thumb_set EXTI7_IRQHandler,Default_Handler
.weak I2C1_IRQHandler
.thumb_set I2C1_IRQHandler,Default_Handler
.weak SPI1_IRQHandler
.thumb_set SPI1_IRQHandler,Default_Handler
.weak USART1_IRQHandler
.thumb_set USART1_IRQHandler,Default_Handler

View File

@@ -0,0 +1,418 @@
/**
******************************************************************************
* @file system_hk32f030m.c
* @author laura.C
* @version V1.0
* @brief API file of system clk config
* @changelist
******************************************************************************
*/
/*
This file configures the system clock as follows:
*=============================================================================
* Supported hk32f030m device
*-----------------------------------------------------------------------------
* System Clock source | HSI32M
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 32000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 32000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 1
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
*/
#include "hk32f030m.h"
/* system clock source */
#define SYSCLK_SRC_HSI8M 0x2
#define SYSCLK_SRC_HSI16M 0x3
#define SYSCLK_SRC_HSI32M 0x4
#define SYSCLK_SRC_LSI 0x5
#define SYSCLK_SCR_EXTCLK_IO 0x6
#define SYSCLK_SOURCE SYSCLK_SRC_HSI8M
/* vector table location */
// #define VECT_TAB_SRAM
#ifndef VECT_TAB_OFFSET
#define VECT_TAB_OFFSET 0x0 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */
#endif
uint32_t System_SysClk; // SYSCLK which feeds AHB, ADC, USART, etc. System clock.
uint32_t System_HClk; // HCLK which feeds core, AHB bus, memory. CPU clock.
#if(SYSCLK_SOURCE==SYSCLK_SRC_HSI8M)
#define SYSCLK_FREQ_HSI 32000000
#define HCLK_FREQ 8000000
#define SET_FLASH_LATENCY FLASH_Latency_0
#define SET_HPRE_DIV RCC_CFGR_HPRE_DIV4
static void SetSysClockToHSI(void);
#elif(SYSCLK_SOURCE == SYSCLK_SRC_HSI16M)
#define SYSCLK_FREQ_HSI 32000000
#define HCLK_FREQ 16000000
#define SET_FLASH_LATENCY FLASH_Latency_0
#define SET_HPRE_DIV RCC_CFGR_HPRE_DIV2
static void SetSysClockToHSI(void);
#elif(SYSCLK_SOURCE == SYSCLK_SRC_HSI32M)
#define SYSCLK_FREQ_HSI 32000000
#define HCLK_FREQ 32000000
#define SET_FLASH_LATENCY FLASH_Latency_1
#define SET_HPRE_DIV RCC_CFGR_HPRE_DIV1
static void SetSysClockToHSI(void);
#elif(SYSCLK_SOURCE == SYSCLK_SRC_LSI)
#define SYSCLK_FREQ_LSI LSI_VALUE
uint32_t SystemCoreClock = SYSCLK_FREQ_LSI;
static void SetSysClockToLSI(void);
#elif(SYSCLK_SOURCE == SYSCLK_SCR_EXTCLK_IO)
#define SYSCLK_FREQ_EXTCLK EXTCLK_VALUE
uint32_t SystemCoreClock = SYSCLK_FREQ_EXTCLK;
static void SetSysClockToEXTCLK(void);
#endif
static void SetSysClock(void);
/**
* @brief Setup the microcontroller system.
* Initialize the default HSI clock source, vector table location and the PLL configuration is reset.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* Set HSION bit */
RCC->CR |= (uint32_t)0x00000001;
/* Reset SW[1:0], HPRE[3:0], PPRE[2:0] and MCOSEL[2:0] bits */
RCC->CFGR &= (uint32_t)0xF8FFB81C;
/* Reset USARTSW[1:0], I2CSW bits */
RCC->CFGR3 &= (uint32_t)0xFFFFFFEC;
/* Disable all interrupts */
RCC->CIR = 0x00000000;
SetSysClock();
#ifdef VECT_TAB_SRAM
SYSCFG->CFGR1 |= SYSCFG_CFGR1_MEM_MODE; /* Vector Table Relocation in Internal SRAM. */
#else
FLASH->INT_VEC_OFFSET = VECT_TAB_OFFSET ; /* Vector Table Relocation in Internal FLASH. */
#endif
}
/**
* @brief Configures the System clock frequency, HCLK, PCLK prescalers.
* @param None
* @retval None
*/
static void SetSysClock(void)
{
/*reload the hsi trimming value to the bit3~bit13 of RCC_CR register */
uint32_t u32HSIFLASH = 0;
uint32_t u32RCC_CR = 0;
uint32_t u32HSITemp = 0;
uint16_t u16HSITempH = 0;
uint16_t u16HSITempL = 0;
u32HSIFLASH = *(uint32_t *) 0x1FFFF820;
u16HSITempH = (uint16_t)(u32HSIFLASH>>16);
u16HSITempL = (uint16_t)(u32HSIFLASH);
if(!(u16HSITempH & u16HSITempL))
{
u32HSITemp = RCC->CR;
u32HSITemp &= (uint32_t)((uint32_t)~(RCC_CR_HSITRIM|RCC_CR_HSICAL));
u32RCC_CR = (uint32_t)(((u16HSITempL & 0x001F) <<3) | (((u16HSITempL>>5) & 0x003F)<<8));
RCC->CR |= u32RCC_CR;
}
/*end*/
#if(SYSCLK_SOURCE==SYSCLK_SRC_HSI8M)
SetSysClockToHSI();
#elif(SYSCLK_SOURCE == SYSCLK_SRC_HSI16M)
SetSysClockToHSI();
#elif(SYSCLK_SOURCE == SYSCLK_SRC_HSI32M)
SetSysClockToHSI();
#elif(SYSCLK_SOURCE == SYSCLK_SRC_LSI)
SetSysClockToLSI();
#elif(SYSCLK_SOURCE == SYSCLK_SCR_EXTCLK_IO)
SetSysClockToEXTCLK();
#endif
/* If none of the define above is enabled, the HSI is used as System clock source (default after reset) */
}
#ifdef SYSCLK_FREQ_HSI
static void SetSysClockToHSI(void)
{
__IO uint32_t StartUpCounter = 0, HSIStatus = 0;
__IO uint32_t ACRreg = 0;
__IO uint32_t RCCHCLKReg = 0;
__IO uint32_t RCCPCLKReg = 0;
/* Enable HSI */
RCC->CR |= RCC_CR_HSION;
/* Set flash programming clock to 2MHz using HSI32M directly
* Datasheet and RM was updated in 2023 which derated flash programming from 4MHz
* 0x07 = 4MHz, 0x08 = 2MHz. change as you see fit */
RCC->CFGR4 &= ~(RCC_RCC_CFGR4_FLITFCLK_PRE | RCC_RCC_CFGR4_FLITFCLK_SE);
RCC->CFGR4 |= (((uint32_t)0x07) << RCC_RCC_CFGR4_FLITFCLK_PRE_Pos);
/* Wait until HSI is ready; if timeout is reached, then exit */
do {
HSIStatus = RCC->CR & RCC_CR_HSIRDY;
StartUpCounter++;
} while((HSIStatus == 0) && (StartUpCounter != HSI_STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_HSIRDY) != RESET) {
HSIStatus = (uint32_t)0x01;
} else {
HSIStatus = (uint32_t)0x00;
}
if (HSIStatus == (uint32_t)0x01) {
/* Flash wait state */
ACRreg = FLASH->ACR;
ACRreg &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR = (uint32_t)(SET_FLASH_LATENCY | ACRreg);
/* HCLK = configured divided value from SYSCLK (which will later be set to HSI32M) */
RCCHCLKReg = RCC->CFGR;
RCCHCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_HPRE_Msk);
RCC->CFGR = (uint32_t)(SET_HPRE_DIV | RCCHCLKReg);
/* PCLK = HCLK */
RCCPCLKReg = RCC->CFGR;
RCCPCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_PPRE_Msk);
RCC->CFGR = (uint32_t)(RCC_CFGR_PPRE_DIV1|RCCPCLKReg);
/* Select HSI32M as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_HSI;
/* Wait until HSI is active as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI);
} else {
/* If clock fails to start, the application will have wrong clock configuration.
* User can add some code here to deal with this error
*/
}
}
#elif (SYSCLK_SOURCE == SYSCLK_SRC_LSI)
static void SetSysClockToLSI(void)
{
__IO uint32_t StartUpCounter = 0, LSIStatus = 0;
/* Enable LSI */
RCC->CSR |= RCC_CSR_LSION;
/* Wait till LSI is ready and if Time out is reached exit */
do{
LSIStatus = RCC->CSR & RCC_CSR_LSIRDY;
StartUpCounter++;
} while((LSIStatus == 0) && (StartUpCounter != STARTUP_TIMEOUT));
if ((RCC->CSR & RCC_CSR_LSIRDY) != RESET)
{
LSIStatus = (uint32_t)0x01;
}
else
{
LSIStatus = (uint32_t)0x00;
}
if (LSIStatus == (uint32_t)0x01)
{
/* Flash wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_Latency_0;
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE_DIV1;
/* Select HSI as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_LSI;
/* Wait till LSI is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_LSI)
{
}
}
else
{ /* If fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */
}
};
#elif (SYSCLK_SOURCE == SYSCLK_SCR_EXTCLK_IO)
static void SetSysClockToEXTCLK(void)
{
__IO uint32_t StartUpCounter = 0, EXTCLKStatus = 0;
__IO uint32_t ACRreg = 0;
__IO uint32_t RCCHCLKReg = 0;
__IO uint32_t RCCPCLKReg = 0;
//enable EXTIO PA1/PD7/PB5/PC5
/* Configure PA1 as CLOCK input */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
// GPIO_InitTypeDef GPIO_InitStructure;
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// GPIO_Init(GPIOD, &GPIO_InitStructure);
// RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
// GPIO_InitTypeDef GPIO_InitStructure;
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// GPIO_Init(GPIOB, &GPIO_InitStructure);
// RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
// GPIO_InitTypeDef GPIO_InitStructure;
// GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
// GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
// GPIO_Init(GPIOC, &GPIO_InitStructure);
/*CLOCK select */
RCC->CFGR4 &= (uint32_t)~(RCC_RCC_CFGR4_EXTCLK_SEL);
RCC->CFGR4 |= (uint32_t)RCC_CFGR4_EXTCLK_SEL_PA1;
// RCC->CFGR4 |= (uint32_t)RCC_CFGR4_EXTCLK_SEL_PB5;
// RCC->CFGR4 |= (uint32_t)RCC_CFGR4_EXTCLK_SEL_PC5;
// RCC->CFGR4 |= (uint32_t)RCC_CFGR4_EXTCLK_SEL_PD7;
/* Enable EXTCLK */
RCC->CR |= RCC_CR_EXTCLKON;
/* Wait till LSI is ready and if Time out is reached exit */
do{
EXTCLKStatus = RCC->CR & RCC_CR_EXTCLKRDY;
StartUpCounter++;
} while((EXTCLKStatus == 0) && (StartUpCounter != STARTUP_TIMEOUT));
if ((RCC->CR & RCC_CR_EXTCLKRDY) != RESET)
{
EXTCLKStatus = (uint32_t)0x01;
}
else
{
EXTCLKStatus = (uint32_t)0x00;
}
if (EXTCLKStatus == (uint32_t)0x01)
{
/* Flash wait state */
ACRreg= FLASH->ACR;
ACRreg &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
if (SystemCoreClock <= 16000000)
FLASH->ACR = (uint32_t)(FLASH_Latency_0|ACRreg);
else if(SystemCoreClock <= 32000000)
FLASH->ACR = (uint32_t)(FLASH_Latency_1|ACRreg);
else
FLASH->ACR = (uint32_t)(FLASH_Latency_2|ACRreg);
RCCHCLKReg = RCC->CFGR;
RCCHCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_HPRE_Msk);
/* HCLK = SYSCLK */
RCC->CFGR = (uint32_t)(RCC_CFGR_HPRE_DIV1|RCCHCLKReg);
RCCPCLKReg = RCC->CFGR;
RCCPCLKReg &= (uint32_t)((uint32_t)~RCC_CFGR_PPRE_Msk);
/* PCLK = HCLK */
RCC->CFGR = (uint32_t)(RCC_CFGR_PPRE_DIV1|RCCPCLKReg);
/* Select EXTCLK as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_EXTCLK;
/* Wait till EXTCLK is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != RCC_CFGR_SWS_EXTCLK)
{
}
}
else
{ /* If fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */
}
};
#endif
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
* @param None
* @retval None
*/
void SystemCoreClockUpdate (void)
{
uint32_t tmp = 0, presc = 0;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case RCC_CFGR_SWS_HSI: /* HSI used as system clock */
SystemCoreClock = HCLK_FREQ;
break;
case RCC_CFGR_SWS_EXTCLK: /* EXTCLK used as system clock */
SystemCoreClock = EXTCLK_VALUE;
break;
case RCC_CFGR_SWS_LSI: /* LSI used as system clock */
SystemCoreClock = LSI_VALUE;
break;
default: /* HSI used as system clock */
SystemCoreClock = HCLK_FREQ;
break;
}
/* Compute HCLK clock frequency ----------------*/
/* Get HCLK prescaler */
tmp = RCC->CFGR & RCC_CFGR_HPRE;
tmp = tmp >> 4;
presc = AHBPrescTable[tmp];
/* HCLK clock frequency */
SystemCoreClock = SystemCoreClock/presc;
}