Skip to content

Commit b654af2

Browse files
committed
STM32L4 : json clock source configuration
- default value is the same as before patch - system_stm32l4xx.c file is copied to family level with all other ST cube files - specific clock configuration is now in a new file: system_clock.c (target level) - nvic_addr.h file is now in TARGET_STM level
1 parent 912c0de commit b654af2

File tree

13 files changed

+1887
-2686
lines changed

13 files changed

+1887
-2686
lines changed

targets/TARGET_STM/TARGET_STM32L4/TARGET_STM32L432xC/TARGET_NUCLEO_L432KC/system_clock.c

Lines changed: 374 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 361 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,361 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2006-2017 ARM Limited
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/**
18+
* This file configures the system clock as follows:
19+
*-----------------------------------------------------------------------------
20+
* System clock source | 1- USE_PLL_HSE_EXTC (external 8 MHz clock)
21+
* | 2- USE_PLL_HSE_XTAL (external 8 MHz xtal)
22+
* | 3- USE_PLL_HSI (internal 16 MHz)
23+
* | 4- USE_PLL_MSI (internal 100kHz to 48 MHz)
24+
*-----------------------------------------------------------------------------
25+
* SYSCLK(MHz) | 80
26+
* AHBCLK (MHz) | 80
27+
* APB1CLK (MHz) | 80
28+
* APB2CLK (MHz) | 80
29+
* USB capable | YES
30+
*-----------------------------------------------------------------------------
31+
**/
32+
33+
#include "stm32l4xx.h"
34+
#include "nvic_addr.h"
35+
#include "mbed_assert.h"
36+
37+
/*!< Uncomment the following line if you need to relocate your vector Table in
38+
Internal SRAM. */
39+
/* #define VECT_TAB_SRAM */
40+
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
41+
This value must be a multiple of 0x200. */
42+
43+
44+
// clock source is selected with CLOCK_SOURCE in json config
45+
#define USE_PLL_HSE_EXTC 0x8 // Use external clock (ST Link MCO - not enabled by default)
46+
#define USE_PLL_HSE_XTAL 0x4 // Use external xtal (X3 on board - not provided by default)
47+
#define USE_PLL_HSI 0x2 // Use HSI internal clock
48+
#define USE_PLL_MSI 0x1 // Use MSI internal clock
49+
50+
#define DEBUG_MCO (0) // Output the MCO on PA8 for debugging (0=OFF, 1=SYSCLK, 2=HSE, 3=HSI, 4=MSI)
51+
52+
#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) )
53+
uint8_t SetSysClock_PLL_HSE(uint8_t bypass);
54+
#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */
55+
56+
#if ((CLOCK_SOURCE) & USE_PLL_HSI)
57+
uint8_t SetSysClock_PLL_HSI(void);
58+
#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */
59+
60+
#if ((CLOCK_SOURCE) & USE_PLL_MSI)
61+
uint8_t SetSysClock_PLL_MSI(void);
62+
#endif /* ((CLOCK_SOURCE) & USE_PLL_MSI) */
63+
64+
65+
/**
66+
* @brief Setup the microcontroller system.
67+
* @param None
68+
* @retval None
69+
*/
70+
71+
void SystemInit(void)
72+
{
73+
/* FPU settings ------------------------------------------------------------*/
74+
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
75+
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
76+
#endif
77+
/* Reset the RCC clock configuration to the default reset state ------------*/
78+
/* Set MSION bit */
79+
RCC->CR |= RCC_CR_MSION;
80+
81+
/* Reset CFGR register */
82+
RCC->CFGR = 0x00000000;
83+
84+
/* Reset HSEON, CSSON , HSION, and PLLON bits */
85+
RCC->CR &= (uint32_t)0xEAF6FFFF;
86+
87+
/* Reset PLLCFGR register */
88+
RCC->PLLCFGR = 0x00001000;
89+
90+
/* Reset HSEBYP bit */
91+
RCC->CR &= (uint32_t)0xFFFBFFFF;
92+
93+
/* Disable all interrupts */
94+
RCC->CIER = 0x00000000;
95+
96+
/* Configure the Vector Table location add offset address ------------------*/
97+
#ifdef VECT_TAB_SRAM
98+
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
99+
#else
100+
SCB->VTOR = NVIC_FLASH_VECTOR_ADDRESS; /* Vector Table Relocation in Internal FLASH */
101+
#endif
102+
103+
}
104+
105+
106+
/**
107+
* @brief Configures the System clock source, PLL Multiplier and Divider factors,
108+
* AHB/APBx prescalers and Flash settings
109+
* @note This function should be called only once the RCC clock configuration
110+
* is reset to the default reset state (done in SystemInit() function).
111+
* @param None
112+
* @retval None
113+
*/
114+
115+
void SetSysClock(void)
116+
{
117+
#if ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC)
118+
/* 1- Try to start with HSE and external clock */
119+
if (SetSysClock_PLL_HSE(1) == 0)
120+
#endif
121+
{
122+
#if ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL)
123+
/* 2- If fail try to start with HSE and external xtal */
124+
if (SetSysClock_PLL_HSE(0) == 0)
125+
#endif
126+
{
127+
#if ((CLOCK_SOURCE) & USE_PLL_HSI)
128+
/* 3- If fail start with HSI clock */
129+
if (SetSysClock_PLL_HSI()==0)
130+
#endif
131+
{
132+
#if ((CLOCK_SOURCE) & USE_PLL_MSI)
133+
/* 4- If fail start with MSI clock */
134+
if (SetSysClock_PLL_MSI() == 0)
135+
#endif
136+
{
137+
while(1) {
138+
MBED_ASSERT(1);
139+
}
140+
}
141+
}
142+
}
143+
}
144+
145+
// Output clock on MCO1 pin(PA8) for debugging purpose
146+
#if DEBUG_MCO == 1
147+
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
148+
#endif
149+
}
150+
151+
#if ( ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) )
152+
/******************************************************************************/
153+
/* PLL (clocked by HSE) used as System clock source */
154+
/******************************************************************************/
155+
uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
156+
{
157+
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
158+
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
159+
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit = {0};
160+
161+
// Used to gain time after DeepSleep in case HSI is used
162+
if (__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY) != RESET) {
163+
return 0;
164+
}
165+
166+
// Select MSI as system clock source to allow modification of the PLL configuration
167+
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
168+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
169+
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
170+
171+
// Enable HSE oscillator and activate PLL with HSE as source
172+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE | RCC_OSCILLATORTYPE_HSI;
173+
if (bypass == 0) {
174+
RCC_OscInitStruct.HSEState = RCC_HSE_ON; // External 8 MHz xtal on OSC_IN/OSC_OUT
175+
} else {
176+
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; // External 8 MHz clock on OSC_IN
177+
}
178+
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
179+
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; // 8 MHz
180+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
181+
RCC_OscInitStruct.PLL.PLLM = 1; // VCO input clock = 8 MHz (8 MHz / 1)
182+
RCC_OscInitStruct.PLL.PLLN = 20; // VCO output clock = 160 MHz (8 MHz * 20)
183+
RCC_OscInitStruct.PLL.PLLP = 7; // PLLSAI3 clock = 22 MHz (160 MHz / 7)
184+
RCC_OscInitStruct.PLL.PLLQ = 2;
185+
RCC_OscInitStruct.PLL.PLLR = 2; // PLL clock = 80 MHz (160 MHz / 2)
186+
187+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
188+
return 0; // FAIL
189+
}
190+
191+
// Select PLL clock as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
192+
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
193+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 80 MHz or 48 MHz
194+
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 80 MHz or 48 MHz
195+
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 80 MHz or 48 MHz
196+
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 80 MHz or 48 MHz
197+
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
198+
return 0; // FAIL
199+
}
200+
201+
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
202+
RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
203+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
204+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
205+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1N = 12;
206+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
207+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
208+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
209+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK;
210+
if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) {
211+
return 0; // FAIL
212+
}
213+
214+
// Disable MSI Oscillator
215+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
216+
RCC_OscInitStruct.MSIState = RCC_MSI_OFF;
217+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // No PLL update
218+
HAL_RCC_OscConfig(&RCC_OscInitStruct);
219+
220+
// Output clock on MCO1 pin(PA8) for debugging purpose
221+
#if DEBUG_MCO == 2
222+
if (bypass == 0)
223+
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_2); // 4 MHz
224+
else
225+
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSE, RCC_MCODIV_1); // 8 MHz
226+
#endif
227+
228+
return 1; // OK
229+
}
230+
#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */
231+
232+
#if ((CLOCK_SOURCE) & USE_PLL_HSI)
233+
/******************************************************************************/
234+
/* PLL (clocked by HSI) used as System clock source */
235+
/******************************************************************************/
236+
uint8_t SetSysClock_PLL_HSI(void)
237+
{
238+
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
239+
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
240+
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit = {0};
241+
242+
// Select MSI as system clock source to allow modification of the PLL configuration
243+
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK;
244+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
245+
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);
246+
247+
// Enable HSI oscillator and activate PLL with HSI as source
248+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE;
249+
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
250+
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
251+
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
252+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
253+
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; // 16 MHz
254+
RCC_OscInitStruct.PLL.PLLM = 2; // VCO input clock = 8 MHz (16 MHz / 2)
255+
RCC_OscInitStruct.PLL.PLLN = 20; // VCO output clock = 160 MHz (8 MHz * 20)
256+
RCC_OscInitStruct.PLL.PLLP = 7; // PLLSAI3 clock = 22 MHz (160 MHz / 7)
257+
RCC_OscInitStruct.PLL.PLLQ = 2;
258+
RCC_OscInitStruct.PLL.PLLR = 2; // PLL clock = 80 MHz (160 MHz / 2)
259+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
260+
return 0; // FAIL
261+
}
262+
263+
// Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
264+
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
265+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; // 80 MHz
266+
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; // 80 MHz
267+
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; // 80 MHz
268+
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; // 80 MHz
269+
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
270+
return 0; // FAIL
271+
}
272+
273+
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
274+
RCC_PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
275+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSI;
276+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1M = 2;
277+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1N = 12;
278+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
279+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
280+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
281+
RCC_PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK;
282+
if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit) != HAL_OK) {
283+
return 0; // FAIL
284+
}
285+
286+
// Disable MSI Oscillator
287+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
288+
RCC_OscInitStruct.MSIState = RCC_MSI_OFF;
289+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // No PLL update
290+
HAL_RCC_OscConfig(&RCC_OscInitStruct);
291+
292+
// Output clock on MCO1 pin(PA8) for debugging purpose
293+
#if DEBUG_MCO == 3
294+
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1); // 16 MHz
295+
#endif
296+
297+
return 1; // OK
298+
}
299+
#endif /* ((CLOCK_SOURCE) & USE_PLL_HSI) */
300+
301+
#if ((CLOCK_SOURCE) & USE_PLL_MSI)
302+
/******************************************************************************/
303+
/* PLL (clocked by MSI) used as System clock source */
304+
/******************************************************************************/
305+
uint8_t SetSysClock_PLL_MSI(void)
306+
{
307+
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
308+
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
309+
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
310+
311+
// Enable LSE Oscillator to automatically calibrate the MSI clock
312+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;
313+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // No PLL update
314+
RCC_OscInitStruct.LSEState = RCC_LSE_ON; // External 32.768 kHz clock on OSC_IN/OSC_OUT
315+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) {
316+
RCC->CR |= RCC_CR_MSIPLLEN; // Enable MSI PLL-mode
317+
}
318+
319+
HAL_RCCEx_DisableLSECSS();
320+
/* Enable MSI Oscillator and activate PLL with MSI as source */
321+
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI | RCC_OSCILLATORTYPE_HSI | RCC_OSCILLATORTYPE_HSE;
322+
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
323+
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
324+
RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
325+
326+
RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
327+
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_11; /* 48 MHz */
328+
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
329+
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
330+
RCC_OscInitStruct.PLL.PLLM = 6; /* 8 MHz */
331+
RCC_OscInitStruct.PLL.PLLN = 40; /* 320 MHz */
332+
RCC_OscInitStruct.PLL.PLLP = 7; /* 45 MHz */
333+
RCC_OscInitStruct.PLL.PLLQ = 4; /* 80 MHz */
334+
RCC_OscInitStruct.PLL.PLLR = 4; /* 80 MHz */
335+
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
336+
return 0; // FAIL
337+
}
338+
/* Enable MSI Auto-calibration through LSE */
339+
HAL_RCCEx_EnableMSIPLLMode();
340+
/* Select MSI output as USB clock source */
341+
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
342+
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; /* 48 MHz */
343+
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
344+
// Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
345+
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
346+
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; /* 80 MHz */
347+
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; /* 80 MHz */
348+
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; /* 80 MHz */
349+
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; /* 80 MHz */
350+
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
351+
return 0; // FAIL
352+
}
353+
354+
// Output clock on MCO1 pin(PA8) for debugging purpose
355+
#if DEBUG_MCO == 4
356+
HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_MSI, RCC_MCODIV_2); // 2 MHz
357+
#endif
358+
359+
return 1; // OK
360+
}
361+
#endif /* ((CLOCK_SOURCE) & USE_PLL_MSI) */

0 commit comments

Comments
 (0)