2 **************************************************************************
3 * @file at32f435_437_crm.c
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
34 * @brief CRM driver modules
38 #ifdef CRM_MODULE_ENABLED
40 /** @defgroup CRM_private_functions
45 * @brief reset the crm register
51 /* reset the crm clock configuration to the default reset state(for debug purpose) */
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 */
70 /* reset pllms pllns pllfr pllrcs bits */
71 CRM
->pllcfg
= 0x00033002U
;
73 /* reset clkout[3], usbbufs, hickdiv, clkoutdiv */
76 /* disable all interrupts enable and clear pending bits */
77 CRM
->clkint
= 0x009F0000U
;
81 * @brief enable or disable crm low speed external crystal bypass
82 * @param new_state (TRUE or FALSE)
85 void crm_lext_bypass(confirm_state new_state
)
87 CRM
->bpdc_bit
.lextbyps
= new_state
;
91 * @brief enable or disable crm high speed external crystal bypass
92 * @param new_state (TRUE or FALSE)
95 void crm_hext_bypass(confirm_state new_state
)
97 CRM
->ctrl_bit
.hextbyps
= new_state
;
101 * @brief get crm flag status
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
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
))
139 * @brief wait for hext stable
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
))
153 if(crm_flag_get(CRM_HEXT_STABLE_FLAG
) != SET
)
166 * @brief set the hick trimming value
167 * @param trim_value (0x00~0x3F)
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)
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
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)
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 */
225 CRM_REG(value
) &= ~(CRM_REG_BIT(value
));
230 * @brief enable or disable the peripheral reset
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)
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 */
261 CRM_REG(value
) &= ~(CRM_REG_BIT(value
));
266 * @brief enable or disable the peripheral clock in lowpower mode
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)
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 */
299 CRM_REG(value
) &= ~(CRM_REG_BIT(value
));
304 * @brief enable or disable the crm clock 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)
315 void crm_clock_source_enable(crm_clock_source_type source
, confirm_state new_state
)
319 case CRM_CLOCK_SOURCE_HICK
:
320 CRM
->ctrl_bit
.hicken
= new_state
;
322 case CRM_CLOCK_SOURCE_HEXT
:
323 CRM
->ctrl_bit
.hexten
= new_state
;
325 case CRM_CLOCK_SOURCE_PLL
:
326 CRM
->ctrl_bit
.pllen
= new_state
;
328 case CRM_CLOCK_SOURCE_LEXT
:
329 CRM
->bpdc_bit
.lexten
= new_state
;
331 case CRM_CLOCK_SOURCE_LICK
:
332 CRM
->ctrlsts_bit
.licken
= new_state
;
339 * @brief clear the crm reset flags
341 * this parameter can be one of the following values:
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
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
359 void crm_flag_clear(uint32_t 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
);
373 case CRM_LICK_READY_INT_FLAG
:
374 CRM
->clkint_bit
.lickstblfc
= TRUE
;
376 case CRM_LEXT_READY_INT_FLAG
:
377 CRM
->clkint_bit
.lextstblfc
= TRUE
;
379 case CRM_HICK_READY_INT_FLAG
:
380 CRM
->clkint_bit
.hickstblfc
= TRUE
;
382 case CRM_HEXT_READY_INT_FLAG
:
383 CRM
->clkint_bit
.hextstblfc
= TRUE
;
385 case CRM_PLL_READY_INT_FLAG
:
386 CRM
->clkint_bit
.pllstblfc
= TRUE
;
388 case CRM_CLOCK_FAILURE_INT_FLAG
:
389 CRM
->clkint_bit
.cfdfc
= TRUE
;
397 * @brief select ertc clock
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
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)
446 void crm_ertc_clock_enable(confirm_state new_state
)
448 CRM
->bpdc_bit
.ertcen
= new_state
;
452 * @brief set crm ahb division
454 * this parameter can be one of the following values:
466 void crm_ahb_div_set(crm_ahb_div_type value
)
468 CRM
->cfg_bit
.ahbdiv
= value
;
472 * @brief set crm apb1 division
474 * this parameter can be one of the following values:
482 void crm_apb1_div_set(crm_apb1_div_type value
)
484 CRM
->cfg_bit
.apb1div
= value
;
488 * @brief set crm apb2 division
490 * this parameter can be one of the following values:
498 void crm_apb2_div_set(crm_apb2_div_type value
)
500 CRM
->cfg_bit
.apb2div
= value
;
504 * @brief set usb division
506 * this parameter can be one of the following values:
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)
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)
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)
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
;
557 CRM
->misc2_bit
.auto_step_en
= CRM_AUTO_STEP_MODE_DISABLE
;
561 * @brief config hick divider select
563 * this parameter can be one of the following values:
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
576 * this parameter can be one of the following values:
577 * - CRM_HICK_SCLK_8MHZ
578 * - CRM_HICK_SCLK_48MHZ
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
590 * this parameter can be one of the following values:
591 * - CRM_USB_CLOCK_SOURCE_PLL
592 * - CRM_USB_CLOCK_SOURCE_HICK
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)
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 = --------------------------------
620 * 31 <= pll_ns <= 500
624 * 2mhz <= ---------------------- <= 16mhz
627 * pll_rcs_freq * pll_ns
628 * 500mhz <= -------------------------------- <= 1000mhz
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)
637 * this parameter can be one of the following values:
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
661 * this parameter can be one of the following values:
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
676 * this return can be one of the following values:
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
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();
709 if(((CRM
->misc1_bit
.hick_to_sclk
) != RESET
) && ((CRM
->misc1_bit
.hickdiv
) != RESET
))
710 clocks_struct
->sclk_freq
= HICK_VALUE
* 6;
712 clocks_struct
->sclk_freq
= HICK_VALUE
;
715 clocks_struct
->sclk_freq
= HEXT_VALUE
;
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
;
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
));
740 clocks_struct
->sclk_freq
= HICK_VALUE
;
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
767 * this parameter can be one of the following values:
774 void crm_clock_out1_set(crm_clkout1_select_type clkout
)
776 CRM
->cfg_bit
.clkout1_sel
= clkout
;
780 * @brief set crm clkout2
782 * this parameter can be one of the following values:
793 void crm_clock_out2_set(crm_clkout2_select_type clkout
)
797 CRM
->cfg_bit
.clkout2_sel1
= (clkout
& 0x3);
801 CRM
->cfg_bit
.clkout2_sel1
= 0x1;
802 CRM
->misc1_bit
.clkout2_sel2
= (clkout
& 0xF);
807 * @brief set crm clkout1 division1
809 * this parameter can be one of the following values:
810 * - CRM_CLKOUT_INDEX_1
811 * - CRM_CLKOUT_INDEX_2
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
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
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
;
841 CRM
->cfg_bit
.clkout2div1
= div1
;
842 CRM
->misc1_bit
.clkout2div2
= div2
;
847 * @brief set emac output pulse width
849 * this parameter can be one of the following values:
850 * - CRM_EMAC_PULSE_125MS
851 * - CRM_EMAC_PULSE_1SCLK
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
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)
871 void crm_interrupt_enable(uint32_t crm_int
, confirm_state new_state
)
873 if(TRUE
== new_state
)
874 CRM
->clkint
|= crm_int
;
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 = --------------------------------
885 * 31 <= pll_ns <= 500
889 * 2mhz <= ---------------------- <= 16mhz
892 * pll_rcs_freq * pll_ns
893 * 500mhz <= -------------------------------- <= 1000mhz
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;
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))
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))
947 /* calculate pll output frequency */
948 result
= result
/ (0x1 << fr
);
949 /* check frequency */
950 if(target_sclk_freq
== result
)
955 /* the pll parameters that is equal to target_sclk_freq */
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
;
970 /* the pll parameters that is the closest approach to target_sclk_freq */