problem with resetting backup domain clears clocking options set up before in *rcc.c
use INITS flag to avoid magic reg value to detect power up reset state of rtc correct a problem clearing interrupt flags (they weren't) which prevented an alarm from ever being used more than once per reset cycle
This commit is contained in:
parent
4e57c36a8c
commit
48fc8b9dd7
@ -86,17 +86,17 @@ static int stm32l4_exti_alarm_isr(int irq, void *context)
|
|||||||
{
|
{
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
/* Clear the pending EXTI interrupt */
|
/* Dispatch the interrupt to the handler */
|
||||||
|
|
||||||
putreg32(EXTI1_RTC_ALARM, STM32L4_EXTI1_PR);
|
|
||||||
|
|
||||||
/* And dispatch the interrupt to the handler */
|
|
||||||
|
|
||||||
if (stm32l4_exti_callback)
|
if (stm32l4_exti_callback)
|
||||||
{
|
{
|
||||||
ret = stm32l4_exti_callback(irq, context);
|
ret = stm32l4_exti_callback(irq, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the pending EXTI interrupt */
|
||||||
|
|
||||||
|
putreg32(EXTI1_RTC_ALARM, STM32L4_EXTI1_PR);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +99,6 @@
|
|||||||
|
|
||||||
#define SYNCHRO_TIMEOUT (0x00020000)
|
#define SYNCHRO_TIMEOUT (0x00020000)
|
||||||
#define INITMODE_TIMEOUT (0x00010000)
|
#define INITMODE_TIMEOUT (0x00010000)
|
||||||
#define RTC_MAGIC CONFIG_RTC_MAGIC
|
|
||||||
#define RTC_MAGIC_REG STM32L4_RTC_BKR(CONFIG_RTC_MAGIC_REG)
|
|
||||||
|
|
||||||
/* BCD conversions */
|
/* BCD conversions */
|
||||||
|
|
||||||
@ -213,7 +211,6 @@ static void rtc_dumpregs(FAR const char *msg)
|
|||||||
rtclldbg(" TAMPCR: %08x\n", getreg32(STM32L4_RTC_TAMPCR));
|
rtclldbg(" TAMPCR: %08x\n", getreg32(STM32L4_RTC_TAMPCR));
|
||||||
rtclldbg("ALRMASSR: %08x\n", getreg32(STM32L4_RTC_ALRMASSR));
|
rtclldbg("ALRMASSR: %08x\n", getreg32(STM32L4_RTC_ALRMASSR));
|
||||||
rtclldbg("ALRMBSSR: %08x\n", getreg32(STM32L4_RTC_ALRMBSSR));
|
rtclldbg("ALRMBSSR: %08x\n", getreg32(STM32L4_RTC_ALRMBSSR));
|
||||||
rtclldbg("MAGICREG: %08x\n", getreg32(RTC_MAGIC_REG));
|
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
# define rtc_dumpregs(msg)
|
# define rtc_dumpregs(msg)
|
||||||
@ -254,6 +251,31 @@ static void rtc_dumptime(FAR const struct tm *tp, FAR const char *msg)
|
|||||||
# define rtc_dumptime(tp, msg)
|
# define rtc_dumptime(tp, msg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: rtc_is_inits
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Returns 'true' if the RTC has been initialized (according to the RTC itself).
|
||||||
|
* It will be 'false' if the RTC has never been initialized since first time power
|
||||||
|
* up, and the counters are stopped until it is first initialized.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* bool -- true if the INITS flag is set in the ISR.
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
static bool rtc_is_inits(void)
|
||||||
|
{
|
||||||
|
uint32_t regval;
|
||||||
|
|
||||||
|
regval = getreg32(STM32L4_RTC_ISR);
|
||||||
|
|
||||||
|
return (regval & RTC_ISR_INITS) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: rtc_wprunlock
|
* Name: rtc_wprunlock
|
||||||
*
|
*
|
||||||
@ -482,81 +504,6 @@ static int rtc_bcd2bin(uint32_t value)
|
|||||||
return (int)(tens + (value & 0x0f));
|
return (int)(tens + (value & 0x0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
|
||||||
* Name: rtc_setup
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Performs first time configuration of the RTC. A special value written into
|
|
||||||
* back-up register 0 will prevent this function from being called on sub-sequent
|
|
||||||
* resets or power up.
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* None
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* Zero (OK) on success; a negated errno on failure
|
|
||||||
*
|
|
||||||
************************************************************************************/
|
|
||||||
|
|
||||||
static int rtc_setup(void)
|
|
||||||
{
|
|
||||||
uint32_t regval;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Disable the write protection for RTC registers */
|
|
||||||
|
|
||||||
rtc_wprunlock();
|
|
||||||
|
|
||||||
/* Set Initialization mode */
|
|
||||||
|
|
||||||
ret = rtc_enterinit();
|
|
||||||
if (ret == OK)
|
|
||||||
{
|
|
||||||
/* Set the 24 hour format by clearing the FMT bit in the RTC
|
|
||||||
* control register
|
|
||||||
*/
|
|
||||||
|
|
||||||
regval = getreg32(STM32L4_RTC_CR);
|
|
||||||
regval &= ~RTC_CR_FMT;
|
|
||||||
putreg32(regval, STM32L4_RTC_CR);
|
|
||||||
|
|
||||||
/* Configure RTC pre-scaler with the required values */
|
|
||||||
|
|
||||||
#ifdef CONFIG_STM32L4_RTC_HSECLOCK
|
|
||||||
/* For a 1 MHz clock this yields 0.9999360041 Hz on the second
|
|
||||||
* timer - which is pretty close.
|
|
||||||
* NOTE: max HSE is 4 MHz if it is to be used with RTC
|
|
||||||
*/
|
|
||||||
|
|
||||||
putreg32(((uint32_t)7812 << RTC_PRER_PREDIV_S_SHIFT) |
|
|
||||||
((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
|
|
||||||
STM32L4_RTC_PRER);
|
|
||||||
#elif defined(CONFIG_STM32L4_RTC_LSICLOCK)
|
|
||||||
/* Suitable values for 32.000 KHz LSI clock (29.5 - 34 KHz, though) */
|
|
||||||
|
|
||||||
putreg32(((uint32_t)0xf9 << RTC_PRER_PREDIV_S_SHIFT) |
|
|
||||||
((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
|
|
||||||
STM32L4_RTC_PRER);
|
|
||||||
#else /* defined(CONFIG_STM32L4_RTC_LSECLOCK) */
|
|
||||||
/* Correct values for 32.768 KHz LSE clock */
|
|
||||||
|
|
||||||
putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) |
|
|
||||||
((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
|
|
||||||
STM32L4_RTC_PRER);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Exit RTC initialization mode */
|
|
||||||
|
|
||||||
rtc_exitinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Re-enable the write protection for RTC registers */
|
|
||||||
|
|
||||||
rtc_wprlock();
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: rtc_resume
|
* Name: rtc_resume
|
||||||
*
|
*
|
||||||
@ -585,7 +532,7 @@ static void rtc_resume(void)
|
|||||||
|
|
||||||
/* Clear the EXTI Line 18 Pending bit (Connected internally to RTC Alarm) */
|
/* Clear the EXTI Line 18 Pending bit (Connected internally to RTC Alarm) */
|
||||||
|
|
||||||
putreg32((1 << 18), STM32L4_EXTI1_PR);
|
putreg32(EXTI1_RTC_ALARM, STM32L4_EXTI1_PR);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,14 +561,19 @@ static int stm32l4_rtc_alarm_handler(int irq, void *context)
|
|||||||
uint32_t cr;
|
uint32_t cr;
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
|
|
||||||
isr = getreg32(STM32L4_RTC_ISR);
|
/* Enable write access to the backup domain (RTC registers, RTC
|
||||||
|
* backup data registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
(void)stm32l4_pwr_enablebkp(true);
|
||||||
|
|
||||||
/* Check for EXTI from Alarm A or B and handle according */
|
/* Check for EXTI from Alarm A or B and handle according */
|
||||||
|
|
||||||
if ((isr & RTC_ISR_ALRAF) != 0)
|
cr = getreg32(STM32L4_RTC_CR);
|
||||||
|
if ((cr & RTC_CR_ALRAIE) != 0)
|
||||||
{
|
{
|
||||||
cr = getreg32(STM32L4_RTC_CR);
|
isr = getreg32(STM32L4_RTC_ISR);
|
||||||
if ((cr & RTC_CR_ALRAIE) != 0)
|
if ((isr & RTC_ISR_ALRAF) != 0)
|
||||||
{
|
{
|
||||||
cbinfo = &g_alarmcb[RTC_ALARMA];
|
cbinfo = &g_alarmcb[RTC_ALARMA];
|
||||||
if (cbinfo->ac_cb != NULL)
|
if (cbinfo->ac_cb != NULL)
|
||||||
@ -636,18 +588,20 @@ static int stm32l4_rtc_alarm_handler(int irq, void *context)
|
|||||||
|
|
||||||
cb(arg, RTC_ALARMA);
|
cb(arg, RTC_ALARMA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* note, bits 8-13 do /not/ require the write enable procedure */
|
||||||
|
|
||||||
|
isr = getreg32(STM32L4_RTC_ISR);
|
||||||
|
isr &= ~RTC_ISR_ALRAF;
|
||||||
|
putreg32(isr, STM32L4_RTC_ISR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note, bits 8-13 do /not/ require the write enable procedure */
|
|
||||||
|
|
||||||
isr = getreg32(STM32L4_RTC_ISR) & ~RTC_ISR_ALRAF;
|
|
||||||
putreg32(isr, STM32L4_RTC_ISR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((isr & RTC_ISR_ALRBF) != 0)
|
cr = getreg32(STM32L4_RTC_CR);
|
||||||
|
if ((cr & RTC_CR_ALRBIE) != 0)
|
||||||
{
|
{
|
||||||
cr = getreg32(STM32L4_RTC_CR);
|
isr = getreg32(STM32L4_RTC_ISR);
|
||||||
if ((cr & RTC_CR_ALRBIE) != 0)
|
if ((isr & RTC_ISR_ALRBF) != 0)
|
||||||
{
|
{
|
||||||
cbinfo = &g_alarmcb[RTC_ALARMB];
|
cbinfo = &g_alarmcb[RTC_ALARMB];
|
||||||
if (cbinfo->ac_cb != NULL)
|
if (cbinfo->ac_cb != NULL)
|
||||||
@ -662,14 +616,21 @@ static int stm32l4_rtc_alarm_handler(int irq, void *context)
|
|||||||
|
|
||||||
cb(arg, RTC_ALARMB);
|
cb(arg, RTC_ALARMB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* note, bits 8-13 do /not/ require the write enable procedure */
|
||||||
|
|
||||||
|
isr = getreg32(STM32L4_RTC_ISR);
|
||||||
|
isr &= ~RTC_ISR_ALRBF;
|
||||||
|
putreg32(isr, STM32L4_RTC_ISR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* note, bits 8-13 do /not/ require the write enable procedure */
|
|
||||||
|
|
||||||
isr = getreg32(STM32L4_RTC_ISR) & ~RTC_ISR_ALRBF;
|
|
||||||
putreg32(isr, STM32L4_RTC_ISR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Disable write access to the backup domain (RTC registers, RTC backup
|
||||||
|
* data registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
(void)stm32l4_pwr_enablebkp(false);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -771,6 +732,13 @@ static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg)
|
|||||||
|
|
||||||
modifyreg32(STM32L4_RTC_CR, (RTC_CR_ALRAE | RTC_CR_ALRAIE), 0);
|
modifyreg32(STM32L4_RTC_CR, (RTC_CR_ALRAE | RTC_CR_ALRAIE), 0);
|
||||||
|
|
||||||
|
/* Ensure Alarm A flag reset; this is edge triggered */
|
||||||
|
|
||||||
|
isr = getreg32(STM32L4_RTC_ISR) & ~RTC_ISR_ALRAF;
|
||||||
|
putreg32(isr, STM32L4_RTC_ISR);
|
||||||
|
|
||||||
|
/* Wait for Alarm A to be writable */
|
||||||
|
|
||||||
ret = rtchw_check_alrawf();
|
ret = rtchw_check_alrawf();
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
@ -780,14 +748,10 @@ static int rtchw_set_alrmar(rtc_alarmreg_t alarmreg)
|
|||||||
/* Set the RTC Alarm A register */
|
/* Set the RTC Alarm A register */
|
||||||
|
|
||||||
putreg32(alarmreg, STM32L4_RTC_ALRMAR);
|
putreg32(alarmreg, STM32L4_RTC_ALRMAR);
|
||||||
|
putreg32(0, STM32L4_RTC_ALRMASSR);
|
||||||
rtcvdbg(" TR: %08x ALRMAR: %08x\n",
|
rtcvdbg(" TR: %08x ALRMAR: %08x\n",
|
||||||
getreg32(STM32L4_RTC_TR), getreg32(STM32L4_RTC_ALRMAR));
|
getreg32(STM32L4_RTC_TR), getreg32(STM32L4_RTC_ALRMAR));
|
||||||
|
|
||||||
/* ensure Alarm A flag reset; this is edge triggered */
|
|
||||||
|
|
||||||
isr = getreg32(STM32L4_RTC_ISR) & ~RTC_ISR_ALRAF;
|
|
||||||
putreg32(isr, STM32L4_RTC_ISR);
|
|
||||||
|
|
||||||
/* Enable RTC alarm A */
|
/* Enable RTC alarm A */
|
||||||
|
|
||||||
modifyreg32(STM32L4_RTC_CR, 0, (RTC_CR_ALRAE | RTC_CR_ALRAIE));
|
modifyreg32(STM32L4_RTC_CR, 0, (RTC_CR_ALRAE | RTC_CR_ALRAIE));
|
||||||
@ -814,23 +778,26 @@ static int rtchw_set_alrmbr(rtc_alarmreg_t alarmreg)
|
|||||||
|
|
||||||
modifyreg32(STM32L4_RTC_CR, (RTC_CR_ALRBE | RTC_CR_ALRBIE), 0);
|
modifyreg32(STM32L4_RTC_CR, (RTC_CR_ALRBE | RTC_CR_ALRBIE), 0);
|
||||||
|
|
||||||
|
/* Ensure Alarm B flag reset; this is edge triggered */
|
||||||
|
|
||||||
|
isr = getreg32(STM32L4_RTC_ISR) & ~RTC_ISR_ALRBF;
|
||||||
|
putreg32(isr, STM32L4_RTC_ISR);
|
||||||
|
|
||||||
|
/* Wait for Alarm B to be writable */
|
||||||
|
|
||||||
ret = rtchw_check_alrbwf();
|
ret = rtchw_check_alrbwf();
|
||||||
if (ret != OK)
|
if (ret != OK)
|
||||||
{
|
{
|
||||||
goto rtchw_set_alrmbr_exit;
|
goto rtchw_set_alrmbr_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the RTC Alarm register */
|
/* Set the RTC Alarm B register */
|
||||||
|
|
||||||
putreg32(alarmreg, STM32L4_RTC_ALRMBR);
|
putreg32(alarmreg, STM32L4_RTC_ALRMBR);
|
||||||
|
putreg32(0, STM32L4_RTC_ALRMBSSR);
|
||||||
rtcvdbg(" TR: %08x ALRMBR: %08x\n",
|
rtcvdbg(" TR: %08x ALRMBR: %08x\n",
|
||||||
getreg32(STM32L4_RTC_TR), getreg32(STM32L4_RTC_ALRMBR));
|
getreg32(STM32L4_RTC_TR), getreg32(STM32L4_RTC_ALRMBR));
|
||||||
|
|
||||||
/* ensure Alarm B flag reset; this is edge triggered */
|
|
||||||
|
|
||||||
isr = getreg32(STM32L4_RTC_ISR) & ~RTC_ISR_ALRBF;
|
|
||||||
putreg32(isr, STM32L4_RTC_ISR);
|
|
||||||
|
|
||||||
/* Enable RTC alarm B */
|
/* Enable RTC alarm B */
|
||||||
|
|
||||||
modifyreg32(STM32L4_RTC_CR, 0, (RTC_CR_ALRBE | RTC_CR_ALRBIE));
|
modifyreg32(STM32L4_RTC_CR, 0, (RTC_CR_ALRBE | RTC_CR_ALRBIE));
|
||||||
@ -862,183 +829,148 @@ rtchw_set_alrmbr_exit:
|
|||||||
|
|
||||||
int up_rtc_initialize(void)
|
int up_rtc_initialize(void)
|
||||||
{
|
{
|
||||||
|
bool init_stat;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
uint32_t tr_bkp;
|
|
||||||
uint32_t dr_bkp;
|
|
||||||
int ret;
|
int ret;
|
||||||
int maxretry = 10;
|
|
||||||
int nretry = 0;
|
|
||||||
|
|
||||||
/* Clocking for the PWR block must be provided.
|
rtc_dumpregs("Before Initialization");
|
||||||
|
|
||||||
|
/* See if the clock has already been initialized; since it is battery
|
||||||
|
* backed, we don't need or want to re-initialize on each reset.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
rtc_dumpregs("On reset");
|
init_stat = rtc_is_inits();
|
||||||
|
|
||||||
/* Select the clock source */
|
if(!init_stat)
|
||||||
/* Save the token before losing it when resetting */
|
|
||||||
|
|
||||||
regval = getreg32(RTC_MAGIC_REG);
|
|
||||||
|
|
||||||
(void)stm32l4_pwr_enablebkp(true);
|
|
||||||
|
|
||||||
if (regval != RTC_MAGIC)
|
|
||||||
{
|
{
|
||||||
/* We might be changing RTCSEL - to ensure such changes work, we must reset the
|
|
||||||
* backup domain (having backed up the RTC_MAGIC token)
|
|
||||||
*/
|
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_BDRST);
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_BDRST, 0);
|
|
||||||
|
|
||||||
/* Some boards do not have the external 32khz oscillator installed, for those
|
|
||||||
* boards we must fall back to the crummy internal RC clock or the external high
|
|
||||||
* rate clock (which for the STM32L4 must not exceed 4MHz).
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef CONFIG_STM32L4_RTC_HSECLOCK
|
|
||||||
/* Use the HSE clock as the input to the RTC block */
|
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_HSE);
|
|
||||||
|
|
||||||
#elif defined(CONFIG_STM32L4_RTC_LSICLOCK)
|
|
||||||
/* Use the LSI clock as the input to the RTC block */
|
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSI);
|
|
||||||
|
|
||||||
#elif defined(CONFIG_STM32L4_RTC_LSECLOCK)
|
|
||||||
/* Use the LSE clock as the input to the RTC block */
|
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* Enable the RTC Clock by setting the RTCEN bit in the RCC register */
|
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_RTCEN);
|
|
||||||
}
|
|
||||||
else /* The RTC is already in use: check if the clock source is changed */
|
|
||||||
{
|
|
||||||
#if defined(CONFIG_STM32L4_RTC_HSECLOCK) || defined(CONFIG_STM32L4_RTC_LSICLOCK) || \
|
|
||||||
defined(CONFIG_STM32L4_RTC_LSECLOCK)
|
|
||||||
|
|
||||||
uint32_t clksrc = getreg32(STM32L4_RCC_BDCR);
|
|
||||||
|
|
||||||
#if defined(CONFIG_STM32L4_RTC_HSECLOCK)
|
|
||||||
if ((clksrc & RCC_BDCR_RTCSEL_MASK) != RCC_BDCR_RTCSEL_HSE)
|
|
||||||
#elif defined(CONFIG_STM32L4_RTC_LSICLOCK)
|
|
||||||
if ((clksrc & RCC_BDCR_RTCSEL_MASK) != RCC_BDCR_RTCSEL_LSI)
|
|
||||||
#elif defined(CONFIG_STM32L4_RTC_LSECLOCK)
|
|
||||||
if ((clksrc & RCC_BDCR_RTCSEL_MASK) != RCC_BDCR_RTCSEL_LSE)
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
tr_bkp = getreg32(STM32L4_RTC_TR);
|
|
||||||
dr_bkp = getreg32(STM32L4_RTC_DR);
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_BDRST);
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_BDRST, 0);
|
|
||||||
|
|
||||||
#if defined(CONFIG_STM32L4_RTC_HSECLOCK)
|
|
||||||
/* Change to the new clock as the input to the RTC block */
|
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_HSE);
|
|
||||||
|
|
||||||
#elif defined(CONFIG_STM32L4_RTC_LSICLOCK)
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSI);
|
|
||||||
|
|
||||||
#elif defined(CONFIG_STM32L4_RTC_LSECLOCK)
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
putreg32(tr_bkp, STM32L4_RTC_TR);
|
|
||||||
putreg32(dr_bkp, STM32L4_RTC_DR);
|
|
||||||
|
|
||||||
/* Remember that the RTC is initialized */
|
|
||||||
|
|
||||||
putreg32(RTC_MAGIC, RTC_MAGIC_REG);
|
|
||||||
|
|
||||||
/* Enable the RTC Clock by setting the RTCEN bit in the RCC register */
|
|
||||||
|
|
||||||
modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_RTCEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)stm32l4_pwr_enablebkp(false);
|
|
||||||
|
|
||||||
/* 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()).
|
|
||||||
*/
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
/* Wait for the RTC Time and Date registers to be synchronized with RTC APB
|
|
||||||
* clock.
|
|
||||||
*/
|
|
||||||
|
|
||||||
ret = rtc_synchwait();
|
|
||||||
|
|
||||||
/* Check that rtc_syncwait() returned successfully */
|
|
||||||
|
|
||||||
switch (ret)
|
|
||||||
{
|
|
||||||
case OK:
|
|
||||||
{
|
|
||||||
rtclldbg("rtc_syncwait() okay\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
rtclldbg("rtc_syncwait() failed (%d)\n", ret);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (ret != OK && ++nretry < maxretry);
|
|
||||||
|
|
||||||
/* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (regval != RTC_MAGIC)
|
|
||||||
{
|
|
||||||
rtclldbg("Do setup\n");
|
|
||||||
|
|
||||||
/* Perform the one-time setup of the LSE clocking to the RTC */
|
|
||||||
|
|
||||||
ret = rtc_setup();
|
|
||||||
|
|
||||||
/* Enable write access to the backup domain (RTC registers, RTC
|
/* Enable write access to the backup domain (RTC registers, RTC
|
||||||
* backup data registers and backup SRAM).
|
* backup data registers and backup SRAM).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
(void)stm32l4_pwr_enablebkp(true);
|
(void)stm32l4_pwr_enablebkp(true);
|
||||||
|
|
||||||
/* Remember that the RTC is initialized */
|
#if 0
|
||||||
|
/* Do not reset the backup domain; you will lose your clock setup done in *rcc.c */
|
||||||
|
|
||||||
putreg32(RTC_MAGIC, RTC_MAGIC_REG);
|
modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_BDRST);
|
||||||
|
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_BDRST, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_STM32L4_RTC_HSECLOCK)
|
||||||
|
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_HSE);
|
||||||
|
#elif defined(CONFIG_STM32L4_RTC_LSICLOCK)
|
||||||
|
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSI);
|
||||||
|
#elif defined(CONFIG_STM32L4_RTC_LSECLOCK)
|
||||||
|
modifyreg32(STM32L4_RCC_BDCR, RCC_BDCR_RTCSEL_MASK, RCC_BDCR_RTCSEL_LSE);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Enable the RTC Clock by setting the RTCEN bit in the RCC register */
|
||||||
|
|
||||||
|
modifyreg32(STM32L4_RCC_BDCR, 0, RCC_BDCR_RTCEN);
|
||||||
|
|
||||||
|
/* Disable the write protection for RTC registers */
|
||||||
|
|
||||||
|
rtc_wprunlock();
|
||||||
|
|
||||||
|
/* Set Initialization mode */
|
||||||
|
|
||||||
|
if (OK != rtc_enterinit())
|
||||||
|
{
|
||||||
|
/* Enable the write protection for RTC registers */
|
||||||
|
|
||||||
|
rtc_wprlock();
|
||||||
|
|
||||||
|
/* Disable write access to the backup domain (RTC registers, RTC backup
|
||||||
|
* data registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
(void)stm32l4_pwr_enablebkp(false);
|
||||||
|
|
||||||
|
rtc_dumpregs("After Failed Initialization");
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Clear RTC_CR FMT, OSEL and POL Bits */
|
||||||
|
|
||||||
|
regval = getreg32(STM32L4_RTC_CR);
|
||||||
|
regval &= ~(RTC_CR_FMT | RTC_CR_OSEL_MASK | RTC_CR_POL);
|
||||||
|
|
||||||
|
/* Configure RTC pre-scaler with the required values */
|
||||||
|
|
||||||
|
#ifdef CONFIG_STM32L4_RTC_HSECLOCK
|
||||||
|
/* The HSE is divided by 32 prior to the prescaler we set here.
|
||||||
|
* 1953
|
||||||
|
* NOTE: max HSE/32 is 4 MHz if it is to be used with RTC
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* For a 1 MHz clock this yields 0.9999360041 Hz on the second
|
||||||
|
* timer - which is pretty close.
|
||||||
|
*/
|
||||||
|
|
||||||
|
putreg32(((uint32_t)7812 << RTC_PRER_PREDIV_S_SHIFT) |
|
||||||
|
((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
|
||||||
|
STM32L4_RTC_PRER);
|
||||||
|
#elif defined(CONFIG_STM32L4_RTC_LSICLOCK)
|
||||||
|
/* Suitable values for 32.000 KHz LSI clock (29.5 - 34 KHz, though) */
|
||||||
|
|
||||||
|
putreg32(((uint32_t)0xf9 << RTC_PRER_PREDIV_S_SHIFT) |
|
||||||
|
((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
|
||||||
|
STM32L4_RTC_PRER);
|
||||||
|
#else /* defined(CONFIG_STM32L4_RTC_LSECLOCK) */
|
||||||
|
/* Correct values for 32.768 KHz LSE clock */
|
||||||
|
|
||||||
|
putreg32(((uint32_t)0xff << RTC_PRER_PREDIV_S_SHIFT) |
|
||||||
|
((uint32_t)0x7f << RTC_PRER_PREDIV_A_SHIFT),
|
||||||
|
STM32L4_RTC_PRER);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Wait for the RTC Time and Date registers to be synchronized with RTC APB
|
||||||
|
* clock.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ret = rtc_synchwait();
|
||||||
|
(void)ret;
|
||||||
|
|
||||||
|
/* Exit Initialization mode */
|
||||||
|
|
||||||
|
rtc_exitinit();
|
||||||
|
|
||||||
|
/* Enable the write protection for RTC registers */
|
||||||
|
|
||||||
|
rtc_wprlock();
|
||||||
|
|
||||||
|
/* Disable write access to the backup domain (RTC registers, RTC backup
|
||||||
|
* data registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
(void)stm32l4_pwr_enablebkp(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
rtclldbg("Do resume\n");
|
/* Enable write access to the backup domain (RTC registers, RTC
|
||||||
|
* backup data registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
/* RTC already set-up, just resume normal operation */
|
(void)stm32l4_pwr_enablebkp(true);
|
||||||
|
|
||||||
|
/* Disable the write protection for RTC registers */
|
||||||
|
|
||||||
|
//rtc_wprunlock();
|
||||||
|
|
||||||
rtc_resume();
|
rtc_resume();
|
||||||
rtc_dumpregs("Did resume");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable write access to the backup domain (RTC registers, RTC backup
|
/* Enable the write protection for RTC registers */
|
||||||
* data registers and backup SRAM).
|
|
||||||
*/
|
|
||||||
|
|
||||||
(void)stm32l4_pwr_enablebkp(false);
|
//rtc_wprlock();
|
||||||
|
|
||||||
if (ret != OK && nretry > 0)
|
/* Disable write access to the backup domain (RTC registers, RTC backup
|
||||||
{
|
* data registers and backup SRAM).
|
||||||
rtclldbg("setup/resume ran %d times and failed with %d\n",
|
*/
|
||||||
nretry, ret);
|
|
||||||
return -ETIMEDOUT;
|
(void)stm32l4_pwr_enablebkp(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_RTC_ALARM
|
#ifdef CONFIG_RTC_ALARM
|
||||||
@ -1059,9 +991,12 @@ int up_rtc_initialize(void)
|
|||||||
|
|
||||||
g_rtc_enabled = true;
|
g_rtc_enabled = true;
|
||||||
rtc_dumpregs("After Initialization");
|
rtc_dumpregs("After Initialization");
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32l4_rtc_getdatetime_with_subseconds
|
* Name: stm32l4_rtc_getdatetime_with_subseconds
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user