Skip to main content
Ozone
Principal
October 1, 2026
Question

L432 MSI clock configuration issue

  • October 1, 2026
  • 5 replies
  • 14 views

I got an issue with a STM32L432 project, were the MCU doesn't seem to behave according to the reference manual.
This is the first time I deal with an L4xx variant, so I lack the experience with the clock tree of this devices.

The sample code is a minimal Segger Embedded Studio application, with some printf() calls and an endless loop.
The code works so far, I can flash and debug it.

What doesn't work are my modifications to the clock configuration.
Hardware is the L432 Nucleo-32 I got recently, just to mention it.

The clock tree setup is basically the standard code, leaving MSI enabled in the default configuration (MSI, MSIRANGE=6, 4MHz), via functions SystemInit() and SystemCoreClockUpdate() in system_stm32l4xx.c.

As modification, I tried to set a higher clock frequency, as MSI can be set in a range from 100kHz to 48MHz.
However, I am not able to set a frequency higher than 8MHz (RCC->CR [MSIRANGE] = 7), writes to higher values are simply ignored.
The code basically works (MSION = 1, MSIRGSEL = 1, MSIRDY = 1), since I can set the MSIRANGE value from 0x06 to 0x07.
"Basically works" means I can watch the RCC->CR values change in the debugger when MSIRANGE=7, but MSIRANGE remains at 6 (default) for higher values.

Section 3.3.3 of the RM states I need increase the Flash latency in respect to the core clock frequency (and supply voltage).
But even if I set the maximum of 4 waitstates, I cannot set any MSIRANGE value greater than 7 in RCC->CR.
Of course I checked the Flash->ACR, and I can see the updated WS value written to the register.

Not sure what I am missing here...

5 replies

Andrew Neil
Super User
October 1, 2026

You forgot to post the original code, and your modifications ?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Ozone
OzoneAuthor
Principal
October 1, 2026

I considered it redundant …
But here the modified code section:
 

void SystemInit(void)
{
#if defined(USER_VECT_TAB_ADDRESS)
/* Configure the Vector Table location -------------------------------------*/
SCB->VTOR = VECT_TAB_BASE_ADDRESS | VECT_TAB_OFFSET;
#endif

/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 20U)|(3UL << 22U)); /* set CP10 and CP11 Full Access */
#endif

/* Reset the RCC clock configuration to the default reset state ------------*/
/* Set MSION bit */
RCC->CR |= RCC_CR_MSION;

// wait for MSI Ready
while ((RCC->CR & RCC_CR_MSIRDY_Msk) == 0) ; /*****************/

RCC->CR |= 0x00008; // set MSIRGSEL bit /*****************/

// set Flash waitstates for 32MHz; 1ws should suffice
FLASH->ACR |= FLASH_ACR_LATENCY_1WS; /*****************/
while ((FLASH->ACR & FLASH_ACR_LATENCY_Msk) < 1) ; /*****************/

RCC->CR |= 0x00070; // set to ...MHz /*****************/

/* Reset CFGR register */
RCC->CFGR = 0x00000000U;

The lines marked with “  /*****************/” are added by me, the rest is the “default” code of system_stm32l4xx.c.
I (visually) compared the Segger ES version with ST / Cube versions of system_stm32l4xx.c, and they are basically identical.

Given example with 0x000070 works (corresponding to ‘7’ as MSIRANGE value and thus to 8MHz.
Higher values don’t work.
In final versions I would use pretty stm32l4xx.h - defined constants instead of magic numbers, but this is test code … ;-)

Ozone
OzoneAuthor
Principal
October 1, 2026

Annoyingly, the formatting in the final post is different from the editor, that respective “marker” comments are wrapped around to the next line.
And I cannot use different colors or other highlighting methods in a code block, it seems ...

waclawek.jan
Super User
October 1, 2026

Given example with 0x000070 works (corresponding to ‘7’ as MSIRANGE value and thus to 8MHz.
Higher values don’t work.

you mean if you in above code just replace 

RCC->CR |= 0x00070;  // set to ...MHz                /*****************/

by for example

RCC->CR |= 0x00080;  // set to ...MHz                /*****************/

?

Well, yes, that can’t work, as RCC_CR.MSIRANGE is by default 0b0110 (range 6), so if you just OR the MSB to it, it will go out of range.

 

JW