Nucleo F401RE fails to execute Clock init issue

Thanks for the feedback. Wondering if regression to an older version is a good approach to keep solving this. I guess it’s part of ST code inherited here. Any idea what is the real root cause ? Saw something similar on the old STM32DUINO forum, where it was related to an incorrect assumption on the quartz crystal frequency.

BTW : Nice to see this community is really alive !

This doesn’t feel like the right fix at all, the current Arduino-STM32 core (and platform) should just work with such a well-known board.

Can you take a photo of your board, especially regarding the crystall oscillator? My Nucleo F103RB e.g. gets fed its high-speed clock via the “clock in” feature (GND on XTAL2, signal on XTAL1) and the ST-Link chip on the upper side, which sources it from an 8MHz crystal, and has an unpopulated crystal slot marked “X3” otherwise. But it does have a 32.768kHz low-speed / LSE crystal.

Have you made any modifications / changed solder bridges on your Nucleo board that might affect things?

Hereby the picture.


It doesn’t indeed have an X3 crystal. I didn’t do any change to solder bridges;

Hi maxgerhardt, the board is pretty much stock. I did up date the ST-Link firmware to lastest…

Version: V2J37M26
Build:   May 13 2020 17:07:43

Okay and that board doesn’t have an X2 LSE, too.

If the Arduino core assumes a X3 crystal of 8MHz to create the HSE_XTAL+PLL config, that’s the fault. I assume it uses the same technique that the clock is actually sourced from the ST-Link and 8MHz crystal above and the STM32F4 chip directly gets the needed clock.

I’ll double check the clock init code of the Arduino core. It needs to do HSE in BYPASS mode (to get a nice high clock speed, or HSI = internal for low-speed but still working).

Hold up. Why select an F401RE when you have a F411RE? Needs this one doesn’t it ST Nucleo F411RE — PlatformIO latest documentation

Max I agre that the 8 Mhz clock should pass via the ST-link chip, according to the doc it should work like that.


SB16 should be closed, but by inspection of the board I see that it is open. Going to try.

Both pictures above are of Nucleo F401RE…

Oops, my mistake : bad title

Okay then that’s good, but the title and text of the first post is still wrong then.

The clock init code is at

And looks “okay”. Depending on whether it’s a ARDUINO_NUCLEO_F401RE or a ARDUINO_NUCLEO_F411RE operates the HSE in BYPASS mode, expecting an input frequency of 8 MHz to then use the PLL with factors / divisors, in the first case, of “/ 8 * 336 / 4” to get 84 MHz. For the F411RE it changes the factors to to / 4 * 100 / 2 to get 100 MHz.

But for that to work the clock needs to get through to the STM32. And that is by default not the case? SB16 is open on maybe older boards, when it should be closed so that the chip gets the clock?

Edit: On my Nucleo F103RB board, the SB16 bridge is closed / jumpered with 0 Ohms.

Ok, guys , I think I cracked it.
Also soldering bridge 50 is missing. After putting this also together with SB16, it works with the most recent version.
MCO2
Looks these boards were manufactured with the idea that an X3 crystal would be present.

2 Likes

Yep, while the Arduino core assumes that (apparently on my newer Nucleo base board revision), the SB16 and SB50 are closed so that the 8MHz gets through to the chip and it can then do HSE_BYPASS + PLL.

Then this mystery seems solved: Either do the hardware modification as above, or, adapt the code to source the clock from the internal HSI RC-oscillator and the PLL. The SystemClock_Config() function is WEAK so it can be overwritten in user code / sketch. I’ll shortly post code that implements this code can be found below.

Then with either a hardware or software modification, these (seemingly) older-revision Nucleo F401RE boards should work without problems in the latest STM32 platform and Arduino core.

Maybe also a patch should be proposed in the Arduino-STM32 core that switches it to HSI. Or at least have a note in a Wiki that that might be necessary.

1 Like

Looks we are not the first one looking for this mystery.
https://forum.micropython.org/viewtopic.php?t=1384

Tomorrow at the office I’ll have a look at my SB50, then bridge it if need. Will let U guys know the outcome… :slight_smile:

1 Like

If someone has the time to also test the software-patch side, while the hardware fix is either temporarily undone or not yet done, please use a standard platformio.ini of

[env:nucleo_f401re]
board = nucleo_f401re
platform = ststm32
framework = arduino

