-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSystem.c
115 lines (87 loc) · 3.19 KB
/
System.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include "System.h"
// PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
#define PLL_M 8
#ifndef EnableOverclocking
#define PLL_N 336
#else
#define PLL_N 352
#endif
// SYSCLK = PLL_VCO / PLL_P
#define PLL_P 2
// USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ
#define PLL_Q 7
// PLLI2S_VCO = (HSE_VALUE Or HSI_VALUE / PLL_M) * PLLI2S_N
// I2SCLK = PLLI2S_VCO / PLLI2S_R
#define PLLI2S_N 192
#define PLLI2S_R 5
static void InitializeClocks();
void InitializeSystem()
{
// Reset the RCC clock configuration to the default reset state
RCC->CR|=0x00000001; // Set HSION bit
RCC->CFGR=0x00000000; // Reset CFGR register
RCC->CR&=0xFEF6FFFF; // Reset HSEON, CSSON and PLLON bits
RCC->PLLCFGR=0x24003010; // Reset PLLCFGR register
RCC->CR&=0xFFFBFFFF; // Reset HSEBYP bit
RCC->CIR=0x00000000; // Disable all interrupts
// Configure the System clock source, PLL Multiplier and Divider factors,
// AHB/APBx prescalers and Flash settings
InitializeClocks();
// Set vector table offset to flash memory start.
SCB->VTOR=FLASH_BASE;
// Set up interrupts to 4 bits preemption priority.
SCB->AIRCR=0x05FA0000|0x300;
}
static void InitializeClocks()
{
// PLL (clocked by HSE) used as System clock source.
// Enable HSE and wait until it is read.
RCC->CR|=RCC_CR_HSEON;
while(!(RCC->CR&RCC_CR_HSERDY));
// Enable high performance mode, System frequency up to 168 MHz.
RCC->APB1ENR|=RCC_APB1ENR_PWREN;
PWR->CR|=PWR_CR_PMODE;
RCC->CFGR|=RCC_CFGR_HPRE_DIV1; // HCLK = SYSCLK / 1
RCC->CFGR|=RCC_CFGR_PPRE2_DIV2; // PCLK2 = HCLK / 2
RCC->CFGR|=RCC_CFGR_PPRE1_DIV4; // PCLK1 = HCLK / 4
// Configure the main PLL.
RCC->PLLCFGR=PLL_M|(PLL_N<<6)|(((PLL_P>>1)-1)<<16)|(RCC_PLLCFGR_PLLSRC_HSE)|(PLL_Q<<24);
// Enable the main PLL and wait until it is ready.
RCC->CR|=RCC_CR_PLLON;
while(!(RCC->CR&RCC_CR_PLLRDY));
// Configure Flash prefetch, Instruction cache, Data cache and wait state
FLASH->ACR=FLASH_ACR_ICEN|FLASH_ACR_DCEN|FLASH_ACR_LATENCY_5WS;
// Select the main PLL as system clock source.
RCC->CFGR&=~RCC_CFGR_SW;
RCC->CFGR|=RCC_CFGR_SW_PLL;
// Wait until the main PLL is used as system clock source.
while((RCC->CFGR&RCC_CFGR_SWS)!=RCC_CFGR_SWS_PLL);
}
// Interrupt handlers.
static InterruptHandler **WritableInterruptTable();
void Default_Handler();
extern InterruptHandler *__isr_vector_sram[];
void InstallInterruptHandler(IRQn_Type interrupt,InterruptHandler handler)
{
// TODO: Disable interrupts.
InterruptHandler **currenttable=WritableInterruptTable();
currenttable[interrupt+16]=handler;
}
void RemoveInterruptHandler(IRQn_Type interrupt,InterruptHandler handler)
{
// TODO: Disable interrupts.
InterruptHandler **currenttable=WritableInterruptTable();
currenttable[interrupt+16]=Default_Handler;
}
static InterruptHandler **WritableInterruptTable()
{
InterruptHandler **currenttable=(InterruptHandler **)SCB->VTOR;
if((uint32_t)currenttable==FLASH_BASE)
{
InterruptHandler **flashtable=(InterruptHandler **)FLASH_BASE;
currenttable=__isr_vector_sram;
for(int i=0;i<98;i++) currenttable[i]=flashtable[i];
SCB->VTOR=(uint32_t)currenttable;
}
return currenttable;
}