You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2020/11/19 22:43:32 UTC

[GitHub] [mynewt-core] kasjer opened a new pull request #2413: STM32 RTC based os tick

kasjer opened a new pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413


   STMF1 already had support for tickles sleep.
   Now other MCU with quite distinct RTC also can be configured to LSE/RTC as system tick source.
   
   RTC is added to F0/F4/L0/L1/L4/WB55 which share similar hardware design.
   Small changes are present for L0/L1/F0 MCUs.
   
   Some families have low power clocks other then RTC that could be used as tick source but some don't hence common code.
   
   RTC in ST MCUs can be powered by battery and then time can be kept even when MCU is shut down.
   Wall clock changes made in current API are stored as UTC time in RTC and are restored at boot time if RTC is powered by battery.
   
   This is first step to use low power STOP mode when tick can wake up system while high speed clocks are stopped.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] kasjer commented on a change in pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
kasjer commented on a change in pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#discussion_r527699379



##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,315 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    int32_t sub_seconds;

Review comment:
       it was, but now I see that it does not need to be, I will change it to unsigned.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] vrahane commented on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
vrahane commented on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-773207940


   @kasjer Looks good to me but needs a rebase.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] sjanc commented on a change in pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
sjanc commented on a change in pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#discussion_r527700117



##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,315 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    int32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(int32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    int32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    int32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;

Review comment:
       ct.dow is left uninitialized here




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] apache-mynewt-bot commented on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-730683742


   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### hw/mcu/stm/stm32_common/src/hal_os_tick.c
   <details>
   
   ```diff
   @@ -81,7 +81,8 @@
    #define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
    #endif
    
   -_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
   +_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(
   +    SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
    
    /* RTC time of the last tick. */
    static uint32_t last_rtc_time;
   ```
   
   </details>


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] sjanc commented on a change in pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
sjanc commented on a change in pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#discussion_r527697145



##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,315 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    int32_t sub_seconds;

Review comment:
       is this signed type on purpose?




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] apache-mynewt-bot commented on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-731283332


   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### hw/mcu/stm/stm32_common/src/hal_os_tick.c
   <details>
   
   ```diff
   @@ -81,7 +81,8 @@
    #define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
    #endif
    
   -_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
   +_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(
   +    SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
    
    /* RTC time of the last tick. */
    static uint32_t last_rtc_time;
   ```
   
   </details>


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] kasjer commented on a change in pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
kasjer commented on a change in pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#discussion_r696912595



##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,317 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV),
+    "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    uint32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(uint32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    uint32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    uint32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.dow = date->WeekDay == 7 ? 0 : date->WeekDay;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;

Review comment:
       the other one is correct, it is `ct.usec * 64 / 15625` and could be `ct.usec * 4096 / 1000000` it was divided by 64 to lower the range but even with 4096 nominator multiplier 32bit range will not be exceeded, I will change it to make it more readable as it seem to be safe.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] utzig commented on a change in pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
utzig commented on a change in pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#discussion_r696904309



##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,317 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV),
+    "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    uint32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(uint32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    uint32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    uint32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.dow = date->WeekDay == 7 ? 0 : date->WeekDay;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;

Review comment:
       Btw, there is another use of `15625` in another function with what looks as the same purpose.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] kasjer commented on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
kasjer commented on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-774317871


   > @kasjer Looks good to me but needs a rebase.
   
   @vrahane I rebased with necessary corrections, thanks for checking out.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] utzig commented on a change in pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
utzig commented on a change in pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#discussion_r696596243



