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
This commit is contained in:
barthess 2011-12-15 20:49:24 +00:00
parent 124a432b0e
commit 9a98744b28
10 changed files with 117 additions and 29 deletions

View File

@ -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))

View File

@ -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,

View File

@ -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. */

View File

@ -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 */

View File

@ -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;

View File

@ -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

View File

@ -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
#

View File

@ -30,7 +30,7 @@
* DMA priorities:
* 0...3 Lowest...Highest.
*/
#include "main.h"
/*
* HAL driver system settings.
*/

View File

@ -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
/*===========================================================================*/

View File

@ -18,12 +18,14 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <time.h>
#include <stdlib.h>
#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, &timespec);
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)), &timespec);
rtcSetTime(&RTCD1, &timespec);