Tried to add SPL framework to STM32VLDISCOVERY but failed

Hi, I’m using SPL for STM32VLDISCOVERY, which is not supported by Platform IO IDE. I’ve tried to configure an SPL framework manually by downloading SPL from ST official website and set up the directories in “framework-spl” folder just as the SPL framework for other boards does. However, there is still some problems on uploading the elf file to my board. The VS Code keeps popping up like “Error: no handler found” and although the files seemed to compile and upload successfully, there was no response on my board (I wrote a simple LED-blink program, but the LED was not blinking). I entered the debug mode to check it out and found that the program kept stuck at this line of code:

Any suggestions on how to add SPL framework manually to STM32VLDISCOVERY? Thanks!!

Plus: I’m using STlink for on-board debugging, and here is my platform.ini:

platform = ststm32
board = disco_f100rb
framework = spl
debug_tool = stlink
upload_protocol = stlink
build_flags = -DSTM32F10X_MD

I also configured the disco_100rb.json to be the following:

  "build": {
"core": "stm32",
"cpu": "cortex-m3",
"extra_flags": "-DSTM32F100xB -DSTM32F10X_MD",
"f_cpu": "24000000L",
"mcu": "stm32f100rbt6",
"variant": "DISCO_F100RB"
  "debug": {
"default_tools": [
"jlink_device": "STM32F100RB",
"onboard_tools": [
"openocd_board": "stm32vldiscovery",
"openocd_target": "stm32f1x",
"svd_path": "STM32F100xx.svd"
  "frameworks": [
  "name": "ST STM32VLDISCOVERY",
  "upload": {
"maximum_ram_size": 8192,
"maximum_size": 131072,
"protocol": "stlink",
"protocols": [
  "url": "",
  "vendor": "ST"

and I modified the file:

# Target: Build SPL Library

extra_flags = env.BoardConfig().get("build.extra_flags", "")
src_filter_patterns = ["+<*>"]
if "STM32F40_41xxx" in extra_flags:
    src_filter_patterns += ["-<stm32f4xx_fmc.c>"]
if "STM32F427_437xx" in extra_flags:
    src_filter_patterns += ["-<stm32f4xx_fsmc.c>"]
elif "STM32F303xC" in extra_flags:
    src_filter_patterns += ["-<stm32f30x_hrtim.c>"]
elif "STM32L1XX_MD" in extra_flags:
    src_filter_patterns += ["-<stm32l1xx_flash_ramfunc.c>"]
elif "STM32F10X_MD" in extra_flags:
    src_filter_patterns += [""]

I really have no idea on how to add an SPL manually, but I just tried to imitate the existing SPL framework. Any suggestions will help!

The line you’re stuck on in the code is the clock source configuration. You seem to be using a clock source configuration with a high-speed-external (HSE) + PLL. Does your board have an external crystal even? Maybe you just configured the clock source wrong and should try HSI (high-speed internal) instead. Either way it can’t get the PLL to lock, either because the PLL assumes a wrong crystal frequency and thus has wrong multiplier/dividor settings or becuase there is no external crystal.

Thank you for your response! My board actually has an 8 MHz external crystal on it. So how should I configure the clock source then?

Can you point me to the exact code you’re running, specifically that file you’ve screenshotted?

Hello, actually just like the general methods for using existing framworks in Platform IO, I did not configure any clock source manually. My main function just looked like this:

#include <stm32f10x.h>
#include <stm32f10x_gpio.h>
#include <stm32f10x_rcc.h>

int main(void)
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure); 

	while (1) {
		// toggle led
		GPIO_WriteBit(GPIOC, GPIO_Pin_8, Bit_SET);
		GPIO_WriteBit(GPIOC, GPIO_Pin_9, Bit_SET);

and I built this source code with the “build” button. The output from Platform IO IDE indicated that it was successful. Then I debugged it and it jumped to the line as indicated in the <system_stm32f10x.c> and was stuck. So I’m wondering if I missed any configuration file (maybe python scripts) in the Platform IO IDE which is critical for the STlink debugger to recognize the clock source for my board.

The used clock source is always determined by the code. The user code can e.g. also try to use HSI instead of HSE, the debugger doesn’t have to do with this.

The function must be called implicitly before main() if it’s getting stuck on it. I’ll have a look.

Looking at the initialization code at Espruino/system_stm32f10x.c at master · espruino/Espruino · GitHub you’re stuck in the line which has

/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */ 

above it so it means you’re stuck in the function SetSysClockTo72(), which attempts to use a 25MHz crystal HSE to get a 72MHz core clock after the PLL. This is obviously wrong for your device which needs a 8MHz crystal to get 24MHz after the PLL. The reason this function is executed is because the SYSCLK_FREQ_72MHz macro is set. This macro was set because

#if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
 #define SYSCLK_FREQ_24MHz  24000000
/* #define SYSCLK_FREQ_HSE    HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz  24000000 */ 
/* #define SYSCLK_FREQ_36MHz  36000000 */
/* #define SYSCLK_FREQ_48MHz  48000000 */
/* #define SYSCLK_FREQ_56MHz  56000000 */
#define SYSCLK_FREQ_72MHz  72000000

So we need to set the correct macro STM32F10X_MD_VL since your MCU (STM32F100RBT6B) is classified by STM as a “medium-density device (MD), value line (VL)” (here).

Thus the fix should be to add -DSTM32F10X_MD_VL into your JSON config where it already said

"extra_flags": "-DSTM32F100xB -DSTM32F10X_MD",
1 Like

Oh!!! Thank you so much! It finally works!!!

1 Like

Can you upload your work so that it may be integrated in a future release of PIO? :wink:

Hi, sorry for the delay. You can find my work here.

1 Like