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

Reply via email to