diff --git a/arch/arm/src/stm32/stm32_irq.c b/arch/arm/src/stm32/stm32_irq.c
index 2a51836a52..0f9553210a 100644
--- a/arch/arm/src/stm32/stm32_irq.c
+++ b/arch/arm/src/stm32/stm32_irq.c
@@ -387,6 +387,11 @@ void up_irqinitialize(void)
   up_enable_irq(STM32_IRQ_MEMFAULT);
 #endif
 
+#ifdef CONFIG_RTC
+  /* RTC was initialized earlier but IRQs weren't ready at that time */
+  stm32_rtc_irqinitialize();
+#endif
+
   /* Attach all other processor exceptions (except reset and sys tick) */
 
 #ifdef CONFIG_DEBUG_FEATURES
diff --git a/arch/arm/src/stm32/stm32_rtc.h b/arch/arm/src/stm32/stm32_rtc.h
index d228a3c458..0c4e5ecbf3 100644
--- a/arch/arm/src/stm32/stm32_rtc.h
+++ b/arch/arm/src/stm32/stm32_rtc.h
@@ -79,21 +79,35 @@
 #define STM32_RTC_PRESCALER_SECOND  32767  /* Default prescaler to get a second base */
 #define STM32_RTC_PRESCALER_MIN         1  /* Maximum speed of 16384 Hz */
 
+#if defined(CONFIG_STM32_STM32F10XX)
+/* RTC is only a counter, store RTC data in backup domain register DR1 (if CONFIG_RTC_HIRES) and DR2 (state) */
+
 #if !defined(CONFIG_RTC_MAGIC)
-# define CONFIG_RTC_MAGIC           (0xfacefeee)
+# define CONFIG_RTC_MAGIC           (0xface) /* only 16 bit */
 #endif
 
-#if !defined(CONFIG_RTC_MAGIC_TIME_SET)
-#  define CONFIG_RTC_MAGIC_TIME_SET  (CONFIG_RTC_MAGIC + 1)
+#define RTC_MAGIC_REG               STM32_BKP_DR2
+
+#else /* !CONFIG_STM32_STM32F10XX */
+
+#if !defined(CONFIG_RTC_MAGIC)
+# define CONFIG_RTC_MAGIC           (0xfacefeee)
 #endif
 
 #if !defined(CONFIG_RTC_MAGIC_REG)
 # define CONFIG_RTC_MAGIC_REG       (0)
 #endif
 
+#define RTC_MAGIC_REG               STM32_RTC_BKR(CONFIG_RTC_MAGIC_REG)
+
+#endif /* CONFIG_STM32_STM32F10XX */
+
 #define RTC_MAGIC                   CONFIG_RTC_MAGIC
 #define RTC_MAGIC_TIME_SET          CONFIG_RTC_MAGIC_TIME_SET
-#define RTC_MAGIC_REG               STM32_RTC_BKR(CONFIG_RTC_MAGIC_REG)
+
+#if !defined(CONFIG_RTC_MAGIC_TIME_SET)
+#  define CONFIG_RTC_MAGIC_TIME_SET  (CONFIG_RTC_MAGIC + 1)
+#endif
 
 /****************************************************************************
  * Public Types
@@ -118,6 +132,23 @@ extern "C"
  * Public Functions
  ****************************************************************************/
 
+/************************************************************************************
+ * Name: stm32_rtc_irqinitialize
+ *
+ * Description:
+ *   Initialize IRQs for RTC, not possible during up_rtc_initialize because
+ *   up_irqinitialize is called later.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno on failure
+ *
+ ************************************************************************************/
+
+int stm32_rtc_irqinitialize(void);
+
 /****************************************************************************
  * Name: stm32_rtc_getdatetime_with_subseconds
  *
diff --git a/arch/arm/src/stm32/stm32_rtc_lowerhalf.c b/arch/arm/src/stm32/stm32_rtc_lowerhalf.c
index 548b7fa81b..6a8c079399 100644
--- a/arch/arm/src/stm32/stm32_rtc_lowerhalf.c
+++ b/arch/arm/src/stm32/stm32_rtc_lowerhalf.c
@@ -365,7 +365,11 @@ static int stm32_settime(FAR struct rtc_lowerhalf_s *lower,
 
 static bool stm32_havesettime(FAR struct rtc_lowerhalf_s *lower)
 {
+#if defined(CONFIG_STM32_STM32F10XX)
+  return getreg16(RTC_MAGIC_REG) == RTC_MAGIC_TIME_SET;
+#else
   return getreg32(RTC_MAGIC_REG) == RTC_MAGIC_TIME_SET;
+#endif
 }
 
 /****************************************************************************
diff --git a/arch/arm/src/stm32/stm32_rtcc.c b/arch/arm/src/stm32/stm32_rtcc.c
index 9adc62433c..b7c96f336a 100644
--- a/arch/arm/src/stm32/stm32_rtcc.c
+++ b/arch/arm/src/stm32/stm32_rtcc.c
@@ -763,17 +763,37 @@ int up_rtc_initialize(void)
    * 3. Configure the RTC to generate RTC alarms (Alarm A or Alarm B).
    */
 
+  g_rtc_enabled = true;
+  rtc_dumpregs("After Initialization");
+  return OK;
+}
+
+/************************************************************************************
+ * Name: stm32_rtc_irqinitialize
+ *
+ * Description:
+ *   Initialize IRQs for RTC, not possible during up_rtc_initialize because
+ *   up_irqinitialize is called later.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno on failure
+ *
+ ************************************************************************************/
+
+int stm32_rtc_irqinitialize(void)
+{
 #ifdef CONFIG_RTC_ALARM
 #  warning "Missing EXTI setup logic"
 
-  /* Then attach the ALARM interrupt handler */
+  /* then attach the ALARM interrupt handler */
 
   irq_attach(STM32_IRQ_RTC_WKUP, rtc_interrupt, NULL);
   up_enable_irq(STM32_IRQ_RTC_WKUP);
 #endif
 
-  g_rtc_enabled = true;
-  rtc_dumpregs("After Initialization");
   return OK;
 }
 
diff --git a/arch/arm/src/stm32/stm32_rtcounter.c b/arch/arm/src/stm32/stm32_rtcounter.c
index 9a046f8318..5db3865c0d 100644
--- a/arch/arm/src/stm32/stm32_rtcounter.c
+++ b/arch/arm/src/stm32/stm32_rtcounter.c
@@ -331,7 +331,9 @@ static int stm32_rtc_interrupt(int irq, void *context, FAR void *arg)
 #ifdef CONFIG_RTC_HIRES
   if ((source & RTC_CRL_OWF) != 0)
     {
+      stm32_pwr_enablebkp(true);
       putreg16(getreg16(RTC_TIMEMSB_REG) + 1, RTC_TIMEMSB_REG);
+      stm32_pwr_enablebkp(false);
     }
 #endif
 
@@ -373,25 +375,33 @@ static int stm32_rtc_interrupt(int irq, void *context, FAR void *arg)
 
 int up_rtc_initialize(void)
 {
+  uint32_t regval;
+
   /* Enable write access to the backup domain (RTC registers, RTC backup data
    * registers and backup SRAM).
    */
 
   stm32_pwr_enablebkp(true);
+
+  regval = getreg32(RTC_MAGIC_REG);
+
+  if (regval != RTC_MAGIC && regval != RTC_MAGIC_TIME_SET)
+    {
+      /* reset backup domain if bad magic */
+      modifyreg32(STM32_RCC_BDCR, 0, RCC_BDCR_BDRST);
+      modifyreg32(STM32_RCC_BDCR, RCC_BDCR_BDRST, 0);
+      putreg16(RTC_MAGIC, RTC_MAGIC_REG);
+    }
   
   /* Select the lower power external 32,768Hz (Low-Speed External, LSE) oscillator
    * as RTC Clock Source and enable the Clock */
   
   modifyreg16(STM32_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE);
+
+  /* enable RTC and wait for RSF */
+
   modifyreg16(STM32_RCC_BDCR, 0, RCC_BDCR_RTCEN);
 
-  /* TODO: Get state from this function, if everything is
-   *   okay and whether it is already enabled (if it was disabled
-   *   reset upper time register)
-   */
-
-  g_rtc_enabled = true;
-
   /* TODO: Possible stall? should we set the timeout period? and return with -1 */
 
   stm32_rtc_wait4rsf();
@@ -403,21 +413,19 @@ int up_rtc_initialize(void)
   putreg16(STM32_RTC_PRESCALAR_VALUE & 0xffff, STM32_RTC_PRLL);
   stm32_rtc_endwr();
 
-  /* Configure RTC interrupt to catch overflow and alarm interrupts. */
+  stm32_rtc_wait4rsf();
 
-#if defined(CONFIG_RTC_HIRES) || defined(CONFIG_RTC_ALARM)
-  irq_attach(STM32_IRQ_RTC, stm32_rtc_interrupt, NULL);
-  up_enable_irq(STM32_IRQ_RTC);
+#ifdef CONFIG_RTC_HIRES
+  /* enable overflow interrupt - alarm interrupt is enabled in stm32_rtc_setalarm */
+  modifyreg16(STM32_RTC_CRH, 0, RTC_CRH_OWIE);
 #endif
 
-  /* Previous write is done? This is required prior writing into CRH */
+  /* TODO: Get state from this function, if everything is
+   *   okay and whether it is already enabled (if it was disabled
+   *   reset upper time register)
+   */
 
-  while ((getreg16(STM32_RTC_CRL) & RTC_CRL_RTOFF) == 0)
-    {
-      up_waste();
-    }
-
-  modifyreg16(STM32_RTC_CRH, 0, RTC_CRH_OWIE);
+  g_rtc_enabled = true;
 
   /* Alarm Int via EXTI Line */
 
@@ -432,6 +440,33 @@ int up_rtc_initialize(void)
   return OK;
 }
 
