diff options
Diffstat (limited to 'lib/chibios/os/hal/ports/STM32/STM32F3xx/hal_lld.c')
-rw-r--r-- | lib/chibios/os/hal/ports/STM32/STM32F3xx/hal_lld.c | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/lib/chibios/os/hal/ports/STM32/STM32F3xx/hal_lld.c b/lib/chibios/os/hal/ports/STM32/STM32F3xx/hal_lld.c new file mode 100644 index 000000000..cde7bd777 --- /dev/null +++ b/lib/chibios/os/hal/ports/STM32/STM32F3xx/hal_lld.c | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio | ||
3 | |||
4 | Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | you may not use this file except in compliance with the License. | ||
6 | You may obtain a copy of the License at | ||
7 | |||
8 | http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | |||
10 | Unless required by applicable law or agreed to in writing, software | ||
11 | distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | See the License for the specific language governing permissions and | ||
14 | limitations under the License. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file STM32F3xx/hal_lld.c | ||
19 | * @brief STM32F3xx HAL subsystem low level driver source. | ||
20 | * | ||
21 | * @addtogroup HAL | ||
22 | * @{ | ||
23 | */ | ||
24 | |||
25 | #include "hal.h" | ||
26 | |||
27 | /*===========================================================================*/ | ||
28 | /* Driver local definitions. */ | ||
29 | /*===========================================================================*/ | ||
30 | |||
31 | /*===========================================================================*/ | ||
32 | /* Driver exported variables. */ | ||
33 | /*===========================================================================*/ | ||
34 | |||
35 | /** | ||
36 | * @brief CMSIS system core clock variable. | ||
37 | * @note It is declared in system_stm32f3xx.h. | ||
38 | */ | ||
39 | uint32_t SystemCoreClock = STM32_HCLK; | ||
40 | |||
41 | /*===========================================================================*/ | ||
42 | /* Driver local variables and types. */ | ||
43 | /*===========================================================================*/ | ||
44 | |||
45 | /*===========================================================================*/ | ||
46 | /* Driver local functions. */ | ||
47 | /*===========================================================================*/ | ||
48 | |||
49 | /** | ||
50 | * @brief Initializes the backup domain. | ||
51 | * @note WARNING! Changing clock source impossible without resetting | ||
52 | * of the whole BKP domain. | ||
53 | */ | ||
54 | static void hal_lld_backup_domain_init(void) { | ||
55 | |||
56 | /* Backup domain access enabled and left open.*/ | ||
57 | PWR->CR |= PWR_CR_DBP; | ||
58 | |||
59 | /* Reset BKP domain if different clock source selected.*/ | ||
60 | if ((RCC->BDCR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { | ||
61 | /* Backup domain reset.*/ | ||
62 | RCC->BDCR = RCC_BDCR_BDRST; | ||
63 | RCC->BDCR = 0; | ||
64 | } | ||
65 | |||
66 | /* If enabled then the LSE is started.*/ | ||
67 | #if STM32_LSE_ENABLED | ||
68 | #if defined(STM32_LSE_BYPASS) | ||
69 | /* LSE Bypass.*/ | ||
70 | RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON | RCC_BDCR_LSEBYP; | ||
71 | #else | ||
72 | /* No LSE Bypass.*/ | ||
73 | RCC->BDCR |= STM32_LSEDRV | RCC_BDCR_LSEON; | ||
74 | #endif | ||
75 | while ((RCC->BDCR & RCC_BDCR_LSERDY) == 0) | ||
76 | ; /* Waits until LSE is stable. */ | ||
77 | #endif | ||
78 | |||
79 | #if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK | ||
80 | /* If the backup domain hasn't been initialized yet then proceed with | ||
81 | initialization.*/ | ||
82 | if ((RCC->BDCR & RCC_BDCR_RTCEN) == 0) { | ||
83 | /* Selects clock source.*/ | ||
84 | RCC->BDCR |= STM32_RTCSEL; | ||
85 | |||
86 | /* RTC clock enabled.*/ | ||
87 | RCC->BDCR |= RCC_BDCR_RTCEN; | ||
88 | } | ||
89 | #endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ | ||
90 | } | ||
91 | |||
92 | /*===========================================================================*/ | ||
93 | /* Driver interrupt handlers. */ | ||
94 | /*===========================================================================*/ | ||
95 | |||
96 | /*===========================================================================*/ | ||
97 | /* Driver exported functions. */ | ||
98 | /*===========================================================================*/ | ||
99 | |||
100 | /** | ||
101 | * @brief Low level HAL driver initialization. | ||
102 | * | ||
103 | * @notapi | ||
104 | */ | ||
105 | void hal_lld_init(void) { | ||
106 | |||
107 | /* Reset of all peripherals. | ||
108 | Note, GPIOs are not reset because initialized before this point in | ||
109 | board files.*/ | ||
110 | rccResetAHB(~STM32_GPIO_EN_MASK); | ||
111 | rccResetAPB1(0xFFFFFFFF); | ||
112 | rccResetAPB2(0xFFFFFFFF); | ||
113 | |||
114 | /* PWR clock enabled.*/ | ||
115 | rccEnablePWRInterface(true); | ||
116 | |||
117 | /* Initializes the backup domain.*/ | ||
118 | hal_lld_backup_domain_init(); | ||
119 | |||
120 | /* DMA subsystems initialization.*/ | ||
121 | #if defined(STM32_DMA_REQUIRED) | ||
122 | dmaInit(); | ||
123 | #endif | ||
124 | |||
125 | /* IRQ subsystem initialization.*/ | ||
126 | irqInit(); | ||
127 | |||
128 | /* Programmable voltage detector enable.*/ | ||
129 | #if STM32_PVD_ENABLE | ||
130 | PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); | ||
131 | #endif /* STM32_PVD_ENABLE */ | ||
132 | |||
133 | /* SYSCFG clock enabled here because it is a multi-functional unit shared | ||
134 | among multiple drivers.*/ | ||
135 | rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); | ||
136 | |||
137 | #if STM32_HAS_USB | ||
138 | /* USB IRQ relocated to not conflict with CAN.*/ | ||
139 | SYSCFG->CFGR1 |= SYSCFG_CFGR1_USB_IT_RMP; | ||
140 | #endif | ||
141 | } | ||
142 | |||
143 | /** | ||
144 | * @brief STM32 clocks and PLL initialization. | ||
145 | * @note All the involved constants come from the file @p board.h. | ||
146 | * @note This function should be invoked just after the system reset. | ||
147 | * | ||
148 | * @special | ||
149 | */ | ||
150 | void stm32_clock_init(void) { | ||
151 | |||
152 | #if !STM32_NO_INIT | ||
153 | /* HSI setup, it enforces the reset situation in order to handle possible | ||
154 | problems with JTAG probes and re-initializations.*/ | ||
155 | RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */ | ||
156 | while (!(RCC->CR & RCC_CR_HSIRDY)) | ||
157 | ; /* Wait until HSI is stable. */ | ||
158 | |||
159 | /* HSI is selected as new source without touching the other fields in | ||
160 | CFGR. Clearing the register has to be postponed after HSI is the | ||
161 | new source.*/ | ||
162 | RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */ | ||
163 | while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI) | ||
164 | ; /* Wait until HSI is selected. */ | ||
165 | |||
166 | /* Registers finally cleared to reset values.*/ | ||
167 | RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */ | ||
168 | RCC->CFGR = 0; /* CFGR reset value. */ | ||
169 | |||
170 | #if STM32_HSE_ENABLED | ||
171 | /* HSE activation.*/ | ||
172 | #if defined(STM32_HSE_BYPASS) | ||
173 | /* HSE Bypass.*/ | ||
174 | RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; | ||
175 | #else | ||
176 | /* No HSE Bypass.*/ | ||
177 | RCC->CR |= RCC_CR_HSEON; | ||
178 | #endif | ||
179 | while (!(RCC->CR & RCC_CR_HSERDY)) | ||
180 | ; /* Waits until HSE is stable. */ | ||
181 | #endif | ||
182 | |||
183 | #if STM32_LSI_ENABLED | ||
184 | /* LSI activation.*/ | ||
185 | RCC->CSR |= RCC_CSR_LSION; | ||
186 | while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) | ||
187 | ; /* Waits until LSI is stable. */ | ||
188 | #endif | ||
189 | |||
190 | /* Clock settings.*/ | ||
191 | RCC->CFGR = STM32_MCOSEL | STM32_USBPRE | STM32_PLLMUL | | ||
192 | STM32_PLLSRC | STM32_PPRE1 | STM32_PPRE2 | | ||
193 | STM32_HPRE; | ||
194 | RCC->CFGR2 = STM32_ADC34PRES | STM32_ADC12PRES | STM32_PREDIV; | ||
195 | RCC->CFGR3 = STM32_UART5SW | STM32_UART4SW | STM32_USART3SW | | ||
196 | STM32_USART2SW | STM32_I2C2SW | STM32_I2C1SW | | ||
197 | STM32_USART1SW; | ||
198 | |||
199 | #if STM32_ACTIVATE_PLL | ||
200 | /* PLL activation.*/ | ||
201 | RCC->CR |= RCC_CR_PLLON; | ||
202 | while (!(RCC->CR & RCC_CR_PLLRDY)) | ||
203 | ; /* Waits until PLL is stable. */ | ||
204 | #endif | ||
205 | |||
206 | /* Flash setup and final clock selection. */ | ||
207 | FLASH->ACR = STM32_FLASHBITS; | ||
208 | while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != | ||
209 | (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { | ||
210 | } | ||
211 | |||
212 | /* Switching to the configured clock source if it is different from HSI.*/ | ||
213 | #if (STM32_SW != STM32_SW_HSI) | ||
214 | /* Switches clock source.*/ | ||
215 | RCC->CFGR |= STM32_SW; | ||
216 | while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) | ||
217 | ; /* Waits selection complete. */ | ||
218 | #endif | ||
219 | |||
220 | /* After PLL activation because the special requirements for TIM1 and | ||
221 | TIM8 bits.*/ | ||
222 | RCC->CFGR3 |= STM32_HRTIM1SW | STM32_TIM8SW | STM32_TIM1SW; | ||
223 | #endif /* !STM32_NO_INIT */ | ||
224 | } | ||
225 | |||
226 | /** @} */ | ||