Unify STM32 implementation, remove legacy STM32F1 (#1579)

* Unify STM32 implementation, remove legacy STM32F1

* Add build stage for STM32F4 examples

* Apply restyling patch

* Update fqbn for STM32F1 and STM32F4 builds

* Update fqbn parameters for STM32F1 and STM32F4 builds

* Update fqbn for STM32F1 to use BLUEPILL_F103C8

* Add STM32F4 build stages to pipeline

* Fix condition for setting build status on failure
This commit is contained in:
Olivier
2025-11-23 14:13:11 +01:00
committed by GitHub
parent 130091deb8
commit 96c4df79e8
18 changed files with 100 additions and 71 deletions

View File

@@ -189,7 +189,7 @@ def buildArduinoMega(config, sketches, String key) {
}
def buildSTM32F1(config, sketches, String key) {
def fqbn = '-fqbn stm32duino:STM32F1:genericSTM32F103C:device_variant=STM32F103C8,upload_method=DFUUploadMethod,cpu_speed=speed_72mhz,opt=osstd'
def fqbn = '-fqbn STMicroelectronics:stm32:GenF1:pnum=BLUEPILL_F103C8,upload_method=swdMethod,xserial=generic,usb=none,xusb=FS,opt=osstd,dbg=none,rtlib=nano'
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (STM32F1 - '+key+')', 'Building...', '${BUILD_URL}flowGraphTable/')
try {
for (sketch = 0; sketch < sketches.size(); sketch++) {
@@ -223,6 +223,41 @@ def buildSTM32F1(config, sketches, String key) {
}
}
def buildSTM32F4(config, sketches, String key) {
def fqbn = '-fqbn STMicroelectronics:stm32:GenF4:pnum=BLACKPILL_F411CE,upload_method=swdMethod,xserial=generic,usb=none,xusb=FS,opt=osstd,dbg=none,rtlib=nano'
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (STM32F4 - '+key+')', 'Building...', '${BUILD_URL}flowGraphTable/')
try {
for (sketch = 0; sketch < sketches.size(); sketch++) {
if (sketches[sketch].path != config.library_root+'examples/GatewayESP8266/GatewayESP8266.ino' &&
sketches[sketch].path != config.library_root+'examples/GatewayESP8266MQTTClient/GatewayESP8266MQTTClient.ino' &&
sketches[sketch].path != config.library_root+'examples/GatewayESP8266SecureMQTTClient/GatewayESP8266SecureMQTTClient.ino' &&
sketches[sketch].path != config.library_root+'examples/GatewayESP8266OTA/GatewayESP8266OTA.ino' &&
sketches[sketch].path != config.library_root+'examples/GatewayESP32/GatewayESP32.ino' &&
sketches[sketch].path != config.library_root+'examples/GatewayESP32OTA/GatewayESP32OTA.ino' &&
sketches[sketch].path != config.library_root+'examples/GatewayESP32MQTTClient/GatewayESP32MQTTClient.ino' &&
sketches[sketch].path != config.library_root+'examples/SensebenderGatewaySerial/SensebenderGatewaySerial.ino') {
buildArduino(config, fqbn, sketches[sketch].path, key+'_STM32F4')
}
}
} catch (ex) {
echo "Build failed with: "+ ex.toString()
config.pr.setBuildStatus(config, 'FAILURE', 'Toll gate (STM32F4 - '+key+')', 'Build error', '${BUILD_URL}')
throw ex
} finally {
parseWarnings(key+'_STM32F4')
}
if (currentBuild.currentResult == 'UNSTABLE') {
config.pr.setBuildStatus(config, 'ERROR', 'Toll gate (STM32F4 - '+key+')', 'Warnings found', '${BUILD_URL}warnings2Result/new')
if (config.is_pull_request) {
error 'Terminated due to warnings found'
}
} else if (currentBuild.currentResult == 'FAILURE') {
config.pr.setBuildStatus(config, 'FAILURE', 'Toll gate (STM32F4 - '+key+')', 'Build error', '${BUILD_URL}')
} else {
config.pr.setBuildStatus(config, 'SUCCESS', 'Toll gate (STM32F4 - '+key+')', 'Pass', '')
}
}
def buildESP8266(config, sketches, String key) {
def fqbn = '-fqbn=esp8266:esp8266:generic:xtal=80,vt=flash,exception=disabled,ResetMethod=ck,CrystalFreq=26,FlashFreq=40,FlashMode=dout,eesz=512K,led=2,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=115200'
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (ESP8266 - '+key+')', 'Building...', '${BUILD_URL}flowGraphTable/')

View File

@@ -33,6 +33,7 @@ def call(Closure body) {
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (nRF5 - Tests)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (ESP8266 - Tests)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (STM32F1 - Tests)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (STM32F4 - Tests)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (Arduino Uno - Tests)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (Arduino Mega - Tests)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (MySensorsMicro - Examples)', 'Not run yet...', '')
@@ -51,8 +52,9 @@ def call(Closure body) {
/*
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (ESP32 - Examples)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (STM32F1 - Examples)', 'Not run yet...', '')
*/
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (STM32F1 - Examples)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (STM32F4 - Examples)', 'Not run yet...', '')
config.pr.setBuildStatus(config, 'PENDING', 'Toll gate (Arduino Uno - Examples)', 'Not run yet...', '')
@@ -156,6 +158,9 @@ def call(Closure body) {
stage('STM32F1 (tests)') {
arduino.buildSTM32F1(config, config.tests, 'Tests')
}
stage('STM32F4 (tests)') {
arduino.buildSTM32F4(config, config.tests, 'Tests')
}
stage('ArduinoUno (tests)') {
arduino.buildArduinoUno(config, config.tests, 'Tests')
}
@@ -195,11 +200,12 @@ def call(Closure body) {
arduino.buildESP32(config, config.examples, 'Examples')
}
*/
// No point in building examples for STM32F1 yet
/*
stage('STM32F1 (Examples)') {
arduino.buildSTM32F1(config, config.tests, 'Examples')
*/
}
stage('STM32F4 (Examples)') {
arduino.buildSTM32F4(config, config.tests, 'Examples')
}
stage('ArduinoUno (examples)') {
arduino.buildArduinoUno(config, config.examples, 'Examples')
}
@@ -216,7 +222,7 @@ def call(Closure body) {
currentBuild.result = 'FAILURE'
throw ex
} finally {
if (currentBuild.result != 'SUCCESS')
if (currentBuild.result && currentBuild.result != 'SUCCESS')
{
config.pr.setBuildStatus(config, 'ERROR', 'Toll gate', 'Failed', '${BUILD_URL}flowGraphTable/')
if (config.is_pull_request) {

View File

@@ -2614,10 +2614,10 @@
#define ARDUINO_ARCH_MEGAAVR
/**
* @def ARDUINO_ARCH_STM32F1
* @brief Automatically set when building for STM32F1 targets
* @def ARDUINO_ARCH_STM32
* @brief Automatically set when building for STM32 targets
*/
#define ARDUINO_ARCH_STM32F1
#define ARDUINO_ARCH_STM32
/**
* @def TEENSYDUINO

View File

@@ -70,9 +70,6 @@
#include "drivers/extEEPROM/extEEPROM.cpp"
#include "hal/architecture/SAMD/MyHwSAMD.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
#elif defined(ARDUINO_ARCH_STM32F1)
#include "hal/architecture/STM32F1/MyHwSTM32F1.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
#elif defined(ARDUINO_ARCH_STM32)
#include "hal/architecture/STM32/MyHwSTM32.cpp"
#include "hal/crypto/generic/MyCryptoGeneric.cpp"
@@ -339,7 +336,7 @@ MY_DEFAULT_RX_LED_PIN in your sketch instead to enable LEDs
#define MY_RAM_ROUTING_TABLE_ENABLED
#elif defined(MY_RAM_ROUTING_TABLE_FEATURE) && defined(MY_REPEATER_FEATURE)
// activate feature based on architecture
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_NRF5) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32) || defined(TEENSYDUINO) || defined(__linux__) || defined(__ASR6501__) || defined (__ASR6502__)
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_SAMD) || defined(ARDUINO_ARCH_NRF5) || defined(ARDUINO_ARCH_STM32) || defined(TEENSYDUINO) || defined(__linux__) || defined(__ASR6501__) || defined (__ASR6502__)
#define MY_RAM_ROUTING_TABLE_ENABLED
#elif defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
#if defined(__avr_atmega1280__) || defined(__avr_atmega1284__) || defined(__avr_atmega2560__) || defined(__avr_attiny3224__) || defined(__avr_attiny3227__)
@@ -475,8 +472,6 @@ MY_DEFAULT_RX_LED_PIN in your sketch instead to enable LEDs
#include "hal/architecture/ESP32/MyMainESP32.cpp"
#elif defined(__linux__)
#include "hal/architecture/Linux/MyMainLinuxGeneric.cpp"
#elif defined(ARDUINO_ARCH_STM32F1)
#include "hal/architecture/STM32F1/MyMainSTM32F1.cpp"
#elif defined(ARDUINO_ARCH_STM32)
#include "hal/architecture/STM32/MyMainSTM32.cpp"
#elif defined(__ASR6501__) || defined(__ASR6502__)

View File

@@ -147,7 +147,7 @@
* @def MY_CAP_ARCH
* @brief Indicate the architecture.
*
* @see ARDUINO_ARCH_SAMD, ARDUINO_ARCH_NRF5, ARDUINO_ARCH_ESP8266, ARDUINO_ARCH_ESP32, ARDUINO_ARCH_AVR, ARDUINO_ARCH_STM32F1, TEENSYDUINO
* @see ARDUINO_ARCH_SAMD, ARDUINO_ARCH_NRF5, ARDUINO_ARCH_ESP8266, ARDUINO_ARCH_ESP32, ARDUINO_ARCH_AVR, ARDUINO_ARCH_STM32, TEENSYDUINO
*
* | Architecture | Indicator
* |--------------|----------
@@ -156,7 +156,7 @@
* | ESP8266 | E
* | ESP32 | F
* | AVR | A
* | STM32F1 | M
* | STM32 | M
* | TEENSY | T
* | Linux | L
* | Unknown | -
@@ -171,7 +171,7 @@
#define MY_CAP_ARCH "F"
#elif defined(ARDUINO_ARCH_AVR) || defined(ARDUINO_ARCH_MEGAAVR)
#define MY_CAP_ARCH "A"
#elif defined(ARDUINO_ARCH_STM32F1)
#elif defined(ARDUINO_ARCH_STM32)
#define MY_CAP_ARCH "M"
#elif defined(__arm__) && defined(TEENSYDUINO)
#define MY_CAP_ARCH "T"

View File

@@ -1349,8 +1349,8 @@ static void probe_and_print_peripherals(void)
Serial.print(F("| ESP8266 | DETECTED | N/A | "));
#elif defined(ARDUINO_ARCH_SAMD)
Serial.print(F("| SAMD | DETECTED | N/A | "));
#elif defined(ARDUINO_ARCH_STM32F1)
Serial.print(F("| STM32F1 | DETECTED | N/A | "));
#elif defined(ARDUINO_ARCH_STM32)
Serial.print(F("| STM32 | DETECTED | N/A | "));
#elif defined(__linux__)
Serial.print(F("| Linux | DETECTED | N/A | "));
#else

View File

@@ -84,9 +84,6 @@ void hwWriteConfigBlock(void *buf, void *addr, size_t length)
for (size_t i = 0; i < length; i++) {
EEPROM.update(pos + i, src[i]);
}
// Commit changes to flash (STM32duino EEPROM emulation)
// Note: This happens automatically on next read or explicit commit
}
uint8_t hwReadConfig(const int addr)
@@ -107,7 +104,6 @@ void hwWatchdogReset(void)
// This works whether IWDG was initialized by HAL or LL drivers
IWDG->KR = IWDG_KEY_RELOAD;
#endif
// No-op if watchdog not enabled
}
void hwReboot(void)
@@ -162,20 +158,8 @@ bool hwUniqueID(unique_id_t *uniqueID)
#ifdef UID_BASE
// STM32 unique device ID is stored at a fixed address
// Length is 96 bits (12 bytes) but we store 16 bytes for compatibility
uint32_t *id = (uint32_t *)UID_BASE;
uint8_t *dst = (uint8_t *)uniqueID;
// Copy 12 bytes of unique ID
for (uint8_t i = 0; i < 12; i++) {
dst[i] = ((uint8_t *)id)[i];
}
// Pad remaining bytes with zeros
for (uint8_t i = 12; i < 16; i++) {
dst[i] = 0;
}
(void)memcpy((uint8_t *)uniqueID, (uint32_t *)UID_BASE, 12);
(void)memset(static_cast<void *>(uniqueID + 12), MY_HWID_PADDING_BYTE, 4); // padding
return true;
#else
// Unique ID not available on this variant

View File

@@ -28,30 +28,45 @@
#include "MyHwSTM32.h"
// Declare the sketch's setup() and loop() functions
__attribute__((weak)) void setup(void);
__attribute__((weak)) void loop(void);
__attribute__((constructor(101))) void premain()
{
// Required by FreeRTOS, see http://www.freertos.org/RTOS-Cortex-M3-M4.html
#ifdef NVIC_PRIORITYGROUP_4
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
#endif
#if (__CORTEX_M == 0x07U)
// Defined in CMSIS core_cm7.h
#ifndef I_CACHE_DISABLED
SCB_EnableICache();
#endif
#ifndef D_CACHE_DISABLED
SCB_EnableDCache();
#endif
#endif
// Override Arduino's main() function
init();
}
/*
* \brief Main entry point of Arduino application
*/
int main(void)
{
// Initialize Arduino core
init();
#if defined(USBCON)
// Initialize USB if available
USBDevice.attach();
#endif
initVariant();
_begin(); // Startup MySensors library
for(;;) {
for (;;) {
#if defined(CORE_CALLBACK)
CoreCallback();
#endif
_process(); // Process incoming data
if (loop) {
loop(); // Call sketch loop
}
// STM32duino doesn't use serialEventRun by default
serialEventRun();
}
return 0;
}

View File

@@ -7,7 +7,7 @@ This directory contains the Hardware Abstraction Layer (HAL) implementation for
The STM32 HAL enables MySensors to run on a wide range of STM32 microcontrollers, including:
- **STM32F0** series (Cortex-M0)
- **STM32F1** series (Cortex-M3) - Note: This is separate from the old STM32F1 maple implementation
- **STM32F1** series (Cortex-M3)
- **STM32F4** series (Cortex-M4 with FPU)
- **STM32L0/L4** series (Low-power Cortex-M0+/M4)
- **STM32G0/G4** series (Cortex-M0+/M4)
@@ -103,20 +103,9 @@ board = blackpill_f411ce
; Upload configuration
upload_protocol = stlink
; Build flags
build_flags =
-D MY_DEBUG
-D MY_BAUD_RATE=115200
-D MY_GATEWAY_SERIAL
-D MY_RADIO_RF24
-D MY_RF24_CE_PIN=PB0
-D MY_RF24_CS_PIN=PA4
-D MY_RF24_PA_LEVEL=RF24_PA_LOW
; Library dependencies
lib_deps =
mysensors/MySensors@^2.4.0
; Add radio-specific libraries if needed
; Monitor configuration
monitor_speed = 115200
@@ -130,7 +119,7 @@ debug_tool = stlink
Common `board` values for platformio.ini:
- `blackpill_f401cc` - STM32F401CC Black Pill
- `blackpill_f411ce` - STM32F411CE Black Pill (recommended)
- `bluepill_f103c8` - STM32F103C8 Blue Pill (use old STM32F1 HAL instead)
- `bluepill_f103c8` - STM32F103C8 Blue Pill
- `nucleo_f401re` - STM32F401RE Nucleo
- `nucleo_f411re` - STM32F411RE Nucleo
- `genericSTM32F103C8` - Generic F103C8
@@ -144,6 +133,7 @@ Supported `upload_protocol` options:
- `serial` - Serial bootloader (requires FTDI adapter)
- `jlink` - Segger J-Link
- `blackmagic` - Black Magic Probe
- `hid` - HID Bootloader 2.0
## Arduino IDE Configuration

View File

@@ -17,6 +17,8 @@
* version 2 as published by the Free Software Foundation.
*/
#error This STM32F1 implementation is deprecated, use the STM32duino implementation instead
#include "MyHwSTM32F1.h"
/*

View File

@@ -17,6 +17,8 @@
* version 2 as published by the Free Software Foundation.
*/
#error This STM32F1 implementation is deprecated, use the STM32duino implementation instead
// Force init to be called *first*, i.e. before static object allocation.
// Otherwise, statically allocated objects that need libmaple may fail.
__attribute__(( constructor (101))) void premain()

View File

@@ -76,7 +76,7 @@
#elif defined(LINUX_ARCH_RASPBERRYPI)
#define DEFAULT_RF24_CE_PIN (22) //!< DEFAULT_RF24_CE_PIN
//#define DEFAULT_RF24_CS_PIN (24) //!< DEFAULT_RF24_CS_PIN
#elif defined(ARDUINO_ARCH_STM32F1)
#elif defined(ARDUINO_ARCH_STM32)
#define DEFAULT_RF24_CE_PIN (PB0) //!< DEFAULT_RF24_CE_PIN
#elif defined(TEENSYDUINO)
#define DEFAULT_RF24_CE_PIN (9) //!< DEFAULT_RF24_CE_PIN

View File

@@ -95,7 +95,7 @@
#define DEFAULT_RFM69_IRQ_PIN (2) //!< DEFAULT_RFM69_IRQ_PIN
#elif defined(LINUX_ARCH_RASPBERRYPI)
#define DEFAULT_RFM69_IRQ_PIN (22) //!< DEFAULT_RFM69_IRQ_PIN
#elif defined(ARDUINO_ARCH_STM32F1)
#elif defined(ARDUINO_ARCH_STM32)
#define DEFAULT_RFM69_IRQ_PIN (PA3) //!< DEFAULT_RFM69_IRQ_PIN
#elif defined(TEENSYDUINO)
#define DEFAULT_RFM69_IRQ_PIN (8) //!< DEFAULT_RFM69_IRQ_PIN

View File

@@ -56,7 +56,7 @@
#elif defined(LINUX_ARCH_RASPBERRYPI)
#define DEFAULT_RFM69_IRQ_PIN (22) //!< DEFAULT_RFM69_IRQ_PIN
#define DEFAULT_RFM69_IRQ_NUM DEFAULT_RFM69_IRQ_PIN //!< DEFAULT_RFM69_IRQ_NUM
#elif defined(ARDUINO_ARCH_STM32F1)
#elif defined(ARDUINO_ARCH_STM32)
#define DEFAULT_RFM69_IRQ_PIN (PA3) //!< DEFAULT_RFM69_IRQ_PIN
#define DEFAULT_RFM69_IRQ_NUM DEFAULT_RFM69_IRQ_PIN //!< DEFAULT_RFM69_IRQ_NUM
#elif defined(TEENSYDUINO)

View File

@@ -101,7 +101,7 @@
#define DEFAULT_RFM95_IRQ_PIN (2) //!< DEFAULT_RFM95_IRQ_PIN
#elif defined(LINUX_ARCH_RASPBERRYPI)
#define DEFAULT_RFM95_IRQ_PIN (22) //!< DEFAULT_RFM95_IRQ_PIN
#elif defined(ARDUINO_ARCH_STM32F1)
#elif defined(ARDUINO_ARCH_STM32)
#define DEFAULT_RFM95_IRQ_PIN (PA3) //!< DEFAULT_RFM95_IRQ_PIN
#elif defined(TEENSYDUINO)
#define DEFAULT_RFM95_IRQ_PIN (8) //!< DEFAULT_RFM95_IRQ_PIN

View File

@@ -102,7 +102,7 @@
#define DEFAULT_SX126x_IRQ_PIN (2) //!< DEFAULT_SX126x_IRQ_PIN
#elif defined(LINUX_ARCH_RASPBERRYPI)
#define DEFAULT_SX126x_IRQ_PIN (22) //!< DEFAULT_SX126x_IRQ_PIN
#elif defined(ARDUINO_ARCH_STM32F1)
#elif defined(ARDUINO_ARCH_STM32)
#define DEFAULT_SX126x_IRQ_PIN (PA3) //!< DEFAULT_SX126x_IRQ_PIN
#elif defined(TEENSYDUINO)
#define DEFAULT_SX126x_IRQ_PIN (8) //!< DEFAULT_SX126x_IRQ_PIN

View File

@@ -1,7 +1,7 @@
{
"name": "MySensors",
"keywords": "framework, sensor, rf",
"description": "Home Automation Framework. Create your own wireless sensor mesh using nRF24L01+, RFM69 and RFM95 radios running on AVR, ESP32, ESP8266, NRF5x, SAMD, STM32, STM32F1 and Teensyduino. Over-the-air updates and MySensors support by 20+ home automation controllers.",
"description": "Home Automation Framework. Create your own wireless sensor mesh using nRF24L01+, RFM69 and RFM95 radios running on AVR, ESP32, ESP8266, NRF5x, SAMD, STM32 and Teensyduino. Over-the-air updates and MySensors support by 20+ home automation controllers.",
"repository":
{
"type": "git",

View File

@@ -3,7 +3,7 @@ version=2.4.0-alpha
author=The MySensors Team
maintainer=The MySensors Team
sentence=Home Automation Framework
paragraph=Create your own wireless sensor mesh using nRF24L01+, RFM69 and RFM95 radios running on AVR, ESP32, ESP8266, NRF5x, SAMD, STM32, STM32F1 and Teensyduino. Over-the-air updates and MySensors support by 20+ home automation controllers.
paragraph=Create your own wireless sensor mesh using nRF24L01+, RFM69 and RFM95 radios running on AVR, ESP32, ESP8266, NRF5x, SAMD, STM32 and Teensyduino. Over-the-air updates and MySensors support by 20+ home automation controllers.
category=Communication
url=https://www.mysensors.org
architectures=*