RP RTC update

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14149 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
cinsights 2021-04-08 13:36:24 +00:00
parent 21c59fea5c
commit 55e27e771d
3 changed files with 58 additions and 50 deletions

View File

@ -794,7 +794,7 @@ typedef struct {
#define RTC_SETUP_0_MONTH_Pos 8U
#define RTC_SETUP_0_MONTH_Msk (0xFU << RTC_SETUP_0_MONTH_Pos)
#define RTC_SETUP_0_MONTH(n) ((n) << RTC_SETUP_0_MONTH_Pos)
#define RTC_SETUP_0_DAY_Pos 4U
#define RTC_SETUP_0_DAY_Pos 0U
#define RTC_SETUP_0_DAY_Msk (0x1FU << RTC_SETUP_0_DAY_Pos)
#define RTC_SETUP_0_DAY(n) ((n) << RTC_SETUP_0_DAY_Pos)
@ -903,7 +903,7 @@ typedef struct {
#define RTC_RTC_1_MONTH_Pos 8U
#define RTC_RTC_1_MONTH_Msk (0xFU << RTC_RTC_1_MONTH_Pos)
#define RTC_RTC_1_MONTH(n) ((n & RTC_RTC_1_MONTH_Msk) >> \
RTC_RTC_1_DAY_Pos)
RTC_RTC_1_MONTH_Pos)
#define RTC_RTC_1_DAY_Pos 0U
#define RTC_RTC_1_DAY_Msk (0x1FU << RTC_RTC_1_DAY_Pos)
#define RTC_RTC_1_DAY(n) ((n & RTC_RTC_1_DAY_Msk) >> \

View File

@ -23,7 +23,6 @@
*/
#include "hal.h"
#include "hardware/rtc.h"
#if (HAL_USE_RTC == TRUE) || defined(__DOXYGEN__)
@ -48,6 +47,7 @@ RTCDriver RTCD1;
/* Driver local functions. */
/*===========================================================================*/
#if (RTC_ALARMS > 0) || defined(__DOXYGEN__)
static void rtc_enable_alarm(RTCDriver *rtcp) {
/* Enable matching and wait for it to be activated. */
rtcp->rtc->IRQSETUP0 |= RTC_IRQ_SETUP_0_MATCH_ENA;
@ -61,10 +61,28 @@ static void rtc_disable_alarm(RTCDriver *rtcp) {
while (rtcp->rtc->IRQSETUP0 & RTC_IRQ_SETUP_0_MATCH_ACTIVE)
;
}
#endif
/*===========================================================================*/
/* Driver interrupt handlers. */
/*===========================================================================*/
#if (RTC_ALARMS > 0) || defined(__DOXYGEN__)
/**
* @brief RTC alarm interrupt handler.
*
* @isr
*/
OSAL_IRQ_HANDLER(RP_RTC_IRQ_HANDLER) {
OSAL_IRQ_PROLOGUE();
if (RTCD1.callback != NULL) {
RTCD1.callback(&RTCD1, 1);
}
OSAL_IRQ_EPILOGUE();
}
#endif
/*===========================================================================*/
/* Driver exported functions. */
@ -88,20 +106,23 @@ void rtc_lld_init(void) {
/* Get clock parameters. */
uint32_t clock = hal_lld_get_clock(clk_rtc);
osalDbgAssert((clock > 0U) || (clock - 1 <= RTC_CLKDIV_M1_BITS), "bad clock");
osalDbgAssert((clock > 0U) || (clock - 1 <= RTC_CLKDIV_M1), "bad clock");
/* Take RTC out of reset. */
hal_lld_peripheral_unreset(RESETS_ALLREG_RTC);
/* Set divider. */
RTCD1.rtc->CLKDIVM1 = clock - 1;
/* Enable RTC vector. */
nvicEnableVector(RP_RTC_IRQ_NUMBER, RP_IRQ_RTC_PRIORITY);
}
/**
* @brief Set current time.
* @note Fractional seconds part will be silently ignored. There is no
* possibility to set it on RP2040 platform. The RP2040 handles
* leap year for years evenly divisible by 4.
* possibility to set it on RP2040 platform.
* @note The RP2040 handles leap year for years evenly divisible by 4.
* @note The function can be called from any context.
*
* @param[in] rtcp pointer to RTC driver structure
@ -117,15 +138,16 @@ void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) {
uint32_t min = sec / 60;
sec %= 60;
/* Entering a reentrant critical zone.*/
syssts_t sts = osalSysGetStatusAndLockX();
/* Disable RTC. */
rtcp->rtc->CTRL = 0;
rtcp->rtc->CTRL &= ~RTC_CTRL_RTC_ENABLE;
/* Wait for RTC to go inactive. */
while ((rtcp->rtc->CTRL & RTC_CTRL_RTC_ACTIVE) != 0)
;
/* Entering a reentrant critical zone.*/
syssts_t sts = osalSysGetStatusAndLockX();
/* Write setup to pre-load registers. */
rtcp->rtc->SETUP0 = (RTC_SETUP_0_YEAR(timespec->year + 1980)) |
@ -134,17 +156,18 @@ void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) {
rtcp->rtc->SETUP1 = (RTC_SETUP_1_DOTW(timespec->dayofweek - 1)) |
(RTC_SETUP_1_HOUR(hour)) |
(RTC_SETUP_1_MIN(min)) |
(RTC_SETUP_1_SEC(sec);
(RTC_SETUP_1_SEC(sec));
/* Move setup values into RTC clock domain. */
rtcp->rtc->CTRL = RTC_CTRL_LOAD;
/* Enable RTC and wait for active. */
rtcp->rtc->CTRL = RTC_CTRL_RTC_ENABLE;
rtcp->rtc->CTRL |= RTC_CTRL_RTC_ENABLE;
/* Leaving a reentrant critical zone.*/
osalSysRestoreStatusX(sts);
/* Wait for RTC to go active. */
while ((rtcp->rtc->CTRL & RTC_CTRL_RTC_ACTIVE) == 0)
;
}
@ -171,9 +194,9 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) {
osalSysRestoreStatusX(sts);
/* Calculate and set milliseconds since midnight field. */
timespec->millisecond = (RTC_RTC_0_HOUR(rtc_0) * 3600) +
(RTC_RTC_0_MIN(rtc_0) * 60) +
(RTC_RTC_0_SEC(rtc_0) * 1000);
timespec->millisecond = ((RTC_RTC_0_HOUR(rtc_0) * 3600) +
(RTC_RTC_0_MIN(rtc_0) * 60) +
(RTC_RTC_0_SEC(rtc_0))) * 1000;
/* Set RTCDateTime fields with adjustments from RTC data. */
timespec->dayofweek = RTC_RTC_0_DOTW(rtc_0) + 1;
@ -185,8 +208,7 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) {
#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 alarm time can be partially specified by leaving fields as zero.
* @note The function can be called from any context.
*
* @param[in] rtcp pointer to RTC driver structure.
@ -201,7 +223,7 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
(void)alarm;
uint32_t sec, min, hour, day, month, year, dotw, setup0, setup1;
RTCDateTime *timespec = &alarmspec->alarm;
const RTCDateTime *timespec = &alarmspec->alarm;
sec = (uint32_t)timespec->millisecond / 1000;
hour = sec / 3600;
sec %= 3600;
@ -214,14 +236,14 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
year = timespec->year == 0 ? 0 : timespec->year + 1980;
dotw = timespec->dayofweek;
/* Write all registers regardless. */
/* Setup register data. */
setup0 = (RTC_IRQ_SETUP_0_YEAR(year)) |
(RTC_IRQ_SETUP_0_MONTH(month)) |
(RTC_IRQ_SETUP_0_DAY(day));
setup1 = (RTC_IRQ_SETUP_1_DOTW(dotw - 1)) |
(RTC_IRQ_SETUP_1_HOUR(hour)) |
(RTC_IRQ_SETUP_1_MIN(min)) |
(RTC_IRQ_SETUP_1_SEC(sec);
(RTC_IRQ_SETUP_1_SEC(sec));
/* Check and set match enable bits for non-zero */
if (year > 0) setup0 |= RTC_IRQ_SETUP_0_YEAR_ENA;
@ -235,26 +257,18 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
/* Entering a reentrant critical zone.*/
syssts_t sts = osalSysGetStatusAndLockX();
/* Disable RTC and load the alarm time. */
rtc_disable_alarm(rtcp);
rtcp->rtc->IRQSETUP0 = setup0;
rtcp->rtc->IRQSETUP1 = setup1;
// Does it repeat? I.e. do we not match on any of the bits
//_alarm_repeats = rtc_alarm_repeats(t);
// Store function pointer we can call later
//_callback = user_callback;
//irq_set_exclusive_handler(RTC_IRQ, rtc_irq_handler);
// Enable the IRQ at the peri
//rtc_hw->inte = RTC_INTE_RTC_BITS;
// Enable the IRQ at the proc
//irq_set_enabled(RTC_IRQ, true);
/* Enable the interrupt and re-enable the RTC. */
rtcp->rtc->INTE = RTC_INTE_RTC;
rtc_enable_alarm(rtcp);
/* Save the alarm setting. */
rtcp->alarm = *timespec;
/* Leaving a reentrant critical zone.*/
osalSysRestoreStatusX(sts);
}
@ -263,8 +277,8 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
* @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
* @param[in] rtcp pointer to RTC driver structure
* @param[in] alarm alarm identifier
* @param[out] alarmspec pointer to a @p RTCAlarm structure
*
* @notapi
@ -273,15 +287,14 @@ void rtc_lld_get_alarm(RTCDriver *rtcp,
rtcalarm_t alarm,
RTCAlarm *alarmspec) {
(void)rtcp;
(void)alarm;
(void)alarmspec;
alarmspec->alarm = rtcp->alarm;
}
#endif /* RTC_ALARMS > 0 */
/**
* @brief Enables or disables RTC callbacks.
* @details This function enables or disables callbacks, use a @p NULL pointer
* @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.
*

View File

@ -43,7 +43,7 @@
/**
* @brief Number of alarms available.
*/
#define RTC_ALARMS 0
#define RTC_ALARMS 1
/**
* @brief Presence of a local persistent storage.
@ -59,14 +59,10 @@
* @name PLATFORM configuration options
* @{
*/
/**
* @brief RTCD1 driver enable switch.
* @details If set to @p TRUE the support for RTC1 is included.
* @note The default is @p FALSE.
*/
//#if !defined(PLATFORM_RTC_USE_RTC1) || defined(__DOXYGEN__)
//#define PLATFORM_RTC_USE_RTC1 FALSE
//#endif
/* Priority settings checks.*/
#if !defined(RP_IRQ_RTC_PRIORITY)
#error "RP_IRQ_RTC_PRIORITY not defined in mcuconf.h"
#endif
/** @} */
/*===========================================================================*/
@ -104,7 +100,8 @@ typedef struct {
/* Pointer to the RTC registers block.*/ \
RTC_TypeDef *rtc; \
/* Callback pointer.*/ \
rtccb_t callback
rtccb_t callback; \
RTCDateTime alarm;
/*===========================================================================*/
/* Driver macros. */
@ -114,9 +111,7 @@ typedef struct {
/* External declarations. */
/*===========================================================================*/
//#if (PLATFORM_RTC_USE_RTC1 == TRUE) && !defined(__DOXYGEN__)
extern RTCDriver RTCD1;
//#endif
#ifdef __cplusplus
extern "C" {