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

sam0/rtc_rtt: optimizations to get around the painful long syncwaits #18920

Merged
merged 2 commits into from
Nov 22, 2022
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
66 changes: 38 additions & 28 deletions cpu/sam0_common/periph/rtc_rtt.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,10 +588,22 @@ int rtc_get_time(struct tm *time)
return 0;
}

static void _rtc_clear_alarm(void)
{
/* disable alarm interrupt */
RTC->MODE2.INTENCLR.reg = RTC_MODE2_INTENCLR_ALARM0;
}

void rtc_clear_alarm(void)
{
_rtc_clear_alarm();
_pm_unblock(&_pm_alarm);
}

int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg)
{
/* prevent old alarm from ringing */
rtc_clear_alarm();
_rtc_clear_alarm();

/* normalize input */
rtc_tm_normalize(time);
Expand All @@ -600,18 +612,18 @@ int rtc_set_alarm(struct tm *time, rtc_alarm_cb_t cb, void *arg)
(time->tm_year > (reference_year + 63))) {
return -2;
}
else {
RTC->MODE2.Mode2Alarm[0].ALARM.reg = RTC_MODE2_ALARM_YEAR(time->tm_year - reference_year)
| RTC_MODE2_ALARM_MONTH(time->tm_mon + 1)
| RTC_MODE2_ALARM_DAY(time->tm_mday)
| RTC_MODE2_ALARM_HOUR(time->tm_hour)
| RTC_MODE2_ALARM_MINUTE(time->tm_min)
| RTC_MODE2_ALARM_SECOND(time->tm_sec);
RTC->MODE2.Mode2Alarm[0].MASK.reg = RTC_MODE2_MASK_SEL(6);
}

/* make sure that preceding changes have been applied */
_wait_syncbusy();

RTC->MODE2.Mode2Alarm[0].ALARM.reg = RTC_MODE2_ALARM_YEAR(time->tm_year - reference_year)
| RTC_MODE2_ALARM_MONTH(time->tm_mon + 1)
| RTC_MODE2_ALARM_DAY(time->tm_mday)
| RTC_MODE2_ALARM_HOUR(time->tm_hour)
| RTC_MODE2_ALARM_MINUTE(time->tm_min)
| RTC_MODE2_ALARM_SECOND(time->tm_sec);
RTC->MODE2.Mode2Alarm[0].MASK.reg = RTC_MODE2_MASK_SEL(6);

/* Enable IRQ */
alarm_cb.cb = cb;
alarm_cb.arg = arg;
Expand Down Expand Up @@ -650,14 +662,6 @@ int rtc_set_time(struct tm *time)
return 0;
}

void rtc_clear_alarm(void)
{
/* disable alarm interrupt */
RTC->MODE2.INTENCLR.reg = RTC_MODE2_INTENCLR_ALARM0;

_pm_unblock(&_pm_alarm);
}

void rtc_poweron(void)
{
_poweron();
Expand Down Expand Up @@ -713,18 +717,32 @@ uint32_t rtt_get_alarm(void)
return RTC->MODE0.COMP[0].reg;
}

static void _rtt_clear_alarm(void)
{
/* disable compare interrupt */
RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
}

void rtt_clear_alarm(void)
{
_rtt_clear_alarm();
_pm_unblock(&_pm_alarm);
}

void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
{
/* disable interrupt to avoid race */
rtt_clear_alarm();
_rtt_clear_alarm();

/* setup callback */
alarm_cb.cb = cb;
alarm_cb.arg = arg;

/* make sure that preceding changes have been applied */
_wait_syncbusy();

/* set COMP register */
RTC->MODE0.COMP[0].reg = alarm;
_wait_syncbusy();

/* enable compare interrupt and clear flag */
RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
Expand All @@ -736,14 +754,6 @@ void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
}
}

void rtt_clear_alarm(void)
{
/* disable compare interrupt */
RTC->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;

_pm_unblock(&_pm_alarm);
}

void rtt_poweron(void)
{
_poweron();
Expand Down