diff --git a/mbed-os-to-arduino b/mbed-os-to-arduino index 1c077227a..244ccba80 100755 --- a/mbed-os-to-arduino +++ b/mbed-os-to-arduino @@ -198,15 +198,21 @@ generate_flags () { .pdm_section (NOLOAD) : {\n \ . = ABSOLUTE(0x3800FC00);\n \ *(.pdm_buffer)\n \ - } > RAM_D3" + } > RAM_D3\n \ + _dtcm_lma = __etext + SIZEOF(.data);\n \ + .dtcm : AT(_dtcm_lma) {\n \ + _sdtcm = .;\n \ + *(.dtcm*)\n \ + _edtcm = .;\n \ + } > DTCMRAM" sed -i "s?.heap (COPY):?${OPENAMP_SECTION}\n .heap (COPY):?g" $ARDUINOVARIANT/linker_script.ld OPENAMP_REGIONS="__OPENAMP_region_start__ = 0x38000400;\n__OPENAMP_region_end__ = 0x38000400 + LENGTH(RAM_D3) - 1K;" sed -i "s?ENTRY(Reset_Handler)?${OPENAMP_REGIONS}\nENTRY(Reset_Handler)?g" $ARDUINOVARIANT/linker_script.ld fi echo "Patching linker scripts" sed -i 's/0x8100000/CM4_BINARY_START/g' "$ARDUINOVARIANT"/linker_script.ld - sed -i 's/LENGTH = 0x100000/LENGTH = CM4_BINARY_END - CM4_BINARY_START/g' "$ARDUINOVARIANT"/linker_script.ld - sed -i 's/LENGTH = 0xc0000/LENGTH = CM4_BINARY_START - 0x8040000/g' "$ARDUINOVARIANT"/linker_script.ld + sed -i 's/LENGTH = 0x200000/LENGTH = CM4_BINARY_END - CM4_BINARY_START/g' "$ARDUINOVARIANT"/linker_script.ld + sed -i 's/LENGTH = 0x1c0000/LENGTH = CM4_BINARY_START - 0x8040000/g' "$ARDUINOVARIANT"/linker_script.ld fi if [[ $ARDUINOVARIANT == *NANO_RP2040* ]]; then set +e diff --git a/patches/0175-STM32-lpticker-allow-dynamic-configuration.patch b/patches/0175-STM32-lpticker-allow-dynamic-configuration.patch new file mode 100644 index 000000000..e4d296a2d --- /dev/null +++ b/patches/0175-STM32-lpticker-allow-dynamic-configuration.patch @@ -0,0 +1,194 @@ +From ff38953e8e678c697b52ddbe62bc99fe445a1c74 Mon Sep 17 00:00:00 2001 +From: Martino Facchin +Date: Thu, 7 Oct 2021 17:00:27 +0200 +Subject: [PATCH 175/176] STM32: lpticker: allow dynamic configuration + +Step1: allow automatic fallback to LSI if LSE is not functional +Step2: expose two reconfiguration APIs, so the user can check if LSE is precise enough and eventually revert to LSI +--- + targets/TARGET_STM/lp_ticker.c | 121 ++++++++++++++++++++++----------- + 1 file changed, 83 insertions(+), 38 deletions(-) + +diff --git a/targets/TARGET_STM/lp_ticker.c b/targets/TARGET_STM/lp_ticker.c +index d5292566e5..6dc806ccf6 100644 +--- a/targets/TARGET_STM/lp_ticker.c ++++ b/targets/TARGET_STM/lp_ticker.c +@@ -126,20 +126,35 @@ + + + LPTIM_HandleTypeDef LptimHandle; ++static uint8_t using_lse = MBED_CONF_TARGET_LSE_AVAILABLE; + +-const ticker_info_t *lp_ticker_get_info() ++static const ticker_info_t *lp_ticker_get_info_lse() + { +- static const ticker_info_t info = { +-#if MBED_CONF_TARGET_LSE_AVAILABLE ++ const static ticker_info_t info = { + LSE_VALUE / MBED_CONF_TARGET_LPTICKER_LPTIM_CLOCK, +-#else ++ 16 ++ }; ++ return &info; ++} ++ ++static const ticker_info_t *lp_ticker_get_info_lsi() ++{ ++ const static ticker_info_t info = { + LSI_VALUE / MBED_CONF_TARGET_LPTICKER_LPTIM_CLOCK, +-#endif + 16 + }; + return &info; + } + ++const ticker_info_t *lp_ticker_get_info() ++{ ++ if (using_lse) { ++ return lp_ticker_get_info_lse(); ++ } else { ++ return lp_ticker_get_info_lsi(); ++ } ++} ++ + volatile uint8_t lp_Fired = 0; + /* Flag and stored counter to handle delayed programing at low level */ + volatile bool lp_delayed_prog = false; +@@ -154,71 +169,101 @@ volatile bool sleep_manager_locked = false; + static int LPTICKER_inited = 0; + static void LPTIM_IRQHandler(void); + +-void lp_ticker_init(void) +-{ +- /* Check if LPTIM is already configured */ +- if (LPTICKER_inited) { +- lp_ticker_disable_interrupt(); +- return; +- } +- LPTICKER_inited = 1; +- +- RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0}; +- RCC_OscInitTypeDef RCC_OscInitStruct = {0}; +- +-#if MBED_CONF_TARGET_LSE_AVAILABLE ++static void configureClocksLSE(RCC_PeriphCLKInitTypeDef* RCC_PeriphCLKInitStruct, ++ RCC_OscInitTypeDef* RCC_OscInitStruct){ + + /* Enable LSE clock */ +- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; ++ RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_LSE; + #if MBED_CONF_TARGET_LSE_BYPASS +- RCC_OscInitStruct.LSEState = RCC_LSE_BYPASS; ++ RCC_OscInitStruct->LSEState = RCC_LSE_BYPASS; + #else +- RCC_OscInitStruct.LSEState = RCC_LSE_ON; ++ RCC_OscInitStruct->LSEState = RCC_LSE_ON; + #endif +- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; ++ RCC_OscInitStruct->PLL.PLLState = RCC_PLL_NONE; + + /* Select the LSE clock as LPTIM peripheral clock */ +- RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM; ++ RCC_PeriphCLKInitStruct->PeriphClockSelection = RCC_PERIPHCLK_LPTIM; + #if (TARGET_STM32L0) +- RCC_PeriphCLKInitStruct.LptimClockSelection = RCC_LPTIMCLKSOURCE_LSE; ++ RCC_PeriphCLKInitStruct->LptimClockSelection = RCC_LPTIMCLKSOURCE_LSE; + #else + #if (LPTIM_MST_BASE == LPTIM1_BASE) +- RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIMCLKSOURCE_LSE; ++ RCC_PeriphCLKInitStruct->Lptim1ClockSelection = RCC_LPTIMCLKSOURCE_LSE; + #elif (LPTIM_MST_BASE == LPTIM3_BASE) || (LPTIM_MST_BASE == LPTIM4_BASE) || (LPTIM_MST_BASE == LPTIM5_BASE) +- RCC_PeriphCLKInitStruct.Lptim345ClockSelection = RCC_LPTIMCLKSOURCE_LSE; ++ RCC_PeriphCLKInitStruct->Lptim345ClockSelection = RCC_LPTIMCLKSOURCE_LSE; + #endif /* LPTIM_MST_BASE == LPTIM1 */ + #endif /* TARGET_STM32L0 */ +-#else /* MBED_CONF_TARGET_LSE_AVAILABLE */ ++} ++ ++static void configureClocksLSI(RCC_PeriphCLKInitTypeDef* RCC_PeriphCLKInitStruct, ++ RCC_OscInitTypeDef* RCC_OscInitStruct){ + + /* Enable LSI clock */ + #if TARGET_STM32WB +- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1; ++ RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_LSI1; + #else +- RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; ++ RCC_OscInitStruct->OscillatorType = RCC_OSCILLATORTYPE_LSI; + #endif +- RCC_OscInitStruct.LSIState = RCC_LSI_ON; +- RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; ++ RCC_OscInitStruct->LSIState = RCC_LSI_ON; ++ RCC_OscInitStruct->PLL.PLLState = RCC_PLL_NONE; + + /* Select the LSI clock as LPTIM peripheral clock */ +- RCC_PeriphCLKInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LPTIM; ++ RCC_PeriphCLKInitStruct->PeriphClockSelection = RCC_PERIPHCLK_LPTIM; + #if (TARGET_STM32L0) +- RCC_PeriphCLKInitStruct.LptimClockSelection = RCC_LPTIMCLKSOURCE_LSI; ++ RCC_PeriphCLKInitStruct->LptimClockSelection = RCC_LPTIMCLKSOURCE_LSI; + #else + #if (LPTIM_MST_BASE == LPTIM1_BASE) +- RCC_PeriphCLKInitStruct.Lptim1ClockSelection = RCC_LPTIMCLKSOURCE_LSI; ++ RCC_PeriphCLKInitStruct->Lptim1ClockSelection = RCC_LPTIMCLKSOURCE_LSI; + #elif (LPTIM_MST_BASE == LPTIM3_BASE) || (LPTIM_MST_BASE == LPTIM4_BASE) || (LPTIM_MST_BASE == LPTIM5_BASE) +- RCC_PeriphCLKInitStruct.Lptim345ClockSelection = RCC_LPTIMCLKSOURCE_LSI; ++ RCC_PeriphCLKInitStruct->Lptim345ClockSelection = RCC_LPTIMCLKSOURCE_LSI; + #endif /* LPTIM_MST_BASE == LPTIM1 */ + #endif /* TARGET_STM32L0 */ ++} ++ ++void lp_ticker_reconfigure_with_lsi() { ++ lp_ticker_disable_interrupt(); ++ LPTICKER_inited = 0; ++ using_lse = 0; ++ lp_ticker_init(); ++} ++ ++void lp_ticker_reconfigure_with_lse() { ++ lp_ticker_disable_interrupt(); ++ LPTICKER_inited = 0; ++ using_lse = 1; ++ lp_ticker_init(); ++} ++ ++void lp_ticker_init(void) ++{ ++ /* Check if LPTIM is already configured */ ++ if (LPTICKER_inited) { ++ lp_ticker_disable_interrupt(); ++ return; ++ } ++ LPTICKER_inited = 1; ++ ++ RCC_PeriphCLKInitTypeDef RCC_PeriphCLKInitStruct = {0}; ++ RCC_OscInitTypeDef RCC_OscInitStruct = {0}; ++ ++ if (using_lse) { ++ configureClocksLSE(&RCC_PeriphCLKInitStruct, &RCC_OscInitStruct); ++ } else { ++ configureClocksLSI(&RCC_PeriphCLKInitStruct, &RCC_OscInitStruct); ++ } + +-#endif /* MBED_CONF_TARGET_LSE_AVAILABLE */ + #if defined(DUAL_CORE) && (TARGET_STM32H7) + while (LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) { + } + #endif /* DUAL_CORE */ + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { +- error("HAL_RCC_OscConfig ERROR\n"); +- return; ++ ++ // retry with LSI ++ using_lse = 0; ++ configureClocksLSI(&RCC_PeriphCLKInitStruct, &RCC_OscInitStruct); ++ if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { ++ error("HAL_RCC_OscConfig ERROR\n"); ++ return; ++ } + } + + if (HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphCLKInitStruct) != HAL_OK) { +-- +2.37.1 + diff --git a/patches/0176-Portenta-use-LSE-for-low-power-ticker.patch b/patches/0176-Portenta-use-LSE-for-low-power-ticker.patch new file mode 100644 index 000000000..3f4ef2873 --- /dev/null +++ b/patches/0176-Portenta-use-LSE-for-low-power-ticker.patch @@ -0,0 +1,25 @@ +From 0c7a86e2041971dc3d247c54e85870b6056c03fb Mon Sep 17 00:00:00 2001 +From: Martino Facchin +Date: Thu, 7 Oct 2021 17:02:45 +0200 +Subject: [PATCH 176/176] Portenta: use LSE for low power ticker + +--- + targets/targets.json | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/targets/targets.json b/targets/targets.json +index c998e1d8f0..7274f5d03e 100644 +--- a/targets/targets.json ++++ b/targets/targets.json +@@ -3483,7 +3483,7 @@ + "overrides": { + "system_power_supply": "PWR_SMPS_1V8_SUPPLIES_LDO", + "clock_source": "USE_PLL_HSE_EXTC", +- "lse_available": 0, ++ "lse_available": 1, + "lpticker_delay_ticks": 0, + "network-default-interface-type": "ETHERNET", + "i2c_timing_value_algo": true +-- +2.37.1 + diff --git a/variants/PORTENTA_H7_M7/conf/mbed_app.json b/variants/PORTENTA_H7_M7/conf/mbed_app.json index 6cc069773..5ac9c9bb7 100644 --- a/variants/PORTENTA_H7_M7/conf/mbed_app.json +++ b/variants/PORTENTA_H7_M7/conf/mbed_app.json @@ -22,7 +22,8 @@ "VIRTIO_MASTER_ONLY", "NO_ATOMIC_64_SUPPORT", "METAL_MAX_DEVICE_REGIONS=2", - "RPMSG_BUFFER_SIZE=2048" + "RPMSG_BUFFER_SIZE=2048", + "LSE_STARTUP_TIMEOUT=200" ] } } diff --git a/variants/PORTENTA_H7_M7/variant.cpp b/variants/PORTENTA_H7_M7/variant.cpp index 52cf947e2..f17a33059 100644 --- a/variants/PORTENTA_H7_M7/variant.cpp +++ b/variants/PORTENTA_H7_M7/variant.cpp @@ -235,6 +235,8 @@ void fixup3V1Rail() { i2c.write(8 << 1, data, sizeof(data)); } +extern "C" void lp_ticker_reconfigure_with_lsi(); + void initVariant() { RTCHandle.Instance = RTC; // Turn off LED from bootloader @@ -244,6 +246,19 @@ void initVariant() { // Disable the FMC bank1 (enabled after reset) // See https://github.com/STMicroelectronics/STM32CubeH7/blob/beced99ac090fece04d1e0eb6648b8075e156c6c/Projects/STM32H747I-DISCO/Applications/OpenAMP/OpenAMP_RTOS_PingPong/Common/Src/system_stm32h7xx.c#L215 FMC_Bank1_R->BTCR[0] = 0x000030D2; + // Check that the selected lsi clock is ok + if (__HAL_RCC_GET_LPTIM4_SOURCE() == RCC_LPTIM4CLKSOURCE_LSI) { + // rtc is not mounted, no need to do other actions + return; + } + // Use micros() to check the lptim precision + // if the error is > 1% , reconfigure the clock using lsi + uint32_t start_ms = millis(); + uint32_t start_us = micros(); + while (micros() - start_us < 100000); + if (millis() - start_ms != 100) { + lp_ticker_reconfigure_with_lsi(); + } } #ifdef SERIAL_CDC