RP RTC alarm matching update
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@14151 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
c97e9fad20
commit
dfb451f438
|
@ -148,14 +148,13 @@ void rtc_lld_set_time(RTCDriver *rtcp, const RTCDateTime *timespec) {
|
||||||
while ((rtcp->rtc->CTRL & RTC_CTRL_RTC_ACTIVE) != 0)
|
while ((rtcp->rtc->CTRL & RTC_CTRL_RTC_ACTIVE) != 0)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
/* Write setup to pre-load registers. */
|
/* Write setup to pre-load registers. */
|
||||||
rtcp->rtc->SETUP0 = (RTC_SETUP_0_YEAR(timespec->year + 1980)) |
|
rtcp->rtc->SETUP0 = (RTC_SETUP_0_YEAR(timespec->year + RTC_BASE_YEAR)) |
|
||||||
(RTC_SETUP_0_MONTH(timespec->month)) |
|
(RTC_SETUP_0_MONTH(timespec->month)) |
|
||||||
(RTC_SETUP_0_DAY(timespec->day));
|
(RTC_SETUP_0_DAY(timespec->day));
|
||||||
rtcp->rtc->SETUP1 = (RTC_SETUP_1_DOTW(timespec->dayofweek - 1)) |
|
rtcp->rtc->SETUP1 = (RTC_SETUP_1_DOTW(timespec->dayofweek - 1)) |
|
||||||
(RTC_SETUP_1_HOUR(hour)) |
|
(RTC_SETUP_1_HOUR(hour)) |
|
||||||
(RTC_SETUP_1_MIN(min)) |
|
(RTC_SETUP_1_MIN(min)) |
|
||||||
(RTC_SETUP_1_SEC(sec));
|
(RTC_SETUP_1_SEC(sec));
|
||||||
|
|
||||||
/* Move setup values into RTC clock domain. */
|
/* Move setup values into RTC clock domain. */
|
||||||
|
@ -200,7 +199,7 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) {
|
||||||
|
|
||||||
/* Set RTCDateTime fields with adjustments from RTC data. */
|
/* Set RTCDateTime fields with adjustments from RTC data. */
|
||||||
timespec->dayofweek = RTC_RTC_0_DOTW(rtc_0) + 1;
|
timespec->dayofweek = RTC_RTC_0_DOTW(rtc_0) + 1;
|
||||||
timespec->year = RTC_RTC_1_YEAR(rtc_1) - 1980;
|
timespec->year = RTC_RTC_1_YEAR(rtc_1) - RTC_BASE_YEAR;
|
||||||
timespec->month = RTC_RTC_1_MONTH(rtc_1);
|
timespec->month = RTC_RTC_1_MONTH(rtc_1);
|
||||||
timespec->day = RTC_RTC_1_DAY(rtc_1);
|
timespec->day = RTC_RTC_1_DAY(rtc_1);
|
||||||
}
|
}
|
||||||
|
@ -224,6 +223,15 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
|
||||||
(void)alarm;
|
(void)alarm;
|
||||||
uint32_t sec, min, hour, day, month, year, dotw, setup0, setup1;
|
uint32_t sec, min, hour, day, month, year, dotw, setup0, setup1;
|
||||||
const RTCDateTime *timespec = &alarmspec->alarm;
|
const RTCDateTime *timespec = &alarmspec->alarm;
|
||||||
|
const rtcdtmask_t dtmask = alarmspec->mask;
|
||||||
|
|
||||||
|
if (dtmask == 0) {
|
||||||
|
/* Disable RTC when no fields are enabled. */
|
||||||
|
rtc_disable_alarm(rtcp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup date/time fields. */
|
||||||
sec = (uint32_t)timespec->millisecond / 1000;
|
sec = (uint32_t)timespec->millisecond / 1000;
|
||||||
hour = sec / 3600;
|
hour = sec / 3600;
|
||||||
sec %= 3600;
|
sec %= 3600;
|
||||||
|
@ -231,10 +239,8 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
|
||||||
sec %= 60;
|
sec %= 60;
|
||||||
day = timespec->day;
|
day = timespec->day;
|
||||||
month = timespec->month;
|
month = timespec->month;
|
||||||
|
|
||||||
/* Normalise and setup for non-zero checking. */
|
|
||||||
year = timespec->year == 0 ? 0 : timespec->year + 1980;
|
|
||||||
dotw = timespec->dayofweek;
|
dotw = timespec->dayofweek;
|
||||||
|
year = timespec->year + RTC_BASE_YEAR;
|
||||||
|
|
||||||
/* Setup register data. */
|
/* Setup register data. */
|
||||||
setup0 = (RTC_IRQ_SETUP_0_YEAR(year)) |
|
setup0 = (RTC_IRQ_SETUP_0_YEAR(year)) |
|
||||||
|
@ -245,14 +251,21 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
|
||||||
(RTC_IRQ_SETUP_1_MIN(min)) |
|
(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 */
|
/* Check and set match enable bits. */
|
||||||
if (year > 0) setup0 |= RTC_IRQ_SETUP_0_YEAR_ENA;
|
if (RTC_TEST_DT_ALARM(dtmask, RTC_DT_ALARM_YEAR))
|
||||||
if (month > 0) setup0 |= RTC_IRQ_SETUP_0_MONTH_ENA;
|
setup0 |= RTC_IRQ_SETUP_0_YEAR_ENA;
|
||||||
if (day > 0) setup0 |= RTC_IRQ_SETUP_0_DAY_ENA;
|
if (RTC_TEST_DT_ALARM(dtmask, RTC_DT_ALARM_MONTH))
|
||||||
if (dotw > 0) setup1 |= RTC_IRQ_SETUP_1_DOTW_ENA;
|
setup0 |= RTC_IRQ_SETUP_0_MONTH_ENA;
|
||||||
if (hour > 0) setup1 |= RTC_IRQ_SETUP_1_HOUR_ENA;
|
if (RTC_TEST_DT_ALARM(dtmask, RTC_DT_ALARM_DAY))
|
||||||
if (min > 0) setup1 |= RTC_IRQ_SETUP_1_MIN_ENA;
|
setup0 |= RTC_IRQ_SETUP_0_DAY_ENA;
|
||||||
if (sec > 0) setup1 |= RTC_IRQ_SETUP_1_SEC_ENA;
|
if (RTC_TEST_DT_ALARM(dtmask, RTC_DT_ALARM_DOTW))
|
||||||
|
setup1 |= RTC_IRQ_SETUP_1_DOTW_ENA;
|
||||||
|
if (RTC_TEST_DT_ALARM(dtmask, RTC_DT_ALARM_HOUR))
|
||||||
|
setup1 |= RTC_IRQ_SETUP_1_HOUR_ENA;
|
||||||
|
if (RTC_TEST_DT_ALARM(dtmask, RTC_DT_ALARM_MINUTE))
|
||||||
|
setup1 |= RTC_IRQ_SETUP_1_MIN_ENA;
|
||||||
|
if (RTC_TEST_DT_ALARM(dtmask, RTC_DT_ALARM_SECOND))
|
||||||
|
setup1 |= RTC_IRQ_SETUP_1_SEC_ENA;
|
||||||
|
|
||||||
/* Entering a reentrant critical zone.*/
|
/* Entering a reentrant critical zone.*/
|
||||||
syssts_t sts = osalSysGetStatusAndLockX();
|
syssts_t sts = osalSysGetStatusAndLockX();
|
||||||
|
@ -266,8 +279,9 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
|
||||||
rtcp->rtc->INTE = RTC_INTE_RTC;
|
rtcp->rtc->INTE = RTC_INTE_RTC;
|
||||||
rtc_enable_alarm(rtcp);
|
rtc_enable_alarm(rtcp);
|
||||||
|
|
||||||
/* Save the alarm setting. */
|
/* Save the alarm settings. */
|
||||||
rtcp->alarm = *timespec;
|
rtcp->alarm = *timespec;
|
||||||
|
rtcp->mask = dtmask;
|
||||||
|
|
||||||
/* Leaving a reentrant critical zone.*/
|
/* Leaving a reentrant critical zone.*/
|
||||||
osalSysRestoreStatusX(sts);
|
osalSysRestoreStatusX(sts);
|
||||||
|
@ -279,7 +293,7 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
|
||||||
*
|
*
|
||||||
* @param[in] rtcp pointer to RTC driver structure
|
* @param[in] rtcp pointer to RTC driver structure
|
||||||
* @param[in] alarm alarm identifier
|
* @param[in] alarm alarm identifier
|
||||||
* @param[out] alarmspec pointer to a @p RTCAlarm structure
|
* @param[in] alarmspec pointer to a @p RTCAlarm structure
|
||||||
*
|
*
|
||||||
* @notapi
|
* @notapi
|
||||||
*/
|
*/
|
||||||
|
@ -287,8 +301,10 @@ void rtc_lld_get_alarm(RTCDriver *rtcp,
|
||||||
rtcalarm_t alarm,
|
rtcalarm_t alarm,
|
||||||
RTCAlarm *alarmspec) {
|
RTCAlarm *alarmspec) {
|
||||||
|
|
||||||
|
/* TODO: Read back from the RTC registers (to reduce RTCDriver size). */
|
||||||
(void)alarm;
|
(void)alarm;
|
||||||
alarmspec->alarm = rtcp->alarm;
|
alarmspec->alarm = rtcp->alarm;
|
||||||
|
alarmspec->mask = rtcp->mask;
|
||||||
}
|
}
|
||||||
#endif /* RTC_ALARMS > 0 */
|
#endif /* RTC_ALARMS > 0 */
|
||||||
|
|
||||||
|
|
|
@ -69,28 +69,40 @@
|
||||||
/* Derived constants and error checks. */
|
/* Derived constants and error checks. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Date/time alarm setting values
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define RTC_DT_ALARM_SECOND 0U
|
||||||
|
#define RTC_DT_ALARM_MINUTE 1U
|
||||||
|
#define RTC_DT_ALARM_HOUR 2U
|
||||||
|
#define RTC_DT_ALARM_DAY 3U
|
||||||
|
#define RTC_DT_ALARM_MONTH 4U
|
||||||
|
#define RTC_DT_ALARM_YEAR 5U
|
||||||
|
#define RTC_DT_ALARM_DOTW 6U
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver data structures and types. */
|
/* Driver data structures and types. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Type of an RTC event.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
RTC_EVENT_SECOND = 0 /** Triggered every second. */
|
|
||||||
} rtcevent_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of a generic RTC callback.
|
* @brief Type of a generic RTC callback.
|
||||||
*/
|
*/
|
||||||
typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event);
|
typedef void (*rtccb_t)(RTCDriver *rtcp, rtcevent_t event);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Type of a date/time mask.
|
||||||
|
*/
|
||||||
|
typedef uint8_t rtcdtmask_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Type of a structure representing an RTC alarm time stamp.
|
* @brief Type of a structure representing an RTC alarm time stamp.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* End of the mandatory fields.*/
|
/* End of the mandatory fields.*/
|
||||||
RTCDateTime alarm;
|
RTCDateTime alarm;
|
||||||
|
rtcdtmask_t mask;
|
||||||
} RTCAlarm;
|
} RTCAlarm;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -101,12 +113,16 @@ typedef struct {
|
||||||
RTC_TypeDef *rtc; \
|
RTC_TypeDef *rtc; \
|
||||||
/* Callback pointer.*/ \
|
/* Callback pointer.*/ \
|
||||||
rtccb_t callback; \
|
rtccb_t callback; \
|
||||||
RTCDateTime alarm;
|
RTCDateTime alarm; \
|
||||||
|
rtcdtmask_t mask
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* Driver macros. */
|
/* Driver macros. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
#define RTC_ENABLE_DT_ALARM(n) (1U << n)
|
||||||
|
#define RTC_TEST_DT_ALARM(a, n) ((a & (1U << n)) != 0)
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
/* External declarations. */
|
/* External declarations. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
Loading…
Reference in New Issue