mirror of https://github.com/rusefi/ChibiOS.git
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:
parent
21c59fea5c
commit
55e27e771d
|
@ -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) >> \
|
||||
|
|
|
@ -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) +
|
||||
timespec->millisecond = ((RTC_RTC_0_HOUR(rtc_0) * 3600) +
|
||||
(RTC_RTC_0_MIN(rtc_0) * 60) +
|
||||
(RTC_RTC_0_SEC(rtc_0) * 1000);
|
||||
(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);
|
||||
}
|
||||
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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" {
|
||||
|
|
Loading…
Reference in New Issue