platformio / platform-ststm32

ST STM32: development platform for PlatformIO
https://registry.platformio.org/platforms/platformio/ststm32
Apache License 2.0
407 stars 312 forks source link

genericSTM32F103Vx Clock Frequency #628

Closed nopnop2002 closed 1 year ago

nopnop2002 commented 2 years ago

Configuration

Operating system: Linux (ubuntu)

PlatformIO Version (platformio --version): PlatformIO Core, version 5.2.5

Description of problem

I built with this variant.

genericSTM32F103VB/VC/VD/VE

The clock frequency is set to 64MHz instead of 72MHz.

Is this the correct behavior?

If problems with PlatformIO Build System:

The content of platformio.ini:

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
default_envs = genericSTM32F103VE

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

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

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

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

Source file to reproduce issue:

#include <Arduino.h>
HardwareSerial Serial1(USART1);
//HardwareSerial Serial2(USART2);
HardwareSerial Serial3(USART3);

#define BAUDRATE 115200

void setup() {
  Serial3.begin(BAUDRATE); Serial3.println("serial 3"); // PB10/PB11
  Serial2.begin(BAUDRATE); Serial2.println("serial 2"); // PA2/PA3
  Serial1.begin(BAUDRATE); Serial1.println("serial 1"); // PA9/PA10
}

void loop() {
  Serial3.println("serial 3");
  Serial3.println(F_CPU);
  Serial2.println("serial 2");
  Serial2.println(F_CPU);
  Serial1.println("serial 1");
  Serial1.println(F_CPU);
  Serial.println("serial (same as 2)");
  Serial.println("*****");
  delay(1000);
}

STM32F103Vx

maxgerhardt commented 2 years ago

genericSTM32F103VB/VC/VD/VE

The clock frequency is set to 64MHz instead of 72MHz.

Board maps to variant

https://github.com/platformio/platform-ststm32/blob/9ce784b031f5fb0dfac6dd5cda33ef4ab58191db/boards/genericSTM32F103VB.json#L19

And https://github.com/stm32duino/Arduino_Core_STM32/tree/main/variants/STM32F1xx/F103V8(H-T)_F103VB(H-I-T) only has one clock code in generic_clock.c. If the USB communication is enabled, it clocks the CPU by HSI / 2 12, with HSI = 8MHz, that is 48 Mhz (USB peripheral needs a 48MHz source and that can be achieved easily with that), else, by HSI / 2 16 = 64MHz.

If you have a high-speed crystal (HSE) on the board, you can achieve the full frequency, which is what PlatformIO always lists. It does not account for default clock init code of different frameworks. To do this, you have to place a function in your firmware, e.g. in the src/main.cpp file, with

extern "C" void SystemClock_Config(void)
{
  // clock init code here
}

and that inner code can e.g. be generated with STM32CubeMX's clock configurator tool.

nopnop2002 commented 2 years ago

I did another test using a bluepill board and same code.

blackpill_f103c8 STM32F103C8T6 72MHz 64KB 20KB BlackPill F103C8

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
default_envs = bluepill_f103c8

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

F_CPU show 72000000

genericSTM32F103C8 STM32F103C8T6 72MHz 64KB 20KB STM32F103C8 (20k RAM. 64k Flash)

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[platformio]
default_envs = genericSTM32F103CB

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

F_CPU show 64000000

Code

#include <Arduino.h>
//HardwareSerial Serial1(USART1);
HardwareSerial Serial2(USART2);
HardwareSerial Serial3(USART3);

#define BAUDRATE 115200

void setup() {
  Serial3.begin(BAUDRATE); Serial3.println("serial 3"); // PB10/PC5
  Serial2.begin(BAUDRATE); Serial2.println("serial 2"); // PA2/PA3
  Serial1.begin(BAUDRATE); Serial1.println("serial 1"); // PA9/PA10
  /* Serial.begin(BAUDRATE); */
  Serial.println("serial (same as 1)");
  Serial.println("*****");
}

void loop() {
  Serial3.println("serial 3");
  Serial3.println(F_CPU);
  Serial2.println("serial 2");
  Serial2.println(F_CPU);
  Serial1.println("serial 1");
  Serial1.println(F_CPU);
  Serial.println("serial (same as 1)");
  Serial.println("*****");
  delay(1000);
}
maxgerhardt commented 2 years ago

board = bluepill_f103c8 shows F_CPU = 72000000 because its clock code configures it to do so, HSE (=8MHz) / 1 * 9 = 72 MHz.

board = genericSTM32F103C8 shows F_CPU = 64000000 because its clock code configures it to do so, HSI (=8MHz) / 2 * 16 = 64 MHz.

Choosing different board values will select different variants in the STM32Duino core, which can all have their own clock init code. This is all okay. Specifically, generic* boards don't make assumptions about having a HSE crystal, so they use HSI, which can't achieve the full speed. Known hardware like the Bluepill uses the HSE, because it's on a bluepill.

nopnop2002 commented 2 years ago

@maxgerhardt

Thank you for the commentary.

I would like to keep this issues open for others.

nopnop2002 commented 2 years ago

@maxgerhardt

Do you think 72Mhz on this list should be changed?

STM32F103Vx

maxgerhardt commented 2 years ago

No, because that's the maximum frequency of the chip. People can still use board = genericSTM32F103C8 and achieve 72MHz if they add the clock init code. And the chip supports more frameworks (stm32cube, cmsis, mbed-os, ...), all of which can have a different default frequency. Without doing anything in CMSIS for example, clock frequency is just HSI = 8MHz. Stating the frequency in the table as 8MHz there would be very misleading.

nopnop2002 commented 2 years ago

@maxgerhardt

I got it.

valeros commented 1 year ago

The board manifest contains maximum chip frequency that has nothing to do with specific particular settings.