with a src\main.cpp of

#include <Arduino.h>

extern "C" void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 84;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 4;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}


void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
}

The clock init code is generated by STM32CubeMX and should get the chip from its 8MHz HSI to the full 84MHz clock speed.

If all is good, this should blink the builtin LED 2 times per second, without needing the clock input signal from the ST-Link.

Of course, the external clock signal should be preferred since it’s sourced from a stable quartz crystal instead of the internal RC oscillator, which can wobble a bit.

2 Likes

Hi Max

Just tried your above code, it runs as expected … :slight_smile:

1 Like

Same here, I removed the soldering. Excellent.

Under a microscope at the office I bridged SB16 & SB50, and now I can use the current platform… :slight_smile:

platform = ststm32 (10.0.1)

Processing nucleo_f401re (board: nucleo_f401re; platform: ststm32; framework: arduino)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------Verbose mode can be enabled via `-v, --verbose` option
CONFIGURATION: https://docs.platformio.org/page/boards/ststm32/nucleo_f401re.html
PLATFORM: ST STM32 (10.0.1) > ST Nucleo F401RE
HARDWARE: STM32F401RET6 84MHz, 96KB RAM, 512KB Flash
DEBUG: Current (stlink) On-board (stlink) External (blackmagic, cmsis-dap, jlink)
PACKAGES:
 - framework-arduinoststm32 4.10900.200819 (1.9.0)
 - framework-cmsis 2.50501.200527 (5.5.1)
 - tool-dfuutil 1.9.200310
 - tool-openocd 2.1000.200630 (10.0)
 - tool-stm32duino 1.0.2
 - toolchain-gccarmnoneeabi 1.90201.191206 (9.2.1)
LDF: Library Dependency Finder -> http://bit.ly/configure-pio-ldf
LDF Modes: Finder ~ chain, Compatibility ~ soft
Found 16 compatible libraries
Scanning dependencies...
Dependency Graph
|-- <Adafruit GFX Library> 1.10.4
|   |-- <SPI> 1.0
|   |-- <Adafruit BusIO> 1.7.1
|   |   |-- <Wire> 1.0
|   |   |-- <SPI> 1.0
|   |-- <Wire> 1.0
|-- <Adafruit ST7735 and ST7789 Library> 1.6.0
|   |-- <Adafruit GFX Library> 1.10.4
|   |   |-- <SPI> 1.0
|   |   |-- <Adafruit BusIO> 1.7.1
|   |   |   |-- <Wire> 1.0
|   |   |   |-- <SPI> 1.0
|   |   |-- <Wire> 1.0
|   |-- <SPI> 1.0
|-- <Adafruit BusIO> 1.7.1
|   |-- <Wire> 1.0
|   |-- <SPI> 1.0
|-- <Wire> 1.0
|-- <SPI> 1.0
Building in release mode
Checking size .pio\build\nucleo_f401re\firmware.elf
Advanced Memory Usage is available via "PlatformIO Home > Project Inspect"
RAM:   [          ]   1.2% (used 1208 bytes from 98304 bytes)
Flash: [          ]   4.5% (used 23688 bytes from 524288 bytes)
Configuring upload protocol...
AVAILABLE: blackmagic, cmsis-dap, jlink, mbed, stlink
CURRENT: upload_protocol = stlink
Uploading .pio\build\nucleo_f401re\firmware.elf

Out of interest sake the small tag on the underside of my board is marked ‘MB1136 C-01’, went looking and found this at the bottom pg24 of this pdf https://www.st.com/resource/en/user_manual/dm00105823-stm32-nucleo-64-boards-mb1136-stmicroelectronics.pdf

Thx @vortex314 @maxgerhardt :slight_smile:

1 Like

Ahh, so that’s where the PCB board revision is.

There are two possible default configurations of the HSE pins, depending on the version of the STM32 Nucleo board hardware.
The board version MB1136 C-01 or MB1136 C-02 is mentioned on the sticker, placed on the bottom side of the PCB.
The board marking MB1136 C-01 corresponds to a board, configured as HSE not used.
The board marking MB1136 C-02 (or higher) corresponds to a board, configured to use ST-LINK MCO as the clock input.

Mine’s a MB1136 C-04 so a newer revision and already setup for MCO as clock :slight_smile: