Changes to support fully write protecting the backup domain. N.B. stm32_pwr_enablebkp did not account for the delay from enable to the domain being writable. The KISS solution is a up_udelay. A more complex solution would be a negated write test with restore. From David Sidrane.
This commit is contained in:
parent
2d91128111
commit
7d43cf2087
@ -2,7 +2,7 @@
|
|||||||
* arch/arm/src/stm32/stm32_pwr.c
|
* arch/arm/src/stm32/stm32_pwr.c
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
* Copyright (C) 2011 Uros Platise. All rights reserved.
|
||||||
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2013, 2015 Gregory Nutt. All rights reserved.
|
||||||
* Authors: Uros Platise <uros.platise@isotel.eu>
|
* Authors: Uros Platise <uros.platise@isotel.eu>
|
||||||
* Gregory Nutt <gnutt@nuttx.org>
|
* Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
@ -43,6 +43,7 @@
|
|||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "up_arch.h"
|
#include "up_arch.h"
|
||||||
@ -85,16 +86,64 @@ static inline void stm32_pwr_modifyreg(uint8_t offset, uint16_t clearbits, uint1
|
|||||||
* and backup SRAM).
|
* and backup SRAM).
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* None
|
* protect - sets the write protections
|
||||||
*
|
*
|
||||||
* Returned Values:
|
* Returned Values:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
void stm32_pwr_enablebkp(void)
|
void stm32_pwr_enablebkp(bool writable)
|
||||||
{
|
{
|
||||||
stm32_pwr_modifyreg(STM32_PWR_CR_OFFSET, 0, PWR_CR_DBP);
|
uint16_t regval;
|
||||||
|
|
||||||
|
/* Enable or disable the ability to write*/
|
||||||
|
|
||||||
|
regval = stm32_pwr_getreg(STM32_PWR_CR_OFFSET);
|
||||||
|
regval &= ~PWR_CR_DBP;
|
||||||
|
regval |= writable ? PWR_CR_DBP : 0;
|
||||||
|
stm32_pwr_putreg(STM32_PWR_CR_OFFSET, regval);
|
||||||
|
|
||||||
|
if (writable)
|
||||||
|
{
|
||||||
|
/* Enable does not happen right away */
|
||||||
|
|
||||||
|
up_udelay(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: stm32_pwr_enablebreg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Enables the Backup regulator, the Backup regulator (used to maintain backup
|
||||||
|
* SRAM content in Standby and VBAT modes) is enabled. If BRE is reset, the backup
|
||||||
|
* regulator is switched off. The backup SRAM can still be used but its content will
|
||||||
|
* be lost in the Standby and VBAT modes. Once set, the application must wait that
|
||||||
|
* the Backup Regulator Ready flag (BRR) is set to indicate that the data written
|
||||||
|
* into the RAM will be maintained in the Standby and VBAT modes.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* regon - state to set it to
|
||||||
|
*
|
||||||
|
* Returned Values:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
void stm32_pwr_enablebreg(bool regon)
|
||||||
|
{
|
||||||
|
uint16_t regval;
|
||||||
|
|
||||||
|
regval = stm32_pwr_getreg(STM32_PWR_CSR_OFFSET);
|
||||||
|
regval &= ~PWR_CSR_BRE;
|
||||||
|
regval |= regon ? PWR_CSR_BRE : 0;
|
||||||
|
stm32_pwr_putreg(STM32_PWR_CSR_OFFSET, regval);
|
||||||
|
|
||||||
|
if (regon)
|
||||||
|
{
|
||||||
|
while ((stm32_pwr_getreg(STM32_PWR_CSR_OFFSET) & PWR_CSR_BRR) == 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* arch/arm/src/stm32/stm32_pwr.h
|
* arch/arm/src/stm32/stm32_pwr.h
|
||||||
*
|
*
|
||||||
* Copyright (C) 2009, 2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2009, 2013, 2015 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -42,6 +42,8 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include "chip.h"
|
#include "chip.h"
|
||||||
#include "chip/stm32_pwr.h"
|
#include "chip/stm32_pwr.h"
|
||||||
|
|
||||||
@ -54,7 +56,8 @@
|
|||||||
#undef EXTERN
|
#undef EXTERN
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
#define EXTERN extern "C"
|
#define EXTERN extern "C"
|
||||||
extern "C" {
|
extern "C"
|
||||||
|
{
|
||||||
#else
|
#else
|
||||||
#define EXTERN extern
|
#define EXTERN extern
|
||||||
#endif
|
#endif
|
||||||
@ -71,14 +74,35 @@ extern "C" {
|
|||||||
* and backup SRAM).
|
* and backup SRAM).
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* None
|
* writable - sets the write protections
|
||||||
*
|
*
|
||||||
* Returned Values:
|
* Returned Values:
|
||||||
* None
|
* None
|
||||||
*
|
*
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
void stm32_pwr_enablebkp(void);
|
void stm32_pwr_enablebkp(bool writable);
|
||||||
|
|
||||||
|
/************************************************************************************
|
||||||
|
* Name: stm32_pwr_enablebreg
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Enables the Backup regulator, the Backup regulator (used to maintain backup
|
||||||
|
* SRAM content in Standby and VBAT modes) is enabled. If BRE is reset, the backup
|
||||||
|
* regulator is switched off. The backup SRAM can still be used but its content will
|
||||||
|
* be lost in the Standby and VBAT modes. Once set, the application must wait that
|
||||||
|
* the Backup Regulator Ready flag (BRR) is set to indicate that the data written
|
||||||
|
* into the RAM will be maintained in the Standby and VBAT modes.
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* regon - state to set it to
|
||||||
|
*
|
||||||
|
* Returned Values:
|
||||||
|
* None
|
||||||
|
*
|
||||||
|
************************************************************************************/
|
||||||
|
|
||||||
|
void stm32_pwr_enablebreg(bool regon);
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
* Name: stm32_pwr_setvos
|
* Name: stm32_pwr_setvos
|
||||||
|
@ -39,6 +39,7 @@
|
|||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
@ -219,6 +220,12 @@ static void rtc_dumptime(FAR struct tm *tp, FAR const char *msg)
|
|||||||
|
|
||||||
static void rtc_wprunlock(void)
|
static void rtc_wprunlock(void)
|
||||||
{
|
{
|
||||||
|
/* Enable write access to the backup domain (RTC registers, RTC backup data
|
||||||
|
* registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
stm32_pwr_enablebkp(true);
|
||||||
|
|
||||||
/* The following steps are required to unlock the write protection on all the
|
/* The following steps are required to unlock the write protection on all the
|
||||||
* RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR).
|
* RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR).
|
||||||
*
|
*
|
||||||
@ -251,6 +258,12 @@ static inline void rtc_wprlock(void)
|
|||||||
/* Writing any wrong key reactivates the write protection. */
|
/* Writing any wrong key reactivates the write protection. */
|
||||||
|
|
||||||
putreg32(0xff, STM32_RTC_WPR);
|
putreg32(0xff, STM32_RTC_WPR);
|
||||||
|
|
||||||
|
/* Disable write access to the backup domain (RTC registers, RTC backup data registers
|
||||||
|
* and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
stm32_pwr_enablebkp(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************************
|
/************************************************************************************
|
||||||
@ -569,15 +582,15 @@ static int rtc_resume(void)
|
|||||||
#endif
|
#endif
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Wait for the RTC Time and Date registers to be syncrhonized with RTC APB
|
/* Wait for the RTC Time and Date registers to be synchronized with RTC APB
|
||||||
* clock.
|
* clock.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ret = rtc_synchwait();
|
ret = rtc_synchwait();
|
||||||
|
|
||||||
|
#ifdef CONFIG_RTC_ALARM
|
||||||
/* Clear the RTC alarm flags */
|
/* Clear the RTC alarm flags */
|
||||||
|
|
||||||
#ifdef CONFIG_RTC_ALARM
|
|
||||||
regval = getreg32(STM32_RTC_ISR);
|
regval = getreg32(STM32_RTC_ISR);
|
||||||
regval &= ~(RTC_ISR_ALRAF|RTC_ISR_ALRBF);
|
regval &= ~(RTC_ISR_ALRAF|RTC_ISR_ALRBF);
|
||||||
putreg32(regval, STM32_RTC_ISR);
|
putreg32(regval, STM32_RTC_ISR);
|
||||||
@ -645,11 +658,6 @@ int up_rtcinitialize(void)
|
|||||||
* maximum performance.
|
* maximum performance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Enable access to the backup domain (RTC registers, RTC backup data registers
|
|
||||||
* and backup SRAM).
|
|
||||||
*/
|
|
||||||
|
|
||||||
stm32_pwr_enablebkp();
|
|
||||||
rtc_dumpregs("On reset");
|
rtc_dumpregs("On reset");
|
||||||
|
|
||||||
/* Enable the External Low-Speed (LSE) Oscillator setup the LSE as the RTC clock
|
/* Enable the External Low-Speed (LSE) Oscillator setup the LSE as the RTC clock
|
||||||
@ -677,6 +685,12 @@ int up_rtcinitialize(void)
|
|||||||
|
|
||||||
ret = rtc_setup();
|
ret = rtc_setup();
|
||||||
|
|
||||||
|
/* Enable write access to the backup domain (RTC registers, RTC
|
||||||
|
* backup data registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
stm32_pwr_enablebkp(true);
|
||||||
|
|
||||||
/* Remember that the RTC is initialized */
|
/* Remember that the RTC is initialized */
|
||||||
|
|
||||||
putreg32(RTC_MAGIC, STM32_RTC_BK0R);
|
putreg32(RTC_MAGIC, STM32_RTC_BK0R);
|
||||||
@ -710,9 +724,16 @@ int up_rtcinitialize(void)
|
|||||||
}
|
}
|
||||||
while (ret != OK && ++nretry < maxretry);
|
while (ret != OK && ++nretry < maxretry);
|
||||||
|
|
||||||
|
/* Disable write access to the backup domain (RTC registers, RTC backup
|
||||||
|
* data registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
stm32_pwr_enablebkp(false);
|
||||||
|
|
||||||
if (ret != OK && nretry > 0)
|
if (ret != OK && nretry > 0)
|
||||||
{
|
{
|
||||||
rtclldbg("setup/resume ran %d times and failed with %d\n", nretry, ret);
|
rtclldbg("setup/resume ran %d times and failed with %d\n",
|
||||||
|
nretry, ret);
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1030,4 +1051,3 @@ int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* CONFIG_RTC */
|
#endif /* CONFIG_RTC */
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* With extensions, modifications by:
|
* With extensions, modifications by:
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011-2013 Gregory Nutt. All rights reserved.
|
* Copyright (C) 2011-2013, 2015 Gregory Nutt. All rights reserved.
|
||||||
* Author: Gregroy Nutt <gnutt@nuttx.org>
|
* Author: Gregroy Nutt <gnutt@nuttx.org>
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@ -164,7 +164,7 @@ static alarmcb_t g_alarmcb;
|
|||||||
* Public Data
|
* Public Data
|
||||||
************************************************************************************/
|
************************************************************************************/
|
||||||
|
|
||||||
/* Variable determines the state of the LSE oscilator.
|
/* Variable determines the state of the LSE oscillator.
|
||||||
* Possible errors:
|
* Possible errors:
|
||||||
* - on start-up
|
* - on start-up
|
||||||
* - during operation, reported by LSE interrupt
|
* - during operation, reported by LSE interrupt
|
||||||
@ -358,12 +358,17 @@ static int stm32_rtc_interrupt(int irq, void *context)
|
|||||||
|
|
||||||
int up_rtcinitialize(void)
|
int up_rtcinitialize(void)
|
||||||
{
|
{
|
||||||
/* Set access to the peripheral, enable the backup domain (BKP) and the lower power
|
/* Enable write access to the backup domain (RTC registers, RTC backup data
|
||||||
* extern 32,768Hz (Low-Speed External, LSE) oscillator. Configure the LSE to
|
* registers and backup SRAM).
|
||||||
* drive the RTC.
|
*/
|
||||||
|
|
||||||
|
stm32_pwr_enablebkp(true);
|
||||||
|
|
||||||
|
/* Set access to the peripheral, enable the backup domain (BKP) and the lower
|
||||||
|
* power external 32,768Hz (Low-Speed External, LSE) oscillator. Configure the
|
||||||
|
* LSE to drive the RTC.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
stm32_pwr_enablebkp();
|
|
||||||
stm32_rcc_enablelse();
|
stm32_rcc_enablelse();
|
||||||
|
|
||||||
/* TODO: Get state from this function, if everything is
|
/* TODO: Get state from this function, if everything is
|
||||||
@ -397,12 +402,19 @@ int up_rtcinitialize(void)
|
|||||||
{
|
{
|
||||||
up_waste();
|
up_waste();
|
||||||
}
|
}
|
||||||
|
|
||||||
modifyreg16(STM32_RTC_CRH, 0, RTC_CRH_OWIE);
|
modifyreg16(STM32_RTC_CRH, 0, RTC_CRH_OWIE);
|
||||||
|
|
||||||
/* Alarm Int via EXTI Line */
|
/* Alarm Int via EXTI Line */
|
||||||
|
|
||||||
/* STM32_IRQ_RTCALRM 41: RTC alarm through EXTI line interrupt */
|
/* STM32_IRQ_RTCALRM 41: RTC alarm through EXTI line interrupt */
|
||||||
|
|
||||||
|
/* Disable write access to the backup domain (RTC registers, RTC backup data
|
||||||
|
* registers and backup SRAM).
|
||||||
|
*/
|
||||||
|
|
||||||
|
stm32_pwr_enablebkp(false);
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +446,7 @@ time_t up_rtc_time(void)
|
|||||||
|
|
||||||
/* The RTC counter is read from two 16-bit registers to form one 32-bit
|
/* The RTC counter is read from two 16-bit registers to form one 32-bit
|
||||||
* value. Because these are non-atomic operations, many things can happen
|
* value. Because these are non-atomic operations, many things can happen
|
||||||
* between the two reads: This thread could get suspended or interrrupted
|
* between the two reads: This thread could get suspended or interrupted
|
||||||
* or the lower 16-bit counter could rollover between reads. Disabling
|
* or the lower 16-bit counter could rollover between reads. Disabling
|
||||||
* interrupts will prevent suspensions and interruptions:
|
* interrupts will prevent suspensions and interruptions:
|
||||||
*/
|
*/
|
||||||
@ -502,7 +514,7 @@ int up_rtc_gettime(FAR struct timespec *tp)
|
|||||||
|
|
||||||
/* The RTC counter is read from two 16-bit registers to form one 32-bit
|
/* The RTC counter is read from two 16-bit registers to form one 32-bit
|
||||||
* value. Because these are non-atomic operations, many things can happen
|
* value. Because these are non-atomic operations, many things can happen
|
||||||
* between the two reads: This thread could get suspended or interrrupted
|
* between the two reads: This thread could get suspended or interrupted
|
||||||
* or the lower 16-bit counter could rollover between reads. Disabling
|
* or the lower 16-bit counter could rollover between reads. Disabling
|
||||||
* interrupts will prevent suspensions and interruptions:
|
* interrupts will prevent suspensions and interruptions:
|
||||||
*/
|
*/
|
||||||
@ -643,6 +655,7 @@ int stm32_rtc_setalarm(FAR const struct timespec *tp, alarmcb_t callback)
|
|||||||
|
|
||||||
ret = OK;
|
ret = OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -684,6 +697,7 @@ int stm32_rtc_cancelalarm(void)
|
|||||||
|
|
||||||
ret = OK;
|
ret = OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user