13
13
* See the License for the specific language governing permissions and
14
14
* limitations under the License.
15
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) | 64
26
+ * AHBCLK (MHz) | 64
27
+ * APB1CLK (MHz) | 64
28
+ * APB2CLK (MHz) | 64
29
+ * USB capable | NO // todo
30
+ *-----------------------------------------------------------------------------
31
+ **/
32
+
16
33
#include "stm32wbxx.h"
17
- #include "mbed_assert .h"
34
+ #include "mbed_error .h"
18
35
19
36
// Clock source is selected with CLOCK_SOURCE in json config
20
37
#define USE_PLL_HSE_EXTC 0x8 // Use external clock (not available)
21
38
#define USE_PLL_HSE_XTAL 0x4 // Use external 32 MHz xtal (X1 on board + need HW patch)
22
39
#define USE_PLL_HSI 0x2 // Use HSI 16MHz internal clock
23
- #define USE_PLL_MSI 0x1 // Use MSI 4MHz internal clock (default)
40
+ #define USE_PLL_MSI 0x1 // Use MSI internal clock
24
41
25
42
#define DEBUG_MCO (0) // Output the MCO on PA8 for debugging (0=OFF, 1=SYSCLK, 2=HSE, 3=HSI, 4=MSI)
26
43
27
- #if (((CLOCK_SOURCE ) & USE_PLL_HSE_XTAL ) || ((CLOCK_SOURCE ) & USE_PLL_HSE_EXTC ))
44
+ #if ( ((CLOCK_SOURCE ) & USE_PLL_HSE_XTAL ) || ((CLOCK_SOURCE ) & USE_PLL_HSE_EXTC ) )
28
45
uint8_t SetSysClock_PLL_HSE (uint8_t bypass );
29
46
#endif /* ((CLOCK_SOURCE) & USE_PLL_HSE_XTAL) || ((CLOCK_SOURCE) & USE_PLL_HSE_EXTC) */
30
47
@@ -45,6 +62,7 @@ void Configure_RF_Clock_Sources(void);
45
62
* @param None
46
63
* @retval None
47
64
*/
65
+
48
66
void SetSysClock (void )
49
67
{
50
68
#if ((CLOCK_SOURCE ) & USE_PLL_HSE_EXTC )
@@ -59,16 +77,16 @@ void SetSysClock(void)
59
77
{
60
78
#if ((CLOCK_SOURCE ) & USE_PLL_HSI )
61
79
/* 3- If fail start with HSI clock */
62
- if (SetSysClock_PLL_HSI ()== 0 )
80
+ if (SetSysClock_PLL_HSI () == 0 )
63
81
#endif
64
82
{
65
83
#if ((CLOCK_SOURCE ) & USE_PLL_MSI )
66
84
/* 4- If fail start with MSI clock */
67
85
if (SetSysClock_PLL_MSI () == 0 )
68
86
#endif
69
87
{
70
- while ( 1 ) {
71
- MBED_ASSERT ( 1 );
88
+ {
89
+ error ( "SetSysClock failed\n" );
72
90
}
73
91
}
74
92
}
@@ -89,24 +107,41 @@ void SetSysClock(void)
89
107
/******************************************************************************/
90
108
uint8_t SetSysClock_PLL_HSE (uint8_t bypass )
91
109
{
92
- RCC_OscInitTypeDef RCC_OscInitStruct = {0 };
110
+ // System is fully clocked @ 32MHz from HSE
111
+ //return 1;
112
+
93
113
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0 };
114
+ RCC_OscInitTypeDef RCC_OscInitStruct = {0 };
94
115
116
+ #if MBED_CONF_TARGET_LSE_AVAILABLE
117
+ // Enable LSE Oscillator to automatically calibrate the MSI clock
118
+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_LSE ;
119
+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ; // No PLL update
120
+ RCC_OscInitStruct .LSEState = RCC_LSE_ON ; // External 32.768 kHz clock on OSC_IN/OSC_OUT
121
+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
122
+ return 0 ; // FAIL
123
+ }
124
+
125
+ /* Enable the CSS interrupt in case LSE signal is corrupted or not present */
126
+ HAL_RCCEx_DisableLSECSS ();
127
+ #endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
128
+
129
+
130
+ // HSE has been turned on during system init
95
131
// Enable HSE oscillator and activate PLL with HSE as source
96
- RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_HSE ;
132
+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_HSE ;
97
133
if (bypass == 0 ) {
98
- RCC_OscInitStruct .HSEState = RCC_HSE_ON ; // External 32 MHz xtal on OSC_IN/OSC_OUT
134
+ RCC_OscInitStruct .HSEState = RCC_HSE_ON ; // External 8 MHz xtal on OSC_IN/OSC_OUT
99
135
} else {
100
- RCC_OscInitStruct .HSEState = RCC_HSE_BYPASS ; // External 32 MHz clock on OSC_IN
136
+ RCC_OscInitStruct .HSEState = RCC_HSE_BYPASS ; // External 32 MHz clock on OSC_IN
101
137
}
102
-
103
- RCC_OscInitStruct .PLL .PLLState = RCC_PLL_ON ;
104
- RCC_OscInitStruct .PLL .PLLSource = RCC_PLLSOURCE_HSE ;
105
- RCC_OscInitStruct .PLL .PLLM = RCC_PLLM_DIV2 ;
106
- RCC_OscInitStruct .PLL .PLLN = 16 ;
107
- RCC_OscInitStruct .PLL .PLLP = RCC_PLLP_DIV7 ;
108
- RCC_OscInitStruct .PLL .PLLQ = RCC_PLLQ_DIV4 ;
109
- RCC_OscInitStruct .PLL .PLLR = RCC_PLLR_DIV4 ;
138
+ RCC_OscInitStruct .PLL .PLLSource = RCC_PLLSOURCE_HSE ; // 32 MHz
139
+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_ON ;
140
+ RCC_OscInitStruct .PLL .PLLM = RCC_PLLM_DIV8 ; // 4 MHz
141
+ RCC_OscInitStruct .PLL .PLLN = 32 ; // 128 MHz
142
+ RCC_OscInitStruct .PLL .PLLR = RCC_PLLR_DIV2 ; // 64 MHz // RCC_SYSCLKSOURCE_PLLCLK
143
+ RCC_OscInitStruct .PLL .PLLP = RCC_PLLP_DIV5 ;
144
+ RCC_OscInitStruct .PLL .PLLQ = RCC_PLLQ_DIV4 ;
110
145
111
146
if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
112
147
return 0 ; // FAIL
@@ -125,12 +160,19 @@ uint8_t SetSysClock_PLL_HSE(uint8_t bypass)
125
160
return 0 ; // FAIL
126
161
}
127
162
163
+ // Disable MSI Oscillator
164
+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_MSI ;
165
+ RCC_OscInitStruct .MSIState = RCC_MSI_OFF ;
166
+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ; // No PLL update
167
+ HAL_RCC_OscConfig (& RCC_OscInitStruct );
168
+
128
169
// Output clock on MCO1 pin(PA8) for debugging purpose
129
170
#if DEBUG_MCO == 2
130
- if (bypass == 0 )
131
- HAL_RCC_MCOConfig (RCC_MCO1 , RCC_MCO1SOURCE_HSE , RCC_MCODIV_2 ); // xx MHz
132
- else
133
- HAL_RCC_MCOConfig (RCC_MCO1 , RCC_MCO1SOURCE_HSE , RCC_MCODIV_1 ); // xx MHz
171
+ if (bypass == 0 ) {
172
+ HAL_RCC_MCOConfig (RCC_MCO1 , RCC_MCO1SOURCE_HSE , RCC_MCODIV_4 ); // 8 MHz
173
+ } else {
174
+ HAL_RCC_MCOConfig (RCC_MCO1 , RCC_MCO1SOURCE_HSE , RCC_MCODIV_2 ); // 4 MHz
175
+ }
134
176
#endif
135
177
136
178
return 1 ;
@@ -152,12 +194,12 @@ uint8_t SetSysClock_PLL_HSI(void)
152
194
RCC_OscInitStruct .HSEState = RCC_HSE_OFF ;
153
195
RCC_OscInitStruct .HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT ;
154
196
RCC_OscInitStruct .PLL .PLLState = RCC_PLL_ON ;
155
- RCC_OscInitStruct .PLL .PLLSource = RCC_PLLSOURCE_HSI ;
156
- RCC_OscInitStruct .PLL .PLLM = RCC_PLLM_DIV2 ;
157
- RCC_OscInitStruct .PLL .PLLN = 16 ;
197
+ RCC_OscInitStruct .PLL .PLLSource = RCC_PLLSOURCE_HSI ; // 16 MHz
198
+ RCC_OscInitStruct .PLL .PLLM = RCC_PLLM_DIV2 ; // 8 MHz
199
+ RCC_OscInitStruct .PLL .PLLN = 16 ; // 128 MHz
158
200
RCC_OscInitStruct .PLL .PLLP = RCC_PLLP_DIV7 ;
159
201
RCC_OscInitStruct .PLL .PLLQ = RCC_PLLQ_DIV4 ;
160
- RCC_OscInitStruct .PLL .PLLR = RCC_PLLR_DIV2 ;
202
+ RCC_OscInitStruct .PLL .PLLR = RCC_PLLR_DIV2 ; // 64 MHz // RCC_SYSCLKSOURCE_PLLCLK
161
203
162
204
if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
163
205
return 0 ; // FAIL
@@ -171,7 +213,7 @@ uint8_t SetSysClock_PLL_HSI(void)
171
213
RCC_ClkInitStruct .AHBCLK4Divider = RCC_SYSCLK_DIV1 ; // 64 MHz
172
214
RCC_ClkInitStruct .APB1CLKDivider = RCC_HCLK_DIV1 ; // 64 MHz
173
215
RCC_ClkInitStruct .APB2CLKDivider = RCC_HCLK_DIV1 ; // 64 MHz
174
-
216
+
175
217
if (HAL_RCC_ClockConfig (& RCC_ClkInitStruct , FLASH_LATENCY_3 ) != HAL_OK ) {
176
218
return 0 ; // FAIL
177
219
}
@@ -193,24 +235,47 @@ uint8_t SetSysClock_PLL_MSI(void)
193
235
{
194
236
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0 };
195
237
RCC_OscInitTypeDef RCC_OscInitStruct = {0 };
238
+ // RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; // USB todo
239
+
240
+ #if MBED_CONF_TARGET_LSE_AVAILABLE
241
+ // Enable LSE Oscillator to automatically calibrate the MSI clock
242
+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_LSE ;
243
+ RCC_OscInitStruct .PLL .PLLState = RCC_PLL_NONE ; // No PLL update
244
+ RCC_OscInitStruct .LSEState = RCC_LSE_ON ; // External 32.768 kHz clock on OSC_IN/OSC_OUT
245
+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
246
+ return 0 ; // FAIL
247
+ }
248
+
249
+ /* Enable the CSS interrupt in case LSE signal is corrupted or not present */
250
+ HAL_RCCEx_DisableLSECSS ();
251
+ #endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
196
252
197
253
// Enable MSI Oscillator and activate PLL with MSI as source
198
254
RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_MSI ;
199
255
RCC_OscInitStruct .MSIState = RCC_MSI_ON ;
200
256
RCC_OscInitStruct .MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT ;
201
- RCC_OscInitStruct .MSIClockRange = RCC_MSIRANGE_6 ;
257
+ RCC_OscInitStruct .MSIClockRange = RCC_MSIRANGE_6 ; // 4 MHz
202
258
RCC_OscInitStruct .PLL .PLLState = RCC_PLL_ON ;
203
259
RCC_OscInitStruct .PLL .PLLSource = RCC_PLLSOURCE_MSI ;
204
- RCC_OscInitStruct .PLL .PLLM = RCC_PLLM_DIV1 ;
205
- RCC_OscInitStruct .PLL .PLLN = 32 ;
206
- RCC_OscInitStruct .PLL .PLLR = RCC_PLLR_DIV2 ;
260
+ RCC_OscInitStruct .PLL .PLLM = RCC_PLLM_DIV1 ; // 4 MHz
261
+ RCC_OscInitStruct .PLL .PLLN = 32 ; // 128 MHz
262
+ RCC_OscInitStruct .PLL .PLLR = RCC_PLLR_DIV2 ; // 64 MHz // RCC_SYSCLKSOURCE_PLLCLK
207
263
RCC_OscInitStruct .PLL .PLLP = RCC_PLLP_DIV5 ;
208
264
RCC_OscInitStruct .PLL .PLLQ = RCC_PLLQ_DIV4 ;
209
-
210
265
if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK ) {
211
266
return 0 ; // FAIL
212
267
}
213
268
269
+ #if MBED_CONF_TARGET_LSE_AVAILABLE
270
+ /* Enable MSI Auto-calibration through LSE */
271
+ HAL_RCCEx_EnableMSIPLLMode ();
272
+ #endif /* MBED_CONF_TARGET_LSE_AVAILABLE */
273
+
274
+ /* Select MSI output as USB clock source */
275
+ // PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
276
+ // PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_MSI; /* 48 MHz */
277
+ // HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
278
+
214
279
// Select PLL as system clock source and configure the clocks dividers
215
280
RCC_ClkInitStruct .ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_HCLK2 | RCC_CLOCKTYPE_HCLK4 | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 );
216
281
RCC_ClkInitStruct .SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK ; // 64 MHz
@@ -224,13 +289,6 @@ uint8_t SetSysClock_PLL_MSI(void)
224
289
return 0 ; // FAIL
225
290
}
226
291
227
- // Calibrate MSI
228
- LL_PWR_EnableBkUpAccess ();
229
- LL_RCC_ForceBackupDomainReset ();
230
- LL_RCC_ReleaseBackupDomainReset ();
231
- LL_RCC_LSE_Enable ();
232
- while (LL_RCC_LSE_IsReady () != 1 ) {}
233
- LL_RCC_MSI_EnablePLLMode ();
234
292
235
293
// Output clock on MCO1 pin(PA8) for debugging purpose
236
294
#if DEBUG_MCO == 4
@@ -243,11 +301,21 @@ uint8_t SetSysClock_PLL_MSI(void)
243
301
244
302
void Configure_RF_Clock_Sources (void )
245
303
{
304
+ // Reset backup domain
305
+ if ((LL_RCC_IsActiveFlag_PINRST ()) && (!LL_RCC_IsActiveFlag_SFTRST ())) {
306
+ // Write twice the value to flush the APB-AHB bridge
307
+ // This bit shall be written in the register before writing the next one
308
+ HAL_PWR_EnableBkUpAccess ();
309
+ HAL_PWR_EnableBkUpAccess ();
310
+ __HAL_RCC_BACKUPRESET_FORCE ();
311
+ __HAL_RCC_BACKUPRESET_RELEASE ();
312
+ }
313
+
246
314
/**
247
315
* Select LSE clock
248
316
*/
249
317
LL_RCC_LSE_Enable ();
250
- while (!LL_RCC_LSE_IsReady ());
318
+ while (!LL_RCC_LSE_IsReady ());
251
319
252
320
/**
253
321
* Select wakeup source of BLE RF
@@ -263,7 +331,7 @@ void Configure_RF_Clock_Sources(void)
263
331
* Set RNG on HSI48
264
332
*/
265
333
LL_RCC_HSI48_Enable ();
266
- while (!LL_RCC_HSI48_IsReady ());
334
+ while (!LL_RCC_HSI48_IsReady ());
267
335
LL_RCC_SetCLK48ClockSource (LL_RCC_CLK48_CLKSOURCE_HSI48 );
268
336
269
337
return ;
0 commit comments