RTCv1 code cleanups and adding some safety checks.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3603 35acf78f-673a-0410-8e92-d51de3d6d3f4
master
barthess 2011-12-12 13:13:07 +00:00
parent 527ef56ed3
commit dd834361e8
4 changed files with 32 additions and 40 deletions

View File

@ -60,16 +60,16 @@ static void rtc_lld_serve_interrupt(RTCDriver *rtcp) {
chSysLockFromIsr(); chSysLockFromIsr();
if ((RTC->CRH & RTC_CRH_SECIE) && (RTC->CRL & RTC_CRL_SECF)) { if ((RTC->CRH & RTC_CRH_SECIE) && (RTC->CRL & RTC_CRL_SECF)) {
rtcp->rtc_cb(rtcp, RTC_EVENT_SECOND);
RTC->CRL &= ~RTC_CRL_SECF; RTC->CRL &= ~RTC_CRL_SECF;
rtcp->rtc_cb(rtcp, RTC_EVENT_SECOND);
} }
if ((RTC->CRH & RTC_CRH_ALRIE) && (RTC->CRL & RTC_CRL_ALRF)) { if ((RTC->CRH & RTC_CRH_ALRIE) && (RTC->CRL & RTC_CRL_ALRF)) {
rtcp->rtc_cb(rtcp, RTC_EVENT_ALARM);
RTC->CRL &= ~RTC_CRL_ALRF; RTC->CRL &= ~RTC_CRL_ALRF;
rtcp->rtc_cb(rtcp, RTC_EVENT_ALARM);
} }
if ((RTC->CRH & RTC_CRH_OWIE) && (RTC->CRL & RTC_CRL_OWF)) { if ((RTC->CRH & RTC_CRH_OWIE) && (RTC->CRL & RTC_CRL_OWF)) {
rtcp->rtc_cb(rtcp, RTC_EVENT_OVERFLOW);
RTC->CRL &= ~RTC_CRL_OWF; RTC->CRL &= ~RTC_CRL_OWF;
rtcp->rtc_cb(rtcp, RTC_EVENT_OVERFLOW);
} }
chSysUnlockFromIsr(); chSysUnlockFromIsr();
@ -225,10 +225,8 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) {
uint32_t time_frac; uint32_t time_frac;
READ_REGISTERS: READ_REGISTERS:
chSysLock();
timespec->tv_sec = ((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL; timespec->tv_sec = ((uint32_t)(RTC->CNTH) << 16) + RTC->CNTL;
time_frac = (((uint32_t)RTC->DIVH) << 16) + (uint32_t)RTC->DIVL; time_frac = (((uint32_t)RTC->DIVH) << 16) + (uint32_t)RTC->DIVL;
chSysUnlock();
/* If second counter updated between reading of integer and fractional parts /* If second counter updated between reading of integer and fractional parts
* we must reread both values. */ * we must reread both values. */
@ -306,20 +304,22 @@ void rtc_lld_get_alarm(RTCDriver *rtcp,
* *
* @notapi * @notapi
*/ */
void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback) { void rtc_lld_set_callback(RTCDriver *rtcp, RTCCallbackConfig *cb_cfg) {
if (callback != NULL) {
rtcp->rtc_cb = callback;
NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY));
if (cb_cfg->rtc_cb != NULL) {
rtcp->rtc_cb = cb_cfg->rtc_cb;
/* Interrupts are enabled only after setting up the callback, this /* Interrupts are enabled only after setting up the callback, this
way there is no need to check for the NULL callback pointer inside way there is no need to check for the NULL callback pointer inside
the IRQ handler.*/ the IRQ handler.*/
rtc_lld_wait_write();
RTC->CRL &= ~(RTC_CRL_OWF | RTC_CRL_ALRF | RTC_CRL_SECF); RTC->CRL &= ~(RTC_CRL_OWF | RTC_CRL_ALRF | RTC_CRL_SECF);
NVICEnableVector(RTC_IRQn, CORTEX_PRIORITY_MASK(STM32_RTC_IRQ_PRIORITY));
rtc_lld_wait_write();
RTC->CRH |= RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE; RTC->CRH |= RTC_CRH_OWIE | RTC_CRH_ALRIE | RTC_CRH_SECIE;
} }
else { else {
NVICDisableVector(RTC_IRQn); NVICDisableVector(RTC_IRQn);
rtc_lld_wait_write();
RTC->CRL = 0; RTC->CRL = 0;
RTC->CRH = 0; RTC->CRH = 0;
} }

View File

@ -166,7 +166,7 @@ extern "C" {
void rtc_lld_get_alarm(RTCDriver *rtcp, void rtc_lld_get_alarm(RTCDriver *rtcp,
rtcalarm_t alarm, rtcalarm_t alarm,
RTCAlarm *alarmspec); RTCAlarm *alarmspec);
void rtc_lld_set_callback(RTCDriver *rtcp, rtccb_t callback); void rtc_lld_set_callback(RTCDriver *rtcp, RTCCallbackConfig *cb_cfg);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -134,26 +134,6 @@ void rtcGetAlarm(RTCDriver *rtcp,
} }
#endif /* RTC_ALARMS > 0 */ #endif /* RTC_ALARMS > 0 */
/**
* @brief Sets periodic wakeup period.
*/
void rtcSetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) {
chDbgCheck((rtcp != NULL) && (wakeupspec != NULL), "rtcSetPeriodicWakeup");
rtc_lld_set_periodic_wakeup(rtcp, wakeupspec);
}
/**
* @brief Gets periodic wakeup period.
*/
void rtcGetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) {
chDbgCheck((rtcp != NULL) && (wakeupspec != NULL), "rtcGetPeriodicWakeup");
rtc_lld_get_periodic_wakeup(rtcp, wakeupspec);
}
#if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__) #if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__)
/** /**

View File

@ -24,7 +24,7 @@
RTCTime timespec; RTCTime timespec;
RTCAlarm alarmspec; RTCAlarm alarmspec;
#define TEST_ALARM_WAKEUP TRUE #define TEST_ALARM_WAKEUP FALSE
#if TEST_ALARM_WAKEUP #if TEST_ALARM_WAKEUP
@ -63,8 +63,10 @@ int main(void) {
#else /* TEST_ALARM_WAKEUP */ #else /* TEST_ALARM_WAKEUP */
/**
* Callback function for RTC.
*/
static void my_cb(RTCDriver *rtcp, rtcevent_t event) { static void my_cb(RTCDriver *rtcp, rtcevent_t event) {
(void)rtcp; (void)rtcp;
switch (event) { switch (event) {
@ -77,21 +79,31 @@ static void my_cb(RTCDriver *rtcp, rtcevent_t event) {
case RTC_EVENT_ALARM: case RTC_EVENT_ALARM:
palTogglePad(GPIOC, GPIOC_LED); palTogglePad(GPIOC, GPIOC_LED);
rtcGetTime(&RTCD1, &timespec); rtcGetTime(&RTCD1, &timespec);
alarmspec.tv_sec = timespec.tv_sec + 10; alarmspec.tv_sec = timespec.tv_sec + 5;
rtcSetAlarm(&RTCD1, 0, &alarmspec); rtcSetAlarm(&RTCD1, 0, &alarmspec);
break; break;
} }
} }
/**
* Configuration structure with all callbacks supported by platform.
*/
static RTCCallbackConfig rtc_cb_cfg = {
my_cb
};
/**
* Main function.
*/
int main(void){ int main(void){
halInit(); halInit();
chSysInit(); chSysInit();
rtcGetTime(&RTCD1, &timespec); rtcGetTime(&RTCD1, &timespec);
alarmspec.tv_sec = timespec.tv_sec + 10; alarmspec.tv_sec = timespec.tv_sec + 5;
rtcSetAlarm(&RTCD1, 0, &alarmspec); rtcSetAlarm(&RTCD1, 0, &alarmspec);
rtcSetCallback(&RTCD1, my_cb); rtcSetCallback(&RTCD1, &rtc_cb_cfg);
while (TRUE){ while (TRUE){
chThdSleepMilliseconds(500); chThdSleepMilliseconds(500);
} }