1 /*
2 * Copyright (c) 2022-2024, Xiaohua Semiconductor Co., Ltd.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2024-12-30 CDT first version
9 */
10
11 /*
12 * 程序清单:这是 RTC 设备使用例程和 Alarm 使用示例。
13 * 例程导出了 rtc_sample 命令到控制终端。
14 * 命令调用格式:rtc_sample x
15 * 命令解释:命令第二个参数是要使用的功能对应的编号,
16 * RTC 基本功能对应的编号为 0~3,Alarm 功能对应的编号为 4~9
17 */
18
19 #include <rtthread.h>
20 #include <rtdevice.h>
21 #include <board.h>
22 #include "rtconfig.h"
23 #include "rtdef.h"
24 // #include "alarm.h"
25
26 #if defined(BSP_USING_RTC)
27
28 /* macros define */
29 #define SAMPLE_RTC_NAME "rtc"
30
31 /* variables define */
32 static rt_device_t rtc_dev;
33 #if defined(RT_USING_ALARM)
34 extern void rt_alarm_dump(void);
35
36 static rt_uint16_t callback_counter, alarm_idx = 0;
37 static struct rt_alarm *ptr_alarm = RT_NULL;
38 static struct rt_alarm_setup alarm_setup;
39 #endif /* RT_USING_ALARM */
40
41 /* command type */
42 enum RTC_CMD
43 {
44 CMD_OPEN_RTC = 0x00,
45 CMD_SET_TIME = 0x01,
46 CMD_SET_DATE = 0x02,
47 CMD_GET_DATE_TIME,
48 #if defined(RT_USING_ALARM)
49 CMD_SET_ALARM,
50 CMD_SET_START_ALARM,
51 CMD_STOP_ALARM,
52 CMD_CTRL_ALARM,
53 CMD_DUMP_ALARM,
54 CMD_DEL_ALARM,
55 };
56
alarm_callback_fun(rt_alarm_t alarm,time_t timestamp)57 void alarm_callback_fun(rt_alarm_t alarm, time_t timestamp)
58 {
59 rt_kprintf("\nuser alarm %d callback function.\n", alarm_idx);
60 if ((0 == (--callback_counter)) && (alarm_idx))
61 {
62 rt_kprintf("stop alarm %d \n", alarm_idx);
63 if (RT_EOK != rt_alarm_stop(alarm))
64 {
65 rt_kprintf("failed to stop alarm\n");
66 }
67 /* enter callback 2 times */
68 callback_counter = 2;
69 --alarm_idx;
70 }
71 }
72 #else
73 };
74 #endif /* RT_USING_ALARM */
75
rtc_sample(int argc,char * argv[])76 static int rtc_sample(int argc, char *argv[])
77 {
78 rt_uint8_t idx;
79 rt_uint16_t temp1, temp2, temp3;
80 time_t now;
81 #if defined(RT_USING_ALARM)
82 struct tm p_tm;
83 #endif
84
85 if (argc < 2)
86 {
87 rt_kprintf("unkown rtc command, rtc [usage] as the following: \n");
88 rt_kprintf("\'0\': find and open rtc \n");
89 rt_kprintf("\'1 xx:xx:xx\': set time with \n");
90 rt_kprintf("\'2 xxxx-xx-xx\': set date with \n");
91 rt_kprintf("\'3\': get time and date \n");
92 #if defined(RT_USING_ALARM)
93 rt_kprintf("\'4\': set current time + 10s as alarm \n");
94 rt_kprintf("\'5\': start alarm \n");
95 rt_kprintf("\'6\': stop alarm \n");
96 rt_kprintf("cmd-7 based on cmd-4\n");
97 rt_kprintf("\'7\' o: oneshot,\n\'7\' s: second,\n\'7\' m: minute \n");
98 rt_kprintf("\'8\': dump all alarm \n");
99 rt_kprintf("\'9\': delete all alarm \n");
100 #endif /* RT_USING_ALARM */
101 return -RT_ERROR;
102 }
103
104 idx = *(argv[1]) - '0';
105 switch (idx)
106 {
107 case CMD_OPEN_RTC:
108 /* find and open device with standard interface */
109 rtc_dev = rt_device_find(SAMPLE_RTC_NAME);
110 if (!rtc_dev)
111 {
112 rt_kprintf("find %s failed\n", SAMPLE_RTC_NAME);
113 return -RT_ERROR;
114 }
115 if (RT_EOK != rt_device_open(rtc_dev, RT_NULL))
116 {
117 rt_kprintf("failed to open %s\n", SAMPLE_RTC_NAME);
118 return -RT_ERROR;
119 }
120 rt_kprintf("rtc opened\n");
121 break;
122 case CMD_SET_TIME:
123 /* set time with xx:xx:xx format characters */
124 if (argc < 3)
125 {
126 rt_kprintf("unsurpported command\n");
127 return -RT_ERROR;
128 }
129 temp1 = ((argv[2][0] - '0') * 10) + \
130 (argv[2][1] - '0');
131 temp2 = ((argv[2][3] - '0') * 10) + \
132 (argv[2][4] - '0');
133 temp3 = ((argv[2][6] - '0') * 10) + \
134 (argv[2][7] - '0');
135 if (RT_EOK != set_time(temp1, temp2, temp3))
136 {
137 rt_kprintf("set RTC time failed\n");
138 return -RT_ERROR;
139 }
140 rt_kprintf("\nset RTC time as %2d:%2d:%2d\n", temp1, temp2, temp3);
141 break;
142 case CMD_SET_DATE:
143 /* set data xxxx-xx-xx format characters */
144 temp1 = ((argv[2][0] - '0') * 1000) + \
145 ((argv[2][1] - '0') * 100) + \
146 ((argv[2][2] - '0') * 10) + \
147 (argv[2][3] - '0');
148 temp2 = ((argv[2][5] - '0') * 10) + \
149 (argv[2][6] - '0');
150 temp3 = ((argv[2][8] - '0') * 10) + \
151 (argv[2][9] - '0');
152 if (RT_EOK != set_date(temp1, temp2, temp3))
153 {
154 rt_kprintf("failed to set date for %s\n", SAMPLE_RTC_NAME);
155 return -RT_ERROR;
156 }
157 rt_kprintf("\nset RTC date as %4d-%2d-%2d\n", temp1, temp2, temp3);
158 break;
159 case CMD_GET_DATE_TIME:
160 /* get current time and print it */
161 now = time(NULL);
162 rt_kprintf("GMT time is: %s\n", ctime(&now));
163 break;
164 #if defined(RT_USING_ALARM)
165 case CMD_SET_ALARM:
166 /* get current time (uint: second) from 1970-01-01 */
167 now = time(NULL);
168 rt_kprintf("GMT time is: \n%s\n", ctime(&now));
169 now += 60;
170 gmtime_r(&now, &p_tm);
171 // localtime_r(&now, &p_tm);
172 alarm_setup.flag = RT_ALARM_MINUTE;
173 alarm_setup.wktime.tm_year = p_tm.tm_year;
174 alarm_setup.wktime.tm_mon = p_tm.tm_mon;
175 alarm_setup.wktime.tm_mday = p_tm.tm_mday;
176 alarm_setup.wktime.tm_yday = p_tm.tm_yday;
177 alarm_setup.wktime.tm_wday = p_tm.tm_wday;
178 alarm_setup.wktime.tm_hour = p_tm.tm_hour;
179 alarm_setup.wktime.tm_min = p_tm.tm_min;
180 alarm_setup.wktime.tm_sec = p_tm.tm_sec;
181 alarm_setup.wktime.tm_isdst = -1;
182 rt_kprintf("UTC alarm Time: \n%d-%02d-%02d %02d:%02d:%02d\n\n",
183 p_tm.tm_year + 1900,
184 p_tm.tm_mon + 1,
185 p_tm.tm_mday,
186 p_tm.tm_hour,
187 p_tm.tm_min,
188 p_tm.tm_sec);
189 ptr_alarm = rt_alarm_create(alarm_callback_fun, &alarm_setup);
190 if (RT_NULL == ptr_alarm)
191 {
192 rt_kprintf("failed to create rtc alarm\n");
193 return -RT_ERROR;
194 }
195 callback_counter = 2;
196 ++alarm_idx;
197 rt_alarm_dump();
198 break;
199 case CMD_SET_START_ALARM:
200 if (RT_EOK != rt_alarm_start(ptr_alarm))
201 {
202 rt_kprintf("failed to start rtc alarm\n");
203 return -RT_ERROR;
204 }
205 rt_kprintf("rtc alarm started\n");
206 break;
207 case CMD_STOP_ALARM:
208 if (RT_EOK != rt_alarm_stop(ptr_alarm))
209 {
210 rt_kprintf("failed to stop rtc alarm\n");
211 return -RT_ERROR;
212 }
213 rt_kprintf("rtc alarm stopped\n");
214 break;
215 case CMD_CTRL_ALARM:
216 if (argc < 3)
217 {
218 rt_kprintf("unkown para to control rtc alarm\n");
219 return -RT_ERROR;
220 }
221 switch (argv[2][0])
222 {
223 case 's':
224 alarm_setup.flag = RT_ALARM_SECOND;
225 break;
226 case 'm':
227 alarm_setup.flag = RT_ALARM_MINUTE;
228 break;
229 case 'o':
230 default:
231 alarm_setup.flag = RT_ALARM_ONESHOT;
232 break;
233 }
234 if (RT_EOK != rt_alarm_control(ptr_alarm, RT_ALARM_CTRL_MODIFY, &alarm_setup))
235 {
236 rt_kprintf("failed to control rtc alarm\n");
237 }
238 rt_alarm_dump();
239 break;
240 case CMD_DUMP_ALARM:
241 rt_alarm_dump();
242 break;
243 case CMD_DEL_ALARM:
244 if (RT_EOK != rt_alarm_delete(ptr_alarm))
245 {
246 rt_kprintf("failed to delete alarm\n");
247 }
248 alarm_idx = 0;
249 rt_kprintf("alarm deleted\n");
250 break;
251 #endif /* RT_USING_ALARM */
252 default:
253 if (RT_EOK != rt_device_close(rtc_dev))
254 {
255 rt_kprintf("failed to close RTC\n");
256 return -RT_ERROR;
257 }
258 rt_kprintf("unkown rtc command, rtc closed \n");
259 break;
260 }
261 /* fetch and print current time and date each second until next year */
262 return RT_EOK;
263 }
264
265 MSH_CMD_EXPORT(rtc_sample, rtc option);
266
267 #endif /* BSP_USING_RTC */
268
269 /*
270 EOF
271 */
272