##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,317 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV),
+    "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    uint32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(uint32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    uint32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    uint32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.dow = date->WeekDay == 7 ? 0 : date->WeekDay;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;
+    clocktime_to_timeval(&ct, NULL, &utc);
+    os_settimeofday(&utc, NULL);
+}
+
+void
+os_tick_init(uint32_t os_ticks_per_sec, int prio)
+{
+    uint32_t sr;
+    RTC_DateTypeDef date = { .Year = 20, .Month = 1, .Date = 1, .WeekDay = RTC_WEEKDAY_WEDNESDAY};
+    RTC_TimeTypeDef rtc_time = { 0 };
+
+    RCC_PeriphCLKInitTypeDef clock_init = {
+        .PeriphClockSelection = RCC_PERIPHCLK_RTC,
+        .RTCClockSelection = RCC_RTCCLKSOURCE_LSE,
+    };
+    HAL_RCCEx_PeriphCLKConfig(&clock_init);
+
+    /* Set the system tick priority. */
+    NVIC_SetPriority(RTC_IRQ, prio);
+    NVIC_SetVector(RTC_IRQ, (uint32_t)RTC_Alarm_IRQHandler);
+
+    /* If RTC is already on get time and date before reinit. */
+    if (IS_RTC_ENABLED) {
+        HAL_RTC_GetTime(&rtc, &rtc_time, RTC_FORMAT_BIN);
+        HAL_RTC_GetDate(&rtc, &date, RTC_FORMAT_BIN);
+    } else {
+        bzero(&rtc_time, sizeof(rtc_time));
+        __HAL_RCC_RTC_ENABLE();
+    }
+
+    __HAL_DBGMCU_FREEZE_RTC();
+
+#if !MYNEWT_VAL(MCU_STM32F0)
+    DBGMCU->CR |= (DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY);
+#else
+    DBGMCU->CR |= (DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY);
+#endif
+
+    OS_ENTER_CRITICAL(sr);
+
+    /* RTCCLK 32768 Hz, ck_apre = 4096 Hz, ck_spre = 1Hz. */
+    rtc.Init.AsynchPrediv = 8 - 1;
+    rtc.Init.SynchPrediv = 32768 / 8 - 1;

Review comment:
       `SYNCH_PREDIV` maybe?

##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,317 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV),
+    "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    uint32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(uint32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    uint32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    uint32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.dow = date->WeekDay == 7 ? 0 : date->WeekDay;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;
+    clocktime_to_timeval(&ct, NULL, &utc);
+    os_settimeofday(&utc, NULL);
+}
+
+void
+os_tick_init(uint32_t os_ticks_per_sec, int prio)
+{
+    uint32_t sr;
+    RTC_DateTypeDef date = { .Year = 20, .Month = 1, .Date = 1, .WeekDay = RTC_WEEKDAY_WEDNESDAY};

Review comment:
       Could have space before closing brace for consistency.

##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,317 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV),
+    "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    uint32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(uint32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    uint32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    uint32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.dow = date->WeekDay == 7 ? 0 : date->WeekDay;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;
+    clocktime_to_timeval(&ct, NULL, &utc);
+    os_settimeofday(&utc, NULL);
+}
+
+void
+os_tick_init(uint32_t os_ticks_per_sec, int prio)
+{
+    uint32_t sr;
+    RTC_DateTypeDef date = { .Year = 20, .Month = 1, .Date = 1, .WeekDay = RTC_WEEKDAY_WEDNESDAY};
+    RTC_TimeTypeDef rtc_time = { 0 };
+
+    RCC_PeriphCLKInitTypeDef clock_init = {
+        .PeriphClockSelection = RCC_PERIPHCLK_RTC,
+        .RTCClockSelection = RCC_RTCCLKSOURCE_LSE,
+    };
+    HAL_RCCEx_PeriphCLKConfig(&clock_init);
+
+    /* Set the system tick priority. */
+    NVIC_SetPriority(RTC_IRQ, prio);
+    NVIC_SetVector(RTC_IRQ, (uint32_t)RTC_Alarm_IRQHandler);
+
+    /* If RTC is already on get time and date before reinit. */
+    if (IS_RTC_ENABLED) {
+        HAL_RTC_GetTime(&rtc, &rtc_time, RTC_FORMAT_BIN);
+        HAL_RTC_GetDate(&rtc, &date, RTC_FORMAT_BIN);
+    } else {
+        bzero(&rtc_time, sizeof(rtc_time));
+        __HAL_RCC_RTC_ENABLE();
+    }
+
+    __HAL_DBGMCU_FREEZE_RTC();
+
+#if !MYNEWT_VAL(MCU_STM32F0)
+    DBGMCU->CR |= (DBGMCU_CR_DBG_SLEEP | DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY);
+#else
+    DBGMCU->CR |= (DBGMCU_CR_DBG_STOP | DBGMCU_CR_DBG_STANDBY);
+#endif
+
+    OS_ENTER_CRITICAL(sr);
+
+    /* RTCCLK 32768 Hz, ck_apre = 4096 Hz, ck_spre = 1Hz. */
+    rtc.Init.AsynchPrediv = 8 - 1;

Review comment:
       `ASYNCH_PREDIV` maybe?

##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,317 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV),
+    "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    uint32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(uint32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    uint32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    uint32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.dow = date->WeekDay == 7 ? 0 : date->WeekDay;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;

Review comment:
       Where does `15625` come from?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] apache-mynewt-bot removed a comment on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot removed a comment on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-730683742


   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### hw/mcu/stm/stm32_common/src/hal_os_tick.c
   <details>
   
   ```diff
   @@ -81,7 +81,8 @@
    #define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
    #endif
    
   -_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
   +_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(
   +    SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
    
    /* RTC time of the last tick. */
    static uint32_t last_rtc_time;
   ```
   
   </details>


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] kasjer commented on a change in pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
kasjer commented on a change in pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#discussion_r527703246



