1 /*
2  * Copyright (c) 2006-2024, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2024-02-06     Yilin Sun    Initial version.
9  */
10 
11 #include <rtthread.h>
12 #include <rtdevice.h>
13 #include <sys/time.h>
14 #include "drv_rtc.h"
15 #include "fsl_common.h"
16 #include "fsl_irtc.h"
17 
18 #ifdef RT_USING_RTC
19 
mcx_rtc_init(rt_device_t dev)20 static rt_err_t mcx_rtc_init(rt_device_t dev)
21 {
22     irtc_config_t rtc_cfg;
23 
24     IRTC_GetDefaultConfig(&rtc_cfg);
25 
26     //rtc_cfg.clockSelect = kIRTC_Clk32K;
27 
28     if (IRTC_Init(RTC0, &rtc_cfg) != kStatus_Success)
29     {
30         return -RT_EIO;
31     }
32 
33     return RT_EOK;
34 }
35 
mcx_rtc_get_time(time_t * ts)36 static rt_err_t mcx_rtc_get_time(time_t *ts)
37 {
38     struct tm tm_new = {0};
39 
40     irtc_datetime_t rtc_date;
41 
42     IRTC_GetDatetime(RTC0, &rtc_date);
43 
44     tm_new.tm_sec = rtc_date.second;
45     tm_new.tm_min = rtc_date.minute;
46     tm_new.tm_hour = rtc_date.hour;
47 
48     tm_new.tm_mday = rtc_date.day;
49     tm_new.tm_mon = rtc_date.month - 1;
50     tm_new.tm_year = rtc_date.year - 1900;
51 
52     *ts = timegm(&tm_new);
53 
54     return RT_EOK;
55 }
56 
mcx_rtc_set_time(time_t * ts)57 static rt_err_t mcx_rtc_set_time(time_t *ts)
58 {
59     struct tm now;
60     irtc_datetime_t rtc_date;
61 
62     gmtime_r(ts, &now);
63 
64     rtc_date.second = now.tm_sec ;
65     rtc_date.minute = now.tm_min ;
66     rtc_date.hour   = now.tm_hour;
67 
68     rtc_date.weekDay = now.tm_wday;
69     rtc_date.day     = now.tm_mday;
70     rtc_date.month   = now.tm_mon  + 1;
71     rtc_date.year    = now.tm_year + 1900;
72 
73     IRTC_SetWriteProtection(RTC0, false);
74     IRTC_SetDatetime(RTC0, &rtc_date);
75 
76     return RT_EOK;
77 }
78 
mcx_rtc_control(rt_device_t dev,int cmd,void * args)79 static rt_err_t mcx_rtc_control(rt_device_t dev, int cmd, void *args)
80 {
81     switch (cmd)
82     {
83     case RT_DEVICE_CTRL_RTC_GET_TIME:
84         mcx_rtc_get_time((time_t *)args);
85         break;
86 
87     case RT_DEVICE_CTRL_RTC_SET_TIME:
88         mcx_rtc_set_time((time_t *)args);
89         break;
90 
91     case RT_DEVICE_CTRL_RTC_SET_ALARM:
92     /* TODO: Implement alarm features */
93     default:
94         return -RT_EINVAL;
95     }
96 
97     return RT_EOK;
98 }
99 
100 static struct rt_device device =
101 {
102     .type    = RT_Device_Class_RTC,
103     .init    = mcx_rtc_init,
104     .open    = RT_NULL,
105     .close   = RT_NULL,
106     .read    = RT_NULL,
107     .write   = RT_NULL,
108     .control = mcx_rtc_control,
109 };
110 
rt_hw_rtc_init(void)111 int rt_hw_rtc_init(void)
112 {
113     rt_err_t ret = RT_EOK;
114 
115     ret = rt_device_register(&device, "rtc", RT_DEVICE_FLAG_RDWR);
116     if (ret != RT_EOK)
117     {
118         return ret;
119     }
120 
121     return RT_EOK;
122 }
123 
124 INIT_DEVICE_EXPORT(rt_hw_rtc_init);
125 
126 #endif /*RT_USING_RTC */
127