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