aboutsummaryrefslogtreecommitdiffstats
path: root/os
diff options
context:
space:
mode:
authorgdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-10-30 14:24:38 +0000
committergdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>2014-10-30 14:24:38 +0000
commitb665c20b66e3aff4dc953186df25d0b741634f56 (patch)
treeddf113371faf1c980dcf3b44fdd70326ff03598e /os
parent0de9b5fb056f895437cd939027e536a42b4c04bd (diff)
downloadChibiOS-b665c20b66e3aff4dc953186df25d0b741634f56.tar.gz
ChibiOS-b665c20b66e3aff4dc953186df25d0b741634f56.tar.bz2
ChibiOS-b665c20b66e3aff4dc953186df25d0b741634f56.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7435 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'os')
-rw-r--r--os/hal/include/rtc.h65
-rw-r--r--os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c116
-rw-r--r--os/hal/src/rtc.c60
3 files changed, 115 insertions, 126 deletions
diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h
index 0c3e89b0d..91a3d71e5 100644
--- a/os/hal/include/rtc.h
+++ b/os/hal/include/rtc.h
@@ -105,71 +105,6 @@ typedef struct {
/* Driver macros. */
/*===========================================================================*/
-/**
- * @brief Set current time.
- *
- * @param[in] rtcp pointer to RTC driver structure
- * @param[in] timespec pointer to a @p RTCDateTime structure
- *
- * @iclass
- */
-#define rtcSetTimeI(rtcp, timespec) \
- rtc_lld_set_time(rtcp, timespec)
-
-/**
- * @brief Get current time.
- *
- * @param[in] rtcp pointer to RTC driver structure
- * @param[out] timespec pointer to a @p RTCDateTime structure
- *
- * @iclass
- */
-#define rtcGetTimeI(rtcp, timespec) \
- rtc_lld_get_time(rtcp, timespec)
-
-#if (RTC_ALARMS > 0) || defined(__DOXYGEN__)
-/**
- * @brief Set alarm time.
- *
- * @param[in] rtcp pointer to RTC driver structure
- * @param[in] alarm alarm identifier
- * @param[in] alarmspec pointer to a @p RTCAlarm structure or @p NULL
- *
- * @iclass
- */
-#define rtcSetAlarmI(rtcp, alarm, alarmspec) \
- rtc_lld_set_alarm(rtcp, alarm, alarmspec)
-
-/**
- * @brief Get current alarm.
- * @note If an alarm has not been set then the returned alarm specification
- * is not meaningful.
- *
- * @param[in] rtcp pointer to RTC driver structure
- * @param[in] alarm alarm identifier
- * @param[out] alarmspec pointer to a @p RTCAlarm structure
- *
- * @iclass
- */
-#define rtcGetAlarmI(rtcp, alarm, alarmspec) \
- rtc_lld_get_alarm(rtcp, alarm, alarmspec)
-#endif /* RTC_ALARMS > 0 */
-
-#if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__)
-/**
- * @brief Enables or disables RTC callbacks.
- * @details This function enables or disables the callback, use a @p NULL
- * pointer in order to disable it.
- *
- * @param[in] rtcp pointer to RTC driver structure
- * @param[in] callback callback function pointer or @p NULL
- *
- * @iclass
- */
-#define rtcSetCallbackI(rtcp, callback) \
- rtc_lld_set_callback(rtcp, callback)
-#endif /* RTC_SUPPORTS_CALLBACKS */
-
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
diff --git a/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c b/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c
index 6ca7a00b1..79b4268ca 100644
--- a/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c
+++ b/os/hal/ports/STM32/LLD/RTCv2/rtc_lld.c
@@ -68,19 +68,6 @@ RTCDriver RTCD1;
/*===========================================================================*/
/**
- * @brief Wait for synchronization of RTC registers with shadow registers.
- * @details This function must be invoked before trying to access RTC
- * registers.
- *
- * @notapi
- */
-static void rtc_regs_sync(void) {
-
- while ((RTCD1.rtc->ISR & RTC_ISR_RSF) == 0)
- ;
-}
-
-/**
* @brief Beginning of configuration procedure.
*
* @notapi
@@ -221,7 +208,7 @@ static uint32_t rtc_encode_date(const RTCDateTime *timespec) {
/**
* @brief Enable access to registers.
*
- * @api
+ * @notapi
*/
void rtc_lld_init(void) {
@@ -232,92 +219,120 @@ void rtc_lld_init(void) {
RTCD1.rtc->WPR = 0xCA;
RTCD1.rtc->WPR = 0x53;
+ rtc_enter_init();
+
/* If calendar has not been initialized yet then proceed with the
initial setup.*/
if (!(RTCD1.rtc->ISR & RTC_ISR_INITS)) {
- rtc_enter_init();
RTCD1.rtc->CR = 0;
RTCD1.rtc->ISR = 0;
RTCD1.rtc->PRER = STM32_RTC_PRER_BITS;
RTCD1.rtc->PRER = STM32_RTC_PRER_BITS;
-
- rtc_exit_init();
}
+ else
+ RTCD1.rtc->ISR &= ~RTC_ISR_RSF;
+
+ rtc_exit_init();
}
/**
* @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
*
- * @api
+ * @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);
- rtc_regs_sync();
+ /* Entering a reentrant critical zone.*/
+ sts = chSysGetStatusAndLockX();
+ /* Writing the registers.*/
rtc_enter_init();
-
rtcp->rtc->TR = tr;
rtcp->rtc->DR = dr;
-
rtc_exit_init();
+
+ /* Leaving a reentrant critical zone.*/
+ chSysRestoreStatusX(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
*
- * @api
+ * @notapi
*/
void rtc_lld_get_time(RTCDriver *rtcp, RTCDateTime *timespec) {
+ uint32_t dr, tr, ssr;
uint32_t subs;
+ syssts_t sts;
+
+ /* Entering a reentrant critical zone.*/
+ sts = chSysGetStatusAndLockX();
+
+ /* Synchronization with the RTC and reading the registers, note
+ DR must be read last.*/
+ while ((rtcp->rtc->ISR & RTC_ISR_RSF) == 0)
+ ;
+ ssr = rtcp->rtc->SSR;
+ tr = rtcp->rtc->TR;
+ dr = rtcp->rtc->DR;
+ rtcp->rtc->ISR &= ~RTC_ISR_RSF;
- rtc_regs_sync();
+ /* Leaving a reentrant critical zone.*/
+ chSysRestoreStatusX(sts);
/* Decoding day time, this starts the atomic read sequence, see "Reading
the calendar" in the RTC documentation.*/
- rtc_decode_time(rtcp->rtc->TR, timespec);
+ 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 = (((rtcp->rtc->SSR << 16) / STM32_RTC_PRESS_VALUE) * 1000) >> 16;
+ subs = (((ssr << 16) / STM32_RTC_PRESS_VALUE) * 1000) >> 16;
#else
subs = 0;
#endif /* STM32_RTC_HAS_SUBSECONDS */
timespec->millisecond += subs;
/* Decoding date, this concludes the atomic read sequence.*/
- rtc_decode_date(rtcp->rtc->DR, timespec);
+ rtc_decode_date(dr, 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.
+ * @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 1 or 2.
- * @param[in] alarmspec Pointer to a @p RTCAlarm structure.
+ * @param[in] rtcp pointer to RTC driver structure.
+ * @param[in] alarm alarm identifier. Can be 1 or 2.
+ * @param[in] alarmspec pointer to a @p RTCAlarm structure.
*
- * @api
+ * @notapi
*/
void rtc_lld_set_alarm(RTCDriver *rtcp,
rtcalarm_t alarm,
const RTCAlarm *alarmspec) {
+ syssts_t sts;
+
+ /* Entering a reentrant critical zone.*/
+ sts = chSysGetStatusAndLockX();
if (alarm == 1) {
if (alarmspec != NULL) {
@@ -349,20 +364,25 @@ void rtc_lld_set_alarm(RTCDriver *rtcp,
}
}
#endif /* RTC_ALARMS > 1 */
+
+ /* Leaving a reentrant critical zone.*/
+ chSysRestoreStatusX(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
* @param[out] alarmspec pointer to a @p RTCAlarm structure
*
- * @api
+ * @notapi
*/
void rtc_lld_get_alarm(RTCDriver *rtcp,
rtcalarm_t alarm,
RTCAlarm *alarmspec) {
+
if (alarm == 1)
alarmspec->alrmr = rtcp->rtc->ALRMAR;
#if RTC_ALARMS > 1
@@ -375,9 +395,9 @@ void rtc_lld_get_alarm(RTCDriver *rtcp,
#if STM32_RTC_HAS_PERIODIC_WAKEUPS || defined(__DOXYGEN__)
/**
- * @brief Sets time of periodic wakeup.
- *
- * @note Default value after BKP domain reset is 0x0000FFFF
+ * @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
@@ -385,6 +405,10 @@ void rtc_lld_get_alarm(RTCDriver *rtcp,
* @api
*/
void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) {
+ syssts_t sts;
+
+ /* Entering a reentrant critical zone.*/
+ sts = chSysGetStatusAndLockX();
if (wakeupspec != NULL) {
osalDbgCheck(wakeupspec->wutr != 0x30000);
@@ -401,12 +425,15 @@ void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) {
rtcp->rtc->CR &= ~RTC_CR_WUTIE;
rtcp->rtc->CR &= ~RTC_CR_WUTE;
}
+
+ /* Leaving a reentrant critical zone.*/
+ chSysRestoreStatusX(sts);
}
/**
- * @brief Gets time of periodic wakeup.
- *
- * @note Default value after BKP domain reset is 0x0000FFFF
+ * @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
@@ -414,10 +441,17 @@ void rtcSTM32SetPeriodicWakeup(RTCDriver *rtcp, const RTCWakeup *wakeupspec) {
* @api
*/
void rtcSTM32GetPeriodicWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) {
+ syssts_t sts;
+
+ /* Entering a reentrant critical zone.*/
+ sts = chSysGetStatusAndLockX();
wakeupspec->wutr = 0;
wakeupspec->wutr |= rtcp->rtc->WUTR;
wakeupspec->wutr |= (((uint32_t)rtcp->rtc->CR) & 0x7) << 16;
+
+ /* Leaving a reentrant critical zone.*/
+ chSysRestoreStatusX(sts);
}
#endif /* STM32_RTC_HAS_PERIODIC_WAKEUPS */
diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c
index a80b91444..d3799a011 100644
--- a/os/hal/src/rtc.c
+++ b/os/hal/src/rtc.c
@@ -68,47 +68,61 @@ void rtcInit(void) {
/**
* @brief Set current time.
+ * @note This function can be called from any context but limitations
+ * could be imposed by the low level implementation. It is
+ * guaranteed that the function can be called from thread
+ * context.
+ * @note The function can be reentrant or not reentrant depending on
+ * the low level implementation.
*
* @param[in] rtcp pointer to RTC driver structure
* @param[in] timespec pointer to a @p RTCDateTime structure
*
- * @api
+ * @special
*/
void rtcSetTime(RTCDriver *rtcp, const RTCDateTime *timespec) {
osalDbgCheck((rtcp != NULL) && (timespec != NULL));
- osalSysLock();
- rtcSetTimeI(rtcp, timespec);
- osalSysUnlock();
+ rtc_lld_set_time(rtcp, timespec);
}
/**
* @brief Get current time.
+ * @note This function can be called from any context but limitations
+ * could be imposed by the low level implementation. It is
+ * guaranteed that the function can be called from thread
+ * context.
+ * @note The function can be reentrant or not reentrant depending on
+ * the low level implementation.
*
* @param[in] rtcp pointer to RTC driver structure
* @param[out] timespec pointer to a @p RTCDateTime structure
*
- * @api
+ * @special
*/
void rtcGetTime(RTCDriver *rtcp, RTCDateTime *timespec) {
osalDbgCheck((rtcp != NULL) && (timespec != NULL));
- osalSysLock();
- rtcGetTimeI(rtcp, timespec);
- osalSysUnlock();
+ rtc_lld_get_time(rtcp, timespec);
}
#if (RTC_ALARMS > 0) || defined(__DOXYGEN__)
/**
* @brief Set alarm time.
+ * @note This function can be called from any context but limitations
+ * could be imposed by the low level implementation. It is
+ * guaranteed that the function can be called from thread
+ * context.
+ * @note The function can be reentrant or not reentrant depending on
+ * the low level implementation.
*
* @param[in] rtcp pointer to RTC driver structure
* @param[in] alarm alarm identifier
* @param[in] alarmspec pointer to a @p RTCAlarm structure or @p NULL
*
- * @api
+ * @special
*/
void rtcSetAlarm(RTCDriver *rtcp,
rtcalarm_t alarm,
@@ -116,21 +130,25 @@ void rtcSetAlarm(RTCDriver *rtcp,
osalDbgCheck((rtcp != NULL) && (alarm < RTC_ALARMS));
- osalSysLock();
- rtcSetAlarmI(rtcp, alarm, alarmspec);
- osalSysUnlock();
+ rtc_lld_set_alarm(rtcp, alarm, alarmspec);
}
/**
* @brief Get current alarm.
* @note If an alarm has not been set then the returned alarm specification
* is not meaningful.
+ * @note This function can be called from any context but limitations
+ * could be imposed by the low level implementation. It is
+ * guaranteed that the function can be called from thread
+ * context.
+ * @note The function can be reentrant or not reentrant depending on
+ * the low level implementation.
*
* @param[in] rtcp pointer to RTC driver structure
* @param[in] alarm alarm identifier
* @param[out] alarmspec pointer to a @p RTCAlarm structure
*
- * @api
+ * @special
*/
void rtcGetAlarm(RTCDriver *rtcp,
rtcalarm_t alarm,
@@ -138,9 +156,7 @@ void rtcGetAlarm(RTCDriver *rtcp,
osalDbgCheck((rtcp != NULL) && (alarm < RTC_ALARMS) && (alarmspec != NULL));
- osalSysLock();
- rtcGetAlarmI(rtcp, alarm, alarmspec);
- osalSysUnlock();
+ rtc_lld_get_alarm(rtcp, alarm, alarmspec);
}
#endif /* RTC_ALARMS > 0 */
@@ -149,19 +165,23 @@ void rtcGetAlarm(RTCDriver *rtcp,
* @brief Enables or disables RTC callbacks.
* @details This function enables or disables the callback, use a @p NULL
* pointer in order to disable it.
+ * @note This function can be called from any context but limitations
+ * could be imposed by the low level implementation. It is
+ * guaranteed that the function can be called from thread
+ * context.
+ * @note The function can be reentrant or not reentrant depending on
+ * the low level implementation.
*
* @param[in] rtcp pointer to RTC driver structure
* @param[in] callback callback function pointer or @p NULL
*
- * @api
+ * @special
*/
void rtcSetCallback(RTCDriver *rtcp, rtccb_t callback) {
osalDbgCheck(rtcp != NULL);
- osalSysLock();
- rtcSetCallbackI(rtcp, callback);
- osalSysUnlock();
+ rtc_lld_set_callback(rtcp, callback);
}
#endif /* RTC_SUPPORTS_CALLBACKS */