Mercurial > public > ostc4
comparison Common/Drivers/STM32F4xx_HAL_Driver/Src/stm32f4xx_hal_rcc_ex.c @ 128:c78bcbd5deda FlipDisplay
Added current STM32 standandard libraries in version independend folder structure
author | Ideenmodellierer |
---|---|
date | Sun, 17 Feb 2019 21:12:22 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
127:1369f8660eaa | 128:c78bcbd5deda |
---|---|
1 /** | |
2 ****************************************************************************** | |
3 * @file stm32f4xx_hal_rcc_ex.c | |
4 * @author MCD Application Team | |
5 * @brief Extension RCC HAL module driver. | |
6 * This file provides firmware functions to manage the following | |
7 * functionalities RCC extension peripheral: | |
8 * + Extended Peripheral Control functions | |
9 * | |
10 ****************************************************************************** | |
11 * @attention | |
12 * | |
13 * <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> | |
14 * | |
15 * Redistribution and use in source and binary forms, with or without modification, | |
16 * are permitted provided that the following conditions are met: | |
17 * 1. Redistributions of source code must retain the above copyright notice, | |
18 * this list of conditions and the following disclaimer. | |
19 * 2. Redistributions in binary form must reproduce the above copyright notice, | |
20 * this list of conditions and the following disclaimer in the documentation | |
21 * and/or other materials provided with the distribution. | |
22 * 3. Neither the name of STMicroelectronics nor the names of its contributors | |
23 * may be used to endorse or promote products derived from this software | |
24 * without specific prior written permission. | |
25 * | |
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
27 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
29 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | |
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
32 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | |
33 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |
34 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
36 * | |
37 ****************************************************************************** | |
38 */ | |
39 | |
40 /* Includes ------------------------------------------------------------------*/ | |
41 #include "stm32f4xx_hal.h" | |
42 | |
43 /** @addtogroup STM32F4xx_HAL_Driver | |
44 * @{ | |
45 */ | |
46 | |
47 /** @defgroup RCCEx RCCEx | |
48 * @brief RCCEx HAL module driver | |
49 * @{ | |
50 */ | |
51 | |
52 #ifdef HAL_RCC_MODULE_ENABLED | |
53 | |
54 /* Private typedef -----------------------------------------------------------*/ | |
55 /* Private define ------------------------------------------------------------*/ | |
56 /** @addtogroup RCCEx_Private_Constants | |
57 * @{ | |
58 */ | |
59 /** | |
60 * @} | |
61 */ | |
62 /* Private macro -------------------------------------------------------------*/ | |
63 /* Private variables ---------------------------------------------------------*/ | |
64 /* Private function prototypes -----------------------------------------------*/ | |
65 /* Private functions ---------------------------------------------------------*/ | |
66 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions | |
67 * @{ | |
68 */ | |
69 | |
70 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions | |
71 * @brief Extended Peripheral Control functions | |
72 * | |
73 @verbatim | |
74 =============================================================================== | |
75 ##### Extended Peripheral Control functions ##### | |
76 =============================================================================== | |
77 [..] | |
78 This subsection provides a set of functions allowing to control the RCC Clocks | |
79 frequencies. | |
80 [..] | |
81 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to | |
82 select the RTC clock source; in this case the Backup domain will be reset in | |
83 order to modify the RTC Clock source, as consequence RTC registers (including | |
84 the backup registers) and RCC_BDCR register are set to their reset values. | |
85 | |
86 @endverbatim | |
87 * @{ | |
88 */ | |
89 | |
90 #if defined(STM32F446xx) | |
91 /** | |
92 * @brief Initializes the RCC extended peripherals clocks according to the specified | |
93 * parameters in the RCC_PeriphCLKInitTypeDef. | |
94 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
95 * contains the configuration information for the Extended Peripherals | |
96 * clocks(I2S, SAI, LTDC RTC and TIM). | |
97 * | |
98 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select | |
99 * the RTC clock source; in this case the Backup domain will be reset in | |
100 * order to modify the RTC Clock source, as consequence RTC registers (including | |
101 * the backup registers) and RCC_BDCR register are set to their reset values. | |
102 * | |
103 * @retval HAL status | |
104 */ | |
105 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
106 { | |
107 uint32_t tickstart = 0U; | |
108 uint32_t tmpreg1 = 0U; | |
109 uint32_t plli2sp = 0U; | |
110 uint32_t plli2sq = 0U; | |
111 uint32_t plli2sr = 0U; | |
112 uint32_t pllsaip = 0U; | |
113 uint32_t pllsaiq = 0U; | |
114 uint32_t plli2sused = 0U; | |
115 uint32_t pllsaiused = 0U; | |
116 | |
117 /* Check the peripheral clock selection parameters */ | |
118 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); | |
119 | |
120 /*------------------------ I2S APB1 configuration --------------------------*/ | |
121 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1)) | |
122 { | |
123 /* Check the parameters */ | |
124 assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection)); | |
125 | |
126 /* Configure I2S Clock source */ | |
127 __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection); | |
128 /* Enable the PLLI2S when it's used as clock source for I2S */ | |
129 if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S) | |
130 { | |
131 plli2sused = 1U; | |
132 } | |
133 } | |
134 /*--------------------------------------------------------------------------*/ | |
135 | |
136 /*---------------------------- I2S APB2 configuration ----------------------*/ | |
137 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2)) | |
138 { | |
139 /* Check the parameters */ | |
140 assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection)); | |
141 | |
142 /* Configure I2S Clock source */ | |
143 __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection); | |
144 /* Enable the PLLI2S when it's used as clock source for I2S */ | |
145 if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S) | |
146 { | |
147 plli2sused = 1U; | |
148 } | |
149 } | |
150 /*--------------------------------------------------------------------------*/ | |
151 | |
152 /*--------------------------- SAI1 configuration ---------------------------*/ | |
153 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == (RCC_PERIPHCLK_SAI1)) | |
154 { | |
155 /* Check the parameters */ | |
156 assert_param(IS_RCC_SAI1CLKSOURCE(PeriphClkInit->Sai1ClockSelection)); | |
157 | |
158 /* Configure SAI1 Clock source */ | |
159 __HAL_RCC_SAI1_CONFIG(PeriphClkInit->Sai1ClockSelection); | |
160 /* Enable the PLLI2S when it's used as clock source for SAI */ | |
161 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S) | |
162 { | |
163 plli2sused = 1U; | |
164 } | |
165 /* Enable the PLLSAI when it's used as clock source for SAI */ | |
166 if(PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI) | |
167 { | |
168 pllsaiused = 1U; | |
169 } | |
170 } | |
171 /*--------------------------------------------------------------------------*/ | |
172 | |
173 /*-------------------------- SAI2 configuration ----------------------------*/ | |
174 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == (RCC_PERIPHCLK_SAI2)) | |
175 { | |
176 /* Check the parameters */ | |
177 assert_param(IS_RCC_SAI2CLKSOURCE(PeriphClkInit->Sai2ClockSelection)); | |
178 | |
179 /* Configure SAI2 Clock source */ | |
180 __HAL_RCC_SAI2_CONFIG(PeriphClkInit->Sai2ClockSelection); | |
181 | |
182 /* Enable the PLLI2S when it's used as clock source for SAI */ | |
183 if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S) | |
184 { | |
185 plli2sused = 1U; | |
186 } | |
187 /* Enable the PLLSAI when it's used as clock source for SAI */ | |
188 if(PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI) | |
189 { | |
190 pllsaiused = 1U; | |
191 } | |
192 } | |
193 /*--------------------------------------------------------------------------*/ | |
194 | |
195 /*----------------------------- RTC configuration --------------------------*/ | |
196 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) | |
197 { | |
198 /* Check for RTC Parameters used to output RTCCLK */ | |
199 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); | |
200 | |
201 /* Enable Power Clock*/ | |
202 __HAL_RCC_PWR_CLK_ENABLE(); | |
203 | |
204 /* Enable write access to Backup domain */ | |
205 PWR->CR |= PWR_CR_DBP; | |
206 | |
207 /* Get tick */ | |
208 tickstart = HAL_GetTick(); | |
209 | |
210 while((PWR->CR & PWR_CR_DBP) == RESET) | |
211 { | |
212 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) | |
213 { | |
214 return HAL_TIMEOUT; | |
215 } | |
216 } | |
217 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ | |
218 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); | |
219 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) | |
220 { | |
221 /* Store the content of BDCR register before the reset of Backup Domain */ | |
222 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); | |
223 /* RTC Clock selection can be changed only if the Backup Domain is reset */ | |
224 __HAL_RCC_BACKUPRESET_FORCE(); | |
225 __HAL_RCC_BACKUPRESET_RELEASE(); | |
226 /* Restore the Content of BDCR register */ | |
227 RCC->BDCR = tmpreg1; | |
228 | |
229 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ | |
230 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) | |
231 { | |
232 /* Get tick */ | |
233 tickstart = HAL_GetTick(); | |
234 | |
235 /* Wait till LSE is ready */ | |
236 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) | |
237 { | |
238 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) | |
239 { | |
240 return HAL_TIMEOUT; | |
241 } | |
242 } | |
243 } | |
244 } | |
245 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); | |
246 } | |
247 /*--------------------------------------------------------------------------*/ | |
248 | |
249 /*---------------------------- TIM configuration ---------------------------*/ | |
250 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) | |
251 { | |
252 /* Configure Timer Prescaler */ | |
253 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); | |
254 } | |
255 /*--------------------------------------------------------------------------*/ | |
256 | |
257 /*---------------------------- FMPI2C1 Configuration -----------------------*/ | |
258 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1) | |
259 { | |
260 /* Check the parameters */ | |
261 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection)); | |
262 | |
263 /* Configure the FMPI2C1 clock source */ | |
264 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection); | |
265 } | |
266 /*--------------------------------------------------------------------------*/ | |
267 | |
268 /*------------------------------ CEC Configuration -------------------------*/ | |
269 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CEC) == RCC_PERIPHCLK_CEC) | |
270 { | |
271 /* Check the parameters */ | |
272 assert_param(IS_RCC_CECCLKSOURCE(PeriphClkInit->CecClockSelection)); | |
273 | |
274 /* Configure the CEC clock source */ | |
275 __HAL_RCC_CEC_CONFIG(PeriphClkInit->CecClockSelection); | |
276 } | |
277 /*--------------------------------------------------------------------------*/ | |
278 | |
279 /*----------------------------- CLK48 Configuration ------------------------*/ | |
280 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) | |
281 { | |
282 /* Check the parameters */ | |
283 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection)); | |
284 | |
285 /* Configure the CLK48 clock source */ | |
286 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection); | |
287 | |
288 /* Enable the PLLSAI when it's used as clock source for CLK48 */ | |
289 if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP) | |
290 { | |
291 pllsaiused = 1U; | |
292 } | |
293 } | |
294 /*--------------------------------------------------------------------------*/ | |
295 | |
296 /*----------------------------- SDIO Configuration -------------------------*/ | |
297 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) | |
298 { | |
299 /* Check the parameters */ | |
300 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection)); | |
301 | |
302 /* Configure the SDIO clock source */ | |
303 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection); | |
304 } | |
305 /*--------------------------------------------------------------------------*/ | |
306 | |
307 /*------------------------------ SPDIFRX Configuration ---------------------*/ | |
308 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) | |
309 { | |
310 /* Check the parameters */ | |
311 assert_param(IS_RCC_SPDIFRXCLKSOURCE(PeriphClkInit->SpdifClockSelection)); | |
312 | |
313 /* Configure the SPDIFRX clock source */ | |
314 __HAL_RCC_SPDIFRX_CONFIG(PeriphClkInit->SpdifClockSelection); | |
315 /* Enable the PLLI2S when it's used as clock source for SPDIFRX */ | |
316 if(PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP) | |
317 { | |
318 plli2sused = 1U; | |
319 } | |
320 } | |
321 /*--------------------------------------------------------------------------*/ | |
322 | |
323 /*---------------------------- PLLI2S Configuration ------------------------*/ | |
324 /* PLLI2S is configured when a peripheral will use it as source clock : SAI1, SAI2, I2S on APB1, | |
325 I2S on APB2 or SPDIFRX */ | |
326 if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S)) | |
327 { | |
328 /* Disable the PLLI2S */ | |
329 __HAL_RCC_PLLI2S_DISABLE(); | |
330 /* Get tick */ | |
331 tickstart = HAL_GetTick(); | |
332 /* Wait till PLLI2S is disabled */ | |
333 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) | |
334 { | |
335 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
336 { | |
337 /* return in case of Timeout detected */ | |
338 return HAL_TIMEOUT; | |
339 } | |
340 } | |
341 | |
342 /* check for common PLLI2S Parameters */ | |
343 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM)); | |
344 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); | |
345 | |
346 /*------ In Case of PLLI2S is selected as source clock for I2S -----------*/ | |
347 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) || | |
348 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S))) | |
349 { | |
350 /* check for Parameters */ | |
351 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
352 | |
353 /* Read PLLI2SP/PLLI2SQ value from PLLI2SCFGR register (this value is not needed for I2S configuration) */ | |
354 plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U); | |
355 plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); | |
356 /* Configure the PLLI2S division factors */ | |
357 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ | |
358 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ | |
359 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR); | |
360 } | |
361 | |
362 /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/ | |
363 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLI2S)) || | |
364 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLI2S))) | |
365 { | |
366 /* Check for PLLI2S Parameters */ | |
367 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); | |
368 /* Check for PLLI2S/DIVQ parameters */ | |
369 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ)); | |
370 | |
371 /* Read PLLI2SP/PLLI2SR value from PLLI2SCFGR register (this value is not needed for SAI configuration) */ | |
372 plli2sp = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U); | |
373 plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
374 /* Configure the PLLI2S division factors */ | |
375 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
376 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
377 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ | |
378 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , plli2sp, PeriphClkInit->PLLI2S.PLLI2SQ, plli2sr); | |
379 | |
380 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ | |
381 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ); | |
382 } | |
383 | |
384 /*------ In Case of PLLI2S is selected as source clock for SPDIFRX -------*/ | |
385 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SPDIFRX) == RCC_PERIPHCLK_SPDIFRX) && (PeriphClkInit->SpdifClockSelection == RCC_SPDIFRXCLKSOURCE_PLLI2SP)) | |
386 { | |
387 /* check for Parameters */ | |
388 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP)); | |
389 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */ | |
390 plli2sq = ((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U); | |
391 plli2sr = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
392 /* Configure the PLLI2S division factors */ | |
393 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ | |
394 /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */ | |
395 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, plli2sq, plli2sr); | |
396 } | |
397 | |
398 /*----------------- In Case of PLLI2S is just selected -----------------*/ | |
399 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S) | |
400 { | |
401 /* Check for Parameters */ | |
402 assert_param(IS_RCC_PLLI2SP_VALUE(PeriphClkInit->PLLI2S.PLLI2SP)); | |
403 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
404 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); | |
405 | |
406 /* Configure the PLLI2S division factors */ | |
407 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ | |
408 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SP, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); | |
409 } | |
410 | |
411 /* Enable the PLLI2S */ | |
412 __HAL_RCC_PLLI2S_ENABLE(); | |
413 /* Get tick */ | |
414 tickstart = HAL_GetTick(); | |
415 /* Wait till PLLI2S is ready */ | |
416 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) | |
417 { | |
418 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
419 { | |
420 /* return in case of Timeout detected */ | |
421 return HAL_TIMEOUT; | |
422 } | |
423 } | |
424 } | |
425 /*--------------------------------------------------------------------------*/ | |
426 | |
427 /*----------------------------- PLLSAI Configuration -----------------------*/ | |
428 /* PLLSAI is configured when a peripheral will use it as source clock : SAI1, SAI2, CLK48 or SDIO */ | |
429 if(pllsaiused == 1U) | |
430 { | |
431 /* Disable PLLSAI Clock */ | |
432 __HAL_RCC_PLLSAI_DISABLE(); | |
433 /* Get tick */ | |
434 tickstart = HAL_GetTick(); | |
435 /* Wait till PLLSAI is disabled */ | |
436 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) | |
437 { | |
438 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) | |
439 { | |
440 /* return in case of Timeout detected */ | |
441 return HAL_TIMEOUT; | |
442 } | |
443 } | |
444 | |
445 /* Check the PLLSAI division factors */ | |
446 assert_param(IS_RCC_PLLSAIM_VALUE(PeriphClkInit->PLLSAI.PLLSAIM)); | |
447 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN)); | |
448 | |
449 /*------ In Case of PLLSAI is selected as source clock for SAI -----------*/ | |
450 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI1) == RCC_PERIPHCLK_SAI1) && (PeriphClkInit->Sai1ClockSelection == RCC_SAI1CLKSOURCE_PLLSAI)) || | |
451 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI2) == RCC_PERIPHCLK_SAI2) && (PeriphClkInit->Sai2ClockSelection == RCC_SAI2CLKSOURCE_PLLSAI))) | |
452 { | |
453 /* check for PLLSAIQ Parameter */ | |
454 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ)); | |
455 /* check for PLLSAI/DIVQ Parameter */ | |
456 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ)); | |
457 | |
458 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */ | |
459 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U); | |
460 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ | |
461 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ | |
462 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ | |
463 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, 0U); | |
464 | |
465 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ | |
466 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ); | |
467 } | |
468 | |
469 /*------ In Case of PLLSAI is selected as source clock for CLK48 ---------*/ | |
470 /* In Case of PLLI2S is selected as source clock for CLK48 */ | |
471 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)) | |
472 { | |
473 /* check for Parameters */ | |
474 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP)); | |
475 /* Read PLLSAIQ value from PLLI2SCFGR register (this value is not need for SAI configuration) */ | |
476 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); | |
477 /* Configure the PLLSAI division factors */ | |
478 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLI2SN/PLLSAIM) */ | |
479 /* 48CLK = f(PLLSAI clock output) = f(VCO clock) / PLLSAIP */ | |
480 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIM, PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, 0U); | |
481 } | |
482 | |
483 /* Enable PLLSAI Clock */ | |
484 __HAL_RCC_PLLSAI_ENABLE(); | |
485 /* Get tick */ | |
486 tickstart = HAL_GetTick(); | |
487 /* Wait till PLLSAI is ready */ | |
488 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) | |
489 { | |
490 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) | |
491 { | |
492 /* return in case of Timeout detected */ | |
493 return HAL_TIMEOUT; | |
494 } | |
495 } | |
496 } | |
497 return HAL_OK; | |
498 } | |
499 | |
500 /** | |
501 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal | |
502 * RCC configuration registers. | |
503 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
504 * will be configured. | |
505 * @retval None | |
506 */ | |
507 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
508 { | |
509 uint32_t tempreg; | |
510 | |
511 /* Set all possible values for the extended clock type parameter------------*/ | |
512 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\ | |
513 RCC_PERIPHCLK_SAI1 | RCC_PERIPHCLK_SAI2 |\ | |
514 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ | |
515 RCC_PERIPHCLK_CEC | RCC_PERIPHCLK_FMPI2C1 |\ | |
516 RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO |\ | |
517 RCC_PERIPHCLK_SPDIFRX; | |
518 | |
519 /* Get the PLLI2S Clock configuration --------------------------------------*/ | |
520 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos); | |
521 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); | |
522 PeriphClkInit->PLLI2S.PLLI2SP = (uint32_t)((((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SP) >> RCC_PLLI2SCFGR_PLLI2SP_Pos) + 1U) << 1U); | |
523 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); | |
524 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
525 /* Get the PLLSAI Clock configuration --------------------------------------*/ | |
526 PeriphClkInit->PLLSAI.PLLSAIM = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM) >> RCC_PLLSAICFGR_PLLSAIM_Pos); | |
527 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos); | |
528 PeriphClkInit->PLLSAI.PLLSAIP = (uint32_t)((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U); | |
529 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); | |
530 /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/ | |
531 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos); | |
532 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos); | |
533 | |
534 /* Get the SAI1 clock configuration ----------------------------------------*/ | |
535 PeriphClkInit->Sai1ClockSelection = __HAL_RCC_GET_SAI1_SOURCE(); | |
536 | |
537 /* Get the SAI2 clock configuration ----------------------------------------*/ | |
538 PeriphClkInit->Sai2ClockSelection = __HAL_RCC_GET_SAI2_SOURCE(); | |
539 | |
540 /* Get the I2S APB1 clock configuration ------------------------------------*/ | |
541 PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE(); | |
542 | |
543 /* Get the I2S APB2 clock configuration ------------------------------------*/ | |
544 PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE(); | |
545 | |
546 /* Get the RTC Clock configuration -----------------------------------------*/ | |
547 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); | |
548 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); | |
549 | |
550 /* Get the CEC clock configuration -----------------------------------------*/ | |
551 PeriphClkInit->CecClockSelection = __HAL_RCC_GET_CEC_SOURCE(); | |
552 | |
553 /* Get the FMPI2C1 clock configuration -------------------------------------*/ | |
554 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE(); | |
555 | |
556 /* Get the CLK48 clock configuration ----------------------------------------*/ | |
557 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE(); | |
558 | |
559 /* Get the SDIO clock configuration ----------------------------------------*/ | |
560 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE(); | |
561 | |
562 /* Get the SPDIFRX clock configuration -------------------------------------*/ | |
563 PeriphClkInit->SpdifClockSelection = __HAL_RCC_GET_SPDIFRX_SOURCE(); | |
564 | |
565 /* Get the TIM Prescaler configuration -------------------------------------*/ | |
566 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) | |
567 { | |
568 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; | |
569 } | |
570 else | |
571 { | |
572 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; | |
573 } | |
574 } | |
575 | |
576 /** | |
577 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) | |
578 * @note Return 0 if peripheral clock identifier not managed by this API | |
579 * @param PeriphClk Peripheral clock identifier | |
580 * This parameter can be one of the following values: | |
581 * @arg RCC_PERIPHCLK_SAI1: SAI1 peripheral clock | |
582 * @arg RCC_PERIPHCLK_SAI2: SAI2 peripheral clock | |
583 * @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock | |
584 * @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock | |
585 * @retval Frequency in KHz | |
586 */ | |
587 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) | |
588 { | |
589 uint32_t tmpreg1 = 0U; | |
590 /* This variable used to store the SAI clock frequency (value in Hz) */ | |
591 uint32_t frequency = 0U; | |
592 /* This variable used to store the VCO Input (value in Hz) */ | |
593 uint32_t vcoinput = 0U; | |
594 /* This variable used to store the SAI clock source */ | |
595 uint32_t saiclocksource = 0U; | |
596 uint32_t srcclk = 0U; | |
597 /* This variable used to store the VCO Output (value in Hz) */ | |
598 uint32_t vcooutput = 0U; | |
599 switch (PeriphClk) | |
600 { | |
601 case RCC_PERIPHCLK_SAI1: | |
602 case RCC_PERIPHCLK_SAI2: | |
603 { | |
604 saiclocksource = RCC->DCKCFGR; | |
605 saiclocksource &= (RCC_DCKCFGR_SAI1SRC | RCC_DCKCFGR_SAI2SRC); | |
606 switch (saiclocksource) | |
607 { | |
608 case 0U: /* PLLSAI is the clock source for SAI*/ | |
609 { | |
610 /* Configure the PLLSAI division factor */ | |
611 /* PLLSAI_VCO Input = PLL_SOURCE/PLLSAIM */ | |
612 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) | |
613 { | |
614 /* In Case the PLL Source is HSI (Internal Clock) */ | |
615 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM)); | |
616 } | |
617 else | |
618 { | |
619 /* In Case the PLL Source is HSE (External Clock) */ | |
620 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIM))); | |
621 } | |
622 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ | |
623 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ | |
624 tmpreg1 = (RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> 24U; | |
625 frequency = (vcoinput * ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> 6U))/(tmpreg1); | |
626 | |
627 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ | |
628 tmpreg1 = (((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> 8U) + 1U); | |
629 frequency = frequency/(tmpreg1); | |
630 break; | |
631 } | |
632 case RCC_DCKCFGR_SAI1SRC_0: /* PLLI2S is the clock source for SAI*/ | |
633 case RCC_DCKCFGR_SAI2SRC_0: /* PLLI2S is the clock source for SAI*/ | |
634 { | |
635 /* Configure the PLLI2S division factor */ | |
636 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
637 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) | |
638 { | |
639 /* In Case the PLL Source is HSI (Internal Clock) */ | |
640 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
641 } | |
642 else | |
643 { | |
644 /* In Case the PLL Source is HSE (External Clock) */ | |
645 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM))); | |
646 } | |
647 | |
648 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
649 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ | |
650 tmpreg1 = (RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> 24U; | |
651 frequency = (vcoinput * ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U))/(tmpreg1); | |
652 | |
653 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ | |
654 tmpreg1 = ((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) + 1U); | |
655 frequency = frequency/(tmpreg1); | |
656 break; | |
657 } | |
658 case RCC_DCKCFGR_SAI1SRC_1: /* PLLR is the clock source for SAI*/ | |
659 case RCC_DCKCFGR_SAI2SRC_1: /* PLLR is the clock source for SAI*/ | |
660 { | |
661 /* Configure the PLLI2S division factor */ | |
662 /* PLL_VCO Input = PLL_SOURCE/PLLM */ | |
663 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) | |
664 { | |
665 /* In Case the PLL Source is HSI (Internal Clock) */ | |
666 vcoinput = (HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
667 } | |
668 else | |
669 { | |
670 /* In Case the PLL Source is HSE (External Clock) */ | |
671 vcoinput = ((HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM))); | |
672 } | |
673 | |
674 /* PLL_VCO Output = PLL_VCO Input * PLLN */ | |
675 /* SAI_CLK_x = PLL_VCO Output/PLLR */ | |
676 tmpreg1 = (RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U; | |
677 frequency = (vcoinput * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U))/(tmpreg1); | |
678 break; | |
679 } | |
680 case RCC_DCKCFGR_SAI1SRC: /* External clock is the clock source for SAI*/ | |
681 { | |
682 frequency = EXTERNAL_CLOCK_VALUE; | |
683 break; | |
684 } | |
685 case RCC_DCKCFGR_SAI2SRC: /* PLLSRC(HSE or HSI) is the clock source for SAI*/ | |
686 { | |
687 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSI) | |
688 { | |
689 /* In Case the PLL Source is HSI (Internal Clock) */ | |
690 frequency = (uint32_t)(HSI_VALUE); | |
691 } | |
692 else | |
693 { | |
694 /* In Case the PLL Source is HSE (External Clock) */ | |
695 frequency = (uint32_t)(HSE_VALUE); | |
696 } | |
697 break; | |
698 } | |
699 default : | |
700 { | |
701 break; | |
702 } | |
703 } | |
704 break; | |
705 } | |
706 case RCC_PERIPHCLK_I2S_APB1: | |
707 { | |
708 /* Get the current I2S source */ | |
709 srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE(); | |
710 switch (srcclk) | |
711 { | |
712 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ | |
713 case RCC_I2SAPB1CLKSOURCE_EXT: | |
714 { | |
715 /* Set the I2S clock to the external clock value */ | |
716 frequency = EXTERNAL_CLOCK_VALUE; | |
717 break; | |
718 } | |
719 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ | |
720 case RCC_I2SAPB1CLKSOURCE_PLLI2S: | |
721 { | |
722 /* Configure the PLLI2S division factor */ | |
723 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
724 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
725 { | |
726 /* Get the I2S source clock value */ | |
727 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
728 } | |
729 else | |
730 { | |
731 /* Get the I2S source clock value */ | |
732 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
733 } | |
734 | |
735 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
736 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); | |
737 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ | |
738 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); | |
739 break; | |
740 } | |
741 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ | |
742 case RCC_I2SAPB1CLKSOURCE_PLLR: | |
743 { | |
744 /* Configure the PLL division factor R */ | |
745 /* PLL_VCO Input = PLL_SOURCE/PLLM */ | |
746 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
747 { | |
748 /* Get the I2S source clock value */ | |
749 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
750 } | |
751 else | |
752 { | |
753 /* Get the I2S source clock value */ | |
754 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
755 } | |
756 | |
757 /* PLL_VCO Output = PLL_VCO Input * PLLN */ | |
758 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); | |
759 /* I2S_CLK = PLL_VCO Output/PLLR */ | |
760 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); | |
761 break; | |
762 } | |
763 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ | |
764 case RCC_I2SAPB1CLKSOURCE_PLLSRC: | |
765 { | |
766 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
767 { | |
768 frequency = HSE_VALUE; | |
769 } | |
770 else | |
771 { | |
772 frequency = HSI_VALUE; | |
773 } | |
774 break; | |
775 } | |
776 /* Clock not enabled for I2S*/ | |
777 default: | |
778 { | |
779 frequency = 0U; | |
780 break; | |
781 } | |
782 } | |
783 break; | |
784 } | |
785 case RCC_PERIPHCLK_I2S_APB2: | |
786 { | |
787 /* Get the current I2S source */ | |
788 srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE(); | |
789 switch (srcclk) | |
790 { | |
791 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ | |
792 case RCC_I2SAPB2CLKSOURCE_EXT: | |
793 { | |
794 /* Set the I2S clock to the external clock value */ | |
795 frequency = EXTERNAL_CLOCK_VALUE; | |
796 break; | |
797 } | |
798 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ | |
799 case RCC_I2SAPB2CLKSOURCE_PLLI2S: | |
800 { | |
801 /* Configure the PLLI2S division factor */ | |
802 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
803 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
804 { | |
805 /* Get the I2S source clock value */ | |
806 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
807 } | |
808 else | |
809 { | |
810 /* Get the I2S source clock value */ | |
811 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
812 } | |
813 | |
814 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
815 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); | |
816 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ | |
817 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); | |
818 break; | |
819 } | |
820 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ | |
821 case RCC_I2SAPB2CLKSOURCE_PLLR: | |
822 { | |
823 /* Configure the PLL division factor R */ | |
824 /* PLL_VCO Input = PLL_SOURCE/PLLM */ | |
825 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
826 { | |
827 /* Get the I2S source clock value */ | |
828 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
829 } | |
830 else | |
831 { | |
832 /* Get the I2S source clock value */ | |
833 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
834 } | |
835 | |
836 /* PLL_VCO Output = PLL_VCO Input * PLLN */ | |
837 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); | |
838 /* I2S_CLK = PLL_VCO Output/PLLR */ | |
839 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); | |
840 break; | |
841 } | |
842 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ | |
843 case RCC_I2SAPB2CLKSOURCE_PLLSRC: | |
844 { | |
845 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
846 { | |
847 frequency = HSE_VALUE; | |
848 } | |
849 else | |
850 { | |
851 frequency = HSI_VALUE; | |
852 } | |
853 break; | |
854 } | |
855 /* Clock not enabled for I2S*/ | |
856 default: | |
857 { | |
858 frequency = 0U; | |
859 break; | |
860 } | |
861 } | |
862 break; | |
863 } | |
864 } | |
865 return frequency; | |
866 } | |
867 #endif /* STM32F446xx */ | |
868 | |
869 #if defined(STM32F469xx) || defined(STM32F479xx) | |
870 /** | |
871 * @brief Initializes the RCC extended peripherals clocks according to the specified | |
872 * parameters in the RCC_PeriphCLKInitTypeDef. | |
873 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
874 * contains the configuration information for the Extended Peripherals | |
875 * clocks(I2S, SAI, LTDC, RTC and TIM). | |
876 * | |
877 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select | |
878 * the RTC clock source; in this case the Backup domain will be reset in | |
879 * order to modify the RTC Clock source, as consequence RTC registers (including | |
880 * the backup registers) and RCC_BDCR register are set to their reset values. | |
881 * | |
882 * @retval HAL status | |
883 */ | |
884 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
885 { | |
886 uint32_t tickstart = 0U; | |
887 uint32_t tmpreg1 = 0U; | |
888 uint32_t pllsaip = 0U; | |
889 uint32_t pllsaiq = 0U; | |
890 uint32_t pllsair = 0U; | |
891 | |
892 /* Check the parameters */ | |
893 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); | |
894 | |
895 /*--------------------------- CLK48 Configuration --------------------------*/ | |
896 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) | |
897 { | |
898 /* Check the parameters */ | |
899 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection)); | |
900 | |
901 /* Configure the CLK48 clock source */ | |
902 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection); | |
903 } | |
904 /*--------------------------------------------------------------------------*/ | |
905 | |
906 /*------------------------------ SDIO Configuration ------------------------*/ | |
907 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) | |
908 { | |
909 /* Check the parameters */ | |
910 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection)); | |
911 | |
912 /* Configure the SDIO clock source */ | |
913 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection); | |
914 } | |
915 /*--------------------------------------------------------------------------*/ | |
916 | |
917 /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/ | |
918 /*------------------- Common configuration SAI/I2S -------------------------*/ | |
919 /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division | |
920 factor is common parameters for both peripherals */ | |
921 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) || | |
922 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S) || | |
923 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)) | |
924 { | |
925 /* check for Parameters */ | |
926 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); | |
927 | |
928 /* Disable the PLLI2S */ | |
929 __HAL_RCC_PLLI2S_DISABLE(); | |
930 /* Get tick */ | |
931 tickstart = HAL_GetTick(); | |
932 /* Wait till PLLI2S is disabled */ | |
933 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) | |
934 { | |
935 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
936 { | |
937 /* return in case of Timeout detected */ | |
938 return HAL_TIMEOUT; | |
939 } | |
940 } | |
941 | |
942 /*---------------------- I2S configuration -------------------------------*/ | |
943 /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added | |
944 only for I2S configuration */ | |
945 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S)) | |
946 { | |
947 /* check for Parameters */ | |
948 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
949 /* Configure the PLLI2S division factors */ | |
950 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x (PLLI2SN/PLLM) */ | |
951 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ | |
952 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); | |
953 } | |
954 | |
955 /*---------------------------- SAI configuration -------------------------*/ | |
956 /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must | |
957 be added only for SAI configuration */ | |
958 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S)) | |
959 { | |
960 /* Check the PLLI2S division factors */ | |
961 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); | |
962 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ)); | |
963 | |
964 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */ | |
965 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
966 /* Configure the PLLI2S division factors */ | |
967 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ | |
968 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
969 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ | |
970 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1); | |
971 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ | |
972 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ); | |
973 } | |
974 | |
975 /*----------------- In Case of PLLI2S is just selected -----------------*/ | |
976 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S) | |
977 { | |
978 /* Check for Parameters */ | |
979 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); | |
980 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
981 | |
982 /* Configure the PLLI2S multiplication and division factors */ | |
983 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); | |
984 } | |
985 | |
986 /* Enable the PLLI2S */ | |
987 __HAL_RCC_PLLI2S_ENABLE(); | |
988 /* Get tick */ | |
989 tickstart = HAL_GetTick(); | |
990 /* Wait till PLLI2S is ready */ | |
991 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) | |
992 { | |
993 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
994 { | |
995 /* return in case of Timeout detected */ | |
996 return HAL_TIMEOUT; | |
997 } | |
998 } | |
999 } | |
1000 /*--------------------------------------------------------------------------*/ | |
1001 | |
1002 /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/ | |
1003 /*----------------------- Common configuration SAI/LTDC --------------------*/ | |
1004 /* In Case of SAI, LTDC or CLK48 Clock Configuration through PLLSAI, PLLSAIN division | |
1005 factor is common parameters for these peripherals */ | |
1006 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) || | |
1007 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC) || | |
1008 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && | |
1009 (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP))) | |
1010 { | |
1011 /* Check the PLLSAI division factors */ | |
1012 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN)); | |
1013 | |
1014 /* Disable PLLSAI Clock */ | |
1015 __HAL_RCC_PLLSAI_DISABLE(); | |
1016 /* Get tick */ | |
1017 tickstart = HAL_GetTick(); | |
1018 /* Wait till PLLSAI is disabled */ | |
1019 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) | |
1020 { | |
1021 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) | |
1022 { | |
1023 /* return in case of Timeout detected */ | |
1024 return HAL_TIMEOUT; | |
1025 } | |
1026 } | |
1027 | |
1028 /*---------------------------- SAI configuration -------------------------*/ | |
1029 /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must | |
1030 be added only for SAI configuration */ | |
1031 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI)) | |
1032 { | |
1033 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ)); | |
1034 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ)); | |
1035 | |
1036 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */ | |
1037 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U); | |
1038 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ | |
1039 pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); | |
1040 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ | |
1041 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ | |
1042 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ | |
1043 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, PeriphClkInit->PLLSAI.PLLSAIQ, pllsair); | |
1044 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ | |
1045 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ); | |
1046 } | |
1047 | |
1048 /*---------------------------- LTDC configuration ------------------------*/ | |
1049 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC)) | |
1050 { | |
1051 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR)); | |
1052 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR)); | |
1053 | |
1054 /* Read PLLSAIP value from PLLSAICFGR register (this value is not needed for SAI configuration) */ | |
1055 pllsaip = ((((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIP) >> RCC_PLLSAICFGR_PLLSAIP_Pos) + 1U) << 1U); | |
1056 /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */ | |
1057 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); | |
1058 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ | |
1059 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ | |
1060 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */ | |
1061 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, pllsaip, pllsaiq, PeriphClkInit->PLLSAI.PLLSAIR); | |
1062 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */ | |
1063 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR); | |
1064 } | |
1065 | |
1066 /*---------------------------- CLK48 configuration ------------------------*/ | |
1067 /* Configure the PLLSAI when it is used as clock source for CLK48 */ | |
1068 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == (RCC_PERIPHCLK_CLK48)) && | |
1069 (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLSAIP)) | |
1070 { | |
1071 assert_param(IS_RCC_PLLSAIP_VALUE(PeriphClkInit->PLLSAI.PLLSAIP)); | |
1072 | |
1073 /* Read PLLSAIQ value from PLLSAICFGR register (this value is not need for SAI configuration) */ | |
1074 pllsaiq = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); | |
1075 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ | |
1076 pllsair = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); | |
1077 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ | |
1078 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ | |
1079 /* CLK48_CLK(first level) = PLLSAI_VCO Output/PLLSAIP */ | |
1080 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN, PeriphClkInit->PLLSAI.PLLSAIP, pllsaiq, pllsair); | |
1081 } | |
1082 | |
1083 /* Enable PLLSAI Clock */ | |
1084 __HAL_RCC_PLLSAI_ENABLE(); | |
1085 /* Get tick */ | |
1086 tickstart = HAL_GetTick(); | |
1087 /* Wait till PLLSAI is ready */ | |
1088 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) | |
1089 { | |
1090 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) | |
1091 { | |
1092 /* return in case of Timeout detected */ | |
1093 return HAL_TIMEOUT; | |
1094 } | |
1095 } | |
1096 } | |
1097 | |
1098 /*--------------------------------------------------------------------------*/ | |
1099 | |
1100 /*---------------------------- RTC configuration ---------------------------*/ | |
1101 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) | |
1102 { | |
1103 /* Check for RTC Parameters used to output RTCCLK */ | |
1104 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); | |
1105 | |
1106 /* Enable Power Clock*/ | |
1107 __HAL_RCC_PWR_CLK_ENABLE(); | |
1108 | |
1109 /* Enable write access to Backup domain */ | |
1110 PWR->CR |= PWR_CR_DBP; | |
1111 | |
1112 /* Get tick */ | |
1113 tickstart = HAL_GetTick(); | |
1114 | |
1115 while((PWR->CR & PWR_CR_DBP) == RESET) | |
1116 { | |
1117 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) | |
1118 { | |
1119 return HAL_TIMEOUT; | |
1120 } | |
1121 } | |
1122 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ | |
1123 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); | |
1124 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) | |
1125 { | |
1126 /* Store the content of BDCR register before the reset of Backup Domain */ | |
1127 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); | |
1128 /* RTC Clock selection can be changed only if the Backup Domain is reset */ | |
1129 __HAL_RCC_BACKUPRESET_FORCE(); | |
1130 __HAL_RCC_BACKUPRESET_RELEASE(); | |
1131 /* Restore the Content of BDCR register */ | |
1132 RCC->BDCR = tmpreg1; | |
1133 | |
1134 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ | |
1135 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) | |
1136 { | |
1137 /* Get tick */ | |
1138 tickstart = HAL_GetTick(); | |
1139 | |
1140 /* Wait till LSE is ready */ | |
1141 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) | |
1142 { | |
1143 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) | |
1144 { | |
1145 return HAL_TIMEOUT; | |
1146 } | |
1147 } | |
1148 } | |
1149 } | |
1150 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); | |
1151 } | |
1152 /*--------------------------------------------------------------------------*/ | |
1153 | |
1154 /*---------------------------- TIM configuration ---------------------------*/ | |
1155 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) | |
1156 { | |
1157 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); | |
1158 } | |
1159 return HAL_OK; | |
1160 } | |
1161 | |
1162 /** | |
1163 * @brief Configures the RCC_PeriphCLKInitTypeDef according to the internal | |
1164 * RCC configuration registers. | |
1165 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
1166 * will be configured. | |
1167 * @retval None | |
1168 */ | |
1169 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
1170 { | |
1171 uint32_t tempreg; | |
1172 | |
1173 /* Set all possible values for the extended clock type parameter------------*/ | |
1174 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI |\ | |
1175 RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC |\ | |
1176 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ | |
1177 RCC_PERIPHCLK_CLK48 | RCC_PERIPHCLK_SDIO; | |
1178 | |
1179 /* Get the PLLI2S Clock configuration --------------------------------------*/ | |
1180 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); | |
1181 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
1182 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); | |
1183 /* Get the PLLSAI Clock configuration --------------------------------------*/ | |
1184 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos); | |
1185 PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); | |
1186 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); | |
1187 /* Get the PLLSAI/PLLI2S division factors ----------------------------------*/ | |
1188 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos); | |
1189 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos); | |
1190 PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR); | |
1191 /* Get the RTC Clock configuration -----------------------------------------*/ | |
1192 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); | |
1193 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); | |
1194 | |
1195 /* Get the CLK48 clock configuration -------------------------------------*/ | |
1196 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE(); | |
1197 | |
1198 /* Get the SDIO clock configuration ----------------------------------------*/ | |
1199 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE(); | |
1200 | |
1201 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) | |
1202 { | |
1203 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; | |
1204 } | |
1205 else | |
1206 { | |
1207 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; | |
1208 } | |
1209 } | |
1210 | |
1211 /** | |
1212 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) | |
1213 * @note Return 0 if peripheral clock identifier not managed by this API | |
1214 * @param PeriphClk Peripheral clock identifier | |
1215 * This parameter can be one of the following values: | |
1216 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock | |
1217 * @retval Frequency in KHz | |
1218 */ | |
1219 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) | |
1220 { | |
1221 /* This variable used to store the I2S clock frequency (value in Hz) */ | |
1222 uint32_t frequency = 0U; | |
1223 /* This variable used to store the VCO Input (value in Hz) */ | |
1224 uint32_t vcoinput = 0U; | |
1225 uint32_t srcclk = 0U; | |
1226 /* This variable used to store the VCO Output (value in Hz) */ | |
1227 uint32_t vcooutput = 0U; | |
1228 switch (PeriphClk) | |
1229 { | |
1230 case RCC_PERIPHCLK_I2S: | |
1231 { | |
1232 /* Get the current I2S source */ | |
1233 srcclk = __HAL_RCC_GET_I2S_SOURCE(); | |
1234 switch (srcclk) | |
1235 { | |
1236 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ | |
1237 case RCC_I2SCLKSOURCE_EXT: | |
1238 { | |
1239 /* Set the I2S clock to the external clock value */ | |
1240 frequency = EXTERNAL_CLOCK_VALUE; | |
1241 break; | |
1242 } | |
1243 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ | |
1244 case RCC_I2SCLKSOURCE_PLLI2S: | |
1245 { | |
1246 /* Configure the PLLI2S division factor */ | |
1247 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
1248 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
1249 { | |
1250 /* Get the I2S source clock value */ | |
1251 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
1252 } | |
1253 else | |
1254 { | |
1255 /* Get the I2S source clock value */ | |
1256 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
1257 } | |
1258 | |
1259 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
1260 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); | |
1261 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ | |
1262 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); | |
1263 break; | |
1264 } | |
1265 /* Clock not enabled for I2S*/ | |
1266 default: | |
1267 { | |
1268 frequency = 0U; | |
1269 break; | |
1270 } | |
1271 } | |
1272 break; | |
1273 } | |
1274 } | |
1275 return frequency; | |
1276 } | |
1277 #endif /* STM32F469xx || STM32F479xx */ | |
1278 | |
1279 #if defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) | |
1280 /** | |
1281 * @brief Initializes the RCC extended peripherals clocks according to the specified | |
1282 * parameters in the RCC_PeriphCLKInitTypeDef. | |
1283 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
1284 * contains the configuration information for the Extended Peripherals | |
1285 * clocks(I2S, LTDC RTC and TIM). | |
1286 * | |
1287 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select | |
1288 * the RTC clock source; in this case the Backup domain will be reset in | |
1289 * order to modify the RTC Clock source, as consequence RTC registers (including | |
1290 * the backup registers) and RCC_BDCR register are set to their reset values. | |
1291 * | |
1292 * @retval HAL status | |
1293 */ | |
1294 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
1295 { | |
1296 uint32_t tickstart = 0U; | |
1297 uint32_t tmpreg1 = 0U; | |
1298 #if defined(STM32F413xx) || defined(STM32F423xx) | |
1299 uint32_t plli2sq = 0U; | |
1300 #endif /* STM32F413xx || STM32F423xx */ | |
1301 uint32_t plli2sused = 0U; | |
1302 | |
1303 /* Check the peripheral clock selection parameters */ | |
1304 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); | |
1305 | |
1306 /*----------------------------------- I2S APB1 configuration ---------------*/ | |
1307 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == (RCC_PERIPHCLK_I2S_APB1)) | |
1308 { | |
1309 /* Check the parameters */ | |
1310 assert_param(IS_RCC_I2SAPB1CLKSOURCE(PeriphClkInit->I2sApb1ClockSelection)); | |
1311 | |
1312 /* Configure I2S Clock source */ | |
1313 __HAL_RCC_I2S_APB1_CONFIG(PeriphClkInit->I2sApb1ClockSelection); | |
1314 /* Enable the PLLI2S when it's used as clock source for I2S */ | |
1315 if(PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S) | |
1316 { | |
1317 plli2sused = 1U; | |
1318 } | |
1319 } | |
1320 /*--------------------------------------------------------------------------*/ | |
1321 | |
1322 /*----------------------------------- I2S APB2 configuration ---------------*/ | |
1323 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == (RCC_PERIPHCLK_I2S_APB2)) | |
1324 { | |
1325 /* Check the parameters */ | |
1326 assert_param(IS_RCC_I2SAPB2CLKSOURCE(PeriphClkInit->I2sApb2ClockSelection)); | |
1327 | |
1328 /* Configure I2S Clock source */ | |
1329 __HAL_RCC_I2S_APB2_CONFIG(PeriphClkInit->I2sApb2ClockSelection); | |
1330 /* Enable the PLLI2S when it's used as clock source for I2S */ | |
1331 if(PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S) | |
1332 { | |
1333 plli2sused = 1U; | |
1334 } | |
1335 } | |
1336 /*--------------------------------------------------------------------------*/ | |
1337 | |
1338 #if defined(STM32F413xx) || defined(STM32F423xx) | |
1339 /*----------------------- SAI1 Block A configuration -----------------------*/ | |
1340 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == (RCC_PERIPHCLK_SAIA)) | |
1341 { | |
1342 /* Check the parameters */ | |
1343 assert_param(IS_RCC_SAIACLKSOURCE(PeriphClkInit->SaiAClockSelection)); | |
1344 | |
1345 /* Configure SAI1 Clock source */ | |
1346 __HAL_RCC_SAI_BLOCKACLKSOURCE_CONFIG(PeriphClkInit->SaiAClockSelection); | |
1347 /* Enable the PLLI2S when it's used as clock source for SAI */ | |
1348 if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR) | |
1349 { | |
1350 plli2sused = 1U; | |
1351 } | |
1352 /* Enable the PLLSAI when it's used as clock source for SAI */ | |
1353 if(PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLR) | |
1354 { | |
1355 /* Check for PLL/DIVR parameters */ | |
1356 assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR)); | |
1357 | |
1358 /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */ | |
1359 __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR); | |
1360 } | |
1361 } | |
1362 /*--------------------------------------------------------------------------*/ | |
1363 | |
1364 /*---------------------- SAI1 Block B configuration ------------------------*/ | |
1365 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == (RCC_PERIPHCLK_SAIB)) | |
1366 { | |
1367 /* Check the parameters */ | |
1368 assert_param(IS_RCC_SAIBCLKSOURCE(PeriphClkInit->SaiBClockSelection)); | |
1369 | |
1370 /* Configure SAI1 Clock source */ | |
1371 __HAL_RCC_SAI_BLOCKBCLKSOURCE_CONFIG(PeriphClkInit->SaiBClockSelection); | |
1372 /* Enable the PLLI2S when it's used as clock source for SAI */ | |
1373 if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR) | |
1374 { | |
1375 plli2sused = 1U; | |
1376 } | |
1377 /* Enable the PLLSAI when it's used as clock source for SAI */ | |
1378 if(PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLR) | |
1379 { | |
1380 /* Check for PLL/DIVR parameters */ | |
1381 assert_param(IS_RCC_PLL_DIVR_VALUE(PeriphClkInit->PLLDivR)); | |
1382 | |
1383 /* SAI_CLK_x = SAI_CLK(first level)/PLLDIVR */ | |
1384 __HAL_RCC_PLL_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLDivR); | |
1385 } | |
1386 } | |
1387 /*--------------------------------------------------------------------------*/ | |
1388 #endif /* STM32F413xx || STM32F423xx */ | |
1389 | |
1390 /*------------------------------------ RTC configuration -------------------*/ | |
1391 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) | |
1392 { | |
1393 /* Check for RTC Parameters used to output RTCCLK */ | |
1394 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); | |
1395 | |
1396 /* Enable Power Clock*/ | |
1397 __HAL_RCC_PWR_CLK_ENABLE(); | |
1398 | |
1399 /* Enable write access to Backup domain */ | |
1400 PWR->CR |= PWR_CR_DBP; | |
1401 | |
1402 /* Get tick */ | |
1403 tickstart = HAL_GetTick(); | |
1404 | |
1405 while((PWR->CR & PWR_CR_DBP) == RESET) | |
1406 { | |
1407 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) | |
1408 { | |
1409 return HAL_TIMEOUT; | |
1410 } | |
1411 } | |
1412 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ | |
1413 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); | |
1414 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) | |
1415 { | |
1416 /* Store the content of BDCR register before the reset of Backup Domain */ | |
1417 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); | |
1418 /* RTC Clock selection can be changed only if the Backup Domain is reset */ | |
1419 __HAL_RCC_BACKUPRESET_FORCE(); | |
1420 __HAL_RCC_BACKUPRESET_RELEASE(); | |
1421 /* Restore the Content of BDCR register */ | |
1422 RCC->BDCR = tmpreg1; | |
1423 | |
1424 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ | |
1425 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) | |
1426 { | |
1427 /* Get tick */ | |
1428 tickstart = HAL_GetTick(); | |
1429 | |
1430 /* Wait till LSE is ready */ | |
1431 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) | |
1432 { | |
1433 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) | |
1434 { | |
1435 return HAL_TIMEOUT; | |
1436 } | |
1437 } | |
1438 } | |
1439 } | |
1440 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); | |
1441 } | |
1442 /*--------------------------------------------------------------------------*/ | |
1443 | |
1444 /*------------------------------------ TIM configuration -------------------*/ | |
1445 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) | |
1446 { | |
1447 /* Configure Timer Prescaler */ | |
1448 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); | |
1449 } | |
1450 /*--------------------------------------------------------------------------*/ | |
1451 | |
1452 /*------------------------------------- FMPI2C1 Configuration --------------*/ | |
1453 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1) | |
1454 { | |
1455 /* Check the parameters */ | |
1456 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection)); | |
1457 | |
1458 /* Configure the FMPI2C1 clock source */ | |
1459 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection); | |
1460 } | |
1461 /*--------------------------------------------------------------------------*/ | |
1462 | |
1463 /*------------------------------------- CLK48 Configuration ----------------*/ | |
1464 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) | |
1465 { | |
1466 /* Check the parameters */ | |
1467 assert_param(IS_RCC_CLK48CLKSOURCE(PeriphClkInit->Clk48ClockSelection)); | |
1468 | |
1469 /* Configure the SDIO clock source */ | |
1470 __HAL_RCC_CLK48_CONFIG(PeriphClkInit->Clk48ClockSelection); | |
1471 | |
1472 /* Enable the PLLI2S when it's used as clock source for CLK48 */ | |
1473 if(PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ) | |
1474 { | |
1475 plli2sused = 1U; | |
1476 } | |
1477 } | |
1478 /*--------------------------------------------------------------------------*/ | |
1479 | |
1480 /*------------------------------------- SDIO Configuration -----------------*/ | |
1481 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) | |
1482 { | |
1483 /* Check the parameters */ | |
1484 assert_param(IS_RCC_SDIOCLKSOURCE(PeriphClkInit->SdioClockSelection)); | |
1485 | |
1486 /* Configure the SDIO clock source */ | |
1487 __HAL_RCC_SDIO_CONFIG(PeriphClkInit->SdioClockSelection); | |
1488 } | |
1489 /*--------------------------------------------------------------------------*/ | |
1490 | |
1491 /*-------------------------------------- PLLI2S Configuration --------------*/ | |
1492 /* PLLI2S is configured when a peripheral will use it as source clock : I2S on APB1 or | |
1493 I2S on APB2*/ | |
1494 if((plli2sused == 1U) || (PeriphClkInit->PeriphClockSelection == RCC_PERIPHCLK_PLLI2S)) | |
1495 { | |
1496 /* Disable the PLLI2S */ | |
1497 __HAL_RCC_PLLI2S_DISABLE(); | |
1498 /* Get tick */ | |
1499 tickstart = HAL_GetTick(); | |
1500 /* Wait till PLLI2S is disabled */ | |
1501 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) | |
1502 { | |
1503 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
1504 { | |
1505 /* return in case of Timeout detected */ | |
1506 return HAL_TIMEOUT; | |
1507 } | |
1508 } | |
1509 | |
1510 /* check for common PLLI2S Parameters */ | |
1511 assert_param(IS_RCC_PLLI2SCLKSOURCE(PeriphClkInit->PLLI2SSelection)); | |
1512 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM)); | |
1513 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); | |
1514 /*-------------------- Set the PLL I2S clock -----------------------------*/ | |
1515 __HAL_RCC_PLL_I2S_CONFIG(PeriphClkInit->PLLI2SSelection); | |
1516 | |
1517 /*------- In Case of PLLI2S is selected as source clock for I2S ----------*/ | |
1518 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB1) == RCC_PERIPHCLK_I2S_APB1) && (PeriphClkInit->I2sApb1ClockSelection == RCC_I2SAPB1CLKSOURCE_PLLI2S)) || | |
1519 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S_APB2) == RCC_PERIPHCLK_I2S_APB2) && (PeriphClkInit->I2sApb2ClockSelection == RCC_I2SAPB2CLKSOURCE_PLLI2S)) || | |
1520 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_CLK48) == RCC_PERIPHCLK_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ)) || | |
1521 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SDIO) == RCC_PERIPHCLK_SDIO) && (PeriphClkInit->SdioClockSelection == RCC_SDIOCLKSOURCE_CLK48) && (PeriphClkInit->Clk48ClockSelection == RCC_CLK48CLKSOURCE_PLLI2SQ))) | |
1522 { | |
1523 /* check for Parameters */ | |
1524 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
1525 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); | |
1526 | |
1527 /* Configure the PLLI2S division factors */ | |
1528 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/ | |
1529 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ | |
1530 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); | |
1531 } | |
1532 | |
1533 #if defined(STM32F413xx) || defined(STM32F423xx) | |
1534 /*------- In Case of PLLI2S is selected as source clock for SAI ----------*/ | |
1535 if(((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIA) == RCC_PERIPHCLK_SAIA) && (PeriphClkInit->SaiAClockSelection == RCC_SAIACLKSOURCE_PLLI2SR)) || | |
1536 ((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAIB) == RCC_PERIPHCLK_SAIB) && (PeriphClkInit->SaiBClockSelection == RCC_SAIBCLKSOURCE_PLLI2SR))) | |
1537 { | |
1538 /* Check for PLLI2S Parameters */ | |
1539 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
1540 /* Check for PLLI2S/DIVR parameters */ | |
1541 assert_param(IS_RCC_PLLI2S_DIVR_VALUE(PeriphClkInit->PLLI2SDivR)); | |
1542 | |
1543 /* Read PLLI2SQ value from PLLI2SCFGR register (this value is not needed for SAI configuration) */ | |
1544 plli2sq = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); | |
1545 /* Configure the PLLI2S division factors */ | |
1546 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
1547 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
1548 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ | |
1549 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, plli2sq, PeriphClkInit->PLLI2S.PLLI2SR); | |
1550 | |
1551 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVR */ | |
1552 __HAL_RCC_PLLI2S_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLI2SDivR); | |
1553 } | |
1554 #endif /* STM32F413xx || STM32F423xx */ | |
1555 | |
1556 /*----------------- In Case of PLLI2S is just selected ------------------*/ | |
1557 if((PeriphClkInit->PeriphClockSelection & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S) | |
1558 { | |
1559 /* Check for Parameters */ | |
1560 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
1561 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); | |
1562 | |
1563 /* Configure the PLLI2S division factors */ | |
1564 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/ | |
1565 /* SPDIFRXCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SP */ | |
1566 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ, PeriphClkInit->PLLI2S.PLLI2SR); | |
1567 } | |
1568 | |
1569 /* Enable the PLLI2S */ | |
1570 __HAL_RCC_PLLI2S_ENABLE(); | |
1571 /* Get tick */ | |
1572 tickstart = HAL_GetTick(); | |
1573 /* Wait till PLLI2S is ready */ | |
1574 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) | |
1575 { | |
1576 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
1577 { | |
1578 /* return in case of Timeout detected */ | |
1579 return HAL_TIMEOUT; | |
1580 } | |
1581 } | |
1582 } | |
1583 /*--------------------------------------------------------------------------*/ | |
1584 | |
1585 /*-------------------- DFSDM1 clock source configuration -------------------*/ | |
1586 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1) == RCC_PERIPHCLK_DFSDM1) | |
1587 { | |
1588 /* Check the parameters */ | |
1589 assert_param(IS_RCC_DFSDM1CLKSOURCE(PeriphClkInit->Dfsdm1ClockSelection)); | |
1590 | |
1591 /* Configure the DFSDM1 interface clock source */ | |
1592 __HAL_RCC_DFSDM1_CONFIG(PeriphClkInit->Dfsdm1ClockSelection); | |
1593 } | |
1594 /*--------------------------------------------------------------------------*/ | |
1595 | |
1596 /*-------------------- DFSDM1 Audio clock source configuration -------------*/ | |
1597 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM1_AUDIO) == RCC_PERIPHCLK_DFSDM1_AUDIO) | |
1598 { | |
1599 /* Check the parameters */ | |
1600 assert_param(IS_RCC_DFSDM1AUDIOCLKSOURCE(PeriphClkInit->Dfsdm1AudioClockSelection)); | |
1601 | |
1602 /* Configure the DFSDM1 Audio interface clock source */ | |
1603 __HAL_RCC_DFSDM1AUDIO_CONFIG(PeriphClkInit->Dfsdm1AudioClockSelection); | |
1604 } | |
1605 /*--------------------------------------------------------------------------*/ | |
1606 | |
1607 #if defined(STM32F413xx) || defined(STM32F423xx) | |
1608 /*-------------------- DFSDM2 clock source configuration -------------------*/ | |
1609 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2) == RCC_PERIPHCLK_DFSDM2) | |
1610 { | |
1611 /* Check the parameters */ | |
1612 assert_param(IS_RCC_DFSDM2CLKSOURCE(PeriphClkInit->Dfsdm2ClockSelection)); | |
1613 | |
1614 /* Configure the DFSDM1 interface clock source */ | |
1615 __HAL_RCC_DFSDM2_CONFIG(PeriphClkInit->Dfsdm2ClockSelection); | |
1616 } | |
1617 /*--------------------------------------------------------------------------*/ | |
1618 | |
1619 /*-------------------- DFSDM2 Audio clock source configuration -------------*/ | |
1620 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_DFSDM2_AUDIO) == RCC_PERIPHCLK_DFSDM2_AUDIO) | |
1621 { | |
1622 /* Check the parameters */ | |
1623 assert_param(IS_RCC_DFSDM2AUDIOCLKSOURCE(PeriphClkInit->Dfsdm2AudioClockSelection)); | |
1624 | |
1625 /* Configure the DFSDM1 Audio interface clock source */ | |
1626 __HAL_RCC_DFSDM2AUDIO_CONFIG(PeriphClkInit->Dfsdm2AudioClockSelection); | |
1627 } | |
1628 /*--------------------------------------------------------------------------*/ | |
1629 | |
1630 /*---------------------------- LPTIM1 Configuration ------------------------*/ | |
1631 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1) | |
1632 { | |
1633 /* Check the parameters */ | |
1634 assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection)); | |
1635 | |
1636 /* Configure the LPTIM1 clock source */ | |
1637 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection); | |
1638 } | |
1639 /*--------------------------------------------------------------------------*/ | |
1640 #endif /* STM32F413xx || STM32F423xx */ | |
1641 | |
1642 return HAL_OK; | |
1643 } | |
1644 | |
1645 /** | |
1646 * @brief Get the RCC_PeriphCLKInitTypeDef according to the internal | |
1647 * RCC configuration registers. | |
1648 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
1649 * will be configured. | |
1650 * @retval None | |
1651 */ | |
1652 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
1653 { | |
1654 uint32_t tempreg; | |
1655 | |
1656 /* Set all possible values for the extended clock type parameter------------*/ | |
1657 #if defined(STM32F413xx) || defined(STM32F423xx) | |
1658 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\ | |
1659 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ | |
1660 RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 |\ | |
1661 RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 |\ | |
1662 RCC_PERIPHCLK_DFSDM1_AUDIO | RCC_PERIPHCLK_DFSDM2 |\ | |
1663 RCC_PERIPHCLK_DFSDM2_AUDIO | RCC_PERIPHCLK_LPTIM1 |\ | |
1664 RCC_PERIPHCLK_SAIA | RCC_PERIPHCLK_SAIB; | |
1665 #else /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx */ | |
1666 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S_APB1 | RCC_PERIPHCLK_I2S_APB2 |\ | |
1667 RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC |\ | |
1668 RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_CLK48 |\ | |
1669 RCC_PERIPHCLK_SDIO | RCC_PERIPHCLK_DFSDM1 |\ | |
1670 RCC_PERIPHCLK_DFSDM1_AUDIO; | |
1671 #endif /* STM32F413xx || STM32F423xx */ | |
1672 | |
1673 | |
1674 | |
1675 /* Get the PLLI2S Clock configuration --------------------------------------*/ | |
1676 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM) >> RCC_PLLI2SCFGR_PLLI2SM_Pos); | |
1677 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); | |
1678 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); | |
1679 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
1680 #if defined(STM32F413xx) || defined(STM32F423xx) | |
1681 /* Get the PLL/PLLI2S division factors -------------------------------------*/ | |
1682 PeriphClkInit->PLLI2SDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVR) >> RCC_DCKCFGR_PLLI2SDIVR_Pos); | |
1683 PeriphClkInit->PLLDivR = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLDIVR) >> RCC_DCKCFGR_PLLDIVR_Pos); | |
1684 #endif /* STM32F413xx || STM32F423xx */ | |
1685 | |
1686 /* Get the I2S APB1 clock configuration ------------------------------------*/ | |
1687 PeriphClkInit->I2sApb1ClockSelection = __HAL_RCC_GET_I2S_APB1_SOURCE(); | |
1688 | |
1689 /* Get the I2S APB2 clock configuration ------------------------------------*/ | |
1690 PeriphClkInit->I2sApb2ClockSelection = __HAL_RCC_GET_I2S_APB2_SOURCE(); | |
1691 | |
1692 /* Get the RTC Clock configuration -----------------------------------------*/ | |
1693 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); | |
1694 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); | |
1695 | |
1696 /* Get the FMPI2C1 clock configuration -------------------------------------*/ | |
1697 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE(); | |
1698 | |
1699 /* Get the CLK48 clock configuration ---------------------------------------*/ | |
1700 PeriphClkInit->Clk48ClockSelection = __HAL_RCC_GET_CLK48_SOURCE(); | |
1701 | |
1702 /* Get the SDIO clock configuration ----------------------------------------*/ | |
1703 PeriphClkInit->SdioClockSelection = __HAL_RCC_GET_SDIO_SOURCE(); | |
1704 | |
1705 /* Get the DFSDM1 clock configuration --------------------------------------*/ | |
1706 PeriphClkInit->Dfsdm1ClockSelection = __HAL_RCC_GET_DFSDM1_SOURCE(); | |
1707 | |
1708 /* Get the DFSDM1 Audio clock configuration --------------------------------*/ | |
1709 PeriphClkInit->Dfsdm1AudioClockSelection = __HAL_RCC_GET_DFSDM1AUDIO_SOURCE(); | |
1710 | |
1711 #if defined(STM32F413xx) || defined(STM32F423xx) | |
1712 /* Get the DFSDM2 clock configuration --------------------------------------*/ | |
1713 PeriphClkInit->Dfsdm2ClockSelection = __HAL_RCC_GET_DFSDM2_SOURCE(); | |
1714 | |
1715 /* Get the DFSDM2 Audio clock configuration --------------------------------*/ | |
1716 PeriphClkInit->Dfsdm2AudioClockSelection = __HAL_RCC_GET_DFSDM2AUDIO_SOURCE(); | |
1717 | |
1718 /* Get the LPTIM1 clock configuration --------------------------------------*/ | |
1719 PeriphClkInit->Lptim1ClockSelection = __HAL_RCC_GET_LPTIM1_SOURCE(); | |
1720 | |
1721 /* Get the SAI1 Block Aclock configuration ---------------------------------*/ | |
1722 PeriphClkInit->SaiAClockSelection = __HAL_RCC_GET_SAI_BLOCKA_SOURCE(); | |
1723 | |
1724 /* Get the SAI1 Block B clock configuration --------------------------------*/ | |
1725 PeriphClkInit->SaiBClockSelection = __HAL_RCC_GET_SAI_BLOCKB_SOURCE(); | |
1726 #endif /* STM32F413xx || STM32F423xx */ | |
1727 | |
1728 /* Get the TIM Prescaler configuration -------------------------------------*/ | |
1729 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) | |
1730 { | |
1731 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; | |
1732 } | |
1733 else | |
1734 { | |
1735 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; | |
1736 } | |
1737 } | |
1738 | |
1739 /** | |
1740 * @brief Return the peripheral clock frequency for a given peripheral(I2S..) | |
1741 * @note Return 0 if peripheral clock identifier not managed by this API | |
1742 * @param PeriphClk Peripheral clock identifier | |
1743 * This parameter can be one of the following values: | |
1744 * @arg RCC_PERIPHCLK_I2S_APB1: I2S APB1 peripheral clock | |
1745 * @arg RCC_PERIPHCLK_I2S_APB2: I2S APB2 peripheral clock | |
1746 * @retval Frequency in KHz | |
1747 */ | |
1748 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) | |
1749 { | |
1750 /* This variable used to store the I2S clock frequency (value in Hz) */ | |
1751 uint32_t frequency = 0U; | |
1752 /* This variable used to store the VCO Input (value in Hz) */ | |
1753 uint32_t vcoinput = 0U; | |
1754 uint32_t srcclk = 0U; | |
1755 /* This variable used to store the VCO Output (value in Hz) */ | |
1756 uint32_t vcooutput = 0U; | |
1757 switch (PeriphClk) | |
1758 { | |
1759 case RCC_PERIPHCLK_I2S_APB1: | |
1760 { | |
1761 /* Get the current I2S source */ | |
1762 srcclk = __HAL_RCC_GET_I2S_APB1_SOURCE(); | |
1763 switch (srcclk) | |
1764 { | |
1765 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ | |
1766 case RCC_I2SAPB1CLKSOURCE_EXT: | |
1767 { | |
1768 /* Set the I2S clock to the external clock value */ | |
1769 frequency = EXTERNAL_CLOCK_VALUE; | |
1770 break; | |
1771 } | |
1772 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ | |
1773 case RCC_I2SAPB1CLKSOURCE_PLLI2S: | |
1774 { | |
1775 if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC) | |
1776 { | |
1777 /* Get the I2S source clock value */ | |
1778 vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
1779 } | |
1780 else | |
1781 { | |
1782 /* Configure the PLLI2S division factor */ | |
1783 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
1784 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
1785 { | |
1786 /* Get the I2S source clock value */ | |
1787 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
1788 } | |
1789 else | |
1790 { | |
1791 /* Get the I2S source clock value */ | |
1792 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
1793 } | |
1794 } | |
1795 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
1796 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); | |
1797 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ | |
1798 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); | |
1799 break; | |
1800 } | |
1801 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ | |
1802 case RCC_I2SAPB1CLKSOURCE_PLLR: | |
1803 { | |
1804 /* Configure the PLL division factor R */ | |
1805 /* PLL_VCO Input = PLL_SOURCE/PLLM */ | |
1806 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
1807 { | |
1808 /* Get the I2S source clock value */ | |
1809 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
1810 } | |
1811 else | |
1812 { | |
1813 /* Get the I2S source clock value */ | |
1814 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
1815 } | |
1816 | |
1817 /* PLL_VCO Output = PLL_VCO Input * PLLN */ | |
1818 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); | |
1819 /* I2S_CLK = PLL_VCO Output/PLLR */ | |
1820 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); | |
1821 break; | |
1822 } | |
1823 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ | |
1824 case RCC_I2SAPB1CLKSOURCE_PLLSRC: | |
1825 { | |
1826 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
1827 { | |
1828 frequency = HSE_VALUE; | |
1829 } | |
1830 else | |
1831 { | |
1832 frequency = HSI_VALUE; | |
1833 } | |
1834 break; | |
1835 } | |
1836 /* Clock not enabled for I2S*/ | |
1837 default: | |
1838 { | |
1839 frequency = 0U; | |
1840 break; | |
1841 } | |
1842 } | |
1843 break; | |
1844 } | |
1845 case RCC_PERIPHCLK_I2S_APB2: | |
1846 { | |
1847 /* Get the current I2S source */ | |
1848 srcclk = __HAL_RCC_GET_I2S_APB2_SOURCE(); | |
1849 switch (srcclk) | |
1850 { | |
1851 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ | |
1852 case RCC_I2SAPB2CLKSOURCE_EXT: | |
1853 { | |
1854 /* Set the I2S clock to the external clock value */ | |
1855 frequency = EXTERNAL_CLOCK_VALUE; | |
1856 break; | |
1857 } | |
1858 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ | |
1859 case RCC_I2SAPB2CLKSOURCE_PLLI2S: | |
1860 { | |
1861 if((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SSRC) == RCC_PLLI2SCFGR_PLLI2SSRC) | |
1862 { | |
1863 /* Get the I2S source clock value */ | |
1864 vcoinput = (uint32_t)(EXTERNAL_CLOCK_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
1865 } | |
1866 else | |
1867 { | |
1868 /* Configure the PLLI2S division factor */ | |
1869 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
1870 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
1871 { | |
1872 /* Get the I2S source clock value */ | |
1873 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
1874 } | |
1875 else | |
1876 { | |
1877 /* Get the I2S source clock value */ | |
1878 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
1879 } | |
1880 } | |
1881 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
1882 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); | |
1883 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ | |
1884 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); | |
1885 break; | |
1886 } | |
1887 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ | |
1888 case RCC_I2SAPB2CLKSOURCE_PLLR: | |
1889 { | |
1890 /* Configure the PLL division factor R */ | |
1891 /* PLL_VCO Input = PLL_SOURCE/PLLM */ | |
1892 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
1893 { | |
1894 /* Get the I2S source clock value */ | |
1895 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
1896 } | |
1897 else | |
1898 { | |
1899 /* Get the I2S source clock value */ | |
1900 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
1901 } | |
1902 | |
1903 /* PLL_VCO Output = PLL_VCO Input * PLLN */ | |
1904 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); | |
1905 /* I2S_CLK = PLL_VCO Output/PLLR */ | |
1906 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); | |
1907 break; | |
1908 } | |
1909 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ | |
1910 case RCC_I2SAPB2CLKSOURCE_PLLSRC: | |
1911 { | |
1912 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
1913 { | |
1914 frequency = HSE_VALUE; | |
1915 } | |
1916 else | |
1917 { | |
1918 frequency = HSI_VALUE; | |
1919 } | |
1920 break; | |
1921 } | |
1922 /* Clock not enabled for I2S*/ | |
1923 default: | |
1924 { | |
1925 frequency = 0U; | |
1926 break; | |
1927 } | |
1928 } | |
1929 break; | |
1930 } | |
1931 } | |
1932 return frequency; | |
1933 } | |
1934 #endif /* STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ | |
1935 | |
1936 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) | |
1937 /** | |
1938 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the | |
1939 * RCC_PeriphCLKInitTypeDef. | |
1940 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
1941 * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks). | |
1942 * | |
1943 * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case | |
1944 * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup | |
1945 * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset | |
1946 * | |
1947 * @retval HAL status | |
1948 */ | |
1949 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
1950 { | |
1951 uint32_t tickstart = 0U; | |
1952 uint32_t tmpreg1 = 0U; | |
1953 | |
1954 /* Check the parameters */ | |
1955 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); | |
1956 | |
1957 /*---------------------------- RTC configuration ---------------------------*/ | |
1958 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) | |
1959 { | |
1960 /* Check for RTC Parameters used to output RTCCLK */ | |
1961 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); | |
1962 | |
1963 /* Enable Power Clock*/ | |
1964 __HAL_RCC_PWR_CLK_ENABLE(); | |
1965 | |
1966 /* Enable write access to Backup domain */ | |
1967 PWR->CR |= PWR_CR_DBP; | |
1968 | |
1969 /* Get tick */ | |
1970 tickstart = HAL_GetTick(); | |
1971 | |
1972 while((PWR->CR & PWR_CR_DBP) == RESET) | |
1973 { | |
1974 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) | |
1975 { | |
1976 return HAL_TIMEOUT; | |
1977 } | |
1978 } | |
1979 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ | |
1980 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); | |
1981 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) | |
1982 { | |
1983 /* Store the content of BDCR register before the reset of Backup Domain */ | |
1984 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); | |
1985 /* RTC Clock selection can be changed only if the Backup Domain is reset */ | |
1986 __HAL_RCC_BACKUPRESET_FORCE(); | |
1987 __HAL_RCC_BACKUPRESET_RELEASE(); | |
1988 /* Restore the Content of BDCR register */ | |
1989 RCC->BDCR = tmpreg1; | |
1990 | |
1991 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ | |
1992 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) | |
1993 { | |
1994 /* Get tick */ | |
1995 tickstart = HAL_GetTick(); | |
1996 | |
1997 /* Wait till LSE is ready */ | |
1998 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) | |
1999 { | |
2000 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) | |
2001 { | |
2002 return HAL_TIMEOUT; | |
2003 } | |
2004 } | |
2005 } | |
2006 } | |
2007 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); | |
2008 } | |
2009 /*--------------------------------------------------------------------------*/ | |
2010 | |
2011 /*---------------------------- TIM configuration ---------------------------*/ | |
2012 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) | |
2013 { | |
2014 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); | |
2015 } | |
2016 /*--------------------------------------------------------------------------*/ | |
2017 | |
2018 /*---------------------------- FMPI2C1 Configuration -----------------------*/ | |
2019 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_FMPI2C1) == RCC_PERIPHCLK_FMPI2C1) | |
2020 { | |
2021 /* Check the parameters */ | |
2022 assert_param(IS_RCC_FMPI2C1CLKSOURCE(PeriphClkInit->Fmpi2c1ClockSelection)); | |
2023 | |
2024 /* Configure the FMPI2C1 clock source */ | |
2025 __HAL_RCC_FMPI2C1_CONFIG(PeriphClkInit->Fmpi2c1ClockSelection); | |
2026 } | |
2027 /*--------------------------------------------------------------------------*/ | |
2028 | |
2029 /*---------------------------- LPTIM1 Configuration ------------------------*/ | |
2030 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LPTIM1) == RCC_PERIPHCLK_LPTIM1) | |
2031 { | |
2032 /* Check the parameters */ | |
2033 assert_param(IS_RCC_LPTIM1CLKSOURCE(PeriphClkInit->Lptim1ClockSelection)); | |
2034 | |
2035 /* Configure the LPTIM1 clock source */ | |
2036 __HAL_RCC_LPTIM1_CONFIG(PeriphClkInit->Lptim1ClockSelection); | |
2037 } | |
2038 | |
2039 /*---------------------------- I2S Configuration ---------------------------*/ | |
2040 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) | |
2041 { | |
2042 /* Check the parameters */ | |
2043 assert_param(IS_RCC_I2SAPBCLKSOURCE(PeriphClkInit->I2SClockSelection)); | |
2044 | |
2045 /* Configure the I2S clock source */ | |
2046 __HAL_RCC_I2S_CONFIG(PeriphClkInit->I2SClockSelection); | |
2047 } | |
2048 | |
2049 return HAL_OK; | |
2050 } | |
2051 | |
2052 /** | |
2053 * @brief Configures the RCC_OscInitStruct according to the internal | |
2054 * RCC configuration registers. | |
2055 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
2056 * will be configured. | |
2057 * @retval None | |
2058 */ | |
2059 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
2060 { | |
2061 uint32_t tempreg; | |
2062 | |
2063 /* Set all possible values for the extended clock type parameter------------*/ | |
2064 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_FMPI2C1 | RCC_PERIPHCLK_LPTIM1 | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC; | |
2065 | |
2066 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); | |
2067 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); | |
2068 | |
2069 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) | |
2070 { | |
2071 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; | |
2072 } | |
2073 else | |
2074 { | |
2075 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; | |
2076 } | |
2077 /* Get the FMPI2C1 clock configuration -------------------------------------*/ | |
2078 PeriphClkInit->Fmpi2c1ClockSelection = __HAL_RCC_GET_FMPI2C1_SOURCE(); | |
2079 | |
2080 /* Get the I2S clock configuration -----------------------------------------*/ | |
2081 PeriphClkInit->I2SClockSelection = __HAL_RCC_GET_I2S_SOURCE(); | |
2082 | |
2083 | |
2084 } | |
2085 /** | |
2086 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) | |
2087 * @note Return 0 if peripheral clock identifier not managed by this API | |
2088 * @param PeriphClk Peripheral clock identifier | |
2089 * This parameter can be one of the following values: | |
2090 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock | |
2091 * @retval Frequency in KHz | |
2092 */ | |
2093 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) | |
2094 { | |
2095 /* This variable used to store the I2S clock frequency (value in Hz) */ | |
2096 uint32_t frequency = 0U; | |
2097 /* This variable used to store the VCO Input (value in Hz) */ | |
2098 uint32_t vcoinput = 0U; | |
2099 uint32_t srcclk = 0U; | |
2100 /* This variable used to store the VCO Output (value in Hz) */ | |
2101 uint32_t vcooutput = 0U; | |
2102 switch (PeriphClk) | |
2103 { | |
2104 case RCC_PERIPHCLK_I2S: | |
2105 { | |
2106 /* Get the current I2S source */ | |
2107 srcclk = __HAL_RCC_GET_I2S_SOURCE(); | |
2108 switch (srcclk) | |
2109 { | |
2110 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ | |
2111 case RCC_I2SAPBCLKSOURCE_EXT: | |
2112 { | |
2113 /* Set the I2S clock to the external clock value */ | |
2114 frequency = EXTERNAL_CLOCK_VALUE; | |
2115 break; | |
2116 } | |
2117 /* Check if I2S clock selection is PLL VCO Output divided by PLLR used as I2S clock */ | |
2118 case RCC_I2SAPBCLKSOURCE_PLLR: | |
2119 { | |
2120 /* Configure the PLL division factor R */ | |
2121 /* PLL_VCO Input = PLL_SOURCE/PLLM */ | |
2122 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
2123 { | |
2124 /* Get the I2S source clock value */ | |
2125 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
2126 } | |
2127 else | |
2128 { | |
2129 /* Get the I2S source clock value */ | |
2130 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
2131 } | |
2132 | |
2133 /* PLL_VCO Output = PLL_VCO Input * PLLN */ | |
2134 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6U) & (RCC_PLLCFGR_PLLN >> 6U))); | |
2135 /* I2S_CLK = PLL_VCO Output/PLLR */ | |
2136 frequency = (uint32_t)(vcooutput /(((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> 28U) & (RCC_PLLCFGR_PLLR >> 28U))); | |
2137 break; | |
2138 } | |
2139 /* Check if I2S clock selection is HSI or HSE depending from PLL source Clock */ | |
2140 case RCC_I2SAPBCLKSOURCE_PLLSRC: | |
2141 { | |
2142 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
2143 { | |
2144 frequency = HSE_VALUE; | |
2145 } | |
2146 else | |
2147 { | |
2148 frequency = HSI_VALUE; | |
2149 } | |
2150 break; | |
2151 } | |
2152 /* Clock not enabled for I2S*/ | |
2153 default: | |
2154 { | |
2155 frequency = 0U; | |
2156 break; | |
2157 } | |
2158 } | |
2159 break; | |
2160 } | |
2161 } | |
2162 return frequency; | |
2163 } | |
2164 #endif /* STM32F410Tx || STM32F410Cx || STM32F410Rx */ | |
2165 | |
2166 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) | |
2167 /** | |
2168 * @brief Initializes the RCC extended peripherals clocks according to the specified | |
2169 * parameters in the RCC_PeriphCLKInitTypeDef. | |
2170 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
2171 * contains the configuration information for the Extended Peripherals | |
2172 * clocks(I2S, SAI, LTDC RTC and TIM). | |
2173 * | |
2174 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select | |
2175 * the RTC clock source; in this case the Backup domain will be reset in | |
2176 * order to modify the RTC Clock source, as consequence RTC registers (including | |
2177 * the backup registers) and RCC_BDCR register are set to their reset values. | |
2178 * | |
2179 * @retval HAL status | |
2180 */ | |
2181 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
2182 { | |
2183 uint32_t tickstart = 0U; | |
2184 uint32_t tmpreg1 = 0U; | |
2185 | |
2186 /* Check the parameters */ | |
2187 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); | |
2188 | |
2189 /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------*/ | |
2190 /*----------------------- Common configuration SAI/I2S ---------------------*/ | |
2191 /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division | |
2192 factor is common parameters for both peripherals */ | |
2193 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) || | |
2194 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S)) | |
2195 { | |
2196 /* check for Parameters */ | |
2197 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); | |
2198 | |
2199 /* Disable the PLLI2S */ | |
2200 __HAL_RCC_PLLI2S_DISABLE(); | |
2201 /* Get tick */ | |
2202 tickstart = HAL_GetTick(); | |
2203 /* Wait till PLLI2S is disabled */ | |
2204 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) | |
2205 { | |
2206 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
2207 { | |
2208 /* return in case of Timeout detected */ | |
2209 return HAL_TIMEOUT; | |
2210 } | |
2211 } | |
2212 | |
2213 /*---------------------------- I2S configuration -------------------------*/ | |
2214 /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added | |
2215 only for I2S configuration */ | |
2216 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S)) | |
2217 { | |
2218 /* check for Parameters */ | |
2219 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
2220 /* Configure the PLLI2S division factors */ | |
2221 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */ | |
2222 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ | |
2223 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); | |
2224 } | |
2225 | |
2226 /*---------------------------- SAI configuration -------------------------*/ | |
2227 /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must | |
2228 be added only for SAI configuration */ | |
2229 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S)) | |
2230 { | |
2231 /* Check the PLLI2S division factors */ | |
2232 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ)); | |
2233 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ)); | |
2234 | |
2235 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */ | |
2236 tmpreg1 = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
2237 /* Configure the PLLI2S division factors */ | |
2238 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ | |
2239 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
2240 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */ | |
2241 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg1); | |
2242 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */ | |
2243 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ); | |
2244 } | |
2245 | |
2246 /* Enable the PLLI2S */ | |
2247 __HAL_RCC_PLLI2S_ENABLE(); | |
2248 /* Get tick */ | |
2249 tickstart = HAL_GetTick(); | |
2250 /* Wait till PLLI2S is ready */ | |
2251 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) | |
2252 { | |
2253 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
2254 { | |
2255 /* return in case of Timeout detected */ | |
2256 return HAL_TIMEOUT; | |
2257 } | |
2258 } | |
2259 } | |
2260 /*--------------------------------------------------------------------------*/ | |
2261 | |
2262 /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/ | |
2263 /*----------------------- Common configuration SAI/LTDC --------------------*/ | |
2264 /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division | |
2265 factor is common parameters for both peripherals */ | |
2266 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) || | |
2267 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC)) | |
2268 { | |
2269 /* Check the PLLSAI division factors */ | |
2270 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN)); | |
2271 | |
2272 /* Disable PLLSAI Clock */ | |
2273 __HAL_RCC_PLLSAI_DISABLE(); | |
2274 /* Get tick */ | |
2275 tickstart = HAL_GetTick(); | |
2276 /* Wait till PLLSAI is disabled */ | |
2277 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) | |
2278 { | |
2279 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) | |
2280 { | |
2281 /* return in case of Timeout detected */ | |
2282 return HAL_TIMEOUT; | |
2283 } | |
2284 } | |
2285 | |
2286 /*---------------------------- SAI configuration -------------------------*/ | |
2287 /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must | |
2288 be added only for SAI configuration */ | |
2289 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI)) | |
2290 { | |
2291 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ)); | |
2292 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ)); | |
2293 | |
2294 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ | |
2295 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); | |
2296 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ | |
2297 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ | |
2298 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */ | |
2299 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg1); | |
2300 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */ | |
2301 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ); | |
2302 } | |
2303 | |
2304 /*---------------------------- LTDC configuration ------------------------*/ | |
2305 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC)) | |
2306 { | |
2307 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR)); | |
2308 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR)); | |
2309 | |
2310 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */ | |
2311 tmpreg1 = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); | |
2312 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */ | |
2313 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */ | |
2314 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */ | |
2315 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg1, PeriphClkInit->PLLSAI.PLLSAIR); | |
2316 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */ | |
2317 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR); | |
2318 } | |
2319 /* Enable PLLSAI Clock */ | |
2320 __HAL_RCC_PLLSAI_ENABLE(); | |
2321 /* Get tick */ | |
2322 tickstart = HAL_GetTick(); | |
2323 /* Wait till PLLSAI is ready */ | |
2324 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) | |
2325 { | |
2326 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) | |
2327 { | |
2328 /* return in case of Timeout detected */ | |
2329 return HAL_TIMEOUT; | |
2330 } | |
2331 } | |
2332 } | |
2333 /*--------------------------------------------------------------------------*/ | |
2334 | |
2335 /*---------------------------- RTC configuration ---------------------------*/ | |
2336 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) | |
2337 { | |
2338 /* Check for RTC Parameters used to output RTCCLK */ | |
2339 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); | |
2340 | |
2341 /* Enable Power Clock*/ | |
2342 __HAL_RCC_PWR_CLK_ENABLE(); | |
2343 | |
2344 /* Enable write access to Backup domain */ | |
2345 PWR->CR |= PWR_CR_DBP; | |
2346 | |
2347 /* Get tick */ | |
2348 tickstart = HAL_GetTick(); | |
2349 | |
2350 while((PWR->CR & PWR_CR_DBP) == RESET) | |
2351 { | |
2352 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) | |
2353 { | |
2354 return HAL_TIMEOUT; | |
2355 } | |
2356 } | |
2357 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ | |
2358 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); | |
2359 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) | |
2360 { | |
2361 /* Store the content of BDCR register before the reset of Backup Domain */ | |
2362 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); | |
2363 /* RTC Clock selection can be changed only if the Backup Domain is reset */ | |
2364 __HAL_RCC_BACKUPRESET_FORCE(); | |
2365 __HAL_RCC_BACKUPRESET_RELEASE(); | |
2366 /* Restore the Content of BDCR register */ | |
2367 RCC->BDCR = tmpreg1; | |
2368 | |
2369 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ | |
2370 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) | |
2371 { | |
2372 /* Get tick */ | |
2373 tickstart = HAL_GetTick(); | |
2374 | |
2375 /* Wait till LSE is ready */ | |
2376 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) | |
2377 { | |
2378 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) | |
2379 { | |
2380 return HAL_TIMEOUT; | |
2381 } | |
2382 } | |
2383 } | |
2384 } | |
2385 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); | |
2386 } | |
2387 /*--------------------------------------------------------------------------*/ | |
2388 | |
2389 /*---------------------------- TIM configuration ---------------------------*/ | |
2390 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) | |
2391 { | |
2392 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); | |
2393 } | |
2394 return HAL_OK; | |
2395 } | |
2396 | |
2397 /** | |
2398 * @brief Configures the PeriphClkInit according to the internal | |
2399 * RCC configuration registers. | |
2400 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
2401 * will be configured. | |
2402 * @retval None | |
2403 */ | |
2404 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
2405 { | |
2406 uint32_t tempreg; | |
2407 | |
2408 /* Set all possible values for the extended clock type parameter------------*/ | |
2409 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC; | |
2410 | |
2411 /* Get the PLLI2S Clock configuration -----------------------------------------------*/ | |
2412 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); | |
2413 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
2414 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> RCC_PLLI2SCFGR_PLLI2SQ_Pos); | |
2415 /* Get the PLLSAI Clock configuration -----------------------------------------------*/ | |
2416 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> RCC_PLLSAICFGR_PLLSAIN_Pos); | |
2417 PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> RCC_PLLSAICFGR_PLLSAIR_Pos); | |
2418 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> RCC_PLLSAICFGR_PLLSAIQ_Pos); | |
2419 /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/ | |
2420 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> RCC_DCKCFGR_PLLI2SDIVQ_Pos); | |
2421 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> RCC_DCKCFGR_PLLSAIDIVQ_Pos); | |
2422 PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR); | |
2423 /* Get the RTC Clock configuration -----------------------------------------------*/ | |
2424 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); | |
2425 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); | |
2426 | |
2427 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) | |
2428 { | |
2429 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; | |
2430 } | |
2431 else | |
2432 { | |
2433 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; | |
2434 } | |
2435 } | |
2436 | |
2437 /** | |
2438 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) | |
2439 * @note Return 0 if peripheral clock identifier not managed by this API | |
2440 * @param PeriphClk Peripheral clock identifier | |
2441 * This parameter can be one of the following values: | |
2442 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock | |
2443 * @retval Frequency in KHz | |
2444 */ | |
2445 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) | |
2446 { | |
2447 /* This variable used to store the I2S clock frequency (value in Hz) */ | |
2448 uint32_t frequency = 0U; | |
2449 /* This variable used to store the VCO Input (value in Hz) */ | |
2450 uint32_t vcoinput = 0U; | |
2451 uint32_t srcclk = 0U; | |
2452 /* This variable used to store the VCO Output (value in Hz) */ | |
2453 uint32_t vcooutput = 0U; | |
2454 switch (PeriphClk) | |
2455 { | |
2456 case RCC_PERIPHCLK_I2S: | |
2457 { | |
2458 /* Get the current I2S source */ | |
2459 srcclk = __HAL_RCC_GET_I2S_SOURCE(); | |
2460 switch (srcclk) | |
2461 { | |
2462 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ | |
2463 case RCC_I2SCLKSOURCE_EXT: | |
2464 { | |
2465 /* Set the I2S clock to the external clock value */ | |
2466 frequency = EXTERNAL_CLOCK_VALUE; | |
2467 break; | |
2468 } | |
2469 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ | |
2470 case RCC_I2SCLKSOURCE_PLLI2S: | |
2471 { | |
2472 /* Configure the PLLI2S division factor */ | |
2473 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ | |
2474 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
2475 { | |
2476 /* Get the I2S source clock value */ | |
2477 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
2478 } | |
2479 else | |
2480 { | |
2481 /* Get the I2S source clock value */ | |
2482 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
2483 } | |
2484 | |
2485 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
2486 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); | |
2487 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ | |
2488 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); | |
2489 break; | |
2490 } | |
2491 /* Clock not enabled for I2S */ | |
2492 default: | |
2493 { | |
2494 frequency = 0U; | |
2495 break; | |
2496 } | |
2497 } | |
2498 break; | |
2499 } | |
2500 } | |
2501 return frequency; | |
2502 } | |
2503 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */ | |
2504 | |
2505 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\ | |
2506 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) | |
2507 /** | |
2508 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the | |
2509 * RCC_PeriphCLKInitTypeDef. | |
2510 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
2511 * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks). | |
2512 * | |
2513 * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case | |
2514 * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup | |
2515 * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset | |
2516 * | |
2517 * @retval HAL status | |
2518 */ | |
2519 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
2520 { | |
2521 uint32_t tickstart = 0U; | |
2522 uint32_t tmpreg1 = 0U; | |
2523 | |
2524 /* Check the parameters */ | |
2525 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection)); | |
2526 | |
2527 /*---------------------------- I2S configuration ---------------------------*/ | |
2528 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) || | |
2529 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_PLLI2S) == RCC_PERIPHCLK_PLLI2S)) | |
2530 { | |
2531 /* check for Parameters */ | |
2532 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR)); | |
2533 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN)); | |
2534 #if defined(STM32F411xE) | |
2535 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM)); | |
2536 #endif /* STM32F411xE */ | |
2537 /* Disable the PLLI2S */ | |
2538 __HAL_RCC_PLLI2S_DISABLE(); | |
2539 /* Get tick */ | |
2540 tickstart = HAL_GetTick(); | |
2541 /* Wait till PLLI2S is disabled */ | |
2542 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) | |
2543 { | |
2544 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
2545 { | |
2546 /* return in case of Timeout detected */ | |
2547 return HAL_TIMEOUT; | |
2548 } | |
2549 } | |
2550 | |
2551 #if defined(STM32F411xE) | |
2552 /* Configure the PLLI2S division factors */ | |
2553 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ | |
2554 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ | |
2555 __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR); | |
2556 #else | |
2557 /* Configure the PLLI2S division factors */ | |
2558 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLM) */ | |
2559 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */ | |
2560 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR); | |
2561 #endif /* STM32F411xE */ | |
2562 | |
2563 /* Enable the PLLI2S */ | |
2564 __HAL_RCC_PLLI2S_ENABLE(); | |
2565 /* Get tick */ | |
2566 tickstart = HAL_GetTick(); | |
2567 /* Wait till PLLI2S is ready */ | |
2568 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) | |
2569 { | |
2570 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
2571 { | |
2572 /* return in case of Timeout detected */ | |
2573 return HAL_TIMEOUT; | |
2574 } | |
2575 } | |
2576 } | |
2577 | |
2578 /*---------------------------- RTC configuration ---------------------------*/ | |
2579 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC)) | |
2580 { | |
2581 /* Check for RTC Parameters used to output RTCCLK */ | |
2582 assert_param(IS_RCC_RTCCLKSOURCE(PeriphClkInit->RTCClockSelection)); | |
2583 | |
2584 /* Enable Power Clock*/ | |
2585 __HAL_RCC_PWR_CLK_ENABLE(); | |
2586 | |
2587 /* Enable write access to Backup domain */ | |
2588 PWR->CR |= PWR_CR_DBP; | |
2589 | |
2590 /* Get tick */ | |
2591 tickstart = HAL_GetTick(); | |
2592 | |
2593 while((PWR->CR & PWR_CR_DBP) == RESET) | |
2594 { | |
2595 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE) | |
2596 { | |
2597 return HAL_TIMEOUT; | |
2598 } | |
2599 } | |
2600 /* Reset the Backup domain only if the RTC Clock source selection is modified from reset value */ | |
2601 tmpreg1 = (RCC->BDCR & RCC_BDCR_RTCSEL); | |
2602 if((tmpreg1 != 0x00000000U) && ((tmpreg1) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))) | |
2603 { | |
2604 /* Store the content of BDCR register before the reset of Backup Domain */ | |
2605 tmpreg1 = (RCC->BDCR & ~(RCC_BDCR_RTCSEL)); | |
2606 /* RTC Clock selection can be changed only if the Backup Domain is reset */ | |
2607 __HAL_RCC_BACKUPRESET_FORCE(); | |
2608 __HAL_RCC_BACKUPRESET_RELEASE(); | |
2609 /* Restore the Content of BDCR register */ | |
2610 RCC->BDCR = tmpreg1; | |
2611 | |
2612 /* Wait for LSE reactivation if LSE was enable prior to Backup Domain reset */ | |
2613 if(HAL_IS_BIT_SET(RCC->BDCR, RCC_BDCR_LSEON)) | |
2614 { | |
2615 /* Get tick */ | |
2616 tickstart = HAL_GetTick(); | |
2617 | |
2618 /* Wait till LSE is ready */ | |
2619 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) | |
2620 { | |
2621 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) | |
2622 { | |
2623 return HAL_TIMEOUT; | |
2624 } | |
2625 } | |
2626 } | |
2627 } | |
2628 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection); | |
2629 } | |
2630 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) | |
2631 /*---------------------------- TIM configuration ---------------------------*/ | |
2632 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM)) | |
2633 { | |
2634 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection); | |
2635 } | |
2636 #endif /* STM32F401xC || STM32F401xE || STM32F411xE */ | |
2637 return HAL_OK; | |
2638 } | |
2639 | |
2640 /** | |
2641 * @brief Configures the RCC_OscInitStruct according to the internal | |
2642 * RCC configuration registers. | |
2643 * @param PeriphClkInit pointer to an RCC_PeriphCLKInitTypeDef structure that | |
2644 * will be configured. | |
2645 * @retval None | |
2646 */ | |
2647 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit) | |
2648 { | |
2649 uint32_t tempreg; | |
2650 | |
2651 /* Set all possible values for the extended clock type parameter------------*/ | |
2652 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC; | |
2653 | |
2654 /* Get the PLLI2S Clock configuration --------------------------------------*/ | |
2655 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> RCC_PLLI2SCFGR_PLLI2SN_Pos); | |
2656 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> RCC_PLLI2SCFGR_PLLI2SR_Pos); | |
2657 #if defined(STM32F411xE) | |
2658 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM); | |
2659 #endif /* STM32F411xE */ | |
2660 /* Get the RTC Clock configuration -----------------------------------------*/ | |
2661 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE); | |
2662 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL)); | |
2663 | |
2664 #if defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE) | |
2665 /* Get the TIM Prescaler configuration -------------------------------------*/ | |
2666 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET) | |
2667 { | |
2668 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED; | |
2669 } | |
2670 else | |
2671 { | |
2672 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED; | |
2673 } | |
2674 #endif /* STM32F401xC || STM32F401xE || STM32F411xE */ | |
2675 } | |
2676 | |
2677 /** | |
2678 * @brief Return the peripheral clock frequency for a given peripheral(SAI..) | |
2679 * @note Return 0 if peripheral clock identifier not managed by this API | |
2680 * @param PeriphClk Peripheral clock identifier | |
2681 * This parameter can be one of the following values: | |
2682 * @arg RCC_PERIPHCLK_I2S: I2S peripheral clock | |
2683 * @retval Frequency in KHz | |
2684 */ | |
2685 uint32_t HAL_RCCEx_GetPeriphCLKFreq(uint32_t PeriphClk) | |
2686 { | |
2687 /* This variable used to store the I2S clock frequency (value in Hz) */ | |
2688 uint32_t frequency = 0U; | |
2689 /* This variable used to store the VCO Input (value in Hz) */ | |
2690 uint32_t vcoinput = 0U; | |
2691 uint32_t srcclk = 0U; | |
2692 /* This variable used to store the VCO Output (value in Hz) */ | |
2693 uint32_t vcooutput = 0U; | |
2694 switch (PeriphClk) | |
2695 { | |
2696 case RCC_PERIPHCLK_I2S: | |
2697 { | |
2698 /* Get the current I2S source */ | |
2699 srcclk = __HAL_RCC_GET_I2S_SOURCE(); | |
2700 switch (srcclk) | |
2701 { | |
2702 /* Check if I2S clock selection is External clock mapped on the I2S_CKIN pin used as I2S clock */ | |
2703 case RCC_I2SCLKSOURCE_EXT: | |
2704 { | |
2705 /* Set the I2S clock to the external clock value */ | |
2706 frequency = EXTERNAL_CLOCK_VALUE; | |
2707 break; | |
2708 } | |
2709 /* Check if I2S clock selection is PLLI2S VCO output clock divided by PLLI2SR used as I2S clock */ | |
2710 case RCC_I2SCLKSOURCE_PLLI2S: | |
2711 { | |
2712 #if defined(STM32F411xE) | |
2713 /* Configure the PLLI2S division factor */ | |
2714 /* PLLI2S_VCO Input = PLL_SOURCE/PLLI2SM */ | |
2715 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
2716 { | |
2717 /* Get the I2S source clock value */ | |
2718 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
2719 } | |
2720 else | |
2721 { | |
2722 /* Get the I2S source clock value */ | |
2723 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM)); | |
2724 } | |
2725 #else | |
2726 /* Configure the PLLI2S division factor */ | |
2727 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */ | |
2728 if((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLSOURCE_HSE) | |
2729 { | |
2730 /* Get the I2S source clock value */ | |
2731 vcoinput = (uint32_t)(HSE_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
2732 } | |
2733 else | |
2734 { | |
2735 /* Get the I2S source clock value */ | |
2736 vcoinput = (uint32_t)(HSI_VALUE / (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM)); | |
2737 } | |
2738 #endif /* STM32F411xE */ | |
2739 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */ | |
2740 vcooutput = (uint32_t)(vcoinput * (((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> 6U) & (RCC_PLLI2SCFGR_PLLI2SN >> 6U))); | |
2741 /* I2S_CLK = PLLI2S_VCO Output/PLLI2SR */ | |
2742 frequency = (uint32_t)(vcooutput /(((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> 28U) & (RCC_PLLI2SCFGR_PLLI2SR >> 28U))); | |
2743 break; | |
2744 } | |
2745 /* Clock not enabled for I2S*/ | |
2746 default: | |
2747 { | |
2748 frequency = 0U; | |
2749 break; | |
2750 } | |
2751 } | |
2752 break; | |
2753 } | |
2754 } | |
2755 return frequency; | |
2756 } | |
2757 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */ | |
2758 | |
2759 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F411xE) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\ | |
2760 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) | |
2761 /** | |
2762 * @brief Select LSE mode | |
2763 * | |
2764 * @note This mode is only available for STM32F410xx/STM32F411xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices. | |
2765 * | |
2766 * @param Mode specifies the LSE mode. | |
2767 * This parameter can be one of the following values: | |
2768 * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection | |
2769 * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection | |
2770 * @retval None | |
2771 */ | |
2772 void HAL_RCCEx_SelectLSEMode(uint8_t Mode) | |
2773 { | |
2774 /* Check the parameters */ | |
2775 assert_param(IS_RCC_LSE_MODE(Mode)); | |
2776 if(Mode == RCC_LSE_HIGHDRIVE_MODE) | |
2777 { | |
2778 SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD); | |
2779 } | |
2780 else | |
2781 { | |
2782 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD); | |
2783 } | |
2784 } | |
2785 | |
2786 #endif /* STM32F410xx || STM32F411xE || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ | |
2787 | |
2788 /** @defgroup RCCEx_Exported_Functions_Group2 Extended Clock management functions | |
2789 * @brief Extended Clock management functions | |
2790 * | |
2791 @verbatim | |
2792 =============================================================================== | |
2793 ##### Extended clock management functions ##### | |
2794 =============================================================================== | |
2795 [..] | |
2796 This subsection provides a set of functions allowing to control the | |
2797 activation or deactivation of PLLI2S, PLLSAI. | |
2798 @endverbatim | |
2799 * @{ | |
2800 */ | |
2801 | |
2802 #if defined(RCC_PLLI2S_SUPPORT) | |
2803 /** | |
2804 * @brief Enable PLLI2S. | |
2805 * @param PLLI2SInit pointer to an RCC_PLLI2SInitTypeDef structure that | |
2806 * contains the configuration information for the PLLI2S | |
2807 * @retval HAL status | |
2808 */ | |
2809 HAL_StatusTypeDef HAL_RCCEx_EnablePLLI2S(RCC_PLLI2SInitTypeDef *PLLI2SInit) | |
2810 { | |
2811 uint32_t tickstart; | |
2812 | |
2813 /* Check for parameters */ | |
2814 assert_param(IS_RCC_PLLI2SN_VALUE(PLLI2SInit->PLLI2SN)); | |
2815 assert_param(IS_RCC_PLLI2SR_VALUE(PLLI2SInit->PLLI2SR)); | |
2816 #if defined(RCC_PLLI2SCFGR_PLLI2SM) | |
2817 assert_param(IS_RCC_PLLI2SM_VALUE(PLLI2SInit->PLLI2SM)); | |
2818 #endif /* RCC_PLLI2SCFGR_PLLI2SM */ | |
2819 #if defined(RCC_PLLI2SCFGR_PLLI2SP) | |
2820 assert_param(IS_RCC_PLLI2SP_VALUE(PLLI2SInit->PLLI2SP)); | |
2821 #endif /* RCC_PLLI2SCFGR_PLLI2SP */ | |
2822 #if defined(RCC_PLLI2SCFGR_PLLI2SQ) | |
2823 assert_param(IS_RCC_PLLI2SQ_VALUE(PLLI2SInit->PLLI2SQ)); | |
2824 #endif /* RCC_PLLI2SCFGR_PLLI2SQ */ | |
2825 | |
2826 /* Disable the PLLI2S */ | |
2827 __HAL_RCC_PLLI2S_DISABLE(); | |
2828 | |
2829 /* Wait till PLLI2S is disabled */ | |
2830 tickstart = HAL_GetTick(); | |
2831 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET) | |
2832 { | |
2833 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
2834 { | |
2835 /* return in case of Timeout detected */ | |
2836 return HAL_TIMEOUT; | |
2837 } | |
2838 } | |
2839 | |
2840 /* Configure the PLLI2S division factors */ | |
2841 #if defined(STM32F446xx) | |
2842 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ | |
2843 /* I2SPCLK = PLLI2S_VCO / PLLI2SP */ | |
2844 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */ | |
2845 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ | |
2846 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \ | |
2847 PLLI2SInit->PLLI2SP, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR); | |
2848 #elif defined(STM32F412Zx) || defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) ||\ | |
2849 defined(STM32F413xx) || defined(STM32F423xx) | |
2850 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM)*/ | |
2851 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */ | |
2852 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ | |
2853 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, \ | |
2854 PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR); | |
2855 #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) ||\ | |
2856 defined(STM32F469xx) || defined(STM32F479xx) | |
2857 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * PLLI2SN */ | |
2858 /* I2SQCLK = PLLI2S_VCO / PLLI2SQ */ | |
2859 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ | |
2860 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SQ, PLLI2SInit->PLLI2SR); | |
2861 #elif defined(STM32F411xE) | |
2862 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) * (PLLI2SN/PLLI2SM) */ | |
2863 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ | |
2864 __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PLLI2SInit->PLLI2SM, PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR); | |
2865 #else | |
2866 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) x PLLI2SN */ | |
2867 /* I2SRCLK = PLLI2S_VCO / PLLI2SR */ | |
2868 __HAL_RCC_PLLI2S_CONFIG(PLLI2SInit->PLLI2SN, PLLI2SInit->PLLI2SR); | |
2869 #endif /* STM32F446xx */ | |
2870 | |
2871 /* Enable the PLLI2S */ | |
2872 __HAL_RCC_PLLI2S_ENABLE(); | |
2873 | |
2874 /* Wait till PLLI2S is ready */ | |
2875 tickstart = HAL_GetTick(); | |
2876 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET) | |
2877 { | |
2878 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE) | |
2879 { | |
2880 /* return in case of Timeout detected */ | |
2881 return HAL_TIMEOUT; | |
2882 } | |
2883 } | |
2884 | |
2885 return HAL_OK; | |
2886 } | |
2887 | |
2888 /** | |
2889 * @brief Disable PLLI2S. | |
2890 * @retval HAL status | |
2891 */ | |
2892 HAL_StatusTypeDef HAL_RCCEx_DisablePLLI2S(void) | |
2893 { | |
2894 uint32_t tickstart; | |
2895 | |
2896 /* Disable the PLLI2S */ | |
2897 __HAL_RCC_PLLI2S_DISABLE(); | |
2898 | |
2899 /* Wait till PLLI2S is disabled */ | |
2900 tickstart = HAL_GetTick(); | |
2901 while(READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET) | |
2902 { | |
2903 if((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) | |
2904 { | |
2905 /* return in case of Timeout detected */ | |
2906 return HAL_TIMEOUT; | |
2907 } | |
2908 } | |
2909 | |
2910 return HAL_OK; | |
2911 } | |
2912 | |
2913 #endif /* RCC_PLLI2S_SUPPORT */ | |
2914 | |
2915 #if defined(RCC_PLLSAI_SUPPORT) | |
2916 /** | |
2917 * @brief Enable PLLSAI. | |
2918 * @param PLLSAIInit pointer to an RCC_PLLSAIInitTypeDef structure that | |
2919 * contains the configuration information for the PLLSAI | |
2920 * @retval HAL status | |
2921 */ | |
2922 HAL_StatusTypeDef HAL_RCCEx_EnablePLLSAI(RCC_PLLSAIInitTypeDef *PLLSAIInit) | |
2923 { | |
2924 uint32_t tickstart; | |
2925 | |
2926 /* Check for parameters */ | |
2927 assert_param(IS_RCC_PLLSAIN_VALUE(PLLSAIInit->PLLSAIN)); | |
2928 assert_param(IS_RCC_PLLSAIQ_VALUE(PLLSAIInit->PLLSAIQ)); | |
2929 #if defined(RCC_PLLSAICFGR_PLLSAIM) | |
2930 assert_param(IS_RCC_PLLSAIM_VALUE(PLLSAIInit->PLLSAIM)); | |
2931 #endif /* RCC_PLLSAICFGR_PLLSAIM */ | |
2932 #if defined(RCC_PLLSAICFGR_PLLSAIP) | |
2933 assert_param(IS_RCC_PLLSAIP_VALUE(PLLSAIInit->PLLSAIP)); | |
2934 #endif /* RCC_PLLSAICFGR_PLLSAIP */ | |
2935 #if defined(RCC_PLLSAICFGR_PLLSAIR) | |
2936 assert_param(IS_RCC_PLLSAIR_VALUE(PLLSAIInit->PLLSAIR)); | |
2937 #endif /* RCC_PLLSAICFGR_PLLSAIR */ | |
2938 | |
2939 /* Disable the PLLSAI */ | |
2940 __HAL_RCC_PLLSAI_DISABLE(); | |
2941 | |
2942 /* Wait till PLLSAI is disabled */ | |
2943 tickstart = HAL_GetTick(); | |
2944 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) | |
2945 { | |
2946 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) | |
2947 { | |
2948 /* return in case of Timeout detected */ | |
2949 return HAL_TIMEOUT; | |
2950 } | |
2951 } | |
2952 | |
2953 /* Configure the PLLSAI division factors */ | |
2954 #if defined(STM32F446xx) | |
2955 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * (PLLSAIN/PLLSAIM) */ | |
2956 /* SAIPCLK = PLLSAI_VCO / PLLSAIP */ | |
2957 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */ | |
2958 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */ | |
2959 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIM, PLLSAIInit->PLLSAIN, \ | |
2960 PLLSAIInit->PLLSAIP, PLLSAIInit->PLLSAIQ, 0U); | |
2961 #elif defined(STM32F469xx) || defined(STM32F479xx) | |
2962 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) * PLLSAIN */ | |
2963 /* SAIPCLK = PLLSAI_VCO / PLLSAIP */ | |
2964 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */ | |
2965 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */ | |
2966 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIP, \ | |
2967 PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR); | |
2968 #else | |
2969 /* PLLSAI_VCO = f(VCO clock) = f(PLLSAI clock input) x PLLSAIN */ | |
2970 /* SAIQCLK = PLLSAI_VCO / PLLSAIQ */ | |
2971 /* SAIRCLK = PLLSAI_VCO / PLLSAIR */ | |
2972 __HAL_RCC_PLLSAI_CONFIG(PLLSAIInit->PLLSAIN, PLLSAIInit->PLLSAIQ, PLLSAIInit->PLLSAIR); | |
2973 #endif /* STM32F446xx */ | |
2974 | |
2975 /* Enable the PLLSAI */ | |
2976 __HAL_RCC_PLLSAI_ENABLE(); | |
2977 | |
2978 /* Wait till PLLSAI is ready */ | |
2979 tickstart = HAL_GetTick(); | |
2980 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET) | |
2981 { | |
2982 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE) | |
2983 { | |
2984 /* return in case of Timeout detected */ | |
2985 return HAL_TIMEOUT; | |
2986 } | |
2987 } | |
2988 | |
2989 return HAL_OK; | |
2990 } | |
2991 | |
2992 /** | |
2993 * @brief Disable PLLSAI. | |
2994 * @retval HAL status | |
2995 */ | |
2996 HAL_StatusTypeDef HAL_RCCEx_DisablePLLSAI(void) | |
2997 { | |
2998 uint32_t tickstart; | |
2999 | |
3000 /* Disable the PLLSAI */ | |
3001 __HAL_RCC_PLLSAI_DISABLE(); | |
3002 | |
3003 /* Wait till PLLSAI is disabled */ | |
3004 tickstart = HAL_GetTick(); | |
3005 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET) | |
3006 { | |
3007 if((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE) | |
3008 { | |
3009 /* return in case of Timeout detected */ | |
3010 return HAL_TIMEOUT; | |
3011 } | |
3012 } | |
3013 | |
3014 return HAL_OK; | |
3015 } | |
3016 | |
3017 #endif /* RCC_PLLSAI_SUPPORT */ | |
3018 | |
3019 /** | |
3020 * @} | |
3021 */ | |
3022 | |
3023 #if defined(STM32F446xx) | |
3024 /** | |
3025 * @brief Returns the SYSCLK frequency | |
3026 * | |
3027 * @note This function implementation is valid only for STM32F446xx devices. | |
3028 * @note This function add the PLL/PLLR System clock source | |
3029 * | |
3030 * @note The system frequency computed by this function is not the real | |
3031 * frequency in the chip. It is calculated based on the predefined | |
3032 * constant and the selected clock source: | |
3033 * @note If SYSCLK source is HSI, function returns values based on HSI_VALUE(*) | |
3034 * @note If SYSCLK source is HSE, function returns values based on HSE_VALUE(**) | |
3035 * @note If SYSCLK source is PLL or PLLR, function returns values based on HSE_VALUE(**) | |
3036 * or HSI_VALUE(*) multiplied/divided by the PLL factors. | |
3037 * @note (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value | |
3038 * 16 MHz) but the real value may vary depending on the variations | |
3039 * in voltage and temperature. | |
3040 * @note (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value | |
3041 * 25 MHz), user has to ensure that HSE_VALUE is same as the real | |
3042 * frequency of the crystal used. Otherwise, this function may | |
3043 * have wrong result. | |
3044 * | |
3045 * @note The result of this function could be not correct when using fractional | |
3046 * value for HSE crystal. | |
3047 * | |
3048 * @note This function can be used by the user application to compute the | |
3049 * baudrate for the communication peripherals or configure other parameters. | |
3050 * | |
3051 * @note Each time SYSCLK changes, this function must be called to update the | |
3052 * right SYSCLK value. Otherwise, any configuration based on this function will be incorrect. | |
3053 * | |
3054 * | |
3055 * @retval SYSCLK frequency | |
3056 */ | |
3057 uint32_t HAL_RCC_GetSysClockFreq(void) | |
3058 { | |
3059 uint32_t pllm = 0U; | |
3060 uint32_t pllvco = 0U; | |
3061 uint32_t pllp = 0U; | |
3062 uint32_t pllr = 0U; | |
3063 uint32_t sysclockfreq = 0U; | |
3064 | |
3065 /* Get SYSCLK source -------------------------------------------------------*/ | |
3066 switch (RCC->CFGR & RCC_CFGR_SWS) | |
3067 { | |
3068 case RCC_CFGR_SWS_HSI: /* HSI used as system clock source */ | |
3069 { | |
3070 sysclockfreq = HSI_VALUE; | |
3071 break; | |
3072 } | |
3073 case RCC_CFGR_SWS_HSE: /* HSE used as system clock source */ | |
3074 { | |
3075 sysclockfreq = HSE_VALUE; | |
3076 break; | |
3077 } | |
3078 case RCC_CFGR_SWS_PLL: /* PLL/PLLP used as system clock source */ | |
3079 { | |
3080 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN | |
3081 SYSCLK = PLL_VCO / PLLP */ | |
3082 pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; | |
3083 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) | |
3084 { | |
3085 /* HSE used as PLL clock source */ | |
3086 pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); | |
3087 } | |
3088 else | |
3089 { | |
3090 /* HSI used as PLL clock source */ | |
3091 pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); | |
3092 } | |
3093 pllp = ((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >> RCC_PLLCFGR_PLLP_Pos) + 1U) *2U); | |
3094 | |
3095 sysclockfreq = pllvco/pllp; | |
3096 break; | |
3097 } | |
3098 case RCC_CFGR_SWS_PLLR: /* PLL/PLLR used as system clock source */ | |
3099 { | |
3100 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLLM) * PLLN | |
3101 SYSCLK = PLL_VCO / PLLR */ | |
3102 pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM; | |
3103 if(__HAL_RCC_GET_PLL_OSCSOURCE() != RCC_PLLSOURCE_HSI) | |
3104 { | |
3105 /* HSE used as PLL clock source */ | |
3106 pllvco = (uint32_t) ((((uint64_t) HSE_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); | |
3107 } | |
3108 else | |
3109 { | |
3110 /* HSI used as PLL clock source */ | |
3111 pllvco = (uint32_t) ((((uint64_t) HSI_VALUE * ((uint64_t) ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos)))) / (uint64_t)pllm); | |
3112 } | |
3113 pllr = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos); | |
3114 | |
3115 sysclockfreq = pllvco/pllr; | |
3116 break; | |
3117 } | |
3118 default: | |
3119 { | |
3120 sysclockfreq = HSI_VALUE; | |
3121 break; | |
3122 } | |
3123 } | |
3124 return sysclockfreq; | |
3125 } | |
3126 #endif /* STM32F446xx */ | |
3127 | |
3128 /** | |
3129 * @} | |
3130 */ | |
3131 | |
3132 /** | |
3133 * @} | |
3134 */ | |
3135 | |
3136 /** | |
3137 * @brief Resets the RCC clock configuration to the default reset state. | |
3138 * @note The default reset state of the clock configuration is given below: | |
3139 * - HSI ON and used as system clock source | |
3140 * - HSE, PLL, PLLI2S and PLLSAI OFF | |
3141 * - AHB, APB1 and APB2 prescaler set to 1. | |
3142 * - CSS, MCO1 and MCO2 OFF | |
3143 * - All interrupts disabled | |
3144 * @note This function doesn't modify the configuration of the | |
3145 * - Peripheral clocks | |
3146 * - LSI, LSE and RTC clocks | |
3147 * @retval HAL status | |
3148 */ | |
3149 HAL_StatusTypeDef HAL_RCC_DeInit(void) | |
3150 { | |
3151 uint32_t tickstart; | |
3152 | |
3153 /* Get Start Tick */ | |
3154 tickstart = HAL_GetTick(); | |
3155 | |
3156 /* Set HSION bit to the reset value */ | |
3157 SET_BIT(RCC->CR, RCC_CR_HSION); | |
3158 | |
3159 /* Wait till HSI is ready */ | |
3160 while (READ_BIT(RCC->CR, RCC_CR_HSIRDY) == RESET) | |
3161 { | |
3162 if ((HAL_GetTick() - tickstart) > HSI_TIMEOUT_VALUE) | |
3163 { | |
3164 return HAL_TIMEOUT; | |
3165 } | |
3166 } | |
3167 | |
3168 /* Set HSITRIM[4:0] bits to the reset value */ | |
3169 SET_BIT(RCC->CR, RCC_CR_HSITRIM_4); | |
3170 | |
3171 /* Get Start Tick */ | |
3172 tickstart = HAL_GetTick(); | |
3173 | |
3174 /* Reset CFGR register */ | |
3175 CLEAR_REG(RCC->CFGR); | |
3176 | |
3177 /* Wait till clock switch is ready */ | |
3178 while (READ_BIT(RCC->CFGR, RCC_CFGR_SWS) != RESET) | |
3179 { | |
3180 if ((HAL_GetTick() - tickstart) > CLOCKSWITCH_TIMEOUT_VALUE) | |
3181 { | |
3182 return HAL_TIMEOUT; | |
3183 } | |
3184 } | |
3185 | |
3186 /* Get Start Tick */ | |
3187 tickstart = HAL_GetTick(); | |
3188 | |
3189 /* Clear HSEON, HSEBYP and CSSON bits */ | |
3190 CLEAR_BIT(RCC->CR, RCC_CR_HSEON | RCC_CR_HSEBYP | RCC_CR_CSSON); | |
3191 | |
3192 /* Wait till HSE is disabled */ | |
3193 while (READ_BIT(RCC->CR, RCC_CR_HSERDY) != RESET) | |
3194 { | |
3195 if ((HAL_GetTick() - tickstart) > HSE_TIMEOUT_VALUE) | |
3196 { | |
3197 return HAL_TIMEOUT; | |
3198 } | |
3199 } | |
3200 | |
3201 /* Get Start Tick */ | |
3202 tickstart = HAL_GetTick(); | |
3203 | |
3204 /* Clear PLLON bit */ | |
3205 CLEAR_BIT(RCC->CR, RCC_CR_PLLON); | |
3206 | |
3207 /* Wait till PLL is disabled */ | |
3208 while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) != RESET) | |
3209 { | |
3210 if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) | |
3211 { | |
3212 return HAL_TIMEOUT; | |
3213 } | |
3214 } | |
3215 | |
3216 #if defined(RCC_PLLI2S_SUPPORT) | |
3217 /* Get Start Tick */ | |
3218 tickstart = HAL_GetTick(); | |
3219 | |
3220 /* Reset PLLI2SON bit */ | |
3221 CLEAR_BIT(RCC->CR, RCC_CR_PLLI2SON); | |
3222 | |
3223 /* Wait till PLLI2S is disabled */ | |
3224 while (READ_BIT(RCC->CR, RCC_CR_PLLI2SRDY) != RESET) | |
3225 { | |
3226 if ((HAL_GetTick() - tickstart) > PLLI2S_TIMEOUT_VALUE) | |
3227 { | |
3228 return HAL_TIMEOUT; | |
3229 } | |
3230 } | |
3231 #endif /* RCC_PLLI2S_SUPPORT */ | |
3232 | |
3233 #if defined(RCC_PLLSAI_SUPPORT) | |
3234 /* Get Start Tick */ | |
3235 tickstart = HAL_GetTick(); | |
3236 | |
3237 /* Reset PLLSAI bit */ | |
3238 CLEAR_BIT(RCC->CR, RCC_CR_PLLSAION); | |
3239 | |
3240 /* Wait till PLLSAI is disabled */ | |
3241 while (READ_BIT(RCC->CR, RCC_CR_PLLSAIRDY) != RESET) | |
3242 { | |
3243 if ((HAL_GetTick() - tickstart) > PLLSAI_TIMEOUT_VALUE) | |
3244 { | |
3245 return HAL_TIMEOUT; | |
3246 } | |
3247 } | |
3248 #endif /* RCC_PLLSAI_SUPPORT */ | |
3249 | |
3250 /* Once PLL, PLLI2S and PLLSAI are OFF, reset PLLCFGR register to default value */ | |
3251 #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \ | |
3252 defined(STM32F423xx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) | |
3253 RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLR_1; | |
3254 #elif defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) | |
3255 RCC->PLLCFGR = RCC_PLLCFGR_PLLR_0 | RCC_PLLCFGR_PLLR_1 | RCC_PLLCFGR_PLLR_2 | RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_0 | RCC_PLLCFGR_PLLQ_1 | RCC_PLLCFGR_PLLQ_2 | RCC_PLLCFGR_PLLQ_3; | |
3256 #else | |
3257 RCC->PLLCFGR = RCC_PLLCFGR_PLLM_4 | RCC_PLLCFGR_PLLN_6 | RCC_PLLCFGR_PLLN_7 | RCC_PLLCFGR_PLLQ_2; | |
3258 #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx || STM32F469xx || STM32F479xx */ | |
3259 | |
3260 /* Reset PLLI2SCFGR register to default value */ | |
3261 #if defined(STM32F412Cx) || defined(STM32F412Rx) || defined(STM32F412Vx) || defined(STM32F412Zx) || defined(STM32F413xx) || \ | |
3262 defined(STM32F423xx) || defined(STM32F446xx) | |
3263 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1; | |
3264 #elif defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx) | |
3265 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1; | |
3266 #elif defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx) | |
3267 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SQ_2 | RCC_PLLI2SCFGR_PLLI2SR_1; | |
3268 #elif defined(STM32F411xE) | |
3269 RCC->PLLI2SCFGR = RCC_PLLI2SCFGR_PLLI2SM_4 | RCC_PLLI2SCFGR_PLLI2SN_6 | RCC_PLLI2SCFGR_PLLI2SN_7 | RCC_PLLI2SCFGR_PLLI2SR_1; | |
3270 #endif /* STM32F412Cx || STM32F412Rx || STM32F412Vx || STM32F412Zx || STM32F413xx || STM32F423xx || STM32F446xx */ | |
3271 | |
3272 /* Reset PLLSAICFGR register */ | |
3273 #if defined(STM32F427xx) || defined(STM32F429xx) || defined(STM32F437xx) || defined(STM32F439xx) || defined(STM32F469xx) || defined(STM32F479xx) | |
3274 RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2 | RCC_PLLSAICFGR_PLLSAIR_1; | |
3275 #elif defined(STM32F446xx) | |
3276 RCC->PLLSAICFGR = RCC_PLLSAICFGR_PLLSAIM_4 | RCC_PLLSAICFGR_PLLSAIN_6 | RCC_PLLSAICFGR_PLLSAIN_7 | RCC_PLLSAICFGR_PLLSAIQ_2; | |
3277 #endif /* STM32F427xx || STM32F429xx || STM32F437xx || STM32F439xx || STM32F469xx || STM32F479xx */ | |
3278 | |
3279 /* Disable all interrupts */ | |
3280 CLEAR_BIT(RCC->CIR, RCC_CIR_LSIRDYIE | RCC_CIR_LSERDYIE | RCC_CIR_HSIRDYIE | RCC_CIR_HSERDYIE | RCC_CIR_PLLRDYIE); | |
3281 | |
3282 #if defined(RCC_CIR_PLLI2SRDYIE) | |
3283 CLEAR_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYIE); | |
3284 #endif /* RCC_CIR_PLLI2SRDYIE */ | |
3285 | |
3286 #if defined(RCC_CIR_PLLSAIRDYIE) | |
3287 CLEAR_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYIE); | |
3288 #endif /* RCC_CIR_PLLSAIRDYIE */ | |
3289 | |
3290 /* Clear all interrupt flags */ | |
3291 SET_BIT(RCC->CIR, RCC_CIR_LSIRDYC | RCC_CIR_LSERDYC | RCC_CIR_HSIRDYC | RCC_CIR_HSERDYC | RCC_CIR_PLLRDYC | RCC_CIR_CSSC); | |
3292 | |
3293 #if defined(RCC_CIR_PLLI2SRDYC) | |
3294 SET_BIT(RCC->CIR, RCC_CIR_PLLI2SRDYC); | |
3295 #endif /* RCC_CIR_PLLI2SRDYC */ | |
3296 | |
3297 #if defined(RCC_CIR_PLLSAIRDYC) | |
3298 SET_BIT(RCC->CIR, RCC_CIR_PLLSAIRDYC); | |
3299 #endif /* RCC_CIR_PLLSAIRDYC */ | |
3300 | |
3301 /* Clear LSION bit */ | |
3302 CLEAR_BIT(RCC->CSR, RCC_CSR_LSION); | |
3303 | |
3304 /* Reset all CSR flags */ | |
3305 SET_BIT(RCC->CSR, RCC_CSR_RMVF); | |
3306 | |
3307 /* Update the SystemCoreClock global variable */ | |
3308 SystemCoreClock = HSI_VALUE; | |
3309 | |
3310 /* Adapt Systick interrupt period */ | |
3311 if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) | |
3312 { | |
3313 return HAL_ERROR; | |
3314 } | |
3315 else | |
3316 { | |
3317 return HAL_OK; | |
3318 } | |
3319 } | |
3320 | |
3321 #if defined(STM32F410Tx) || defined(STM32F410Cx) || defined(STM32F410Rx) || defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) ||\ | |
3322 defined(STM32F412Vx) || defined(STM32F412Rx) || defined(STM32F412Cx) || defined(STM32F413xx) || defined(STM32F423xx) | |
3323 /** | |
3324 * @brief Initializes the RCC Oscillators according to the specified parameters in the | |
3325 * RCC_OscInitTypeDef. | |
3326 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that | |
3327 * contains the configuration information for the RCC Oscillators. | |
3328 * @note The PLL is not disabled when used as system clock. | |
3329 * @note Transitions LSE Bypass to LSE On and LSE On to LSE Bypass are not | |
3330 * supported by this API. User should request a transition to LSE Off | |
3331 * first and then LSE On or LSE Bypass. | |
3332 * @note Transition HSE Bypass to HSE On and HSE On to HSE Bypass are not | |
3333 * supported by this API. User should request a transition to HSE Off | |
3334 * first and then HSE On or HSE Bypass. | |
3335 * @note This function add the PLL/PLLR factor management during PLL configuration this feature | |
3336 * is only available in STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices | |
3337 * @retval HAL status | |
3338 */ | |
3339 HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) | |
3340 { | |
3341 uint32_t tickstart = 0U; | |
3342 | |
3343 /* Check the parameters */ | |
3344 assert_param(IS_RCC_OSCILLATORTYPE(RCC_OscInitStruct->OscillatorType)); | |
3345 /*------------------------------- HSE Configuration ------------------------*/ | |
3346 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSE) == RCC_OSCILLATORTYPE_HSE) | |
3347 { | |
3348 /* Check the parameters */ | |
3349 assert_param(IS_RCC_HSE(RCC_OscInitStruct->HSEState)); | |
3350 /* When the HSE is used as system clock or clock source for PLL in these cases HSE will not disabled */ | |
3351 #if defined(STM32F446xx) | |
3352 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\ | |
3353 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE)) ||\ | |
3354 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE))) | |
3355 #else | |
3356 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSE) ||\ | |
3357 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSE))) | |
3358 #endif /* STM32F446xx */ | |
3359 { | |
3360 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) && (RCC_OscInitStruct->HSEState == RCC_HSE_OFF)) | |
3361 { | |
3362 return HAL_ERROR; | |
3363 } | |
3364 } | |
3365 else | |
3366 { | |
3367 /* Set the new HSE configuration ---------------------------------------*/ | |
3368 __HAL_RCC_HSE_CONFIG(RCC_OscInitStruct->HSEState); | |
3369 | |
3370 /* Check the HSE State */ | |
3371 if((RCC_OscInitStruct->HSEState) != RCC_HSE_OFF) | |
3372 { | |
3373 /* Get Start Tick*/ | |
3374 tickstart = HAL_GetTick(); | |
3375 | |
3376 /* Wait till HSE is ready */ | |
3377 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) == RESET) | |
3378 { | |
3379 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) | |
3380 { | |
3381 return HAL_TIMEOUT; | |
3382 } | |
3383 } | |
3384 } | |
3385 else | |
3386 { | |
3387 /* Get Start Tick*/ | |
3388 tickstart = HAL_GetTick(); | |
3389 | |
3390 /* Wait till HSE is bypassed or disabled */ | |
3391 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY) != RESET) | |
3392 { | |
3393 if((HAL_GetTick() - tickstart ) > HSE_TIMEOUT_VALUE) | |
3394 { | |
3395 return HAL_TIMEOUT; | |
3396 } | |
3397 } | |
3398 } | |
3399 } | |
3400 } | |
3401 /*----------------------------- HSI Configuration --------------------------*/ | |
3402 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_HSI) == RCC_OSCILLATORTYPE_HSI) | |
3403 { | |
3404 /* Check the parameters */ | |
3405 assert_param(IS_RCC_HSI(RCC_OscInitStruct->HSIState)); | |
3406 assert_param(IS_RCC_CALIBRATION_VALUE(RCC_OscInitStruct->HSICalibrationValue)); | |
3407 | |
3408 /* Check if HSI is used as system clock or as PLL source when PLL is selected as system clock */ | |
3409 #if defined(STM32F446xx) | |
3410 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\ | |
3411 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI)) ||\ | |
3412 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLLR) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI))) | |
3413 #else | |
3414 if((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_HSI) ||\ | |
3415 ((__HAL_RCC_GET_SYSCLK_SOURCE() == RCC_CFGR_SWS_PLL) && ((RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) == RCC_PLLCFGR_PLLSRC_HSI))) | |
3416 #endif /* STM32F446xx */ | |
3417 { | |
3418 /* When HSI is used as system clock it will not disabled */ | |
3419 if((__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) && (RCC_OscInitStruct->HSIState != RCC_HSI_ON)) | |
3420 { | |
3421 return HAL_ERROR; | |
3422 } | |
3423 /* Otherwise, just the calibration is allowed */ | |
3424 else | |
3425 { | |
3426 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ | |
3427 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); | |
3428 } | |
3429 } | |
3430 else | |
3431 { | |
3432 /* Check the HSI State */ | |
3433 if((RCC_OscInitStruct->HSIState)!= RCC_HSI_OFF) | |
3434 { | |
3435 /* Enable the Internal High Speed oscillator (HSI). */ | |
3436 __HAL_RCC_HSI_ENABLE(); | |
3437 | |
3438 /* Get Start Tick*/ | |
3439 tickstart = HAL_GetTick(); | |
3440 | |
3441 /* Wait till HSI is ready */ | |
3442 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) == RESET) | |
3443 { | |
3444 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) | |
3445 { | |
3446 return HAL_TIMEOUT; | |
3447 } | |
3448 } | |
3449 | |
3450 /* Adjusts the Internal High Speed oscillator (HSI) calibration value.*/ | |
3451 __HAL_RCC_HSI_CALIBRATIONVALUE_ADJUST(RCC_OscInitStruct->HSICalibrationValue); | |
3452 } | |
3453 else | |
3454 { | |
3455 /* Disable the Internal High Speed oscillator (HSI). */ | |
3456 __HAL_RCC_HSI_DISABLE(); | |
3457 | |
3458 /* Get Start Tick*/ | |
3459 tickstart = HAL_GetTick(); | |
3460 | |
3461 /* Wait till HSI is ready */ | |
3462 while(__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) | |
3463 { | |
3464 if((HAL_GetTick() - tickstart ) > HSI_TIMEOUT_VALUE) | |
3465 { | |
3466 return HAL_TIMEOUT; | |
3467 } | |
3468 } | |
3469 } | |
3470 } | |
3471 } | |
3472 /*------------------------------ LSI Configuration -------------------------*/ | |
3473 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSI) == RCC_OSCILLATORTYPE_LSI) | |
3474 { | |
3475 /* Check the parameters */ | |
3476 assert_param(IS_RCC_LSI(RCC_OscInitStruct->LSIState)); | |
3477 | |
3478 /* Check the LSI State */ | |
3479 if((RCC_OscInitStruct->LSIState)!= RCC_LSI_OFF) | |
3480 { | |
3481 /* Enable the Internal Low Speed oscillator (LSI). */ | |
3482 __HAL_RCC_LSI_ENABLE(); | |
3483 | |
3484 /* Get Start Tick*/ | |
3485 tickstart = HAL_GetTick(); | |
3486 | |
3487 /* Wait till LSI is ready */ | |
3488 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) == RESET) | |
3489 { | |
3490 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) | |
3491 { | |
3492 return HAL_TIMEOUT; | |
3493 } | |
3494 } | |
3495 } | |
3496 else | |
3497 { | |
3498 /* Disable the Internal Low Speed oscillator (LSI). */ | |
3499 __HAL_RCC_LSI_DISABLE(); | |
3500 | |
3501 /* Get Start Tick*/ | |
3502 tickstart = HAL_GetTick(); | |
3503 | |
3504 /* Wait till LSI is ready */ | |
3505 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSIRDY) != RESET) | |
3506 { | |
3507 if((HAL_GetTick() - tickstart ) > LSI_TIMEOUT_VALUE) | |
3508 { | |
3509 return HAL_TIMEOUT; | |
3510 } | |
3511 } | |
3512 } | |
3513 } | |
3514 /*------------------------------ LSE Configuration -------------------------*/ | |
3515 if(((RCC_OscInitStruct->OscillatorType) & RCC_OSCILLATORTYPE_LSE) == RCC_OSCILLATORTYPE_LSE) | |
3516 { | |
3517 FlagStatus pwrclkchanged = RESET; | |
3518 | |
3519 /* Check the parameters */ | |
3520 assert_param(IS_RCC_LSE(RCC_OscInitStruct->LSEState)); | |
3521 | |
3522 /* Update LSE configuration in Backup Domain control register */ | |
3523 /* Requires to enable write access to Backup Domain of necessary */ | |
3524 if(__HAL_RCC_PWR_IS_CLK_DISABLED()) | |
3525 { | |
3526 __HAL_RCC_PWR_CLK_ENABLE(); | |
3527 pwrclkchanged = SET; | |
3528 } | |
3529 | |
3530 if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) | |
3531 { | |
3532 /* Enable write access to Backup domain */ | |
3533 SET_BIT(PWR->CR, PWR_CR_DBP); | |
3534 | |
3535 /* Wait for Backup domain Write protection disable */ | |
3536 tickstart = HAL_GetTick(); | |
3537 | |
3538 while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP)) | |
3539 { | |
3540 if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE) | |
3541 { | |
3542 return HAL_TIMEOUT; | |
3543 } | |
3544 } | |
3545 } | |
3546 | |
3547 /* Set the new LSE configuration -----------------------------------------*/ | |
3548 __HAL_RCC_LSE_CONFIG(RCC_OscInitStruct->LSEState); | |
3549 /* Check the LSE State */ | |
3550 if((RCC_OscInitStruct->LSEState) != RCC_LSE_OFF) | |
3551 { | |
3552 /* Get Start Tick*/ | |
3553 tickstart = HAL_GetTick(); | |
3554 | |
3555 /* Wait till LSE is ready */ | |
3556 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) | |
3557 { | |
3558 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) | |
3559 { | |
3560 return HAL_TIMEOUT; | |
3561 } | |
3562 } | |
3563 } | |
3564 else | |
3565 { | |
3566 /* Get Start Tick*/ | |
3567 tickstart = HAL_GetTick(); | |
3568 | |
3569 /* Wait till LSE is ready */ | |
3570 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) != RESET) | |
3571 { | |
3572 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE) | |
3573 { | |
3574 return HAL_TIMEOUT; | |
3575 } | |
3576 } | |
3577 } | |
3578 | |
3579 /* Restore clock configuration if changed */ | |
3580 if(pwrclkchanged == SET) | |
3581 { | |
3582 __HAL_RCC_PWR_CLK_DISABLE(); | |
3583 } | |
3584 } | |
3585 /*-------------------------------- PLL Configuration -----------------------*/ | |
3586 /* Check the parameters */ | |
3587 assert_param(IS_RCC_PLL(RCC_OscInitStruct->PLL.PLLState)); | |
3588 if ((RCC_OscInitStruct->PLL.PLLState) != RCC_PLL_NONE) | |
3589 { | |
3590 /* Check if the PLL is used as system clock or not */ | |
3591 if(__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL) | |
3592 { | |
3593 if((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_ON) | |
3594 { | |
3595 /* Check the parameters */ | |
3596 assert_param(IS_RCC_PLLSOURCE(RCC_OscInitStruct->PLL.PLLSource)); | |
3597 assert_param(IS_RCC_PLLM_VALUE(RCC_OscInitStruct->PLL.PLLM)); | |
3598 assert_param(IS_RCC_PLLN_VALUE(RCC_OscInitStruct->PLL.PLLN)); | |
3599 assert_param(IS_RCC_PLLP_VALUE(RCC_OscInitStruct->PLL.PLLP)); | |
3600 assert_param(IS_RCC_PLLQ_VALUE(RCC_OscInitStruct->PLL.PLLQ)); | |
3601 assert_param(IS_RCC_PLLR_VALUE(RCC_OscInitStruct->PLL.PLLR)); | |
3602 | |
3603 /* Disable the main PLL. */ | |
3604 __HAL_RCC_PLL_DISABLE(); | |
3605 | |
3606 /* Get Start Tick*/ | |
3607 tickstart = HAL_GetTick(); | |
3608 | |
3609 /* Wait till PLL is ready */ | |
3610 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) | |
3611 { | |
3612 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) | |
3613 { | |
3614 return HAL_TIMEOUT; | |
3615 } | |
3616 } | |
3617 | |
3618 /* Configure the main PLL clock source, multiplication and division factors. */ | |
3619 __HAL_RCC_PLL_CONFIG(RCC_OscInitStruct->PLL.PLLSource, | |
3620 RCC_OscInitStruct->PLL.PLLM, | |
3621 RCC_OscInitStruct->PLL.PLLN, | |
3622 RCC_OscInitStruct->PLL.PLLP, | |
3623 RCC_OscInitStruct->PLL.PLLQ, | |
3624 RCC_OscInitStruct->PLL.PLLR); | |
3625 | |
3626 /* Enable the main PLL. */ | |
3627 __HAL_RCC_PLL_ENABLE(); | |
3628 | |
3629 /* Get Start Tick*/ | |
3630 tickstart = HAL_GetTick(); | |
3631 | |
3632 /* Wait till PLL is ready */ | |
3633 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) == RESET) | |
3634 { | |
3635 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) | |
3636 { | |
3637 return HAL_TIMEOUT; | |
3638 } | |
3639 } | |
3640 } | |
3641 else | |
3642 { | |
3643 /* Disable the main PLL. */ | |
3644 __HAL_RCC_PLL_DISABLE(); | |
3645 | |
3646 /* Get Start Tick*/ | |
3647 tickstart = HAL_GetTick(); | |
3648 | |
3649 /* Wait till PLL is ready */ | |
3650 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLRDY) != RESET) | |
3651 { | |
3652 if((HAL_GetTick() - tickstart ) > PLL_TIMEOUT_VALUE) | |
3653 { | |
3654 return HAL_TIMEOUT; | |
3655 } | |
3656 } | |
3657 } | |
3658 } | |
3659 else | |
3660 { | |
3661 return HAL_ERROR; | |
3662 } | |
3663 } | |
3664 return HAL_OK; | |
3665 } | |
3666 | |
3667 /** | |
3668 * @brief Configures the RCC_OscInitStruct according to the internal | |
3669 * RCC configuration registers. | |
3670 * @param RCC_OscInitStruct pointer to an RCC_OscInitTypeDef structure that will be configured. | |
3671 * | |
3672 * @note This function is only available in case of STM32F410xx/STM32F446xx/STM32F469xx/STM32F479xx/STM32F412Zx/STM32F412Vx/STM32F412Rx/STM32F412Cx devices. | |
3673 * @note This function add the PLL/PLLR factor management | |
3674 * @retval None | |
3675 */ | |
3676 void HAL_RCC_GetOscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct) | |
3677 { | |
3678 /* Set all possible values for the Oscillator type parameter ---------------*/ | |
3679 RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_LSE | RCC_OSCILLATORTYPE_LSI; | |
3680 | |
3681 /* Get the HSE configuration -----------------------------------------------*/ | |
3682 if((RCC->CR &RCC_CR_HSEBYP) == RCC_CR_HSEBYP) | |
3683 { | |
3684 RCC_OscInitStruct->HSEState = RCC_HSE_BYPASS; | |
3685 } | |
3686 else if((RCC->CR &RCC_CR_HSEON) == RCC_CR_HSEON) | |
3687 { | |
3688 RCC_OscInitStruct->HSEState = RCC_HSE_ON; | |
3689 } | |
3690 else | |
3691 { | |
3692 RCC_OscInitStruct->HSEState = RCC_HSE_OFF; | |
3693 } | |
3694 | |
3695 /* Get the HSI configuration -----------------------------------------------*/ | |
3696 if((RCC->CR &RCC_CR_HSION) == RCC_CR_HSION) | |
3697 { | |
3698 RCC_OscInitStruct->HSIState = RCC_HSI_ON; | |
3699 } | |
3700 else | |
3701 { | |
3702 RCC_OscInitStruct->HSIState = RCC_HSI_OFF; | |
3703 } | |
3704 | |
3705 RCC_OscInitStruct->HSICalibrationValue = (uint32_t)((RCC->CR &RCC_CR_HSITRIM) >> RCC_CR_HSITRIM_Pos); | |
3706 | |
3707 /* Get the LSE configuration -----------------------------------------------*/ | |
3708 if((RCC->BDCR &RCC_BDCR_LSEBYP) == RCC_BDCR_LSEBYP) | |
3709 { | |
3710 RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; | |
3711 } | |
3712 else if((RCC->BDCR &RCC_BDCR_LSEON) == RCC_BDCR_LSEON) | |
3713 { | |
3714 RCC_OscInitStruct->LSEState = RCC_LSE_ON; | |
3715 } | |
3716 else | |
3717 { | |
3718 RCC_OscInitStruct->LSEState = RCC_LSE_OFF; | |
3719 } | |
3720 | |
3721 /* Get the LSI configuration -----------------------------------------------*/ | |
3722 if((RCC->CSR &RCC_CSR_LSION) == RCC_CSR_LSION) | |
3723 { | |
3724 RCC_OscInitStruct->LSIState = RCC_LSI_ON; | |
3725 } | |
3726 else | |
3727 { | |
3728 RCC_OscInitStruct->LSIState = RCC_LSI_OFF; | |
3729 } | |
3730 | |
3731 /* Get the PLL configuration -----------------------------------------------*/ | |
3732 if((RCC->CR &RCC_CR_PLLON) == RCC_CR_PLLON) | |
3733 { | |
3734 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_ON; | |
3735 } | |
3736 else | |
3737 { | |
3738 RCC_OscInitStruct->PLL.PLLState = RCC_PLL_OFF; | |
3739 } | |
3740 RCC_OscInitStruct->PLL.PLLSource = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); | |
3741 RCC_OscInitStruct->PLL.PLLM = (uint32_t)(RCC->PLLCFGR & RCC_PLLCFGR_PLLM); | |
3742 RCC_OscInitStruct->PLL.PLLN = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); | |
3743 RCC_OscInitStruct->PLL.PLLP = (uint32_t)((((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) + RCC_PLLCFGR_PLLP_0) << 1U) >> RCC_PLLCFGR_PLLP_Pos); | |
3744 RCC_OscInitStruct->PLL.PLLQ = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLQ) >> RCC_PLLCFGR_PLLQ_Pos); | |
3745 RCC_OscInitStruct->PLL.PLLR = (uint32_t)((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos); | |
3746 } | |
3747 #endif /* STM32F410xx || STM32F446xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx || STM32F412Rx || STM32F412Cx || STM32F413xx || STM32F423xx */ | |
3748 | |
3749 #endif /* HAL_RCC_MODULE_ENABLED */ | |
3750 /** | |
3751 * @} | |
3752 */ | |
3753 | |
3754 /** | |
3755 * @} | |
3756 */ | |
3757 | |
3758 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ |