/** ****************************************************************************** * @file system_py32f403.c * @author MCU Application Team * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File ****************************************************************************** * @attention * *

© Copyright (c) 2023 Puya Semiconductor Co. * All rights reserved.

* * This software component is licensed by Puya under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** * @attention * *

© Copyright (c) 2016 STMicroelectronics. * All rights reserved.

* * This software component is licensed by ST under BSD 3-Clause license, * the "License"; You may not use this file except in compliance with the * License. You may obtain a copy of the License at: * opensource.org/licenses/BSD-3-Clause * ****************************************************************************** */ /** @addtogroup CMSIS * @{ */ /** @addtogroup py32f403_system * @{ */ /** @addtogroup py32f403_System_Private_Includes * @{ */ #include "py32f4xx.h" #if !defined (HSE_VALUE) #define HSE_VALUE ((uint32_t)24000000) /*!< Default value of the External oscillator in Hz */ #endif /* HSE_VALUE */ #if !defined (HSI_VALUE) #define HSI_VALUE ((uint32_t)8000000) /*!< Value of the Internal oscillator in Hz*/ #endif /* HSI_VALUE */ /** * @} */ /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ /******************************************************************************/ /** @addtogroup PY32F403_System_Private_Variables * @{ */ /* This variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetHCLKFreq() 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency Note: If you use this function to configure the system clock; then there is no need to call the 2 first functions listed above, since SystemCoreClock variable is updated automatically. */ uint32_t SystemCoreClock = HSI_VALUE; const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9}; const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4}; /** * @} */ /** @addtogroup PY32F403_System_Private_Functions * @{ */ void APP_ErrorProc(void) { HAL_NVIC_SystemReset(); } /** * @brief Load trim. * @param None * @retval None */ void APP_LoadTrim(void) { uint32_t OPTAddr[]={0x1FFF5110,0x1FFF5114,0x1FFF5118,0x1FFF5148,0x1FFF514C,0x1FFF5600,0x1FFF5604,0x1FFF5200,0x1FFF5204,\ 0x1FFF5140,0x1FFF5144,0x1FFF5208,0x1FFF5120,0x1FFF5124,0x1FFF5128,0x1FFF512C,0x1FFF5130,0x1FFF5134}; uint32_t OPTValue[18] = {0}; uint32_t RegAddr[]={0x40022208,0x4002220C,0x40022220,0x40022228,0x40022224,0x4002221C,0x4002222C,0x40022210,0x40022214,0x40022218}; uint32_t RegMask[]={0x0FFF0FFF,0x000000FF,0x001F000F,0x1FFF07FF,0x07FF07FF,0x003F003F,0x0000003F,0xFFFFFFFF,0xFFFFFFFF,0x0FFF0FFF}; uint32_t RegValue[10] = {0}; uint32_t i = 0; uint32_t j = 0; uint32_t temp = 0; /* Enable FLASH_KEYR */ *((__IO uint32_t *)(0x40022008)) = 0x45670123; *((__IO uint32_t *)(0x40022008)) = 0xcdef89ab; /* Enable FLASH_OPTKEYR */ *((__IO uint32_t *)(0x4002200c)) = 0x08192A3B; *((__IO uint32_t *)(0x4002200c)) = 0x4C5D6E7F; /* Enable FLASH_TESTKEYR */ *((__IO uint32_t *)(0x4002228c)) = 0x5D7F4051; *((__IO uint32_t *)(0x4002228c)) = 0x46CE2763; /*********************************************/ for (i=0; i < 18; i++) { j=3; do { temp = READ_REG(*((__IO uint32_t *)(OPTAddr[i]))); if ((temp >> 16U) == ((~temp) & 0xFFFFU)) { OPTValue[i] = temp; break; } }while(--j); if(j == 0) { APP_ErrorProc(); } } /*(1) 0x40022208*/ RegValue[0] = (OPTValue[0] & 0x0FFF) | ((OPTValue[1] & 0x0FFF) << 16); /*(2) 0x4002220C*/ RegValue[1] = (OPTValue[2] & 0x00FF); /*(3) 0x40022220*/ RegValue[2] = (OPTValue[3] & 0x000F) | ((OPTValue[4] & 0x001F) << 16); /*(4) 0x40022228*/ RegValue[3] = (OPTValue[5] & 0x07FF) | ((OPTValue[6] & 0x1FFF) << 16); /*(5) 0x40022224*/ RegValue[4] = (OPTValue[7] & 0x07FF) | ((OPTValue[8] & 0x07FF) << 16); /*(6) 0x4002221C*/ RegValue[5] = (OPTValue[9] & 0x003F) | ((OPTValue[10] & 0x003F) << 16); /*(7) 0x4002222C*/ RegValue[6] = (OPTValue[11] & 0x003F); /*(8) 0x40022210*/ RegValue[7] = (OPTValue[12] & 0xFFFF) | ((OPTValue[13] & 0xFFFF) << 16); /*(9) 0x40022214*/ RegValue[8] = (OPTValue[14] & 0xFFFF) | ((OPTValue[15] & 0xFFFF) << 16); /*(10) 0x40022218*/ RegValue[9] = (OPTValue[16] & 0x0FFF) | ((OPTValue[17] & 0x0FFF) << 16); for(i=0; i < 10;i++) { temp = READ_REG(*((__IO uint32_t *)(RegAddr[i]))); if (RegValue[i] != (temp & RegMask[i])) { MODIFY_REG(*((__IO uint32_t *)(RegAddr[i])), RegMask[i], RegValue[i]); } } /*********************************************/ /* Enable TRIM update */ *((__IO uint32_t *)(0x40022200)) |= 0x01; /* Wait ten nop delays */ __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); /* Disable TRIM update */ *((__IO uint32_t *)(0x40022200)) &= (~0x01); for(i=0; i < 10;i++) { temp = READ_REG(*((__IO uint32_t *)(RegAddr[i]))); if (RegValue[i] != (temp & RegMask[i])) { APP_ErrorProc(); } } /* Disable FLASH_OPTKEYR、FLASH_TESTKEYR */ *((__IO uint32_t *)(0x40022014)) |= 0x40000000; /* Disable FLASH_KEYR、FLASH_TESTKEYR */ *((__IO uint32_t *)(0x40022014)) |= 0x80000000; } /** * @brief Setup the microcontroller system * Initialize the FPU setting, vector table location and External memory * configuration. * @param None * @retval None */ void SystemInit(void) { /* Load trim */ APP_LoadTrim(); #if (__FPU_PRESENT == 1) && (__FPU_USED == 1) SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */ #endif /* Configure the Vector Table location add offset address ------------------*/ #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 SystemCoreClock variable according to Clock Register Values. * The SystemCoreClock variable contains the core clock (HCLK), it can * be used by the user application to setup the SysTick timer or configure * other parameters. * * @note Each time the core clock (HCLK) changes, this function must be called * to update SystemCoreClock variable value. Otherwise, any configuration * based on this variable will be incorrect. * * @note - The system frequency computed by this function is not the real * frequency in the chip. It is calculated based on the predefined * constant and the selected clock source: * * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*) * * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**) * * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**) * or HSI_VALUE(*) multiplied/divided by the PLL factors. * * (*) HSI_VALUE is a constant defined in py32f403_hal_conf.h file (default value * 8 MHz) but the real value may vary depending on the variations * in voltage and temperature. * * (**) HSE_VALUE is a constant defined in py32f403_hal_conf.h file (its value * depends on the application requirements), user has to ensure that HSE_VALUE * is same as the real frequency of the crystal used. Otherwise, this function * may have wrong result. * * - The result of this function could be not correct when using fractional * value for HSE crystal. * * @param None * @retval None */ void SystemCoreClockUpdate(void) { const uint8_t aPLLMULFactorTable[64] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, \ 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, \ 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, \ 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 63, 63}; const uint8_t aPredivFactorTable[2] = {1, 2}; uint32_t tmpreg = 0U, prediv = 0U, pllclk = 0U, pllmul = 0U; uint32_t tmp = 0; tmpreg = RCC->CFGR; /* Get SYSCLK source -------------------------------------------------------*/ switch (tmpreg & RCC_CFGR_SWS) { case 0x00: /* HSI used as system clock source */ { SystemCoreClock = HSI_VALUE; break; } case 0x04: /* HSE used as system clock */ { SystemCoreClock = HSE_VALUE; break; } case 0x08: /* PLL used as system clock */ { pllmul = aPLLMULFactorTable[(((tmpreg&(RCC_CFGR_PLLMULL_4|RCC_CFGR_PLLMULL_5))>>7) | (tmpreg&(RCC_CFGR_PLLMULL_0| \ RCC_CFGR_PLLMULL_1|RCC_CFGR_PLLMULL_2|RCC_CFGR_PLLMULL_3)))>>RCC_CFGR_PLLMULL_Pos]; if ((tmpreg & RCC_CFGR_PLLSRC) == RCC_CFGR_PLLSRC) { prediv = aPredivFactorTable[(uint32_t)(RCC->CFGR & RCC_CFGR_PLLXTPRE) >> RCC_CFGR_PLLXTPRE_Pos]; /* HSE used as PLL clock source : PLLCLK = HSE/PREDIV1 * PLLMUL */ pllclk = (uint32_t)((HSE_VALUE * pllmul) / prediv); } else { /* HSI used as PLL clock source : PLLCLK = HSI * PLLMUL */ pllclk = (uint32_t)(HSI_VALUE * pllmul); } SystemCoreClock = pllclk; break; } default: { break; } } /* Get HCLK prescaler */ tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)]; SystemCoreClock >>= tmp; } /** * @} */ /************************ (C) COPYRIGHT Puya *****END OF FILE******************/