1183 lines
35 KiB
C
1183 lines
35 KiB
C
/**
|
|
**************************************************************************
|
|
* @file at32a423_crm.c
|
|
* @brief contains all the functions for the crm firmware library
|
|
**************************************************************************
|
|
* Copyright notice & Disclaimer
|
|
*
|
|
* The software Board Support Package (BSP) that is made available to
|
|
* download from Artery official website is the copyrighted work of Artery.
|
|
* Artery authorizes customers to use, copy, and distribute the BSP
|
|
* software and its related documentation for the purpose of design and
|
|
* development in conjunction with Artery microcontrollers. Use of the
|
|
* software is governed by this copyright notice and the following disclaimer.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED ON "AS IS" BASIS WITHOUT WARRANTIES,
|
|
* GUARANTEES OR REPRESENTATIONS OF ANY KIND. ARTERY EXPRESSLY DISCLAIMS,
|
|
* TO THE FULLEST EXTENT PERMITTED BY LAW, ALL EXPRESS, IMPLIED OR
|
|
* STATUTORY OR OTHER WARRANTIES, GUARANTEES OR REPRESENTATIONS,
|
|
* INCLUDING BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
|
|
*
|
|
**************************************************************************
|
|
*/
|
|
|
|
#include "at32a423_conf.h"
|
|
|
|
/** @addtogroup AT32A423_periph_driver
|
|
* @{
|
|
*/
|
|
|
|
/** @defgroup CRM
|
|
* @brief CRM driver modules
|
|
* @{
|
|
*/
|
|
|
|
#ifdef CRM_MODULE_ENABLED
|
|
|
|
/** @defgroup CRM_private_functions
|
|
* @{
|
|
*/
|
|
|
|
/**
|
|
* @brief reset the crm register
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void crm_reset(void)
|
|
{
|
|
/* reset the crm clock configuration to the default reset state(for debug purpose) */
|
|
/* enable auto step mode */
|
|
crm_auto_step_mode_enable(TRUE);
|
|
|
|
/* set hicken bit */
|
|
CRM->ctrl_bit.hicken = TRUE;
|
|
|
|
/* wait hick stable */
|
|
while(CRM->ctrl_bit.hickstbl != SET);
|
|
|
|
/* hick used as system clock */
|
|
CRM->cfg_bit.sclksel = CRM_SCLK_HICK;
|
|
|
|
/* wait sclk switch status */
|
|
while(CRM->cfg_bit.sclksts != CRM_SCLK_HICK);
|
|
|
|
/* reset hexten, hextbyps, cfden and pllen bits */
|
|
CRM->ctrl &= ~(0x010D0000U);
|
|
|
|
/* reset cfg register, include sclk switch, ahbdiv, apb1div, apb2div, adcdiv, clkout bits */
|
|
CRM->cfg = 0x40000000U;
|
|
|
|
/* reset pllms pllns pllfr pllrcs bits */
|
|
CRM->pllcfg = 0x00033002U;
|
|
|
|
/* reset clkout_sel, clkoutdiv, pllclk_to_adc, hick_to_usb */
|
|
CRM->misc1 &= 0x00005000U;
|
|
CRM->misc1 |= 0x000F0000U;
|
|
|
|
/* disable all interrupts enable and clear pending bits */
|
|
CRM->clkint = 0x009F0000U;
|
|
|
|
/* disable auto step mode */
|
|
crm_auto_step_mode_enable(FALSE);
|
|
}
|
|
|
|
/**
|
|
* @brief enable or disable crm low speed external crystal bypass
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_lext_bypass(confirm_state new_state)
|
|
{
|
|
CRM->bpdc_bit.lextbyps = new_state;
|
|
}
|
|
|
|
/**
|
|
* @brief enable or disable crm high speed external crystal bypass
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_hext_bypass(confirm_state new_state)
|
|
{
|
|
CRM->ctrl_bit.hextbyps = new_state;
|
|
}
|
|
|
|
/**
|
|
* @brief get crm flag status
|
|
* @param flag
|
|
* this parameter can be one of the following values:
|
|
* - CRM_HICK_STABLE_FLAG
|
|
* - CRM_HEXT_STABLE_FLAG
|
|
* - CRM_PLL_STABLE_FLAG
|
|
* - CRM_LEXT_STABLE_FLAG
|
|
* - CRM_LICK_STABLE_FLAG
|
|
* - CRM_PIN_RESET_FLAG
|
|
* - CRM_POR_RESET_FLAG
|
|
* - CRM_SW_RESET_FLAG
|
|
* - CRM_WDT_RESET_FLAG
|
|
* - CRM_WWDT_RESET_FLAG
|
|
* - CRM_LOWPOWER_RESET_FLAG
|
|
* interrupt flag:
|
|
* - CRM_LICK_READY_INT_FLAG
|
|
* - CRM_LEXT_READY_INT_FLAG
|
|
* - CRM_HICK_READY_INT_FLAG
|
|
* - CRM_HEXT_READY_INT_FLAG
|
|
* - CRM_PLL_READY_INT_FLAG
|
|
* - CRM_CLOCK_FAILURE_INT_FLAG
|
|
* @retval flag_status (SET or RESET)
|
|
*/
|
|
flag_status crm_flag_get(uint32_t flag)
|
|
{
|
|
flag_status status = RESET;
|
|
if((CRM_REG(flag) & CRM_REG_BIT(flag)) != CRM_REG_BIT(flag))
|
|
{
|
|
status = RESET;
|
|
}
|
|
else
|
|
{
|
|
status = SET;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief get crm interrupt flag status
|
|
* @param flag
|
|
* this parameter can be one of the following values:
|
|
* - CRM_LICK_READY_INT_FLAG
|
|
* - CRM_LEXT_READY_INT_FLAG
|
|
* - CRM_HICK_READY_INT_FLAG
|
|
* - CRM_HEXT_READY_INT_FLAG
|
|
* - CRM_PLL_READY_INT_FLAG
|
|
* - CRM_CLOCK_FAILURE_INT_FLAG
|
|
* @retval flag_status (SET or RESET)
|
|
*/
|
|
flag_status crm_interrupt_flag_get(uint32_t flag)
|
|
{
|
|
flag_status status = RESET;
|
|
switch(flag)
|
|
{
|
|
case CRM_LICK_READY_INT_FLAG:
|
|
if(CRM->clkint_bit.lickstblf && CRM->clkint_bit.lickstblien)
|
|
{
|
|
status = SET;
|
|
}
|
|
break;
|
|
case CRM_LEXT_READY_INT_FLAG:
|
|
if(CRM->clkint_bit.lextstblf && CRM->clkint_bit.lextstblien)
|
|
{
|
|
status = SET;
|
|
}
|
|
break;
|
|
case CRM_HICK_READY_INT_FLAG:
|
|
if(CRM->clkint_bit.hickstblf && CRM->clkint_bit.hickstblien)
|
|
{
|
|
status = SET;
|
|
}
|
|
break;
|
|
case CRM_HEXT_READY_INT_FLAG:
|
|
if(CRM->clkint_bit.hextstblf && CRM->clkint_bit.hextstblien)
|
|
{
|
|
status = SET;
|
|
}
|
|
break;
|
|
case CRM_PLL_READY_INT_FLAG:
|
|
if(CRM->clkint_bit.pllstblf && CRM->clkint_bit.pllstblien)
|
|
{
|
|
status = SET;
|
|
}
|
|
break;
|
|
case CRM_CLOCK_FAILURE_INT_FLAG:
|
|
if(CRM->clkint_bit.cfdf && CRM->ctrl_bit.cfden)
|
|
{
|
|
status = SET;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief wait for hext stable
|
|
* @param none
|
|
* @retval error_status (ERROR or SUCCESS)
|
|
*/
|
|
error_status crm_hext_stable_wait(void)
|
|
{
|
|
uint32_t stable_cnt = 0;
|
|
error_status status = ERROR;
|
|
|
|
while((crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET) && (stable_cnt < HEXT_STARTUP_TIMEOUT))
|
|
{
|
|
stable_cnt ++;
|
|
}
|
|
|
|
if(crm_flag_get(CRM_HEXT_STABLE_FLAG) != SET)
|
|
{
|
|
status = ERROR;
|
|
}
|
|
else
|
|
{
|
|
status = SUCCESS;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
/**
|
|
* @brief set the hick trimming value
|
|
* @param trim_value (0x00~0x3F)
|
|
* @retval none
|
|
*/
|
|
void crm_hick_clock_trimming_set(uint8_t trim_value)
|
|
{
|
|
CRM->ctrl_bit.hicktrim = trim_value;
|
|
}
|
|
|
|
/**
|
|
* @brief set the crm calibration value
|
|
* @param cali_value (0x00~0xFF)
|
|
* @retval none
|
|
*/
|
|
void crm_hick_clock_calibration_set(uint8_t cali_value)
|
|
{
|
|
/* enable write hick calibration */
|
|
CRM->misc1_bit.hickcal_key = 0x5A;
|
|
|
|
/* write hick calibration value */
|
|
CRM->ctrl_bit.hickcal = cali_value;
|
|
|
|
/* disable write hick calibration */
|
|
CRM->misc1_bit.hickcal_key = 0x0;
|
|
}
|
|
|
|
/**
|
|
* @brief enable or disable the peripheral clock
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_GPIOA_PERIPH_CLOCK - CRM_GPIOB_PERIPH_CLOCK - CRM_GPIOC_PERIPH_CLOCK - CRM_GPIOD_PERIPH_CLOCK
|
|
* - CRM_GPIOE_PERIPH_CLOCK - CRM_GPIOF_PERIPH_CLOCK - CRM_CRC_PERIPH_CLOCK - CRM_DMA1_PERIPH_CLOCK
|
|
* - CRM_DMA2_PERIPH_CLOCK - CRM_OTGFS1_PERIPH_CLOCK - CRM_XMC_PERIPH_CLOCK - CRM_TMR2_PERIPH_CLOCK
|
|
* - CRM_TMR3_PERIPH_CLOCK - CRM_TMR4_PERIPH_CLOCK - CRM_TMR6_PERIPH_CLOCK - CRM_TMR7_PERIPH_CLOCK
|
|
* - CRM_TMR12_PERIPH_CLOCK - CRM_TMR13_PERIPH_CLOCK - CRM_TMR14_PERIPH_CLOCK - CRM_WWDT_PERIPH_CLOCK
|
|
* - CRM_SPI2_PERIPH_CLOCK - CRM_SPI3_PERIPH_CLOCK - CRM_USART2_PERIPH_CLOCK - CRM_USART3_PERIPH_CLOCK
|
|
* - CRM_USART4_PERIPH_CLOCK - CRM_USART5_PERIPH_CLOCK - CRM_I2C1_PERIPH_CLOCK - CRM_I2C2_PERIPH_CLOCK
|
|
* - CRM_I2C3_PERIPH_CLOCK - CRM_CAN1_PERIPH_CLOCK - CRM_CAN2_PERIPH_CLOCK - CRM_PWC_PERIPH_CLOCK
|
|
* - CRM_DAC_PERIPH_CLOCK - CRM_USART7_PERIPH_CLOCK - CRM_USART8_PERIPH_CLOCK - CRM_TMR1_PERIPH_CLOCK
|
|
* - CRM_USART1_PERIPH_CLOCK - CRM_USART6_PERIPH_CLOCK - CRM_ADC1_PERIPH_CLOCK - CRM_SPI1_PERIPH_CLOCK
|
|
* - CRM_SCFG_PERIPH_CLOCK - CRM_TMR9_PERIPH_CLOCK - CRM_TMR10_PERIPH_CLOCK - CRM_TMR11_PERIPH_CLOCK
|
|
* - CRM_ACC_PERIPH_CLOCK
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_periph_clock_enable(crm_periph_clock_type value, confirm_state new_state)
|
|
{
|
|
/* enable periph clock */
|
|
if(TRUE == new_state)
|
|
{
|
|
CRM_REG(value) |= CRM_REG_BIT(value);
|
|
}
|
|
/* disable periph clock */
|
|
else
|
|
{
|
|
CRM_REG(value) &= ~(CRM_REG_BIT(value));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief enable or disable the peripheral reset
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_GPIOA_PERIPH_RESET - CRM_GPIOB_PERIPH_RESET - CRM_GPIOC_PERIPH_RESET - CRM_GPIOD_PERIPH_RESET
|
|
* - CRM_GPIOE_PERIPH_RESET - CRM_GPIOF_PERIPH_RESET - CRM_CRC_PERIPH_RESET - CRM_DMA1_PERIPH_RESET
|
|
* - CRM_DMA2_PERIPH_RESET - CRM_OTGFS1_PERIPH_RESET - CRM_XMC_PERIPH_RESET - CRM_QSPI1_PERIPH_RESET
|
|
* - CRM_TMR2_PERIPH_RESET - CRM_TMR3_PERIPH_RESET - CRM_TMR4_PERIPH_RESET - CRM_TMR6_PERIPH_RESET
|
|
* - CRM_TMR7_PERIPH_RESET - CRM_TMR12_PERIPH_RESET - CRM_TMR13_PERIPH_RESET - CRM_TMR14_PERIPH_RESET
|
|
* - CRM_WWDT_PERIPH_RESET - CRM_SPI2_PERIPH_RESET - CRM_SPI3_PERIPH_RESET - CRM_USART2_PERIPH_RESET
|
|
* - CRM_USART3_PERIPH_RESET - CRM_USART4_PERIPH_RESET - CRM_USART5_PERIPH_RESET - CRM_I2C1_PERIPH_RESET
|
|
* - CRM_I2C2_PERIPH_RESET - CRM_I2C3_PERIPH_RESET - CRM_CAN1_PERIPH_RESET - CRM_CAN2_PERIPH_RESET
|
|
* - CRM_PWC_PERIPH_RESET - CRM_DAC_PERIPH_RESET - CRM_USART7_PERIPH_RESET - CRM_USART8_PERIPH_RESET
|
|
* - CRM_TMR1_PERIPH_RESET - CRM_USART1_PERIPH_RESET - CRM_USART6_PERIPH_RESET - CRM_ADC_PERIPH_RESET
|
|
* - CRM_SPI1_PERIPH_RESET - CRM_SCFG_PERIPH_RESET - CRM_TMR9_PERIPH_RESET - CRM_TMR10_PERIPH_RESET
|
|
* - CRM_TMR11_PERIPH_RESET - CRM_ACC_PERIPH_RESET
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_periph_reset(crm_periph_reset_type value, confirm_state new_state)
|
|
{
|
|
/* enable periph reset */
|
|
if(new_state == TRUE)
|
|
{
|
|
CRM_REG(value) |= (CRM_REG_BIT(value));
|
|
}
|
|
/* disable periph reset */
|
|
else
|
|
{
|
|
CRM_REG(value) &= ~(CRM_REG_BIT(value));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief enable or disable the peripheral clock in lowpower mode
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_GPIOA_PERIPH_LOWPOWER - CRM_GPIOB_PERIPH_LOWPOWER - CRM_GPIOC_PERIPH_LOWPOWER - CRM_GPIOD_PERIPH_LOWPOWER
|
|
* - CRM_GPIOE_PERIPH_LOWPOWER - CRM_GPIOF_PERIPH_LOWPOWER - CRM_CRC_PERIPH_LOWPOWER - CRM_DMA1_PERIPH_LOWPOWER
|
|
* - CRM_DMA2_PERIPH_LOWPOWER - CRM_OTGFS1_PERIPH_LOWPOWER - CRM_XMC_PERIPH_LOWPOWER - CRM_TMR2_PERIPH_LOWPOWER
|
|
* - CRM_TMR3_PERIPH_LOWPOWER - CRM_TMR4_PERIPH_LOWPOWER - CRM_TMR6_PERIPH_LOWPOWER - CRM_TMR7_PERIPH_LOWPOWER
|
|
* - CRM_TMR12_PERIPH_LOWPOWER - CRM_TMR13_PERIPH_LOWPOWER - CRM_TMR14_PERIPH_LOWPOWER - CRM_WWDT_PERIPH_LOWPOWER
|
|
* - CRM_SPI2_PERIPH_LOWPOWER - CRM_SPI3_PERIPH_LOWPOWER - CRM_USART2_PERIPH_LOWPOWER - CRM_USART3_PERIPH_LOWPOWER
|
|
* - CRM_USART4_PERIPH_LOWPOWER - CRM_USART5_PERIPH_LOWPOWER - CRM_I2C1_PERIPH_LOWPOWER - CRM_I2C2_PERIPH_LOWPOWER
|
|
* - CRM_I2C3_PERIPH_LOWPOWER - CRM_CAN1_PERIPH_LOWPOWER - CRM_CAN2_PERIPH_LOWPOWER - CRM_PWC_PERIPH_LOWPOWER
|
|
* - CRM_DAC_PERIPH_LOWPOWER - CRM_USART7_PERIPH_LOWPOWER - CRM_USART8_PERIPH_LOWPOWER - CRM_TMR1_PERIPH_LOWPOWER
|
|
* - CRM_USART1_PERIPH_LOWPOWER - CRM_USART6_PERIPH_LOWPOWER - CRM_ADC1_PERIPH_LOWPOWER - CRM_SPI1_PERIPH_LOWPOWER
|
|
* - CRM_SCFG_PERIPH_LOWPOWER - CRM_TMR9_PERIPH_LOWPOWER - CRM_TMR10_PERIPH_LOWPOWER - CRM_TMR11_PERIPH_LOWPOWER
|
|
* - CRM_ACC_PERIPH_LOWPOWER - CRM_FLASH_PERIPH_LOWPOWER - CRM_SRAM_PERIPH_LOWPOWER
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_periph_lowpower_mode_enable(crm_periph_clock_lowpower_type value, confirm_state new_state)
|
|
{
|
|
/* enable periph clock in lowpower mode */
|
|
if(new_state == TRUE)
|
|
{
|
|
CRM_REG(value) |= (CRM_REG_BIT(value));
|
|
}
|
|
/* disable periph clock in lowpower mode */
|
|
else
|
|
{
|
|
CRM_REG(value) &= ~(CRM_REG_BIT(value));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief enable or disable the crm clock source
|
|
* @param source
|
|
* this parameter can be one of the following values:
|
|
* - CRM_CLOCK_SOURCE_HICK
|
|
* - CRM_CLOCK_SOURCE_HEXT
|
|
* - CRM_CLOCK_SOURCE_PLL
|
|
* - CRM_CLOCK_SOURCE_LEXT
|
|
* - CRM_CLOCK_SOURCE_LICK
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_clock_source_enable(crm_clock_source_type source, confirm_state new_state)
|
|
{
|
|
switch(source)
|
|
{
|
|
case CRM_CLOCK_SOURCE_HICK:
|
|
CRM->ctrl_bit.hicken = new_state;
|
|
break;
|
|
case CRM_CLOCK_SOURCE_HEXT:
|
|
CRM->ctrl_bit.hexten = new_state;
|
|
break;
|
|
case CRM_CLOCK_SOURCE_PLL:
|
|
CRM->ctrl_bit.pllen = new_state;
|
|
break;
|
|
case CRM_CLOCK_SOURCE_LEXT:
|
|
CRM->bpdc_bit.lexten = new_state;
|
|
break;
|
|
case CRM_CLOCK_SOURCE_LICK:
|
|
CRM->ctrlsts_bit.licken = new_state;
|
|
break;
|
|
default: break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief clear the crm reset flags
|
|
* @param flag
|
|
* this parameter can be one of the following values:
|
|
* reset flag:
|
|
* - CRM_PIN_RESET_FLAG
|
|
* - CRM_POR_RESET_FLAG
|
|
* - CRM_SW_RESET_FLAG
|
|
* - CRM_WDT_RESET_FLAG
|
|
* - CRM_WWDT_RESET_FLAG
|
|
* - CRM_LOWPOWER_RESET_FLAG
|
|
* - CRM_ALL_RESET_FLAG
|
|
* interrupt flag:
|
|
* - CRM_LICK_READY_INT_FLAG
|
|
* - CRM_LEXT_READY_INT_FLAG
|
|
* - CRM_HICK_READY_INT_FLAG
|
|
* - CRM_HEXT_READY_INT_FLAG
|
|
* - CRM_PLL_READY_INT_FLAG
|
|
* - CRM_CLOCK_FAILURE_INT_FLAG
|
|
* @retval none
|
|
*/
|
|
void crm_flag_clear(uint32_t flag)
|
|
{
|
|
switch(flag)
|
|
{
|
|
case CRM_NRST_RESET_FLAG:
|
|
case CRM_POR_RESET_FLAG:
|
|
case CRM_SW_RESET_FLAG:
|
|
case CRM_WDT_RESET_FLAG:
|
|
case CRM_WWDT_RESET_FLAG:
|
|
case CRM_LOWPOWER_RESET_FLAG:
|
|
case CRM_ALL_RESET_FLAG:
|
|
CRM->ctrlsts_bit.rstfc = TRUE;
|
|
while(CRM->ctrlsts_bit.rstfc == TRUE);
|
|
break;
|
|
case CRM_LICK_READY_INT_FLAG:
|
|
CRM->clkint_bit.lickstblfc = TRUE;
|
|
break;
|
|
case CRM_LEXT_READY_INT_FLAG:
|
|
CRM->clkint_bit.lextstblfc = TRUE;
|
|
break;
|
|
case CRM_HICK_READY_INT_FLAG:
|
|
CRM->clkint_bit.hickstblfc = TRUE;
|
|
break;
|
|
case CRM_HEXT_READY_INT_FLAG:
|
|
CRM->clkint_bit.hextstblfc = TRUE;
|
|
break;
|
|
case CRM_PLL_READY_INT_FLAG:
|
|
CRM->clkint_bit.pllstblfc = TRUE;
|
|
break;
|
|
case CRM_CLOCK_FAILURE_INT_FLAG:
|
|
CRM->clkint_bit.cfdfc = TRUE;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief select ertc clock
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_ERTC_CLOCK_NOCLK
|
|
* - CRM_ERTC_CLOCK_LEXT
|
|
* - CRM_ERTC_CLOCK_LICK
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_2
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_3
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_4
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_5
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_6
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_7
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_8
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_9
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_10
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_11
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_12
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_13
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_14
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_15
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_16
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_17
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_18
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_19
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_20
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_21
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_22
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_23
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_24
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_25
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_26
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_27
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_28
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_29
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_30
|
|
* - CRM_ERTC_CLOCK_HEXT_DIV_31
|
|
* @retval none
|
|
*/
|
|
void crm_ertc_clock_select(crm_ertc_clock_type value)
|
|
{
|
|
CRM->cfg_bit.ertcdiv = ((value & 0x1F0) >> 4);
|
|
CRM->bpdc_bit.ertcsel = (value & 0xF);
|
|
}
|
|
|
|
/**
|
|
* @brief enable or disable ertc
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_ertc_clock_enable(confirm_state new_state)
|
|
{
|
|
CRM->bpdc_bit.ertcen = new_state;
|
|
}
|
|
|
|
/**
|
|
* @brief set crm ahb division
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_AHB_DIV_1
|
|
* - CRM_AHB_DIV_2
|
|
* - CRM_AHB_DIV_4
|
|
* - CRM_AHB_DIV_8
|
|
* - CRM_AHB_DIV_16
|
|
* - CRM_AHB_DIV_64
|
|
* - CRM_AHB_DIV_128
|
|
* - CRM_AHB_DIV_256
|
|
* - CRM_AHB_DIV_512
|
|
* @retval none
|
|
*/
|
|
void crm_ahb_div_set(crm_ahb_div_type value)
|
|
{
|
|
/* enable auto step mode */
|
|
crm_auto_step_mode_enable(TRUE);
|
|
|
|
CRM->cfg_bit.ahbdiv = value;
|
|
|
|
/* disable auto step mode */
|
|
crm_auto_step_mode_enable(FALSE);
|
|
}
|
|
|
|
/**
|
|
* @brief set crm apb1 division
|
|
* @note the maximum frequency of APB1 clock is 120 MHz
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_APB1_DIV_1
|
|
* - CRM_APB1_DIV_2
|
|
* - CRM_APB1_DIV_4
|
|
* - CRM_APB1_DIV_8
|
|
* - CRM_APB1_DIV_16
|
|
* @retval none
|
|
*/
|
|
void crm_apb1_div_set(crm_apb1_div_type value)
|
|
{
|
|
CRM->cfg_bit.apb1div = value;
|
|
}
|
|
|
|
/**
|
|
* @brief set crm apb2 division
|
|
* @note the maximum frequency of APB2 clock is 150 MHz
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_APB2_DIV_1
|
|
* - CRM_APB2_DIV_2
|
|
* - CRM_APB2_DIV_4
|
|
* - CRM_APB2_DIV_8
|
|
* - CRM_APB2_DIV_16
|
|
* @retval none
|
|
*/
|
|
void crm_apb2_div_set(crm_apb2_div_type value)
|
|
{
|
|
CRM->cfg_bit.apb2div = value;
|
|
}
|
|
|
|
/**
|
|
* @brief set crm hext to sysclk division
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_HEXT_SCLK_DIV_1
|
|
* - CRM_HEXT_SCLK_DIV_2
|
|
* - CRM_HEXT_SCLK_DIV_4
|
|
* - CRM_HEXT_SCLK_DIV_8
|
|
* - CRM_HEXT_SCLK_DIV_16
|
|
* - CRM_HEXT_SCLK_DIV_32
|
|
* @retval none
|
|
*/
|
|
void crm_hext_sclk_div_set(crm_hext_sclk_div_type value)
|
|
{
|
|
CRM->misc2_bit.hext_to_sclk_div = value;
|
|
}
|
|
|
|
/**
|
|
* @brief set crm hick to sysclk division
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_HICK_SCLK_DIV_1
|
|
* - CRM_HICK_SCLK_DIV_2
|
|
* - CRM_HICK_SCLK_DIV_4
|
|
* - CRM_HICK_SCLK_DIV_8
|
|
* - CRM_HICK_SCLK_DIV_16
|
|
* @retval none
|
|
*/
|
|
void crm_hick_sclk_div_set(crm_hick_sclk_div_type value)
|
|
{
|
|
CRM->misc2_bit.hick_to_sclk_div = value;
|
|
}
|
|
|
|
/**
|
|
* @brief set usb division
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_USB_DIV_3
|
|
* - CRM_USB_DIV_2
|
|
* - CRM_USB_DIV_5
|
|
* - CRM_USB_DIV_4
|
|
* - CRM_USB_DIV_7
|
|
* - CRM_USB_DIV_6
|
|
* - CRM_USB_DIV_9
|
|
* - CRM_USB_DIV_8
|
|
* @retval none
|
|
*/
|
|
void crm_usb_clock_div_set(crm_usb_div_type value)
|
|
{
|
|
CRM->misc2_bit.usbdiv = value;
|
|
}
|
|
|
|
/**
|
|
* @brief enable or disable clock failure detection
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_clock_failure_detection_enable(confirm_state new_state)
|
|
{
|
|
CRM->ctrl_bit.cfden = new_state;
|
|
}
|
|
|
|
/**
|
|
* @brief battery powered domain software reset
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_battery_powered_domain_reset(confirm_state new_state)
|
|
{
|
|
CRM->bpdc_bit.bpdrst = new_state;
|
|
}
|
|
|
|
/**
|
|
* @brief auto step clock switch enable
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_auto_step_mode_enable(confirm_state new_state)
|
|
{
|
|
if(new_state == TRUE)
|
|
CRM->misc2_bit.auto_step_en = CRM_AUTO_STEP_MODE_ENABLE;
|
|
else
|
|
CRM->misc2_bit.auto_step_en = CRM_AUTO_STEP_MODE_DISABLE;
|
|
}
|
|
|
|
/**
|
|
* @brief usart multi clock source select
|
|
* @param usart_index
|
|
* this parameter can be one of the following values:
|
|
* - CRM_USART1
|
|
* - CRM_USART2
|
|
* - CRM_USART3
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_USART_CLOCK_SOURCE_PCLK
|
|
* - CRM_USART_CLOCK_SOURCE_SCLK
|
|
* - CRM_USART_CLOCK_SOURCE_HICK
|
|
* - CRM_USART_CLOCK_SOURCE_LEXT
|
|
* @retval none
|
|
*/
|
|
void crm_usart_clock_select(crm_usart_type usart_index, crm_usart_clock_source_type value)
|
|
{
|
|
switch(usart_index)
|
|
{
|
|
case CRM_USART1:
|
|
CRM->piclks_bit.usart1sel = value;
|
|
break;
|
|
case CRM_USART2:
|
|
CRM->piclks_bit.usart2sel = value;
|
|
break;
|
|
case CRM_USART3:
|
|
CRM->piclks_bit.usart3sel = value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief usart multi clock source select
|
|
* @param usart_index
|
|
* this parameter can be one of the following values:
|
|
* - CRM_USART1
|
|
* - CRM_USART2
|
|
* - CRM_USART3
|
|
* @retval crm_usart_clock_source_type : the clock source of usart index.
|
|
*/
|
|
crm_usart_clock_source_type crm_usart_clock_get(crm_usart_type usart_index)
|
|
{
|
|
crm_usart_clock_source_type value = CRM_USART_CLOCK_SOURCE_PCLK;
|
|
|
|
switch(usart_index)
|
|
{
|
|
case CRM_USART1:
|
|
value = (crm_usart_clock_source_type)CRM->piclks_bit.usart1sel;
|
|
break;
|
|
case CRM_USART2:
|
|
value = (crm_usart_clock_source_type)CRM->piclks_bit.usart2sel;
|
|
break;
|
|
case CRM_USART3:
|
|
value = (crm_usart_clock_source_type)CRM->piclks_bit.usart3sel;
|
|
break;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* @brief i2c multi clock source select
|
|
* @param i2c_index
|
|
* this parameter can be one of the following values:
|
|
* - CRM_I2C1
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_I2C_CLOCK_SOURCE_PCLK
|
|
* - CRM_I2C_CLOCK_SOURCE_SCLK
|
|
* - CRM_I2C_CLOCK_SOURCE_HICK
|
|
* @retval none
|
|
*/
|
|
void crm_i2c_clock_select(crm_i2c_type i2c_index, crm_i2c_clock_source_type value)
|
|
{
|
|
switch(i2c_index)
|
|
{
|
|
case CRM_I2C1:
|
|
CRM->piclks_bit.i2c1sel = value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief i2c multi clock source select
|
|
* @param i2c_index
|
|
* this parameter can be one of the following values:
|
|
* - CRM_I2C1
|
|
* @retval crm_i2c_clock_source_type : the clock source of i2c index.
|
|
*/
|
|
crm_i2c_clock_source_type crm_i2c_clock_get(crm_i2c_type i2c_index)
|
|
{
|
|
crm_i2c_clock_source_type value = CRM_I2C_CLOCK_SOURCE_PCLK;
|
|
|
|
switch(i2c_index)
|
|
{
|
|
case CRM_I2C1:
|
|
value = (crm_i2c_clock_source_type)CRM->piclks_bit.i2c1sel;
|
|
break;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
/**
|
|
* @brief adc multi clock source select
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_ADC_CLOCK_SOURCE_HCLK
|
|
* - CRM_ADC_CLOCK_SOURCE_PLLCLK
|
|
* @retval none
|
|
*/
|
|
void crm_adc_clock_select(crm_adc_clock_source_type value)
|
|
{
|
|
CRM->misc1_bit.pllclk_to_adc = value;
|
|
}
|
|
|
|
/**
|
|
* @brief config hick divider select
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_HICK48_DIV6
|
|
* - CRM_HICK48_NODIV
|
|
* @retval none
|
|
*/
|
|
void crm_hick_divider_select(crm_hick_div_6_type value)
|
|
{
|
|
__IO uint8_t temp_div = CRM->misc2_bit.hick_to_sclk_div;
|
|
__IO uint8_t temp_sclk = CRM->misc1_bit.hick_to_sclk;
|
|
|
|
crm_hick_sclk_div_set(CRM_HICK_SCLK_DIV_16);
|
|
/* delay */
|
|
{
|
|
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
|
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
|
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
|
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
|
}
|
|
|
|
CRM->misc1_bit.hick_to_sclk = TRUE;
|
|
CRM->misc1_bit.hickdiv = value;
|
|
CRM->misc1_bit.hick_to_sclk = temp_sclk;
|
|
crm_hick_sclk_div_set((crm_hick_sclk_div_type)temp_div);
|
|
}
|
|
|
|
/**
|
|
* @brief hick as system clock frequency select
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_HICK_SCLK_8MHZ
|
|
* - CRM_HICK_SCLK_48MHZ
|
|
* @retval none
|
|
*/
|
|
void crm_hick_sclk_frequency_select(crm_hick_sclk_frequency_type value)
|
|
{
|
|
__IO uint8_t temp_div = CRM->misc2_bit.hick_to_sclk_div;
|
|
|
|
crm_hick_sclk_div_set(CRM_HICK_SCLK_DIV_16);
|
|
/* delay */
|
|
{
|
|
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
|
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
|
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
|
__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
|
|
}
|
|
|
|
CRM->misc1_bit.hick_to_sclk = TRUE;
|
|
CRM->misc1_bit.hickdiv = CRM_HICK48_NODIV;
|
|
CRM->misc1_bit.hick_to_sclk = value;
|
|
crm_hick_sclk_div_set((crm_hick_sclk_div_type)temp_div);
|
|
}
|
|
|
|
/**
|
|
* @brief usb 48 mhz clock source select
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_USB_CLOCK_SOURCE_PLL
|
|
* - CRM_USB_CLOCK_SOURCE_HICK
|
|
* @retval none
|
|
*/
|
|
void crm_usb_clock_source_select(crm_usb_clock_source_type value)
|
|
{
|
|
if(value == CRM_USB_CLOCK_SOURCE_HICK)
|
|
{
|
|
crm_hick_sclk_frequency_select(CRM_HICK_SCLK_48MHZ);
|
|
}
|
|
CRM->misc1_bit.hick_to_usb = value;
|
|
}
|
|
|
|
/**
|
|
* @brief config crm pll
|
|
* pll_rcs_freq * pll_ns
|
|
* pll clock = --------------------------------
|
|
* pll_ms * pll_fr_n
|
|
* attemtion:
|
|
* 31 <= pll_ns <= 500
|
|
* 1 <= pll_ms <= 15
|
|
*
|
|
* pll_rcs_freq
|
|
* 2mhz <= ---------------------- <= 16mhz
|
|
* pll_ms
|
|
*
|
|
* pll_rcs_freq * pll_ns
|
|
* 500mhz <= -------------------------------- <= 1000mhz
|
|
* pll_ms
|
|
* @param clock_source
|
|
* this parameter can be one of the following values:
|
|
* - CRM_PLL_SOURCE_HICK
|
|
* - CRM_PLL_SOURCE_HEXT
|
|
* @param pll_ns (31~500)
|
|
* @param pll_ms (1~15)
|
|
* @param pll_fr
|
|
* this parameter can be one of the following values:
|
|
* - CRM_PLL_FR_1
|
|
* - CRM_PLL_FR_2
|
|
* - CRM_PLL_FR_4
|
|
* - CRM_PLL_FR_8
|
|
* - CRM_PLL_FR_16
|
|
* - CRM_PLL_FR_32
|
|
* @retval none
|
|
*/
|
|
void crm_pll_config(crm_pll_clock_source_type clock_source, uint16_t pll_ns, \
|
|
uint16_t pll_ms, crm_pll_fr_type pll_fr)
|
|
{
|
|
/* config pll clock source */
|
|
if(clock_source == CRM_PLL_SOURCE_HICK)
|
|
{
|
|
CRM->misc1_bit.hickdiv = CRM_HICK48_NODIV;
|
|
}
|
|
CRM->pllcfg_bit.pllrcs = clock_source;
|
|
|
|
/* config pll multiplication factor */
|
|
CRM->pllcfg_bit.pllns = pll_ns;
|
|
CRM->pllcfg_bit.pllms = pll_ms;
|
|
CRM->pllcfg_bit.pllfr = pll_fr;
|
|
}
|
|
|
|
/**
|
|
* @brief select system clock source
|
|
* @param value
|
|
* this parameter can be one of the following values:
|
|
* - CRM_SCLK_HICK
|
|
* - CRM_SCLK_HEXT
|
|
* - CRM_SCLK_PLL
|
|
* @retval none
|
|
*/
|
|
void crm_sysclk_switch(crm_sclk_type value)
|
|
{
|
|
/* enable auto step mode */
|
|
crm_auto_step_mode_enable(TRUE);
|
|
|
|
CRM->cfg_bit.sclksel = value;
|
|
|
|
/* disable auto step mode */
|
|
crm_auto_step_mode_enable(FALSE);
|
|
}
|
|
|
|
/**
|
|
* @brief indicate which clock source is used as system clock
|
|
* @param none
|
|
* @retval crm_sclk
|
|
* this return can be one of the following values:
|
|
* - CRM_SCLK_HICK
|
|
* - CRM_SCLK_HEXT
|
|
* - CRM_SCLK_PLL
|
|
*/
|
|
crm_sclk_type crm_sysclk_switch_status_get(void)
|
|
{
|
|
return (crm_sclk_type)CRM->cfg_bit.sclksts;
|
|
}
|
|
|
|
/**
|
|
* @brief get crm clocks freqency
|
|
* @param clocks_struct
|
|
* - pointer to the crm_clocks_freq_type structure
|
|
* @retval none
|
|
*/
|
|
void crm_clocks_freq_get(crm_clocks_freq_type *clocks_struct)
|
|
{
|
|
uint32_t pll_ns = 0, pll_ms = 0, pll_fr = 0, pll_clock_source = 0, pllrcsfreq = 0;
|
|
uint32_t temp = 0, div_value = 0, psc = 0;
|
|
crm_sclk_type sclk_source;
|
|
|
|
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};
|
|
static const uint8_t ahb_apb1_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
|
static const uint8_t ahb_apb2_div_table[8] = {0, 0, 0, 0, 1, 2, 3, 4};
|
|
static const uint8_t pll_fr_table[6] = {1, 2, 4, 8, 16, 32};
|
|
|
|
/* get sclk source */
|
|
sclk_source = crm_sysclk_switch_status_get();
|
|
|
|
switch(sclk_source)
|
|
{
|
|
case CRM_SCLK_HICK:
|
|
if(((CRM->misc1_bit.hick_to_sclk) != RESET) && ((CRM->misc1_bit.hickdiv) != RESET))
|
|
clocks_struct->sclk_freq = HICK_VALUE * 6;
|
|
else
|
|
clocks_struct->sclk_freq = HICK_VALUE;
|
|
|
|
psc = CRM->misc2_bit.hick_to_sclk_div;
|
|
clocks_struct->sclk_freq = clocks_struct->sclk_freq >> psc;
|
|
break;
|
|
case CRM_SCLK_HEXT:
|
|
clocks_struct->sclk_freq = HEXT_VALUE;
|
|
psc = CRM->misc2_bit.hext_to_sclk_div;
|
|
clocks_struct->sclk_freq = clocks_struct->sclk_freq >> psc;
|
|
break;
|
|
case CRM_SCLK_PLL:
|
|
/* get pll clock source */
|
|
pll_clock_source = CRM->pllcfg_bit.pllrcs;
|
|
|
|
/* get multiplication factor */
|
|
pll_ns = CRM->pllcfg_bit.pllns;
|
|
pll_ms = CRM->pllcfg_bit.pllms;
|
|
pll_fr = pll_fr_table[CRM->pllcfg_bit.pllfr];
|
|
|
|
if (pll_clock_source == CRM_PLL_SOURCE_HICK)
|
|
{
|
|
/* hick selected as pll clock entry */
|
|
pllrcsfreq = HICK_VALUE;
|
|
}
|
|
else
|
|
{
|
|
/* hext selected as pll clock entry */
|
|
pllrcsfreq = HEXT_VALUE;
|
|
}
|
|
|
|
clocks_struct->sclk_freq = (uint32_t)(((uint64_t)pllrcsfreq * pll_ns) / (pll_ms * pll_fr) / 2);
|
|
break;
|
|
default:
|
|
clocks_struct->sclk_freq = HICK_VALUE;
|
|
break;
|
|
}
|
|
|
|
/* compute sclk, ahbclk, abp1clk and apb2clk frequencies */
|
|
/* get ahb division */
|
|
temp = CRM->cfg_bit.ahbdiv;
|
|
div_value = sclk_ahb_div_table[temp];
|
|
/* ahbclk frequency */
|
|
clocks_struct->ahb_freq = clocks_struct->sclk_freq >> div_value;
|
|
|
|
/* get apb1 division */
|
|
temp = CRM->cfg_bit.apb1div;
|
|
div_value = ahb_apb1_div_table[temp];
|
|
/* apb1clk frequency */
|
|
clocks_struct->apb1_freq = clocks_struct->ahb_freq >> div_value;
|
|
|
|
/* get apb2 division */
|
|
temp = CRM->cfg_bit.apb2div;
|
|
div_value = ahb_apb2_div_table[temp];
|
|
/* apb2clk frequency */
|
|
clocks_struct->apb2_freq = clocks_struct->ahb_freq >> div_value;
|
|
}
|
|
|
|
/**
|
|
* @brief set crm clkout
|
|
* @param clkout
|
|
* this parameter can be one of the following values:
|
|
* - CRM_CLKOUT_SCLK
|
|
* - CRM_CLKOUT_HEXT
|
|
* - CRM_CLKOUT_PLL
|
|
* - CRM_CLKOUT_USB
|
|
* - CRM_CLKOUT_ADC
|
|
* - CRM_CLKOUT_HICK
|
|
* - CRM_CLKOUT_LICK
|
|
* - CRM_CLKOUT_LEXT
|
|
* @retval none
|
|
*/
|
|
void crm_clock_out_set(crm_clkout_select_type clkout)
|
|
{
|
|
if(clkout < 0x10)
|
|
{
|
|
CRM->cfg_bit.clkout_sel1 = (clkout & 0x3);
|
|
}
|
|
else
|
|
{
|
|
CRM->cfg_bit.clkout_sel1 = 0x1;
|
|
CRM->misc1_bit.clkout_sel2 = (clkout & 0xF);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @brief set crm clkout1 division1
|
|
* @param div1
|
|
* this parameter can be one of the following values:
|
|
* - CRM_CLKOUT_DIV1_1
|
|
* - CRM_CLKOUT_DIV1_2
|
|
* - CRM_CLKOUT_DIV1_3
|
|
* - CRM_CLKOUT_DIV1_4
|
|
* - CRM_CLKOUT_DIV1_5
|
|
* @param div2
|
|
* this parameter can be one of the following values:
|
|
* - CRM_CLKOUT_DIV2_1
|
|
* - CRM_CLKOUT_DIV2_2
|
|
* - CRM_CLKOUT_DIV2_4
|
|
* - CRM_CLKOUT_DIV2_8
|
|
* - CRM_CLKOUT_DIV2_16
|
|
* - CRM_CLKOUT_DIV2_64
|
|
* - CRM_CLKOUT_DIV2_128
|
|
* - CRM_CLKOUT_DIV2_256
|
|
* - CRM_CLKOUT_DIV2_512
|
|
* @retval none
|
|
*/
|
|
void crm_clkout_div_set(crm_clkout_div1_type div1, crm_clkout_div2_type div2)
|
|
{
|
|
CRM->cfg_bit.clkoutdiv1 = div1;
|
|
CRM->misc1_bit.clkoutdiv2 = div2;
|
|
}
|
|
|
|
/**
|
|
* @brief config crm interrupt
|
|
* @param int
|
|
* this parameter can be any combination of the following values:
|
|
* - CRM_LICK_STABLE_INT
|
|
* - CRM_LEXT_STABLE_INT
|
|
* - CRM_HICK_STABLE_INT
|
|
* - CRM_HEXT_STABLE_INT
|
|
* - CRM_PLL_STABLE_INT
|
|
* @param new_state (TRUE or FALSE)
|
|
* @retval none
|
|
*/
|
|
void crm_interrupt_enable(uint32_t crm_int, confirm_state new_state)
|
|
{
|
|
if(TRUE == new_state)
|
|
CRM->clkint |= crm_int;
|
|
else
|
|
CRM->clkint &= ~crm_int;
|
|
}
|
|
|
|
/**
|
|
* @brief calculate the pll parameters with pll reference clock and target pll output frequency.
|
|
* pll_rcs_freq * pll_ns
|
|
* pll clock = --------------------------------
|
|
* pll_ms * pll_fr_n
|
|
* attemtion:
|
|
* 31 <= pll_ns <= 500
|
|
* 1 <= pll_ms <= 15
|
|
*
|
|
* pll_rcs_freq
|
|
* 2mhz <= ---------------------- <= 16mhz
|
|
* pll_ms
|
|
*
|
|
* pll_rcs_freq * pll_ns
|
|
* 500mhz <= -------------------------------- <= 1000mhz
|
|
* pll_ms
|
|
* @param pll_rcs
|
|
* this parameter can be one of the following values:
|
|
* - CRM_PLL_SOURCE_HICK
|
|
* - CRM_PLL_SOURCE_HEXT
|
|
* @param target_sclk_freq: target pll output frequency, such as 200 mhz (target_sclk_freq: 200000000)
|
|
* @param ret_ms: pointer to ms value, return the pll_ms of pll parameters
|
|
* @param ret_ns: pointer to ns value, return the pll_ns of pll parameters
|
|
* @param ret_fr: pointer to fr value, return the pll_fr of pll parameters
|
|
* @retval error_status (SUCCESS or ERROR)
|
|
*/
|
|
error_status crm_pll_parameter_calculate(crm_pll_clock_source_type pll_rcs, uint32_t target_sclk_freq, \
|
|
uint16_t *ret_ms, uint16_t *ret_ns, uint16_t *ret_fr)
|
|
{
|
|
uint32_t error_min = 0xFFFFFFFF;
|
|
uint32_t pll_rcs_freq = 0, result = 0, absolute_value = 0;
|
|
uint16_t ns = 0, ms = 0, fr = 0, ms_min = 0, ms_max = 0;
|
|
|
|
/* reduce calculate accuracy, target_sclk_freq accuracy with khz */
|
|
target_sclk_freq = target_sclk_freq / 1000 * 2;
|
|
|
|
/* get pll reference clock frequency, accuracy with khz */
|
|
if(pll_rcs == CRM_PLL_SOURCE_HICK)
|
|
pll_rcs_freq = HICK_VALUE / 1000;
|
|
else
|
|
pll_rcs_freq = HEXT_VALUE / 1000;
|
|
|
|
/* polling ms range, accuracy with khz */
|
|
for(ms = 1; ms <= 15; ms ++)
|
|
{
|
|
result = pll_rcs_freq / ms;
|
|
if((result >= 2000U) && (result <= 16000U))
|
|
{
|
|
if(ms_min == 0)
|
|
ms_min = ms;
|
|
|
|
ms_max = ms;
|
|
}
|
|
}
|
|
|
|
/* polling pll parameters */
|
|
for(ms = ms_min; ms <= ms_max; ms ++)
|
|
{
|
|
for(fr = 0; fr <= 5; fr ++)
|
|
{
|
|
for(ns = 31; ns <= 500; ns ++)
|
|
{
|
|
result = (pll_rcs_freq * ns) / (ms);
|
|
/* check vco frequency range, accuracy with khz */
|
|
if((result < 500000U) || (result > 1000000U))
|
|
{
|
|
continue;
|
|
}
|
|
/* calculate pll output frequency */
|
|
result = result / (0x1 << fr);
|
|
/* check frequency */
|
|
if(target_sclk_freq == result)
|
|
{
|
|
*ret_ms = ms;
|
|
*ret_ns = ns;
|
|
*ret_fr = fr;
|
|
/* the pll parameters that is equal to target_sclk_freq */
|
|
return SUCCESS;
|
|
}
|
|
/* calculate error range, accuracy with khz */
|
|
absolute_value = (result > target_sclk_freq) ? (result - target_sclk_freq) : (target_sclk_freq - result);
|
|
if(absolute_value < error_min)
|
|
{
|
|
error_min = absolute_value;
|
|
*ret_ms = ms;
|
|
*ret_ns = ns;
|
|
*ret_fr = fr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/* the pll parameters that is the closest approach to target_sclk_freq */
|
|
return ERROR;
|
|
}
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#endif
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @}
|
|
*/
|