platform-ststm32 icon indicating copy to clipboard operation
platform-ststm32 copied to clipboard

genericSTM32F103Vx Clock Frequency

Open nopnop2002 opened this issue 3 years ago • 7 comments

What kind of issue is this?

  • [ ] Question. This issue tracker is not the place for questions. If you want to ask how to do something, or to understand why something isn't working the way you expect it to, use Community Forums or Premium Support

  • [ ] PlatformIO IDE. All issues related to PlatformIO IDE should be reported to appropriate repository: PlatformIO IDE for Atom or PlatformIO IDE for VSCode

  • [ ] Development Platform or Board. All issues (building, uploading, adding new boards, etc.) related to PlatformIO development platforms should be reported to appropriate repository related to your hardware https://github.com/topics/platformio-platform

  • [ ] Feature Request. Start by telling us what problem you’re trying to solve. Often a solution already exists! Don’t send pull requests to implement new features without first getting our support. Sometimes we leave features out on purpose to keep the project small.

  • [x] PlatformIO Core. If you’ve found a bug, please provide an information below.

You can erase any parts of this template not applicable to your Issue.


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

nopnop2002 avatar May 25 '22 08:05 nopnop2002

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.

maxgerhardt avatar Jun 13 '22 09:06 maxgerhardt

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);
}

nopnop2002 avatar Jun 13 '22 14:06 nopnop2002

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.

maxgerhardt avatar Jun 13 '22 15:06 maxgerhardt

@maxgerhardt

Thank you for the commentary.

I would like to keep this issues open for others.

nopnop2002 avatar Jun 13 '22 15:06 nopnop2002

@maxgerhardt

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

STM32F103Vx

nopnop2002 avatar Jun 13 '22 15:06 nopnop2002

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.

maxgerhardt avatar Jun 13 '22 15:06 maxgerhardt

@maxgerhardt

I got it.

nopnop2002 avatar Jun 13 '22 22:06 nopnop2002

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

valeros avatar Jun 14 '23 12:06 valeros