summaryrefslogtreecommitdiff
path: root/bsp
diff options
context:
space:
mode:
authorJingbao Qiu <[email protected]>2024-03-20 15:54:06 +0800
committerMeco Man <[email protected]>2024-03-20 18:22:20 -0400
commit9e6ca172591cd378d465d5001cea7881cbe4efce (patch)
treee7dc09ad038bf490046983cbab1c0509cf10ea38 /bsp
parent73850e24c6296c27e84eb9334b38eb91733d2d5d (diff)
[bsp][CV1800B] add RTC Alarm function for CV1800B
Signed-off-by: Jingbao Qiu <[email protected]>
Diffstat (limited to 'bsp')
-rw-r--r--bsp/cvitek/drivers/drv_rtc.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/bsp/cvitek/drivers/drv_rtc.c b/bsp/cvitek/drivers/drv_rtc.c
index 975b361a1c..92019b9587 100644
--- a/bsp/cvitek/drivers/drv_rtc.c
+++ b/bsp/cvitek/drivers/drv_rtc.c
@@ -54,6 +54,7 @@
#define RTC_SEC_MAX_VAL 0xFFFFFFFF
#define RTC_OFFSET_SN 0x5201800
+#define RTC_ALARM_IRQ_NUM 0x11
struct rtc_device_object
{
@@ -298,13 +299,86 @@ static rt_err_t _rtc_set_secs(time_t *sec)
return result;
}
+#ifdef RT_USING_ALARM
+static void rtc_alarm_enable(rt_bool_t enable)
+{
+ mmio_write_32(CVI_RTC_BASE + CVI_RTC_ALARM_ENABLE, enable);
+}
+
+static void rt_hw_rtc_isr(int irqno, void *param)
+{
+ rt_interrupt_enter();
+
+ /* send event to alarm */
+ rt_alarm_update(&rtc_device.rtc_dev.parent, 1);
+ /* clear alarm */
+ rtc_alarm_enable(0);
+
+ rt_interrupt_leave();
+}
+#endif
+
+static rt_err_t _rtc_get_alarm(struct rt_rtc_wkalarm *alarm)
+{
+ if (alarm == RT_NULL)
+ return -RT_ERROR;
+
+ unsigned long int sec;
+ cvi_rtc_time_t t = {0};
+
+ sec = mmio_read_32(CVI_RTC_BASE + CVI_RTC_ALARM_TIME);
+ rtc_time64_to_tm(sec, &t);
+
+ alarm->tm_sec = t.tm_sec;
+ alarm->tm_min = t.tm_min;
+ alarm->tm_hour = t.tm_hour;
+ alarm->tm_mday = t.tm_mday;
+ alarm->tm_mon = t.tm_mon;
+ alarm->tm_year = t.tm_year;
+ LOG_D("GET_ALARM %d:%d:%d", alarm->tm_hour, alarm->tm_min, alarm->tm_sec);
+
+ return RT_EOK;
+}
+
+static rt_err_t _rtc_set_alarm(struct rt_rtc_wkalarm *alarm)
+{
+ if (alarm == RT_NULL)
+ return -RT_ERROR;
+
+ cvi_rtc_time_t t = {0};
+ unsigned long int set_sec;
+
+ if (alarm->enable){
+ t.tm_sec = alarm->tm_sec;
+ t.tm_min = alarm->tm_min;
+ t.tm_hour = alarm->tm_hour;
+ t.tm_mday = alarm->tm_mday;
+ t.tm_mon = alarm->tm_mon;
+ t.tm_year = alarm->tm_year;
+
+ set_sec = rtc_tm_to_time64(&t);
+ mmio_write_32(CVI_RTC_BASE + CVI_RTC_ALARM_TIME, set_sec);
+
+ LOG_D("GET_ALARM %d:%d:%d", alarm->tm_hour, alarm->tm_min, alarm->tm_sec);
+ }
+
+ rtc_alarm_enable(alarm->enable);
+
+ return RT_EOK;
+}
+
static const struct rt_rtc_ops _rtc_ops =
{
_rtc_init,
_rtc_get_secs,
_rtc_set_secs,
+#ifdef RT_USING_ALARM
+ _rtc_get_alarm,
+ _rtc_set_alarm,
+#else
RT_NULL,
RT_NULL,
+#endif
_rtc_get_timeval,
RT_NULL,
};
@@ -320,6 +394,12 @@ static int rt_hw_rtc_init(void)
LOG_E("rtc register err code: %d", result);
return result;
}
+
+#ifdef RT_USING_ALARM
+ rt_hw_interrupt_install(RTC_ALARM_IRQ_NUM, rt_hw_rtc_isr, RT_NULL, "rtc");
+ rt_hw_interrupt_umask(RTC_ALARM_IRQ_NUM);
+#endif
+
LOG_D("rtc init success");
return RT_EOK;