From 9a98744b28ecfda0d78d5983e3a2d264c36bcec7 Mon Sep 17 00:00:00 2001 From: barthess Date: Thu, 15 Dec 2011 20:49:24 +0000 Subject: [PATCH] RTC. Testhal works on F4x, compiles (but not deeply tested) on F1x. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3615 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- boards/NONSTANDARD_STM32F4_BARTHESS1/board.h | 2 +- os/hal/include/rtc.h | 2 ++ os/hal/platforms/STM32/RTCv1/rtc_lld.h | 33 ++++++++++++++++++++ os/hal/platforms/STM32/RTCv2/rtc_lld.c | 27 +++++++++++----- os/hal/platforms/STM32/RTCv2/rtc_lld.h | 15 ++++++--- os/hal/src/rtc.c | 30 +++++++++++++++++- testhal/STM32F1xx/RTC/Makefile | 11 ++----- testhal/STM32F1xx/RTC/mcuconf.h | 2 +- testhal/STM32F4xx/RTC/halconf.h | 2 +- testhal/STM32F4xx/RTC/main.c | 22 ++++++++++--- 10 files changed, 117 insertions(+), 29 deletions(-) diff --git a/boards/NONSTANDARD_STM32F4_BARTHESS1/board.h b/boards/NONSTANDARD_STM32F4_BARTHESS1/board.h index 289eb6c56..c0c85dde0 100644 --- a/boards/NONSTANDARD_STM32F4_BARTHESS1/board.h +++ b/boards/NONSTANDARD_STM32F4_BARTHESS1/board.h @@ -274,7 +274,7 @@ PIN_PUDR_PULLUP(14) | \ PIN_PUDR_PULLUP(15)) /* 0x00000000 */ -#define VAL_GPIOB_ODR 0x000003B0 +#define VAL_GPIOB_ODR 0x000001C0 /* 0x00000000 */ #define VAL_GPIOB_AFRL (PIN_AFIO_AF(GPIOB_RECEIVER_PPM, 0) | \ PIN_AFIO_AF(GPIOB_JTDO, 0)) diff --git a/os/hal/include/rtc.h b/os/hal/include/rtc.h index ddb495205..354640a11 100644 --- a/os/hal/include/rtc.h +++ b/os/hal/include/rtc.h @@ -85,6 +85,8 @@ extern "C" { void rtcInit(void); void rtcSetTime(RTCDriver *rtcp, const RTCTime *timespec); void rtcGetTime(RTCDriver *rtcp, RTCTime *timespec); + void rtcSetWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec); + void rtcGetWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec); #if RTC_ALARMS > 0 void rtcSetAlarm(RTCDriver *rtcp, diff --git a/os/hal/platforms/STM32/RTCv1/rtc_lld.h b/os/hal/platforms/STM32/RTCv1/rtc_lld.h index b49031126..9237e4dc8 100644 --- a/os/hal/platforms/STM32/RTCv1/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv1/rtc_lld.h @@ -76,6 +76,11 @@ typedef struct RTCAlarm RTCAlarm; */ typedef struct RTCCallbackConfig RTCCallbackConfig; +/** + * @brief Type of a structure representing an RTC wakeup period. + */ +typedef struct RTCWakeup RTCWakeup; + /** * @brief Type of an RTC alarm. * @details Meaningful on platforms with more than 1 alarm comparator. @@ -142,9 +147,37 @@ struct RTCDriver{ rtccb_t rtc_cb; }; +/** + * @brief Structure representing an RTC periodic wakeup period. + * @note On this platform it is pointless. + */ +struct RTCWakeup { +}; + /*===========================================================================*/ /* Driver macros. */ /*===========================================================================*/ +/** + * @brief Gets time of periodic wakeup. + * + * @note On this platform function is pointless. + * There is no possibilities to change period on this platform. + * It always equal to 1 second. + * + * @notapi + */ +#define rtc_lld_set_periodic_wakeup(rtcp, wakeupspec){(void)wakeupspec;} + +/** + * @brief Gets time of periodic wakeup. + * + * @note On this platform function is pointless. + * There is no possibilities to change period on this platform. + * It always equal to 1 second. + * + * @notapi + */ +#define rtc_lld_get_periodic_wakeup(rtcp, wakeupspec){(void)wakeupspec;} /*===========================================================================*/ /* External declarations. */ diff --git a/os/hal/platforms/STM32/RTCv2/rtc_lld.c b/os/hal/platforms/STM32/RTCv2/rtc_lld.c index 3fdc7ceee..ca15dc1b9 100644 --- a/os/hal/platforms/STM32/RTCv2/rtc_lld.c +++ b/os/hal/platforms/STM32/RTCv2/rtc_lld.c @@ -185,12 +185,12 @@ void rtc_lld_get_time(RTCDriver *rtcp, RTCTime *timespec) { while(!(RTC->ISR & RTC_ISR_RSF)) ; - timespec->tv_time = RTCD1.id_rtc->TR; - timespec->tv_date = RTCD1.id_rtc->DR; #if STM32_RTC_HAS_SUBSECONDS - timespec->tv_msec = ((RTCD1.id_rtc->PRER & 0x7FFF) - RTCD1.id_rtc->SSR) / + timespec->tv_msec = (1000 * (RTCD1.id_rtc->PRER & 0x7FFF) - RTCD1.id_rtc->SSR) / ((RTCD1.id_rtc->PRER & 0x7FFF) + 1); #endif /* STM32_RTC_HAS_SUBSECONDS */ + timespec->tv_time = RTCD1.id_rtc->TR; + timespec->tv_date = RTCD1.id_rtc->DR; } /** @@ -297,26 +297,39 @@ void rtc_lld_get_periodic_wakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec){ */ void rtc_lld_set_callback(RTCDriver *rtcp, RTCCallbackConfig *cb_cfg) { - if (cb_cfg->cb_cfg & ALARMA_INT) + if (cb_cfg->cb_cfg & ALARMA_CB_FLAG) rtcp->id_rtc->CR |= RTC_CR_ALRAIE; else rtcp->id_rtc->CR &= ~RTC_CR_ALRAIE; - if (cb_cfg->cb_cfg & ALARMB_INT) + if (cb_cfg->cb_cfg & ALARMB_CB_FLAG) rtcp->id_rtc->CR |= RTC_CR_ALRBIE; else rtcp->id_rtc->CR &= ~RTC_CR_ALRBIE; - if (cb_cfg->cb_cfg & WAKEUP_INT) + if (cb_cfg->cb_cfg & WAKEUP_CB_FLAG) rtcp->id_rtc->CR |= RTC_CR_WUTIE; else rtcp->id_rtc->CR &= ~RTC_CR_WUTIE; - if (cb_cfg->cb_cfg & TIMESTAMP_INT) + if (cb_cfg->cb_cfg & TIMESTAMP_CB_FLAG) rtcp->id_rtc->CR |= RTC_CR_TSIE; else rtcp->id_rtc->CR &= ~RTC_CR_TSIE; } + +/** + * @brief Gets current RTC callbacks. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] cb_cfg callback bitmask + * + * @notapi + */ +void rtc_lld_get_callback(RTCDriver *rtcp, RTCCallbackConfig *cb_cfg) { + cb_cfg->cb_cfg = rtcp->cb_cfg->cb_cfg; +} + #endif /* RTC_SUPPORTS_CALLBACKS */ #endif /* HAL_USE_RTC */ diff --git a/os/hal/platforms/STM32/RTCv2/rtc_lld.h b/os/hal/platforms/STM32/RTCv2/rtc_lld.h index 8e1b58f6b..23ceb3132 100644 --- a/os/hal/platforms/STM32/RTCv2/rtc_lld.h +++ b/os/hal/platforms/STM32/RTCv2/rtc_lld.h @@ -48,12 +48,12 @@ #define RTC_ALARMS 2 /** - * @brief Interrupt enable masks. + * @brief Callback enable masks. */ -#define ALARMA_INT 0x1 -#define ALARMB_INT 0x2 -#define WAKEUP_INT 0x4 -#define TIMESTAMP_INT 0x8 +#define ALARMA_CB_FLAG 0x1 +#define ALARMB_CB_FLAG 0x2 +#define WAKEUP_CB_FLAG 0x4 +#define TIMESTAMP_CB_FLAG 0x8 /*===========================================================================*/ /* Driver pre-compile time settings. */ @@ -158,6 +158,11 @@ struct RTCWakeup { /** * @brief Structure representing an RTC callbacks config. + * @details It is bitmask. Set bit to enable callback, clear bit to disable. + * bit0 - alarmA + * bit1 - alarmB + * bit2 - wakeup + * bit3 - timestamp */ struct RTCCallbackConfig{ uint32_t cb_cfg; diff --git a/os/hal/src/rtc.c b/os/hal/src/rtc.c index 9df399eeb..20a39ea7c 100644 --- a/os/hal/src/rtc.c +++ b/os/hal/src/rtc.c @@ -135,10 +135,38 @@ void rtcGetAlarm(RTCDriver *rtcp, #endif /* RTC_ALARMS > 0 */ + +/** + * @brief Set periodic wakeup period. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[in] wakeupspec pointer to a @p RTCWakeup structure + * + * @api + */ +void rtcSetWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { + + chDbgCheck((rtcp != NULL), "rtcGetAlarm"); + rtc_lld_set_periodic_wakeup(rtcp, wakeupspec); +} + +/** + * @brief Get periodic wakeup period. + * + * @param[in] rtcp pointer to RTC driver structure + * @param[out] wakeupspec pointer to a @p RTCWakeup structure + * + * @api + */ +void rtcGetWakeup(RTCDriver *rtcp, RTCWakeup *wakeupspec) { + + chDbgCheck((rtcp != NULL), "rtcGetAlarm"); + rtc_lld_get_periodic_wakeup(rtcp, wakeupspec); +} + #if RTC_SUPPORTS_CALLBACKS || defined(__DOXYGEN__) /** * @brief Enables or disables RTC callbacks. - * @details TODO: * * @param[in] rtcp pointer to RTC driver structure * @param[in] cb_cfg callback configuration struct diff --git a/testhal/STM32F1xx/RTC/Makefile b/testhal/STM32F1xx/RTC/Makefile index e0c032c91..d11c0f579 100644 --- a/testhal/STM32F1xx/RTC/Makefile +++ b/testhal/STM32F1xx/RTC/Makefile @@ -5,14 +5,7 @@ # Compiler options here. ifeq ($(USE_OPT),) -#-fno-inline -# Don't pay attention to the inline keyword. Normally this option is used to keep the compiler from expanding any functions inline. Note that if you are not optimizing, no functions can be expanded inline. -#-finline-functions -# Integrate all simple functions into their callers. The compiler heuristically decides which functions are simple enough to be worth integrating in this way. -# If all calls to a given function are integrated, and the function is declared static, then the function is normally not output as assembler code in its own right. -# Enabled at level '-O3'. - - USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 + USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16 #USE_OPT = -O1 -ggdb -fomit-frame-pointer -falign-functions=16 -fno-inline #USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16 -fno-strict-aliasing #USE_OPT = -O3 -ggdb -fomit-frame-pointer -falign-functions=16 @@ -41,7 +34,7 @@ endif # Enable this if you want to see the full log while compiling. ifeq ($(USE_VERBOSE_COMPILE),) - USE_VERBOSE_COMPILE = no + USE_VERBOSE_COMPILE = yes endif # diff --git a/testhal/STM32F1xx/RTC/mcuconf.h b/testhal/STM32F1xx/RTC/mcuconf.h index 8413e2421..0ac17c3fd 100644 --- a/testhal/STM32F1xx/RTC/mcuconf.h +++ b/testhal/STM32F1xx/RTC/mcuconf.h @@ -30,7 +30,7 @@ * DMA priorities: * 0...3 Lowest...Highest. */ -#include "main.h" + /* * HAL driver system settings. */ diff --git a/testhal/STM32F4xx/RTC/halconf.h b/testhal/STM32F4xx/RTC/halconf.h index fc6e7aa8d..9e64ec3c0 100644 --- a/testhal/STM32F4xx/RTC/halconf.h +++ b/testhal/STM32F4xx/RTC/halconf.h @@ -156,7 +156,7 @@ * @brief Enables the RTC subsystem. */ #if !defined(RTC_SUPPORTS_CALLBACKS) || defined(__DOXYGEN__) -#define RTC_SUPPORTS_CALLBACKS FLASE +#define RTC_SUPPORTS_CALLBACKS TRUE #endif /*===========================================================================*/ diff --git a/testhal/STM32F4xx/RTC/main.c b/testhal/STM32F4xx/RTC/main.c index d6cf4f533..8864e0f01 100644 --- a/testhal/STM32F4xx/RTC/main.c +++ b/testhal/STM32F4xx/RTC/main.c @@ -18,12 +18,14 @@ along with this program. If not, see . */ #include +#include #include "ch.h" #include "hal.h" RTCTime timespec; RTCAlarm alarmspec; +RTCWakeup wakeupspec; RTCCallbackConfig cb_cfg; time_t unix_time; @@ -39,17 +41,20 @@ static inline void exti_rtcalarm_cb(EXTDriver *extp, expchannel_t channel){ if (RTCD1.id_rtc->ISR | RTC_ISR_ALRAF){ RTCD1.id_rtc->ISR &= ~RTC_ISR_ALRAF; } + palTogglePad(GPIOB, GPIOB_LED_R); } /** - * Wakeup callback + * Periodic wakeup callback */ static inline void exti_rtcwakeup_cb(EXTDriver *extp, expchannel_t channel){ (void)extp; (void)channel; + /* manually clear flags because exti driver does not do that */ if (RTCD1.id_rtc->ISR | RTC_ISR_WUTF){ RTCD1.id_rtc->ISR &= ~RTC_ISR_WUTF; } + palTogglePad(GPIOB, GPIOB_LED_R); } @@ -72,12 +77,12 @@ static const EXTConfig extcfg = { {EXT_CH_MODE_DISABLED, NULL}, {EXT_CH_MODE_DISABLED, NULL}, {EXT_CH_MODE_DISABLED, NULL}, - {EXT_CH_MODE_RISING_EDGE, exti_rtcalarm_cb},// RTC alarms + {EXT_CH_MODE_RISING_EDGE | EXT_CH_MODE_AUTOSTART, exti_rtcalarm_cb},// RTC alarms {EXT_CH_MODE_DISABLED, NULL}, {EXT_CH_MODE_DISABLED, NULL}, {EXT_CH_MODE_DISABLED, NULL}, {EXT_CH_MODE_DISABLED, NULL},// timestamp - {EXT_CH_MODE_RISING_EDGE, exti_rtcwakeup_cb},// wakeup + {EXT_CH_MODE_RISING_EDGE| EXT_CH_MODE_AUTOSTART, exti_rtcwakeup_cb},// wakeup }, EXT_MODE_EXTI( 0, @@ -157,6 +162,15 @@ int main(void){ extStart(&EXTD1, &extcfg); + /* tune wakeup callback */ + wakeupspec.wakeup = ((uint32_t)4) << 16; // select 1 Hz clock source + wakeupspec.wakeup |= 3; // set counter value to 3. Period will be 3+1 seconds. + rtcSetWakeup(&RTCD1, &wakeupspec); + + /* enable wakeup callback */ + cb_cfg.cb_cfg = WAKEUP_CB_FLAG; + rtcSetCallback(&RTCD1, &cb_cfg); + /* get current time in unix format */ rtcGetTime(&RTCD1, ×pec); bcd2tm(&timp, timespec.tv_time, timespec.tv_date); @@ -165,7 +179,7 @@ int main(void){ if (unix_time == -1){// incorrect time in RTC cell unix_time = 1000000000; } - + /* set correct time */ tm2bcd((localtime(&unix_time)), ×pec); rtcSetTime(&RTCD1, ×pec);