aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios/os/hal/ports/STM32/STM32F37x/hal_lld.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios/os/hal/ports/STM32/STM32F37x/hal_lld.c')
-rw-r--r--lib/chibios/os/hal/ports/STM32/STM32F37x/hal_lld.c216
1 files changed, 216 insertions, 0 deletions
diff --git a/lib/chibios/os/hal/ports/STM32/STM32F37x/hal_lld.c b/lib/chibios/os/hal/ports/STM32/STM32F37x/hal_lld.c
new file mode 100644
index 000000000..725de2f6a
--- /dev/null
+++ b/lib/chibios/os/hal/ports/STM32/STM32F37x/hal_lld.c
@@ -0,0 +1,216 @@
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 STM32F37x/hal_lld.c
19 * @brief STM32F37x 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 */
39uint32_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 */
54static 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 */
105void 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
138/**
139 * @brief STM32 clocks and PLL initialization.
140 * @note All the involved constants come from the file @p board.h.
141 * @note This function should be invoked just after the system reset.
142 *
143 * @special
144 */
145void stm32_clock_init(void) {
146
147#if !STM32_NO_INIT
148 /* HSI setup, it enforces the reset situation in order to handle possible
149 problems with JTAG probes and re-initializations.*/
150 RCC->CR |= RCC_CR_HSION; /* Make sure HSI is ON. */
151 while (!(RCC->CR & RCC_CR_HSIRDY))
152 ; /* Wait until HSI is stable. */
153
154 /* HSI is selected as new source without touching the other fields in
155 CFGR. Clearing the register has to be postponed after HSI is the
156 new source.*/
157 RCC->CFGR &= ~RCC_CFGR_SW; /* Reset SW, selecting HSI. */
158 while ((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_HSI)
159 ; /* Wait until HSI is selected. */
160
161 /* Registers finally cleared to reset values.*/
162 RCC->CR &= RCC_CR_HSITRIM | RCC_CR_HSION; /* CR Reset value. */
163 RCC->CFGR = 0; /* CFGR reset value. */
164
165#if STM32_HSE_ENABLED
166 /* HSE activation.*/
167#if defined(STM32_HSE_BYPASS)
168 /* HSE Bypass.*/
169 RCC->CR |= RCC_CR_HSEON | RCC_CR_HSEBYP;
170#else
171 /* No HSE Bypass.*/
172 RCC->CR |= RCC_CR_HSEON;
173#endif
174 while (!(RCC->CR & RCC_CR_HSERDY))
175 ; /* Waits until HSE is stable. */
176#endif
177
178#if STM32_LSI_ENABLED
179 /* LSI activation.*/
180 RCC->CSR |= RCC_CSR_LSION;
181 while ((RCC->CSR & RCC_CSR_LSIRDY) == 0)
182 ; /* Waits until LSI is stable. */
183#endif
184
185 /* Clock settings.*/
186 RCC->CFGR = STM32_SDPRE | STM32_MCOSEL | STM32_USBPRE |
187 STM32_PLLMUL | STM32_PLLSRC | STM32_ADCPRE |
188 STM32_PPRE1 | STM32_PPRE2 | STM32_HPRE;
189 RCC->CFGR2 = STM32_PREDIV;
190 RCC->CFGR3 = STM32_USART3SW | STM32_USART2SW | STM32_I2C2SW |
191 STM32_I2C1SW | STM32_USART1SW;
192
193#if STM32_ACTIVATE_PLL
194 /* PLL activation.*/
195 RCC->CR |= RCC_CR_PLLON;
196 while (!(RCC->CR & RCC_CR_PLLRDY))
197 ; /* Waits until PLL is stable. */
198#endif
199
200 /* Flash setup and final clock selection. */
201 FLASH->ACR = STM32_FLASHBITS;
202 while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) !=
203 (STM32_FLASHBITS & FLASH_ACR_LATENCY_Msk)) {
204 }
205
206 /* Switching to the configured clock source if it is different from HSI.*/
207#if (STM32_SW != STM32_SW_HSI)
208 /* Switches clock source.*/
209 RCC->CFGR |= STM32_SW;
210 while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
211 ; /* Waits selection complete. */
212#endif
213#endif /* !STM32_NO_INIT */
214}
215
216/** @} */