0
|
1 /**
|
|
2 ******************************************************************************
|
|
3 * @file stm32l4xx_hal_rcc_ex.c
|
|
4 * @author MCD Application Team
|
|
5 * @version V1.6.0
|
|
6 * @date 28-October-2016
|
|
7 * @brief Extended RCC HAL module driver.
|
|
8 * This file provides firmware functions to manage the following
|
|
9 * functionalities RCC extended peripheral:
|
|
10 * + Extended Peripheral Control functions
|
|
11 * + Extended Clock management functions
|
|
12 * + Extended Clock Recovery System Control functions
|
|
13 *
|
|
14 ******************************************************************************
|
|
15 * @attention
|
|
16 *
|
|
17 * <h2><center>© COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
|
|
18 *
|
|
19 * Redistribution and use in source and binary forms, with or without modification,
|
|
20 * are permitted provided that the following conditions are met:
|
|
21 * 1. Redistributions of source code must retain the above copyright notice,
|
|
22 * this list of conditions and the following disclaimer.
|
|
23 * 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
24 * this list of conditions and the following disclaimer in the documentation
|
|
25 * and/or other materials provided with the distribution.
|
|
26 * 3. Neither the name of STMicroelectronics nor the names of its contributors
|
|
27 * may be used to endorse or promote products derived from this software
|
|
28 * without specific prior written permission.
|
|
29 *
|
|
30 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
31 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
33 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
34 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
35 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
36 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
37 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
38 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
40 *
|
|
41 ******************************************************************************
|
|
42 */
|
|
43
|
|
44 /* Includes ------------------------------------------------------------------*/
|
|
45 #include "stm32l4xx_hal.h"
|
|
46
|
|
47 /** @addtogroup STM32L4xx_HAL_Driver
|
|
48 * @{
|
|
49 */
|
|
50
|
|
51 /** @defgroup RCCEx RCCEx
|
|
52 * @brief RCC Extended HAL module driver
|
|
53 * @{
|
|
54 */
|
|
55
|
|
56 #ifdef HAL_RCC_MODULE_ENABLED
|
|
57
|
|
58 /* Private typedef -----------------------------------------------------------*/
|
|
59 /* Private defines -----------------------------------------------------------*/
|
|
60 /** @defgroup RCCEx_Private_Constants RCCEx Private Constants
|
|
61 * @{
|
|
62 */
|
|
63 #define PLLSAI1_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
|
|
64 #define PLLSAI2_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
|
|
65 #define PLL_TIMEOUT_VALUE ((uint32_t)2U) /* 2 ms (minimum Tick + 1) */
|
|
66
|
|
67 #define DIVIDER_P_UPDATE 0U
|
|
68 #define DIVIDER_Q_UPDATE 1U
|
|
69 #define DIVIDER_R_UPDATE 2U
|
|
70
|
|
71 #define __LSCO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
|
|
72 #define LSCO_GPIO_PORT GPIOA
|
|
73 #define LSCO_PIN GPIO_PIN_2
|
|
74 /**
|
|
75 * @}
|
|
76 */
|
|
77
|
|
78 /* Private macros ------------------------------------------------------------*/
|
|
79 /* Private variables ---------------------------------------------------------*/
|
|
80 /* Private function prototypes -----------------------------------------------*/
|
|
81 /** @defgroup RCCEx_Private_Functions RCCEx Private Functions
|
|
82 * @{
|
|
83 */
|
|
84 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *PllSai1, uint32_t Divider);
|
|
85
|
|
86 #if defined(RCC_PLLSAI2_SUPPORT)
|
|
87
|
|
88 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider);
|
|
89
|
|
90 #endif /* RCC_PLLSAI2_SUPPORT */
|
|
91
|
|
92 /**
|
|
93 * @}
|
|
94 */
|
|
95
|
|
96 /* Exported functions --------------------------------------------------------*/
|
|
97
|
|
98 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
|
|
99 * @{
|
|
100 */
|
|
101
|
|
102 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
|
|
103 * @brief Extended Peripheral Control functions
|
|
104 *
|
|
105 @verbatim
|
|
106 ===============================================================================
|
|
107 ##### Extended Peripheral Control functions #####
|
|
108 ===============================================================================
|
|
109 [..]
|
|
110 This subsection provides a set of functions allowing to control the RCC Clocks
|
|
111 frequencies.
|
|
112 [..]
|
|
113 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
|
|
114 select the RTC clock source; in this case the Backup domain will be reset in
|
|
115 order to modify the RTC Clock source, as consequence RTC registers (including
|
|
116 the backup registers) are set to their reset values.
|
|
117
|
|
118 @endverbatim
|
|
119 * @{
|
|
120 */
|
|
121 /**
|
|
122 * @brief Initialize the RCC extended peripherals clocks according to the specified
|
|
123 * parameters in the RCC_PeriphCLKInitTypeDef.
|
|
124 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
|
|
125 * contains a field PeriphClockSelection which can be a combination of the following values:
|
|
126 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
|
|
127 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
|
|
128 @if STM32L486xx
|
|
129 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM1)
|
|
130 @endif
|
|
131 @if STM32L462xx
|
|
132 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM1)
|
|
133 @endif
|
|
134 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
|
|
135 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock
|
|
136 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
|
|
137 @if STM32L462xx
|
|
138 * @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (only for devices with I2C4)
|
|
139 @endif
|
|
140 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
|
|
141 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
|
|
142 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
|
|
143 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock
|
|
144 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock
|
|
145 @if STM32L486xx
|
|
146 * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2)
|
|
147 @endif
|
|
148 * @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock
|
|
149 @if STM32L443xx
|
|
150 * @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
|
151 @endif
|
|
152 @if STM32L486xx
|
|
153 * @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
|
154 @endif
|
|
155 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
|
|
156 * @arg @ref RCC_PERIPHCLK_USART2 USART1 peripheral clock
|
|
157 * @arg @ref RCC_PERIPHCLK_USART3 USART1 peripheral clock
|
|
158 @if STM32L462xx
|
|
159 * @arg @ref RCC_PERIPHCLK_UART4 USART1 peripheral clock (only for devices with UART4)
|
|
160 @endif
|
|
161 @if STM32L486xx
|
|
162 * @arg @ref RCC_PERIPHCLK_UART4 USART1 peripheral clock (only for devices with UART4)
|
|
163 * @arg @ref RCC_PERIPHCLK_UART5 USART1 peripheral clock (only for devices with UART5)
|
|
164 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
|
165 @endif
|
|
166 *
|
|
167 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
|
|
168 * the RTC clock source: in this case the access to Backup domain is enabled.
|
|
169 *
|
|
170 * @retval HAL status
|
|
171 */
|
|
172 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
|
173 {
|
|
174 uint32_t tmpregister = 0;
|
|
175 uint32_t tickstart = 0U;
|
|
176 HAL_StatusTypeDef ret = HAL_OK; /* Intermediate status */
|
|
177 HAL_StatusTypeDef status = HAL_OK; /* Final status */
|
|
178
|
|
179 /* Check the parameters */
|
|
180 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
|
|
181
|
|
182 /*-------------------------- SAI1 clock source configuration ---------------------*/
|
|
183 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1))
|
|
184 {
|
|
185 /* Check the parameters */
|
|
186 assert_param(IS_RCC_SAI1CLK(PeriphClkInit->Sai1ClockSelection));
|
|
187
|
|
188 switch(PeriphClkInit->Sai1ClockSelection)
|
|
189 {
|
|
190 case RCC_SAI1CLKSOURCE_PLL: /* PLL is used as clock source for SAI1*/
|
|
191 /* Enable SAI Clock output generated form System PLL . */
|
|
192 #if defined(RCC_PLLSAI2_SUPPORT)
|
|
193 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
|
|
194 #else
|
|
195 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI2CLK);
|
|
196 #endif /* RCC_PLLSAI2_SUPPORT */
|
|
197 /* SAI1 clock source config set later after clock selection check */
|
|
198 break;
|
|
199
|
|
200 case RCC_SAI1CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI1*/
|
|
201 /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
|
|
202 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
|
|
203 /* SAI1 clock source config set later after clock selection check */
|
|
204 break;
|
|
205
|
|
206 #if defined(RCC_PLLSAI2_SUPPORT)
|
|
207
|
|
208 case RCC_SAI1CLKSOURCE_PLLSAI2: /* PLLSAI2 is used as clock source for SAI1*/
|
|
209 /* PLLSAI2 input clock, parameters M, N & P configuration clock output (PLLSAI2ClockOut) */
|
|
210 ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
|
|
211 /* SAI1 clock source config set later after clock selection check */
|
|
212 break;
|
|
213
|
|
214 #endif /* RCC_PLLSAI2_SUPPORT */
|
|
215
|
|
216 case RCC_SAI1CLKSOURCE_PIN: /* External clock is used as source of SAI1 clock*/
|
|
217 /* SAI1 clock source config set later after clock selection check */
|
|
218 break;
|
|
219
|
|
220 default:
|
|
221 ret = HAL_ERROR;
|
|
222 break;
|
|
223 }
|
|
224
|
|
225 if(ret == HAL_OK)
|
|
226 {
|
|
227 /* Set the source of SAI1 clock*/
|
|
228 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection);
|
|
229 }
|
|
230 else
|
|
231 {
|
|
232 /* set overall return value */
|
|
233 status = ret;
|
|
234 }
|
|
235 }
|
|
236
|
|
237 #if defined(SAI2)
|
|
238
|
|
239 /*-------------------------- SAI2 clock source configuration ---------------------*/
|
|
240 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2))
|
|
241 {
|
|
242 /* Check the parameters */
|
|
243 assert_param(IS_RCC_SAI2CLK(PeriphClkInit->Sai2ClockSelection));
|
|
244
|
|
245 switch(PeriphClkInit->Sai2ClockSelection)
|
|
246 {
|
|
247 case RCC_SAI2CLKSOURCE_PLL: /* PLL is used as clock source for SAI2*/
|
|
248 /* Enable SAI Clock output generated form System PLL . */
|
|
249 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_SAI3CLK);
|
|
250 /* SAI2 clock source config set later after clock selection check */
|
|
251 break;
|
|
252
|
|
253 case RCC_SAI2CLKSOURCE_PLLSAI1: /* PLLSAI1 is used as clock source for SAI2*/
|
|
254 /* PLLSAI1 input clock, parameters M, N & P configuration and clock output (PLLSAI1ClockOut) */
|
|
255 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_P_UPDATE);
|
|
256 /* SAI2 clock source config set later after clock selection check */
|
|
257 break;
|
|
258
|
|
259 case RCC_SAI2CLKSOURCE_PLLSAI2: /* PLLSAI2 is used as clock source for SAI2*/
|
|
260 /* PLLSAI2 input clock, parameters M, N & P configuration and clock output (PLLSAI2ClockOut) */
|
|
261 ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_P_UPDATE);
|
|
262 /* SAI2 clock source config set later after clock selection check */
|
|
263 break;
|
|
264
|
|
265 case RCC_SAI2CLKSOURCE_PIN: /* External clock is used as source of SAI2 clock*/
|
|
266 /* SAI2 clock source config set later after clock selection check */
|
|
267 break;
|
|
268
|
|
269 default:
|
|
270 ret = HAL_ERROR;
|
|
271 break;
|
|
272 }
|
|
273
|
|
274 if(ret == HAL_OK)
|
|
275 {
|
|
276 /* Set the source of SAI2 clock*/
|
|
277 __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection);
|
|
278 }
|
|
279 else
|
|
280 {
|
|
281 /* set overall return value */
|
|
282 status = ret;
|
|
283 }
|
|
284 }
|
|
285 #endif /* SAI2 */
|
|
286
|
|
287 /*-------------------------- RTC clock source configuration ----------------------*/
|
|
288 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_RTC) == RCC_PERIPHCLK_RTC)
|
|
289 {
|
|
290 FlagStatus pwrclkchanged = RESET;
|
|
291
|
|
292 /* Check for RTC Parameters used to output RTCCLK */
|
|
293 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection));
|
|
294
|
|
295 /* Enable Power Clock */
|
|
296 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
|
|
297 {
|
|
298 __HAL_RCC_PWR_CLK_ENABLE();
|
|
299 pwrclkchanged = SET;
|
|
300 }
|
|
301
|
|
302 /* Enable write access to Backup domain */
|
|
303 SET_BIT(PWR->CR1, PWR_CR1_DBP);
|
|
304
|
|
305 /* Wait for Backup domain Write protection disable */
|
|
306 tickstart = HAL_GetTick();
|
|
307
|
|
308 while((PWR->CR1 & PWR_CR1_DBP) == RESET)
|
|
309 {
|
|
310 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
|
|
311 {
|
|
312 ret = HAL_TIMEOUT;
|
|
313 break;
|
|
314 }
|
|
315 }
|
|
316
|
|
317 if(ret == HAL_OK)
|
|
318 {
|
|
319 /* Reset the Backup domain only if the RTC Clock source selection is modified from default */
|
|
320 tmpregister = READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL);
|
|
321
|
|
322 if((tmpregister != RCC_RTCCLKSOURCE_NO_CLK) && (tmpregister != PeriphClkInit->RTCClockSelection))
|
|
323 {
|
|
324 /* Store the content of BDCR register before the reset of Backup Domain */
|
|
325 tmpregister = READ_BIT(RCC->BDCR, ~(RCC_BDCR_RTCSEL));
|
|
326 /* RTC Clock selection can be changed only if the Backup Domain is reset */
|
|
327 __HAL_RCC_BACKUPRESET_FORCE();
|
|
328 __HAL_RCC_BACKUPRESET_RELEASE();
|
|
329 /* Restore the Content of BDCR register */
|
|
330 RCC->BDCR = tmpregister;
|
|
331 }
|
|
332
|
|
333 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */
|
|
334 if (HAL_IS_BIT_SET(tmpregister, RCC_BDCR_LSEON))
|
|
335 {
|
|
336 /* Get Start Tick*/
|
|
337 tickstart = HAL_GetTick();
|
|
338
|
|
339 /* Wait till LSE is ready */
|
|
340 while(READ_BIT(RCC->BDCR, RCC_BDCR_LSERDY) == RESET)
|
|
341 {
|
|
342 if((HAL_GetTick() - tickstart) > RCC_LSE_TIMEOUT_VALUE)
|
|
343 {
|
|
344 ret = HAL_TIMEOUT;
|
|
345 break;
|
|
346 }
|
|
347 }
|
|
348 }
|
|
349
|
|
350 if(ret == HAL_OK)
|
|
351 {
|
|
352 /* Apply new RTC clock source selection */
|
|
353 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
|
|
354 }
|
|
355 else
|
|
356 {
|
|
357 /* set overall return value */
|
|
358 status = ret;
|
|
359 }
|
|
360 }
|
|
361 else
|
|
362 {
|
|
363 /* set overall return value */
|
|
364 status = ret;
|
|
365 }
|
|
366
|
|
367 /* Restore clock configuration if changed */
|
|
368 if(pwrclkchanged == SET)
|
|
369 {
|
|
370 __HAL_RCC_PWR_CLK_DISABLE();
|
|
371 }
|
|
372 }
|
|
373
|
|
374 /*-------------------------- USART1 clock source configuration -------------------*/
|
|
375 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART1) == RCC_PERIPHCLK_USART1)
|
|
376 {
|
|
377 /* Check the parameters */
|
|
378 assert_param(IS_RCC_USART1CLKSOURCE(PeriphClkInit->Usart1ClockSelection));
|
|
379
|
|
380 /* Configure the USART1 clock source */
|
|
381 __HAL_RCC_USART1_CONFIG(PeriphClkInit->Usart1ClockSelection);
|
|
382 }
|
|
383
|
|
384 /*-------------------------- USART2 clock source configuration -------------------*/
|
|
385 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART2) == RCC_PERIPHCLK_USART2)
|
|
386 {
|
|
387 /* Check the parameters */
|
|
388 assert_param(IS_RCC_USART2CLKSOURCE(PeriphClkInit->Usart2ClockSelection));
|
|
389
|
|
390 /* Configure the USART2 clock source */
|
|
391 __HAL_RCC_USART2_CONFIG(PeriphClkInit->Usart2ClockSelection);
|
|
392 }
|
|
393
|
|
394 #if defined(USART3)
|
|
395
|
|
396 /*-------------------------- USART3 clock source configuration -------------------*/
|
|
397 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USART3) == RCC_PERIPHCLK_USART3)
|
|
398 {
|
|
399 /* Check the parameters */
|
|
400 assert_param(IS_RCC_USART3CLKSOURCE(PeriphClkInit->Usart3ClockSelection));
|
|
401
|
|
402 /* Configure the USART3 clock source */
|
|
403 __HAL_RCC_USART3_CONFIG(PeriphClkInit->Usart3ClockSelection);
|
|
404 }
|
|
405
|
|
406 #endif /* USART3 */
|
|
407
|
|
408 #if defined(UART4)
|
|
409
|
|
410 /*-------------------------- UART4 clock source configuration --------------------*/
|
|
411 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART4) == RCC_PERIPHCLK_UART4)
|
|
412 {
|
|
413 /* Check the parameters */
|
|
414 assert_param(IS_RCC_UART4CLKSOURCE(PeriphClkInit->Uart4ClockSelection));
|
|
415
|
|
416 /* Configure the UART4 clock source */
|
|
417 __HAL_RCC_UART4_CONFIG(PeriphClkInit->Uart4ClockSelection);
|
|
418 }
|
|
419
|
|
420 #endif /* UART4 */
|
|
421
|
|
422 #if defined(UART5)
|
|
423
|
|
424 /*-------------------------- UART5 clock source configuration --------------------*/
|
|
425 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_UART5) == RCC_PERIPHCLK_UART5)
|
|
426 {
|
|
427 /* Check the parameters */
|
|
428 assert_param(IS_RCC_UART5CLKSOURCE(PeriphClkInit->Uart5ClockSelection));
|
|
429
|
|
430 /* Configure the UART5 clock source */
|
|
431 __HAL_RCC_UART5_CONFIG(PeriphClkInit->Uart5ClockSelection);
|
|
432 }
|
|
433
|
|
434 #endif /* UART5 */
|
|
435
|
|
436 /*-------------------------- LPUART1 clock source configuration ------------------*/
|
|
437 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPUART1) == RCC_PERIPHCLK_LPUART1)
|
|
438 {
|
|
439 /* Check the parameters */
|
|
440 assert_param(IS_RCC_LPUART1CLKSOURCE(PeriphClkInit->Lpuart1ClockSelection));
|
|
441
|
|
442 /* Configure the LPUAR1 clock source */
|
|
443 __HAL_RCC_LPUART1_CONFIG(PeriphClkInit->Lpuart1ClockSelection);
|
|
444 }
|
|
445
|
|
446 /*-------------------------- LPTIM1 clock source configuration -------------------*/
|
|
447 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == (RCC_PERIPHCLK_LPTIM1))
|
|
448 {
|
|
449 assert_param(IS_RCC_LPTIM1CLK(PeriphClkInit->Lptim1ClockSelection));
|
|
450 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection);
|
|
451 }
|
|
452
|
|
453 /*-------------------------- LPTIM2 clock source configuration -------------------*/
|
|
454 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM2) == (RCC_PERIPHCLK_LPTIM2))
|
|
455 {
|
|
456 assert_param(IS_RCC_LPTIM2CLK(PeriphClkInit->Lptim2ClockSelection));
|
|
457 __HAL_RCC_LPTIM2_CONFIG(PeriphClkInit->Lptim2ClockSelection);
|
|
458 }
|
|
459
|
|
460 /*-------------------------- I2C1 clock source configuration ---------------------*/
|
|
461 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C1) == RCC_PERIPHCLK_I2C1)
|
|
462 {
|
|
463 /* Check the parameters */
|
|
464 assert_param(IS_RCC_I2C1CLKSOURCE(PeriphClkInit->I2c1ClockSelection));
|
|
465
|
|
466 /* Configure the I2C1 clock source */
|
|
467 __HAL_RCC_I2C1_CONFIG(PeriphClkInit->I2c1ClockSelection);
|
|
468 }
|
|
469
|
|
470 #if defined(I2C2)
|
|
471
|
|
472 /*-------------------------- I2C2 clock source configuration ---------------------*/
|
|
473 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C2) == RCC_PERIPHCLK_I2C2)
|
|
474 {
|
|
475 /* Check the parameters */
|
|
476 assert_param(IS_RCC_I2C2CLKSOURCE(PeriphClkInit->I2c2ClockSelection));
|
|
477
|
|
478 /* Configure the I2C2 clock source */
|
|
479 __HAL_RCC_I2C2_CONFIG(PeriphClkInit->I2c2ClockSelection);
|
|
480 }
|
|
481
|
|
482 #endif /* I2C2 */
|
|
483
|
|
484 /*-------------------------- I2C3 clock source configuration ---------------------*/
|
|
485 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C3) == RCC_PERIPHCLK_I2C3)
|
|
486 {
|
|
487 /* Check the parameters */
|
|
488 assert_param(IS_RCC_I2C3CLKSOURCE(PeriphClkInit->I2c3ClockSelection));
|
|
489
|
|
490 /* Configure the I2C3 clock source */
|
|
491 __HAL_RCC_I2C3_CONFIG(PeriphClkInit->I2c3ClockSelection);
|
|
492 }
|
|
493
|
|
494 #if defined(I2C4)
|
|
495
|
|
496 /*-------------------------- I2C4 clock source configuration ---------------------*/
|
|
497 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2C4) == RCC_PERIPHCLK_I2C4)
|
|
498 {
|
|
499 /* Check the parameters */
|
|
500 assert_param(IS_RCC_I2C4CLKSOURCE(PeriphClkInit->I2c4ClockSelection));
|
|
501
|
|
502 /* Configure the I2C4 clock source */
|
|
503 __HAL_RCC_I2C4_CONFIG(PeriphClkInit->I2c4ClockSelection);
|
|
504 }
|
|
505
|
|
506 #endif /* I2C4 */
|
|
507
|
|
508 #if defined(USB_OTG_FS) || defined(USB)
|
|
509
|
|
510 /*-------------------------- USB clock source configuration ----------------------*/
|
|
511 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_USB) == (RCC_PERIPHCLK_USB))
|
|
512 {
|
|
513 assert_param(IS_RCC_USBCLKSOURCE(PeriphClkInit->UsbClockSelection));
|
|
514 __HAL_RCC_USB_CONFIG(PeriphClkInit->UsbClockSelection);
|
|
515
|
|
516 if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLL)
|
|
517 {
|
|
518 /* Enable PLL48M1CLK output */
|
|
519 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
|
|
520 }
|
|
521 else
|
|
522 {
|
|
523 if(PeriphClkInit->UsbClockSelection == RCC_USBCLKSOURCE_PLLSAI1)
|
|
524 {
|
|
525 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
|
|
526 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
|
|
527
|
|
528 if(ret != HAL_OK)
|
|
529 {
|
|
530 /* set overall return value */
|
|
531 status = ret;
|
|
532 }
|
|
533 }
|
|
534 }
|
|
535 }
|
|
536
|
|
537 #endif /* USB_OTG_FS || USB */
|
|
538
|
|
539 #if defined(SDMMC1)
|
|
540
|
|
541 /*-------------------------- SDMMC1 clock source configuration -------------------*/
|
|
542 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDMMC1) == (RCC_PERIPHCLK_SDMMC1))
|
|
543 {
|
|
544 assert_param(IS_RCC_SDMMC1CLKSOURCE(PeriphClkInit->Sdmmc1ClockSelection));
|
|
545 __HAL_RCC_SDMMC1_CONFIG(PeriphClkInit->Sdmmc1ClockSelection);
|
|
546
|
|
547 if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLL)
|
|
548 {
|
|
549 /* Enable PLL48M1CLK output */
|
|
550 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
|
|
551 }
|
|
552 else if(PeriphClkInit->Sdmmc1ClockSelection == RCC_SDMMC1CLKSOURCE_PLLSAI1)
|
|
553 {
|
|
554 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
|
|
555 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
|
|
556
|
|
557 if(ret != HAL_OK)
|
|
558 {
|
|
559 /* set overall return value */
|
|
560 status = ret;
|
|
561 }
|
|
562 }
|
|
563 }
|
|
564
|
|
565 #endif /* SDMMC1 */
|
|
566
|
|
567 /*-------------------------- RNG clock source configuration ----------------------*/
|
|
568 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RNG) == (RCC_PERIPHCLK_RNG))
|
|
569 {
|
|
570 assert_param(IS_RCC_RNGCLKSOURCE(PeriphClkInit->RngClockSelection));
|
|
571 __HAL_RCC_RNG_CONFIG(PeriphClkInit->RngClockSelection);
|
|
572
|
|
573 if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLL)
|
|
574 {
|
|
575 /* Enable PLL48M1CLK output */
|
|
576 __HAL_RCC_PLLCLKOUT_ENABLE(RCC_PLL_48M1CLK);
|
|
577 }
|
|
578 else if(PeriphClkInit->RngClockSelection == RCC_RNGCLKSOURCE_PLLSAI1)
|
|
579 {
|
|
580 /* PLLSAI1 input clock, parameters M, N & Q configuration and clock output (PLLSAI1ClockOut) */
|
|
581 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_Q_UPDATE);
|
|
582
|
|
583 if(ret != HAL_OK)
|
|
584 {
|
|
585 /* set overall return value */
|
|
586 status = ret;
|
|
587 }
|
|
588 }
|
|
589 }
|
|
590
|
|
591 /*-------------------------- ADC clock source configuration ----------------------*/
|
|
592 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_ADC) == RCC_PERIPHCLK_ADC)
|
|
593 {
|
|
594 /* Check the parameters */
|
|
595 assert_param(IS_RCC_ADCCLKSOURCE(PeriphClkInit->AdcClockSelection));
|
|
596
|
|
597 /* Configure the ADC interface clock source */
|
|
598 __HAL_RCC_ADC_CONFIG(PeriphClkInit->AdcClockSelection);
|
|
599
|
|
600 if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI1)
|
|
601 {
|
|
602 /* PLLSAI1 input clock, parameters M, N & R configuration and clock output (PLLSAI1ClockOut) */
|
|
603 ret = RCCEx_PLLSAI1_Config(&(PeriphClkInit->PLLSAI1), DIVIDER_R_UPDATE);
|
|
604
|
|
605 if(ret != HAL_OK)
|
|
606 {
|
|
607 /* set overall return value */
|
|
608 status = ret;
|
|
609 }
|
|
610 }
|
|
611
|
|
612 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
|
|
613
|
|
614 else if(PeriphClkInit->AdcClockSelection == RCC_ADCCLKSOURCE_PLLSAI2)
|
|
615 {
|
|
616 /* PLLSAI2 input clock, parameters M, N & R configuration and clock output (PLLSAI2ClockOut) */
|
|
617 ret = RCCEx_PLLSAI2_Config(&(PeriphClkInit->PLLSAI2), DIVIDER_R_UPDATE);
|
|
618
|
|
619 if(ret != HAL_OK)
|
|
620 {
|
|
621 /* set overall return value */
|
|
622 status = ret;
|
|
623 }
|
|
624 }
|
|
625
|
|
626 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */
|
|
627
|
|
628 }
|
|
629
|
|
630 #if defined(SWPMI1)
|
|
631
|
|
632 /*-------------------------- SWPMI1 clock source configuration -------------------*/
|
|
633 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SWPMI1) == RCC_PERIPHCLK_SWPMI1)
|
|
634 {
|
|
635 /* Check the parameters */
|
|
636 assert_param(IS_RCC_SWPMI1CLKSOURCE(PeriphClkInit->Swpmi1ClockSelection));
|
|
637
|
|
638 /* Configure the SWPMI1 clock source */
|
|
639 __HAL_RCC_SWPMI1_CONFIG(PeriphClkInit->Swpmi1ClockSelection);
|
|
640 }
|
|
641
|
|
642 #endif /* SWPMI1 */
|
|
643
|
|
644 #if defined(DFSDM1_Filter0)
|
|
645
|
|
646 /*-------------------------- DFSDM1 clock source configuration -------------------*/
|
|
647 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1)
|
|
648 {
|
|
649 /* Check the parameters */
|
|
650 assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection));
|
|
651
|
|
652 /* Configure the DFSDM1 interface clock source */
|
|
653 __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection);
|
|
654 }
|
|
655
|
|
656 #endif /* DFSDM1_Filter0 */
|
|
657
|
|
658 return status;
|
|
659 }
|
|
660
|
|
661 /**
|
|
662 * @brief Get the RCC_ClkInitStruct according to the internal RCC configuration registers.
|
|
663 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that
|
|
664 * returns the configuration information for the Extended Peripherals
|
|
665 * clocks(SAI1, SAI2, LPTIM1, LPTIM2, I2C1, I2C2, I2C3, I2C4, LPUART,
|
|
666 * USART1, USART2, USART3, UART4, UART5, RTC, ADCx, DFSDMx, SWPMI1, USB, SDMMC1 and RNG).
|
|
667 * @retval None
|
|
668 */
|
|
669 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
|
670 {
|
|
671 /* Set all possible values for the extended clock type parameter------------*/
|
|
672
|
|
673 #if defined(STM32L431xx)
|
|
674
|
|
675 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \
|
|
676 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
|
677 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | \
|
|
678 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \
|
|
679 RCC_PERIPHCLK_RTC ;
|
|
680
|
|
681 #elif defined(STM32L432xx) || defined(STM32L442xx)
|
|
682
|
|
683 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | \
|
|
684 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C3 | \
|
|
685 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_USB | \
|
|
686 RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \
|
|
687 RCC_PERIPHCLK_RTC ;
|
|
688
|
|
689 #elif defined(STM32L433xx) || defined(STM32L443xx)
|
|
690
|
|
691 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | \
|
|
692 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
|
693 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_USB | \
|
|
694 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | \
|
|
695 RCC_PERIPHCLK_RTC ;
|
|
696
|
|
697 #elif defined(STM32L451xx)
|
|
698
|
|
699 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | \
|
|
700 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
|
|
701 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | \
|
|
702 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_DFSDM1 | \
|
|
703 RCC_PERIPHCLK_RTC ;
|
|
704
|
|
705 #elif defined(STM32L452xx) || defined(STM32L462xx)
|
|
706
|
|
707 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | \
|
|
708 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | RCC_PERIPHCLK_I2C4 | \
|
|
709 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_USB | \
|
|
710 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_DFSDM1 | \
|
|
711 RCC_PERIPHCLK_RTC ;
|
|
712
|
|
713 #elif defined(STM32L471xx)
|
|
714
|
|
715 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
|
|
716 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
|
717 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | \
|
|
718 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \
|
|
719 RCC_PERIPHCLK_RTC ;
|
|
720
|
|
721 #elif defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
|
|
722
|
|
723 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_USART1 | RCC_PERIPHCLK_USART2 | RCC_PERIPHCLK_USART3 | RCC_PERIPHCLK_UART4 | RCC_PERIPHCLK_UART5 | \
|
|
724 RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2 | RCC_PERIPHCLK_I2C3 | \
|
|
725 RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_LPTIM2 | RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 | RCC_PERIPHCLK_USB | \
|
|
726 RCC_PERIPHCLK_SDMMC1 | RCC_PERIPHCLK_RNG | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_SWPMI1 | RCC_PERIPHCLK_DFSDM1 | \
|
|
727 RCC_PERIPHCLK_RTC ;
|
|
728
|
|
729 #endif /* STM32L431xx */
|
|
730
|
|
731 /* Get the PLLSAI1 Clock configuration -----------------------------------------------*/
|
|
732
|
|
733 PeriphClkInit->PLLSAI1.PLLSAI1Source = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> POSITION_VAL(RCC_PLLCFGR_PLLSRC));
|
|
734 PeriphClkInit->PLLSAI1.PLLSAI1M = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U;
|
|
735 PeriphClkInit->PLLSAI1.PLLSAI1N = (uint32_t)((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N));
|
|
736 PeriphClkInit->PLLSAI1.PLLSAI1P = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1P) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1P)) << 4U) + 7U;
|
|
737 PeriphClkInit->PLLSAI1.PLLSAI1Q = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1Q) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q))+1U) * 2U;
|
|
738 PeriphClkInit->PLLSAI1.PLLSAI1R = (uint32_t)(((RCC->PLLSAI1CFGR & RCC_PLLSAI1CFGR_PLLSAI1R) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R))+1U) * 2U;
|
|
739
|
|
740 #if defined(RCC_PLLSAI2_SUPPORT)
|
|
741
|
|
742 /* Get the PLLSAI2 Clock configuration -----------------------------------------------*/
|
|
743
|
|
744 PeriphClkInit->PLLSAI2.PLLSAI2Source = PeriphClkInit->PLLSAI1.PLLSAI1Source;
|
|
745 PeriphClkInit->PLLSAI2.PLLSAI2M = PeriphClkInit->PLLSAI1.PLLSAI1M;
|
|
746 PeriphClkInit->PLLSAI2.PLLSAI2N = (uint32_t)((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N));
|
|
747 PeriphClkInit->PLLSAI2.PLLSAI2P = (uint32_t)(((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2P) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2P)) << 4U) + 7U;
|
|
748 PeriphClkInit->PLLSAI2.PLLSAI2R = (uint32_t)(((RCC->PLLSAI2CFGR & RCC_PLLSAI2CFGR_PLLSAI2R)>> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R))+1U) * 2U;
|
|
749
|
|
750 #endif /* RCC_PLLSAI2_SUPPORT */
|
|
751
|
|
752 /* Get the USART1 clock source ---------------------------------------------*/
|
|
753 PeriphClkInit->Usart1ClockSelection = __HAL_RCC_GET_USART1_SOURCE();
|
|
754 /* Get the USART2 clock source ---------------------------------------------*/
|
|
755 PeriphClkInit->Usart2ClockSelection = __HAL_RCC_GET_USART2_SOURCE();
|
|
756
|
|
757 #if defined(USART3)
|
|
758 /* Get the USART3 clock source ---------------------------------------------*/
|
|
759 PeriphClkInit->Usart3ClockSelection = __HAL_RCC_GET_USART3_SOURCE();
|
|
760 #endif /* USART3 */
|
|
761
|
|
762 #if defined(UART4)
|
|
763 /* Get the UART4 clock source ----------------------------------------------*/
|
|
764 PeriphClkInit->Uart4ClockSelection = __HAL_RCC_GET_UART4_SOURCE();
|
|
765 #endif /* UART4 */
|
|
766
|
|
767 #if defined(UART5)
|
|
768 /* Get the UART5 clock source ----------------------------------------------*/
|
|
769 PeriphClkInit->Uart5ClockSelection = __HAL_RCC_GET_UART5_SOURCE();
|
|
770 #endif /* UART5 */
|
|
771
|
|
772 /* Get the LPUART1 clock source --------------------------------------------*/
|
|
773 PeriphClkInit->Lpuart1ClockSelection = __HAL_RCC_GET_LPUART1_SOURCE();
|
|
774
|
|
775 /* Get the I2C1 clock source -----------------------------------------------*/
|
|
776 PeriphClkInit->I2c1ClockSelection = __HAL_RCC_GET_I2C1_SOURCE();
|
|
777
|
|
778 #if defined(I2C2)
|
|
779 /* Get the I2C2 clock source ----------------------------------------------*/
|
|
780 PeriphClkInit->I2c2ClockSelection = __HAL_RCC_GET_I2C2_SOURCE();
|
|
781 #endif /* I2C2 */
|
|
782
|
|
783 /* Get the I2C3 clock source -----------------------------------------------*/
|
|
784 PeriphClkInit->I2c3ClockSelection = __HAL_RCC_GET_I2C3_SOURCE();
|
|
785
|
|
786 #if defined(I2C4)
|
|
787 /* Get the I2C4 clock source -----------------------------------------------*/
|
|
788 PeriphClkInit->I2c4ClockSelection = __HAL_RCC_GET_I2C4_SOURCE();
|
|
789 #endif /* I2C4 */
|
|
790
|
|
791 /* Get the LPTIM1 clock source ---------------------------------------------*/
|
|
792 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE();
|
|
793
|
|
794 /* Get the LPTIM2 clock source ---------------------------------------------*/
|
|
795 PeriphClkInit->Lptim2ClockSelection = __HAL_RCC_GET_LPTIM2_SOURCE();
|
|
796
|
|
797 /* Get the SAI1 clock source -----------------------------------------------*/
|
|
798 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE();
|
|
799
|
|
800 #if defined(SAI2)
|
|
801 /* Get the SAI2 clock source -----------------------------------------------*/
|
|
802 PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE();
|
|
803 #endif /* SAI2 */
|
|
804
|
|
805 /* Get the RTC clock source ------------------------------------------------*/
|
|
806 PeriphClkInit->RTCClockSelection = __HAL_RCC_GET_RTC_SOURCE();
|
|
807
|
|
808 #if defined(USB_OTG_FS) || defined(USB)
|
|
809 /* Get the USB clock source ------------------------------------------------*/
|
|
810 PeriphClkInit->UsbClockSelection = __HAL_RCC_GET_USB_SOURCE();
|
|
811 #endif /* USB_OTG_FS || USB */
|
|
812
|
|
813 #if defined(SDMMC1)
|
|
814 /* Get the SDMMC1 clock source ---------------------------------------------*/
|
|
815 PeriphClkInit->Sdmmc1ClockSelection = __HAL_RCC_GET_SDMMC1_SOURCE();
|
|
816 #endif /* SDMMC1 */
|
|
817
|
|
818 /* Get the RNG clock source ------------------------------------------------*/
|
|
819 PeriphClkInit->RngClockSelection = __HAL_RCC_GET_RNG_SOURCE();
|
|
820
|
|
821 /* Get the ADC clock source ------------------------------------------------*/
|
|
822 PeriphClkInit->AdcClockSelection = __HAL_RCC_GET_ADC_SOURCE();
|
|
823
|
|
824 #if defined(SWPMI1)
|
|
825 /* Get the SWPMI1 clock source ---------------------------------------------*/
|
|
826 PeriphClkInit->Swpmi1ClockSelection = __HAL_RCC_GET_SWPMI1_SOURCE();
|
|
827 #endif /* SWPMI1 */
|
|
828
|
|
829 #if defined(DFSDM1_Filter0)
|
|
830 /* Get the DFSDM1 clock source ---------------------------------------------*/
|
|
831 PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE();
|
|
832 #endif /* DFSDM1_Filter0 */
|
|
833 }
|
|
834
|
|
835 /**
|
|
836 * @brief Return the peripheral clock frequency for peripherals with clock source from PLLSAIs
|
|
837 * @note Return 0 if peripheral clock identifier not managed by this API
|
|
838 * @param PeriphClk Peripheral clock identifier
|
|
839 * This parameter can be one of the following values:
|
|
840 * @arg @ref RCC_PERIPHCLK_RTC RTC peripheral clock
|
|
841 * @arg @ref RCC_PERIPHCLK_ADC ADC peripheral clock
|
|
842 @if STM32L486xx
|
|
843 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM)
|
|
844 @endif
|
|
845 @if STM32L462xx
|
|
846 * @arg @ref RCC_PERIPHCLK_DFSDM1 DFSDM1 peripheral clock (only for devices with DFSDM)
|
|
847 @endif
|
|
848 * @arg @ref RCC_PERIPHCLK_I2C1 I2C1 peripheral clock
|
|
849 * @arg @ref RCC_PERIPHCLK_I2C2 I2C2 peripheral clock
|
|
850 * @arg @ref RCC_PERIPHCLK_I2C3 I2C3 peripheral clock
|
|
851 @if STM32L462xx
|
|
852 * @arg @ref RCC_PERIPHCLK_I2C4 I2C4 peripheral clock (only for devices with I2C4)
|
|
853 @endif
|
|
854 * @arg @ref RCC_PERIPHCLK_LPTIM1 LPTIM1 peripheral clock
|
|
855 * @arg @ref RCC_PERIPHCLK_LPTIM2 LPTIM2 peripheral clock
|
|
856 * @arg @ref RCC_PERIPHCLK_LPUART1 LPUART1 peripheral clock
|
|
857 * @arg @ref RCC_PERIPHCLK_RNG RNG peripheral clock
|
|
858 * @arg @ref RCC_PERIPHCLK_SAI1 SAI1 peripheral clock
|
|
859 @if STM32L486xx
|
|
860 * @arg @ref RCC_PERIPHCLK_SAI2 SAI2 peripheral clock (only for devices with SAI2)
|
|
861 @endif
|
|
862 * @arg @ref RCC_PERIPHCLK_SDMMC1 SDMMC1 peripheral clock
|
|
863 @if STM32L443xx
|
|
864 * @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
|
865 @endif
|
|
866 @if STM32L486xx
|
|
867 * @arg @ref RCC_PERIPHCLK_SWPMI1 SWPMI1 peripheral clock (only for devices with SWPMI1)
|
|
868 @endif
|
|
869 * @arg @ref RCC_PERIPHCLK_USART1 USART1 peripheral clock
|
|
870 * @arg @ref RCC_PERIPHCLK_USART2 USART1 peripheral clock
|
|
871 * @arg @ref RCC_PERIPHCLK_USART3 USART1 peripheral clock
|
|
872 @if STM32L486xx
|
|
873 * @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock (only for devices with UART4)
|
|
874 * @arg @ref RCC_PERIPHCLK_UART5 UART5 peripheral clock (only for devices with UART5)
|
|
875 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
|
876 @endif
|
|
877 @if STM32L462xx
|
|
878 * @arg @ref RCC_PERIPHCLK_UART4 UART4 peripheral clock (only for devices with UART4)
|
|
879 * @arg @ref RCC_PERIPHCLK_USB USB peripheral clock (only for devices with USB)
|
|
880 @endif
|
|
881 * @retval Frequency in Hz
|
|
882 */
|
|
883 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk)
|
|
884 {
|
|
885 uint32_t frequency = 0U;
|
|
886 uint32_t srcclk = 0U;
|
|
887 uint32_t pllvco = 0U, plln = 0U, pllp = 0U;
|
|
888
|
|
889 /* Check the parameters */
|
|
890 assert_param(IS_RCC_PERIPHCLOCK(PeriphClk));
|
|
891
|
|
892 if(PeriphClk == RCC_PERIPHCLK_RTC)
|
|
893 {
|
|
894 /* Get the current RTC source */
|
|
895 srcclk = __HAL_RCC_GET_RTC_SOURCE();
|
|
896
|
|
897 /* Check if LSE is ready and if RTC clock selection is LSE */
|
|
898 if ((srcclk == RCC_RTCCLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
899 {
|
|
900 frequency = LSE_VALUE;
|
|
901 }
|
|
902 /* Check if LSI is ready and if RTC clock selection is LSI */
|
|
903 else if ((srcclk == RCC_RTCCLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
|
|
904 {
|
|
905 frequency = LSI_VALUE;
|
|
906 }
|
|
907 /* Check if HSE is ready and if RTC clock selection is HSI_DIV32*/
|
|
908 else if ((srcclk == RCC_RTCCLKSOURCE_HSE_DIV32) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY)))
|
|
909 {
|
|
910 frequency = HSE_VALUE / 32;
|
|
911 }
|
|
912 /* Clock not enabled for RTC*/
|
|
913 else
|
|
914 {
|
|
915 frequency = 0U;
|
|
916 }
|
|
917 }
|
|
918 else
|
|
919 {
|
|
920 /* Other external peripheral clock source than RTC */
|
|
921
|
|
922 /* Compute PLL clock input */
|
|
923 if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_MSI) /* MSI ? */
|
|
924 {
|
|
925 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
|
|
926 {
|
|
927 pllvco = (1U << ((__HAL_RCC_GET_MSI_RANGE() >> 4U) - 4U)) * 1000000U;
|
|
928 }
|
|
929 else
|
|
930 {
|
|
931 pllvco = 0U;
|
|
932 }
|
|
933 }
|
|
934 else if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSI) /* HSI ? */
|
|
935 {
|
|
936 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
|
937 {
|
|
938 pllvco = HSI_VALUE;
|
|
939 }
|
|
940 else
|
|
941 {
|
|
942 pllvco = 0U;
|
|
943 }
|
|
944 }
|
|
945 else if(__HAL_RCC_GET_PLL_OSCSOURCE() == RCC_PLLSOURCE_HSE) /* HSE ? */
|
|
946 {
|
|
947 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSERDY))
|
|
948 {
|
|
949 pllvco = HSE_VALUE;
|
|
950 }
|
|
951 else
|
|
952 {
|
|
953 pllvco = 0U;
|
|
954 }
|
|
955 }
|
|
956 else /* No source */
|
|
957 {
|
|
958 pllvco = 0U;
|
|
959 }
|
|
960
|
|
961 /* f(PLL Source) / PLLM */
|
|
962 pllvco = (pllvco / ((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U));
|
|
963
|
|
964 switch(PeriphClk)
|
|
965 {
|
|
966 #if defined(SAI2)
|
|
967
|
|
968 case RCC_PERIPHCLK_SAI1:
|
|
969 case RCC_PERIPHCLK_SAI2:
|
|
970
|
|
971 if(PeriphClk == RCC_PERIPHCLK_SAI1)
|
|
972 {
|
|
973 srcclk = __HAL_RCC_GET_SAI1_SOURCE();
|
|
974
|
|
975 if(srcclk == RCC_SAI1CLKSOURCE_PIN)
|
|
976 {
|
|
977 frequency = EXTERNAL_SAI1_CLOCK_VALUE;
|
|
978 }
|
|
979 /* Else, PLL clock output to check below */
|
|
980 }
|
|
981 else /* RCC_PERIPHCLK_SAI2 */
|
|
982 {
|
|
983 srcclk = __HAL_RCC_GET_SAI2_SOURCE();
|
|
984
|
|
985 if(srcclk == RCC_SAI2CLKSOURCE_PIN)
|
|
986 {
|
|
987 frequency = EXTERNAL_SAI2_CLOCK_VALUE;
|
|
988 }
|
|
989 /* Else, PLL clock output to check below */
|
|
990 }
|
|
991
|
|
992 #else
|
|
993
|
|
994 case RCC_PERIPHCLK_SAI1:
|
|
995
|
|
996 if(PeriphClk == RCC_PERIPHCLK_SAI1)
|
|
997 {
|
|
998 srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_SAI1SEL);
|
|
999
|
|
1000 if(srcclk == RCC_SAI1CLKSOURCE_PIN)
|
|
1001 {
|
|
1002 frequency = EXTERNAL_SAI1_CLOCK_VALUE;
|
|
1003 }
|
|
1004 /* Else, PLL clock output to check below */
|
|
1005 }
|
|
1006
|
|
1007 #endif /* SAI2 */
|
|
1008
|
|
1009 if(frequency == 0U)
|
|
1010 {
|
|
1011 #if defined(SAI2)
|
|
1012 if((srcclk == RCC_SAI1CLKSOURCE_PLL) || (srcclk == RCC_SAI2CLKSOURCE_PLL))
|
|
1013 {
|
|
1014 if(__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI3CLK) != RESET)
|
|
1015 {
|
|
1016 /* f(PLLSAI3CLK) = f(VCO input) * PLLN / PLLP */
|
|
1017 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN);
|
|
1018 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
|
|
1019 pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> POSITION_VAL(RCC_PLLCFGR_PLLPDIV);
|
|
1020 #endif
|
|
1021 if(pllp == 0U)
|
|
1022 {
|
|
1023 if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != RESET)
|
|
1024 {
|
|
1025 pllp = 17U;
|
|
1026 }
|
|
1027 else
|
|
1028 {
|
|
1029 pllp = 7U;
|
|
1030 }
|
|
1031 }
|
|
1032 frequency = (pllvco * plln) / pllp;
|
|
1033 }
|
|
1034 }
|
|
1035 else if(srcclk == 0U) /* RCC_SAI1CLKSOURCE_PLLSAI1 || RCC_SAI2CLKSOURCE_PLLSAI1 */
|
|
1036 {
|
|
1037 if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != RESET)
|
|
1038 {
|
|
1039 /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
|
|
1040 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N);
|
|
1041 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
|
|
1042 pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV);
|
|
1043 #endif
|
|
1044 if(pllp == 0U)
|
|
1045 {
|
|
1046 if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != RESET)
|
|
1047 {
|
|
1048 pllp = 17U;
|
|
1049 }
|
|
1050 else
|
|
1051 {
|
|
1052 pllp = 7U;
|
|
1053 }
|
|
1054 }
|
|
1055 frequency = (pllvco * plln) / pllp;
|
|
1056 }
|
|
1057 }
|
|
1058 #else
|
|
1059 if(srcclk == RCC_SAI1CLKSOURCE_PLL)
|
|
1060 {
|
|
1061 if(__HAL_RCC_GET_PLLCLKOUT_CONFIG(RCC_PLL_SAI2CLK) != RESET)
|
|
1062 {
|
|
1063 /* f(PLLSAI2CLK) = f(VCO input) * PLLN / PLLP */
|
|
1064 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN);
|
|
1065 #if defined(RCC_PLLP_DIV_2_31_SUPPORT)
|
|
1066 pllp = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLPDIV) >> POSITION_VAL(RCC_PLLCFGR_PLLPDIV);
|
|
1067 #endif
|
|
1068 if(pllp == 0U)
|
|
1069 {
|
|
1070 if(READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLP) != RESET)
|
|
1071 {
|
|
1072 pllp = 17U;
|
|
1073 }
|
|
1074 else
|
|
1075 {
|
|
1076 pllp = 7U;
|
|
1077 }
|
|
1078 }
|
|
1079
|
|
1080 frequency = (pllvco * plln) / pllp;
|
|
1081 }
|
|
1082 else if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
|
1083 {
|
|
1084 /* HSI automatically selected as clock source if PLLs not enabled */
|
|
1085 frequency = HSI_VALUE;
|
|
1086 }
|
|
1087 else
|
|
1088 {
|
|
1089 /* No clock source */
|
|
1090 frequency = 0U;
|
|
1091 }
|
|
1092 }
|
|
1093 else if(srcclk == RCC_SAI1CLKSOURCE_PLLSAI1)
|
|
1094 {
|
|
1095 if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_SAI1CLK) != RESET)
|
|
1096 {
|
|
1097 /* f(PLLSAI1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1P */
|
|
1098 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N);
|
|
1099 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
|
|
1100 pllp = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1PDIV) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV);
|
|
1101 #endif
|
|
1102 if(pllp == 0U)
|
|
1103 {
|
|
1104 if(READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1P) != RESET)
|
|
1105 {
|
|
1106 pllp = 17U;
|
|
1107 }
|
|
1108 else
|
|
1109 {
|
|
1110 pllp = 7U;
|
|
1111 }
|
|
1112 }
|
|
1113
|
|
1114 frequency = (pllvco * plln) / pllp;
|
|
1115 }
|
|
1116 else if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY))
|
|
1117 {
|
|
1118 /* HSI automatically selected as clock source if PLLs not enabled */
|
|
1119 frequency = HSI_VALUE;
|
|
1120 }
|
|
1121 else
|
|
1122 {
|
|
1123 /* No clock source */
|
|
1124 frequency = 0U;
|
|
1125 }
|
|
1126 }
|
|
1127 #endif /* SAI2 */
|
|
1128
|
|
1129 #if defined(RCC_PLLSAI2_SUPPORT)
|
|
1130
|
|
1131 else if((srcclk == RCC_SAI1CLKSOURCE_PLLSAI2) || (srcclk == RCC_SAI2CLKSOURCE_PLLSAI2))
|
|
1132 {
|
|
1133 if(__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_SAI2CLK) != RESET)
|
|
1134 {
|
|
1135 /* f(PLLSAI2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2P */
|
|
1136 plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N);
|
|
1137 if(pllp == 0U)
|
|
1138 {
|
|
1139 if(READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2P) != RESET)
|
|
1140 {
|
|
1141 pllp = 17U;
|
|
1142 }
|
|
1143 else
|
|
1144 {
|
|
1145 pllp = 7U;
|
|
1146 }
|
|
1147 }
|
|
1148 frequency = (pllvco * plln) / pllp;
|
|
1149 }
|
|
1150 }
|
|
1151
|
|
1152 #endif /* RCC_PLLSAI2_SUPPORT */
|
|
1153
|
|
1154 else
|
|
1155 {
|
|
1156 /* No clock source */
|
|
1157 frequency = 0U;
|
|
1158 }
|
|
1159 }
|
|
1160 break;
|
|
1161
|
|
1162 #if defined(USB_OTG_FS) || defined(USB)
|
|
1163
|
|
1164 case RCC_PERIPHCLK_USB:
|
|
1165
|
|
1166 #endif /* USB_OTG_FS || USB */
|
|
1167
|
|
1168 case RCC_PERIPHCLK_RNG:
|
|
1169
|
|
1170 #if defined(SDMMC1)
|
|
1171
|
|
1172 case RCC_PERIPHCLK_SDMMC1:
|
|
1173
|
|
1174 #endif /* SDMMC1 */
|
|
1175
|
|
1176 srcclk = READ_BIT(RCC->CCIPR, RCC_CCIPR_CLK48SEL);
|
|
1177
|
|
1178 if(srcclk == RCC_CCIPR_CLK48SEL) /* MSI ? */
|
|
1179 {
|
|
1180 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_MSIRDY))
|
|
1181 {
|
|
1182 frequency = (1U << ((__HAL_RCC_GET_MSI_RANGE() >> 4U) - 4U)) * 1000000U;
|
|
1183 }
|
|
1184 else
|
|
1185 {
|
|
1186 frequency = 0U;
|
|
1187 }
|
|
1188 }
|
|
1189 else if(srcclk == RCC_CCIPR_CLK48SEL_1) /* PLL ? */
|
|
1190 {
|
|
1191 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLRDY) && HAL_IS_BIT_SET(RCC->PLLCFGR, RCC_PLLCFGR_PLLQEN))
|
|
1192 {
|
|
1193 /* f(PLL48M1CLK) = f(VCO input) * PLLN / PLLQ */
|
|
1194 plln = READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLN) >> POSITION_VAL(RCC_PLLCFGR_PLLN);
|
|
1195 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLQ) >> POSITION_VAL(RCC_PLLCFGR_PLLQ)) + 1U) << 1U);
|
|
1196 }
|
|
1197 else
|
|
1198 {
|
|
1199 frequency = 0U;
|
|
1200 }
|
|
1201 }
|
|
1202 else if(srcclk == RCC_CCIPR_CLK48SEL_0) /* PLLSAI1 ? */
|
|
1203 {
|
|
1204 if(HAL_IS_BIT_SET(RCC->CR, RCC_CR_PLLSAI1RDY) && HAL_IS_BIT_SET(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1QEN))
|
|
1205 {
|
|
1206 /* f(PLL48M2CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1Q */
|
|
1207 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N);
|
|
1208 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1Q) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q)) + 1U) << 1U);
|
|
1209 }
|
|
1210 else
|
|
1211 {
|
|
1212 frequency = 0U;
|
|
1213 }
|
|
1214 }
|
|
1215 #if defined(RCC_HSI48_SUPPORT)
|
|
1216 else if((srcclk == 0U) && (HAL_IS_BIT_SET(RCC->CRRCR, RCC_CRRCR_HSI48RDY))) /* HSI48 ? */
|
|
1217 {
|
|
1218 frequency = HSI48_VALUE;
|
|
1219 }
|
|
1220 else /* No clock source */
|
|
1221 {
|
|
1222 frequency = 0U;
|
|
1223 }
|
|
1224 #else
|
|
1225 else /* No clock source */
|
|
1226 {
|
|
1227 frequency = 0U;
|
|
1228 }
|
|
1229 #endif /* RCC_HSI48_SUPPORT */
|
|
1230 break;
|
|
1231
|
|
1232 case RCC_PERIPHCLK_USART1:
|
|
1233 /* Get the current USART1 source */
|
|
1234 srcclk = __HAL_RCC_GET_USART1_SOURCE();
|
|
1235
|
|
1236 if(srcclk == RCC_USART1CLKSOURCE_PCLK2)
|
|
1237 {
|
|
1238 frequency = HAL_RCC_GetPCLK2Freq();
|
|
1239 }
|
|
1240 else if(srcclk == RCC_USART1CLKSOURCE_SYSCLK)
|
|
1241 {
|
|
1242 frequency = HAL_RCC_GetSysClockFreq();
|
|
1243 }
|
|
1244 else if((srcclk == RCC_USART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1245 {
|
|
1246 frequency = HSI_VALUE;
|
|
1247 }
|
|
1248 else if((srcclk == RCC_USART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
1249 {
|
|
1250 frequency = LSE_VALUE;
|
|
1251 }
|
|
1252 /* Clock not enabled for USART1 */
|
|
1253 else
|
|
1254 {
|
|
1255 frequency = 0U;
|
|
1256 }
|
|
1257 break;
|
|
1258
|
|
1259 case RCC_PERIPHCLK_USART2:
|
|
1260 /* Get the current USART2 source */
|
|
1261 srcclk = __HAL_RCC_GET_USART2_SOURCE();
|
|
1262
|
|
1263 if(srcclk == RCC_USART2CLKSOURCE_PCLK1)
|
|
1264 {
|
|
1265 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1266 }
|
|
1267 else if(srcclk == RCC_USART2CLKSOURCE_SYSCLK)
|
|
1268 {
|
|
1269 frequency = HAL_RCC_GetSysClockFreq();
|
|
1270 }
|
|
1271 else if((srcclk == RCC_USART2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1272 {
|
|
1273 frequency = HSI_VALUE;
|
|
1274 }
|
|
1275 else if((srcclk == RCC_USART2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
1276 {
|
|
1277 frequency = LSE_VALUE;
|
|
1278 }
|
|
1279 /* Clock not enabled for USART2 */
|
|
1280 else
|
|
1281 {
|
|
1282 frequency = 0U;
|
|
1283 }
|
|
1284 break;
|
|
1285
|
|
1286 #if defined(USART3)
|
|
1287
|
|
1288 case RCC_PERIPHCLK_USART3:
|
|
1289 /* Get the current USART3 source */
|
|
1290 srcclk = __HAL_RCC_GET_USART3_SOURCE();
|
|
1291
|
|
1292 if(srcclk == RCC_USART3CLKSOURCE_PCLK1)
|
|
1293 {
|
|
1294 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1295 }
|
|
1296 else if(srcclk == RCC_USART3CLKSOURCE_SYSCLK)
|
|
1297 {
|
|
1298 frequency = HAL_RCC_GetSysClockFreq();
|
|
1299 }
|
|
1300 else if((srcclk == RCC_USART3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1301 {
|
|
1302 frequency = HSI_VALUE;
|
|
1303 }
|
|
1304 else if((srcclk == RCC_USART3CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
1305 {
|
|
1306 frequency = LSE_VALUE;
|
|
1307 }
|
|
1308 /* Clock not enabled for USART3 */
|
|
1309 else
|
|
1310 {
|
|
1311 frequency = 0U;
|
|
1312 }
|
|
1313 break;
|
|
1314
|
|
1315 #endif /* USART3 */
|
|
1316
|
|
1317 #if defined(UART4)
|
|
1318
|
|
1319 case RCC_PERIPHCLK_UART4:
|
|
1320 /* Get the current UART4 source */
|
|
1321 srcclk = __HAL_RCC_GET_UART4_SOURCE();
|
|
1322
|
|
1323 if(srcclk == RCC_UART4CLKSOURCE_PCLK1)
|
|
1324 {
|
|
1325 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1326 }
|
|
1327 else if(srcclk == RCC_UART4CLKSOURCE_SYSCLK)
|
|
1328 {
|
|
1329 frequency = HAL_RCC_GetSysClockFreq();
|
|
1330 }
|
|
1331 else if((srcclk == RCC_UART4CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1332 {
|
|
1333 frequency = HSI_VALUE;
|
|
1334 }
|
|
1335 else if((srcclk == RCC_UART4CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
1336 {
|
|
1337 frequency = LSE_VALUE;
|
|
1338 }
|
|
1339 /* Clock not enabled for UART4 */
|
|
1340 else
|
|
1341 {
|
|
1342 frequency = 0U;
|
|
1343 }
|
|
1344 break;
|
|
1345
|
|
1346 #endif /* UART4 */
|
|
1347
|
|
1348 #if defined(UART5)
|
|
1349
|
|
1350 case RCC_PERIPHCLK_UART5:
|
|
1351 /* Get the current UART5 source */
|
|
1352 srcclk = __HAL_RCC_GET_UART5_SOURCE();
|
|
1353
|
|
1354 if(srcclk == RCC_UART5CLKSOURCE_PCLK1)
|
|
1355 {
|
|
1356 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1357 }
|
|
1358 else if(srcclk == RCC_UART5CLKSOURCE_SYSCLK)
|
|
1359 {
|
|
1360 frequency = HAL_RCC_GetSysClockFreq();
|
|
1361 }
|
|
1362 else if((srcclk == RCC_UART5CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1363 {
|
|
1364 frequency = HSI_VALUE;
|
|
1365 }
|
|
1366 else if((srcclk == RCC_UART5CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
1367 {
|
|
1368 frequency = LSE_VALUE;
|
|
1369 }
|
|
1370 /* Clock not enabled for UART5 */
|
|
1371 else
|
|
1372 {
|
|
1373 frequency = 0U;
|
|
1374 }
|
|
1375 break;
|
|
1376
|
|
1377 #endif /* UART5 */
|
|
1378
|
|
1379 case RCC_PERIPHCLK_LPUART1:
|
|
1380 /* Get the current LPUART1 source */
|
|
1381 srcclk = __HAL_RCC_GET_LPUART1_SOURCE();
|
|
1382
|
|
1383 if(srcclk == RCC_LPUART1CLKSOURCE_PCLK1)
|
|
1384 {
|
|
1385 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1386 }
|
|
1387 else if(srcclk == RCC_LPUART1CLKSOURCE_SYSCLK)
|
|
1388 {
|
|
1389 frequency = HAL_RCC_GetSysClockFreq();
|
|
1390 }
|
|
1391 else if((srcclk == RCC_LPUART1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1392 {
|
|
1393 frequency = HSI_VALUE;
|
|
1394 }
|
|
1395 else if((srcclk == RCC_LPUART1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
1396 {
|
|
1397 frequency = LSE_VALUE;
|
|
1398 }
|
|
1399 /* Clock not enabled for LPUART1 */
|
|
1400 else
|
|
1401 {
|
|
1402 frequency = 0U;
|
|
1403 }
|
|
1404 break;
|
|
1405
|
|
1406 case RCC_PERIPHCLK_ADC:
|
|
1407
|
|
1408 srcclk = __HAL_RCC_GET_ADC_SOURCE();
|
|
1409
|
|
1410 if(srcclk == RCC_ADCCLKSOURCE_SYSCLK)
|
|
1411 {
|
|
1412 frequency = HAL_RCC_GetSysClockFreq();
|
|
1413 }
|
|
1414 else if(srcclk == RCC_ADCCLKSOURCE_PLLSAI1)
|
|
1415 {
|
|
1416 if(__HAL_RCC_GET_PLLSAI1CLKOUT_CONFIG(RCC_PLLSAI1_ADC1CLK) != RESET)
|
|
1417 {
|
|
1418 /* f(PLLADC1CLK) = f(VCOSAI1 input) * PLLSAI1N / PLLSAI1R */
|
|
1419 plln = READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1N) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N);
|
|
1420 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI1CFGR, RCC_PLLSAI1CFGR_PLLSAI1R) >> POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R)) + 1U) << 1U);
|
|
1421 }
|
|
1422 }
|
|
1423 #if defined(STM32L471xx) || defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx)
|
|
1424 else if(srcclk == RCC_ADCCLKSOURCE_PLLSAI2)
|
|
1425 {
|
|
1426 if(__HAL_RCC_GET_PLLSAI2CLKOUT_CONFIG(RCC_PLLSAI2_ADC2CLK) != RESET)
|
|
1427 {
|
|
1428 /* f(PLLADC2CLK) = f(VCOSAI2 input) * PLLSAI2N / PLLSAI2R */
|
|
1429 plln = READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2N) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N);
|
|
1430 frequency = (pllvco * plln) / (((READ_BIT(RCC->PLLSAI2CFGR, RCC_PLLSAI2CFGR_PLLSAI2R) >> POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R)) + 1U) << 1U);
|
|
1431 }
|
|
1432 }
|
|
1433 #endif /* STM32L471xx || STM32L475xx || STM32L476xx || STM32L485xx || STM32L486xx */
|
|
1434 /* Clock not enabled for ADC */
|
|
1435 else
|
|
1436 {
|
|
1437 frequency = 0U;
|
|
1438 }
|
|
1439 break;
|
|
1440
|
|
1441 #if defined(DFSDM1_Filter0)
|
|
1442
|
|
1443 case RCC_PERIPHCLK_DFSDM1:
|
|
1444 /* Get the current DFSDM1 source */
|
|
1445 srcclk = __HAL_RCC_GET_DFSDM1_SOURCE();
|
|
1446
|
|
1447 if(srcclk == RCC_DFSDM1CLKSOURCE_PCLK)
|
|
1448 {
|
|
1449 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1450 }
|
|
1451 else
|
|
1452 {
|
|
1453 frequency = HAL_RCC_GetSysClockFreq();
|
|
1454 }
|
|
1455 break;
|
|
1456
|
|
1457 #endif /* DFSDM1_Filter0 */
|
|
1458
|
|
1459 case RCC_PERIPHCLK_I2C1:
|
|
1460 /* Get the current I2C1 source */
|
|
1461 srcclk = __HAL_RCC_GET_I2C1_SOURCE();
|
|
1462
|
|
1463 if(srcclk == RCC_I2C1CLKSOURCE_PCLK1)
|
|
1464 {
|
|
1465 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1466 }
|
|
1467 else if(srcclk == RCC_I2C1CLKSOURCE_SYSCLK)
|
|
1468 {
|
|
1469 frequency = HAL_RCC_GetSysClockFreq();
|
|
1470 }
|
|
1471 else if((srcclk == RCC_I2C1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1472 {
|
|
1473 frequency = HSI_VALUE;
|
|
1474 }
|
|
1475 /* Clock not enabled for I2C1 */
|
|
1476 else
|
|
1477 {
|
|
1478 frequency = 0U;
|
|
1479 }
|
|
1480 break;
|
|
1481
|
|
1482 #if defined(I2C2)
|
|
1483
|
|
1484 case RCC_PERIPHCLK_I2C2:
|
|
1485 /* Get the current I2C2 source */
|
|
1486 srcclk = __HAL_RCC_GET_I2C2_SOURCE();
|
|
1487
|
|
1488 if(srcclk == RCC_I2C2CLKSOURCE_PCLK1)
|
|
1489 {
|
|
1490 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1491 }
|
|
1492 else if(srcclk == RCC_I2C2CLKSOURCE_SYSCLK)
|
|
1493 {
|
|
1494 frequency = HAL_RCC_GetSysClockFreq();
|
|
1495 }
|
|
1496 else if((srcclk == RCC_I2C2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1497 {
|
|
1498 frequency = HSI_VALUE;
|
|
1499 }
|
|
1500 /* Clock not enabled for I2C2 */
|
|
1501 else
|
|
1502 {
|
|
1503 frequency = 0U;
|
|
1504 }
|
|
1505 break;
|
|
1506
|
|
1507 #endif /* I2C2 */
|
|
1508
|
|
1509 case RCC_PERIPHCLK_I2C3:
|
|
1510 /* Get the current I2C3 source */
|
|
1511 srcclk = __HAL_RCC_GET_I2C3_SOURCE();
|
|
1512
|
|
1513 if(srcclk == RCC_I2C3CLKSOURCE_PCLK1)
|
|
1514 {
|
|
1515 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1516 }
|
|
1517 else if(srcclk == RCC_I2C3CLKSOURCE_SYSCLK)
|
|
1518 {
|
|
1519 frequency = HAL_RCC_GetSysClockFreq();
|
|
1520 }
|
|
1521 else if((srcclk == RCC_I2C3CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1522 {
|
|
1523 frequency = HSI_VALUE;
|
|
1524 }
|
|
1525 /* Clock not enabled for I2C3 */
|
|
1526 else
|
|
1527 {
|
|
1528 frequency = 0U;
|
|
1529 }
|
|
1530 break;
|
|
1531
|
|
1532 #if defined(I2C4)
|
|
1533
|
|
1534 case RCC_PERIPHCLK_I2C4:
|
|
1535 /* Get the current I2C4 source */
|
|
1536 srcclk = __HAL_RCC_GET_I2C4_SOURCE();
|
|
1537
|
|
1538 if(srcclk == RCC_I2C4CLKSOURCE_PCLK1)
|
|
1539 {
|
|
1540 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1541 }
|
|
1542 else if(srcclk == RCC_I2C4CLKSOURCE_SYSCLK)
|
|
1543 {
|
|
1544 frequency = HAL_RCC_GetSysClockFreq();
|
|
1545 }
|
|
1546 else if((srcclk == RCC_I2C4CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1547 {
|
|
1548 frequency = HSI_VALUE;
|
|
1549 }
|
|
1550 /* Clock not enabled for I2C4 */
|
|
1551 else
|
|
1552 {
|
|
1553 frequency = 0U;
|
|
1554 }
|
|
1555 break;
|
|
1556
|
|
1557 #endif /* I2C4 */
|
|
1558
|
|
1559 case RCC_PERIPHCLK_LPTIM1:
|
|
1560 /* Get the current LPTIM1 source */
|
|
1561 srcclk = __HAL_RCC_GET_LPTIM1_SOURCE();
|
|
1562
|
|
1563 if(srcclk == RCC_LPTIM1CLKSOURCE_PCLK)
|
|
1564 {
|
|
1565 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1566 }
|
|
1567 else if((srcclk == RCC_LPTIM1CLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
|
|
1568 {
|
|
1569 frequency = LSI_VALUE;
|
|
1570 }
|
|
1571 else if((srcclk == RCC_LPTIM1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1572 {
|
|
1573 frequency = HSI_VALUE;
|
|
1574 }
|
|
1575 else if ((srcclk == RCC_LPTIM1CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
1576 {
|
|
1577 frequency = LSE_VALUE;
|
|
1578 }
|
|
1579 /* Clock not enabled for LPTIM1 */
|
|
1580 else
|
|
1581 {
|
|
1582 frequency = 0U;
|
|
1583 }
|
|
1584 break;
|
|
1585
|
|
1586 case RCC_PERIPHCLK_LPTIM2:
|
|
1587 /* Get the current LPTIM2 source */
|
|
1588 srcclk = __HAL_RCC_GET_LPTIM2_SOURCE();
|
|
1589
|
|
1590 if(srcclk == RCC_LPTIM2CLKSOURCE_PCLK)
|
|
1591 {
|
|
1592 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1593 }
|
|
1594 else if((srcclk == RCC_LPTIM2CLKSOURCE_LSI) && (HAL_IS_BIT_SET(RCC->CSR, RCC_CSR_LSIRDY)))
|
|
1595 {
|
|
1596 frequency = LSI_VALUE;
|
|
1597 }
|
|
1598 else if((srcclk == RCC_LPTIM2CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1599 {
|
|
1600 frequency = HSI_VALUE;
|
|
1601 }
|
|
1602 else if ((srcclk == RCC_LPTIM2CLKSOURCE_LSE) && (HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSERDY)))
|
|
1603 {
|
|
1604 frequency = LSE_VALUE;
|
|
1605 }
|
|
1606 /* Clock not enabled for LPTIM2 */
|
|
1607 else
|
|
1608 {
|
|
1609 frequency = 0U;
|
|
1610 }
|
|
1611 break;
|
|
1612
|
|
1613 #if defined(SWPMI1)
|
|
1614
|
|
1615 case RCC_PERIPHCLK_SWPMI1:
|
|
1616 /* Get the current SWPMI1 source */
|
|
1617 srcclk = __HAL_RCC_GET_SWPMI1_SOURCE();
|
|
1618
|
|
1619 if(srcclk == RCC_SWPMI1CLKSOURCE_PCLK)
|
|
1620 {
|
|
1621 frequency = HAL_RCC_GetPCLK1Freq();
|
|
1622 }
|
|
1623 else if((srcclk == RCC_SWPMI1CLKSOURCE_HSI) && (HAL_IS_BIT_SET(RCC->CR, RCC_CR_HSIRDY)))
|
|
1624 {
|
|
1625 frequency = HSI_VALUE;
|
|
1626 }
|
|
1627 /* Clock not enabled for SWPMI1 */
|
|
1628 else
|
|
1629 {
|
|
1630 frequency = 0U;
|
|
1631 }
|
|
1632 break;
|
|
1633
|
|
1634 #endif /* SWPMI1 */
|
|
1635
|
|
1636 default:
|
|
1637 break;
|
|
1638 }
|
|
1639 }
|
|
1640
|
|
1641 return(frequency);
|
|
1642 }
|
|
1643
|
|
1644 /**
|
|
1645 * @}
|
|
1646 */
|
|
1647
|
|
1648 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions
|
|
1649 * @brief Extended Clock management functions
|
|
1650 *
|
|
1651 @verbatim
|
|
1652 ===============================================================================
|
|
1653 ##### Extended clock management functions #####
|
|
1654 ===============================================================================
|
|
1655 [..]
|
|
1656 This subsection provides a set of functions allowing to control the
|
|
1657 activation or deactivation of MSI PLL-mode, PLLSAI1, PLLSAI2, LSE CSS,
|
|
1658 Low speed clock output and clock after wake-up from STOP mode.
|
|
1659 @endverbatim
|
|
1660 * @{
|
|
1661 */
|
|
1662
|
|
1663 /**
|
|
1664 * @brief Enable PLLSAI1.
|
|
1665 * @param PLLSAI1Init pointer to an RCC_PLLSAI1InitTypeDef structure that
|
|
1666 * contains the configuration information for the PLLSAI1
|
|
1667 * @retval HAL status
|
|
1668 */
|
|
1669 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI1(RCC_PLLSAI1InitTypeDef *PLLSAI1Init)
|
|
1670 {
|
|
1671 uint32_t tickstart = 0U;
|
|
1672 HAL_StatusTypeDef status = HAL_OK;
|
|
1673
|
|
1674 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
|
|
1675 assert_param(IS_RCC_PLLSAI1SOURCE(PLLSAI1Init->PLLSAI1Source));
|
|
1676 assert_param(IS_RCC_PLLSAI1M_VALUE(PLLSAI1Init->PLLSAI1M));
|
|
1677 assert_param(IS_RCC_PLLSAI1N_VALUE(PLLSAI1Init->PLLSAI1N));
|
|
1678 assert_param(IS_RCC_PLLSAI1P_VALUE(PLLSAI1Init->PLLSAI1P));
|
|
1679 assert_param(IS_RCC_PLLSAI1Q_VALUE(PLLSAI1Init->PLLSAI1Q));
|
|
1680 assert_param(IS_RCC_PLLSAI1R_VALUE(PLLSAI1Init->PLLSAI1R));
|
|
1681 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PLLSAI1Init->PLLSAI1ClockOut));
|
|
1682
|
|
1683 /* Disable the PLLSAI1 */
|
|
1684 __HAL_RCC_PLLSAI1_DISABLE();
|
|
1685
|
|
1686 /* Get Start Tick*/
|
|
1687 tickstart = HAL_GetTick();
|
|
1688
|
|
1689 /* Wait till PLLSAI1 is ready to be updated */
|
|
1690 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET)
|
|
1691 {
|
|
1692 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
|
1693 {
|
|
1694 status = HAL_TIMEOUT;
|
|
1695 break;
|
|
1696 }
|
|
1697 }
|
|
1698
|
|
1699 if(status == HAL_OK)
|
|
1700 {
|
|
1701 /* Configure the PLLSAI1 Multiplication factor N */
|
|
1702 /* Configure the PLLSAI1 Division factors P, Q and R */
|
|
1703 __HAL_RCC_PLLSAI1_CONFIG(PLLSAI1Init->PLLSAI1N, PLLSAI1Init->PLLSAI1P, PLLSAI1Init->PLLSAI1Q, PLLSAI1Init->PLLSAI1R);
|
|
1704 /* Configure the PLLSAI1 Clock output(s) */
|
|
1705 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PLLSAI1Init->PLLSAI1ClockOut);
|
|
1706
|
|
1707 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
|
|
1708 __HAL_RCC_PLLSAI1_ENABLE();
|
|
1709
|
|
1710 /* Get Start Tick*/
|
|
1711 tickstart = HAL_GetTick();
|
|
1712
|
|
1713 /* Wait till PLLSAI1 is ready */
|
|
1714 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET)
|
|
1715 {
|
|
1716 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
|
1717 {
|
|
1718 status = HAL_TIMEOUT;
|
|
1719 break;
|
|
1720 }
|
|
1721 }
|
|
1722 }
|
|
1723
|
|
1724 return status;
|
|
1725 }
|
|
1726
|
|
1727 /**
|
|
1728 * @brief Disable PLLSAI1.
|
|
1729 * @retval HAL status
|
|
1730 */
|
|
1731 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI1(void)
|
|
1732 {
|
|
1733 uint32_t tickstart = 0U;
|
|
1734 HAL_StatusTypeDef status = HAL_OK;
|
|
1735
|
|
1736 /* Disable the PLLSAI1 */
|
|
1737 __HAL_RCC_PLLSAI1_DISABLE();
|
|
1738
|
|
1739 /* Get Start Tick*/
|
|
1740 tickstart = HAL_GetTick();
|
|
1741
|
|
1742 /* Wait till PLLSAI1 is ready */
|
|
1743 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET)
|
|
1744 {
|
|
1745 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
|
1746 {
|
|
1747 status = HAL_TIMEOUT;
|
|
1748 break;
|
|
1749 }
|
|
1750 }
|
|
1751
|
|
1752 /* Disable the PLLSAI1 Clock outputs */
|
|
1753 __HAL_RCC_PLLSAI1CLKOUT_DISABLE(RCC_PLLSAI1CFGR_PLLSAI1PEN|RCC_PLLSAI1CFGR_PLLSAI1QEN|RCC_PLLSAI1CFGR_PLLSAI1REN);
|
|
1754
|
|
1755 /* Reset PLL source to save power if no PLLs on */
|
|
1756 if((READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET)
|
|
1757 #if defined(RCC_PLLSAI2_SUPPORT)
|
|
1758 &&
|
|
1759 (READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET)
|
|
1760 #endif /* RCC_PLLSAI2_SUPPORT */
|
|
1761 )
|
|
1762 {
|
|
1763 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
|
|
1764 }
|
|
1765
|
|
1766 return status;
|
|
1767 }
|
|
1768
|
|
1769 #if defined(RCC_PLLSAI2_SUPPORT)
|
|
1770
|
|
1771 /**
|
|
1772 * @brief Enable PLLSAI2.
|
|
1773 * @param PLLSAI2Init pointer to an RCC_PLLSAI2InitTypeDef structure that
|
|
1774 * contains the configuration information for the PLLSAI2
|
|
1775 * @retval HAL status
|
|
1776 */
|
|
1777 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI2(RCC_PLLSAI2InitTypeDef *PLLSAI2Init)
|
|
1778 {
|
|
1779 uint32_t tickstart = 0U;
|
|
1780 HAL_StatusTypeDef status = HAL_OK;
|
|
1781
|
|
1782 /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
|
|
1783 assert_param(IS_RCC_PLLSAI2SOURCE(PLLSAI2Init->PLLSAI2Source));
|
|
1784 assert_param(IS_RCC_PLLSAI2M_VALUE(PLLSAI2Init->PLLSAI2M));
|
|
1785 assert_param(IS_RCC_PLLSAI2N_VALUE(PLLSAI2Init->PLLSAI2N));
|
|
1786 assert_param(IS_RCC_PLLSAI2P_VALUE(PLLSAI2Init->PLLSAI2P));
|
|
1787 assert_param(IS_RCC_PLLSAI2R_VALUE(PLLSAI2Init->PLLSAI2R));
|
|
1788 assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PLLSAI2Init->PLLSAI2ClockOut));
|
|
1789
|
|
1790 /* Disable the PLLSAI2 */
|
|
1791 __HAL_RCC_PLLSAI2_DISABLE();
|
|
1792
|
|
1793 /* Get Start Tick*/
|
|
1794 tickstart = HAL_GetTick();
|
|
1795
|
|
1796 /* Wait till PLLSAI2 is ready to be updated */
|
|
1797 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET)
|
|
1798 {
|
|
1799 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
|
1800 {
|
|
1801 status = HAL_TIMEOUT;
|
|
1802 break;
|
|
1803 }
|
|
1804 }
|
|
1805
|
|
1806 if(status == HAL_OK)
|
|
1807 {
|
|
1808 /* Configure the PLLSAI2 Multiplication factor N */
|
|
1809 /* Configure the PLLSAI2 Division factors P and R */
|
|
1810 __HAL_RCC_PLLSAI2_CONFIG(PLLSAI2Init->PLLSAI2N, PLLSAI2Init->PLLSAI2P, PLLSAI2Init->PLLSAI2R);
|
|
1811 /* Configure the PLLSAI2 Clock output(s) */
|
|
1812 __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PLLSAI2Init->PLLSAI2ClockOut);
|
|
1813
|
|
1814 /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
|
|
1815 __HAL_RCC_PLLSAI2_ENABLE();
|
|
1816
|
|
1817 /* Get Start Tick*/
|
|
1818 tickstart = HAL_GetTick();
|
|
1819
|
|
1820 /* Wait till PLLSAI2 is ready */
|
|
1821 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET)
|
|
1822 {
|
|
1823 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
|
1824 {
|
|
1825 status = HAL_TIMEOUT;
|
|
1826 break;
|
|
1827 }
|
|
1828 }
|
|
1829 }
|
|
1830
|
|
1831 return status;
|
|
1832 }
|
|
1833
|
|
1834 /**
|
|
1835 * @brief Disable PLLISAI2.
|
|
1836 * @retval HAL status
|
|
1837 */
|
|
1838 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI2(void)
|
|
1839 {
|
|
1840 uint32_t tickstart = 0U;
|
|
1841 HAL_StatusTypeDef status = HAL_OK;
|
|
1842
|
|
1843 /* Disable the PLLSAI2 */
|
|
1844 __HAL_RCC_PLLSAI2_DISABLE();
|
|
1845
|
|
1846 /* Get Start Tick*/
|
|
1847 tickstart = HAL_GetTick();
|
|
1848
|
|
1849 /* Wait till PLLSAI2 is ready */
|
|
1850 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET)
|
|
1851 {
|
|
1852 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
|
1853 {
|
|
1854 status = HAL_TIMEOUT;
|
|
1855 break;
|
|
1856 }
|
|
1857 }
|
|
1858
|
|
1859 /* Disable the PLLSAI2 Clock outputs */
|
|
1860 __HAL_RCC_PLLSAI2CLKOUT_DISABLE(RCC_PLLSAI2CFGR_PLLSAI2PEN|RCC_PLLSAI2CFGR_PLLSAI2REN);
|
|
1861
|
|
1862 /* Reset PLL source to save power if no PLLs on */
|
|
1863 if((READ_BIT(RCC->CR, RCC_CR_PLLRDY) == RESET)
|
|
1864 &&
|
|
1865 (READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET)
|
|
1866 )
|
|
1867 {
|
|
1868 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC, RCC_PLLSOURCE_NONE);
|
|
1869 }
|
|
1870
|
|
1871 return status;
|
|
1872 }
|
|
1873
|
|
1874 #endif /* RCC_PLLSAI2_SUPPORT */
|
|
1875
|
|
1876 /**
|
|
1877 * @brief Configure the oscillator clock source for wakeup from Stop and CSS backup clock.
|
|
1878 * @param WakeUpClk Wakeup clock
|
|
1879 * This parameter can be one of the following values:
|
|
1880 * @arg @ref RCC_STOP_WAKEUPCLOCK_MSI MSI oscillator selection
|
|
1881 * @arg @ref RCC_STOP_WAKEUPCLOCK_HSI HSI oscillator selection
|
|
1882 * @note This function shall not be called after the Clock Security System on HSE has been
|
|
1883 * enabled.
|
|
1884 * @retval None
|
|
1885 */
|
|
1886 void HAL_RCCEx_WakeUpStopCLKConfig(uint32_t WakeUpClk)
|
|
1887 {
|
|
1888 assert_param(IS_RCC_STOP_WAKEUPCLOCK(WakeUpClk));
|
|
1889
|
|
1890 __HAL_RCC_WAKEUPSTOP_CLK_CONFIG(WakeUpClk);
|
|
1891 }
|
|
1892
|
|
1893 /**
|
|
1894 * @brief Configure the MSI range after standby mode.
|
|
1895 * @note After Standby its frequency can be selected between 4 possible values (1, 2, 4 or 8 MHz).
|
|
1896 * @param MSIRange MSI range
|
|
1897 * This parameter can be one of the following values:
|
|
1898 * @arg @ref RCC_MSIRANGE_4 Range 4 around 1 MHz
|
|
1899 * @arg @ref RCC_MSIRANGE_5 Range 5 around 2 MHz
|
|
1900 * @arg @ref RCC_MSIRANGE_6 Range 6 around 4 MHz (reset value)
|
|
1901 * @arg @ref RCC_MSIRANGE_7 Range 7 around 8 MHz
|
|
1902 * @retval None
|
|
1903 */
|
|
1904 void HAL_RCCEx_StandbyMSIRangeConfig(uint32_t MSIRange)
|
|
1905 {
|
|
1906 assert_param(IS_RCC_MSI_STANDBY_CLOCK_RANGE(MSIRange));
|
|
1907
|
|
1908 __HAL_RCC_MSI_STANDBY_RANGE_CONFIG(MSIRange);
|
|
1909 }
|
|
1910
|
|
1911 /**
|
|
1912 * @brief Enable the LSE Clock Security System.
|
|
1913 * @note Prior to enable the LSE Clock Security System, LSE oscillator is to be enabled
|
|
1914 * with HAL_RCC_OscConfig() and the LSE oscillator clock is to be selected as RTC
|
|
1915 * clock with HAL_RCCEx_PeriphCLKConfig().
|
|
1916 * @retval None
|
|
1917 */
|
|
1918 void HAL_RCCEx_EnableLSECSS(void)
|
|
1919 {
|
|
1920 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
|
|
1921 }
|
|
1922
|
|
1923 /**
|
|
1924 * @brief Disable the LSE Clock Security System.
|
|
1925 * @note LSE Clock Security System can only be disabled after a LSE failure detection.
|
|
1926 * @retval None
|
|
1927 */
|
|
1928 void HAL_RCCEx_DisableLSECSS(void)
|
|
1929 {
|
|
1930 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
|
|
1931
|
|
1932 /* Disable LSE CSS IT if any */
|
|
1933 __HAL_RCC_DISABLE_IT(RCC_IT_LSECSS);
|
|
1934 }
|
|
1935
|
|
1936 /**
|
|
1937 * @brief Enable the LSE Clock Security System Interrupt & corresponding EXTI line.
|
|
1938 * @note LSE Clock Security System Interrupt is mapped on RTC EXTI line 19
|
|
1939 * @retval None
|
|
1940 */
|
|
1941 void HAL_RCCEx_EnableLSECSS_IT(void)
|
|
1942 {
|
|
1943 /* Enable LSE CSS */
|
|
1944 SET_BIT(RCC->BDCR, RCC_BDCR_LSECSSON) ;
|
|
1945
|
|
1946 /* Enable LSE CSS IT */
|
|
1947 __HAL_RCC_ENABLE_IT(RCC_IT_LSECSS);
|
|
1948
|
|
1949 /* Enable IT on EXTI Line 19 */
|
|
1950 __HAL_RCC_LSECSS_EXTI_ENABLE_IT();
|
|
1951 __HAL_RCC_LSECSS_EXTI_ENABLE_RISING_EDGE();
|
|
1952 }
|
|
1953
|
|
1954 /**
|
|
1955 * @brief Handle the RCC LSE Clock Security System interrupt request.
|
|
1956 * @retval None
|
|
1957 */
|
|
1958 void HAL_RCCEx_LSECSS_IRQHandler(void)
|
|
1959 {
|
|
1960 /* Check RCC LSE CSSF flag */
|
|
1961 if(__HAL_RCC_GET_IT(RCC_IT_LSECSS))
|
|
1962 {
|
|
1963 /* RCC LSE Clock Security System interrupt user callback */
|
|
1964 HAL_RCCEx_LSECSS_Callback();
|
|
1965
|
|
1966 /* Clear RCC LSE CSS pending bit */
|
|
1967 __HAL_RCC_CLEAR_IT(RCC_IT_LSECSS);
|
|
1968 }
|
|
1969 }
|
|
1970
|
|
1971 /**
|
|
1972 * @brief RCCEx LSE Clock Security System interrupt callback.
|
|
1973 * @retval none
|
|
1974 */
|
|
1975 __weak void HAL_RCCEx_LSECSS_Callback(void)
|
|
1976 {
|
|
1977 /* NOTE : This function should not be modified, when the callback is needed,
|
|
1978 the @ref HAL_RCCEx_LSECSS_Callback should be implemented in the user file
|
|
1979 */
|
|
1980 }
|
|
1981
|
|
1982 /**
|
|
1983 * @brief Select the Low Speed clock source to output on LSCO pin (PA2).
|
|
1984 * @param LSCOSource specifies the Low Speed clock source to output.
|
|
1985 * This parameter can be one of the following values:
|
|
1986 * @arg @ref RCC_LSCOSOURCE_LSI LSI clock selected as LSCO source
|
|
1987 * @arg @ref RCC_LSCOSOURCE_LSE LSE clock selected as LSCO source
|
|
1988 * @retval None
|
|
1989 */
|
|
1990 void HAL_RCCEx_EnableLSCO(uint32_t LSCOSource)
|
|
1991 {
|
|
1992 GPIO_InitTypeDef GPIO_InitStruct;
|
|
1993 FlagStatus pwrclkchanged = RESET;
|
|
1994 FlagStatus backupchanged = RESET;
|
|
1995
|
|
1996 /* Check the parameters */
|
|
1997 assert_param(IS_RCC_LSCOSOURCE(LSCOSource));
|
|
1998
|
|
1999 /* LSCO Pin Clock Enable */
|
|
2000 __LSCO_CLK_ENABLE();
|
|
2001
|
|
2002 /* Configue the LSCO pin in analog mode */
|
|
2003 GPIO_InitStruct.Pin = LSCO_PIN;
|
|
2004 GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
|
|
2005 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
2006 GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
2007 HAL_GPIO_Init(LSCO_GPIO_PORT, &GPIO_InitStruct);
|
|
2008
|
|
2009 /* Update LSCOSEL clock source in Backup Domain control register */
|
|
2010 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
|
|
2011 {
|
|
2012 __HAL_RCC_PWR_CLK_ENABLE();
|
|
2013 pwrclkchanged = SET;
|
|
2014 }
|
|
2015 if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
|
2016 {
|
|
2017 HAL_PWR_EnableBkUpAccess();
|
|
2018 backupchanged = SET;
|
|
2019 }
|
|
2020
|
|
2021 MODIFY_REG(RCC->BDCR, RCC_BDCR_LSCOSEL | RCC_BDCR_LSCOEN, LSCOSource | RCC_BDCR_LSCOEN);
|
|
2022
|
|
2023 if(backupchanged == SET)
|
|
2024 {
|
|
2025 HAL_PWR_DisableBkUpAccess();
|
|
2026 }
|
|
2027 if(pwrclkchanged == SET)
|
|
2028 {
|
|
2029 __HAL_RCC_PWR_CLK_DISABLE();
|
|
2030 }
|
|
2031 }
|
|
2032
|
|
2033 /**
|
|
2034 * @brief Disable the Low Speed clock output.
|
|
2035 * @retval None
|
|
2036 */
|
|
2037 void HAL_RCCEx_DisableLSCO(void)
|
|
2038 {
|
|
2039 FlagStatus pwrclkchanged = RESET;
|
|
2040 FlagStatus backupchanged = RESET;
|
|
2041
|
|
2042 /* Update LSCOEN bit in Backup Domain control register */
|
|
2043 if(__HAL_RCC_PWR_IS_CLK_DISABLED())
|
|
2044 {
|
|
2045 __HAL_RCC_PWR_CLK_ENABLE();
|
|
2046 pwrclkchanged = SET;
|
|
2047 }
|
|
2048 if(HAL_IS_BIT_CLR(PWR->CR1, PWR_CR1_DBP))
|
|
2049 {
|
|
2050 /* Enable access to the backup domain */
|
|
2051 HAL_PWR_EnableBkUpAccess();
|
|
2052 backupchanged = SET;
|
|
2053 }
|
|
2054
|
|
2055 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSCOEN);
|
|
2056
|
|
2057 /* Restore previous configuration */
|
|
2058 if(backupchanged == SET)
|
|
2059 {
|
|
2060 /* Disable access to the backup domain */
|
|
2061 HAL_PWR_DisableBkUpAccess();
|
|
2062 }
|
|
2063 if(pwrclkchanged == SET)
|
|
2064 {
|
|
2065 __HAL_RCC_PWR_CLK_DISABLE();
|
|
2066 }
|
|
2067 }
|
|
2068
|
|
2069 /**
|
|
2070 * @brief Enable the PLL-mode of the MSI.
|
|
2071 * @note Prior to enable the PLL-mode of the MSI for automatic hardware
|
|
2072 * calibration LSE oscillator is to be enabled with HAL_RCC_OscConfig().
|
|
2073 * @retval None
|
|
2074 */
|
|
2075 void HAL_RCCEx_EnableMSIPLLMode(void)
|
|
2076 {
|
|
2077 SET_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
|
|
2078 }
|
|
2079
|
|
2080 /**
|
|
2081 * @brief Disable the PLL-mode of the MSI.
|
|
2082 * @note PLL-mode of the MSI is automatically reset when LSE oscillator is disabled.
|
|
2083 * @retval None
|
|
2084 */
|
|
2085 void HAL_RCCEx_DisableMSIPLLMode(void)
|
|
2086 {
|
|
2087 CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN) ;
|
|
2088 }
|
|
2089
|
|
2090 /**
|
|
2091 * @}
|
|
2092 */
|
|
2093
|
|
2094 #if defined(CRS)
|
|
2095
|
|
2096 /** @defgroup RCCEx_Exported_Functions_Group3 Extended Clock Recovery System Control functions
|
|
2097 * @brief Extended Clock Recovery System Control functions
|
|
2098 *
|
|
2099 @verbatim
|
|
2100 ===============================================================================
|
|
2101 ##### Extended Clock Recovery System Control functions #####
|
|
2102 ===============================================================================
|
|
2103 [..]
|
|
2104 For devices with Clock Recovery System feature (CRS), RCC Extention HAL driver can be used as follows:
|
|
2105
|
|
2106 (#) In System clock config, HSI48 needs to be enabled
|
|
2107
|
|
2108 (#) Enable CRS clock in IP MSP init which will use CRS functions
|
|
2109
|
|
2110 (#) Call CRS functions as follows:
|
|
2111 (##) Prepare synchronization configuration necessary for HSI48 calibration
|
|
2112 (+++) Default values can be set for frequency Error Measurement (reload and error limit)
|
|
2113 and also HSI48 oscillator smooth trimming.
|
|
2114 (+++) Macro __HAL_RCC_CRS_RELOADVALUE_CALCULATE can be also used to calculate
|
|
2115 directly reload value with target and sychronization frequencies values
|
|
2116 (##) Call function HAL_RCCEx_CRSConfig which
|
|
2117 (+++) Resets CRS registers to their default values.
|
|
2118 (+++) Configures CRS registers with synchronization configuration
|
|
2119 (+++) Enables automatic calibration and frequency error counter feature
|
|
2120 Note: When using USB LPM (Link Power Management) and the device is in Sleep mode, the
|
|
2121 periodic USB SOF will not be generated by the host. No SYNC signal will therefore be
|
|
2122 provided to the CRS to calibrate the HSI48 on the run. To guarantee the required clock
|
|
2123 precision after waking up from Sleep mode, the LSE or reference clock on the GPIOs
|
|
2124 should be used as SYNC signal.
|
|
2125
|
|
2126 (##) A polling function is provided to wait for complete synchronization
|
|
2127 (+++) Call function HAL_RCCEx_CRSWaitSynchronization()
|
|
2128 (+++) According to CRS status, user can decide to adjust again the calibration or continue
|
|
2129 application if synchronization is OK
|
|
2130
|
|
2131 (#) User can retrieve information related to synchronization in calling function
|
|
2132 HAL_RCCEx_CRSGetSynchronizationInfo()
|
|
2133
|
|
2134 (#) Regarding synchronization status and synchronization information, user can try a new calibration
|
|
2135 in changing synchronization configuration and call again HAL_RCCEx_CRSConfig.
|
|
2136 Note: When the SYNC event is detected during the downcounting phase (before reaching the zero value),
|
|
2137 it means that the actual frequency is lower than the target (and so, that the TRIM value should be
|
|
2138 incremented), while when it is detected during the upcounting phase it means that the actual frequency
|
|
2139 is higher (and that the TRIM value should be decremented).
|
|
2140
|
|
2141 (#) In interrupt mode, user can resort to the available macros (__HAL_RCC_CRS_XXX_IT). Interrupts will go
|
|
2142 through CRS Handler (CRS_IRQn/CRS_IRQHandler)
|
|
2143 (++) Call function HAL_RCCEx_CRSConfig()
|
|
2144 (++) Enable CRS_IRQn (thanks to NVIC functions)
|
|
2145 (++) Enable CRS interrupt (__HAL_RCC_CRS_ENABLE_IT)
|
|
2146 (++) Implement CRS status management in the following user callbacks called from
|
|
2147 HAL_RCCEx_CRS_IRQHandler():
|
|
2148 (+++) HAL_RCCEx_CRS_SyncOkCallback()
|
|
2149 (+++) HAL_RCCEx_CRS_SyncWarnCallback()
|
|
2150 (+++) HAL_RCCEx_CRS_ExpectedSyncCallback()
|
|
2151 (+++) HAL_RCCEx_CRS_ErrorCallback()
|
|
2152
|
|
2153 (#) To force a SYNC EVENT, user can use the function HAL_RCCEx_CRSSoftwareSynchronizationGenerate().
|
|
2154 This function can be called before calling HAL_RCCEx_CRSConfig (for instance in Systick handler)
|
|
2155
|
|
2156 @endverbatim
|
|
2157 * @{
|
|
2158 */
|
|
2159
|
|
2160 /**
|
|
2161 * @brief Start automatic synchronization for polling mode
|
|
2162 * @param pInit Pointer on RCC_CRSInitTypeDef structure
|
|
2163 * @retval None
|
|
2164 */
|
|
2165 void HAL_RCCEx_CRSConfig(RCC_CRSInitTypeDef *pInit)
|
|
2166 {
|
|
2167 uint32_t value = 0;
|
|
2168
|
|
2169 /* Check the parameters */
|
|
2170 assert_param(IS_RCC_CRS_SYNC_DIV(pInit->Prescaler));
|
|
2171 assert_param(IS_RCC_CRS_SYNC_SOURCE(pInit->Source));
|
|
2172 assert_param(IS_RCC_CRS_SYNC_POLARITY(pInit->Polarity));
|
|
2173 assert_param(IS_RCC_CRS_RELOADVALUE(pInit->ReloadValue));
|
|
2174 assert_param(IS_RCC_CRS_ERRORLIMIT(pInit->ErrorLimitValue));
|
|
2175 assert_param(IS_RCC_CRS_HSI48CALIBRATION(pInit->HSI48CalibrationValue));
|
|
2176
|
|
2177 /* CONFIGURATION */
|
|
2178
|
|
2179 /* Before configuration, reset CRS registers to their default values*/
|
|
2180 __HAL_RCC_CRS_FORCE_RESET();
|
|
2181 __HAL_RCC_CRS_RELEASE_RESET();
|
|
2182
|
|
2183 /* Set the SYNCDIV[2:0] bits according to Prescaler value */
|
|
2184 /* Set the SYNCSRC[1:0] bits according to Source value */
|
|
2185 /* Set the SYNCSPOL bit according to Polarity value */
|
|
2186 value = (pInit->Prescaler | pInit->Source | pInit->Polarity);
|
|
2187 /* Set the RELOAD[15:0] bits according to ReloadValue value */
|
|
2188 value |= pInit->ReloadValue;
|
|
2189 /* Set the FELIM[7:0] bits according to ErrorLimitValue value */
|
|
2190 value |= (pInit->ErrorLimitValue << POSITION_VAL(CRS_CFGR_FELIM));
|
|
2191 WRITE_REG(CRS->CFGR, value);
|
|
2192
|
|
2193 /* Adjust HSI48 oscillator smooth trimming */
|
|
2194 /* Set the TRIM[5:0] bits according to RCC_CRS_HSI48CalibrationValue value */
|
|
2195 MODIFY_REG(CRS->CR, CRS_CR_TRIM, (pInit->HSI48CalibrationValue << POSITION_VAL(CRS_CR_TRIM)));
|
|
2196
|
|
2197 /* START AUTOMATIC SYNCHRONIZATION*/
|
|
2198
|
|
2199 /* Enable Automatic trimming & Frequency error counter */
|
|
2200 SET_BIT(CRS->CR, CRS_CR_AUTOTRIMEN | CRS_CR_CEN);
|
|
2201 }
|
|
2202
|
|
2203 /**
|
|
2204 * @brief Generate the software synchronization event
|
|
2205 * @retval None
|
|
2206 */
|
|
2207 void HAL_RCCEx_CRSSoftwareSynchronizationGenerate(void)
|
|
2208 {
|
|
2209 SET_BIT(CRS->CR, CRS_CR_SWSYNC);
|
|
2210 }
|
|
2211
|
|
2212 /**
|
|
2213 * @brief Return synchronization info
|
|
2214 * @param pSynchroInfo Pointer on RCC_CRSSynchroInfoTypeDef structure
|
|
2215 * @retval None
|
|
2216 */
|
|
2217 void HAL_RCCEx_CRSGetSynchronizationInfo(RCC_CRSSynchroInfoTypeDef *pSynchroInfo)
|
|
2218 {
|
|
2219 /* Check the parameter */
|
|
2220 assert_param(pSynchroInfo != NULL);
|
|
2221
|
|
2222 /* Get the reload value */
|
|
2223 pSynchroInfo->ReloadValue = (uint32_t)(READ_BIT(CRS->CFGR, CRS_CFGR_RELOAD));
|
|
2224
|
|
2225 /* Get HSI48 oscillator smooth trimming */
|
|
2226 pSynchroInfo->HSI48CalibrationValue = (uint32_t)(READ_BIT(CRS->CR, CRS_CR_TRIM) >> POSITION_VAL(CRS_CR_TRIM));
|
|
2227
|
|
2228 /* Get Frequency error capture */
|
|
2229 pSynchroInfo->FreqErrorCapture = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FECAP) >> POSITION_VAL(CRS_ISR_FECAP));
|
|
2230
|
|
2231 /* Get Frequency error direction */
|
|
2232 pSynchroInfo->FreqErrorDirection = (uint32_t)(READ_BIT(CRS->ISR, CRS_ISR_FEDIR));
|
|
2233 }
|
|
2234
|
|
2235 /**
|
|
2236 * @brief Wait for CRS Synchronization status.
|
|
2237 * @param Timeout Duration of the timeout
|
|
2238 * @note Timeout is based on the maximum time to receive a SYNC event based on synchronization
|
|
2239 * frequency.
|
|
2240 * @note If Timeout set to HAL_MAX_DELAY, HAL_TIMEOUT will be never returned.
|
|
2241 * @retval Combination of Synchronization status
|
|
2242 * This parameter can be a combination of the following values:
|
|
2243 * @arg @ref RCC_CRS_TIMEOUT
|
|
2244 * @arg @ref RCC_CRS_SYNCOK
|
|
2245 * @arg @ref RCC_CRS_SYNCWARN
|
|
2246 * @arg @ref RCC_CRS_SYNCERR
|
|
2247 * @arg @ref RCC_CRS_SYNCMISS
|
|
2248 * @arg @ref RCC_CRS_TRIMOVF
|
|
2249 */
|
|
2250 uint32_t HAL_RCCEx_CRSWaitSynchronization(uint32_t Timeout)
|
|
2251 {
|
|
2252 uint32_t crsstatus = RCC_CRS_NONE;
|
|
2253 uint32_t tickstart = 0U;
|
|
2254
|
|
2255 /* Get timeout */
|
|
2256 tickstart = HAL_GetTick();
|
|
2257
|
|
2258 /* Wait for CRS flag or timeout detection */
|
|
2259 do
|
|
2260 {
|
|
2261 if(Timeout != HAL_MAX_DELAY)
|
|
2262 {
|
|
2263 if((Timeout == 0U) || ((HAL_GetTick() - tickstart) > Timeout))
|
|
2264 {
|
|
2265 crsstatus = RCC_CRS_TIMEOUT;
|
|
2266 }
|
|
2267 }
|
|
2268 /* Check CRS SYNCOK flag */
|
|
2269 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCOK))
|
|
2270 {
|
|
2271 /* CRS SYNC event OK */
|
|
2272 crsstatus |= RCC_CRS_SYNCOK;
|
|
2273
|
|
2274 /* Clear CRS SYNC event OK bit */
|
|
2275 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCOK);
|
|
2276 }
|
|
2277
|
|
2278 /* Check CRS SYNCWARN flag */
|
|
2279 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCWARN))
|
|
2280 {
|
|
2281 /* CRS SYNC warning */
|
|
2282 crsstatus |= RCC_CRS_SYNCWARN;
|
|
2283
|
|
2284 /* Clear CRS SYNCWARN bit */
|
|
2285 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCWARN);
|
|
2286 }
|
|
2287
|
|
2288 /* Check CRS TRIM overflow flag */
|
|
2289 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_TRIMOVF))
|
|
2290 {
|
|
2291 /* CRS SYNC Error */
|
|
2292 crsstatus |= RCC_CRS_TRIMOVF;
|
|
2293
|
|
2294 /* Clear CRS Error bit */
|
|
2295 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_TRIMOVF);
|
|
2296 }
|
|
2297
|
|
2298 /* Check CRS Error flag */
|
|
2299 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCERR))
|
|
2300 {
|
|
2301 /* CRS SYNC Error */
|
|
2302 crsstatus |= RCC_CRS_SYNCERR;
|
|
2303
|
|
2304 /* Clear CRS Error bit */
|
|
2305 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCERR);
|
|
2306 }
|
|
2307
|
|
2308 /* Check CRS SYNC Missed flag */
|
|
2309 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_SYNCMISS))
|
|
2310 {
|
|
2311 /* CRS SYNC Missed */
|
|
2312 crsstatus |= RCC_CRS_SYNCMISS;
|
|
2313
|
|
2314 /* Clear CRS SYNC Missed bit */
|
|
2315 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_SYNCMISS);
|
|
2316 }
|
|
2317
|
|
2318 /* Check CRS Expected SYNC flag */
|
|
2319 if(__HAL_RCC_CRS_GET_FLAG(RCC_CRS_FLAG_ESYNC))
|
|
2320 {
|
|
2321 /* frequency error counter reached a zero value */
|
|
2322 __HAL_RCC_CRS_CLEAR_FLAG(RCC_CRS_FLAG_ESYNC);
|
|
2323 }
|
|
2324 } while(RCC_CRS_NONE == crsstatus);
|
|
2325
|
|
2326 return crsstatus;
|
|
2327 }
|
|
2328
|
|
2329 /**
|
|
2330 * @brief Handle the Clock Recovery System interrupt request.
|
|
2331 * @retval None
|
|
2332 */
|
|
2333 void HAL_RCCEx_CRS_IRQHandler(void)
|
|
2334 {
|
|
2335 uint32_t crserror = RCC_CRS_NONE;
|
|
2336 /* Get current IT flags and IT sources values */
|
|
2337 uint32_t itflags = READ_REG(CRS->ISR);
|
|
2338 uint32_t itsources = READ_REG(CRS->CR);
|
|
2339
|
|
2340 /* Check CRS SYNCOK flag */
|
|
2341 if(((itflags & RCC_CRS_FLAG_SYNCOK) != RESET) && ((itsources & RCC_CRS_IT_SYNCOK) != RESET))
|
|
2342 {
|
|
2343 /* Clear CRS SYNC event OK flag */
|
|
2344 WRITE_REG(CRS->ICR, CRS_ICR_SYNCOKC);
|
|
2345
|
|
2346 /* user callback */
|
|
2347 HAL_RCCEx_CRS_SyncOkCallback();
|
|
2348 }
|
|
2349 /* Check CRS SYNCWARN flag */
|
|
2350 else if(((itflags & RCC_CRS_FLAG_SYNCWARN) != RESET) && ((itsources & RCC_CRS_IT_SYNCWARN) != RESET))
|
|
2351 {
|
|
2352 /* Clear CRS SYNCWARN flag */
|
|
2353 WRITE_REG(CRS->ICR, CRS_ICR_SYNCWARNC);
|
|
2354
|
|
2355 /* user callback */
|
|
2356 HAL_RCCEx_CRS_SyncWarnCallback();
|
|
2357 }
|
|
2358 /* Check CRS Expected SYNC flag */
|
|
2359 else if(((itflags & RCC_CRS_FLAG_ESYNC) != RESET) && ((itsources & RCC_CRS_IT_ESYNC) != RESET))
|
|
2360 {
|
|
2361 /* frequency error counter reached a zero value */
|
|
2362 WRITE_REG(CRS->ICR, CRS_ICR_ESYNCC);
|
|
2363
|
|
2364 /* user callback */
|
|
2365 HAL_RCCEx_CRS_ExpectedSyncCallback();
|
|
2366 }
|
|
2367 /* Check CRS Error flags */
|
|
2368 else
|
|
2369 {
|
|
2370 if(((itflags & RCC_CRS_FLAG_ERR) != RESET) && ((itsources & RCC_CRS_IT_ERR) != RESET))
|
|
2371 {
|
|
2372 if((itflags & RCC_CRS_FLAG_SYNCERR) != RESET)
|
|
2373 {
|
|
2374 crserror |= RCC_CRS_SYNCERR;
|
|
2375 }
|
|
2376 if((itflags & RCC_CRS_FLAG_SYNCMISS) != RESET)
|
|
2377 {
|
|
2378 crserror |= RCC_CRS_SYNCMISS;
|
|
2379 }
|
|
2380 if((itflags & RCC_CRS_FLAG_TRIMOVF) != RESET)
|
|
2381 {
|
|
2382 crserror |= RCC_CRS_TRIMOVF;
|
|
2383 }
|
|
2384
|
|
2385 /* Clear CRS Error flags */
|
|
2386 WRITE_REG(CRS->ICR, CRS_ICR_ERRC);
|
|
2387
|
|
2388 /* user error callback */
|
|
2389 HAL_RCCEx_CRS_ErrorCallback(crserror);
|
|
2390 }
|
|
2391 }
|
|
2392 }
|
|
2393
|
|
2394 /**
|
|
2395 * @brief RCCEx Clock Recovery System SYNCOK interrupt callback.
|
|
2396 * @retval none
|
|
2397 */
|
|
2398 __weak void HAL_RCCEx_CRS_SyncOkCallback(void)
|
|
2399 {
|
|
2400 /* NOTE : This function should not be modified, when the callback is needed,
|
|
2401 the @ref HAL_RCCEx_CRS_SyncOkCallback should be implemented in the user file
|
|
2402 */
|
|
2403 }
|
|
2404
|
|
2405 /**
|
|
2406 * @brief RCCEx Clock Recovery System SYNCWARN interrupt callback.
|
|
2407 * @retval none
|
|
2408 */
|
|
2409 __weak void HAL_RCCEx_CRS_SyncWarnCallback(void)
|
|
2410 {
|
|
2411 /* NOTE : This function should not be modified, when the callback is needed,
|
|
2412 the @ref HAL_RCCEx_CRS_SyncWarnCallback should be implemented in the user file
|
|
2413 */
|
|
2414 }
|
|
2415
|
|
2416 /**
|
|
2417 * @brief RCCEx Clock Recovery System Expected SYNC interrupt callback.
|
|
2418 * @retval none
|
|
2419 */
|
|
2420 __weak void HAL_RCCEx_CRS_ExpectedSyncCallback(void)
|
|
2421 {
|
|
2422 /* NOTE : This function should not be modified, when the callback is needed,
|
|
2423 the @ref HAL_RCCEx_CRS_ExpectedSyncCallback should be implemented in the user file
|
|
2424 */
|
|
2425 }
|
|
2426
|
|
2427 /**
|
|
2428 * @brief RCCEx Clock Recovery System Error interrupt callback.
|
|
2429 * @param Error Combination of Error status.
|
|
2430 * This parameter can be a combination of the following values:
|
|
2431 * @arg @ref RCC_CRS_SYNCERR
|
|
2432 * @arg @ref RCC_CRS_SYNCMISS
|
|
2433 * @arg @ref RCC_CRS_TRIMOVF
|
|
2434 * @retval none
|
|
2435 */
|
|
2436 __weak void HAL_RCCEx_CRS_ErrorCallback(uint32_t Error)
|
|
2437 {
|
|
2438 /* Prevent unused argument(s) compilation warning */
|
|
2439 UNUSED(Error);
|
|
2440
|
|
2441 /* NOTE : This function should not be modified, when the callback is needed,
|
|
2442 the @ref HAL_RCCEx_CRS_ErrorCallback should be implemented in the user file
|
|
2443 */
|
|
2444 }
|
|
2445
|
|
2446 /**
|
|
2447 * @}
|
|
2448 */
|
|
2449
|
|
2450 #endif /* CRS */
|
|
2451
|
|
2452 /**
|
|
2453 * @}
|
|
2454 */
|
|
2455
|
|
2456 /** @addtogroup RCCEx_Private_Functions
|
|
2457 * @{
|
|
2458 */
|
|
2459
|
|
2460 /**
|
|
2461 * @brief Configure the parameters N & P & optionally M of PLLSAI1 and enable PLLSAI1 output clock(s).
|
|
2462 * @param PllSai1 pointer to an RCC_PLLSAI1InitTypeDef structure that
|
|
2463 * contains the configuration parameters N & P & optionally M as well as PLLSAI1 output clock(s)
|
|
2464 * @param Divider divider parameter to be updated
|
|
2465 *
|
|
2466 * @note PLLSAI1 is temporary disable to apply new parameters
|
|
2467 *
|
|
2468 * @retval HAL status
|
|
2469 */
|
|
2470 static HAL_StatusTypeDef RCCEx_PLLSAI1_Config(RCC_PLLSAI1InitTypeDef *PllSai1, uint32_t Divider)
|
|
2471 {
|
|
2472 uint32_t tickstart = 0U;
|
|
2473 HAL_StatusTypeDef status = HAL_OK;
|
|
2474
|
|
2475 /* check for PLLSAI1 Parameters used to output PLLSAI1CLK */
|
|
2476 /* P, Q and R dividers are verified in each specific divider case below */
|
|
2477 assert_param(IS_RCC_PLLSAI1SOURCE(PllSai1->PLLSAI1Source));
|
|
2478 assert_param(IS_RCC_PLLSAI1M_VALUE(PllSai1->PLLSAI1M));
|
|
2479 assert_param(IS_RCC_PLLSAI1N_VALUE(PllSai1->PLLSAI1N));
|
|
2480 assert_param(IS_RCC_PLLSAI1CLOCKOUT_VALUE(PllSai1->PLLSAI1ClockOut));
|
|
2481
|
|
2482 /* Check that PLLSAI1 clock source and divider M can be applied */
|
|
2483 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE)
|
|
2484 {
|
|
2485 /* PLL clock source and divider M already set, check that no request for change */
|
|
2486 if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai1->PLLSAI1Source)
|
|
2487 ||
|
|
2488 (PllSai1->PLLSAI1Source == RCC_PLLSOURCE_NONE)
|
|
2489 ||
|
|
2490 (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U) != PllSai1->PLLSAI1M)
|
|
2491 )
|
|
2492 {
|
|
2493 status = HAL_ERROR;
|
|
2494 }
|
|
2495 }
|
|
2496 else
|
|
2497 {
|
|
2498 /* Check PLLSAI1 clock source availability */
|
|
2499 switch(PllSai1->PLLSAI1Source)
|
|
2500 {
|
|
2501 case RCC_PLLSOURCE_MSI:
|
|
2502 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
|
|
2503 {
|
|
2504 status = HAL_ERROR;
|
|
2505 }
|
|
2506 break;
|
|
2507 case RCC_PLLSOURCE_HSI:
|
|
2508 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
|
|
2509 {
|
|
2510 status = HAL_ERROR;
|
|
2511 }
|
|
2512 break;
|
|
2513 case RCC_PLLSOURCE_HSE:
|
|
2514 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY) && HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP))
|
|
2515 {
|
|
2516 status = HAL_ERROR;
|
|
2517 }
|
|
2518 break;
|
|
2519 default:
|
|
2520 status = HAL_ERROR;
|
|
2521 break;
|
|
2522 }
|
|
2523
|
|
2524 if(status == HAL_OK)
|
|
2525 {
|
|
2526 /* Set PLLSAI1 clock source and divider M */
|
|
2527 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai1->PLLSAI1Source | (PllSai1->PLLSAI1M - 1U) << POSITION_VAL(RCC_PLLCFGR_PLLM));
|
|
2528 }
|
|
2529 }
|
|
2530
|
|
2531 if(status == HAL_OK)
|
|
2532 {
|
|
2533 /* Disable the PLLSAI1 */
|
|
2534 __HAL_RCC_PLLSAI1_DISABLE();
|
|
2535
|
|
2536 /* Get Start Tick*/
|
|
2537 tickstart = HAL_GetTick();
|
|
2538
|
|
2539 /* Wait till PLLSAI1 is ready to be updated */
|
|
2540 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) != RESET)
|
|
2541 {
|
|
2542 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
|
2543 {
|
|
2544 status = HAL_TIMEOUT;
|
|
2545 break;
|
|
2546 }
|
|
2547 }
|
|
2548
|
|
2549 if(status == HAL_OK)
|
|
2550 {
|
|
2551 if(Divider == DIVIDER_P_UPDATE)
|
|
2552 {
|
|
2553 assert_param(IS_RCC_PLLSAI1P_VALUE(PllSai1->PLLSAI1P));
|
|
2554 /* Configure the PLLSAI1 Division factor P and Multiplication factor N*/
|
|
2555 #if defined(RCC_PLLSAI1P_DIV_2_31_SUPPORT)
|
|
2556 MODIFY_REG(RCC->PLLSAI1CFGR,
|
|
2557 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1PDIV,
|
|
2558 (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) |
|
|
2559 (PllSai1->PLLSAI1P << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1PDIV)));
|
|
2560 #else
|
|
2561 MODIFY_REG(RCC->PLLSAI1CFGR,
|
|
2562 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1P,
|
|
2563 (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) |
|
|
2564 ((PllSai1->PLLSAI1P >> 4U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1P)));
|
|
2565 #endif /* RCC_PLLSAI1P_DIV_2_31_SUPPORT */
|
|
2566 }
|
|
2567 else if(Divider == DIVIDER_Q_UPDATE)
|
|
2568 {
|
|
2569 assert_param(IS_RCC_PLLSAI1Q_VALUE(PllSai1->PLLSAI1Q));
|
|
2570 /* Configure the PLLSAI1 Division factor Q and Multiplication factor N*/
|
|
2571 MODIFY_REG(RCC->PLLSAI1CFGR,
|
|
2572 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1Q,
|
|
2573 (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) |
|
|
2574 (((PllSai1->PLLSAI1Q >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1Q)));
|
|
2575 }
|
|
2576 else
|
|
2577 {
|
|
2578 assert_param(IS_RCC_PLLSAI1R_VALUE(PllSai1->PLLSAI1R));
|
|
2579 /* Configure the PLLSAI1 Division factor R and Multiplication factor N*/
|
|
2580 MODIFY_REG(RCC->PLLSAI1CFGR,
|
|
2581 RCC_PLLSAI1CFGR_PLLSAI1N | RCC_PLLSAI1CFGR_PLLSAI1R,
|
|
2582 (PllSai1->PLLSAI1N << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1N)) |
|
|
2583 (((PllSai1->PLLSAI1R >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI1CFGR_PLLSAI1R)));
|
|
2584 }
|
|
2585
|
|
2586 /* Enable the PLLSAI1 again by setting PLLSAI1ON to 1*/
|
|
2587 __HAL_RCC_PLLSAI1_ENABLE();
|
|
2588
|
|
2589 /* Get Start Tick*/
|
|
2590 tickstart = HAL_GetTick();
|
|
2591
|
|
2592 /* Wait till PLLSAI1 is ready */
|
|
2593 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI1RDY) == RESET)
|
|
2594 {
|
|
2595 if((HAL_GetTick() - tickstart) > PLLSAI1_TIMEOUT_VALUE)
|
|
2596 {
|
|
2597 status = HAL_TIMEOUT;
|
|
2598 break;
|
|
2599 }
|
|
2600 }
|
|
2601
|
|
2602 if(status == HAL_OK)
|
|
2603 {
|
|
2604 /* Configure the PLLSAI1 Clock output(s) */
|
|
2605 __HAL_RCC_PLLSAI1CLKOUT_ENABLE(PllSai1->PLLSAI1ClockOut);
|
|
2606 }
|
|
2607 }
|
|
2608 }
|
|
2609
|
|
2610 return status;
|
|
2611 }
|
|
2612
|
|
2613 #if defined(RCC_PLLSAI2_SUPPORT)
|
|
2614
|
|
2615 /**
|
|
2616 * @brief Configure the parameters N & P & optionally M of PLLSAI2 and enable PLLSAI2 output clock(s).
|
|
2617 * @param PllSai2 pointer to an RCC_PLLSAI2InitTypeDef structure that
|
|
2618 * contains the configuration parameters N & P & optionally M as well as PLLSAI2 output clock(s)
|
|
2619 * @param Divider divider parameter to be updated
|
|
2620 *
|
|
2621 * @note PLLSAI2 is temporary disable to apply new parameters
|
|
2622 *
|
|
2623 * @retval HAL status
|
|
2624 */
|
|
2625 static HAL_StatusTypeDef RCCEx_PLLSAI2_Config(RCC_PLLSAI2InitTypeDef *PllSai2, uint32_t Divider)
|
|
2626 {
|
|
2627 uint32_t tickstart = 0U;
|
|
2628 HAL_StatusTypeDef status = HAL_OK;
|
|
2629
|
|
2630 /* check for PLLSAI2 Parameters used to output PLLSAI2CLK */
|
|
2631 /* P, Q and R dividers are verified in each specific divider case below */
|
|
2632 assert_param(IS_RCC_PLLSAI2SOURCE(PllSai2->PLLSAI2Source));
|
|
2633 assert_param(IS_RCC_PLLSAI2M_VALUE(PllSai2->PLLSAI2M));
|
|
2634 assert_param(IS_RCC_PLLSAI2N_VALUE(PllSai2->PLLSAI2N));
|
|
2635 assert_param(IS_RCC_PLLSAI2CLOCKOUT_VALUE(PllSai2->PLLSAI2ClockOut));
|
|
2636
|
|
2637 /* Check that PLLSAI2 clock source and divider M can be applied */
|
|
2638 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_NONE)
|
|
2639 {
|
|
2640 /* PLL clock source and divider M already set, check that no request for change */
|
|
2641 if((__HAL_RCC_GET_PLL_OSCSOURCE() != PllSai2->PLLSAI2Source)
|
|
2642 ||
|
|
2643 (PllSai2->PLLSAI2Source == RCC_PLLSOURCE_NONE)
|
|
2644 ||
|
|
2645 (((READ_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLM) >> POSITION_VAL(RCC_PLLCFGR_PLLM)) + 1U) != PllSai2->PLLSAI2M)
|
|
2646 )
|
|
2647 {
|
|
2648 status = HAL_ERROR;
|
|
2649 }
|
|
2650 }
|
|
2651 else
|
|
2652 {
|
|
2653 /* Check PLLSAI2 clock source availability */
|
|
2654 switch(PllSai2->PLLSAI2Source)
|
|
2655 {
|
|
2656 case RCC_PLLSOURCE_MSI:
|
|
2657 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_MSIRDY))
|
|
2658 {
|
|
2659 status = HAL_ERROR;
|
|
2660 }
|
|
2661 break;
|
|
2662 case RCC_PLLSOURCE_HSI:
|
|
2663 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSIRDY))
|
|
2664 {
|
|
2665 status = HAL_ERROR;
|
|
2666 }
|
|
2667 break;
|
|
2668 case RCC_PLLSOURCE_HSE:
|
|
2669 if(HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSERDY) && HAL_IS_BIT_CLR(RCC->CR, RCC_CR_HSEBYP))
|
|
2670 {
|
|
2671 status = HAL_ERROR;
|
|
2672 }
|
|
2673 break;
|
|
2674 default:
|
|
2675 status = HAL_ERROR;
|
|
2676 break;
|
|
2677 }
|
|
2678
|
|
2679 if(status == HAL_OK)
|
|
2680 {
|
|
2681 /* Set PLLSAI2 clock source and divider M */
|
|
2682 MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM, PllSai2->PLLSAI2Source | (PllSai2->PLLSAI2M - 1U) << POSITION_VAL(RCC_PLLCFGR_PLLM));
|
|
2683 }
|
|
2684 }
|
|
2685
|
|
2686 if(status == HAL_OK)
|
|
2687 {
|
|
2688 /* Disable the PLLSAI2 */
|
|
2689 __HAL_RCC_PLLSAI2_DISABLE();
|
|
2690
|
|
2691 /* Get Start Tick*/
|
|
2692 tickstart = HAL_GetTick();
|
|
2693
|
|
2694 /* Wait till PLLSAI2 is ready to be updated */
|
|
2695 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) != RESET)
|
|
2696 {
|
|
2697 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
|
2698 {
|
|
2699 status = HAL_TIMEOUT;
|
|
2700 break;
|
|
2701 }
|
|
2702 }
|
|
2703
|
|
2704 if(status == HAL_OK)
|
|
2705 {
|
|
2706 if(Divider == DIVIDER_P_UPDATE)
|
|
2707 {
|
|
2708 assert_param(IS_RCC_PLLSAI2P_VALUE(PllSai2->PLLSAI2P));
|
|
2709 /* Configure the PLLSAI2 Division factor P and Multiplication factor N*/
|
|
2710 MODIFY_REG(RCC->PLLSAI2CFGR,
|
|
2711 RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2P,
|
|
2712 (PllSai2->PLLSAI2N << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)) |
|
|
2713 ((PllSai2->PLLSAI2P >> 4U) << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2P)));
|
|
2714 }
|
|
2715 else
|
|
2716 {
|
|
2717 assert_param(IS_RCC_PLLSAI2R_VALUE(PllSai2->PLLSAI2R));
|
|
2718 /* Configure the PLLSAI2 Division factor R and Multiplication factor N*/
|
|
2719 MODIFY_REG(RCC->PLLSAI2CFGR,
|
|
2720 RCC_PLLSAI2CFGR_PLLSAI2N | RCC_PLLSAI2CFGR_PLLSAI2R,
|
|
2721 (PllSai2->PLLSAI2N << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2N)) |
|
|
2722 (((PllSai2->PLLSAI2R >> 1U) - 1U) << POSITION_VAL(RCC_PLLSAI2CFGR_PLLSAI2R)));
|
|
2723 }
|
|
2724
|
|
2725 /* Enable the PLLSAI2 again by setting PLLSAI2ON to 1*/
|
|
2726 __HAL_RCC_PLLSAI2_ENABLE();
|
|
2727
|
|
2728 /* Get Start Tick*/
|
|
2729 tickstart = HAL_GetTick();
|
|
2730
|
|
2731 /* Wait till PLLSAI2 is ready */
|
|
2732 while(READ_BIT(RCC->CR, RCC_CR_PLLSAI2RDY) == RESET)
|
|
2733 {
|
|
2734 if((HAL_GetTick() - tickstart) > PLLSAI2_TIMEOUT_VALUE)
|
|
2735 {
|
|
2736 status = HAL_TIMEOUT;
|
|
2737 break;
|
|
2738 }
|
|
2739 }
|
|
2740
|
|
2741 if(status == HAL_OK)
|
|
2742 {
|
|
2743 /* Configure the PLLSAI2 Clock output(s) */
|
|
2744 __HAL_RCC_PLLSAI2CLKOUT_ENABLE(PllSai2->PLLSAI2ClockOut);
|
|
2745 }
|
|
2746 }
|
|
2747 }
|
|
2748
|
|
2749 return status;
|
|
2750 }
|
|
2751
|
|
2752 #endif /* RCC_PLLSAI2_SUPPORT */
|
|
2753
|
|
2754 /**
|
|
2755 * @}
|
|
2756 */
|
|
2757
|
|
2758 /**
|
|
2759 * @}
|
|
2760 */
|
|
2761
|
|
2762 #endif /* HAL_RCC_MODULE_ENABLED */
|
|
2763 /**
|
|
2764 * @}
|
|
2765 */
|
|
2766
|
|
2767 /**
|
|
2768 * @}
|
|
2769 */
|
|
2770
|
|
2771 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
|
2772
|