mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-12-15 01:23:49 +01:00
Merge pull request #21837 from crasbe/pr/nucleo-wl55jc-rtc-support_new
boards/nucleo-wl55jc, cpu/stm32: enable RTC support, increase RTC accuracy
This commit is contained in:
commit
b1256ffb1b
@ -5,6 +5,7 @@ CPU_MODEL = stm32wle5jc
|
||||
FEATURES_PROVIDED += periph_adc
|
||||
FEATURES_PROVIDED += periph_i2c
|
||||
FEATURES_PROVIDED += periph_lpuart
|
||||
FEATURES_PROVIDED += periph_rtc
|
||||
FEATURES_PROVIDED += periph_rtt
|
||||
FEATURES_PROVIDED += periph_spi
|
||||
FEATURES_PROVIDED += periph_timer
|
||||
|
||||
@ -5,6 +5,7 @@ CPU_MODEL = stm32wl55jc
|
||||
FEATURES_PROVIDED += periph_adc
|
||||
FEATURES_PROVIDED += periph_i2c
|
||||
FEATURES_PROVIDED += periph_lpuart
|
||||
FEATURES_PROVIDED += periph_rtc
|
||||
FEATURES_PROVIDED += periph_rtt
|
||||
FEATURES_PROVIDED += periph_spi
|
||||
FEATURES_PROVIDED += periph_timer
|
||||
|
||||
@ -35,7 +35,8 @@ ifneq (,$(filter $(CPU_FAM),c0 f0 f1 f3 g0 g4 l0 l1 l4 l5 u5 wb wl))
|
||||
endif
|
||||
|
||||
ifneq (,$(filter $(CPU_FAM),f0 f2 f3 f4 f7 l0 l1 l4 l5 u5 wb wl))
|
||||
CPU_MODELS_WITHOUT_RTC_BKPR += stm32f030% stm32f070%
|
||||
CPU_MODELS_WITHOUT_RTC_BKPR += stm32f030% stm32f070% \
|
||||
stm32f302%
|
||||
ifeq (,$(filter $(CPU_MODELS_WITHOUT_RTC_BKPR),$(CPU_MODEL)))
|
||||
FEATURES_PROVIDED += periph_rtc_mem
|
||||
endif
|
||||
|
||||
@ -26,109 +26,112 @@
|
||||
|
||||
/* map some CPU specific register names */
|
||||
#if defined (CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
||||
#define EN_REG (RCC->CSR)
|
||||
#define EN_BIT (RCC_CSR_RTCEN)
|
||||
#define CLKSEL_MASK (RCC_CSR_RTCSEL)
|
||||
#define CLKSEL_LSE (RCC_CSR_RTCSEL_LSE)
|
||||
#define CLKSEL_LSI (RCC_CSR_RTCSEL_LSI)
|
||||
# define EN_REG (RCC->CSR)
|
||||
# define EN_BIT (RCC_CSR_RTCEN)
|
||||
# define CLKSEL_MASK (RCC_CSR_RTCSEL)
|
||||
# define CLKSEL_LSE (RCC_CSR_RTCSEL_LSE)
|
||||
# define CLKSEL_LSI (RCC_CSR_RTCSEL_LSI)
|
||||
#else
|
||||
#define EN_REG (RCC->BDCR)
|
||||
#define EN_BIT (RCC_BDCR_RTCEN)
|
||||
#define CLKSEL_MASK (RCC_BDCR_RTCSEL_0 | RCC_BDCR_RTCSEL_1)
|
||||
#define CLKSEL_LSE (RCC_BDCR_RTCSEL_0)
|
||||
#define CLKSEL_LSI (RCC_BDCR_RTCSEL_1)
|
||||
# define EN_REG (RCC->BDCR)
|
||||
# define EN_BIT (RCC_BDCR_RTCEN)
|
||||
# define CLKSEL_MASK (RCC_BDCR_RTCSEL_0 | RCC_BDCR_RTCSEL_1)
|
||||
# define CLKSEL_LSE (RCC_BDCR_RTCSEL_0)
|
||||
# define CLKSEL_LSI (RCC_BDCR_RTCSEL_1)
|
||||
#endif
|
||||
|
||||
/* map some EXTI register names */
|
||||
#if defined(CPU_FAM_STM32L4) || defined(CPU_FAM_STM32WB) || \
|
||||
defined(CPU_FAM_STM32G4)
|
||||
#define EXTI_REG_RTSR (EXTI->RTSR1)
|
||||
#define EXTI_REG_FTSR (EXTI->FTSR1)
|
||||
#define EXTI_REG_PR (EXTI->PR1)
|
||||
#define EXTI_REG_IMR (EXTI->IMR1)
|
||||
#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5)
|
||||
#define EXTI_REG_RTSR (EXTI->RTSR1)
|
||||
#define EXTI_REG_FTSR (EXTI->FTSR1)
|
||||
#define EXTI_REG_PR (EXTI->RPR1)
|
||||
#define EXTI_REG_IMR (EXTI->IMR1)
|
||||
# define EXTI_REG_RTSR (EXTI->RTSR1)
|
||||
# define EXTI_REG_FTSR (EXTI->FTSR1)
|
||||
# define EXTI_REG_PR (EXTI->PR1)
|
||||
# define EXTI_REG_IMR (EXTI->IMR1)
|
||||
#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL)
|
||||
# define EXTI_REG_RTSR (EXTI->RTSR1)
|
||||
# define EXTI_REG_FTSR (EXTI->FTSR1)
|
||||
# define EXTI_REG_PR (EXTI->RPR1)
|
||||
# define EXTI_REG_IMR (EXTI->IMR1)
|
||||
#elif defined(CPU_FAM_STM32L5)
|
||||
#define EXTI_REG_IMR (EXTI->IMR1)
|
||||
# define EXTI_REG_IMR (EXTI->IMR1)
|
||||
#else
|
||||
#define EXTI_REG_RTSR (EXTI->RTSR)
|
||||
#define EXTI_REG_FTSR (EXTI->FTSR)
|
||||
#define EXTI_REG_PR (EXTI->PR)
|
||||
#define EXTI_REG_IMR (EXTI->IMR)
|
||||
# define EXTI_REG_RTSR (EXTI->RTSR)
|
||||
# define EXTI_REG_FTSR (EXTI->FTSR)
|
||||
# define EXTI_REG_PR (EXTI->PR)
|
||||
# define EXTI_REG_IMR (EXTI->IMR)
|
||||
#endif
|
||||
|
||||
/* map some RTC register names and bitfield */
|
||||
#if defined(CPU_FAM_STM32G4) || defined(CPU_FAM_STM32G0)
|
||||
#define RTC_REG_ISR RTC->ICSR
|
||||
#define RTC_REG_SR RTC->SR
|
||||
#define RTC_REG_SCR RTC->SCR
|
||||
#define RTC_ISR_RSF RTC_ICSR_RSF
|
||||
#define RTC_ISR_INIT RTC_ICSR_INIT
|
||||
#define RTC_ISR_INITF RTC_ICSR_INITF
|
||||
#define RTC_ISR_ALRAWF RTC_ICSR_ALRAWF
|
||||
#define RTC_ISR_ALRAF RTC_SR_ALRAF
|
||||
#elif defined(CPU_FAM_STM32L5)
|
||||
#define RTC_REG_ISR RTC->ICSR
|
||||
#define RTC_REG_SR RTC->SR
|
||||
#define RTC_REG_SCR RTC->SCR
|
||||
#define RTC_ISR_RSF RTC_ICSR_RSF
|
||||
#define RTC_ISR_INIT RTC_ICSR_INIT
|
||||
#define RTC_ISR_INITF RTC_ICSR_INITF
|
||||
# define RTC_REG_ISR RTC->ICSR
|
||||
# define RTC_REG_SR RTC->SR
|
||||
# define RTC_REG_SCR RTC->SCR
|
||||
# define RTC_ISR_RSF RTC_ICSR_RSF
|
||||
# define RTC_ISR_INIT RTC_ICSR_INIT
|
||||
# define RTC_ISR_INITF RTC_ICSR_INITF
|
||||
# define RTC_ISR_INITS RTC_ICSR_INITS
|
||||
# define RTC_ISR_ALRAWF RTC_ICSR_ALRAWF
|
||||
# define RTC_ISR_ALRAF RTC_SR_ALRAF
|
||||
#elif defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL)
|
||||
# define RTC_REG_ISR RTC->ICSR
|
||||
# define RTC_REG_SR RTC->SR
|
||||
# define RTC_REG_SCR RTC->SCR
|
||||
# define RTC_ISR_RSF RTC_ICSR_RSF
|
||||
# define RTC_ISR_INIT RTC_ICSR_INIT
|
||||
# define RTC_ISR_INITF RTC_ICSR_INITF
|
||||
# define RTC_ISR_INITS RTC_ICSR_INITS
|
||||
#elif defined(CPU_FAM_STM32U5)
|
||||
#define RTC_REG_ISR RTC->ICSR
|
||||
#define RTC_REG_SR RTC->SR
|
||||
#define RTC_REG_SCR RTC->SCR
|
||||
#define RTC_ISR_RSF RTC_ICSR_RSF
|
||||
#define RTC_ISR_INIT RTC_ICSR_INIT
|
||||
#define RTC_ISR_INITF RTC_ICSR_INITF
|
||||
#define RTC_ISR_ALRAF RTC_SR_ALRAF
|
||||
# define RTC_REG_ISR RTC->ICSR
|
||||
# define RTC_REG_SR RTC->SR
|
||||
# define RTC_REG_SCR RTC->SCR
|
||||
# define RTC_ISR_RSF RTC_ICSR_RSF
|
||||
# define RTC_ISR_INIT RTC_ICSR_INIT
|
||||
# define RTC_ISR_INITF RTC_ICSR_INITF
|
||||
# define RTC_ISR_INITS RTC_ICSR_INITS
|
||||
# define RTC_ISR_ALRAF RTC_SR_ALRAF
|
||||
#else
|
||||
#define RTC_REG_ISR RTC->ISR
|
||||
# define RTC_REG_ISR RTC->ISR
|
||||
#endif
|
||||
|
||||
/* interrupt line name mapping */
|
||||
#if defined(CPU_FAM_STM32F0) || defined(CPU_FAM_STM32L0) || \
|
||||
defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5)
|
||||
#define IRQN (RTC_IRQn)
|
||||
#define ISR_NAME isr_rtc
|
||||
# define IRQN (RTC_IRQn)
|
||||
# define ISR_NAME isr_rtc
|
||||
#elif defined(CPU_FAM_STM32G0)
|
||||
#define IRQN (RTC_TAMP_IRQn)
|
||||
#define ISR_NAME isr_rtc_tamp
|
||||
# define IRQN (RTC_TAMP_IRQn)
|
||||
# define ISR_NAME isr_rtc_tamp
|
||||
#else
|
||||
#define IRQN (RTC_Alarm_IRQn)
|
||||
#define ISR_NAME isr_rtc_alarm
|
||||
# define IRQN (RTC_Alarm_IRQn)
|
||||
# define ISR_NAME isr_rtc_alarm
|
||||
#endif
|
||||
|
||||
/* EXTI bitfield mapping */
|
||||
#if defined(CPU_FAM_STM32L4)
|
||||
#define EXTI_IMR_BIT (EXTI_IMR1_IM18)
|
||||
#define EXTI_FTSR_BIT (EXTI_FTSR1_FT18)
|
||||
#define EXTI_RTSR_BIT (EXTI_RTSR1_RT18)
|
||||
#define EXTI_PR_BIT (EXTI_PR1_PIF18)
|
||||
#elif defined(CPU_FAM_STM32L5)
|
||||
#define EXTI_IMR_BIT (EXTI_IMR1_IM17)
|
||||
# define EXTI_IMR_BIT (EXTI_IMR1_IM18)
|
||||
# define EXTI_FTSR_BIT (EXTI_FTSR1_FT18)
|
||||
# define EXTI_RTSR_BIT (EXTI_RTSR1_RT18)
|
||||
# define EXTI_PR_BIT (EXTI_PR1_PIF18)
|
||||
#elif defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL)
|
||||
# define EXTI_IMR_BIT (EXTI_IMR1_IM17)
|
||||
#elif defined(CPU_FAM_STM32WB) || defined(CPU_FAM_STM32G4)
|
||||
#define EXTI_IMR_BIT (EXTI_IMR1_IM17)
|
||||
#define EXTI_FTSR_BIT (EXTI_FTSR1_FT17)
|
||||
#define EXTI_RTSR_BIT (EXTI_RTSR1_RT17)
|
||||
#define EXTI_PR_BIT (EXTI_PR1_PIF17)
|
||||
# define EXTI_IMR_BIT (EXTI_IMR1_IM17)
|
||||
# define EXTI_FTSR_BIT (EXTI_FTSR1_FT17)
|
||||
# define EXTI_RTSR_BIT (EXTI_RTSR1_RT17)
|
||||
# define EXTI_PR_BIT (EXTI_PR1_PIF17)
|
||||
#elif defined(CPU_FAM_STM32G0) || defined(CPU_FAM_STM32U5)
|
||||
#define EXTI_IMR_BIT (EXTI_IMR1_IM11)
|
||||
#define EXTI_FTSR_BIT (EXTI_FTSR1_FT11)
|
||||
#define EXTI_RTSR_BIT (EXTI_RTSR1_RT11)
|
||||
#define EXTI_PR_BIT (EXTI_RPR1_RPIF11)
|
||||
# define EXTI_IMR_BIT (EXTI_IMR1_IM11)
|
||||
# define EXTI_FTSR_BIT (EXTI_FTSR1_FT11)
|
||||
# define EXTI_RTSR_BIT (EXTI_RTSR1_RT11)
|
||||
# define EXTI_PR_BIT (EXTI_RPR1_RPIF11)
|
||||
#else
|
||||
#if defined(CPU_FAM_STM32L0)
|
||||
#define EXTI_IMR_BIT (EXTI_IMR_IM17)
|
||||
#else
|
||||
#define EXTI_IMR_BIT (EXTI_IMR_MR17)
|
||||
#endif
|
||||
#define EXTI_FTSR_BIT (EXTI_FTSR_TR17)
|
||||
#define EXTI_RTSR_BIT (EXTI_RTSR_TR17)
|
||||
#define EXTI_PR_BIT (EXTI_PR_PR17)
|
||||
# if defined(CPU_FAM_STM32L0)
|
||||
# define EXTI_IMR_BIT (EXTI_IMR_IM17)
|
||||
# else
|
||||
# define EXTI_IMR_BIT (EXTI_IMR_MR17)
|
||||
# endif
|
||||
# define EXTI_FTSR_BIT (EXTI_FTSR_TR17)
|
||||
# define EXTI_RTSR_BIT (EXTI_RTSR_TR17)
|
||||
# define EXTI_PR_BIT (EXTI_PR_PR17)
|
||||
#endif
|
||||
|
||||
/* write protection values */
|
||||
@ -147,62 +150,62 @@
|
||||
#define ALRM_M_MASK (RTC_ALRMAR_MNU | RTC_ALRMAR_MNT)
|
||||
#define ALRM_S_MASK (RTC_ALRMAR_SU | RTC_ALRMAR_ST)
|
||||
#ifndef RTC_DR_YU_Pos
|
||||
#define RTC_DR_YU_Pos (16U)
|
||||
# define RTC_DR_YU_Pos (16U)
|
||||
#endif
|
||||
#ifndef RTC_DR_MU_Pos
|
||||
#define RTC_DR_MU_Pos (8U)
|
||||
# define RTC_DR_MU_Pos (8U)
|
||||
#endif
|
||||
#ifndef RTC_DR_DU_Pos
|
||||
#define RTC_DR_DU_Pos (0U)
|
||||
# define RTC_DR_DU_Pos (0U)
|
||||
#endif
|
||||
#ifndef RTC_TR_HU_Pos
|
||||
#define RTC_TR_HU_Pos (16U)
|
||||
# define RTC_TR_HU_Pos (16U)
|
||||
#endif
|
||||
#ifndef RTC_TR_MNU_Pos
|
||||
#define RTC_TR_MNU_Pos (8U)
|
||||
# define RTC_TR_MNU_Pos (8U)
|
||||
#endif
|
||||
#ifndef RTC_TR_SU_Pos
|
||||
#define RTC_TR_SU_Pos (0U)
|
||||
# define RTC_TR_SU_Pos (0U)
|
||||
#endif
|
||||
#ifndef RTC_ALRMAR_DU_Pos
|
||||
#define RTC_ALRMAR_DU_Pos (24U)
|
||||
# define RTC_ALRMAR_DU_Pos (24U)
|
||||
#endif
|
||||
#ifndef RTC_ALRMAR_HU_Pos
|
||||
#define RTC_ALRMAR_HU_Pos (16U)
|
||||
# define RTC_ALRMAR_HU_Pos (16U)
|
||||
#endif
|
||||
#ifndef RTC_ALRMAR_MNU_Pos
|
||||
#define RTC_ALRMAR_MNU_Pos (8U)
|
||||
# define RTC_ALRMAR_MNU_Pos (8U)
|
||||
#endif
|
||||
#ifndef RTC_ALRMAR_SU_Pos
|
||||
#define RTC_ALRMAR_SU_Pos (0U)
|
||||
# define RTC_ALRMAR_SU_Pos (0U)
|
||||
#endif
|
||||
|
||||
/* figure out sync and async prescaler */
|
||||
#if IS_ACTIVE(CONFIG_BOARD_HAS_LSE)
|
||||
#define PRE_SYNC (255)
|
||||
#define PRE_ASYNC (127)
|
||||
# define PRE_SYNC (255)
|
||||
# define PRE_ASYNC (127)
|
||||
#elif (CLOCK_LSI == 40000)
|
||||
#define PRE_SYNC (319)
|
||||
#define PRE_ASYNC (124)
|
||||
# define PRE_SYNC (319)
|
||||
# define PRE_ASYNC (124)
|
||||
#elif (CLOCK_LSI == 37000)
|
||||
#define PRE_SYNC (295)
|
||||
#define PRE_ASYNC (124)
|
||||
# define PRE_SYNC (295)
|
||||
# define PRE_ASYNC (124)
|
||||
#elif (CLOCK_LSI == 32000)
|
||||
#define PRE_SYNC (249)
|
||||
#define PRE_ASYNC (127)
|
||||
# define PRE_SYNC (249)
|
||||
# define PRE_ASYNC (127)
|
||||
#else
|
||||
#error "rtc: unable to determine RTC SYNC and ASYNC prescalers from LSI value"
|
||||
# error "RTC: unable to determine RTC SYNC and ASYNC prescalers from LSI value"
|
||||
#endif
|
||||
|
||||
/* struct tm counts years since 1900 but RTC has only two-digit year, hence the offset */
|
||||
#define YEAR_OFFSET (RIOT_EPOCH - 1900)
|
||||
|
||||
/* Use a magic number to determine the initial RTC source. This will be used
|
||||
to know if a reset of the RTC is required at initialization. */
|
||||
* to know if a reset of the RTC is required at initialization. */
|
||||
#if IS_ACTIVE(CONFIG_BOARD_HAS_LSE)
|
||||
#define MAGIC_CLCK_NUMBER (0x1970)
|
||||
# define MAGIC_CLCK_NUMBER (0x1970)
|
||||
#else
|
||||
#define MAGIC_CLCK_NUMBER (0x1971)
|
||||
# define MAGIC_CLCK_NUMBER (0x1971)
|
||||
#endif
|
||||
|
||||
static struct {
|
||||
@ -228,6 +231,14 @@ static int bcd2val(uint32_t val, int shift, uint32_t mask)
|
||||
return (((tmp >> 4) * 10) + (tmp & 0x0f));
|
||||
}
|
||||
|
||||
void rtc_lock(void)
|
||||
{
|
||||
/* lock RTC device */
|
||||
RTC->WPR = 0xff;
|
||||
/* disable backup clock domain */
|
||||
stmclk_dbp_lock();
|
||||
}
|
||||
|
||||
void rtc_unlock(void)
|
||||
{
|
||||
/* enable backup clock domain */
|
||||
@ -235,20 +246,22 @@ void rtc_unlock(void)
|
||||
/* unlock RTC */
|
||||
RTC->WPR = WPK1;
|
||||
RTC->WPR = WPK2;
|
||||
}
|
||||
|
||||
static inline void rtc_enter_init_mode(void)
|
||||
{
|
||||
rtc_unlock();
|
||||
/* enter RTC init mode */
|
||||
RTC_REG_ISR |= RTC_ISR_INIT;
|
||||
while (!(RTC_REG_ISR & RTC_ISR_INITF)) {}
|
||||
}
|
||||
|
||||
void rtc_lock(void)
|
||||
static inline void rtc_exit_init_mode(void)
|
||||
{
|
||||
/* exit RTC init mode */
|
||||
RTC_REG_ISR &= ~RTC_ISR_INIT;
|
||||
while (RTC_REG_ISR & RTC_ISR_INITF) {}
|
||||
/* lock RTC device */
|
||||
RTC->WPR = 0xff;
|
||||
/* disable backup clock domain */
|
||||
stmclk_dbp_lock();
|
||||
rtc_lock();
|
||||
}
|
||||
|
||||
void rtc_init(void)
|
||||
@ -256,47 +269,53 @@ void rtc_init(void)
|
||||
stmclk_dbp_unlock();
|
||||
#if defined(CPU_FAM_STM32L0) || defined(CPU_FAM_STM32L1)
|
||||
/* Compare the stored magic number with the current one. If it's different
|
||||
it means the clock source has changed and thus a RTC reset is
|
||||
required. */
|
||||
* it means the clock source has changed and thus a RTC reset is
|
||||
* required. */
|
||||
if (RTC->BKP0R != MAGIC_CLCK_NUMBER) {
|
||||
RCC->CSR |= RCC_CSR_RTCRST;
|
||||
RCC->CSR &= ~RCC_CSR_RTCRST;
|
||||
RTC->BKP0R = MAGIC_CLCK_NUMBER; /* Store the new magic number */
|
||||
}
|
||||
#endif
|
||||
stmclk_dbp_lock();
|
||||
|
||||
/* enable low frequency clock */
|
||||
stmclk_enable_lfclk();
|
||||
|
||||
/* select input clock and enable the RTC */
|
||||
stmclk_dbp_unlock();
|
||||
#if defined(CPU_FAM_STM32L5)
|
||||
#if defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL)
|
||||
periph_clk_en(APB1, RCC_APB1ENR1_RTCAPBEN);
|
||||
#elif defined(CPU_FAM_STM32G0)
|
||||
periph_clk_en(APB1, RCC_APBENR1_RTCAPBEN);
|
||||
#elif defined(CPU_FAM_STM32U5)
|
||||
periph_clk_en(APB3, RCC_APB3ENR_RTCAPBEN);
|
||||
#endif
|
||||
EN_REG &= ~(CLKSEL_MASK);
|
||||
|
||||
#if IS_ACTIVE(CONFIG_BOARD_HAS_LSE)
|
||||
EN_REG |= (CLKSEL_LSE | EN_BIT);
|
||||
if ((EN_REG & (CLKSEL_MASK | EN_BIT)) != (CLKSEL_LSE | EN_BIT)) {
|
||||
EN_REG &= ~(CLKSEL_MASK);
|
||||
EN_REG |= (CLKSEL_LSE | EN_BIT);
|
||||
}
|
||||
#else
|
||||
EN_REG |= (CLKSEL_LSI | EN_BIT);
|
||||
if ((EN_REG & (CLKSEL_MASK | EN_BIT)) != (CLKSEL_LSI | EN_BIT)) {
|
||||
EN_REG &= ~(CLKSEL_MASK);
|
||||
EN_REG |= (CLKSEL_LSI | EN_BIT);
|
||||
}
|
||||
#endif
|
||||
|
||||
rtc_unlock();
|
||||
/* reset configuration */
|
||||
RTC->CR = 0;
|
||||
RTC_REG_ISR = RTC_ISR_INIT;
|
||||
/* configure prescaler (RTC PRER) */
|
||||
RTC->PRER = (PRE_SYNC | (PRE_ASYNC << 16));
|
||||
rtc_lock();
|
||||
if (!(RTC_REG_ISR & RTC_ISR_INITS))
|
||||
{
|
||||
rtc_enter_init_mode();
|
||||
/* reset configuration */
|
||||
RTC->CR = 0;
|
||||
/* configure prescaler (RTC PRER) */
|
||||
RTC->PRER = (PRE_SYNC | (PRE_ASYNC << 16));
|
||||
rtc_exit_init_mode();
|
||||
}
|
||||
|
||||
/* configure the EXTI channel, as RTC interrupts are routed through it.
|
||||
* Needs to be configured to trigger on rising edges. */
|
||||
EXTI_REG_IMR |= EXTI_IMR_BIT;
|
||||
#if !defined(CPU_FAM_STM32L5)
|
||||
#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL))
|
||||
EXTI_REG_FTSR &= ~(EXTI_FTSR_BIT);
|
||||
EXTI_REG_RTSR |= EXTI_RTSR_BIT;
|
||||
EXTI_REG_PR = EXTI_PR_BIT;
|
||||
@ -310,15 +329,14 @@ int rtc_set_time(struct tm *time)
|
||||
/* normalize input */
|
||||
rtc_tm_normalize(time);
|
||||
|
||||
rtc_unlock();
|
||||
|
||||
rtc_enter_init_mode();
|
||||
RTC->DR = (val2bcd((time->tm_year - YEAR_OFFSET), RTC_DR_YU_Pos, DR_Y_MASK) |
|
||||
val2bcd(time->tm_mon + 1, RTC_DR_MU_Pos, DR_M_MASK) |
|
||||
val2bcd(time->tm_mday, RTC_DR_DU_Pos, DR_D_MASK));
|
||||
RTC->TR = (val2bcd(time->tm_hour, RTC_TR_HU_Pos, TR_H_MASK) |
|
||||
val2bcd(time->tm_min, RTC_TR_MNU_Pos, TR_M_MASK) |
|
||||
val2bcd(time->tm_sec, RTC_TR_SU_Pos, TR_S_MASK));
|
||||
rtc_lock();
|
||||
rtc_exit_init_mode();
|
||||
while (!(RTC_REG_ISR & RTC_ISR_RSF)) {}
|
||||
|
||||
return 0;
|
||||
@ -326,6 +344,16 @@ int rtc_set_time(struct tm *time)
|
||||
|
||||
int rtc_get_time(struct tm *time)
|
||||
{
|
||||
/* After waking up from standby, the RSF flag has to be manually cleared.
|
||||
* To be safe, we do it every time even though we might not have been in
|
||||
* standby before. */
|
||||
rtc_unlock();
|
||||
RTC_REG_ISR &= ~RTC_ISR_RSF;
|
||||
rtc_lock();
|
||||
|
||||
/* waiting for the RSF bit to be set again before accessing the time */
|
||||
while (!(RTC_REG_ISR & RTC_ISR_RSF)) {};
|
||||
|
||||
/* save current time */
|
||||
uint32_t tr = RTC->TR;
|
||||
uint32_t dr = RTC->DR;
|
||||
@ -360,7 +388,7 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg)
|
||||
val2bcd(time->tm_sec, RTC_ALRMAR_SU_Pos, ALRM_S_MASK));
|
||||
|
||||
/* Enable Alarm A */
|
||||
#if !defined(CPU_FAM_STM32L5)
|
||||
#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL))
|
||||
RTC_REG_ISR &= ~(RTC_ISR_ALRAF);
|
||||
#else
|
||||
RTC_REG_SCR = RTC_SCR_CALRAF;
|
||||
@ -393,7 +421,7 @@ void rtc_clear_alarm(void)
|
||||
|
||||
RTC->CR &= ~(RTC_CR_ALRAE | RTC_CR_ALRAIE);
|
||||
|
||||
#if !defined(CPU_FAM_STM32L5) && !defined(CPU_FAM_STM32U5)
|
||||
#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32U5) || defined(CPU_FAM_STM32WL))
|
||||
while (!(RTC_REG_ISR & RTC_ISR_ALRAWF)) {}
|
||||
#else
|
||||
RTC_REG_SCR = RTC_SCR_CALRAF;
|
||||
@ -421,7 +449,8 @@ void rtc_poweroff(void)
|
||||
|
||||
void ISR_NAME(void)
|
||||
{
|
||||
#if !defined(CPU_FAM_STM32L5) && !defined(CPU_FAM_STM32G0) && !defined(CPU_FAM_STM32U5)
|
||||
#if !(defined(CPU_FAM_STM32L5) || defined(CPU_FAM_STM32WL) || defined(CPU_FAM_STM32G0) || \
|
||||
defined(CPU_FAM_STM32U5))
|
||||
if (RTC_REG_ISR & RTC_ISR_ALRAF) {
|
||||
if (isr_ctx.cb != NULL) {
|
||||
isr_ctx.cb(isr_ctx.arg);
|
||||
|
||||
@ -138,7 +138,7 @@ int main(void)
|
||||
}
|
||||
|
||||
time = (struct tm){
|
||||
.tm_year = 2020 - 1900, /* years are counted from 1900 */
|
||||
.tm_year = 2025 - 1900, /* years are counted from 1900 */
|
||||
.tm_mon = 1, /* 0 = January, 11 = December */
|
||||
.tm_mday = 28,
|
||||
.tm_hour = 23,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user