1616
1717// Digital PinName array
1818const PinName digitalPin[] = {
19- PA_0, // 0 - D0/A0
20- PA_1, // 1 - D1/A1
21- PA_2, // 2 - D2/A2
22- PA_3, // 3 - D3/A3
23- PB_1, // 4 - D4/A4
24- PB_8, // 5 - D5
25- PB_9, // 6 - D6
26- PA_4 , // 7 - BAT_VOLTAGE
27- PA_8 , // 8 - LED_BUILTIN
28- PB_14, // 9 - D9
19+ PA_0, // 0 - A0/D0
20+ PA_1, // 1 - A1/D1
21+ PA_2, // 2 - A2/D2
22+ PA_3, // 3 - A3/D3
23+ PB_1, // 4 - A4/D4
24+ PB_8, // 5 - D5
25+ PB_9, // 6 - D6
26+ PA_8 , // 7 - LED_BUILTIN
27+ PC_13 , // 8 - USER_BTN
28+ PB_14, // 9 - D9
2929 PB_13, // 10 - D10
3030 PB_0, // 11 - D11
3131 PB_15, // 12 - D12
3232 PB_4, // 13 - D13
33- PA_5 , // 14 - CK
34- PA_6 , // 15 - MI
35- PA_7 , // 16 - A5
36- PA_9 , // 17 - TX
33+ PA_7 , // 14 - A5
34+ PA_5 , // 15 - CK
35+ PB_5 , // 16 - MO
36+ PA_6 , // 17 - MI
3737 PA_10, // 18 - RX
38- PA_11 , // 19 - USB_DM
39- PA_12 , // 20 - USB_DP
40- PA_13 , // 21 - SWDIO
41- PA_14 , // 22 - SWCLK
42- PA_15 , // 23 - CHARGE_DETECT
43- PB_3 , // 24 - USB_DETECT
44- PB_5 , // 25 - MO
45- PB_6 , // 26 - SCL
46- PB_7 , // 27 - SDA
47- PB_10 , // 28 - LPUART1_VCP_RX
48- PB_11 , // 29 - LPUART1_VCP_TX
49- PC_13 , // 30 - USER_BTN
50- PC_14 , // 31 - OSC32_IN
51- PC_15 , // 32 - OSC32_OUT
52- PH_0 , // 33 - ENABLE_3V3
53- PH_1 , // 34 - DISCHARGE_3V3
54- PH_3 // 35 - B
38+ PA_9 , // 19 - TX
39+ PH_3 , // 20 - B
40+ PB_6 , // 21 - SCL
41+ PB_7 , // 22 - SDA
42+ PA_13 , // 23 - SWDIO
43+ PA_14 , // 24 - SWCLK
44+ PB_10 , // 25 - LPUART1_VCP_RX
45+ PB_11 , // 26 - LPUART1_VCP_TX
46+ PH_0 , // 27 - ENABLE_3V3
47+ PH_1 , // 28 - DISCHARGE_3V3
48+ PA_15 , // 29 - CHARGE_DETECT
49+ PA_4 , // 30 - A6/BATTERY_VOLTAGE (STAT)
50+ PB_3 , // 31 - USB_DETECT
51+ PA_11 , // 32 - USB_DM
52+ PA_12 , // 33 - USB_DP
53+ PC_14 , // 34 - OSC32_IN (LSE)
54+ PC_15 // 35 - OSC32_OUT (LSE)
5555};
5656
5757// Analog (Ax) to digital pin number array
5858const uint32_t analogInputPin[] = {
59- 0 , // PA0, A0
60- 1 , // PA1, A1
61- 2 , // PA2, A2
62- 3 , // PA3, A3
63- 4 , // PB1, A4
64- 16 , // PA7, A5
65- 7 // PA4, BAT_VOLTAGE
59+ 0 , // PA0, A0
60+ 1 , // PA1, A1
61+ 2 , // PA2, A2
62+ 3 , // PA3, A3
63+ 4 , // PB1, A4
64+ 14 , // PA7, A5
65+ 30 // PA4, A6/BATTERY_VOLTAGE (STAT)
6666};
6767
6868// ----------------------------------------------------------------------------
@@ -76,7 +76,7 @@ WEAK void initVariant(void)
7676 /* All pins set to high-Z (floating) initially */
7777 /* DS11449 Rev 8, Section 3.9.5 - Reset Mode: */
7878 /* In order to improve the consumption under reset, the I/Os state under
79- * and after reset is “ analog state” (the I/O schmitt trigger is disable ).
79+ * and after reset is " analog state" (the I/O schmitt trigger is disabled ).
8080 * In addition, the internal reset pull-up is deactivated when the reset
8181 * source is internal.
8282 */
@@ -121,10 +121,24 @@ WEAK void initVariant(void)
121121}
122122
123123/* *
124- * @brief System Clock Configuration
125- * @param None
126- * @retval None
127- */
124+ * @brief System Clock Configuration - PLL-based STM32L433 with native USB FS
125+ *
126+ * Key features:
127+ * - SYSCLK = 80 MHz from MSI (4 MHz, Range 6) via PLL (4MHz x 40/2)
128+ * - USB FS (48 MHz) sourced from PLLSAI1 (4MHz x 24/2)
129+ * - HSI disabled to reduce current consumption (~200-300 uA)
130+ * - LSE enabled with medium-low drive for RTC and MSI auto-calibration (MSIPLLEN)
131+ * - Voltage Scale 1 required for 80 MHz operation
132+ * - FLASH_LATENCY_4 required for HCLK > 64 MHz at VOS1 (RM0394 s.3.3.3)
133+ * - MSI PLL-mode (MSIPLLEN) enabled after SYSCLK moves to PLL to avoid MSIRDY stall
134+ * - Wake-up clock after STOP: MSI (PLL must be re-locked manually after wake)
135+ *
136+ * References:
137+ * - RM0394 Rev 6 (STM32L43x/L44x) - s.6.2 "MSI clock"
138+ * - RM0394 s.6.2.9 "MSI PLL-mode"
139+ * - RM0394 s.3.3.3 "Performance versus VDD and clock frequency"
140+ * - AN2867 Rev 11 - "Oscillator design guide for STM8AF/AL/S, STM32 MCUs and MPUs"
141+ */
128142WEAK void SystemClock_Config (void )
129143{
130144 RCC_OscInitTypeDef RCC_OscInitStruct = {};
@@ -133,15 +147,16 @@ WEAK void SystemClock_Config(void)
133147
134148 /* * Enable PWR peripheral clock
135149 *
136- * RM0394 § 5.1.2: PWR registers are on APB1. PWREN (RCC_APB1ENR1 bit 28)
150+ * RM0394 s. 5.1.2: PWR registers are on APB1. PWREN (RCC_APB1ENR1 bit 28)
137151 * resets to 1, so this is defensive rather than strictly necessary, but
138152 * required for correctness if PWREN has been cleared by prior code.
139153 * CubeMX generates this unconditionally for all STM32L4 projects.
140154 */
141155 __HAL_RCC_PWR_CLK_ENABLE ();
142156
143- /* * Configure the main internal regulator output voltage
144- */
157+ /* Voltage scaling - Scale 1 required for SYSCLK = 80 MHz
158+ * RM0394 s.6.1: VOS2 supports up to 26 MHz only
159+ */
145160 if (HAL_PWREx_ControlVoltageScaling (PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) {
146161 Error_Handler ();
147162 }
@@ -163,33 +178,29 @@ WEAK void SystemClock_Config(void)
163178 /* * Initializes the RCC Oscillators according to the specified parameters
164179 * in the RCC_OscInitTypeDef structure.
165180 *
166- * Cygnet config :
167- * - MSI: MSIRANGE_6 (4 MHz) — used as PLL input
168- * - HSI: OFF — nothing in this config uses it
169- * - PLL: NONE → ON (MSI 4 MHz × PLLN=40 / PLLR=2 → SYSCLK = 80 MHz)
170- * - SYSCLK: MSI (48 MHz) → PLLCLK (80 MHz)
171- * - USB clock: removed from PeriphCLKConfig (MSI) → PLLSAI1 (48 MHz)
181+ * Oscillator configuration summary :
182+ * - MSI: MSIRANGE_6 (4 MHz) -- used as PLL input
183+ * - HSI: OFF -- Unused, disabling it saves ~200-300 uA
184+ * - PLL: ON (MSI 4MHz x PLLN=40 / PLLR=2 = 80 MHz)
185+ * - SYSCLK: PLLCLK (80 MHz)
186+ * - USB clock: PLLSAI1 (48 MHz)
172187 * - MSIRDY transient can not stall SysTick because SYSCLK = PLL, not MSI.
173- * - FLASH_LATENCY: 2 → 4 (required for 80 MHz / VOS1 per RM0394 § 3.3)
188+ * - FLASH_LATENCY: 4 (required for 80 MHz / VOS1 per RM0394 s. 3.3)
174189 */
175190 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE
176191 | RCC_OSCILLATORTYPE_MSI;
177192 RCC_OscInitStruct.LSEState = RCC_LSE_ON;
178- /* HSI is not used as SYSCLK source, PLL/PLLSAI1 input, or any peripheral
179- * clock reference. Disabling it saves ~200-300 µA. */
180193 RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
181194 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
182195 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
183- /* MSIRANGE_6 = 4 MHz — same as Nucleo. Low-frequency reference fed into
184- * the main PLL (×40/÷2 = 80 MHz) and PLLSAI1 (×24/÷2 = 48 MHz). */
185196 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
186197 RCC_OscInitStruct.PLL .PLLState = RCC_PLL_ON;
187198 RCC_OscInitStruct.PLL .PLLSource = RCC_PLLSOURCE_MSI;
188199 RCC_OscInitStruct.PLL .PLLM = 1 ;
189200 RCC_OscInitStruct.PLL .PLLN = 40 ;
190201 RCC_OscInitStruct.PLL .PLLP = RCC_PLLP_DIV7;
191202 RCC_OscInitStruct.PLL .PLLQ = RCC_PLLQ_DIV2;
192- RCC_OscInitStruct.PLL .PLLR = RCC_PLLR_DIV2; /* 4 × 40 / 2 = 80 MHz */
203+ RCC_OscInitStruct.PLL .PLLR = RCC_PLLR_DIV2; /* 4MHz x 40 / 2 = 80 MHz */
193204 if (HAL_RCC_OscConfig (&RCC_OscInitStruct) != HAL_OK) {
194205 Error_Handler ();
195206 }
@@ -206,24 +217,24 @@ WEAK void SystemClock_Config(void)
206217 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
207218 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
208219 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
209- /* FLASH_LATENCY_4: required for HCLK > 64 MHz at VOS1 (RM0394 § 3.3.3) */
220+ /* FLASH_LATENCY_4: required for HCLK > 64 MHz at VOS1 (RM0394 s. 3.3.3) */
210221 if (HAL_RCC_ClockConfig (&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK) {
211222 Error_Handler ();
212223 }
213224
214225 /* * Initializes the Peripheral clocks
215226 *
216- * USB clock: PLLSAI1 (MSI 4 MHz × PLLSAI1N=24 / PLLSAI1Q=2 = 48 MHz).
227+ * USB clock: PLLSAI1 (MSI 4 MHz x PLLSAI1N=24 / PLLSAI1Q=2 = 48 MHz).
217228 * This mirrors the Nucleo L432KC exactly. RCCEx_PLLSAI1_Config() waits
218229 * for PLLSAI1RDY using HAL_GetTick(). Because SYSCLK is now PLL-based,
219- * HAL_GetTick() is immune to MSI transients — the wait is reliable.
230+ * HAL_GetTick() is immune to MSI transients -- the wait is reliable.
220231 * PLLSAI1 and the main PLL share the same source (MSI) and M divider (1),
221232 * which the HAL enforces; both are configured consistently here.
222233 *
223234 * HAL_RCCEx_PeriphCLKConfig writes CLK48SEL first (pointing at PLLSAI1
224235 * before it is running), then enables PLLSAI1 and waits for its RDY flag.
225236 * During that brief window the USB peripheral has no 48 MHz clock and
226- * stays quiescent — avoiding the race where a live MSI clock is handed
237+ * stays quiescent -- avoiding the race where a live MSI clock is handed
227238 * to USB before the peripheral is ready to handle the absence of VBUS.
228239 */
229240 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_USB;
@@ -233,7 +244,7 @@ WEAK void SystemClock_Config(void)
233244 PeriphClkInit.PLLSAI1 .PLLSAI1M = 1 ;
234245 PeriphClkInit.PLLSAI1 .PLLSAI1N = 24 ;
235246 PeriphClkInit.PLLSAI1 .PLLSAI1P = RCC_PLLP_DIV7;
236- PeriphClkInit.PLLSAI1 .PLLSAI1Q = RCC_PLLQ_DIV2; /* 4 × 24 / 2 = 48 MHz */
247+ PeriphClkInit.PLLSAI1 .PLLSAI1Q = RCC_PLLQ_DIV2; /* 4 x 24 / 2 = 48 MHz */
237248 PeriphClkInit.PLLSAI1 .PLLSAI1R = RCC_PLLR_DIV2;
238249 PeriphClkInit.PLLSAI1 .PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK;
239250 if (HAL_RCCEx_PeriphCLKConfig (&PeriphClkInit) != HAL_OK) {
@@ -242,10 +253,10 @@ WEAK void SystemClock_Config(void)
242253
243254/* * Enable MSI Auto calibration (MSIPLLEN, RCC_CR[2])
244255 *
245- * RM0394 § 6.2 (MSI clock): setting MSIPLLEN causes the MSI hardware
256+ * RM0394 s. 6.2 (MSI clock): setting MSIPLLEN causes the MSI hardware
246257 * to automatically trim itself against LSE as a phase reference,
247- * reducing MSI frequency error to < ± 0.25%. LSE must already be
248- * stable (LSERDY=1) before the bit is set — guaranteed here because
258+ * reducing MSI frequency error to < +/- 0.25%. LSE must already be
259+ * stable (LSERDY=1) before the bit is set -- guaranteed here because
249260 * HAL_RCC_OscConfig() waited for LSERDY before returning.
250261 *
251262 * Setting MSIPLLEN causes MSIRDY to deassert transiently while MSI
@@ -254,18 +265,18 @@ WEAK void SystemClock_Config(void)
254265 * inside it. Two conclusions follow:
255266 *
256267 * (1) This call must come AFTER any HAL routine that polls MSIRDY
257- * under a HAL_GetTick() timeout — if MSIRDY drops inside such
268+ * under a HAL_GetTick() timeout -- if MSIRDY drops inside such
258269 * a routine, the routine returns HAL_TIMEOUT and leaves the
259270 * clock tree in an undefined state.
260271 *
261272 * (2) If SYSCLK were MSI, a deadlock would be possible: MSIRDY
262- * drops → SysTick stalls → HAL_GetTick() freezes → any
263- * subsequent timeout loop never exits. RM0394 § 6.2.9 confirms
273+ * drops -> SysTick stalls -> HAL_GetTick() freezes -> any
274+ * subsequent timeout loop never exits. RM0394 s. 6.2.9 confirms
264275 * SysTick is driven by HCLK (= SYSCLK / AHBdiv). Because
265276 * SYSCLK is now PLLCLK (80 MHz), SysTick is completely
266277 * decoupled from MSI and the transient is harmless.
267278 *
268- * Placement here — after PeriphCLKConfig — satisfies both constraints
279+ * Placement here -- after PeriphCLKConfig -- satisfies both constraints
269280 * and mirrors the ordering generated by CubeMX for the Nucleo L432KC.
270281 */
271282HAL_RCCEx_EnableMSIPLLMode ();
@@ -278,7 +289,6 @@ HAL_RCCEx_EnableMSIPLLMode();
278289 * PLL-based design on STM32L4.
279290 */
280291 HAL_RCCEx_WakeUpStopCLKConfig (RCC_STOP_WAKEUPCLOCK_MSI);
281- #pragma message("Compiled using local Arduino_Core_STM32: 2.13.0-dev.")
282292}
283293
284294#ifdef __cplusplus
0 commit comments