Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/fw/drivers/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,22 @@ RtcTicks rtc_alarm_get_elapsed_ticks(void);
//! us from going into stop mode before we're ready to wake up from it.
bool rtc_alarm_is_initialized(void);

// RTC Wake-up
///////////////////////////////////////////////////////////////////////////////

//! RTC second tick callback.
typedef void (*RtcSecondTickCallback)(void *ctx);

//! Configures the RTC to fire the given callback on every second tick.
//!
//! @note Callback happens in ISR context.
//!
//! @param callback Callback to call every time RTC increases 1 second.
//! @param ctx Context to pass to the callback when called.
void rtc_second_tick_subscribe(RtcSecondTickCallback callback, void *ctx);

//! Unsubscribes from the RTC second tick.
void rtc_second_tick_unsubscribe(void);

// Utility Functions
///////////////////////////////////////////////////////////////////////////////
Expand Down
38 changes: 38 additions & 0 deletions src/fw/drivers/rtc/sf32lb.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,17 @@ static RTC_HandleTypeDef RTC_Handler = {

static bool s_initialized = false;

static RtcSecondTickCallback s_second_tick_callback = NULL;
static void *s_second_tick_callback_ctx = NULL;

void RTC_IRQHandler(void) {
HAL_RTC_IRQHandler(&RTC_Handler);
}

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) {
s_second_tick_callback(s_second_tick_callback_ctx);
}

#ifndef SF32LB52_USE_LXT
static uint32_t prv_rtc_get_lpcycle() {
uint32_t value;
Expand Down Expand Up @@ -204,6 +215,9 @@ void rtc_init(void) {
prv_rtc_reconfig();
#endif

HAL_HPAON_EnableWakeupSrc(HPAON_WAKEUP_SRC_RTC, AON_PIN_MODE_HIGH);
HAL_NVIC_SetPriority(RTC_IRQn, 5, 0);

s_initialized = true;
}

Expand Down Expand Up @@ -477,3 +491,27 @@ void rtc_calibrate_frequency(uint32_t frequency) {
PBL_ASSERTN(success);
#endif
}

void rtc_second_tick_subscribe(RtcSecondTickCallback callback, void *ctx) {
PBL_ASSERTN(s_second_tick_callback == NULL);

s_second_tick_callback = callback;
s_second_tick_callback_ctx = ctx;

RTC_AlarmTypeDef alarm = {
// Mask all fields, and subsecond mask to 8-bit (covers DIV_B=256)
.AlarmMask = RTC_ALRMDR_MSKWD | RTC_ALRMDR_MSKM | RTC_ALRMDR_MSKD |
RTC_ALRMDR_MSKH | RTC_ALRMDR_MSKMN | RTC_ALRMDR_MSKS |
(8U << RTC_ALRMDR_MSKSS_Pos),
.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL,
};
HAL_RTC_SetAlarm(&RTC_Handler, &alarm, RTC_FORMAT_BIN);
}

void rtc_second_tick_unsubscribe(void) {
PBL_ASSERTN(s_second_tick_callback != NULL);

HAL_RTC_DeactivateAlarm(&RTC_Handler);

s_second_tick_callback = NULL;
}
19 changes: 19 additions & 0 deletions src/fw/services/common/tick_timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
#include "system/logging.h"
#include "system/passert.h"

// FIXME: Move to Kconfig
#ifdef MICRO_FAMILY_SF32LB52
#define USE_RTC_SECOND_TICK
#endif

static uint16_t s_num_subscribers;

static void timer_tick_event_publisher(void* data) {
Expand All @@ -18,18 +23,28 @@ static void timer_tick_event_publisher(void* data) {
.clock_tick.tick_time = rtc_get_time(),
};

#ifdef USE_RTC_SECOND_TICK
event_put_isr(&e);
#else
event_put(&e);
#endif
}

#ifndef USE_RTC_SECOND_TICK
static RegularTimerInfo s_tick_timer_info = {
.cb = &timer_tick_event_publisher
};
#endif

void tick_timer_add_subscriber(PebbleTask task) {
++s_num_subscribers;
if (s_num_subscribers == 1) {
PBL_LOG_DBG("starting tick timer");
#ifdef USE_RTC_SECOND_TICK
rtc_second_tick_subscribe(timer_tick_event_publisher, NULL);
#else
regular_timer_add_seconds_callback(&s_tick_timer_info);
#endif
}
}

Expand All @@ -38,6 +53,10 @@ void tick_timer_remove_subscriber(PebbleTask task) {
--s_num_subscribers;
if (s_num_subscribers == 0) {
PBL_LOG_DBG("stopping tick timer");
#ifdef USE_RTC_SECOND_TICK
rtc_second_tick_unsubscribe();
#else
regular_timer_remove_callback(&s_tick_timer_info);
#endif
}
}
Loading