From 3feabec7d5b45b7a5574f7227edc981b28495e13 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Tue, 27 May 2014 07:10:53 -0600 Subject: [PATCH] STM32 RTC: Add retry to initialization logic. Sometime RTC initialization takes longer. From dlsitzer. --- arch/arm/src/stm32/stm32_rtcc.c | 66 ++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/arch/arm/src/stm32/stm32_rtcc.c b/arch/arm/src/stm32/stm32_rtcc.c index 63af2f3745..f3dc454881 100644 --- a/arch/arm/src/stm32/stm32_rtcc.c +++ b/arch/arm/src/stm32/stm32_rtcc.c @@ -1,7 +1,7 @@ /************************************************************************************ * arch/arm/src/stm32/stm32_rtcc.c * - * Copyright (C) 2012-2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2012-2014 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -575,6 +575,8 @@ int up_rtcinitialize(void) { uint32_t regval; int ret; + int maxretry = 10; + int nretry = 0; rtc_dumpregs("On reset"); @@ -590,27 +592,63 @@ int up_rtcinitialize(void) stm32_pwr_enablebkp(); - /* Check if the one-time initialization of the RTC has already been performed. - * We can determine this by checking if the magic number has been writing to - * to back-up date register DR0. + /* Loop, attempting to initialize/resume the RTC. This loop is necessary + * because it seems that occasionally it takes longer to initialize the RTC + * (the actual failure is in rtc_synchwait()). */ - regval = getreg32(STM32_RTC_BK0R); - if (regval != RTC_MAGIC) + do { - /* Perform the one-time setup of the LSE clocking to the RTC */ + /* Check if the one-time initialization of the RTC has already been + * performed. We can determine this by checking if the magic number + * has been writing to to back-up date register DR0. + */ - ret = rtc_setup(); + regval = getreg32(STM32_RTC_BK0R); + if (regval != RTC_MAGIC) + { + rtclldbg("Do setup\n"); - /* Remember that the RTC is initialized */ + /* Perform the one-time setup of the LSE clocking to the RTC */ - putreg32(RTC_MAGIC, STM32_RTC_BK0R); + ret = rtc_setup(); + + /* Remember that the RTC is initialized */ + + putreg32(RTC_MAGIC, STM32_RTC_BK0R); + } + else + { + rtclldbg("Do resume\n"); + + /* RTC already set-up, just resume normal operation */ + + ret = rtc_resume(); + } + + /* Check that setup or resume returned successfully */ + + switch (ret) + { + case OK: + { + rtclldbg("setup/resume okay\n"); + break; + } + + default: + { + rtclldbg("setup/resume failed (%d)\n", ret); + break; + } + } } - else - { - /* RTC already set-up, just resume normal operation */ + while (ret != OK && ++nretry < maxretry); - ret = rtc_resume(); + if (ret != OK && nretry > 0) + { + rtclldbg("setup/resume ran %d times and failed with %d\n", nretry, ret); + return -ETIMEDOUT; } /* Configure RTC interrupt to catch alarm interrupts. All RTC interrupts are