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-d51de3d6d3f4master
parent
124a432b0e
commit
9a98744b28
|
@ -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))
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
* DMA priorities:
|
||||
* 0...3 Lowest...Highest.
|
||||
*/
|
||||
#include "main.h"
|
||||
|
||||
/*
|
||||
* HAL driver system settings.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -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, ×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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue