1 /**
2   ******************************************************************************
3   * @file    system_stm32mp1xx.c
4   * @author  MCD Application Team
5   * @brief   CMSIS Cortex Device Peripheral Access Layer System Source File.
6   *
7   *   This file provides two functions and one global variable to be called from
8   *   user application:
9   *      - SystemInit(): This function is called at startup just after reset and
10   *                      before branch to main program. This call is made inside
11   *                      the "startup_stm32mp1xx.s" file.
12   *
13   *      - SystemCoreClock variable: Contains the core clock frequency, it can
14   *                                  be used by the user application to setup
15   *                                  the SysTick timer or configure other
16   *                                  parameters.
17   *
18   *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
19   *                                 be called whenever the core clock is changed
20   *                                 during program execution.
21   *
22   *
23   ******************************************************************************
24   * @attention
25   *
26   * Copyright (c) 2019 STMicroelectronics.
27   * All rights reserved.
28   *
29   * This software is licensed under terms that can be found in the LICENSE file
30   * in the root directory of this software component.
31   * If no LICENSE file comes with this software, it is provided AS-IS.
32   *
33   ******************************************************************************
34   */
35 
36 /** @addtogroup CMSIS
37   * @{
38   */
39 
40 /** @addtogroup stm32mp1xx_system
41   * @{
42   */
43 
44 /** @addtogroup STM32MP1xx_System_Private_Includes
45   * @{
46   */
47 
48 #include "stm32mp1xx.h"
49 
50 /**
51   * @}
52   */
53 
54 /** @addtogroup STM32MP1xx_System_Private_TypesDefinitions
55   * @{
56   */
57 
58 
59 /**
60   * @}
61   */
62 
63 /** @addtogroup STM32MP1xx_System_Private_Defines
64   * @{
65   */
66 
67 
68 /************************* Miscellaneous Configuration ************************/
69 /*!< Uncomment the following line if you need to use external SRAM mounted
70      on EVAL board as data memory  */
71 /* #define DATA_IN_ExtSRAM */
72 
73 /*!< Uncomment the following line if you need to relocate your vector Table in
74      Internal SRAM. */
75 /* #define VECT_TAB_SRAM */
76 #define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.
77                                    This value must be a multiple of 0x400. */
78 /******************************************************************************/
79 
80 /**
81   * @}
82   */
83 
84 /** @addtogroup STM32MP1xx_System_Private_Macros
85   * @{
86   */
87 
88 /**
89   * @}
90   */
91 
92 /** @addtogroup STM32MP1xx_System_Private_Variables
93   * @{
94   */
95   /* This variable is updated in three ways:
96       1) by calling CMSIS function SystemCoreClockUpdate()
97       2) each time HAL_RCC_ClockConfig() is called to configure the system clock
98          frequency
99          Note: If you use this function to configure the system clock;
100                then there is no need to call the first functions listed above,
101                since SystemCoreClock variable is updated automatically.
102   */
103   uint32_t SystemCoreClock = HSI_VALUE;
104 /**
105   * @}
106   */
107 
108 /** @addtogroup STM32MP1xx_System_Private_FunctionPrototypes
109   * @{
110   */
111 
112 #if defined (DATA_IN_ExtSRAM)
113   static void SystemInit_ExtMemCtl(void);
114 #endif /* DATA_IN_ExtSRAM */
115 
116 /**
117   * @}
118   */
119 
120 /** @addtogroup STM32MP1xx_System_Private_Functions
121   * @{
122   */
123 
124   /**
125   * @brief  Setup the microcontroller system
126   *         Initialize the FPU setting, vector table location and External memory
127   *         configuration.
128   * @param  None
129   * @retval None
130   */
SystemInit(void)131 void SystemInit (void)
132 {
133   /* FPU settings ------------------------------------------------------------*/
134 #if defined (CORE_CM4)
135   #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
136    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
137   #endif
138 
139   /* Configure the Vector Table location add offset address ------------------*/
140 #if defined (VECT_TAB_SRAM)
141   SCB->VTOR = MCU_AHB_SRAM | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
142 #endif
143   /* Disable all interrupts and events */
144   CLEAR_REG(EXTI_C2->IMR1);
145   CLEAR_REG(EXTI_C2->IMR2);
146   CLEAR_REG(EXTI_C2->IMR3);
147   CLEAR_REG(EXTI_C2->EMR1);
148   CLEAR_REG(EXTI_C2->EMR2);
149   CLEAR_REG(EXTI_C2->EMR3);
150 #else
151 #error Please #define CORE_CM4
152 #endif
153 }
154 
155 /**
156    * @brief Update SystemCoreClock variable according to Clock Register Values.
157   *         The SystemCoreClock variable contains the core clock frequency (Hz),
158   *         it can be used by the user application to setup the SysTick timer or
159   *         configure other parameters.
160   *
161   * @note   Each time the core clock changes, this function must be called to
162   *         update SystemCoreClock variable value. Otherwise, any configuration
163   *         based on this variable will be incorrect.
164   *
165   * @note   - The system frequency computed by this function is not the real
166   *           frequency in the chip. It is calculated based on the predefined
167   *           constant and the selected clock source:
168   *
169   *           - If SYSCLK source is HSI, SystemCoreClock will contain the
170   *             HSI_VALUE(*)
171   *
172   *           - If SYSCLK source is HSE, SystemCoreClock will contain the
173   *             HSE_VALUE(**)
174   *
175   *           - If SYSCLK source is CSI, SystemCoreClock will contain the
176   *             CSI_VALUE(***)
177   *
178   *           - If SYSCLK source is PLL3_P, SystemCoreClock will contain the
179   *             HSI_VALUE(*) or the HSE_VALUE(*) or the CSI_VALUE(***)
180   *             multiplied/divided by the PLL3 factors.
181   *
182   *         (*) HSI_VALUE is a constant defined in stm32mp1xx_hal_conf.h file
183   *             (default value 64 MHz) but the real value may vary depending
184   *             on the variations in voltage and temperature.
185   *
186   *         (**) HSE_VALUE is a constant defined in stm32mp1xx_hal_conf.h file
187   *              (default value 24 MHz), user has to ensure that HSE_VALUE is
188   *              same as the real frequency of the crystal used. Otherwise, this
189   *              function may have wrong result.
190   *
191   *         (***) CSI_VALUE is a constant defined in stm32mp1xx_hal_conf.h file
192   *              (default value 4 MHz)but the real value may vary depending
193   *              on the variations in voltage and temperature.
194   *
195   *         - The result of this function could be not correct when using
196   *           fractional value for HSE crystal.
197   *
198   * @param  None
199   * @retval None
200   */
SystemCoreClockUpdate(void)201 void SystemCoreClockUpdate (void)
202 {
203   uint32_t   pllsource, pll3m, pll3fracen;
204   float fracn1, pll3vco;
205 
206   switch (RCC->MSSCKSELR & RCC_MSSCKSELR_MCUSSRC)
207   {
208   case 0x00:  /* HSI used as system clock source */
209     SystemCoreClock = (HSI_VALUE >> (RCC->HSICFGR & RCC_HSICFGR_HSIDIV));
210     break;
211 
212   case 0x01:  /* HSE used as system clock source */
213     SystemCoreClock = HSE_VALUE;
214     break;
215 
216   case 0x02:  /* CSI used as system clock source */
217     SystemCoreClock = CSI_VALUE;
218     break;
219 
220   case 0x03:  /* PLL3_P used as system clock source */
221     pllsource = (RCC->RCK3SELR & RCC_RCK3SELR_PLL3SRC);
222     pll3m = ((RCC->PLL3CFGR1 & RCC_PLL3CFGR1_DIVM3) >> RCC_PLL3CFGR1_DIVM3_Pos) + 1U;
223     pll3fracen = (RCC->PLL3FRACR & RCC_PLL3FRACR_FRACLE) >> 16U;
224     fracn1 = (float)(pll3fracen * ((RCC->PLL3FRACR & RCC_PLL3FRACR_FRACV) >> 3U));
225     pll3vco = (float)((float)((RCC->PLL3CFGR1 & RCC_PLL3CFGR1_DIVN) + 1U) + (fracn1 / (float) 0x1FFF));
226 
227     if (pll3m != 0U)
228     {
229       switch (pllsource)
230       {
231         case 0x00:  /* HSI used as PLL clock source */
232           pll3vco *= (float)((HSI_VALUE >> (RCC->HSICFGR & RCC_HSICFGR_HSIDIV)) / pll3m);
233           break;
234 
235         case 0x01:  /* HSE used as PLL clock source */
236           pll3vco *= (float)(HSE_VALUE / pll3m);
237           break;
238 
239         case 0x02:  /* CSI used as PLL clock source */
240           pll3vco *= (float)(CSI_VALUE / pll3m);
241           break;
242 
243         case 0x03:  /* No clock source for PLL */
244           pll3vco = 0;
245           break;
246        }
247       SystemCoreClock = (uint32_t)(pll3vco/ ((float)((RCC->PLL3CFGR2 & RCC_PLL3CFGR2_DIVP) + 1U)));
248     }
249     else
250     {
251       SystemCoreClock = 0U;
252     }
253     break;
254   }
255 
256   /* Compute mcu_ck */
257   SystemCoreClock = SystemCoreClock >> (RCC->MCUDIVR & RCC_MCUDIVR_MCUDIV);
258 }
259 
260 
261 #ifdef DATA_IN_ExtSRAM
262 /**
263   * @brief  Setup the external memory controller.
264   *         Called in startup_stm32mp15xx.s before jump to main.
265   *         This function configures the external SRAM mounted on Eval boards
266   *         This SRAM will be used as program data memory (including heap and stack).
267   * @param  None
268   * @retval None
269   */
SystemInit_ExtMemCtl(void)270 void SystemInit_ExtMemCtl(void)
271 {
272 
273 }
274 #endif /* DATA_IN_ExtSRAM */
275 
276 /**
277   * @}
278   */
279 
280 /**
281   * @}
282   */
283 
284 /**
285   * @}
286   */
287