2727 */
2828#include "cmsis.h"
2929#include "objects.h"
30+ #include "platform/mbed_error.h"
3031
3132int mbed_sdk_inited = 0 ;
3233extern void SetSysClock (void );
3334
35+ #if MBED_CONF_TARGET_LSE_AVAILABLE
36+
37+ #if defined(STM32F410Tx ) || defined(STM32F410Cx ) || defined(STM32F410Rx ) || defined(STM32F411xE ) || defined(STM32F446xx ) || defined(STM32F469xx ) || defined(STM32F479xx ) || defined(STM32F412Zx ) || \
38+ defined(STM32F412Vx ) || defined(STM32F412Rx ) || defined(STM32F412Cx ) || defined(STM32F413xx ) || defined(STM32F423xx )
39+ # if MBED_CONF_TARGET_LSE_DRIVE_LOAD_LEVEL
40+ # define LSE_DRIVE_LOAD_LEVEL MBED_CONF_TARGET_LSE_DRIVE_LOAD_LEVEL
41+ # else
42+ # define LSE_DRIVE_LOAD_LEVEL RCC_LSE_HIGHDRIVE_MODE
43+ # endif
44+ #else // defined(STM32F4xx)
45+ # if MBED_CONF_TARGET_LSE_DRIVE_LOAD_LEVEL
46+ # define LSE_DRIVE_LOAD_LEVEL MBED_CONF_TARGET_LSE_DRIVE_LOAD_LEVEL
47+ # else
48+ # define LSE_DRIVE_LOAD_LEVEL RCC_LSEDRIVE_MEDIUMHIGH
49+ # endif
50+ #endif
51+
52+ /**
53+ * @brief configure the LSE crystal driver load
54+ * This settings ist target hardware dependend and
55+ * depends on the crystal that is used for LSE clock.
56+ * For low power requirements, crystals with low load capacitors can be used and
57+ * driver setting is RCC_LSEDRIVE_LOW.
58+ * For higher stablity, crystals with higher load capacitys can be used and
59+ * driver setting is RCC_LSEDRIVE_HIGH.
60+ *
61+ * A detailed description about this setting can be found here:
62+ * https://www.st.com/resource/en/application_note/cd00221665-oscillator-design-guide-for-stm8afals-stm32-mcus-and-mpus-stmicroelectronics.pdf
63+ *
64+ * LSE maybe used later, but crystal load drive setting is necessary before
65+ * enabling LSE.
66+ *
67+ * @param None
68+ * @retval None
69+ */
70+
71+ static void LSEDriveConfig (void ) {
72+ // this config can be changed only when LSE is stopped
73+ // LSE could be enabled before a reset and will remain running, disable first
74+ RCC_OscInitTypeDef RCC_OscInitStruct = {0 };
75+ RCC_OscInitStruct .OscillatorType = RCC_OSCILLATORTYPE_LSE ;
76+ RCC_OscInitStruct .LSEState = RCC_LSE_OFF ;
77+ if (HAL_RCC_OscConfig (& RCC_OscInitStruct ) != HAL_OK )
78+ {
79+ error ("LSEDriveConfig : failed to disable LSE\n" );
80+ }
81+
82+ // set LSE drive level. Exception only for F4_g2 series
83+ #if defined(STM32F410Tx ) || defined(STM32F410Cx ) || defined(STM32F410Rx ) || defined(STM32F411xE ) || defined(STM32F446xx ) || defined(STM32F469xx ) || defined(STM32F479xx ) || defined(STM32F412Zx ) || \
84+ defined(STM32F412Vx ) || defined(STM32F412Rx ) || defined(STM32F412Cx ) || defined(STM32F413xx ) || defined(STM32F423xx )
85+ HAL_RCCEx_SelectLSEMode (LSE_DRIVE_LOAD_LEVEL );
86+ #else
87+ HAL_PWR_EnableBkUpAccess ();
88+ __HAL_RCC_LSEDRIVE_CONFIG (LSE_DRIVE_LOAD_LEVEL );
89+ #endif
90+ }
91+ #endif // MBED_CONF_TARGET_LSE_AVAILABLE
92+
3493/**
3594 * @brief Setup the target board-specific configuration
3695 * of the microcontroller
@@ -120,6 +179,11 @@ void mbed_sdk_init()
120179
121180 /* Configure the System clock source, PLL Multiplier and Divider factors,
122181 AHB/APBx prescalers and Flash settings */
182+ #if MBED_CONF_TARGET_LSE_AVAILABLE
183+ // LSE maybe used later, but crystal load drive setting is necessary before
184+ // enabling LSE
185+ LSEDriveConfig ();
186+ #endif
123187 SetSysClock ();
124188 SystemCoreClockUpdate ();
125189
@@ -142,6 +206,9 @@ void mbed_sdk_init()
142206
143207 /* Configure the System clock source, PLL Multiplier and Divider factors,
144208 AHB/APBx prescalers and Flash settings */
209+ #if MBED_CONF_TARGET_LSE_AVAILABLE
210+ LSEDriveConfig ();
211+ #endif
145212 SetSysClock ();
146213 SystemCoreClockUpdate ();
147214#endif /* DUAL_CORE */
0 commit comments