+/************************************************************************************
+ * Name: stm32_rtc_irqinitialize
+ *
+ * Description:
+ *   Initialize IRQs for RTC, not possible during up_rtc_initialize because
+ *   up_irqinitialize is called later.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno on failure
+ *
+ ************************************************************************************/
+
+int stm32_rtc_irqinitialize(void)
+{
+  /* Configure RTC interrupt to catch overflow and alarm interrupts. */
+
+#if defined(CONFIG_RTC_HIRES) || defined(CONFIG_RTC_ALARM)
+  irq_attach(STM32_IRQ_RTC, stm32_rtc_interrupt, NULL);
+  up_enable_irq(STM32_IRQ_RTC);
+#endif
+
+  return OK;
+}
+
 /************************************************************************************
  * Name: up_rtc_time
  *
@@ -613,6 +648,7 @@ int up_rtc_settime(FAR const struct timespec *tp)
   do
     {
       stm32_rtc_beginwr();
+      putreg16(RTC_MAGIC, RTC_MAGIC_TIME_SET);
       putreg16(regvals.cnth, STM32_RTC_CNTH);
       putreg16(regvals.cntl, STM32_RTC_CNTL);
       cntl = getreg16(STM32_RTC_CNTL);
@@ -652,6 +688,8 @@ int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
   uint16_t cr;
   int ret = -EBUSY;
 
+  flags = enter_critical_section();
+
   /* Is there already something waiting on the ALARM? */
 
   if (g_alarmcb == NULL)
@@ -664,6 +702,8 @@ int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
 
       stm32_rtc_breakout(tp, &regvals);
 
+      stm32_pwr_enablebkp(true);
+
       /* Enable RTC alarm */
 
       cr  = getreg16(STM32_RTC_CRH);
@@ -672,16 +712,18 @@ int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
 
       /* The set the alarm */
 
-      flags = enter_critical_section();
       stm32_rtc_beginwr();
       putreg16(regvals.cnth, STM32_RTC_ALRH);
       putreg16(regvals.cntl, STM32_RTC_ALRL);
       stm32_rtc_endwr();
-      leave_critical_section(flags);
+
+      stm32_pwr_enablebkp(false);
 
       ret = OK;
     }
 
+  leave_critical_section(flags);
+
   return ret;
 }
 #endif
@@ -706,6 +748,8 @@ int stm32_rtc_cancelalarm(void)
   irqstate_t flags;
   int ret = -ENODATA;
 
+  flags = enter_critical_section();
+
   if (g_alarmcb != NULL)
     {
       /* Cancel the global callback function */
@@ -714,16 +758,18 @@ int stm32_rtc_cancelalarm(void)
 
       /* Unset the alarm */
 
-      flags = enter_critical_section();
+      stm32_pwr_enablebkp(true);
       stm32_rtc_beginwr();
       putreg16(0xffff, STM32_RTC_ALRH);
       putreg16(0xffff, STM32_RTC_ALRL);
       stm32_rtc_endwr();
-      leave_critical_section(flags);
+      stm32_pwr_enablebkp(false);
 
       ret = OK;
     }
 
+  leave_critical_section(flags);
+
   return ret;
 }
 #endif
diff --git a/arch/arm/src/stm32/stm32f40xxx_rtcc.c b/arch/arm/src/stm32/stm32f40xxx_rtcc.c
index e15c995a6c..751989b487 100644
--- a/arch/arm/src/stm32/stm32f40xxx_rtcc.c
+++ b/arch/arm/src/stm32/stm32f40xxx_rtcc.c
@@ -1058,6 +1058,27 @@ int up_rtc_initialize(void)
   return OK;
 }
 
+/************************************************************************************
+ * Name: stm32_rtc_irqinitialize
+ *
+ * Description:
+ *   Initialize IRQs for RTC, not possible during up_rtc_initialize because
+ *   up_irqinitialize is called later.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno on failure
+ *
+ ************************************************************************************/
+
+int stm32_rtc_irqinitialize(void)
+{
+  /* nothing to do */
+  return OK;
+}
+
 /****************************************************************************
  * Name: stm32_rtc_getdatetime_with_subseconds
  *
diff --git a/arch/arm/src/stm32l4/stm32l4_rtcc.c b/arch/arm/src/stm32l4/stm32l4_rtcc.c
index d053ee9929..9ca5c7b9f8 100644
--- a/arch/arm/src/stm32l4/stm32l4_rtcc.c
+++ b/arch/arm/src/stm32l4/stm32l4_rtcc.c
@@ -1003,6 +1003,27 @@ int up_rtc_initialize(void)
   return OK;
 }
 
+/************************************************************************************
+ * Name: stm32_rtc_irqinitialize
+ *
+ * Description:
+ *   Initialize IRQs for RTC, not possible during up_rtc_initialize because
+ *   up_irqinitialize is called later.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   Zero (OK) on success; a negated errno on failure
+ *
+ ************************************************************************************/
+
+int stm32_rtc_irqinitialize(void)
+{
+  /* nothing to do */
+  return OK;
+}
+
 /************************************************************************************
  * Name: stm32l4_rtc_getdatetime_with_subseconds
  *