PlatformIO Community

Clock Settings for STM32F103 with Maple Core

In searching through this forum, I found a setting that manages to let the STM32 run without any external crystal, if I add
build_flags = -D USE_HSI_CLOCK
to the platform.ini file.

This will then just use the internal oscillator, if I’m understanding correctly.

My general problem is that this is a custom board, and it has an 8MHz crystal on it, but no 32.768kHz crystal. For reasons of the other library I want to use (mySensors) I need to use the Maple core. Is there any combination of settings that will allow the board to run with only the high speed external crystal? I’ve read through the source code that I could fine, and the only option available seems to either be no external crystal or both of them.

The board runs fine when I use the HSI setting, but there’s a crystal there, so I would like to use it if possible. Not a huge deal if I can’t, as precision isn’t necessary. This will be getting a precise timebase from a central controller. (Precise in human timescale terms. Clock updates every 5-10 seconds or so.)

It just seems a waste to not use the crystal if I can somehow do it. I’m not going to lose sleep over it, I think, but I hate waste. :slight_smile:


Low-speed and high-speed crystal are two seperate things. The high-speed clock, which can be either the HSI (high-speed-internal, RC oscillator, 8MHz) or the HSE (high-speed-external, quartz, usually 8MHz). It is used either directly or through a PLL (phase-locked-loop) to derive the core speed. The low-speed clock only feeds into the real-time-clock module and the watchdog (IWDG). There you have the choice between the LSI (RC oscillator, 40kHz) or LSE (needs external 32.768kH crystal).

The clock tree for the STM32F103C series shows that.


Note that RTCCLK can also be provided by HSE/128. This means that for your board that has an external crystal for the HSE, the boad can achieve the full high-speed clock frequency of 72MHz but can also achieve a precise low-speed clock, for e.g. the RTC, by dividing the available high-speed clock.

Regarding the code. The code where USE_HSI_CLOCK is used only sets up the HSE/HSI, PLL and the high speed clock domains. It does not do anything with the low speed clock.

The place where the low speed clocks are configured is when you use the “RTCClock” library. There, you have all clock selection options

So instantiating RTClock gClock(RTCSEL_HSE); from the RTClock.h library as global variable in the code will give you a clock object and setup which is optimal in precision / time stability. Since you also have an HSE you should not define USE_HSI_CLOCK.

If you do not use the RTC at all in your project, no further modifications need to be done – the standard settings are already HSE and RTC from LSI, but since you don’t use the RTC, it doesn’t matter.

Hi Max,

Thank you for taking the time for a very detailed reply!

I am aware that the two crystals are for two different things, and I’ve used STM32 Cube IDE before and had to set up all the clocks and multiplier/dividers.

That’s part of why I’m so confused that not having the 32.768k crystal on the board keeps it from running. I haven’t done any manual setup of the clocks at all, and I’m not using the RTC. (However, it’s entirely possible that the mySensors library is making use of it. I’m not familiar enough with it to say.) I guess I should flash a simple blink program on there and ensure that it works with the HSE enabled.

I will do more digging into the possible RTC connection as I get time. At the moment the board is running fine on the HSI while I do further development of the software and figure out why it’s transmitting but not receiving… :slight_smile: Also possible that it’s tied to me not having the low speed crystal on the board, I guess.

At any rate, I’ll also play around with adding the watch crystal to see how it affects it.

Thanks again, I really appreciate it!

Can you provide the full platformio.ini and project code? Because the way I read the maple core code a non-existent LSE should not keep the board from booting. You made sure to select the maple core by setting build_build.core = maple too right?

A wrongly setup HSE will however also keep it from booting. If the crystal frequency is off (expected 8MHz) or it doesn’t have the correct loading capacitors, starting the oscillator will fail. But you can also check that by debugging in VSCode. If you upload via an STLink, all you need to do is just Run -> Start Debugging. The stacktrace should give you an idea on where and why the MCU is stuck.