New RTCv3 driver for STM32G0xx and STM32G4xx.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13116 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
5749bfc979
commit
68da5e845a
|
@ -80,13 +80,14 @@
|
||||||
/*
|
/*
|
||||||
* Shared IRQ settings.
|
* Shared IRQ settings.
|
||||||
*/
|
*/
|
||||||
#define STM32_IRQ_EXTI0_1_PRIORITY 2
|
#define STM32_IRQ_EXTI0_1_PRIORITY 3
|
||||||
#define STM32_IRQ_EXTI2_3_PRIORITY 2
|
#define STM32_IRQ_EXTI2_3_PRIORITY 3
|
||||||
#define STM32_IRQ_EXTI4_15_PRIORITY 2
|
#define STM32_IRQ_EXTI4_15_PRIORITY 3
|
||||||
|
#define STM32_IRQ_EXTI1921_PRIORITY 3
|
||||||
|
|
||||||
#define STM32_IRQ_USART1_PRIORITY 2
|
#define STM32_IRQ_USART1_PRIORITY 2
|
||||||
#define STM32_IRQ_USART2_PRIORITY 2
|
#define STM32_IRQ_USART2_PRIORITY 2
|
||||||
#define STM32_IRQ_USART3_4_LP1_PRIORITY 1
|
#define STM32_IRQ_USART3_4_LP1_PRIORITY 2
|
||||||
|
|
||||||
#define STM32_IRQ_TIM1_UP_PRIORITY 1
|
#define STM32_IRQ_TIM1_UP_PRIORITY 1
|
||||||
#define STM32_IRQ_TIM1_CC_PRIORITY 1
|
#define STM32_IRQ_TIM1_CC_PRIORITY 1
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
ifeq ($(USE_SMART_BUILD),yes)
|
||||||
|
ifneq ($(findstring HAL_USE_RTC TRUE,$(HALCONF)),)
|
||||||
|
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
PLATFORMSRC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/hal_rtc_lld.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
PLATFORMINC += $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3
|
|
@ -0,0 +1,665 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2019 Giovanni Di Sirio
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
Concepts and parts of this file have been contributed by Uladzimir Pylinsky
|
||||||
|
aka barthess.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file RTCv3/hal_rtc_lld.c
|
||||||
|
* @brief STM32 RTC low level driver.
|
||||||
|
*
|
||||||
|
* @addtogroup RTC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "hal.h"
|
||||||
|
|
||||||
|
#if HAL_USE_RTC || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local definitions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define RTC_TR_PM_OFFSET RTC_TR_PM_Pos
|
||||||
|
#define RTC_TR_HT_OFFSET RTC_TR_HT_Pos
|
||||||
|
#define RTC_TR_HU_OFFSET RTC_TR_HU_Pos
|
||||||
|
#define RTC_TR_MNT_OFFSET RTC_TR_MNT_Pos
|
||||||
|
#define RTC_TR_MNU_OFFSET RTC_TR_MNU_Pos
|
||||||
|
#define RTC_TR_ST_OFFSET RTC_TR_ST_Pos
|
||||||
|
#define RTC_TR_SU_OFFSET RTC_TR_SU_Pos
|
||||||
|
|
||||||
|
#define RTC_DR_YT_OFFSET RTC_DR_YT_Pos
|
||||||
|
#define RTC_DR_YU_OFFSET RTC_DR_YU_Pos
|
||||||
|
#define RTC_DR_WDU_OFFSET RTC_DR_WDU_Pos
|
||||||
|
#define RTC_DR_MT_OFFSET RTC_DR_MT_Pos
|
||||||
|
#define RTC_DR_MU_OFFSET RTC_DR_MU_Pos
|
||||||
|
#define RTC_DR_DT_OFFSET RTC_DR_DT_Pos
|
||||||
|
#define RTC_DR_DU_OFFSET RTC_DR_DU_Pos
|
||||||
|
|
||||||
|
#define RTC_CR_BKP_OFFSET RTC_CR_BKP_Pos
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported variables. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RTC driver identifier.
|
||||||
|
*/
|
||||||
|
RTCDriver RTCD1;
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local variables and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver local functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Beginning of configuration procedure.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static void rtc_enter_init(void) {
|
||||||
|
|
||||||
|
RTCD1.rtc->ICSR |= RTC_ICSR_INIT;
|
||||||
|
while ((RTCD1.rtc->ICSR & RTC_ICSR_INITF) == 0)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Finalizing of configuration procedure.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static inline void rtc_exit_init(void) {
|
||||||
|
|
||||||
|
RTCD1.rtc->ICSR &= ~RTC_ICSR_INIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts time from TR register encoding to timespec.
|
||||||
|
*
|
||||||
|
* @param[in] tr TR register value
|
||||||
|
* @param[out] timespec pointer to a @p RTCDateTime structure
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static void rtc_decode_time(uint32_t tr, RTCDateTime *timespec) {
|
||||||
|
uint32_t n;
|
||||||
|
|
||||||
|
n = ((tr >> RTC_TR_HT_OFFSET) & 3) * 36000000;
|
||||||
|
n += ((tr >> RTC_TR_HU_OFFSET) & 15) * 3600000;
|
||||||
|
n += ((tr >> RTC_TR_MNT_OFFSET) & 7) * 600000;
|
||||||
|
n += ((tr >> RTC_TR_MNU_OFFSET) & 15) * 60000;
|
||||||
|
n += ((tr >> RTC_TR_ST_OFFSET) & 7) * 10000;
|
||||||
|
n += ((tr >> RTC_TR_SU_OFFSET) & 15) * 1000;
|
||||||
|
timespec->millisecond = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts date from DR register encoding to timespec.
|
||||||
|
*
|
||||||
|
* @param[in] dr DR register value
|
||||||
|
* @param[out] timespec pointer to a @p RTCDateTime structure
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static void rtc_decode_date(uint32_t dr, RTCDateTime *timespec) {
|
||||||
|
|
||||||
|
timespec->year = (((dr >> RTC_DR_YT_OFFSET) & 15) * 10) +
|
||||||
|
((dr >> RTC_DR_YU_OFFSET) & 15);
|
||||||
|
timespec->month = (((dr >> RTC_TR_MNT_OFFSET) & 1) * 10) +
|
||||||
|
((dr >> RTC_TR_MNU_OFFSET) & 15);
|
||||||
|
timespec->day = (((dr >> RTC_DR_DT_OFFSET) & 3) * 10) +
|
||||||
|
((dr >> RTC_DR_DU_OFFSET) & 15);
|
||||||
|
timespec->dayofweek = ((dr >> RTC_DR_WDU_OFFSET) & 7) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts time from timespec to TR register encoding.
|
||||||
|
*
|
||||||
|
* @param[in] timespec pointer to a @p RTCDateTime structure
|
||||||
|
* @return the TR register encoding.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static uint32_t rtc_encode_time(const RTCDateTime *timespec) {
|
||||||
|
uint32_t n, tr = 0;
|
||||||
|
|
||||||
|
/* Subseconds cannot be set.*/
|
||||||
|
n = timespec->millisecond / 1000;
|
||||||
|
|
||||||
|
/* Seconds conversion.*/
|
||||||
|
tr = tr | ((n % 10) << RTC_TR_SU_OFFSET);
|
||||||
|
n /= 10;
|
||||||
|
tr = tr | ((n % 6) << RTC_TR_ST_OFFSET);
|
||||||
|
n /= 6;
|
||||||
|
|
||||||
|
/* Minutes conversion.*/
|
||||||
|
tr = tr | ((n % 10) << RTC_TR_MNU_OFFSET);
|
||||||
|
n /= 10;
|
||||||
|
tr = tr | ((n % 6) << RTC_TR_MNT_OFFSET);
|
||||||
|
n /= 6;
|
||||||
|
|
||||||
|
/* Hours conversion.*/
|
||||||
|
tr = tr | ((n % 10) << RTC_TR_HU_OFFSET);
|
||||||
|
n /= 10;
|
||||||
|
tr = tr | (n << RTC_TR_HT_OFFSET);
|
||||||
|
|
||||||
|
return tr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Converts a date from timespec to DR register encoding.
|
||||||
|
*
|
||||||
|
* @param[in] timespec pointer to a @p RTCDateTime structure
|
||||||
|
* @return the DR register encoding.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
static uint32_t rtc_encode_date(const RTCDateTime *timespec) {
|
||||||
|
uint32_t n, dr = 0;
|
||||||
|
|
||||||
|
/* Year conversion. Note, only years last two digits are considered.*/
|
||||||
|
n = timespec->year;
|
||||||
|
dr = dr | ((n % 10) << RTC_DR_YU_OFFSET);
|
||||||
|
n /= 10;
|
||||||
|
dr = dr | ((n % 10) << RTC_DR_YT_OFFSET);
|
||||||
|
|
||||||
|
/* Months conversion.*/
|
||||||
|
n = timespec->month;
|
||||||
|
dr = dr | ((n % 10) << RTC_DR_MU_OFFSET);
|
||||||
|
n /= 10;
|
||||||
|
dr = dr | ((n % 10) << RTC_DR_MT_OFFSET);
|
||||||
|
|
||||||
|
/* Days conversion.*/
|
||||||
|
n = timespec->day;
|
||||||
|
dr = dr | ((n % 10) << RTC_DR_DU_OFFSET);
|
||||||
|
n /= 10;
|
||||||
|
dr = dr | ((n % 10) << RTC_DR_DT_OFFSET);
|
||||||
|
|
||||||
|
/* Days of week conversion.*/
|
||||||
|
dr = dr | ((timespec->dayofweek) << RTC_DR_WDU_OFFSET);
|
||||||
|
|
||||||
|
return dr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if RTC_HAS_STORAGE == TRUE
|
||||||
|
static size_t _getsize(void *instance) {
|
||||||
|
|
||||||
|
(void)instance;
|
||||||
|
|
||||||
|
return (size_t)STM32_RTC_STORAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ps_error_t _read(void *instance, ps_offset_t offset,
|
||||||
|
size_t n, uint8_t *rp) {
|
||||||
|
volatile uint32_t *bkpr = &((RTCDriver *)instance)->tamp->BKP0R;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
chDbgCheck((instance != NULL) && (rp != NULL));
|
||||||
|
chDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE));
|
||||||
|
chDbgCheck((offset < STM32_RTC_STORAGE_SIZE) &&
|
||||||
|
(offset + n <= STM32_RTC_STORAGE_SIZE));
|
||||||
|
|
||||||
|
for (i = 0; i < (unsigned)n; i++) {
|
||||||
|
unsigned index = ((unsigned)offset + i) / sizeof (uint32_t);
|
||||||
|
unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t);
|
||||||
|
*rp++ = (uint8_t)(bkpr[index] >> (shift * 8U));
|
||||||
|
}
|
||||||
|
|
||||||
|
return PS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ps_error_t _write(void *instance, ps_offset_t offset,
|
||||||
|
size_t n, const uint8_t *wp) {
|
||||||
|
volatile uint32_t *bkpr = &((RTCDriver *)instance)->tamp->BKP0R;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
chDbgCheck((instance != NULL) && (wp != NULL));
|
||||||
|
chDbgCheck((n > 0U) && (n <= STM32_RTC_STORAGE_SIZE));
|
||||||
|
chDbgCheck((offset < STM32_RTC_STORAGE_SIZE) &&
|
||||||
|
(offset + n <= STM32_RTC_STORAGE_SIZE));
|
||||||
|
|
||||||
|
for (i = 0; i < (unsigned)n; i++) {
|
||||||
|
unsigned index = ((unsigned)offset + i) / sizeof (uint32_t);
|
||||||
|
unsigned shift = ((unsigned)offset + i) % sizeof (uint32_t);
|
||||||
|
uint32_t regval = bkpr[index];
|
||||||
|
regval &= ~(0xFFU << (shift * 8U));
|
||||||
|
regval |= (uint32_t)*wp++ << (shift * 8U);
|
||||||
|
bkpr[index] = regval;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PS_NO_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief VMT for the RTC storage file interface.
|
||||||
|
*/
|
||||||
|
struct RTCDriverVMT _rtc_lld_vmt = {
|
||||||
|
(size_t)0,
|
||||||
|
_getsize, _read, _write
|
||||||
|
};
|
||||||
|
#endif /* RTC_HAS_STORAGE == TRUE */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver interrupt handlers. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if defined(STM32_RTC_COMMON_HANDLER)
|
||||||
|
#if !defined(STM32_RTC_SUPPRESS_COMMON_ISR)
|
||||||
|
/**
|
||||||
|
* @brief RTC common interrupt handler.
|
||||||
|
*
|
||||||
|
* @isr
|
||||||
|
*/
|
||||||
|
OSAL_IRQ_HANDLER(STM32_RTC_COMMON_HANDLER) {
|
||||||
|
uint32_t isr;
|
||||||
|
|
||||||
|
OSAL_IRQ_PROLOGUE();
|
||||||
|
|
||||||
|
/* Get the interrupt events. */
|
||||||
|
isr = RTCD1.rtc->MISR;
|
||||||
|
RTCD1.rtc->SCR = isr;
|
||||||
|
extiClearGroup1(EXTI_MASK1(STM32_RTC_EVENT_EXTI) |
|
||||||
|
EXTI_MASK1(STM32_TAMP_EVENT_EXTI));
|
||||||
|
|
||||||
|
if (RTCD1.callback != NULL) {
|
||||||
|
|
||||||
|
#if defined(RTC_MISR_WUTMF)
|
||||||
|
if ((isr & RTC_MISR_WUTMF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_WAKEUP);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(RTC_MISR_ALRAMF)
|
||||||
|
if ((isr & RTC_MISR_ALRAMF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_A);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(RTC_MISR_ALRBMF)
|
||||||
|
if ((isr & RTC_MISR_ALRBMF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_ALARM_B);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(RTC_MISR_ITSMF)
|
||||||
|
if ((isr & RTC_MISR_ITSMF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_TS);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(RTC_MISR_TSOVMF)
|
||||||
|
if ((isr & RTC_MISR_TSOVMF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_TS_OVF);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Next handle the tamper interrupts. */
|
||||||
|
isr = RTCD1.tamp->MISR;
|
||||||
|
RTCD1.tamp->SCR = isr;
|
||||||
|
#if defined(TAMP_MISR_TAMP1MF)
|
||||||
|
if ((isr & TAMP_MISR_TAMP1MF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(TAMP_MISR_TAMP2MF)
|
||||||
|
if ((isr & TAMP_MISR_TAMP2MF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP2);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(TAMP_MISR_TAMP3MF)
|
||||||
|
if ((isr & TAMP_MISR_TAMP3MF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP3);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(TAMP_MISR_TAMP4MF)
|
||||||
|
if ((isr & TAMP_MISR_TAMP4MF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP4);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(TAMP_MISR_TAMP5MF)
|
||||||
|
if ((isr & TAMP_MISR_TAMP5MF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP5);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(TAMP_MISR_TAMP6MF)
|
||||||
|
if ((isr & TAMP_MISR_TAMP6MF) != 0U) {
|
||||||
|
RTCD1.callback(&RTCD1, RTC_EVENT_TAMP6);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
OSAL_IRQ_EPILOGUE();
|
||||||
|
}
|
||||||
|
#endif /* !defined(STM32_RTC_SUPPRESS_COMMON_ISR) */
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "missing required RTC handlers definitions in registry"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver exported functions. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable access to registers.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void rtc_lld_init(void) {
|
||||||
|
|
||||||
|
/* RTC object initialization.*/
|
||||||
|
rtcObjectInit(&RTCD1);
|
||||||
|
|
||||||
|
/* RTC pointer initialization.*/
|
||||||
|
RTCD1.rtc = RTC;
|
||||||
|
|
||||||
|
/* Disable write protection. */
|
||||||
|
RTCD1.rtc->WPR = 0xCA;
|
||||||
|
RTCD1.rtc->WPR = 0x53;
|
||||||
|
|
||||||
|
/* If calendar has not been initialized yet then proceed with the
|
||||||
|
initial setup.*/
|
||||||
|
if (!(RTCD1.rtc->ICSR & RTC_ICSR_INITS)) {
|
||||||
|
|
||||||
|
rtc_enter_init();
|
||||||
|
|
||||||
|
RTCD1.rtc->CR |= (STM32_RTC_CR_INIT & STM32_RTC_CR_MASK);
|
||||||
|
RTCD1.rtc->ICSR |= RTC_ICSR_INIT; /* Clearing all but RTC_ISR_INIT. */
|
||||||
|
RTCD1.rtc->PRER |= (STM32_RTC_PRER_BITS & STM32_RTC_PRER_MASK);
|
||||||
|
|
||||||
|
rtc_exit_init();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
RTCD1.rtc->ICSR &= ~RTC_ICSR_RSF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* TAMP pointer initialization. */
|
||||||
|
RTCD1.tamp = TAMP;
|
||||||
|
|
||||||
|
/* Initialise TAMP registers. */
|
||||||
|
RTCD1.tamp->CR1 |= (STM32_TAMP_CR1_INIT & STM32_TAMP_CR1_MASK);
|
||||||
|
RTCD1.tamp->CR2 |= (STM32_TAMP_CR2_INIT & STM32_TAMP_CR2_MASK);
|
||||||
|
RTCD1.tamp->FLTCR |= (STM32_TAMP_FLTCR_INIT & STM32_TAMP_FLTCR_MASK);
|
||||||
|
RTCD1.tamp->IER |= (STM32_TAMP_IER_INIT & STM32_TAMP_IER_MASK);
|
||||||
|
|
||||||
|
/* Callback initially disabled.*/
|
||||||
|
RTCD1.callback = NULL;
|
||||||
|
|
||||||
|
/* Enabling RTC-related EXTI lines.*/
|
||||||
|
|
||||||
|
extiEnableGroup1(EXTI_MASK1(STM32_RTC_EVENT_EXTI) |
|
||||||
|
EXTI_MASK1(STM32_TAMP_EVENT_EXTI),
|
||||||
|
EXTI_MODE_RISING_EDGE | EXTI_MODE_ACTION_INTERRUPT);
|
||||||
|
/* The EXTI lines are direct. Events enabled by peripheral
|
||||||
|
and trigger on their rising edge only */
|
||||||
|
|
||||||
|
/* IRQ vectors permanently assigned to this driver.*/
|
||||||
|
STM32_RTC_AND_TAMP_IRQ_ENABLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set current time.
|
||||||
|
* @note Fractional part will be silently ignored. There is no possibility
|
||||||
|
* to set it on STM32 platform.
|
||||||
|
* @note The function can be called from any context.
|
||||||
|
*
|
||||||
|
* @param[in] rtcp pointer to RTC driver structure
|
||||||
|
* @param[in] timespec pointer to a @p RTCDateTime structure
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) {
|
||||||
|
uint32_t dr, tr;
|
||||||
|
syssts_t sts;
|
||||||
|
|
||||||
|
tr = rtc_encode_time(timespec);
|
||||||
|
dr = rtc_encode_date(timespec);
|
||||||
|
|
||||||
|
/* Entering a reentrant critical zone.*/
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
|
||||||
|
/* Writing the registers.*/
|
||||||
|
rtc_enter_init();
|
||||||
|
rtcp->rtc->TR = tr;
|
||||||
|
rtcp->rtc->DR = dr;
|
||||||
|
rtcp->rtc->CR = (rtcp->rtc->CR & ~(1U << RTC_CR_BKP_OFFSET)) |
|
||||||
|
(timespec->dstflag << RTC_CR_BKP_OFFSET);
|
||||||
|
rtc_exit_init();
|
||||||
|
|
||||||
|
/* Leaving a reentrant critical zone.*/
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get current time.
|
||||||
|
* @note The function can be called from any context.
|
||||||
|
*
|
||||||
|
* @param[in] rtcp pointer to RTC driver structure
|
||||||
|
* @param[out] timespec pointer to a @p RTCDateTime structure
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) {
|
||||||
|
uint32_t dr, tr, cr;
|
||||||
|
uint32_t subs;
|
||||||
|
#if STM32_RTC_HAS_SUBSECONDS
|
||||||
|
uint32_t ssr;
|
||||||
|
#endif /* STM32_RTC_HAS_SUBSECONDS */
|
||||||
|
syssts_t sts;
|
||||||
|
|
||||||
|
/* Entering a reentrant critical zone.*/
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
|
||||||
|
/* Synchronization with the RTC and reading the registers, note
|
||||||
|
DR must be read last.*/
|
||||||
|
while ((rtcp->rtc->ICSR & RTC_ICSR_RSF) == 0)
|
||||||
|
;
|
||||||
|
#if STM32_RTC_HAS_SUBSECONDS
|
||||||
|
ssr = rtcp->rtc->SSR;
|
||||||
|
#endif /* STM32_RTC_HAS_SUBSECONDS */
|
||||||
|
tr = rtcp->rtc->TR;
|
||||||
|
dr = rtcp->rtc->DR;
|
||||||
|
cr = rtcp->rtc->CR;
|
||||||
|
rtcp->rtc->ICSR &= ~RTC_ICSR_RSF;
|
||||||
|
|
||||||
|
/* Leaving a reentrant critical zone.*/
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
|
||||||
|
/* Decoding day time, this starts the atomic read sequence, see "Reading
|
||||||
|
the calendar" in the RTC documentation.*/
|
||||||
|
rtc_decode_time(tr, timespec);
|
||||||
|
|
||||||
|
/* If the RTC is capable of sub-second counting then the value is
|
||||||
|
normalized in milliseconds and added to the time.*/
|
||||||
|
#if STM32_RTC_HAS_SUBSECONDS
|
||||||
|
subs = (((STM32_RTC_PRESS_VALUE - 1U) - ssr) * 1000U) / STM32_RTC_PRESS_VALUE;
|
||||||
|
#else
|
||||||
|
subs = 0;
|
||||||
|
#endif /* STM32_RTC_HAS_SUBSECONDS */
|
||||||
|
timespec->millisecond += subs;
|
||||||
|
|
||||||
|
/* Decoding date, this concludes the atomic read sequence.*/
|
||||||
|
rtc_decode_date(dr, timespec);
|
||||||
|
|
||||||
|
/* Retrieving the DST bit.*/
|
||||||
|
timespec->dstflag = (cr >> RTC_CR_BKP_OFFSET) & 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (RTC_ALARMS > 0) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Set alarm time.
|
||||||
|
* @note Default value after BKP domain reset for both comparators is 0.
|
||||||
|
* @note Function does not performs any checks of alarm time validity.
|
||||||
|
* @note The function can be called from any context.
|
||||||
|
*
|
||||||
|
* @param[in] rtcp pointer to RTC driver structure.
|
||||||
|
* @param[in] alarm alarm identifier. Can be 0 (=1), 1 or 2.
|
||||||
|
* @param[in] alarmspec pointer to a @p RTCAlarm structure.
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void rtc_lld_set_alarm(RTCDriver *rtcp,
|
||||||
|
rtcalarm_t alarm,
|
||||||
|
const RTCAlarm *alarmspec) {
|
||||||
|
syssts_t sts;
|
||||||
|
|
||||||
|
/* Entering a reentrant critical zone.*/
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
|
||||||
|
if (alarm == 0) {
|
||||||
|
if (alarmspec != NULL) {
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_ALRAE;
|
||||||
|
while (!(rtcp->rtc->ICSR & RTC_ICSR_ALRAWF))
|
||||||
|
;
|
||||||
|
rtcp->rtc->ALRMAR = alarmspec->alrmr;
|
||||||
|
rtcp->rtc->CR |= RTC_CR_ALRAE;
|
||||||
|
rtcp->rtc->CR |= RTC_CR_ALRAIE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_ALRAIE;
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_ALRAE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if RTC_ALARMS > 1
|
||||||
|
else {
|
||||||
|
if (alarmspec != NULL) {
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_ALRBE;
|
||||||
|
while (!(rtcp->rtc->ICSR & RTC_ICSR_ALRBWF))
|
||||||
|
;
|
||||||
|
rtcp->rtc->ALRMBR = alarmspec->alrmr;
|
||||||
|
rtcp->rtc->CR |= RTC_CR_ALRBE;
|
||||||
|
rtcp->rtc->CR |= RTC_CR_ALRBIE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_ALRBIE;
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_ALRBE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* RTC_ALARMS > 1 */
|
||||||
|
|
||||||
|
/* Leaving a reentrant critical zone.*/
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get alarm time.
|
||||||
|
* @note The function can be called from any context.
|
||||||
|
*
|
||||||
|
* @param[in] rtcp pointer to RTC driver structure
|
||||||
|
* @param[in] alarm alarm identifier. Can be 0 (=1), 1 or 2.
|
||||||
|
* @param[out] alarmspec pointer to a @p RTCAlarm structure
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void rtc_lld_get_alarm(RTCDriver *rtcp,
|
||||||
|
rtcalarm_t alarm,
|
||||||
|
RTCAlarm *alarmspec) {
|
||||||
|
|
||||||
|
if (alarm == 0)
|
||||||
|
alarmspec->alrmr = rtcp->rtc->ALRMAR;
|
||||||
|
#if RTC_ALARMS > 1
|
||||||
|
else
|
||||||
|
alarmspec->alrmr = rtcp->rtc->ALRMBR;
|
||||||
|
#endif /* RTC_ALARMS > 1 */
|
||||||
|
}
|
||||||
|
#endif /* RTC_ALARMS > 0 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enables or disables RTC callbacks.
|
||||||
|
* @details This function enables or disables callbacks, use a @p NULL pointer
|
||||||
|
* in order to disable a callback.
|
||||||
|
* @note The function can be called from any context.
|
||||||
|
*
|
||||||
|
* @param[in] rtcp pointer to RTC driver structure
|
||||||
|
* @param[in] callback callback function pointer or @p NULL
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) {
|
||||||
|
|
||||||
|
rtcp->callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @brief Sets time of periodic wakeup.
|
||||||
|
* @note Default value after BKP domain reset is 0x0000FFFF
|
||||||
|
* @note The function can be called from any context.
|
||||||
|
*
|
||||||
|
* @param[in] rtcp pointer to RTC driver structure
|
||||||
|
* @param[in] wakeupspec pointer to a @p RTCWakeup structure
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) {
|
||||||
|
syssts_t sts;
|
||||||
|
|
||||||
|
/* Entering a reentrant critical zone.*/
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
|
||||||
|
if (wakeupspec != NULL) {
|
||||||
|
osalDbgCheck(wakeupspec->wutr != 0x30000);
|
||||||
|
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_WUTE;
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_WUTIE;
|
||||||
|
while (!(rtcp->rtc->ICSR & RTC_ICSR_WUTWF))
|
||||||
|
;
|
||||||
|
rtcp->rtc->WUTR = wakeupspec->wutr & 0xFFFF;
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_WUCKSEL;
|
||||||
|
rtcp->rtc->CR |= (wakeupspec->wutr >> 16) & RTC_CR_WUCKSEL;
|
||||||
|
rtcp->rtc->CR |= RTC_CR_WUTIE;
|
||||||
|
rtcp->rtc->CR |= RTC_CR_WUTE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_WUTE;
|
||||||
|
rtcp->rtc->CR &= ~RTC_CR_WUTIE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leaving a reentrant critical zone.*/
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Gets time of periodic wakeup.
|
||||||
|
* @note Default value after BKP domain reset is 0x0000FFFF
|
||||||
|
* @note The function can be called from any context.
|
||||||
|
*
|
||||||
|
* @param[in] rtcp pointer to RTC driver structure
|
||||||
|
* @param[out] wakeupspec pointer to a @p RTCWakeup structure
|
||||||
|
*
|
||||||
|
* @api
|
||||||
|
*/
|
||||||
|
void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) {
|
||||||
|
syssts_t sts;
|
||||||
|
|
||||||
|
/* Entering a reentrant critical zone.*/
|
||||||
|
sts = osalSysGetStatusAndLockX();
|
||||||
|
|
||||||
|
wakeupspec->wutr = 0;
|
||||||
|
wakeupspec->wutr |= rtcp->rtc->WUTR;
|
||||||
|
wakeupspec->wutr |= (((uint32_t)rtcp->rtc->CR) & 0x7) << 16;
|
||||||
|
|
||||||
|
/* Leaving a reentrant critical zone.*/
|
||||||
|
osalSysRestoreStatusX(sts);
|
||||||
|
}
|
||||||
|
#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */
|
||||||
|
|
||||||
|
#endif /* HAL_USE_RTC */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -0,0 +1,285 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
Concepts and parts of this file have been contributed by Uladzimir Pylinsky
|
||||||
|
aka barthess.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file RTCv3/hal_rtc_lld.h
|
||||||
|
* @brief STM32 RTC low level driver header.
|
||||||
|
*
|
||||||
|
* @addtogroup RTC
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HAL_RTC_LLD_H
|
||||||
|
#define HAL_RTC_LLD_H
|
||||||
|
|
||||||
|
#if HAL_USE_RTC || defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver constants. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Implementation capabilities
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief Callback support int the driver.
|
||||||
|
*/
|
||||||
|
#define RTC_SUPPORTS_CALLBACKS TRUE
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Number of alarms available.
|
||||||
|
*/
|
||||||
|
#define RTC_ALARMS STM32_RTC_NUM_ALARMS
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Presence of a local persistent storage.
|
||||||
|
*/
|
||||||
|
#define RTC_HAS_STORAGE (STM32_RTC_STORAGE_SIZE > 0)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RTC PRER register initializer.
|
||||||
|
*/
|
||||||
|
#define RTC_PRER(a, s) ((((a) - 1) << 16) | ((s) - 1))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Alarm helper macros
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RTC_ALRM_MSK4 (1U << 31)
|
||||||
|
#define RTC_ALRM_WDSEL (1U << 30)
|
||||||
|
#define RTC_ALRM_DT(n) ((n) << 28)
|
||||||
|
#define RTC_ALRM_DU(n) ((n) << 24)
|
||||||
|
#define RTC_ALRM_MSK3 (1U << 23)
|
||||||
|
#define RTC_ALRM_HT(n) ((n) << 20)
|
||||||
|
#define RTC_ALRM_HU(n) ((n) << 16)
|
||||||
|
#define RTC_ALRM_MSK2 (1U << 15)
|
||||||
|
#define RTC_ALRM_MNT(n) ((n) << 12)
|
||||||
|
#define RTC_ALRM_MNU(n) ((n) << 8)
|
||||||
|
#define RTC_ALRM_MSK1 (1U << 7)
|
||||||
|
#define RTC_ALRM_ST(n) ((n) << 4)
|
||||||
|
#define RTC_ALRM_SU(n) ((n) << 0)
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/* Requires services from the EXTI driver.*/
|
||||||
|
#if !defined(STM32_EXTI_REQUIRED)
|
||||||
|
#define STM32_EXTI_REQUIRED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver pre-compile time settings. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Configuration options
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @brief RTC PRES register initialization.
|
||||||
|
* @note The default is calculated for a 32768Hz clock.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_RTC_PRESA_VALUE) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_RTC_PRESA_VALUE 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RTC PRESS divider initialization.
|
||||||
|
* @note The default is calculated for a 32768Hz clock.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_RTC_PRESS_VALUE) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_RTC_PRESS_VALUE 1024
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief RTC CR register initialization value.
|
||||||
|
* @note Use this value to initialize features not directly handled by
|
||||||
|
* the RTC driver.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_RTC_CR_INIT) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_RTC_CR_INIT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TAMP register initialization value.
|
||||||
|
* @note Use this value to initialize features not directly handled by
|
||||||
|
* the RTC driver.
|
||||||
|
* @note On some devices this values goes in the similar TAFCR register.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_TAMP_CR1_INIT) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_TAMP_CR1_INIT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TAMP register initialization value.
|
||||||
|
* @note Use this value to initialize features not directly handled by
|
||||||
|
* the RTC driver.
|
||||||
|
* @note On some devices this values goes in the similar TAFCR register.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_TAMP_CR2_INIT) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_TAMP_CR2_INIT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TAMP register initialization value.
|
||||||
|
* @note Use this value to initialize features not directly handled by
|
||||||
|
* the RTC driver.
|
||||||
|
* @note On some devices this values goes in the similar TAFCR register.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_TAMP_FLTCR_INIT) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_TAMP_FLTCR_INIT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief TAMP register initialization value.
|
||||||
|
* @note Use this value to initialize features not directly handled by
|
||||||
|
* the RTC driver.
|
||||||
|
* @note On some devices this values goes in the similar TAFCR register.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_TAMP_IER_INIT) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_TAMP_IER_INIT 0
|
||||||
|
#endif
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Derived constants and error checks. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#if HAL_USE_RTC && !STM32_HAS_RTC
|
||||||
|
#error "RTC not present in the selected device"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(STM32_RTC_CK) && !defined(STM32_RTCCLK)
|
||||||
|
#define STM32_RTCCLK STM32_RTC_CK
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(STM32_RTCCLK)
|
||||||
|
#error "RTC clock not exported by HAL layer"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if STM32_PCLK1 < (STM32_RTCCLK * 7)
|
||||||
|
#error "STM32_PCLK1 frequency is too low"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialization for the RTC_PRER register.
|
||||||
|
*/
|
||||||
|
#define STM32_RTC_PRER_BITS RTC_PRER(STM32_RTC_PRESA_VALUE, \
|
||||||
|
STM32_RTC_PRESS_VALUE)
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver data structures and types. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of an RTC event.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
RTC_EVENT_ALARM_A = 0, /** Alarm A. */
|
||||||
|
RTC_EVENT_ALARM_B = 1, /** Alarm B. */
|
||||||
|
RTC_EVENT_TS = 2, /** Time stamp. */
|
||||||
|
RTC_EVENT_TS_OVF = 3, /** Time stamp overflow. */
|
||||||
|
RTC_EVENT_TAMP1 = 4, /** Tamper 1. */
|
||||||
|
RTC_EVENT_TAMP2 = 5, /** Tamper 2- */
|
||||||
|
RTC_EVENT_TAMP3 = 6, /** Tamper 3. */
|
||||||
|
RTC_EVENT_TAMP4 = 7, /** Tamper 4. */
|
||||||
|
RTC_EVENT_TAMP5 = 8, /** Tamper 5. */
|
||||||
|
RTC_EVENT_TAMP6 = 9, /** Tamper 6. */
|
||||||
|
RTC_EVENT_WAKEUP = 10, /** Wakeup. */
|
||||||
|
} rtcevent_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a generic RTC callback.
|
||||||
|
*/
|
||||||
|
typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a structure representing an RTC alarm time stamp.
|
||||||
|
*/
|
||||||
|
typedef struct hal_rtc_alarm {
|
||||||
|
/**
|
||||||
|
* @brief Type of an alarm as encoded in RTC ALRMxR registers.
|
||||||
|
*/
|
||||||
|
uint32_t alrmr;
|
||||||
|
} RTCAlarm;
|
||||||
|
|
||||||
|
#if STM32_RTC_HAS_PERIODIC_WAKEUPS
|
||||||
|
/**
|
||||||
|
* @brief Type of a wakeup as encoded in RTC WUTR register.
|
||||||
|
*/
|
||||||
|
typedef struct hal_rtc_wakeup {
|
||||||
|
/**
|
||||||
|
* @brief Wakeup as encoded in RTC WUTR register.
|
||||||
|
* @note ((WUTR == 0) || (WUCKSEL == 3)) are a forbidden combination.
|
||||||
|
* @note Bits 16..18 are copied in the CR bits 0..2 (WUCKSEL).
|
||||||
|
*/
|
||||||
|
uint32_t wutr;
|
||||||
|
} RTCWakeup;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Implementation-specific @p RTCDriver fields.
|
||||||
|
*/
|
||||||
|
#define rtc_lld_driver_fields \
|
||||||
|
/* Pointer to the RTC registers block.*/ \
|
||||||
|
RTC_TypeDef *rtc; \
|
||||||
|
/* RTC event callback pointer.*/ \
|
||||||
|
rtccb_t callback; \
|
||||||
|
/* Pointer to TAMPER registers block. */ \
|
||||||
|
TAMP_TypeDef *tamp
|
||||||
|
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* Driver macros. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/*===========================================================================*/
|
||||||
|
/* External declarations. */
|
||||||
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
void rtc_lld_init(void);
|
||||||
|
void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec);
|
||||||
|
void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec);
|
||||||
|
#if RTC_SUPPORTS_CALLBACKS == TRUE
|
||||||
|
void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback);
|
||||||
|
#endif
|
||||||
|
#if RTC_ALARMS > 0
|
||||||
|
void rtc_lld_set_alarm(RTCDriver *rtcp,
|
||||||
|
rtcalarm_t alarm,
|
||||||
|
const RTCAlarm *alarmspec);
|
||||||
|
void rtc_lld_get_alarm(RTCDriver *rtcp,
|
||||||
|
rtcalarm_t alarm,
|
||||||
|
RTCAlarm *alarmspec);
|
||||||
|
#endif
|
||||||
|
#if STM32_RTC_HAS_PERIODIC_WAKEUPS
|
||||||
|
void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec);
|
||||||
|
void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec);
|
||||||
|
#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* HAL_USE_RTC */
|
||||||
|
|
||||||
|
#endif /* HAL_RTC_LLD_H */
|
||||||
|
|
||||||
|
/** @} */
|
|
@ -32,7 +32,7 @@ include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
|
||||||
#include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/USARTv2/driver.mk
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
/* Common. */
|
/* Common. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/* RTC attributes.*/
|
/* RTC and TAMP attributes.*/
|
||||||
#define STM32_HAS_RTC TRUE
|
#define STM32_HAS_RTC TRUE
|
||||||
#define STM32_RTC_HAS_SUBSECONDS TRUE
|
#define STM32_RTC_HAS_SUBSECONDS TRUE
|
||||||
#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
|
#define STM32_RTC_HAS_PERIODIC_WAKEUPS TRUE
|
||||||
|
@ -46,14 +46,21 @@
|
||||||
#define STM32_RTC_STORAGE_SIZE 20
|
#define STM32_RTC_STORAGE_SIZE 20
|
||||||
#define STM32_RTC_COMMON_HANDLER Vector48
|
#define STM32_RTC_COMMON_HANDLER Vector48
|
||||||
#define STM32_RTC_COMMON_NUMBER 2
|
#define STM32_RTC_COMMON_NUMBER 2
|
||||||
#define STM32_RTC_ALARM_EXTI 18
|
#define STM32_RTC_EVENT_EXTI 19
|
||||||
#define STM32_RTC_TAMP_STAMP_EXTI 19
|
#define STM32_TAMP_EVENT_EXTI 21
|
||||||
#define STM32_RTC_WKUP_EXTI 20
|
#define STM32_RTC_AND_TAMP_IRQ_ENABLE() do { \
|
||||||
#define STM32_RTC_IRQ_ENABLE() do { \
|
|
||||||
nvicEnableVector(STM32_RTC_COMMON_NUMBER, \
|
nvicEnableVector(STM32_RTC_COMMON_NUMBER, \
|
||||||
STM32_IRQ_EXTI19_21_IRQ_PRIORITY); \
|
STM32_IRQ_EXTI1921_PRIORITY); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
/* Masks used to preserve state of reserved bits. */
|
||||||
|
#define STM32_RTC_CR_MASK 0xE7FFFF7F
|
||||||
|
#define STM32_RTC_PRER_MASK 0x007F7FFF
|
||||||
|
#define STM32_TAMP_CR1_MASK 0x003C0003
|
||||||
|
#define STM32_TAMP_CR2_MASK 0x030300FF
|
||||||
|
#define STM32_TAMP_FLTCR_MASK 0x000000FF
|
||||||
|
#define STM32_TAMP_IER_MASK 0x003C0003
|
||||||
|
|
||||||
#if defined(STM32G081xx) || defined(__DOXYGEN__)
|
#if defined(STM32G081xx) || defined(__DOXYGEN__)
|
||||||
#define STM32_HAS_RNG1 TRUE
|
#define STM32_HAS_RNG1 TRUE
|
||||||
#define STM32_HAS_HASH1 FALSE
|
#define STM32_HAS_HASH1 FALSE
|
||||||
|
|
|
@ -31,7 +31,7 @@ include $(CHIBIOS)/os/hal/ports/STM32/LLD/DMAv1/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/EXTIv1/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/GPIOv2/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/I2Cv2/driver.mk
|
||||||
#include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/RTCv3/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/QUADSPIv1/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/SPIv2/driver.mk
|
||||||
include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
|
include $(CHIBIOS)/os/hal/ports/STM32/LLD/TIMv1/driver.mk
|
||||||
|
|
|
@ -74,6 +74,7 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** Next ***
|
*** Next ***
|
||||||
|
- HAL: New RTCv3 driver for STM32G0xx and STM32G4xx.
|
||||||
- HAL: Added support for DAC3 and DAC4 in STM32 DACv1 driver.
|
- HAL: Added support for DAC3 and DAC4 in STM32 DACv1 driver.
|
||||||
- NIL: New functions: chSemResetWithMessageI() and chSemResetWithMessage().
|
- NIL: New functions: chSemResetWithMessageI() and chSemResetWithMessage().
|
||||||
- RT: New functions: chSemResetWithMessageI() and chSemResetWithMessage().
|
- RT: New functions: chSemResetWithMessageI() and chSemResetWithMessage().
|
||||||
|
|
|
@ -94,10 +94,11 @@
|
||||||
#define STM32_IRQ_EXTI0_1_PRIORITY ${doc.STM32_IRQ_EXTI0_1_PRIORITY!"3"}
|
#define STM32_IRQ_EXTI0_1_PRIORITY ${doc.STM32_IRQ_EXTI0_1_PRIORITY!"3"}
|
||||||
#define STM32_IRQ_EXTI2_3_PRIORITY ${doc.STM32_IRQ_EXTI2_3_PRIORITY!"3"}
|
#define STM32_IRQ_EXTI2_3_PRIORITY ${doc.STM32_IRQ_EXTI2_3_PRIORITY!"3"}
|
||||||
#define STM32_IRQ_EXTI4_15_PRIORITY ${doc.STM32_IRQ_EXTI4_15_PRIORITY!"3"}
|
#define STM32_IRQ_EXTI4_15_PRIORITY ${doc.STM32_IRQ_EXTI4_15_PRIORITY!"3"}
|
||||||
|
#define STM32_IRQ_EXTI1921_PRIORITY ${doc.STM32_IRQ_EXTI1921_PRIORITY!"3"}
|
||||||
|
|
||||||
#define STM32_IRQ_USART1_PRIORITY ${doc.STM32_IRQ_USART1_PRIORITY!"2"}
|
#define STM32_IRQ_USART1_PRIORITY ${doc.STM32_IRQ_USART1_PRIORITY!"2"}
|
||||||
#define STM32_IRQ_USART2_PRIORITY ${doc.STM32_IRQ_USART2_PRIORITY!"2"}
|
#define STM32_IRQ_USART2_PRIORITY ${doc.STM32_IRQ_USART2_PRIORITY!"2"}
|
||||||
#define STM32_IRQ_USART3_4_LP1_PRIORITY ${doc.STM32_IRQ_USART3_4_LP1_PRIORITY!"1"}
|
#define STM32_IRQ_USART3_4_LP1_PRIORITY ${doc.STM32_IRQ_USART3_4_LP1_PRIORITY!"2"}
|
||||||
|
|
||||||
#define STM32_IRQ_TIM1_UP_PRIORITY ${doc.STM32_IRQ_TIM1_UP_PRIORITY!"1"}
|
#define STM32_IRQ_TIM1_UP_PRIORITY ${doc.STM32_IRQ_TIM1_UP_PRIORITY!"1"}
|
||||||
#define STM32_IRQ_TIM1_CC_PRIORITY ${doc.STM32_IRQ_TIM1_CC_PRIORITY!"1"}
|
#define STM32_IRQ_TIM1_CC_PRIORITY ${doc.STM32_IRQ_TIM1_CC_PRIORITY!"1"}
|
||||||
|
|
Loading…
Reference in New Issue