This is an automated email from the ASF dual-hosted git repository. jerzy pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push: new 03f4a508b hw/mcu/stm32: Add option to place WFI in RAM 03f4a508b is described below commit 03f4a508b5126e110183ddf5e22dc57d8656fd18 Author: Jerzy Kasenberg <jerzy.kasenb...@codecoup.pl> AuthorDate: Sun May 26 12:41:07 2024 +0200 hw/mcu/stm32: Add option to place WFI in RAM Some STM32 devices have erratas for flash related issues that recommend workaround of placing WFI instruction in RAM. This is the case for STM32F4xx devices where other solution was to put WFI instruction at specific address locations (divisible by 8). New syscfg value STM32_WFI_FROM_RAM is introduced that adds function stm32_wfi_from_ram(). STM32_WFI is also added and can be used instead of WFI when needed BSP for affected STM32F4xx devices now use WFI from RAM instead of placing WFI instruction at aligne address. STM32L0 devices are also updated since anomally was also observed there. Signed-off-by: Jerzy Kasenberg <je...@apache.org> --- hw/bsp/ada_feather_stm32f405/syscfg.yml | 1 + hw/bsp/b-l072z-lrwan1/syscfg.yml | 1 + hw/bsp/black_vet6/syscfg.yml | 1 + hw/bsp/nucleo-l073rz/syscfg.yml | 1 + hw/bsp/olimex_stm32-e407_devboard/syscfg.yml | 1 + hw/mcu/stm/stm32_common/include/stm32_common/mcu.h | 7 ++++ hw/mcu/stm/stm32_common/src/hal_os_tick.c | 39 +++++++++------------- hw/mcu/stm/stm32_common/syscfg.yml | 6 ++++ 8 files changed, 33 insertions(+), 24 deletions(-) diff --git a/hw/bsp/ada_feather_stm32f405/syscfg.yml b/hw/bsp/ada_feather_stm32f405/syscfg.yml index 3e0ff7546..fc9fcd2fc 100644 --- a/hw/bsp/ada_feather_stm32f405/syscfg.yml +++ b/hw/bsp/ada_feather_stm32f405/syscfg.yml @@ -48,6 +48,7 @@ syscfg.vals: STM32_FLASH_PREFETCH_ENABLE: 1 STM32_INSTRUCTION_CACHE_ENABLE: 1 STM32_DATA_CACHE_ENABLE: 1 + STM32_WFI_FROM_RAM: 1 WATCHDOG_INTERVAL: 28000 # UART0 is on the large breakout connector, pins TX and RX. UART_0_PIN_TX: 'MCU_GPIO_PORTB(10)' diff --git a/hw/bsp/b-l072z-lrwan1/syscfg.yml b/hw/bsp/b-l072z-lrwan1/syscfg.yml index ca61b36b6..c893b7f7b 100644 --- a/hw/bsp/b-l072z-lrwan1/syscfg.yml +++ b/hw/bsp/b-l072z-lrwan1/syscfg.yml @@ -51,6 +51,7 @@ syscfg.vals: STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1' STM32_FLASH_LATENCY: 1 # max 32MHz STM32_FLASH_PREFETCH_ENABLE: 0 + STM32_WFI_FROM_RAM: 1 WATCHDOG_INTERVAL: 25000 UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)' UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)' diff --git a/hw/bsp/black_vet6/syscfg.yml b/hw/bsp/black_vet6/syscfg.yml index e5653b1a0..82335b00a 100644 --- a/hw/bsp/black_vet6/syscfg.yml +++ b/hw/bsp/black_vet6/syscfg.yml @@ -64,6 +64,7 @@ syscfg.vals: STM32_FLASH_PREFETCH_ENABLE: 1 STM32_INSTRUCTION_CACHE_ENABLE: 1 STM32_DATA_CACHE_ENABLE: 1 + STM32_WFI_FROM_RAM: 1 WATCHDOG_INTERVAL: 25000 SPI_0_MASTER: 1 diff --git a/hw/bsp/nucleo-l073rz/syscfg.yml b/hw/bsp/nucleo-l073rz/syscfg.yml index a964b30ff..fa2678abe 100644 --- a/hw/bsp/nucleo-l073rz/syscfg.yml +++ b/hw/bsp/nucleo-l073rz/syscfg.yml @@ -57,6 +57,7 @@ syscfg.vals: STM32_CLOCK_APB2_DIVIDER: 'RCC_HCLK_DIV1' STM32_FLASH_LATENCY: 1 # max 32MHz STM32_FLASH_PREFETCH_ENABLE: 0 + STM32_WFI_FROM_RAM: 1 WATCHDOG_INTERVAL: 25000 UART_0_PIN_TX: 'MCU_GPIO_PORTA(2)' UART_0_PIN_RX: 'MCU_GPIO_PORTA(3)' diff --git a/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml b/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml index 27cc90cce..e6fb90f58 100644 --- a/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml +++ b/hw/bsp/olimex_stm32-e407_devboard/syscfg.yml @@ -48,6 +48,7 @@ syscfg.vals: STM32_FLASH_PREFETCH_ENABLE: 1 STM32_INSTRUCTION_CACHE_ENABLE: 1 STM32_DATA_CACHE_ENABLE: 1 + STM32_WFI_FROM_RAM: 1 WATCHDOG_INTERVAL: 28000 UART_0_PIN_TX: 'MCU_GPIO_PORTC(6)' UART_0_PIN_RX: 'MCU_GPIO_PORTC(7)' diff --git a/hw/mcu/stm/stm32_common/include/stm32_common/mcu.h b/hw/mcu/stm/stm32_common/include/stm32_common/mcu.h index b0612b58f..a6c67fe21 100644 --- a/hw/mcu/stm/stm32_common/include/stm32_common/mcu.h +++ b/hw/mcu/stm/stm32_common/include/stm32_common/mcu.h @@ -108,6 +108,13 @@ extern "C" { void stm32_start_bootloader(void); +#if MYNEWT_VAL_STM32_WFI_FROM_RAM +extern void stm32_wfi_from_ram(void); +#define STM32_WFI stm32_wfi_from_ram +#else +#define STM32_WFI __WFI +#endif + #ifdef __cplusplus } #endif diff --git a/hw/mcu/stm/stm32_common/src/hal_os_tick.c b/hw/mcu/stm/stm32_common/src/hal_os_tick.c index fa7d14fda..4a2869078 100644 --- a/hw/mcu/stm/stm32_common/src/hal_os_tick.c +++ b/hw/mcu/stm/stm32_common/src/hal_os_tick.c @@ -18,7 +18,8 @@ */ #include <assert.h> -#include "os/mynewt.h" +#include <os/mynewt.h> +#include <stm32_common/mcu.h> #include <hal/hal_os_tick.h> #if MYNEWT_VAL(OS_TICKS_USE_RTC) @@ -26,33 +27,23 @@ #include <datetime/datetime.h> #endif +#if MYNEWT_VAL(STM32_WFI_FROM_RAM) +__attribute__((section(".text_ram"))) void +stm32_wfi_from_ram(void) +{ + __ASM volatile ("wfi\n" + "bx lr"); +} +#endif + /* * ST's MCUs seems to have problem with accessing AHB interface from SWD during SLEEP. * This makes it almost impossible to use with SEGGER SystemView, therefore when OS_SYSVIEW * is defined __WFI will become a loop waiting for pending interrupts. */ #if MYNEWT_VAL(OS_SYSVIEW) -#undef __WFI -#define __WFI() do { } while ((SCB->ICSR & (SCB_ICSR_ISRPENDING_Msk | SCB_ICSR_PENDSTSET_Msk)) == 0) -#else -/* - * Errata for STM32F405, STM32F407, STM32F415, STM32F417. - * When WFI instruction is placed at address like 0x080xxxx4 - * (also seen for addresses ending with xxx2). System may - * crash. - * __WFI function places WFI instruction at address ending with x0 or x8 - * for affected MCUs. - */ -#if defined(STM32F405xx) || defined(STM32F407xx) || \ - defined(STM32F415xx) || defined(STM32F417xx) -#undef __WFI -__attribute__((aligned(8), naked)) void static -__WFI(void) -{ - __ASM volatile("wfi\n" - "bx lr"); -} -#endif +#undef STM32_WFI +#define STM32_WFI() do { } while ((SCB->ICSR & (SCB_ICSR_ISRPENDING_Msk | SCB_ICSR_PENDSTSET_Msk)) == 0) #endif #if MYNEWT_VAL(OS_TICKS_USE_RTC) @@ -219,7 +210,7 @@ os_tick_idle(os_time_t ticks) } __DSB(); - __WFI(); + STM32_WFI(); if (ticks > 0) { rtc_update_time(); @@ -389,7 +380,7 @@ os_tick_idle(os_time_t ticks) { OS_ASSERT_CRITICAL(); __DSB(); - __WFI(); + STM32_WFI(); } void diff --git a/hw/mcu/stm/stm32_common/syscfg.yml b/hw/mcu/stm/stm32_common/syscfg.yml index eeef9d7a0..1603bced6 100644 --- a/hw/mcu/stm/stm32_common/syscfg.yml +++ b/hw/mcu/stm/stm32_common/syscfg.yml @@ -466,5 +466,11 @@ syscfg.defs: When enabled, OS_TICKS_PER_SEC should be one of 128, 256, 512, 1024. value: 0 + STM32_WFI_FROM_RAM: + description: > + Place WFI instruction in RAM instead of flash. + This may be needed for several MCU's including STM32F40x. + value: + syscfg.vals: OS_TICKS_PER_SEC: 1000