##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,315 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    int32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(int32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    int32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    int32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;

Review comment:
       ct.dow is not used for conversions from clocktime, it is filled when conversion is done other way round.
   day of week can be incorrect in hardware, MCU will not enforce correct value so there is no guarantee that value extracted from registers is correct.
   I saw no point in computing correct value since conversion function will not use it any way.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] apache-mynewt-bot commented on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-774317539


   
   <!-- style-bot -->
   
   ## Style check summary
   
   #### No suggestions at this time!
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] kasjer commented on a change in pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
kasjer commented on a change in pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#discussion_r696869146



##########
File path: hw/mcu/stm/stm32_common/src/hal_os_tick.c
##########
@@ -54,6 +55,317 @@ __WFI(void)
 #endif
 #endif
 
+#if MYNEWT_VAL(OS_TICKS_USE_RTC)
+
+#if MYNEWT_VAL(STM32_CLOCK_LSE) && (((32768 / OS_TICKS_PER_SEC) * OS_TICKS_PER_SEC) != 32768)
+#error OS_TICKS_PER_SEC should be divisible by power of 2 like 128, 256, 512, 1024 when OS_TICKS_USE_RTC is enabled.
+#endif
+
+#ifndef HAL_RTC_MODULE_ENABLED
+#error Define HAL_RTC_MODULE_ENABLED in stm32[fl][0-4]xx_hal_conf.h in your bsp
+#endif
+
+#define ASYNCH_PREDIV       7
+#define SYNCH_PREDIV        (32768 / (ASYNCH_PREDIV + 1) - 1)
+#define SUB_SECONDS_BITS    12
+
+#if defined(STM32L0) || defined(STM32F0)
+#define RTC_IRQ RTC_IRQn
+#else
+#define RTC_IRQ RTC_Alarm_IRQn
+#endif
+
+#if defined(STM32L0) || defined(STM32L1)
+#define IS_RTC_ENABLED (RCC->CSR & RCC_CSR_RTCEN)
+#else
+#define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
+#endif
+
+_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV),
+    "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
+
+/* RTC time of the last tick. */
+static uint32_t last_rtc_time;
+static uint32_t sub_seconds_per_tick;
+static uint8_t sub_seconds_tick_bits;
+
+/* RTC holds UTC time. */
+static RTC_HandleTypeDef rtc = {
+    .Instance = RTC,
+    .Init = {
+        .HourFormat = RTC_HOURFORMAT_24,
+        .OutPut = RTC_OUTPUT_DISABLE,
+        .OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH,
+        .OutPutType = RTC_OUTPUT_TYPE_PUSHPULL,
+    }
+};
+
+/* RTC AlarmA used for OS ticks. */
+static RTC_AlarmTypeDef alarm = {
+    .AlarmTime = {
+        .Hours = 0,
+        .Minutes = 0,
+        .Seconds = 0,
+        .SubSeconds = 0,
+        .TimeFormat = RTC_HOURFORMAT12_AM,
+        .SecondFraction = 0,
+        .DayLightSaving = RTC_DAYLIGHTSAVING_NONE,
+        .StoreOperation = RTC_STOREOPERATION_RESET,
+    },
+    .AlarmMask = RTC_ALARMMASK_ALL,
+    .AlarmSubSecondMask = 0,
+    .Alarm = RTC_ALARM_A,
+};
+
+static uint32_t
+rtc_time_to_sub_seconds(const RTC_TimeTypeDef *time)
+{
+    uint32_t sub_seconds;
+
+    /* Convert sub second filed to running up sub seconds. */
+    sub_seconds = time->SecondFraction - time->SubSeconds;
+
+    sub_seconds += (((time->Hours * 60 + time->Minutes) * 60) + time->Seconds) << SUB_SECONDS_BITS;
+
+    /* Round down to ticks. */
+    sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+
+    return sub_seconds;
+}
+
+static void
+sub_seconds_to_rtc(uint32_t sub_seconds, RTC_TimeTypeDef *time)
+{
+    time->SubSeconds = time->SecondFraction - (sub_seconds & time->SecondFraction);
+    sub_seconds >>= SUB_SECONDS_BITS;
+    time->Seconds = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Minutes = sub_seconds % 60;
+    sub_seconds /= 60;
+    time->Hours = sub_seconds % 24;
+}
+
+static void
+rtc_update_time(void)
+{
+    int32_t delta;
+    uint32_t now;
+
+    HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    /* Get sub seconds rounded down to tick. */
+    now = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    delta = now - last_rtc_time;
+    if (delta < 0) {
+        delta += 3600 << SUB_SECONDS_BITS;
+    }
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - (now & alarm.AlarmTime.SecondFraction);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    if ((int32_t)alarm.AlarmTime.SubSeconds < 0) {
+        alarm.AlarmTime.SubSeconds += alarm.AlarmTime.SecondFraction + 1;
+        alarm.AlarmTime.Seconds++;
+        if (alarm.AlarmTime.Seconds >= 60) {
+            alarm.AlarmTime.Seconds = 0;
+            alarm.AlarmTime.Minutes++;
+            if (alarm.AlarmTime.Minutes >= 60) {
+                alarm.AlarmTime.Minutes = 0;
+                if (alarm.AlarmTime.Hours >= 24) {
+                    alarm.AlarmTime.Hours = 0;
+                }
+            }
+        }
+    }
+    /* Switch to tick timer interrupt by unmasking only sub second alarm bits. */
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    alarm.AlarmSubSecondMask = sub_seconds_tick_bits << RTC_ALRMASSR_MASKSS_Pos;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    last_rtc_time = now;
+    os_time_advance(delta >> sub_seconds_tick_bits);
+}
+
+void
+os_tick_idle(os_time_t ticks)
+{
+    uint32_t sub_seconds;
+    OS_ASSERT_CRITICAL();
+
+    if (ticks > 0) {
+        /* Get current time directly to alarm. */
+        HAL_RTC_GetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+
+        alarm.AlarmSubSecondMask = SUB_SECONDS_BITS << RTC_ALRMASSR_MASKSS_Pos;
+        if (ticks < OS_TICKS_PER_SEC) {
+            /* Convert sub-seconds to up-counting value. */
+            sub_seconds = alarm.AlarmTime.SecondFraction - alarm.AlarmTime.SubSeconds;
+            /* Round down to tick. */
+            sub_seconds &= ~((1 << sub_seconds_tick_bits) - 1);
+            /* Add requested number of ticks. */
+            sub_seconds += (ticks & (OS_TICKS_PER_SEC - 1)) << sub_seconds_tick_bits;
+            /* Remove any overflow which is OK since we are sticking to 1 second limit. */
+            sub_seconds &= (1 << SUB_SECONDS_BITS) - 1;
+            /* Convert back to down-counting sub-seconds for alarm to use. */
+            alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction - sub_seconds;
+            alarm.AlarmMask = RTC_ALARMMASK_ALL;
+        } else {
+            sub_seconds = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+            sub_seconds += ticks << sub_seconds_tick_bits;
+            sub_seconds_to_rtc(sub_seconds, &alarm.AlarmTime);
+            alarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY;
+        }
+        HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+    }
+
+    __DSB();
+    __WFI();
+
+    if (ticks > 0) {
+        rtc_update_time();
+    }
+}
+
+/* ST HAL interrupt handler calls this function. */
+void
+HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
+{
+    (void)hrtc;
+    rtc_update_time();
+}
+
+void
+RTC_Alarm_IRQHandler(void)
+{
+    int sr;
+
+    os_trace_isr_enter();
+
+    OS_ENTER_CRITICAL(sr);
+    HAL_RTC_AlarmIRQHandler(&rtc);
+    OS_EXIT_CRITICAL(sr);
+
+    os_trace_isr_exit();
+}
+
+static void
+stm32_rtc_os_time_change(const struct os_time_change_info *info, void *arg)
+{
+    struct clocktime ct;
+    RTC_DateTypeDef date;
+    uint32_t sub_seconds;
+    int sr;
+
+    timeval_to_clocktime(info->tci_cur_tv, NULL, &ct);
+    date.Year = ct.year - 2000;
+    date.Month = ct.mon;
+    date.Date = ct.day;
+    /* ST HAL Sunday is 7. */
+    date.WeekDay = ct.dow ? ct.dow : 7;
+    sub_seconds = ct.usec * 64 / 15625;
+
+    OS_ENTER_CRITICAL(sr);
+
+    alarm.AlarmTime.Hours = ct.hour;
+    alarm.AlarmTime.Minutes = ct.min;
+    alarm.AlarmTime.Seconds = ct.sec;
+    alarm.AlarmTime.SubSeconds = alarm.AlarmTime.SecondFraction;
+
+    HAL_RTC_SetTime(&rtc, &alarm.AlarmTime, RTC_FORMAT_BIN);
+    HAL_RTC_SetDate(&rtc, &date, RTC_FORMAT_BIN);
+    if (sub_seconds) {
+        RTC->SHIFTR = RTC_SHIFTR_ADD1S | sub_seconds;
+    }
+    last_rtc_time = rtc_time_to_sub_seconds(&alarm.AlarmTime);
+    alarm.AlarmTime.SubSeconds -= sub_seconds_per_tick;
+    alarm.AlarmMask = RTC_ALARMMASK_ALL;
+    HAL_RTC_SetAlarm_IT(&rtc, &alarm, RTC_FORMAT_BIN);
+
+    OS_EXIT_CRITICAL(sr);
+}
+
+static struct os_time_change_listener rtc_setter = {
+    .tcl_fn = stm32_rtc_os_time_change,
+};
+
+static void
+set_os_datetime_from_rtc(const RTC_TimeTypeDef *time, const RTC_DateTypeDef *date)
+{
+    struct os_timeval utc;
+    struct clocktime ct;
+    ct.year = 2000 + date->Year;
+    ct.mon = date->Month;
+    ct.day = date->Date;
+    ct.dow = date->WeekDay == 7 ? 0 : date->WeekDay;
+    ct.hour = time->Hours;
+    ct.min = time->Minutes;
+    ct.sec = time->Seconds;
+    ct.usec = ((time->SecondFraction - time->SubSeconds) * 15625) >> SUB_SECONDS_BITS;

Review comment:
       excellent point, it should be 1000000




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] apache-mynewt-bot removed a comment on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot removed a comment on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-731283332


   
   <!-- style-bot -->
   
   ## Style check summary
   
   ### Our coding style is [here!](https://github.com/apache/mynewt-core/blob/master/CODING_STANDARDS.md)
   
   
   #### hw/mcu/stm/stm32_common/src/hal_os_tick.c
   <details>
   
   ```diff
   @@ -81,7 +81,8 @@
    #define IS_RTC_ENABLED (RCC->BDCR & RCC_BDCR_RTCEN)
    #endif
    
   -_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
   +_Static_assert(SUB_SECONDS_BITS == __builtin_popcount(
   +    SYNCH_PREDIV), "SUB_SECONDS_BITS should be number of 1s in SYNCH_PREDIV");
    
    /* RTC time of the last tick. */
    static uint32_t last_rtc_time;
   ```
   
   </details>


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] vrahane commented on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
vrahane commented on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-773207940


   @kasjer Looks good to me but needs a rebase.


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] apache-mynewt-bot commented on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot commented on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-731284061


   
   <!-- style-bot -->
   
   ## Style check summary
   
   #### No suggestions at this time!
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] kasjer merged pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
kasjer merged pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] utzig commented on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
utzig commented on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-906668445


   @kasjer Also the correct spelling is `tickless` (with two `s` at the end)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscribe@mynewt.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [mynewt-core] apache-mynewt-bot removed a comment on pull request #2413: STM32 RTC based os tick

Posted by GitBox <gi...@apache.org>.
apache-mynewt-bot removed a comment on pull request #2413:
URL: https://github.com/apache/mynewt-core/pull/2413#issuecomment-731284061


   
   <!-- style-bot -->
   
   ## Style check summary
   
   #### No suggestions at this time!
   


----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org