diff options
Diffstat (limited to 'lib/chibios/os/hal/ports/STM32/STM32L0xx/hal_lld.c')
-rw-r--r-- | lib/chibios/os/hal/ports/STM32/STM32L0xx/hal_lld.c | 261 |
1 files changed, 261 insertions, 0 deletions
diff --git a/lib/chibios/os/hal/ports/STM32/STM32L0xx/hal_lld.c b/lib/chibios/os/hal/ports/STM32/STM32L0xx/hal_lld.c new file mode 100644 index 000000000..a1b72ad6b --- /dev/null +++ b/lib/chibios/os/hal/ports/STM32/STM32L0xx/hal_lld.c | |||
@@ -0,0 +1,261 @@ | |||
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 STM32L0xx/hal_lld.c | ||
19 | * @brief STM32L0xx 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_stm32l0xx.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 | */ | ||
52 | static void hal_lld_backup_domain_init(void) { | ||
53 | |||
54 | /* Backup domain access enabled and left open.*/ | ||
55 | PWR->CR |= PWR_CR_DBP; | ||
56 | |||
57 | /* Reset BKP domain if different clock source selected.*/ | ||
58 | if ((RCC->CSR & STM32_RTCSEL_MASK) != STM32_RTCSEL) { | ||
59 | /* Backup domain reset.*/ | ||
60 | RCC->CSR |= RCC_CSR_RTCRST; | ||
61 | RCC->CSR &= ~RCC_CSR_RTCRST; | ||
62 | } | ||
63 | |||
64 | /* If enabled then the LSE is started.*/ | ||
65 | #if STM32_LSE_ENABLED | ||
66 | RCC->CSR |= RCC_CSR_LSEON; | ||
67 | while ((RCC->CSR & RCC_CSR_LSERDY) == 0) | ||
68 | ; /* Waits until LSE is stable. */ | ||
69 | #endif | ||
70 | |||
71 | #if STM32_RTCSEL != STM32_RTCSEL_NOCLOCK | ||
72 | /* If the backup domain hasn't been initialized yet then proceed with | ||
73 | initialization.*/ | ||
74 | if ((RCC->CSR & RCC_CSR_RTCEN) == 0) { | ||
75 | /* Selects clock source.*/ | ||
76 | RCC->CSR |= STM32_RTCSEL; | ||
77 | |||
78 | /* RTC clock enabled.*/ | ||
79 | RCC->CSR |= RCC_CSR_RTCEN; | ||
80 | } | ||
81 | #endif /* STM32_RTCSEL != STM32_RTCSEL_NOCLOCK */ | ||
82 | } | ||
83 | |||
84 | /*===========================================================================*/ | ||
85 | /* Driver interrupt handlers. */ | ||
86 | /*===========================================================================*/ | ||
87 | |||
88 | /*===========================================================================*/ | ||
89 | /* Driver exported functions. */ | ||
90 | /*===========================================================================*/ | ||
91 | |||
92 | /** | ||
93 | * @brief Low level HAL driver initialization. | ||
94 | * | ||
95 | * @notapi | ||
96 | */ | ||
97 | void hal_lld_init(void) { | ||
98 | |||
99 | /* Reset of all peripherals except those on IOP.*/ | ||
100 | rccResetAHB(~RCC_AHBRSTR_MIFRST); | ||
101 | rccResetAPB1(~RCC_APB1RSTR_PWRRST); | ||
102 | rccResetAPB2(~0); | ||
103 | |||
104 | /* PWR clock enabled.*/ | ||
105 | rccEnablePWRInterface(true); | ||
106 | |||
107 | /* Initializes the backup domain.*/ | ||
108 | hal_lld_backup_domain_init(); | ||
109 | |||
110 | /* DMA subsystems initialization.*/ | ||
111 | #if defined(STM32_DMA_REQUIRED) | ||
112 | dmaInit(); | ||
113 | #endif | ||
114 | |||
115 | /* IRQ subsystem initialization.*/ | ||
116 | irqInit(); | ||
117 | |||
118 | /* Programmable voltage detector enable.*/ | ||
119 | #if STM32_PVD_ENABLE | ||
120 | PWR->CR |= PWR_CR_PVDE | (STM32_PLS & STM32_PLS_MASK); | ||
121 | #endif /* STM32_PVD_ENABLE */ | ||
122 | } | ||
123 | |||
124 | /** | ||
125 | * @brief STM32L0xx voltage, clocks and PLL initialization. | ||
126 | * @note All the involved constants come from the file @p board.h. | ||
127 | * @note This function should be invoked just after the system reset. | ||
128 | * | ||
129 | * @special | ||
130 | */ | ||
131 | /** | ||
132 | * @brief Clocks and internal voltage initialization. | ||
133 | */ | ||
134 | void stm32_clock_init(void) { | ||
135 | |||
136 | #if !STM32_NO_INIT | ||
137 | /* PWR clock enable.*/ | ||
138 | RCC->APB1ENR = RCC_APB1ENR_PWREN; | ||
139 | |||
140 | /* Core voltage setup.*/ | ||
141 | while ((PWR->CSR & PWR_CSR_VOSF) != 0) | ||
142 | ; /* Waits until regulator is stable. */ | ||
143 | PWR->CR = STM32_VOS; | ||
144 | while ((PWR->CSR & PWR_CSR_VOSF) != 0) | ||
145 | ; /* Waits until regulator is stable. */ | ||
146 | |||
147 | /* Initial clocks setup and wait for MSI stabilization, the MSI clock is | ||
148 | always enabled because it is the fallback clock when PLL the fails. | ||
149 | Trim fields are not altered from reset values.*/ | ||
150 | RCC->CFGR = 0; | ||
151 | RCC->ICSCR = (RCC->ICSCR & ~STM32_MSIRANGE_MASK) | STM32_MSIRANGE; | ||
152 | RCC->CR = RCC_CR_MSION; | ||
153 | while ((RCC->CR & RCC_CR_MSIRDY) == 0) | ||
154 | ; /* Waits until MSI is stable. */ | ||
155 | |||
156 | #if STM32_HSI16_ENABLED | ||
157 | /* HSI activation.*/ | ||
158 | RCC->CR |= RCC_CR_HSION; | ||
159 | while ((RCC->CR & RCC_CR_HSIRDY) == 0) | ||
160 | ; /* Waits until HSI16 is stable. */ | ||
161 | |||
162 | #if STM32_HSI16_DIVIDER_ENABLED | ||
163 | RCC->CR |= RCC_CR_HSIDIVEN; | ||
164 | while ((RCC->CR & RCC_CR_HSIDIVF) == 0) | ||
165 | ; | ||
166 | #endif | ||
167 | #endif | ||
168 | |||
169 | #if STM32_HSE_ENABLED | ||
170 | #if defined(STM32_HSE_BYPASS) | ||
171 | /* HSE Bypass.*/ | ||
172 | RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP; | ||
173 | #endif | ||
174 | /* HSE activation.*/ | ||
175 | RCC->CR |= RCC_CR_HSEON; | ||
176 | while ((RCC->CR & RCC_CR_HSERDY) == 0) | ||
177 | ; /* Waits until HSE is stable. */ | ||
178 | #endif | ||
179 | |||
180 | #if STM32_LSI_ENABLED | ||
181 | /* LSI activation.*/ | ||
182 | RCC->CSR |= RCC_CSR_LSION; | ||
183 | while ((RCC->CSR & RCC_CSR_LSIRDY) == 0) | ||
184 | ; /* Waits until LSI is stable. */ | ||
185 | #endif | ||
186 | |||
187 | #if STM32_LSE_ENABLED | ||
188 | /* LSE activation, have to unlock the register.*/ | ||
189 | if ((RCC->CSR & RCC_CSR_LSEON) == 0) { | ||
190 | PWR->CR |= PWR_CR_DBP; | ||
191 | #if defined(STM32_LSE_BYPASS) | ||
192 | /* LSE Bypass.*/ | ||
193 | RCC->CSR |= STM32_LSEDRV | RCC_CSR_LSEBYP; | ||
194 | #else | ||
195 | /* No LSE Bypass.*/ | ||
196 | RCC->CSR |= STM32_LSEDRV; | ||
197 | #endif | ||
198 | RCC->CSR |= RCC_CSR_LSEON; | ||
199 | PWR->CR &= ~PWR_CR_DBP; | ||
200 | } | ||
201 | while ((RCC->CSR & RCC_CSR_LSERDY) == 0) | ||
202 | ; /* Waits until LSE is stable. */ | ||
203 | #endif | ||
204 | |||
205 | #if STM32_ACTIVATE_PLL | ||
206 | /* PLL activation.*/ | ||
207 | RCC->CFGR |= STM32_PLLDIV | STM32_PLLMUL | STM32_PLLSRC; | ||
208 | RCC->CR |= RCC_CR_PLLON; | ||
209 | while (!(RCC->CR & RCC_CR_PLLRDY)) | ||
210 | ; /* Waits until PLL is stable. */ | ||
211 | #endif | ||
212 | |||
213 | #if STM32_ACTIVATE_HSI48 | ||
214 | /* Enabling SYSCFG clock. */ | ||
215 | rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); | ||
216 | /* Configuring SYSCFG to enable VREFINT and HSI48 VREFINT buffer. */ | ||
217 | SYSCFG->CFGR3 = STM32_VREFINT_EN | SYSCFG_CFGR3_ENREF_HSI48; | ||
218 | |||
219 | while (!(SYSCFG->CFGR3 & SYSCFG_CFGR3_VREFINT_RDYF)) | ||
220 | ; /* Waits until VREFINT is stable. */ | ||
221 | /* Disabling SYSCFG clock. */ | ||
222 | rccDisableAPB2(RCC_APB2ENR_SYSCFGEN); | ||
223 | |||
224 | /* Enabling HSI48. */ | ||
225 | RCC->CRRCR |= RCC_CRRCR_HSI48ON; | ||
226 | while (!(RCC->CRRCR & RCC_CRRCR_HSI48RDY)) | ||
227 | ; /* Waits until HSI48 is stable. */ | ||
228 | #endif | ||
229 | |||
230 | /* Other clock-related settings (dividers, MCO etc).*/ | ||
231 | RCC->CR |= STM32_RTCPRE; | ||
232 | RCC->CFGR |= STM32_MCOPRE | STM32_MCOSEL | | ||
233 | STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE; | ||
234 | RCC->CSR |= STM32_RTCSEL; | ||
235 | |||
236 | /* Flash setup and final clock selection.*/ | ||
237 | #if defined(STM32_FLASHBITS) | ||
238 | FLASH->ACR = STM32_FLASHBITS; | ||
239 | while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) != | ||
240 | (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) { | ||
241 | } | ||
242 | #endif | ||
243 | |||
244 | /* Switching to the configured clock source if it is different from MSI. */ | ||
245 | #if (STM32_SW != STM32_SW_MSI) | ||
246 | RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */ | ||
247 | while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2)) | ||
248 | ; | ||
249 | #endif | ||
250 | |||
251 | /* Peripherals clock sources setup.*/ | ||
252 | RCC->CCIPR = STM32_HSI48SEL | STM32_LPTIM1SEL | STM32_I2C1SEL | | ||
253 | STM32_LPUART1SEL | STM32_USART2SEL | STM32_USART1SEL; | ||
254 | |||
255 | /* SYSCFG clock enabled here because it is a multi-functional unit shared | ||
256 | among multiple drivers.*/ | ||
257 | rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true); | ||
258 | #endif /* STM32_NO_INIT */ | ||
259 | } | ||
260 | |||
261 | /** @} */ | ||