38
|
1 /**
|
|
2 ******************************************************************************
|
|
3 * @file stm32f4xx_hal_rcc_ex.c
|
|
4 * @author MCD Application Team
|
|
5 * @version V1.2.0
|
|
6 * @date 26-December-2014
|
|
7 * @brief Extension RCC HAL module driver.
|
|
8 * This file provides firmware functions to manage the following
|
|
9 * functionalities RCC extension peripheral:
|
|
10 * + Extended Peripheral Control functions
|
|
11 *
|
|
12 ******************************************************************************
|
|
13 * @attention
|
|
14 *
|
|
15 * <h2><center>© COPYRIGHT(c) 2014 STMicroelectronics</center></h2>
|
|
16 *
|
|
17 * Redistribution and use in source and binary forms, with or without modification,
|
|
18 * are permitted provided that the following conditions are met:
|
|
19 * 1. Redistributions of source code must retain the above copyright notice,
|
|
20 * this list of conditions and the following disclaimer.
|
|
21 * 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
22 * this list of conditions and the following disclaimer in the documentation
|
|
23 * and/or other materials provided with the distribution.
|
|
24 * 3. Neither the name of STMicroelectronics nor the names of its contributors
|
|
25 * may be used to endorse or promote products derived from this software
|
|
26 * without specific prior written permission.
|
|
27 *
|
|
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
31 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
34 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
35 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
36 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
38 *
|
|
39 ******************************************************************************
|
|
40 */
|
|
41
|
|
42 /* Includes ------------------------------------------------------------------*/
|
|
43 #include "stm32f4xx_hal.h"
|
|
44
|
|
45 /** @addtogroup STM32F4xx_HAL_Driver
|
|
46 * @{
|
|
47 */
|
|
48
|
|
49 /** @defgroup RCCEx RCCEx
|
|
50 * @brief RCCEx HAL module driver
|
|
51 * @{
|
|
52 */
|
|
53
|
|
54 #ifdef HAL_RCC_MODULE_ENABLED
|
|
55
|
|
56 /* Private typedef -----------------------------------------------------------*/
|
|
57 /* Private define ------------------------------------------------------------*/
|
|
58 /** @addtogroup RCCEx_Private_Constants
|
|
59 * @{
|
|
60 */
|
|
61 #define PLLI2S_TIMEOUT_VALUE 100 /* Timeout value fixed to 100 ms */
|
|
62 #define PLLSAI_TIMEOUT_VALUE 100 /* Timeout value fixed to 100 ms */
|
|
63 /**
|
|
64 * @}
|
|
65 */
|
|
66 /* Private macro -------------------------------------------------------------*/
|
|
67 /* Private variables ---------------------------------------------------------*/
|
|
68 /* Private function prototypes -----------------------------------------------*/
|
|
69 /* Private functions ---------------------------------------------------------*/
|
|
70 /** @defgroup RCCEx_Exported_Functions RCCEx Exported Functions
|
|
71 * @{
|
|
72 */
|
|
73
|
|
74 /** @defgroup RCCEx_Exported_Functions_Group1 Extended Peripheral Control functions
|
|
75 * @brief Extended Peripheral Control functions
|
|
76 *
|
|
77 @verbatim
|
|
78 ===============================================================================
|
|
79 ##### Extended Peripheral Control functions #####
|
|
80 ===============================================================================
|
|
81 [..]
|
|
82 This subsection provides a set of functions allowing to control the RCC Clocks
|
|
83 frequencies.
|
|
84 [..]
|
|
85 (@) Important note: Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to
|
|
86 select the RTC clock source; in this case the Backup domain will be reset in
|
|
87 order to modify the RTC Clock source, as consequence RTC registers (including
|
|
88 the backup registers) and RCC_BDCR register are set to their reset values.
|
|
89
|
|
90 @endverbatim
|
|
91 * @{
|
|
92 */
|
|
93 #if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx)|| defined(STM32F439xx)
|
|
94 /**
|
|
95 * @brief Initializes the RCC extended peripherals clocks according to the specified
|
|
96 * parameters in the RCC_PeriphCLKInitTypeDef.
|
|
97 * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
|
|
98 * contains the configuration information for the Extended Peripherals
|
|
99 * clocks(I2S, SAI, LTDC RTC and TIM).
|
|
100 *
|
|
101 * @note Care must be taken when HAL_RCCEx_PeriphCLKConfig() is used to select
|
|
102 * the RTC clock source; in this case the Backup domain will be reset in
|
|
103 * order to modify the RTC Clock source, as consequence RTC registers (including
|
|
104 * the backup registers) and RCC_BDCR register are set to their reset values.
|
|
105 *
|
|
106 * @retval HAL status
|
|
107 */
|
|
108 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
|
109 {
|
|
110 uint32_t tickstart = 0;
|
|
111 uint32_t tmpreg = 0;
|
|
112
|
|
113 /* Check the parameters */
|
|
114 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
|
|
115
|
|
116 /*----------------------- SAI/I2S Configuration (PLLI2S) -------------------------*/
|
|
117
|
|
118 /*----------------------- Common configuration SAI/I2S ---------------------------*/
|
|
119 /* In Case of SAI or I2S Clock Configuration through PLLI2S, PLLI2SN division
|
|
120 factor is common parameters for both peripherals */
|
|
121 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == RCC_PERIPHCLK_I2S) ||
|
|
122 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == RCC_PERIPHCLK_SAI_PLLI2S))
|
|
123 {
|
|
124 /* check for Parameters */
|
|
125 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
|
|
126
|
|
127 /* Disable the PLLI2S */
|
|
128 __HAL_RCC_PLLI2S_DISABLE();
|
|
129 /* Get tick */
|
|
130 tickstart = HAL_GetTick();
|
|
131 /* Wait till PLLI2S is disabled */
|
|
132 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
|
|
133 {
|
|
134 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
|
|
135 {
|
|
136 /* return in case of Timeout detected */
|
|
137 return HAL_TIMEOUT;
|
|
138 }
|
|
139 }
|
|
140
|
|
141 /*---------------------------- I2S configuration -------------------------------*/
|
|
142 /* In Case of I2S Clock Configuration through PLLI2S, PLLI2SR must be added
|
|
143 only for I2S configuration */
|
|
144 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
|
|
145 {
|
|
146 /* check for Parameters */
|
|
147 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
|
|
148 /* Configure the PLLI2S division factors */
|
|
149 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) */
|
|
150 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
|
|
151 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
|
|
152 }
|
|
153
|
|
154 /*---------------------------- SAI configuration -------------------------------*/
|
|
155 /* In Case of SAI Clock Configuration through PLLI2S, PLLI2SQ and PLLI2S_DIVQ must
|
|
156 be added only for SAI configuration */
|
|
157 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLI2S) == (RCC_PERIPHCLK_SAI_PLLI2S))
|
|
158 {
|
|
159 /* Check the PLLI2S division factors */
|
|
160 assert_param(IS_RCC_PLLI2SQ_VALUE(PeriphClkInit->PLLI2S.PLLI2SQ));
|
|
161 assert_param(IS_RCC_PLLI2S_DIVQ_VALUE(PeriphClkInit->PLLI2SDivQ));
|
|
162
|
|
163 /* Read PLLI2SR value from PLLI2SCFGR register (this value is not need for SAI configuration) */
|
|
164 tmpreg = ((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
|
|
165 /* Configure the PLLI2S division factors */
|
|
166 /* PLLI2S_VCO Input = PLL_SOURCE/PLLM */
|
|
167 /* PLLI2S_VCO Output = PLLI2S_VCO Input * PLLI2SN */
|
|
168 /* SAI_CLK(first level) = PLLI2S_VCO Output/PLLI2SQ */
|
|
169 __HAL_RCC_PLLI2S_SAICLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SQ , tmpreg);
|
|
170 /* SAI_CLK_x = SAI_CLK(first level)/PLLI2SDIVQ */
|
|
171 __HAL_RCC_PLLI2S_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLI2SDivQ);
|
|
172 }
|
|
173
|
|
174 /* Enable the PLLI2S */
|
|
175 __HAL_RCC_PLLI2S_ENABLE();
|
|
176 /* Get tick */
|
|
177 tickstart = HAL_GetTick();
|
|
178 /* Wait till PLLI2S is ready */
|
|
179 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
|
|
180 {
|
|
181 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
|
|
182 {
|
|
183 /* return in case of Timeout detected */
|
|
184 return HAL_TIMEOUT;
|
|
185 }
|
|
186 }
|
|
187 }
|
|
188
|
|
189 /*----------------------- SAI/LTDC Configuration (PLLSAI) ------------------*/
|
|
190
|
|
191 /*----------------------- Common configuration SAI/LTDC --------------------*/
|
|
192 /* In Case of SAI or LTDC Clock Configuration through PLLSAI, PLLSAIN division
|
|
193 factor is common parameters for both peripherals */
|
|
194 if((((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == RCC_PERIPHCLK_SAI_PLLSAI) ||
|
|
195 (((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == RCC_PERIPHCLK_LTDC))
|
|
196 {
|
|
197 /* Check the PLLSAI division factors */
|
|
198 assert_param(IS_RCC_PLLSAIN_VALUE(PeriphClkInit->PLLSAI.PLLSAIN));
|
|
199
|
|
200 /* Disable PLLSAI Clock */
|
|
201 __HAL_RCC_PLLSAI_DISABLE();
|
|
202 /* Get tick */
|
|
203 tickstart = HAL_GetTick();
|
|
204 /* Wait till PLLSAI is disabled */
|
|
205 while(__HAL_RCC_PLLSAI_GET_FLAG() != RESET)
|
|
206 {
|
|
207 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
|
|
208 {
|
|
209 /* return in case of Timeout detected */
|
|
210 return HAL_TIMEOUT;
|
|
211 }
|
|
212 }
|
|
213
|
|
214 /*---------------------------- SAI configuration -------------------------*/
|
|
215 /* In Case of SAI Clock Configuration through PLLSAI, PLLSAIQ and PLLSAI_DIVQ must
|
|
216 be added only for SAI configuration */
|
|
217 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_SAI_PLLSAI) == (RCC_PERIPHCLK_SAI_PLLSAI))
|
|
218 {
|
|
219 assert_param(IS_RCC_PLLSAIQ_VALUE(PeriphClkInit->PLLSAI.PLLSAIQ));
|
|
220 assert_param(IS_RCC_PLLSAI_DIVQ_VALUE(PeriphClkInit->PLLSAIDivQ));
|
|
221
|
|
222 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
|
|
223 tmpreg = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
|
|
224 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
|
|
225 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
|
|
226 /* SAI_CLK(first level) = PLLSAI_VCO Output/PLLSAIQ */
|
|
227 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , PeriphClkInit->PLLSAI.PLLSAIQ, tmpreg);
|
|
228 /* SAI_CLK_x = SAI_CLK(first level)/PLLSAIDIVQ */
|
|
229 __HAL_RCC_PLLSAI_PLLSAICLKDIVQ_CONFIG(PeriphClkInit->PLLSAIDivQ);
|
|
230 }
|
|
231
|
|
232 /*---------------------------- LTDC configuration ------------------------*/
|
|
233 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_LTDC) == (RCC_PERIPHCLK_LTDC))
|
|
234 {
|
|
235 assert_param(IS_RCC_PLLSAIR_VALUE(PeriphClkInit->PLLSAI.PLLSAIR));
|
|
236 assert_param(IS_RCC_PLLSAI_DIVR_VALUE(PeriphClkInit->PLLSAIDivR));
|
|
237
|
|
238 /* Read PLLSAIR value from PLLSAICFGR register (this value is not need for SAI configuration) */
|
|
239 tmpreg = ((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
|
|
240 /* PLLSAI_VCO Input = PLL_SOURCE/PLLM */
|
|
241 /* PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN */
|
|
242 /* LTDC_CLK(first level) = PLLSAI_VCO Output/PLLSAIR */
|
|
243 __HAL_RCC_PLLSAI_CONFIG(PeriphClkInit->PLLSAI.PLLSAIN , tmpreg, PeriphClkInit->PLLSAI.PLLSAIR);
|
|
244 /* LTDC_CLK = LTDC_CLK(first level)/PLLSAIDIVR */
|
|
245 __HAL_RCC_PLLSAI_PLLSAICLKDIVR_CONFIG(PeriphClkInit->PLLSAIDivR);
|
|
246 }
|
|
247 /* Enable PLLSAI Clock */
|
|
248 __HAL_RCC_PLLSAI_ENABLE();
|
|
249 /* Get tick */
|
|
250 tickstart = HAL_GetTick();
|
|
251 /* Wait till PLLSAI is ready */
|
|
252 while(__HAL_RCC_PLLSAI_GET_FLAG() == RESET)
|
|
253 {
|
|
254 if((HAL_GetTick() - tickstart ) > PLLSAI_TIMEOUT_VALUE)
|
|
255 {
|
|
256 /* return in case of Timeout detected */
|
|
257 return HAL_TIMEOUT;
|
|
258 }
|
|
259 }
|
|
260 }
|
|
261
|
|
262
|
|
263 /*---------------------------- RTC configuration ---------------------------*/
|
|
264 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
|
|
265 {
|
|
266 /* Enable Power Clock*/
|
|
267 __HAL_RCC_PWR_CLK_ENABLE();
|
|
268
|
|
269 /* Enable write access to Backup domain */
|
|
270 PWR->CR |= PWR_CR_DBP;
|
|
271
|
|
272 /* Get tick */
|
|
273 tickstart = HAL_GetTick();
|
|
274
|
|
275 while((PWR->CR & PWR_CR_DBP) == RESET)
|
|
276 {
|
|
277 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
|
|
278 {
|
|
279 return HAL_TIMEOUT;
|
|
280 }
|
|
281 }
|
|
282
|
|
283 /* Reset the Backup domain only if the RTC Clock source selection is modified */
|
|
284 if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
|
|
285 {
|
|
286 /* Store the content of BDCR register before the reset of Backup Domain */
|
|
287 tmpreg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
|
|
288 /* RTC Clock selection can be changed only if the Backup Domain is reset */
|
|
289 __HAL_RCC_BACKUPRESET_FORCE();
|
|
290 __HAL_RCC_BACKUPRESET_RELEASE();
|
|
291 /* Restore the Content of BDCR register */
|
|
292 RCC->BDCR = tmpreg;
|
|
293 }
|
|
294
|
|
295 /* If LSE is selected as RTC clock source, wait for LSE reactivation */
|
|
296 if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
|
|
297 {
|
|
298 /* Get tick */
|
|
299 tickstart = HAL_GetTick();
|
|
300
|
|
301 /* Wait till LSE is ready */
|
|
302 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
|
|
303 {
|
|
304 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
|
|
305 {
|
|
306 return HAL_TIMEOUT;
|
|
307 }
|
|
308 }
|
|
309 }
|
|
310 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
|
|
311 }
|
|
312
|
|
313 /*---------------------------- TIM configuration ---------------------------*/
|
|
314 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_TIM) == (RCC_PERIPHCLK_TIM))
|
|
315 {
|
|
316 __HAL_RCC_TIMCLKPRESCALER(PeriphClkInit->TIMPresSelection);
|
|
317 }
|
|
318 return HAL_OK;
|
|
319 }
|
|
320
|
|
321 /**
|
|
322 * @brief Configures the RCC_OscInitStruct according to the internal
|
|
323 * RCC configuration registers.
|
|
324 * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
|
|
325 * will be configured.
|
|
326 * @retval None
|
|
327 */
|
|
328 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
|
329 {
|
|
330 uint32_t tempreg;
|
|
331
|
|
332 /* Set all possible values for the extended clock type parameter------------*/
|
|
333 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_SAI_PLLSAI | RCC_PERIPHCLK_SAI_PLLI2S | RCC_PERIPHCLK_LTDC | RCC_PERIPHCLK_TIM | RCC_PERIPHCLK_RTC;
|
|
334
|
|
335 /* Get the PLLI2S Clock configuration -----------------------------------------------*/
|
|
336 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
|
|
337 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
|
|
338 PeriphClkInit->PLLI2S.PLLI2SQ = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SQ) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SQ));
|
|
339 /* Get the PLLSAI Clock configuration -----------------------------------------------*/
|
|
340 PeriphClkInit->PLLSAI.PLLSAIN = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIN) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIN));
|
|
341 PeriphClkInit->PLLSAI.PLLSAIR = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIR) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIR));
|
|
342 PeriphClkInit->PLLSAI.PLLSAIQ = (uint32_t)((RCC->PLLSAICFGR & RCC_PLLSAICFGR_PLLSAIQ) >> POSITION_VAL(RCC_PLLSAICFGR_PLLSAIQ));
|
|
343 /* Get the PLLSAI/PLLI2S division factors -----------------------------------------------*/
|
|
344 PeriphClkInit->PLLI2SDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLI2SDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLI2SDIVQ));
|
|
345 PeriphClkInit->PLLSAIDivQ = (uint32_t)((RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVQ) >> POSITION_VAL(RCC_DCKCFGR_PLLSAIDIVQ));
|
|
346 PeriphClkInit->PLLSAIDivR = (uint32_t)(RCC->DCKCFGR & RCC_DCKCFGR_PLLSAIDIVR);
|
|
347 /* Get the RTC Clock configuration -----------------------------------------------*/
|
|
348 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
|
|
349 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
|
|
350
|
|
351 if ((RCC->DCKCFGR & RCC_DCKCFGR_TIMPRE) == RESET)
|
|
352 {
|
|
353 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_DESACTIVATED;
|
|
354 }
|
|
355 else
|
|
356 {
|
|
357 PeriphClkInit->TIMPresSelection = RCC_TIMPRES_ACTIVATED;
|
|
358 }
|
|
359 }
|
|
360 #endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
|
|
361
|
|
362 #if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx) ||\
|
|
363 defined(STM32F401xC) || defined(STM32F401xE) || defined(STM32F411xE)
|
|
364 /**
|
|
365 * @brief Initializes the RCC extended peripherals clocks according to the specified parameters in the
|
|
366 * RCC_PeriphCLKInitTypeDef.
|
|
367 * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
|
|
368 * contains the configuration information for the Extended Peripherals clocks(I2S and RTC clocks).
|
|
369 *
|
|
370 * @note A caution to be taken when HAL_RCCEx_PeriphCLKConfig() is used to select RTC clock selection, in this case
|
|
371 * the Reset of Backup domain will be applied in order to modify the RTC Clock source as consequence all backup
|
|
372 * domain (RTC and RCC_BDCR register expect BKPSRAM) will be reset
|
|
373 *
|
|
374 * @retval HAL status
|
|
375 */
|
|
376 HAL_StatusTypeDef HAL_RCCEx_PeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
|
377 {
|
|
378 uint32_t tickstart = 0;
|
|
379 uint32_t tmpreg = 0;
|
|
380
|
|
381 /* Check the parameters */
|
|
382 assert_param(IS_RCC_PERIPHCLOCK(PeriphClkInit->PeriphClockSelection));
|
|
383
|
|
384 /*---------------------------- I2S configuration ---------------------------*/
|
|
385 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_I2S) == (RCC_PERIPHCLK_I2S))
|
|
386 {
|
|
387 /* check for Parameters */
|
|
388 assert_param(IS_RCC_PLLI2SR_VALUE(PeriphClkInit->PLLI2S.PLLI2SR));
|
|
389 assert_param(IS_RCC_PLLI2SN_VALUE(PeriphClkInit->PLLI2S.PLLI2SN));
|
|
390 #if defined(STM32F411xE)
|
|
391 assert_param(IS_RCC_PLLI2SM_VALUE(PeriphClkInit->PLLI2S.PLLI2SM));
|
|
392 #endif /* STM32F411xE */
|
|
393 /* Disable the PLLI2S */
|
|
394 __HAL_RCC_PLLI2S_DISABLE();
|
|
395 /* Get tick */
|
|
396 tickstart = HAL_GetTick();
|
|
397 /* Wait till PLLI2S is disabled */
|
|
398 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) != RESET)
|
|
399 {
|
|
400 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
|
|
401 {
|
|
402 /* return in case of Timeout detected */
|
|
403 return HAL_TIMEOUT;
|
|
404 }
|
|
405 }
|
|
406
|
|
407 #if defined(STM32F411xE)
|
|
408 /* Configure the PLLI2S division factors */
|
|
409 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLI2SM) */
|
|
410 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
|
|
411 __HAL_RCC_PLLI2S_I2SCLK_CONFIG(PeriphClkInit->PLLI2S.PLLI2SM, PeriphClkInit->PLLI2S.PLLI2SN, PeriphClkInit->PLLI2S.PLLI2SR);
|
|
412 #else
|
|
413 /* Configure the PLLI2S division factors */
|
|
414 /* PLLI2S_VCO = f(VCO clock) = f(PLLI2S clock input) × (PLLI2SN/PLLM) */
|
|
415 /* I2SCLK = f(PLLI2S clock output) = f(VCO clock) / PLLI2SR */
|
|
416 __HAL_RCC_PLLI2S_CONFIG(PeriphClkInit->PLLI2S.PLLI2SN , PeriphClkInit->PLLI2S.PLLI2SR);
|
|
417 #endif /* STM32F411xE */
|
|
418
|
|
419 /* Enable the PLLI2S */
|
|
420 __HAL_RCC_PLLI2S_ENABLE();
|
|
421 /* Get tick */
|
|
422 tickstart = HAL_GetTick();
|
|
423 /* Wait till PLLI2S is ready */
|
|
424 while(__HAL_RCC_GET_FLAG(RCC_FLAG_PLLI2SRDY) == RESET)
|
|
425 {
|
|
426 if((HAL_GetTick() - tickstart ) > PLLI2S_TIMEOUT_VALUE)
|
|
427 {
|
|
428 /* return in case of Timeout detected */
|
|
429 return HAL_TIMEOUT;
|
|
430 }
|
|
431 }
|
|
432 }
|
|
433
|
|
434 /*---------------------------- RTC configuration ---------------------------*/
|
|
435 if(((PeriphClkInit->PeriphClockSelection) & RCC_PERIPHCLK_RTC) == (RCC_PERIPHCLK_RTC))
|
|
436 {
|
|
437 /* Enable Power Clock*/
|
|
438 __HAL_RCC_PWR_CLK_ENABLE();
|
|
439
|
|
440 /* Enable write access to Backup domain */
|
|
441 PWR->CR |= PWR_CR_DBP;
|
|
442
|
|
443 /* Get tick */
|
|
444 tickstart = HAL_GetTick();
|
|
445
|
|
446 while((PWR->CR & PWR_CR_DBP) == RESET)
|
|
447 {
|
|
448 if((HAL_GetTick() - tickstart ) > RCC_DBP_TIMEOUT_VALUE)
|
|
449 {
|
|
450 return HAL_TIMEOUT;
|
|
451 }
|
|
452 }
|
|
453
|
|
454 /* Reset the Backup domain only if the RTC Clock source selection is modified */
|
|
455 if((RCC->BDCR & RCC_BDCR_RTCSEL) != (PeriphClkInit->RTCClockSelection & RCC_BDCR_RTCSEL))
|
|
456 {
|
|
457 /* Store the content of BDCR register before the reset of Backup Domain */
|
|
458 tmpreg = (RCC->BDCR & ~(RCC_BDCR_RTCSEL));
|
|
459 /* RTC Clock selection can be changed only if the Backup Domain is reset */
|
|
460 __HAL_RCC_BACKUPRESET_FORCE();
|
|
461 __HAL_RCC_BACKUPRESET_RELEASE();
|
|
462 /* Restore the Content of BDCR register */
|
|
463 RCC->BDCR = tmpreg;
|
|
464 }
|
|
465
|
|
466 /* If LSE is selected as RTC clock source, wait for LSE reactivation */
|
|
467 if(PeriphClkInit->RTCClockSelection == RCC_RTCCLKSOURCE_LSE)
|
|
468 {
|
|
469 /* Get tick */
|
|
470 tickstart = HAL_GetTick();
|
|
471
|
|
472 /* Wait till LSE is ready */
|
|
473 while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET)
|
|
474 {
|
|
475 if((HAL_GetTick() - tickstart ) > RCC_LSE_TIMEOUT_VALUE)
|
|
476 {
|
|
477 return HAL_TIMEOUT;
|
|
478 }
|
|
479 }
|
|
480 }
|
|
481 __HAL_RCC_RTC_CONFIG(PeriphClkInit->RTCClockSelection);
|
|
482 }
|
|
483
|
|
484 return HAL_OK;
|
|
485 }
|
|
486
|
|
487 /**
|
|
488 * @brief Configures the RCC_OscInitStruct according to the internal
|
|
489 * RCC configuration registers.
|
|
490 * @param PeriphClkInit: pointer to an RCC_PeriphCLKInitTypeDef structure that
|
|
491 * will be configured.
|
|
492 * @retval None
|
|
493 */
|
|
494 void HAL_RCCEx_GetPeriphCLKConfig(RCC_PeriphCLKInitTypeDef *PeriphClkInit)
|
|
495 {
|
|
496 uint32_t tempreg;
|
|
497
|
|
498 /* Set all possible values for the extended clock type parameter------------*/
|
|
499 PeriphClkInit->PeriphClockSelection = RCC_PERIPHCLK_I2S | RCC_PERIPHCLK_RTC;
|
|
500
|
|
501 /* Get the PLLI2S Clock configuration -----------------------------------------------*/
|
|
502 PeriphClkInit->PLLI2S.PLLI2SN = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SN) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SN));
|
|
503 PeriphClkInit->PLLI2S.PLLI2SR = (uint32_t)((RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SR) >> POSITION_VAL(RCC_PLLI2SCFGR_PLLI2SR));
|
|
504 #if defined(STM32F411xE)
|
|
505 PeriphClkInit->PLLI2S.PLLI2SM = (uint32_t)(RCC->PLLI2SCFGR & RCC_PLLI2SCFGR_PLLI2SM);
|
|
506 #endif /* STM32F411xE */
|
|
507 /* Get the RTC Clock configuration -----------------------------------------------*/
|
|
508 tempreg = (RCC->CFGR & RCC_CFGR_RTCPRE);
|
|
509 PeriphClkInit->RTCClockSelection = (uint32_t)((tempreg) | (RCC->BDCR & RCC_BDCR_RTCSEL));
|
|
510
|
|
511 }
|
|
512 #endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F401xC || STM32F401xE || STM32F411xE */
|
|
513
|
|
514 #if defined(STM32F411xE)
|
|
515 /**
|
|
516 * @brief Select LSE mode
|
|
517 *
|
|
518 * @note This mode is only available for STM32F411xx devices.
|
|
519 *
|
|
520 * @param Mode: specifies the LSE mode.
|
|
521 * This parameter can be one of the following values:
|
|
522 * @arg RCC_LSE_LOWPOWER_MODE: LSE oscillator in low power mode selection
|
|
523 * @arg RCC_LSE_HIGHDRIVE_MODE: LSE oscillator in High Drive mode selection
|
|
524 * @retval None
|
|
525 */
|
|
526 void HAL_RCCEx_SelectLSEMode(uint8_t Mode)
|
|
527 {
|
|
528 /* Check the parameters */
|
|
529 assert_param(IS_RCC_LSE_MODE(Mode));
|
|
530 if(Mode == RCC_LSE_HIGHDRIVE_MODE)
|
|
531 {
|
|
532 SET_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
|
|
533 }
|
|
534 else
|
|
535 {
|
|
536 CLEAR_BIT(RCC->BDCR, RCC_BDCR_LSEMOD);
|
|
537 }
|
|
538 }
|
|
539
|
|
540 #endif /* STM32F411xE */
|
|
541
|
|
542 /**
|
|
543 * @}
|
|
544 */
|
|
545
|
|
546 /**
|
|
547 * @}
|
|
548 */
|
|
549
|
|
550 #endif /* HAL_RCC_MODULE_ENABLED */
|
|
551 /**
|
|
552 * @}
|
|
553 */
|
|
554
|
|
555 /**
|
|
556 * @}
|
|
557 */
|
|
558
|
|
559 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|