AT32F435_437_Firmware_Library/libraries/cmsis/cm4/device_support/system_at32f435_437.c

181 lines
5.4 KiB
C

/**
**************************************************************************
* @file system_at32f435_437.c
* @brief contains all the functions for cmsis cortex-m4 system source file
**************************************************************************
* 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.
*
**************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup AT32F435_437_system
* @{
*/
#include "at32f435_437.h"
/** @addtogroup AT32F435_437_system_private_defines
* @{
*/
#define VECT_TAB_OFFSET 0x0 /*!< vector table base offset field. this value must be a multiple of 0x400. */
/**
* @}
*/
/** @addtogroup AT32F435_437_system_private_variables
* @{
*/
unsigned int system_core_clock = HICK_VALUE; /*!< system clock frequency (core clock) */
/**
* @}
*/
/** @addtogroup AT32F435_437_system_private_functions
* @{
*/
/**
* @brief setup the microcontroller system
* initialize the flash interface.
* @note this function should be used only after reset.
* @param none
* @retval none
*/
void SystemInit (void)
{
#if defined (__FPU_USED) && (__FPU_USED == 1U)
SCB->CPACR |= ((3U << 10U * 2U) | /* set cp10 full access */
(3U << 11U * 2U) ); /* set cp11 full access */
#endif
/* reset the crm clock configuration to the default reset state(for debug purpose) */
/* 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 = 0;
/* reset pllms pllns pllfr pllrcs bits */
CRM->pllcfg = 0x00033002U;
/* reset clkout[3], usbbufs, hickdiv, clkoutdiv */
CRM->misc1 = 0;
/* disable all interrupts enable and clear pending bits */
CRM->clkint = 0x009F0000U;
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* vector table relocation in internal sram. */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* vector table relocation in internal flash. */
#endif
}
/**
* @brief update system_core_clock variable according to clock register values.
* the system_core_clock variable contains the core clock (hclk), it can
* be used by the user application to setup the systick timer or configure
* other parameters.
* @param none
* @retval none
*/
void system_core_clock_update(void)
{
uint32_t pll_ns = 0, pll_ms = 0, pll_fr = 0, pll_clock_source = 0, pllrcsfreq = 0;
uint32_t temp = 0, div_value = 0;
crm_sclk_type sclk_source;
static const uint8_t sys_ahb_div_table[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
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))
system_core_clock = HICK_VALUE * 6;
else
system_core_clock = HICK_VALUE;
break;
case CRM_SCLK_HEXT:
system_core_clock = HEXT_VALUE;
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;
}
system_core_clock = (uint32_t)(((uint64_t)pllrcsfreq * pll_ns) / (pll_ms * pll_fr));
break;
default:
system_core_clock = HICK_VALUE;
break;
}
/* compute sclk, ahbclk frequency */
/* get ahb division */
temp = CRM->cfg_bit.ahbdiv;
div_value = sys_ahb_div_table[temp];
/* ahbclk frequency */
system_core_clock = system_core_clock >> div_value;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/