Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32 LPTICKER : optimize RTC wake up timer init #6370

Merged
merged 1 commit into from
Mar 20, 2018
Merged
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
37 changes: 22 additions & 15 deletions targets/TARGET_STM/rtc_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,11 @@ uint32_t rtc_read_us(void)

void rtc_set_wake_up_timer(uint32_t delta)
{
#define RTC_CLOCK_US (((uint64_t)RTC_CLOCK << 32 ) / 1000000)

uint32_t WakeUpCounter;
uint32_t WakeUpClock;

/* Ex for Wakeup period resolution with RTCCLK=32768 Hz :
* RTCCLK_DIV2: ~122us < wakeup period < ~4s
* RTCCLK_DIV4: ~244us < wakeup period < ~8s
Expand All @@ -340,28 +345,30 @@ void rtc_set_wake_up_timer(uint32_t delta)
* CK_SPRE_16BITS: 1s < wakeup period < (0xFFFF+ 1) x 1 s = 65536 s (18 hours)
* CK_SPRE_17BITS: 18h+1s < wakeup period < (0x1FFFF+ 1) x 1 s = 131072 s (36 hours)
*/
uint32_t WakeUpClock[6] = {RTC_WAKEUPCLOCK_RTCCLK_DIV2, RTC_WAKEUPCLOCK_RTCCLK_DIV4, RTC_WAKEUPCLOCK_RTCCLK_DIV8, RTC_WAKEUPCLOCK_RTCCLK_DIV16, RTC_WAKEUPCLOCK_CK_SPRE_16BITS, RTC_WAKEUPCLOCK_CK_SPRE_17BITS};
uint8_t ClockDiv[4] = {2, 4, 8, 16};
uint32_t WakeUpCounter;
uint8_t DivIndex = 0;

do {
WakeUpCounter = delta / (ClockDiv[DivIndex] * 1000000 / RTC_CLOCK);
DivIndex++;
} while ( (WakeUpCounter > 0xFFFF) && (DivIndex < 4) );

if (WakeUpCounter > 0xFFFF) {
WakeUpCounter = delta / 1000000;
DivIndex++;
if (delta < (0x10000 * 2 / RTC_CLOCK * 1000000) ) { // (0xFFFF + 1) * RTCCLK_DIV2 / RTC_CLOCK * 1s
WakeUpCounter = (((uint64_t)delta * RTC_CLOCK_US) >> 32) >> 1 ;
WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV2;
} else if (delta < (0x10000 * 4 / RTC_CLOCK * 1000000) ) {
WakeUpCounter = (((uint64_t)delta * RTC_CLOCK_US) >> 32) >> 2 ;
WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV4;
} else if (delta < (0x10000 * 8 / RTC_CLOCK * 1000000) ) {
WakeUpCounter = (((uint64_t)delta * RTC_CLOCK_US) >> 32) >> 3 ;
WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV8;
} else if (delta < (0x10000 * 16 / RTC_CLOCK * 1000000) ) {
WakeUpCounter = (((uint64_t)delta * RTC_CLOCK_US) >> 32) >> 4 ;
WakeUpClock = RTC_WAKEUPCLOCK_RTCCLK_DIV16;
} else {
WakeUpCounter = (delta / 1000000) ;
WakeUpClock = RTC_WAKEUPCLOCK_CK_SPRE_16BITS;
}

irq_handler = (void (*)(void))lp_ticker_irq_handler;
NVIC_SetVector(RTC_WKUP_IRQn, (uint32_t)RTC_IRQHandler);
NVIC_EnableIRQ(RTC_WKUP_IRQn);

RtcHandle.Instance = RTC;
if (HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, 0xFFFF & WakeUpCounter, WakeUpClock[DivIndex - 1]) != HAL_OK) {
error("rtc_set_wake_up_timer init error (%d)\n", DivIndex);
if (HAL_RTCEx_SetWakeUpTimer_IT(&RtcHandle, (uint32_t)WakeUpCounter, WakeUpClock) != HAL_OK) {
error("rtc_set_wake_up_timer init error\n");
}
}

Expand Down