From feaa789c34013034358895dd22018f718f0f3df6 Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Thu, 23 Nov 2017 15:33:02 +0100 Subject: [PATCH 1/8] STM32 LOW_POWER_TIMER update : targets.json Move LSI configuration from macro to config part Add missing boards to the LPT supported targets --- targets/targets.json | 53 +++++++++++++++++++++++++++++++++----------- 1 file changed, 40 insertions(+), 13 deletions(-) mode change 100755 => 100644 targets/targets.json diff --git a/targets/targets.json b/targets/targets.json old mode 100755 new mode 100644 index f6d3f95f782..958f72df8d7 --- a/targets/targets.json +++ b/targets/targets.json @@ -772,10 +772,15 @@ "help": "Mask value : USE_PLL_HSE_EXTC (need HW patch) | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - } + }, + "rtc_lsi": { + "help": "Use internal low speed clock (default clock is LSE)", + "value": "1", + "macro_name": "RTC_LSI" + } }, "detect_code": ["0791"], - "macros_add": ["RTC_LSI=1", "CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""], + "macros_add": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""], "device_has_add": ["SERIAL_FC"], "default_lib": "small", "release_versions": ["2"], @@ -792,10 +797,15 @@ "help": "Mask value : USE_PLL_HSE_EXTC (need HW patch) | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - } + }, + "rtc_lsi": { + "help": "Use internal low speed clock (default clock is LSE)", + "value": "1", + "macro_name": "RTC_LSI" + } }, "detect_code": ["0785"], - "macros_add": ["RTC_LSI=1", "CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""], + "macros_add": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""], "device_has_add": ["CAN", "SERIAL_FC"], "default_lib": "small", "release_versions": ["2"], @@ -924,13 +934,17 @@ "supported_form_factors": ["ARDUINO"], "core": "Cortex-M4F", "extra_labels_add": ["STM32F3", "STM32F303x8", "STM32F303K8"], - "macros_add": ["RTC_LSI=1"], "config": { "clock_source": { "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - } + }, + "rtc_lsi": { + "help": "Use internal low speed clock (default clock is LSE)", + "value": "1", + "macro_name": "RTC_LSI" + } }, "detect_code": ["0775"], "default_lib": "small", @@ -1004,7 +1018,7 @@ }, "detect_code": ["0720"], "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], - "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "FLASH"], + "device_has_add": ["SERIAL_ASYNCH", "SERIAL_FC", "FLASH", "LOWPOWERTIMER"], "release_versions": ["2", "5"], "device_name": "STM32F401RE" }, @@ -1488,13 +1502,17 @@ "inherits": ["FAMILY_STM32"], "core": "Cortex-M4F", "extra_labels_add": ["STM32F3", "STM32F334x8","STM32F334C8"], - "macros_add": ["RTC_LSI=1"], "config": { "clock_source": { "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - } + }, + "rtc_lsi": { + "help": "Use internal low speed clock (default clock is LSE)", + "value": "1", + "macro_name": "RTC_LSI" + } }, "detect_code": ["0810"], "device_has_add": ["ANALOGOUT", "LOWPOWERTIMER", "SERIAL_ASYNCH", "SERIAL_FC"], @@ -1525,9 +1543,14 @@ "help": "As 48 Mhz clock is configured for USB, SYSCLK has to be reduced from 180 to 168 MHz (set 0 for the max SYSCLK value)", "value": "1", "macro_name": "CLOCK_SOURCE_USB" - } + }, + "rtc_lsi": { + "help": "Use internal low speed clock (default clock is LSE)", + "value": "1", + "macro_name": "RTC_LSI" + } }, - "macros_add": ["RTC_LSI=1", "USB_STM_HAL", "USBHOST_OTHER"], + "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH"], "release_versions": ["2", "5"], "device_name": "STM32F429ZI", @@ -1555,13 +1578,17 @@ "inherits": ["FAMILY_STM32"], "core": "Cortex-M0+", "extra_labels_add": ["STM32L0", "STM32L053x8", "STM32L053C8"], - "macros": ["RTC_LSI=1"], "config": { "clock_source": { "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - } + }, + "rtc_lsi": { + "help": "Use internal low speed clock (default clock is LSE)", + "value": "1", + "macro_name": "RTC_LSI" + } }, "device_has_add": ["ANALOGOUT", "LOWPOWERTIMER", "SERIAL_FC", "FLASH"], "default_lib": "small", From b65e861b20ba30207458f34e28103b1c8aea727a Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Tue, 7 Nov 2017 17:18:09 +0100 Subject: [PATCH 2/8] STM32 LOW_POWER_TIMER update : lp_ticker Removed unnecessary part --- targets/TARGET_STM/lp_ticker.c | 17 +++-------------- targets/TARGET_STM/rtc_api_hal.h | 11 ++--------- 2 files changed, 5 insertions(+), 23 deletions(-) diff --git a/targets/TARGET_STM/lp_ticker.c b/targets/TARGET_STM/lp_ticker.c index 689833ffcd6..dfe84aff752 100644 --- a/targets/TARGET_STM/lp_ticker.c +++ b/targets/TARGET_STM/lp_ticker.c @@ -1,6 +1,6 @@ /* mbed Microcontroller Library ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics + * Copyright (c) 2017, STMicroelectronics * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,20 +31,11 @@ #if DEVICE_LOWPOWERTIMER -#include "ticker_api.h" -#include "lp_ticker_api.h" -#include "rtc_api.h" #include "rtc_api_hal.h" -static uint8_t lp_ticker_inited = 0; - void lp_ticker_init(void) { - if (lp_ticker_inited) return; - lp_ticker_inited = 1; - rtc_init(); - rtc_set_irq_handler((uint32_t) lp_ticker_irq_handler); } uint32_t lp_ticker_read(void) @@ -52,8 +43,6 @@ uint32_t lp_ticker_read(void) uint32_t usecs = 0; time_t time = 0; - lp_ticker_init(); - do { time = rtc_read(); usecs = rtc_read_subseconds(); @@ -82,7 +71,7 @@ void lp_ticker_disable_interrupt(void) void lp_ticker_clear_interrupt(void) { - + NVIC_ClearPendingIRQ(RTC_WKUP_IRQn); } -#endif +#endif /* DEVICE_LOWPOWERTIMER */ diff --git a/targets/TARGET_STM/rtc_api_hal.h b/targets/TARGET_STM/rtc_api_hal.h index 14a345438d3..313b0dbd788 100644 --- a/targets/TARGET_STM/rtc_api_hal.h +++ b/targets/TARGET_STM/rtc_api_hal.h @@ -33,19 +33,12 @@ #include #include "rtc_api.h" +#include "ticker_api.h" +#include "lp_ticker_api.h" #ifdef __cplusplus extern "C" { #endif -/* - * Extend rtc_api.h - */ - -/** Set the given function as handler of wakeup timer event. - * - * @param handler The function to set as handler - */ -void rtc_set_irq_handler(uint32_t handler); /** Read the subsecond register. * From 0bf364ea555ab3768d33610b8cb98e14b735911d Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Tue, 7 Nov 2017 17:24:34 +0100 Subject: [PATCH 3/8] STM32 LOW_POWER_TIMER update : rtc_api.c Add RSF synchro during init Set a better WakeUp clock for long wake up period in order to stay in sleep mode Use rtc_isenabled function before init as rtc_init is called at each set_time call --- targets/TARGET_STM/rtc_api.c | 108 +++++++++++++++++-------------- targets/TARGET_STM/rtc_api_hal.h | 8 ++- 2 files changed, 68 insertions(+), 48 deletions(-) diff --git a/targets/TARGET_STM/rtc_api.c b/targets/TARGET_STM/rtc_api.c index 23f7625012b..ab3087df6d7 100644 --- a/targets/TARGET_STM/rtc_api.c +++ b/targets/TARGET_STM/rtc_api.c @@ -1,6 +1,6 @@ /* mbed Microcontroller Library ******************************************************************************* - * Copyright (c) 2016, STMicroelectronics + * Copyright (c) 2017, STMicroelectronics * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,29 +27,23 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************* */ + #if DEVICE_RTC -#include "rtc_api.h" #include "rtc_api_hal.h" #include "mbed_error.h" #include "mbed_mktime.h" static RTC_HandleTypeDef RtcHandle; -#if RTC_LSI -#define RTC_CLOCK LSI_VALUE -#else -#define RTC_CLOCK LSE_VALUE -#endif - #if DEVICE_LOWPOWERTIMER #define RTC_ASYNCH_PREDIV ((RTC_CLOCK - 1) / 0x8000) -#define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1) #else #define RTC_ASYNCH_PREDIV (0x007F) -#define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1) #endif +#define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1) + #if DEVICE_LOWPOWERTIMER static void (*irq_handler)(void); static void RTC_IRQHandler(void); @@ -63,28 +57,29 @@ void rtc_init(void) // Enable access to Backup domain HAL_PWR_EnableBkUpAccess(); - RtcHandle.Instance = RTC; - RtcHandle.State = HAL_RTC_STATE_RESET; - -#if !RTC_LSI +#if !RTC_LSI /* => LSE */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.LSIState = RCC_LSI_OFF; - if (HAL_RCC_OscConfig(&RCC_OscInitStruct) == HAL_OK) { - __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE); - __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); - } else { + if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { error("Cannot initialize RTC with LSE\n"); } + __HAL_RCC_RTC_CLKPRESCALER(RCC_RTCCLKSOURCE_LSE); + __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE); + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { error("PeriphClkInitStruct RTC failed with LSE\n"); } -#else /* !RTC_LSI */ + + if (rtc_isenabled()) return; +#else /* => RTC_LSI */ + if (rtc_isenabled()) return; + __HAL_RCC_PWR_CLK_ENABLE(); // Reset Backup domain @@ -113,6 +108,9 @@ void rtc_init(void) // Enable RTC __HAL_RCC_RTC_ENABLE(); + RtcHandle.Instance = RTC; + RtcHandle.State = HAL_RTC_STATE_RESET; + #if TARGET_STM32F1 RtcHandle.Init.AsynchPrediv = RTC_AUTO_1_SECOND; #else /* TARGET_STM32F1 */ @@ -125,24 +123,14 @@ void rtc_init(void) #endif /* TARGET_STM32F1 */ if (HAL_RTC_Init(&RtcHandle) != HAL_OK) { - error("RTC error: RTC initialization failed."); + error("RTC initialization failed"); } -#if DEVICE_LOWPOWERTIMER + rtc_synchronize(); // Wait for RSF -#if !RTC_LSI - if (!rtc_isenabled()) -#endif /* !RTC_LSI */ - { + if (!rtc_isenabled()) { rtc_write(0); } - - NVIC_ClearPendingIRQ(RTC_WKUP_IRQn); - NVIC_DisableIRQ(RTC_WKUP_IRQn); - NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)RTC_IRQHandler); - NVIC_EnableIRQ(RTC_WKUP_IRQn); - -#endif /* DEVICE_LOWPOWERTIMER */ } void rtc_free(void) @@ -279,8 +267,12 @@ void rtc_write(time_t t) #endif /* TARGET_STM32F1 */ // Change the RTC current date/time - HAL_RTC_SetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN); - HAL_RTC_SetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN); + if (HAL_RTC_SetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN) != HAL_OK) { + printf("HAL_RTC_SetDate error\n"); + } + if (HAL_RTC_SetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN) != HAL_OK) { + printf("HAL_RTC_SetTime error\n"); + } } int rtc_isenabled(void) @@ -292,6 +284,13 @@ int rtc_isenabled(void) #endif /* TARGET_STM32F1 */ } +void rtc_synchronize(void) +{ + if (HAL_RTC_WaitForSynchro(&RtcHandle) != HAL_OK) { + error("rtc_synchronize error\n"); + } +} + #if DEVICE_LOWPOWERTIMER static void RTC_IRQHandler(void) @@ -304,11 +303,6 @@ static void RTC_IRQHandler(void) } } -void rtc_set_irq_handler(uint32_t handler) -{ - irq_handler = (void (*)(void))handler; -} - uint32_t rtc_read_subseconds(void) { return 1000000.f * ((double)(RTC_SYNCH_PREDIV - RTC->SSR) / (RTC_SYNCH_PREDIV + 1)); @@ -316,11 +310,35 @@ uint32_t rtc_read_subseconds(void) void rtc_set_wake_up_timer(uint32_t delta) { - uint32_t wake_up_counter = delta / (2000000 / RTC_CLOCK); + /* Ex for Wakeup period resolution with RTCCLK=32768 Hz : + * RTCCLK_DIV2: ~122us < wakeup period < ~4s + * RTCCLK_DIV4: ~244us < wakeup period < ~8s + * RTCCLK_DIV8: ~488us < wakeup period < ~16s + * RTCCLK_DIV16: ~976us < wakeup period < ~32s + * CK_SPRE_16BITS: 1s < wakeup period < (0xFFFF+ 1) x 1 s = 65536 s (18 hours) + * CK_SPRE_17BITS: 18h+1s < wakeup period < (0x1FFFF+ 1) x 1 s = 131072 s (36 hours) + */ + uint32_t WakeUpClock[6] = {RTC_WAKEUPCLOCK_RTCCLK_DIV2, RTC_WAKEUPCLOCK_RTCCLK_DIV4, RTC_WAKEUPCLOCK_RTCCLK_DIV8, RTC_WAKEUPCLOCK_RTCCLK_DIV16, RTC_WAKEUPCLOCK_CK_SPRE_16BITS, RTC_WAKEUPCLOCK_CK_SPRE_17BITS}; + uint8_t ClockDiv[4] = {2, 4, 8, 16}; + uint32_t WakeUpCounter; + uint8_t DivIndex = 0; + + do { + WakeUpCounter = delta / (ClockDiv[DivIndex] * 1000000 / RTC_CLOCK); + DivIndex++; + } while ( (WakeUpCounter > 0xFFFF) && (DivIndex < 4) ); + + if (WakeUpCounter > 0xFFFF) { + WakeUpCounter = delta / 1000000; + DivIndex++; + } - if (HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, wake_up_counter, - RTC_WAKEUPCLOCK_RTCCLK_DIV2) != HAL_OK) { - error("Set wake up timer failed\n"); + irq_handler = (void (*)(void))lp_ticker_irq_handler; + NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)RTC_IRQHandler); + NVIC_EnableIRQ(RTC_WKUP_IRQn); + + if (HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, 0xFFFF & WakeUpCounter, WakeUpClock[DivIndex-1]) != HAL_OK) { + error("rtc_set_wake_up_timer init error (%d)\n", DivIndex); } } @@ -329,10 +347,6 @@ void rtc_deactivate_wake_up_timer(void) HAL_RTCEx_DeactivateWakeUpTimer(&RtcHandle); } -void rtc_synchronize(void) -{ - HAL_RTC_WaitForSynchro(&RtcHandle); -} #endif /* DEVICE_LOWPOWERTIMER */ #endif /* DEVICE_RTC */ diff --git a/targets/TARGET_STM/rtc_api_hal.h b/targets/TARGET_STM/rtc_api_hal.h index 313b0dbd788..fc66ab740cc 100644 --- a/targets/TARGET_STM/rtc_api_hal.h +++ b/targets/TARGET_STM/rtc_api_hal.h @@ -1,6 +1,6 @@ /* mbed Microcontroller Library ******************************************************************************* -* Copyright (c) 2016, STMicroelectronics +* Copyright (c) 2017, STMicroelectronics * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,6 +40,12 @@ extern "C" { #endif +#if RTC_LSI +#define RTC_CLOCK LSI_VALUE +#else +#define RTC_CLOCK LSE_VALUE +#endif + /** Read the subsecond register. * * @return The remaining time as microseconds (0-999999) From c13ffaf4778d8e64c3ccf9c2874b32e2d2966cba Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Tue, 7 Nov 2017 17:50:56 +0100 Subject: [PATCH 4/8] STM32 LOW_POWER_TIMER update : sleep RSF synchro after deepsleep is not specific to Low Power Timer feature And we have to check if RTC is configured before synchro --- targets/TARGET_STM/sleep.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/targets/TARGET_STM/sleep.c b/targets/TARGET_STM/sleep.c index d41edfe5b74..fb232ec8b78 100644 --- a/targets/TARGET_STM/sleep.c +++ b/targets/TARGET_STM/sleep.c @@ -68,16 +68,16 @@ void hal_deepsleep(void) #if TARGET_STM32L4 int pwrClockEnabled = __HAL_RCC_PWR_IS_CLK_ENABLED(); int lowPowerModeEnabled = PWR->CR1 & PWR_CR1_LPR; - + if (!pwrClockEnabled) { __HAL_RCC_PWR_CLK_ENABLE(); } if (lowPowerModeEnabled) { HAL_PWREx_DisableLowPowerRunMode(); } - + HAL_PWREx_EnterSTOP2Mode(PWR_STOPENTRY_WFI); - + if (lowPowerModeEnabled) { HAL_PWREx_EnableLowPowerRunMode(); } @@ -101,8 +101,15 @@ void hal_deepsleep(void) TimMasterHandle.Instance = TIM_MST; __HAL_TIM_SET_COUNTER(&TimMasterHandle, EnterTimeUS); -#if DEVICE_LOWPOWERTIMER - rtc_synchronize(); +#if DEVICE_RTC + /* Wait for RTC RSF bit synchro if RTC is configured */ +#if (TARGET_STM32F2) || (TARGET_STM32F4) || (TARGET_STM32F7) + if (READ_BIT(RCC->BDCR, RCC_BDCR_RTCSEL)) { +#else /* (TARGET_STM32F2) || (TARGET_STM32F4) || (TARGET_STM32F7) */ + if (__HAL_RCC_GET_RTC_SOURCE()) { +#endif /* (TARGET_STM32F2) || (TARGET_STM32F4) || (TARGET_STM32F7) */ + rtc_synchronize(); + } #endif } From 85c337d0b9266d58e4530e529de297b2a88ef2e9 Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Fri, 17 Nov 2017 12:11:22 +0100 Subject: [PATCH 5/8] STM32 LOW_POWER_TIMER update : rtc_init procedure --- targets/TARGET_STM/rtc_api.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/targets/TARGET_STM/rtc_api.c b/targets/TARGET_STM/rtc_api.c index ab3087df6d7..eea48c02aee 100644 --- a/targets/TARGET_STM/rtc_api.c +++ b/targets/TARGET_STM/rtc_api.c @@ -55,8 +55,13 @@ void rtc_init(void) RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; // Enable access to Backup domain + __HAL_RCC_PWR_CLK_ENABLE(); HAL_PWR_EnableBkUpAccess(); + if (rtc_isenabled()) { + return; + } + #if !RTC_LSI /* => LSE */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! @@ -76,12 +81,7 @@ void rtc_init(void) error("PeriphClkInitStruct RTC failed with LSE\n"); } - if (rtc_isenabled()) return; #else /* => RTC_LSI */ - if (rtc_isenabled()) return; - - __HAL_RCC_PWR_CLK_ENABLE(); - // Reset Backup domain __HAL_RCC_BACKUPRESET_FORCE(); __HAL_RCC_BACKUPRESET_RELEASE(); From 354ed44a65ee7a6a765a497c7ca4423e3f28f108 Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Fri, 17 Nov 2017 13:07:19 +0100 Subject: [PATCH 6/8] STM32 LOW_POWER_TIMER update : use error --- targets/TARGET_STM/rtc_api.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/targets/TARGET_STM/rtc_api.c b/targets/TARGET_STM/rtc_api.c index eea48c02aee..1b1cb83fc4a 100644 --- a/targets/TARGET_STM/rtc_api.c +++ b/targets/TARGET_STM/rtc_api.c @@ -268,10 +268,10 @@ void rtc_write(time_t t) // Change the RTC current date/time if (HAL_RTC_SetDate(&RtcHandle, &dateStruct, RTC_FORMAT_BIN) != HAL_OK) { - printf("HAL_RTC_SetDate error\n"); + error("HAL_RTC_SetDate error\n"); } if (HAL_RTC_SetTime(&RtcHandle, &timeStruct, RTC_FORMAT_BIN) != HAL_OK) { - printf("HAL_RTC_SetTime error\n"); + error("HAL_RTC_SetTime error\n"); } } From 01b2b1baf339713dcfd30c8c0c134e229fce5775 Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Mon, 4 Dec 2017 14:00:30 +0100 Subject: [PATCH 7/8] STM32: RTC_LSI macro is replaced by lse_available config --- targets/TARGET_STM/rtc_api.c | 13 +++--- targets/TARGET_STM/rtc_api_hal.h | 6 +-- targets/targets.json | 69 +++++++++++++------------------- 3 files changed, 36 insertions(+), 52 deletions(-) diff --git a/targets/TARGET_STM/rtc_api.c b/targets/TARGET_STM/rtc_api.c index 1b1cb83fc4a..b488e2aaa08 100644 --- a/targets/TARGET_STM/rtc_api.c +++ b/targets/TARGET_STM/rtc_api.c @@ -62,8 +62,8 @@ void rtc_init(void) return; } -#if !RTC_LSI /* => LSE */ - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE; +#if MBED_CONF_TARGET_LSE_AVAILABLE + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.LSIState = RCC_LSI_OFF; @@ -80,14 +80,13 @@ void rtc_init(void) if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { error("PeriphClkInitStruct RTC failed with LSE\n"); } - -#else /* => RTC_LSI */ +#else /* MBED_CONF_TARGET_LSE_AVAILABLE */ // Reset Backup domain __HAL_RCC_BACKUPRESET_FORCE(); __HAL_RCC_BACKUPRESET_RELEASE(); // Enable LSI clock - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; // Mandatory, otherwise the PLL is reconfigured! RCC_OscInitStruct.LSEState = RCC_LSE_OFF; RCC_OscInitStruct.LSIState = RCC_LSI_ON; @@ -103,7 +102,7 @@ void rtc_init(void) if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { error("PeriphClkInitStruct RTC failed with LSI\n"); } -#endif /* !RTC_LSI */ +#endif /* MBED_CONF_TARGET_LSE_AVAILABLE */ // Enable RTC __HAL_RCC_RTC_ENABLE(); @@ -135,7 +134,7 @@ void rtc_init(void) void rtc_free(void) { -#if RTC_LSI +#if !MBED_CONF_TARGET_LSE_AVAILABLE // Enable Power clock __HAL_RCC_PWR_CLK_ENABLE(); diff --git a/targets/TARGET_STM/rtc_api_hal.h b/targets/TARGET_STM/rtc_api_hal.h index fc66ab740cc..ca948ca36b0 100644 --- a/targets/TARGET_STM/rtc_api_hal.h +++ b/targets/TARGET_STM/rtc_api_hal.h @@ -40,10 +40,10 @@ extern "C" { #endif -#if RTC_LSI -#define RTC_CLOCK LSI_VALUE -#else +#if MBED_CONF_TARGET_LSE_AVAILABLE #define RTC_CLOCK LSE_VALUE +#else +#define RTC_CLOCK LSI_VALUE #endif /** Read the subsecond register. diff --git a/targets/targets.json b/targets/targets.json index 958f72df8d7..cbb87813b62 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -706,6 +706,12 @@ "extra_labels": ["STM"], "supported_toolchains": ["ARM", "uARM", "IAR", "GCC_ARM"], "macros": ["TRANSACTION_QUEUE_SIZE_SPI=2"], + "config": { + "lse_available": { + "help": "Define if a Low Speed External xtal (LSE) is available on the board (0 = No, 1 = Yes). If Yes, the LSE will be used to clock the RTC, LPUART, ... otherwise the Low Speed Internal clock (LSI) will be used", + "value": "1" + } + }, "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "I2C_ASYNCH", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"] }, "LPC54114": { @@ -772,14 +778,10 @@ "help": "Mask value : USE_PLL_HSE_EXTC (need HW patch) | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - }, - "rtc_lsi": { - "help": "Use internal low speed clock (default clock is LSE)", - "value": "1", - "macro_name": "RTC_LSI" - } + } }, "detect_code": ["0791"], + "overrides": {"lse_available": 0}, "macros_add": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""], "device_has_add": ["SERIAL_FC"], "default_lib": "small", @@ -797,14 +799,10 @@ "help": "Mask value : USE_PLL_HSE_EXTC (need HW patch) | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - }, - "rtc_lsi": { - "help": "Use internal low speed clock (default clock is LSE)", - "value": "1", - "macro_name": "RTC_LSI" - } + } }, "detect_code": ["0785"], + "overrides": {"lse_available": 0}, "macros_add": ["CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\""], "device_has_add": ["CAN", "SERIAL_FC"], "default_lib": "small", @@ -939,13 +937,9 @@ "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - }, - "rtc_lsi": { - "help": "Use internal low speed clock (default clock is LSE)", - "value": "1", - "macro_name": "RTC_LSI" - } + } }, + "overrides": {"lse_available": 0}, "detect_code": ["0775"], "default_lib": "small", "device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_FC"], @@ -1493,7 +1487,7 @@ "inherits": ["FAMILY_STM32"], "core": "Cortex-M4F", "extra_labels_add": ["STM32F3", "STM32F303", "STM32F303xC", "STM32F303VC"], - "macros_add": ["RTC_LSI=1"], + "overrides": {"lse_available": 0}, "supported_toolchains": ["GCC_ARM"], "device_has_add": ["ANALOGOUT", "CAN", "LOWPOWERTIMER", "SERIAL_FC"], "device_name": "STM32F303VC" @@ -1507,13 +1501,9 @@ "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - }, - "rtc_lsi": { - "help": "Use internal low speed clock (default clock is LSE)", - "value": "1", - "macro_name": "RTC_LSI" - } + } }, + "overrides": {"lse_available": 0}, "detect_code": ["0810"], "device_has_add": ["ANALOGOUT", "LOWPOWERTIMER", "SERIAL_ASYNCH", "SERIAL_FC"], "default_lib": "small", @@ -1525,7 +1515,8 @@ "core": "Cortex-M4F", "extra_labels_add": ["STM32F4", "STM32F407", "STM32F407xG", "STM32F407VG"], "supported_toolchains": ["ARM", "uARM", "GCC_ARM"], - "macros_add": ["RTC_LSI=1", "USB_STM_HAL"], + "macros_add": ["USB_STM_HAL"], + "overrides": {"lse_available": 0}, "device_has_add": ["ANALOGOUT"], "device_name": "STM32F407VG" }, @@ -1543,13 +1534,9 @@ "help": "As 48 Mhz clock is configured for USB, SYSCLK has to be reduced from 180 to 168 MHz (set 0 for the max SYSCLK value)", "value": "1", "macro_name": "CLOCK_SOURCE_USB" - }, - "rtc_lsi": { - "help": "Use internal low speed clock (default clock is LSE)", - "value": "1", - "macro_name": "RTC_LSI" - } + } }, + "overrides": {"lse_available": 0}, "macros_add": ["USB_STM_HAL", "USBHOST_OTHER"], "device_has_add": ["ANALOGOUT", "CAN", "SERIAL_ASYNCH", "SERIAL_FC", "TRNG", "FLASH"], "release_versions": ["2", "5"], @@ -1583,13 +1570,9 @@ "help": "Mask value : USE_PLL_HSE_EXTC | USE_PLL_HSE_XTAL (need HW patch) | USE_PLL_HSI", "value": "USE_PLL_HSE_EXTC|USE_PLL_HSI", "macro_name": "CLOCK_SOURCE" - }, - "rtc_lsi": { - "help": "Use internal low speed clock (default clock is LSE)", - "value": "1", - "macro_name": "RTC_LSI" - } + } }, + "overrides": {"lse_available": 0}, "device_has_add": ["ANALOGOUT", "LOWPOWERTIMER", "SERIAL_FC", "FLASH"], "default_lib": "small", "release_versions": ["2"], @@ -1728,7 +1711,8 @@ "macro_name": "MODEM_ON_BOARD_UART" } }, - "macros_add": ["HSE_VALUE=26000000", "VECT_TAB_OFFSET=0x08010000", "RTC_LSI=1"], + "overrides": {"lse_available": 0}, + "macros_add": ["HSE_VALUE=26000000", "VECT_TAB_OFFSET=0x08010000"], "post_binary_hook": { "function": "MTSCode.combine_bins_mts_dragonfly", "toolchains": ["GCC_ARM", "ARM_STD", "ARM_MICRO", "IAR"] @@ -1764,7 +1748,7 @@ "core": "Cortex-M3", "default_toolchain": "uARM", "extra_labels_add": ["STM32L1", "STM32L152RC"], - "macros": ["RTC_LSI=1"], + "overrides": {"lse_available": 0}, "detect_code": ["4100"], "device_has_add": ["ANALOGOUT"], "default_lib": "small", @@ -1848,7 +1832,8 @@ "macro_name": "MODEM_ON_BOARD_UART" } }, - "macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT", "RTC_LSI=1", "HSE_VALUE=12000000", "GNSSBAUD=9600"], + "macros_add": ["MBEDTLS_CONFIG_HW_SUPPORT", "HSE_VALUE=12000000", "GNSSBAUD=9600"], + "overrides": {"lse_available": 0}, "device_has_add": ["ANALOGOUT", "SERIAL_FC", "TRNG", "FLASH"], "features": ["LWIP"], "public": false, @@ -1869,7 +1854,7 @@ "default_toolchain": "uARM", "program_cycle_s": 1.5, "extra_labels_add": ["STM32L1", "STM32L151RC"], - "macros": ["RTC_LSI=1"], + "overrides": {"lse_available": 0}, "supported_toolchains": ["ARM", "uARM", "GCC_ARM"], "device_has_add": ["ANALOGOUT"], "default_lib": "small", From 17a54840c77d7d2eeec08738b7c19f514e08e863 Mon Sep 17 00:00:00 2001 From: jeromecoutant Date: Mon, 4 Dec 2017 17:20:56 +0100 Subject: [PATCH 8/8] STM32 RTC : update and comment prescaler values --- targets/TARGET_STM/rtc_api.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/targets/TARGET_STM/rtc_api.c b/targets/TARGET_STM/rtc_api.c index b488e2aaa08..2b9b31a769f 100644 --- a/targets/TARGET_STM/rtc_api.c +++ b/targets/TARGET_STM/rtc_api.c @@ -36,14 +36,6 @@ static RTC_HandleTypeDef RtcHandle; -#if DEVICE_LOWPOWERTIMER -#define RTC_ASYNCH_PREDIV ((RTC_CLOCK - 1) / 0x8000) -#else -#define RTC_ASYNCH_PREDIV (0x007F) -#endif - -#define RTC_SYNCH_PREDIV (RTC_CLOCK / (RTC_ASYNCH_PREDIV + 1) - 1) - #if DEVICE_LOWPOWERTIMER static void (*irq_handler)(void); static void RTC_IRQHandler(void); @@ -114,8 +106,19 @@ void rtc_init(void) RtcHandle.Init.AsynchPrediv = RTC_AUTO_1_SECOND; #else /* TARGET_STM32F1 */ RtcHandle.Init.HourFormat = RTC_HOURFORMAT_24; - RtcHandle.Init.AsynchPrediv = RTC_ASYNCH_PREDIV; - RtcHandle.Init.SynchPrediv = RTC_SYNCH_PREDIV; + + /* PREDIV_A : 7-bit asynchronous prescaler */ +#if DEVICE_LOWPOWERTIMER + /* PREDIV_A is set to a small value to improve the SubSeconds resolution */ + /* with a 32768Hz clock, PREDIV_A=7 gives a precision of 244us */ + RtcHandle.Init.AsynchPrediv = 7; +#else + /* PREDIV_A is set to the maximum value to improve the consumption */ + RtcHandle.Init.AsynchPrediv = 0x007F; +#endif + /* PREDIV_S : 15-bit synchronous prescaler */ + /* PREDIV_S is set in order to get a 1 Hz clock */ + RtcHandle.Init.SynchPrediv = RTC_CLOCK / (RtcHandle.Init.AsynchPrediv + 1) - 1; RtcHandle.Init.OutPut = RTC_OUTPUT_DISABLE; RtcHandle.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; RtcHandle.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; @@ -304,7 +307,7 @@ static void RTC_IRQHandler(void) uint32_t rtc_read_subseconds(void) { - return 1000000.f * ((double)(RTC_SYNCH_PREDIV - RTC->SSR) / (RTC_SYNCH_PREDIV + 1)); + return 1000000.f * ((double)((RTC->PRER & RTC_PRER_PREDIV_S) - RTC->SSR) / ((RTC->PRER & RTC_PRER_PREDIV_S) + 1)); } void rtc_set_wake_up_timer(uint32_t delta)