1 /*!
2 * @file system_apm32f4xx.c
3 *
4 * @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File
5 *
6 * @version V1.0.2
7 *
8 * @date 2022-06-23
9 *
10 * @attention
11 *
12 * Copyright (C) 2021-2022 Geehy Semiconductor
13 *
14 * You may not use this file except in compliance with the
15 * GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16 *
17 * The program is only for reference, which is distributed in the hope
18 * that it will be usefull and instructional for customers to develop
19 * their software. Unless required by applicable law or agreed to in
20 * writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21 * ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23 * and limitations under the License.
24 */
25
26 #include "apm32f4xx.h"
27 #include "system_apm32f4xx.h"
28
29 /** @addtogroup CMSIS
30 @{
31 */
32
33 /** @addtogroup APM32F4xx_System
34 * @brief APM32F4xx system configuration
35 @{
36 */
37
38 /** @defgroup System_Macros
39 @{
40 */
41
42 /* Uncomment the following line if you need to use external SRAM as data memory */
43 /* #define DATA_IN_ExtSRAM */
44
45 /* Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */
46 /* #define VECT_TAB_SRAM */
47
48 /* Vector Table base offset field. This value must be a multiple of 0x200. */
49 #define VECT_TAB_OFFSET 0x00
50
51 /* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_B) * PLL_A */
52 #define PLL_B 8
53
54 /* USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLL_D */
55 #define PLL_D 7
56
57 #define PLL_A 336
58 /* SYSCLK = PLL_VCO / PLL_C */
59 #define PLL_C 2
60
61 /**@} end of group System_Macros*/
62
63 /** @defgroup System_Variables
64 @{
65 */
66
67 /**
68 * @brief APM32F4xx_System_Private_Variables
69 */
70
71 uint32_t SystemCoreClock = 168000000;
72
73 __I uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
74
75 /**@} end of group System_Variables */
76
77 /** @defgroup System_Functions
78 @{
79 */
80
81 /**
82 * @brief APM32F4xx_System_Private_FunctionPrototypes
83 */
84
85 static void SystemClockConfig(void);
86
87 #if defined(DATA_IN_ExtSRAM)
88 static void SystemInit_ExtSRAM(void);
89 #endif /* DATA_IN_ExtSRAM */
90
91 /*!
92 * @brief Setup the microcontroller system
93 *
94 * @param None
95 *
96 * @retval None
97 */
SystemInit(void)98 void SystemInit(void)
99 {
100 /* FPU settings */
101 #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
102 SCB->CPACR |= ((3UL << 10 * 2) | (3UL << 11 * 2)); //!< set CP10 and CP11 Full Access
103 #endif
104 /* Reset the RCM clock configuration to the default reset state */
105 /* Set HSIEN bit */
106 RCM->CTRL_B.HSIEN = BIT_SET;
107
108 /* Reset CFG register */
109 RCM->CFG = 0x00000000;
110
111 /* Reset HSEEN, CSSEN and PLL1EN bits */
112 RCM->CTRL &= (uint32_t)0xFEF6FFFF;
113
114 /* Reset PLL1CFG register */
115 RCM->PLL1CFG = 0x24003010;
116
117 /* Reset HSEBCFG bit */
118 RCM->CTRL &= (uint32_t)0xFFFBFFFF;
119
120 /* Disable all interrupts */
121 RCM->INT = 0x00000000;
122
123 #if defined(DATA_IN_ExtSRAM)
124 SystemInit_ExtSRAM();
125 #endif /* DATA_IN_ExtSRAM */
126
127 SystemClockConfig();
128
129 /* Configure the Vector Table location add offset address */
130 #ifdef VECT_TAB_SRAM
131 SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
132 #else
133 SCB->VTOR = FMC_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
134 #endif
135 }
136
137 /*!
138 * @brief Update SystemCoreClock variable according to Clock Register Values
139 * The SystemCoreClock variable contains the core clock (HCLK)
140 *
141 * @param None
142 *
143 * @retval None
144 */
SystemCoreClockUpdate(void)145 void SystemCoreClockUpdate(void)
146 {
147 uint32_t sysClock, pllvco, pllc, pllClock, pllb;
148
149 /* Get SYSCLK source */
150 sysClock = RCM->CFG_B.SCLKSWSTS;
151
152 switch (sysClock)
153 {
154 case 0:
155 SystemCoreClock = HSI_VALUE;
156 break;
157
158 case 1:
159 SystemCoreClock = HSE_VALUE;
160 break;
161
162 case 2:
163 pllClock = RCM->PLL1CFG_B.PLL1CLKS;
164 pllb = RCM->PLL1CFG_B.PLLB;
165
166 if (pllClock == 0)
167 {
168 /* HSI used as PLL clock source */
169 pllvco = (HSI_VALUE / pllb) * (RCM->PLL1CFG_B.PLL1A); //!< PLL_VCO = (HSI_VALUE / PLL_B) * PLL_A */
170 }
171 else
172 {
173 /* HSE used as PLL clock source */
174 pllvco = (HSE_VALUE / pllb) * (RCM->PLL1CFG_B.PLL1A); //!< PLL_VCO = (HSE_VALUE / PLL_B) * PLL_A */
175 }
176
177 pllc = ((RCM->PLL1CFG_B.PLL1C) + 1) * 2;
178 SystemCoreClock = pllvco / pllc;
179 break;
180
181 default:
182 SystemCoreClock = HSI_VALUE;
183 break;
184 }
185
186 /* Compute HCLK frequency */
187 /* Get HCLK prescaler */
188 sysClock = AHBPrescTable[(RCM->CFG_B.AHBPSC)];
189 /* HCLK frequency */
190 SystemCoreClock >>= sysClock;
191 }
192
193 /*!
194 * @brief Configures the System clock source, PLL Multiplier and Divider factors,
195 * AHB/APBx prescalers and Flash settings
196 *
197 * @param None
198 *
199 * @retval None
200 */
SystemClockConfig(void)201 static void SystemClockConfig(void)
202 {
203 __IO uint32_t i;
204
205 RCM->CTRL_B.HSEEN = BIT_SET;
206
207 for (i = 0; i < HSE_STARTUP_TIMEOUT; i++)
208 {
209 if (RCM->CTRL_B.HSERDYFLG)
210 {
211 break;
212 }
213 }
214
215 if (RCM->CTRL_B.HSERDYFLG)
216 {
217 /* Select regulator voltage output Scale 1 mode */
218 RCM->APB1CLKEN_B.PMUEN = BIT_SET;
219 PMU->CTRL_B.VOSSEL = BIT_SET;
220
221 /* HCLK = SYSCLK / 1*/
222 RCM->CFG_B.AHBPSC = 0x0000;
223
224 /* PCLK2 = HCLK / 2*/
225 RCM->CFG_B.APB2PSC = 0x04;
226
227 /* PCLK1 = HCLK / 4*/
228 RCM->CFG_B.APB1PSC = 0x05;
229
230 /* Configure the main PLL */
231 RCM->PLL1CFG = PLL_B | (PLL_A << 6) | (((PLL_C >> 1) - 1) << 16) | (PLL_D << 24);
232 RCM->PLL1CFG_B.PLL1CLKS = 0x01;
233
234 /* Enable the main PLL */
235 RCM->CTRL_B.PLL1EN = BIT_SET;
236
237 /* Wait till the main PLL is ready */
238 while (RCM->CTRL_B.PLL1RDYFLG == 0)
239 {
240 }
241
242 /* Configure Flash prefetch, Instruction cache, Data cache and wait state */
243 FMC->ACCTRL = 0x05 | BIT8 | BIT9 | BIT10;
244
245 /* Select the main PLL as system clock source */
246 RCM->CFG_B.SCLKSEL = RESET;
247 RCM->CFG_B.SCLKSEL = 0x02;
248
249 /* Wait till the main PLL is used as system clock source */
250 while ((RCM->CFG_B.SCLKSWSTS) != 0x02)
251 {
252 }
253 }
254 else
255 {
256 /* If HSE fails to start-up, the application will have wrong clock configuration. */
257 }
258 }
259
260 #if defined (DATA_IN_ExtSRAM)
261
262 /*!
263 * @brief Setup the external memory controller. Called in startup_apm32f4xx.s before jump to main.
264 * This function configures the external SRAM
265 * This SRAM will be used as program data memory (including heap and stack).
266 *
267 * @param None
268 *
269 * @retval None
270 */
SystemInit_ExtSRAM(void)271 void SystemInit_ExtSRAM(void)
272 {
273 /* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
274 RCM->AHB1CLKEN |= 0x00000078;
275
276 /* Connect PDx pins to FMC Alternate function */
277 GPIOD->ALFL = 0x00cc00cc;
278 GPIOD->ALFH = 0xcccccccc;
279 /* Configure PDx pins in Alternate function mode */
280 GPIOD->MODE = 0xaaaa0a0a;
281 /* Configure PDx pins speed to 100 MHz */
282 GPIOD->OSSEL = 0xffff0f0f;
283 /* Configure PDx pins Output type to push-pull */
284 GPIOD->OMODE = 0x00000000;
285 /* No pull-up, pull-down for PDx pins */
286 GPIOD->PUPD = 0x00000000;
287
288 /* Connect PEx pins to FMC Alternate function */
289 GPIOE->ALFL = 0xcccccccc;
290 GPIOE->ALFH = 0xcccccccc;
291 /* Configure PEx pins in Alternate function mode */
292 GPIOE->MODE = 0xaaaaaaaa;
293 /* Configure PEx pins speed to 100 MHz */
294 GPIOE->OSSEL = 0xffffffff;
295 /* Configure PEx pins Output type to push-pull */
296 GPIOE->OMODE = 0x00000000;
297 /* No pull-up, pull-down for PEx pins */
298 GPIOE->PUPD = 0x00000000;
299
300 /* Connect PFx pins to FMC Alternate function */
301 GPIOF->ALFL = 0x00cccccc;
302 GPIOF->ALFH = 0xcccc0000;
303 /* Configure PFx pins in Alternate function mode */
304 GPIOF->MODE = 0xaa000aaa;
305 /* Configure PFx pins speed to 100 MHz */
306 GPIOF->OSSEL = 0xff000fff;
307 /* Configure PFx pins Output type to push-pull */
308 GPIOF->OMODE = 0x00000000;
309 /* No pull-up, pull-down for PFx pins */
310 GPIOF->PUPD = 0x00000000;
311
312 /* Connect PGx pins to FMC Alternate function */
313 GPIOG->ALFL = 0x00cccccc;
314 GPIOG->ALFH = 0x000000c0;
315 /* Configure PGx pins in Alternate function mode */
316 GPIOG->MODE = 0x00080aaa;
317 /* Configure PGx pins speed to 100 MHz */
318 GPIOG->OSSEL = 0x000c0fff;
319 /* Configure PGx pins Output type to push-pull */
320 GPIOG->OMODE = 0x00000000;
321 /* No pull-up, pull-down for PGx pins */
322 GPIOG->PUPD = 0x00000000;
323
324 /* FMC Configuration */
325 /* Enable the FMC/SMC interface clock */
326 RCM->AHB3CLKEN |= 0x00000001;
327
328 /* Configure and enable Bank1_SRAM2 */
329 SMC_Bank1->CSCTRL2 = 0x00001011;
330 SMC_Bank1->CSTIM2 = 0x00000201;
331 SMC_Bank1E->WRTTIM2 = 0x0fffffff;
332 }
333 #endif /* DATA_IN_ExtSRAM */
334
335 /**@} end of group System_Functions */
336 /**@} end of group APM32F4xx_System */
337 /**@} end of group CMSIS */
338