before merging master
[inav.git] / lib / main / AT32F43x / Drivers / AT32F43x_StdPeriph_Driver / src / at32f435_437_crm.c
blobc8523ba41e730dc70243ce990f365a4291ae677d
1 /**
2 **************************************************************************
3 * @file at32f435_437_crm.c
4 * @version v2.1.0
5 * @date 2022-08-16
6 * @brief contains all the functions for the crm firmware library
7 **************************************************************************
8 * Copyright notice & Disclaimer
10 * The software Board Support Package (BSP) that is made available to
11 * download from Artery official website is the copyrighted work of Artery.
12 * Artery authorizes customers to use, copy, and distribute the BSP
13 * software and its related documentation for the purpose of design and
14 * development in conjunction with Artery microcontrollers. Use of the
15 * software is governed by this copyright notice and the following disclaimer.
17 * THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
18 * GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
19 * TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
20 * STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
21 * INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
24 **************************************************************************
27 #include "at32f435_437_conf.h"
29 /** @addtogroup AT32F435_437_periph_driver
30 * @{
33 /** @defgroup CRM
34 * @brief CRM driver modules
35 * @{
38 #ifdef CRM_MODULE_ENABLED
40 /** @defgroup CRM_private_functions
41 * @{
44 /**
45 * @brief reset the crm register
46 * @param none
47 * @retval none
49 void crm_reset(void)
51 /* reset the crm clock configuration to the default reset state(for debug purpose) */
52 /* set hicken bit */
53 CRM->ctrl_bit.hicken = TRUE;
55 /* wait hick stable */
56 while(CRM->ctrl_bit.hickstbl != SET);
58 /* hick used as system clock */
59 CRM->cfg_bit.sclksel = CRM_SCLK_HICK;
61 /* wait sclk switch status */
62 while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK);
64 /* reset hexten, hextbyps, cfden and pllen bits */
65 CRM->ctrl &= ~(0x010D0000U);
67 /* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv, clkout bits */
68 CRM->cfg = 0;
70 /* reset pllms pllns pllfr pllrcs bits */
71 CRM->pllcfg = 0x00033002U;
73 /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */
74 CRM->misc1 = 0;
76 /* disable all interrupts enable and clear pending bits */
77 CRM->clkint = 0x009F0000U;
80 /**
81 * @brief enable or disable crm low speed external crystal bypass
82 * @param new_state (TRUE or FALSE)
83 * @retval none
85 void crm_lext_bypass(confirm_state new_state)
87 CRM->bpdc_bit.lextbyps = new_state;
90 /**
91 * @brief enable or disable crm high speed external crystal bypass
92 * @param new_state (TRUE or FALSE)
93 * @retval none
95 void crm_hext_bypass(confirm_state new_state)
97 CRM->ctrl_bit.hextbyps = new_state;
101 * @brief get crm flag status
102 * @param flag
103 * this parameter can be one of the following values:
104 * - CRM_HICK_STABLE_FLAG
105 * - CRM_HEXT_STABLE_FLAG
106 * - CRM_PLL_STABLE_FLAG
107 * - CRM_LEXT_STABLE_FLAG
108 * - CRM_LICK_STABLE_FLAG
109 * - CRM_PIN_RESET_FLAG
110 * - CRM_POR_RESET_FLAG
111 * - CRM_SW_RESET_FLAG
112 * - CRM_WDT_RESET_FLAG
113 * - CRM_WWDT_RESET_FLAG
114 * - CRM_LOWPOWER_RESET_FLAG
115 * interrupt flag:
116 * - CRM_LICK_READY_INT_FLAG
117 * - CRM_LEXT_READY_INT_FLAG
118 * - CRM_HICK_READY_INT_FLAG
119 * - CRM_HEXT_READY_INT_FLAG
120 * - CRM_PLL_READY_INT_FLAG
121 * - CRM_CLOCK_FAILURE_INT_FLAG
122 * @retval flag_status (SET or RESET)
124 flag_status crm_flag_get(uint32_t flag)
126 flag_status status = RESET;
127 if((CRM_REG(flag) & CRM_REG_BIT(flag)) != CRM_REG_BIT(flag))
129 status = RESET;
131 else
133 status = SET;
135 return status;
139 * @brief wait for hext stable
140 * @param none
141 * @retval error_status (ERROR or SUCCESS)
143 error_status crm_hext_stable_wait(void)
145 uint32_t stable_cnt = 0;
146 error_status status = ERROR;
148 while((crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET) && (stable_cnt < HEXT_STARTUP_TIMEOUT))
150 stable_cnt ++;
153 if(crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET)
155 status = ERROR;
157 else
159 status = SUCCESS;
162 return status;
166 * @brief set the hick trimming value
167 * @param trim_value (0x00~0x3F)
168 * @retval none
170 void crm_hick_clock_trimming_set(uint8_t trim_value)
172 CRM->ctrl_bit.hicktrim = trim_value;
176 * @brief set the crm calibration value
177 * @param cali_value (0x00~0xFF)
178 * @retval none
180 void crm_hick_clock_calibration_set(uint8_t cali_value)
182 /* enable write hick calibration */
183 CRM->misc1_bit.hickcal_key = 0x5A;
185 /* write hick calibration value */
186 CRM->ctrl_bit.hickcal = cali_value;
188 /* disable write hick calibration */
189 CRM->misc1_bit.hickcal_key = 0x0;
193 * @brief enable or disable the peripheral clock
194 * @param value
195 * this parameter can be one of the following values:
196 * - CRM_GPIOA_PERIPH_CLOCK - CRM_GPIOB_PERIPH_CLOCK - CRM_GPIOC_PERIPH_CLOCK - CRM_GPIOD_PERIPH_CLOCK
197 * - CRM_GPIOE_PERIPH_CLOCK - CRM_GPIOF_PERIPH_CLOCK - CRM_GPIOG_PERIPH_CLOCK - CRM_GPIOH_PERIPH_CLOCK
198 * - CRM_CRC_PERIPH_CLOCK - CRM_EDMA_PERIPH_CLOCK - CRM_DMA1_PERIPH_CLOCK - CRM_DMA2_PERIPH_CLOCK
199 * - CRM_EMAC_PERIPH_CLOCK - CRM_EMACTX_PERIPH_CLOCK - CRM_EMACRX_PERIPH_CLOCK - CRM_EMACPTP_PERIPH_CLOCK
200 * - CRM_OTGFS2_PERIPH_CLOCK - CRM_DVP_PERIPH_CLOCK - CRM_OTGFS1_PERIPH_CLOCK - CRM_SDIO1_PERIPH_CLOCK
201 * - CRM_XMC_PERIPH_CLOCK - CRM_QSPI1_PERIPH_CLOCK - CRM_QSPI2_PERIPH_CLOCK - CRM_SDIO2_PERIPH_CLOCK
202 * - CRM_TMR2_PERIPH_CLOCK - CRM_TMR3_PERIPH_CLOCK - CRM_TMR4_PERIPH_CLOCK - CRM_TMR5_PERIPH_CLOCK
203 * - CRM_TMR6_PERIPH_CLOCK - CRM_TMR7_PERIPH_CLOCK - CRM_TMR12_PERIPH_CLOCK - CRM_TMR13_PERIPH_CLOCK
204 * - CRM_TMR14_PERIPH_CLOCK - CRM_WWDT_PERIPH_CLOCK - CRM_SPI2_PERIPH_CLOCK - CRM_SPI3_PERIPH_CLOCK
205 * - CRM_USART2_PERIPH_CLOCK - CRM_USART3_PERIPH_CLOCK - CRM_UART4_PERIPH_CLOCK - CRM_UART5_PERIPH_CLOCK
206 * - CRM_I2C1_PERIPH_CLOCK - CRM_I2C2_PERIPH_CLOCK - CRM_I2C3_PERIPH_CLOCK - CRM_CAN1_PERIPH_CLOCK
207 * - CRM_CAN2_PERIPH_CLOCK - CRM_PWC_PERIPH_CLOCK - CRM_DAC_PERIPH_CLOCK - CRM_UART7_PERIPH_CLOCK
208 * - CRM_UART8_PERIPH_CLOCK - CRM_TMR1_PERIPH_CLOCK - CRM_TMR8_PERIPH_CLOCK - CRM_USART1_PERIPH_CLOCK
209 * - CRM_USART6_PERIPH_CLOCK - CRM_ADC1_PERIPH_CLOCK - CRM_ADC2_PERIPH_CLOCK - CRM_ADC3_PERIPH_CLOCK
210 * - CRM_SPI1_PERIPH_CLOCK - CRM_SPI4_PERIPH_CLOCK - CRM_SCFG_PERIPH_CLOCK - CRM_TMR9_PERIPH_CLOCK
211 * - CRM_TMR10_PERIPH_CLOCK - CRM_TMR11_PERIPH_CLOCK - CRM_TMR20_PERIPH_CLOCK - CRM_ACC_PERIPH_CLOCK
212 * @param new_state (TRUE or FALSE)
213 * @retval none
215 void crm_periph_clock_enable(crm_periph_clock_type value, confirm_state new_state)
217 /* enable periph clock */
218 if(TRUE == new_state)
220 CRM_REG(value) |= CRM_REG_BIT(value);
222 /* disable periph clock */
223 else
225 CRM_REG(value) &= ~(CRM_REG_BIT(value));
230 * @brief enable or disable the peripheral reset
231 * @param value
232 * this parameter can be one of the following values:
233 * - CRM_GPIOA_PERIPH_RESET - CRM_GPIOB_PERIPH_RESET - CRM_GPIOC_PERIPH_RESET - CRM_GPIOD_PERIPH_RESET
234 * - CRM_GPIOE_PERIPH_RESET - CRM_GPIOF_PERIPH_RESET - CRM_GPIOG_PERIPH_RESET - CRM_GPIOH_PERIPH_RESET
235 * - CRM_CRC_PERIPH_RESET - CRM_EDMA_PERIPH_RESET - CRM_DMA1_PERIPH_RESET - CRM_DMA2_PERIPH_RESET
236 * - CRM_EMAC_PERIPH_RESET - CRM_OTGFS2_PERIPH_RESET - CRM_DVP_PERIPH_RESET - CRM_OTGFS1_PERIPH_RESET
237 * - CRM_SDIO1_PERIPH_RESET - CRM_XMC_PERIPH_RESET - CRM_QSPI1_PERIPH_RESET - CRM_QSPI2_PERIPH_RESET
238 * - CRM_SDIO2_PERIPH_RESET - CRM_TMR2_PERIPH_RESET - CRM_TMR3_PERIPH_RESET - CRM_TMR4_PERIPH_RESET
239 * - CRM_TMR5_PERIPH_RESET - CRM_TMR6_PERIPH_RESET - CRM_TMR7_PERIPH_RESET - CRM_TMR12_PERIPH_RESET
240 * - CRM_TMR13_PERIPH_RESET - CRM_TMR14_PERIPH_RESET - CRM_WWDT_PERIPH_RESET - CRM_SPI2_PERIPH_RESET
241 * - CRM_SPI3_PERIPH_RESET - CRM_USART2_PERIPH_RESET - CRM_USART3_PERIPH_RESET - CRM_UART4_PERIPH_RESET
242 * - CRM_UART5_PERIPH_RESET - CRM_I2C1_PERIPH_RESET - CRM_I2C2_PERIPH_RESET - CRM_I2C3_PERIPH_RESET
243 * - CRM_CAN1_PERIPH_RESET - CRM_CAN2_PERIPH_RESET - CRM_PWC_PERIPH_RESET - CRM_DAC_PERIPH_RESET
244 * - CRM_UART7_PERIPH_RESET - CRM_UART8_PERIPH_RESET - CRM_TMR1_PERIPH_RESET - CRM_TMR8_PERIPH_RESET
245 * - CRM_USART1_PERIPH_RESET - CRM_USART6_PERIPH_RESET - CRM_ADC_PERIPH_RESET - CRM_SPI1_PERIPH_RESET
246 * - CRM_SPI4_PERIPH_RESET - CRM_SCFG_PERIPH_RESET - CRM_TMR9_PERIPH_RESET - CRM_TMR10_PERIPH_RESET
247 * - CRM_TMR11_PERIPH_RESET - CRM_TMR20_PERIPH_RESET - CRM_ACC_PERIPH_RESET
248 * @param new_state (TRUE or FALSE)
249 * @retval none
251 void crm_periph_reset(crm_periph_reset_type value, confirm_state new_state)
253 /* enable periph reset */
254 if(new_state == TRUE)
256 CRM_REG(value) |= (CRM_REG_BIT(value));
258 /* disable periph reset */
259 else
261 CRM_REG(value) &= ~(CRM_REG_BIT(value));
266 * @brief enable or disable the peripheral clock in lowpower mode
267 * @param value
268 * this parameter can be one of the following values:
269 * - CRM_GPIOA_PERIPH_LOWPOWER - CRM_GPIOB_PERIPH_LOWPOWER - CRM_GPIOC_PERIPH_LOWPOWER - CRM_GPIOD_PERIPH_LOWPOWER
270 * - CRM_GPIOE_PERIPH_LOWPOWER - CRM_GPIOF_PERIPH_LOWPOWER - CRM_GPIOG_PERIPH_LOWPOWER - CRM_GPIOH_PERIPH_LOWPOWER
271 * - CRM_CRC_PERIPH_LOWPOWER - CRM_EDMA_PERIPH_LOWPOWER - CRM_DMA1_PERIPH_LOWPOWER - CRM_DMA2_PERIPH_LOWPOWER
272 * - CRM_EMAC_PERIPH_LOWPOWER - CRM_EMACTX_PERIPH_LOWPOWER - CRM_EMACRX_PERIPH_LOWPOWER - CRM_EMACPTP_PERIPH_LOWPOWER
273 * - CRM_OTGFS2_PERIPH_LOWPOWER - CRM_DVP_PERIPH_LOWPOWER - CRM_OTGFS1_PERIPH_LOWPOWER - CRM_SDIO1_PERIPH_LOWPOWER
274 * - CRM_XMC_PERIPH_LOWPOWER - CRM_QSPI1_PERIPH_LOWPOWER - CRM_QSPI2_PERIPH_LOWPOWER - CRM_SDIO2_PERIPH_LOWPOWER
275 * - CRM_TMR2_PERIPH_LOWPOWER - CRM_TMR3_PERIPH_LOWPOWER - CRM_TMR4_PERIPH_LOWPOWER - CRM_TMR5_PERIPH_LOWPOWER
276 * - CRM_TMR6_PERIPH_LOWPOWER - CRM_TMR7_PERIPH_LOWPOWER - CRM_TMR12_PERIPH_LOWPOWER - CRM_TMR13_PERIPH_LOWPOWER
277 * - CRM_TMR14_PERIPH_LOWPOWER - CRM_WWDT_PERIPH_LOWPOWER - CRM_SPI2_PERIPH_LOWPOWER - CRM_SPI3_PERIPH_LOWPOWER
278 * - CRM_USART2_PERIPH_LOWPOWER - CRM_USART3_PERIPH_LOWPOWER - CRM_UART4_PERIPH_LOWPOWER - CRM_UART5_PERIPH_LOWPOWER
279 * - CRM_I2C1_PERIPH_LOWPOWER - CRM_I2C2_PERIPH_LOWPOWER - CRM_I2C3_PERIPH_LOWPOWER - CRM_CAN1_PERIPH_LOWPOWER
280 * - CRM_CAN2_PERIPH_LOWPOWER - CRM_PWC_PERIPH_LOWPOWER - CRM_DAC_PERIPH_LOWPOWER - CRM_UART7_PERIPH_LOWPOWER
281 * - CRM_UART8_PERIPH_LOWPOWER - CRM_TMR1_PERIPH_LOWPOWER - CRM_TMR8_PERIPH_LOWPOWER - CRM_USART1_PERIPH_LOWPOWER
282 * - CRM_USART6_PERIPH_LOWPOWER - CRM_ADC1_PERIPH_LOWPOWER - CRM_ADC2_PERIPH_LOWPOWER - CRM_ADC3_PERIPH_LOWPOWER
283 * - CRM_SPI1_PERIPH_LOWPOWER - CRM_SPI4_PERIPH_LOWPOWER - CRM_SCFG_PERIPH_LOWPOWER - CRM_TMR9_PERIPH_LOWPOWER
284 * - CRM_TMR10_PERIPH_LOWPOWER - CRM_TMR11_PERIPH_LOWPOWER - CRM_TMR20_PERIPH_LOWPOWER - CRM_ACC_PERIPH_LOWPOWER
285 * - CRM_FLASH_PERIPH_LOWPOWER - CRM_SRAM1_PERIPH_LOWPOWER - CRM_SRAM2_PERIPH_LOWPOWER
286 * @param new_state (TRUE or FALSE)
287 * @retval none
289 void crm_periph_lowpower_mode_enable(crm_periph_clock_lowpower_type value, confirm_state new_state)
291 /* enable periph clock in lowpower mode */
292 if(new_state == TRUE)
294 CRM_REG(value) |= (CRM_REG_BIT(value));
296 /* disable periph clock in lowpower mode */
297 else
299 CRM_REG(value) &= ~(CRM_REG_BIT(value));
304 * @brief enable or disable the crm clock source
305 * @param source
306 * this parameter can be one of the following values:
307 * - CRM_CLOCK_SOURCE_HICK
308 * - CRM_CLOCK_SOURCE_HEXT
309 * - CRM_CLOCK_SOURCE_PLL
310 * - CRM_CLOCK_SOURCE_LEXT
311 * - CRM_CLOCK_SOURCE_LICK
312 * @param new_state (TRUE or FALSE)
313 * @retval none
315 void crm_clock_source_enable(crm_clock_source_type source, confirm_state new_state)
317 switch(source)
319 case CRM_CLOCK_SOURCE_HICK:
320 CRM->ctrl_bit.hicken = new_state;
321 break;
322 case CRM_CLOCK_SOURCE_HEXT:
323 CRM->ctrl_bit.hexten = new_state;
324 break;
325 case CRM_CLOCK_SOURCE_PLL:
326 CRM->ctrl_bit.pllen = new_state;
327 break;
328 case CRM_CLOCK_SOURCE_LEXT:
329 CRM->bpdc_bit.lexten = new_state;
330 break;
331 case CRM_CLOCK_SOURCE_LICK:
332 CRM->ctrlsts_bit.licken = new_state;
333 break;
334 default: break;
339 * @brief clear the crm reset flags
340 * @param flag
341 * this parameter can be one of the following values:
342 * reset flag:
343 * - CRM_PIN_RESET_FLAG
344 * - CRM_POR_RESET_FLAG
345 * - CRM_SW_RESET_FLAG
346 * - CRM_WDT_RESET_FLAG
347 * - CRM_WWDT_RESET_FLAG
348 * - CRM_LOWPOWER_RESET_FLAG
349 * - CRM_ALL_RESET_FLAG
350 * interrupt flag:
351 * - CRM_LICK_READY_INT_FLAG
352 * - CRM_LEXT_READY_INT_FLAG
353 * - CRM_HICK_READY_INT_FLAG
354 * - CRM_HEXT_READY_INT_FLAG
355 * - CRM_PLL_READY_INT_FLAG
356 * - CRM_CLOCK_FAILURE_INT_FLAG
357 * @retval none
359 void crm_flag_clear(uint32_t flag)
361 switch(flag)
363 case CRM_NRST_RESET_FLAG:
364 case CRM_POR_RESET_FLAG:
365 case CRM_SW_RESET_FLAG:
366 case CRM_WDT_RESET_FLAG:
367 case CRM_WWDT_RESET_FLAG:
368 case CRM_LOWPOWER_RESET_FLAG:
369 case CRM_ALL_RESET_FLAG:
370 CRM->ctrlsts_bit.rstfc = TRUE;
371 while(CRM->ctrlsts_bit.rstfc == TRUE);
372 break;
373 case CRM_LICK_READY_INT_FLAG:
374 CRM->clkint_bit.lickstblfc = TRUE;
375 break;
376 case CRM_LEXT_READY_INT_FLAG:
377 CRM->clkint_bit.lextstblfc = TRUE;
378 break;
379 case CRM_HICK_READY_INT_FLAG:
380 CRM->clkint_bit.hickstblfc = TRUE;
381 break;
382 case CRM_HEXT_READY_INT_FLAG:
383 CRM->clkint_bit.hextstblfc = TRUE;
384 break;
385 case CRM_PLL_READY_INT_FLAG:
386 CRM->clkint_bit.pllstblfc = TRUE;
387 break;
388 case CRM_CLOCK_FAILURE_INT_FLAG:
389 CRM->clkint_bit.cfdfc = TRUE;
390 break;
391 default:
392 break;
397 * @brief select ertc clock
398 * @param value
399 * this parameter can be one of the following values:
400 * - CRM_ERTC_CLOCK_NOCLK
401 * - CRM_ERTC_CLOCK_LEXT
402 * - CRM_ERTC_CLOCK_LICK
403 * - CRM_ERTC_CLOCK_HEXT_DIV_2
404 * - CRM_ERTC_CLOCK_HEXT_DIV_3
405 * - CRM_ERTC_CLOCK_HEXT_DIV_4
406 * - CRM_ERTC_CLOCK_HEXT_DIV_5
407 * - CRM_ERTC_CLOCK_HEXT_DIV_6
408 * - CRM_ERTC_CLOCK_HEXT_DIV_7
409 * - CRM_ERTC_CLOCK_HEXT_DIV_8
410 * - CRM_ERTC_CLOCK_HEXT_DIV_9
411 * - CRM_ERTC_CLOCK_HEXT_DIV_10
412 * - CRM_ERTC_CLOCK_HEXT_DIV_11
413 * - CRM_ERTC_CLOCK_HEXT_DIV_12
414 * - CRM_ERTC_CLOCK_HEXT_DIV_13
415 * - CRM_ERTC_CLOCK_HEXT_DIV_14
416 * - CRM_ERTC_CLOCK_HEXT_DIV_15
417 * - CRM_ERTC_CLOCK_HEXT_DIV_16
418 * - CRM_ERTC_CLOCK_HEXT_DIV_17
419 * - CRM_ERTC_CLOCK_HEXT_DIV_18
420 * - CRM_ERTC_CLOCK_HEXT_DIV_19
421 * - CRM_ERTC_CLOCK_HEXT_DIV_20
422 * - CRM_ERTC_CLOCK_HEXT_DIV_21
423 * - CRM_ERTC_CLOCK_HEXT_DIV_22
424 * - CRM_ERTC_CLOCK_HEXT_DIV_23
425 * - CRM_ERTC_CLOCK_HEXT_DIV_24
426 * - CRM_ERTC_CLOCK_HEXT_DIV_25
427 * - CRM_ERTC_CLOCK_HEXT_DIV_26
428 * - CRM_ERTC_CLOCK_HEXT_DIV_27
429 * - CRM_ERTC_CLOCK_HEXT_DIV_28
430 * - CRM_ERTC_CLOCK_HEXT_DIV_29
431 * - CRM_ERTC_CLOCK_HEXT_DIV_30
432 * - CRM_ERTC_CLOCK_HEXT_DIV_31
433 * @retval none
435 void crm_ertc_clock_select(crm_ertc_clock_type value)
437 CRM->cfg_bit.ertcdiv = ((value & 0x1F0) >> 4);
438 CRM->bpdc_bit.ertcsel = (value & 0xF);
442 * @brief enable or disable ertc
443 * @param new_state (TRUE or FALSE)
444 * @retval none
446 void crm_ertc_clock_enable(confirm_state new_state)
448 CRM->bpdc_bit.ertcen = new_state;
452 * @brief set crm ahb division
453 * @param value
454 * this parameter can be one of the following values:
455 * - CRM_AHB_DIV_1
456 * - CRM_AHB_DIV_2
457 * - CRM_AHB_DIV_4
458 * - CRM_AHB_DIV_8
459 * - CRM_AHB_DIV_16
460 * - CRM_AHB_DIV_64
461 * - CRM_AHB_DIV_128
462 * - CRM_AHB_DIV_256
463 * - CRM_AHB_DIV_512
464 * @retval none
466 void crm_ahb_div_set(crm_ahb_div_type value)
468 CRM->cfg_bit.ahbdiv = value;
472 * @brief set crm apb1 division
473 * @param value
474 * this parameter can be one of the following values:
475 * - CRM_APB1_DIV_1
476 * - CRM_APB1_DIV_2
477 * - CRM_APB1_DIV_4
478 * - CRM_APB1_DIV_8
479 * - CRM_APB1_DIV_16
480 * @retval none
482 void crm_apb1_div_set(crm_apb1_div_type value)
484 CRM->cfg_bit.apb1div = value;
488 * @brief set crm apb2 division
489 * @param value
490 * this parameter can be one of the following values:
491 * - CRM_APB2_DIV_1
492 * - CRM_APB2_DIV_2
493 * - CRM_APB2_DIV_4
494 * - CRM_APB2_DIV_8
495 * - CRM_APB2_DIV_16
496 * @retval none
498 void crm_apb2_div_set(crm_apb2_div_type value)
500 CRM->cfg_bit.apb2div = value;
504 * @brief set usb division
505 * @param value
506 * this parameter can be one of the following values:
507 * - CRM_USB_DIV_1_5
508 * - CRM_USB_DIV_1
509 * - CRM_USB_DIV_2_5
510 * - CRM_USB_DIV_2
511 * - CRM_USB_DIV_3_5
512 * - CRM_USB_DIV_3
513 * - CRM_USB_DIV_4_5
514 * - CRM_USB_DIV_4
515 * - CRM_USB_DIV_5_5
516 * - CRM_USB_DIV_5
517 * - CRM_USB_DIV_6_5
518 * - CRM_USB_DIV_6
519 * - CRM_USB_DIV_7
520 * @retval none
522 void crm_usb_clock_div_set(crm_usb_div_type value)
524 CRM->misc2_bit.usbdiv = value;
528 * @brief enable or disable clock failure detection
529 * @param new_state (TRUE or FALSE)
530 * @retval none
532 void crm_clock_failure_detection_enable(confirm_state new_state)
534 CRM->ctrl_bit.cfden = new_state;
538 * @brief battery powered domain software reset
539 * @param new_state (TRUE or FALSE)
540 * @retval none
542 void crm_battery_powered_domain_reset(confirm_state new_state)
544 CRM->bpdc_bit.bpdrst = new_state;
548 * @brief auto step clock switch enable
549 * @param new_state (TRUE or FALSE)
550 * @retval none
552 void crm_auto_step_mode_enable(confirm_state new_state)
554 if(new_state == TRUE)
555 CRM->misc2_bit.auto_step_en = CRM_AUTO_STEP_MODE_ENABLE;
556 else
557 CRM->misc2_bit.auto_step_en = CRM_AUTO_STEP_MODE_DISABLE;
561 * @brief config hick divider select
562 * @param value
563 * this parameter can be one of the following values:
564 * - CRM_HICK48_DIV6
565 * - CRM_HICK48_NODIV
566 * @retval none
568 void crm_hick_divider_select(crm_hick_div_6_type value)
570 CRM->misc1_bit.hickdiv = value;
574 * @brief hick as system clock frequency select
575 * @param value
576 * this parameter can be one of the following values:
577 * - CRM_HICK_SCLK_8MHZ
578 * - CRM_HICK_SCLK_48MHZ
579 * @retval none
581 void crm_hick_sclk_frequency_select(crm_hick_sclk_frequency_type value)
583 crm_hick_divider_select(CRM_HICK48_NODIV);
584 CRM->misc1_bit.hick_to_sclk = value;
588 * @brief usb 48 mhz clock source select
589 * @param value
590 * this parameter can be one of the following values:
591 * - CRM_USB_CLOCK_SOURCE_PLL
592 * - CRM_USB_CLOCK_SOURCE_HICK
593 * @retval none
595 void crm_usb_clock_source_select(crm_usb_clock_source_type value)
597 if(value == CRM_USB_CLOCK_SOURCE_HICK)
599 crm_hick_sclk_frequency_select(CRM_HICK_SCLK_48MHZ);
601 CRM->misc1_bit.hick_to_usb = value;
605 * @brief enable or disable clkout direct to tmr10 channel 1
606 * @param new_state (TRUE or FALSE)
607 * @retval none
609 void crm_clkout_to_tmr10_enable(confirm_state new_state)
611 CRM->misc2_bit.clk_to_tmr = new_state;
615 * @brief config crm pll
616 * pll_rcs_freq * pll_ns
617 * pll clock = --------------------------------
618 * pll_ms * pll_fr_n
619 * attemtion:
620 * 31 <= pll_ns <= 500
621 * 1 <= pll_ms <= 15
623 * pll_rcs_freq
624 * 2mhz <= ---------------------- <= 16mhz
625 * pll_ms
627 * pll_rcs_freq * pll_ns
628 * 500mhz <= -------------------------------- <= 1000mhz
629 * pll_ms
630 * @param clock_source
631 * this parameter can be one of the following values:
632 * - CRM_PLL_SOURCE_HICK
633 * - CRM_PLL_SOURCE_HEXT
634 * @param pll_ns (31~500)
635 * @param pll_ms (1~15)
636 * @param pll_fr
637 * this parameter can be one of the following values:
638 * - CRM_PLL_FR_1
639 * - CRM_PLL_FR_2
640 * - CRM_PLL_FR_4
641 * - CRM_PLL_FR_8
642 * - CRM_PLL_FR_16
643 * - CRM_PLL_FR_32
644 * @retval none
646 void crm_pll_config(crm_pll_clock_source_type clock_source, uint16_t pll_ns, \
647 uint16_t pll_ms, crm_pll_fr_type pll_fr)
649 /* config pll clock source */
650 CRM->pllcfg_bit.pllrcs = clock_source;
652 /* config pll multiplication factor */
653 CRM->pllcfg_bit.pllns = pll_ns;
654 CRM->pllcfg_bit.pllms = pll_ms;
655 CRM->pllcfg_bit.pllfr = pll_fr;
659 * @brief select system clock source
660 * @param value
661 * this parameter can be one of the following values:
662 * - CRM_SCLK_HICK
663 * - CRM_SCLK_HEXT
664 * - CRM_SCLK_PLL
665 * @retval none
667 void crm_sysclk_switch(crm_sclk_type value)
669 CRM->cfg_bit.sclksel = value;
673 * @brief indicate which clock source is used as system clock
674 * @param none
675 * @retval crm_sclk
676 * this return can be one of the following values:
677 * - CRM_SCLK_HICK
678 * - CRM_SCLK_HEXT
679 * - CRM_SCLK_PLL
681 crm_sclk_type crm_sysclk_switch_status_get(void)
683 return (crm_sclk_type)CRM->cfg_bit.sclksts;
687 * @brief get crm clocks freqency
688 * @param clocks_struct
689 * - pointer to the crm_clocks_freq_type structure
690 * @retval none
692 void crm_clocks_freq_get(crm_clocks_freq_type *clocks_struct)
694 uint32_t pll_ns = 0, pll_ms = 0, pll_fr = 0, pll_clock_source = 0, pllrcsfreq = 0;
695 uint32_t temp = 0, div_value = 0;
696 crm_sclk_type sclk_source;
698 static const uint8_t sclk_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
699 static const uint8_t ahb_apb1_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4};
700 static const uint8_t ahb_apb2_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4};
701 static const uint8_t pll_fr_table[6] = {1, 2, 4, 8, 16, 32};
703 /* get sclk source */
704 sclk_source = crm_sysclk_switch_status_get();
706 switch(sclk_source)
708 case CRM_SCLK_HICK:
709 if(((CRM->misc1_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET))
710 clocks_struct->sclk_freq = HICK_VALUE * 6;
711 else
712 clocks_struct->sclk_freq = HICK_VALUE;
713 break;
714 case CRM_SCLK_HEXT:
715 clocks_struct->sclk_freq = HEXT_VALUE;
716 break;
717 case CRM_SCLK_PLL:
718 /* get pll clock source */
719 pll_clock_source = CRM->pllcfg_bit.pllrcs;
721 /* get multiplication factor */
722 pll_ns = CRM->pllcfg_bit.pllns;
723 pll_ms = CRM->pllcfg_bit.pllms;
724 pll_fr = pll_fr_table[CRM->pllcfg_bit.pllfr];
726 if (pll_clock_source == CRM_PLL_SOURCE_HICK)
728 /* hick selected as pll clock entry */
729 pllrcsfreq = HICK_VALUE;
731 else
733 /* hext selected as pll clock entry */
734 pllrcsfreq = HEXT_VALUE;
737 clocks_struct->sclk_freq = (uint32_t)(((uint64_t)pllrcsfreq * pll_ns) / (pll_ms * pll_fr));
738 break;
739 default:
740 clocks_struct->sclk_freq = HICK_VALUE;
741 break;
744 /* compute sclk, ahbclk, abp1clk and apb2clk frequencies */
745 /* get ahb division */
746 temp = CRM->cfg_bit.ahbdiv;
747 div_value = sclk_ahb_div_table[temp];
748 /* ahbclk frequency */
749 clocks_struct->ahb_freq = clocks_struct->sclk_freq >> div_value;
751 /* get apb1 division */
752 temp = CRM->cfg_bit.apb1div;
753 div_value = ahb_apb1_div_table[temp];
754 /* apb1clk frequency */
755 clocks_struct->apb1_freq = clocks_struct->ahb_freq >> div_value;
757 /* get apb2 division */
758 temp = CRM->cfg_bit.apb2div;
759 div_value = ahb_apb2_div_table[temp];
760 /* apb2clk frequency */
761 clocks_struct->apb2_freq = clocks_struct->ahb_freq >> div_value;
765 * @brief set crm clkout1
766 * @param clkout
767 * this parameter can be one of the following values:
768 * - CRM_CLKOUT1_HICK
769 * - CRM_CLKOUT1_LEXT
770 * - CRM_CLKOUT1_HEXT
771 * - CRM_CLKOUT1_PLL
772 * @retval none
774 void crm_clock_out1_set(crm_clkout1_select_type clkout)
776 CRM->cfg_bit.clkout1_sel = clkout;
780 * @brief set crm clkout2
781 * @param clkout
782 * this parameter can be one of the following values:
783 * - CRM_CLKOUT2_SCLK
784 * - CRM_CLKOUT2_HEXT
785 * - CRM_CLKOUT2_PLL
786 * - CRM_CLKOUT2_USB
787 * - CRM_CLKOUT2_ADC
788 * - CRM_CLKOUT2_HICK
789 * - CRM_CLKOUT2_LICK
790 * - CRM_CLKOUT2_LEXT
791 * @retval none
793 void crm_clock_out2_set(crm_clkout2_select_type clkout)
795 if(clkout < 0x10)
797 CRM->cfg_bit.clkout2_sel1 = (clkout & 0x3);
799 else
801 CRM->cfg_bit.clkout2_sel1 = 0x1;
802 CRM->misc1_bit.clkout2_sel2 = (clkout & 0xF);
807 * @brief set crm clkout1 division1
808 * @param div1
809 * this parameter can be one of the following values:
810 * - CRM_CLKOUT_INDEX_1
811 * - CRM_CLKOUT_INDEX_2
812 * @param div1
813 * this parameter can be one of the following values:
814 * - CRM_CLKOUT_DIV1_1
815 * - CRM_CLKOUT_DIV1_2
816 * - CRM_CLKOUT_DIV1_3
817 * - CRM_CLKOUT_DIV1_4
818 * - CRM_CLKOUT_DIV1_5
819 * @param div2
820 * this parameter can be one of the following values:
821 * - CRM_CLKOUT_DIV2_1
822 * - CRM_CLKOUT_DIV2_2
823 * - CRM_CLKOUT_DIV2_4
824 * - CRM_CLKOUT_DIV2_8
825 * - CRM_CLKOUT_DIV2_16
826 * - CRM_CLKOUT_DIV2_64
827 * - CRM_CLKOUT_DIV2_128
828 * - CRM_CLKOUT_DIV2_256
829 * - CRM_CLKOUT_DIV2_512
830 * @retval none
832 void crm_clkout_div_set(crm_clkout_index_type index, crm_clkout_div1_type div1, crm_clkout_div2_type div2)
834 if(index == CRM_CLKOUT_INDEX_1)
836 CRM->cfg_bit.clkout1div1 = div1;
837 CRM->misc1_bit.clkout1div2 = div2;
839 else
841 CRM->cfg_bit.clkout2div1 = div1;
842 CRM->misc1_bit.clkout2div2 = div2;
847 * @brief set emac output pulse width
848 * @param width
849 * this parameter can be one of the following values:
850 * - CRM_EMAC_PULSE_125MS
851 * - CRM_EMAC_PULSE_1SCLK
852 * @retval none
854 void crm_emac_output_pulse_set(crm_emac_output_pulse_type width)
856 CRM->misc2_bit.emac_pps_sel = width;
860 * @brief config crm interrupt
861 * @param int
862 * this parameter can be any combination of the following values:
863 * - CRM_LICK_STABLE_INT
864 * - CRM_LEXT_STABLE_INT
865 * - CRM_HICK_STABLE_INT
866 * - CRM_HEXT_STABLE_INT
867 * - CRM_PLL_STABLE_INT
868 * @param new_state (TRUE or FALSE)
869 * @retval none
871 void crm_interrupt_enable(uint32_t crm_int, confirm_state new_state)
873 if(TRUE == new_state)
874 CRM->clkint |= crm_int;
875 else
876 CRM->clkint &= ~crm_int;
880 * @brief calculate the pll parameters with pll reference clock and target pll output frequency.
881 * pll_rcs_freq * pll_ns
882 * pll clock = --------------------------------
883 * pll_ms * pll_fr_n
884 * attemtion:
885 * 31 <= pll_ns <= 500
886 * 1 <= pll_ms <= 15
888 * pll_rcs_freq
889 * 2mhz <= ---------------------- <= 16mhz
890 * pll_ms
892 * pll_rcs_freq * pll_ns
893 * 500mhz <= -------------------------------- <= 1000mhz
894 * pll_ms
895 * @param pll_rcs
896 * this parameter can be one of the following values:
897 * - CRM_PLL_SOURCE_HICK
898 * - CRM_PLL_SOURCE_HEXT
899 * @param target_sclk_freq: target pll output frequency, such as 200 mhz (target_sclk_freq: 200000000)
900 * @param ret_ms: pointer to ms value, return the pll_ms of pll parameters
901 * @param ret_ns: pointer to ns value, return the pll_ns of pll parameters
902 * @param ret_fr: pointer to fr value, return the pll_fr of pll parameters
903 * @retval error_status (SUCCESS or ERROR)
905 error_status crm_pll_parameter_calculate(crm_pll_clock_source_type pll_rcs, uint32_t target_sclk_freq, \
906 uint16_t *ret_ms, uint16_t *ret_ns, uint16_t *ret_fr)
908 uint32_t pll_rcs_freq = 0, ns = 0, ms = 0, fr = 0;
909 uint32_t ms_min = 0, ms_max = 0, error_min = 0xFFFFFFFF;
910 uint32_t result = 0, absolute_value = 0;
912 /* reduce calculate accuracy, target_sclk_freq accuracy with khz */
913 target_sclk_freq = target_sclk_freq / 1000;
915 /* get pll reference clock frequency, accuracy with khz */
916 if(pll_rcs == CRM_PLL_SOURCE_HICK)
917 pll_rcs_freq = HICK_VALUE / 1000;
918 else
919 pll_rcs_freq = HEXT_VALUE / 1000;
921 /* polling ms range, accuracy with khz */
922 for(ms = 1; ms <= 15; ms ++)
924 result = pll_rcs_freq / ms;
925 if((result >= 2000U) && (result <= 16000U))
927 if(ms_min == 0)
928 ms_min = ms;
930 ms_max = ms;
934 /* polling pll parameters */
935 for(ms = ms_min; ms <= ms_max; ms ++)
937 for(fr = 0; fr <= 5; fr ++)
939 for(ns = 31; ns <= 500; ns ++)
941 result = (pll_rcs_freq * ns) / (ms);
942 /* check vco frequency range, accuracy with khz */
943 if((result < 500000U) || (result > 1000000U))
945 continue;
947 /* calculate pll output frequency */
948 result = result / (0x1 << fr);
949 /* check frequency */
950 if(target_sclk_freq == result)
952 *ret_ms = ms;
953 *ret_ns = ns;
954 *ret_fr = fr;
955 /* the pll parameters that is equal to target_sclk_freq */
956 return SUCCESS;
958 /* calculate error range, accuracy with khz */
959 absolute_value = (result > target_sclk_freq) ? (result - target_sclk_freq) : (target_sclk_freq - result);
960 if(absolute_value < error_min)
962 error_min = absolute_value;
963 *ret_ms = ms;
964 *ret_ns = ns;
965 *ret_fr = fr;
970 /* the pll parameters that is the closest approach to target_sclk_freq */
971 return ERROR;
975 * @}
978 #endif
981 * @}
985 * @}