Rev 2374 | Details | Compare with Previous | Last modification | View Log
Rev | Author | Line No. | Line |
---|---|---|---|
1393 | Kulich | 1 | #include <stdio.h> |
2 | #include <string.h> |
||
3 | #include <oscalls.h> |
||
4 | #include <socket.h> |
||
5 | #include <intrz80.h> |
||
2068 | kulich | 6 | #include <osfs.h> |
7 | #include <stdlib.h> |
||
2368 | kulich | 8 | /////// |
2361 | kulich | 9 | #define true 1 |
10 | #define false 0 |
||
11 | |||
2068 | kulich | 12 | unsigned int RBR_THR = 0xf8ef; |
13 | unsigned int IER = 0xf9ef; |
||
14 | unsigned int IIR_FCR = 0xfaef; |
||
15 | unsigned int LCR = 0xfbef; |
||
16 | unsigned int MCR = 0xfcef; |
||
17 | unsigned int LSR = 0xfdef; |
||
18 | unsigned int MSR = 0xfeef; |
||
19 | unsigned int SR = 0xffef; |
||
2366 | kulich | 20 | unsigned int divider = 1; |
21 | unsigned int comType = 0; |
||
2068 | kulich | 22 | unsigned int espType = 32; |
2364 | kulich | 23 | unsigned int espRetry = 5; |
2378 | kulich | 24 | unsigned int magic = 16; |
2364 | kulich | 25 | unsigned long factor, timerok; |
2068 | kulich | 26 | const unsigned char sendOk[] = "SEND OK"; |
27 | const unsigned char gotWiFi[] = "WIFI GOT IP"; |
||
2078 | kulich | 28 | const unsigned char timeUpdated[] = "+CIPSNTPTIME:"; |
1668 | kulich | 29 | int GMT = 3; |
2068 | kulich | 30 | unsigned char is_atm; |
2374 | kulich | 31 | unsigned char netbuf[4096]; |
32 | unsigned char cmd[512]; |
||
33 | //unsigned char dump[128]; |
||
2068 | kulich | 34 | struct sockaddr_in ntp_ia; |
1668 | kulich | 35 | union |
36 | { |
||
37 | unsigned long ul; |
||
38 | unsigned char b[4]; |
||
39 | } secsUnix; |
||
1393 | Kulich | 40 | unsigned int hour, minute, second, day, month, year, weekday; |
1668 | kulich | 41 | SOCKET s = 0; |
2068 | kulich | 42 | unsigned char inet = 0, espInet = 0; |
1668 | kulich | 43 | const unsigned char monthDays[12] = |
44 | {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; |
||
1393 | Kulich | 45 | const unsigned char ntpnead[48] = |
1668 | kulich | 46 | { |
47 | 0xdb, |
||
48 | 0x00, |
||
49 | 0x11, |
||
50 | 0xfa, |
||
51 | 0x00, |
||
52 | 0x00, |
||
53 | 0x00, |
||
54 | 0x00, |
||
55 | 0x00, |
||
56 | 0x01, |
||
57 | 0x03, |
||
58 | 0xfe, |
||
59 | }; |
||
60 | unsigned char *defntp = "2.ru.pool.ntp.org"; |
||
61 | const unsigned char regaddr_ve[16] = {0x10, 0, 0x50, 0, 0x90, 0, 0, 0x12, 0x52, 0x92, 0, 0, 0, 0, 0, 0}; |
||
1394 | Kulich | 62 | |
1393 | Kulich | 63 | const unsigned char help[] = "\ |
64 | -H help\r\n\ |
||
65 | -T set time(-T17:59:38)\r\n\ |
||
66 | -D set date(-D21-06-2019)\r\n\ |
||
67 | -N ntp-server default: -N2.ru.pool.ntp.org\r\n\ |
||
68 | -Z time-zone default: -Z3\r\n\ |
||
2068 | kulich | 69 | -i get datetime from internet\r\n\ |
70 | -e get datetime from ESP-COM"; |
||
1393 | Kulich | 71 | |
2068 | kulich | 72 | extern void |
73 | dns_resolve(void); |
||
1393 | Kulich | 74 | |
2205 | kulich | 75 | void clearStatus(void) |
76 | { |
||
77 | } |
||
78 | |||
79 | void delay(unsigned long counter) |
||
80 | { |
||
2361 | kulich | 81 | unsigned long finish; |
2205 | kulich | 82 | counter = counter / 20; |
83 | if (counter < 1) |
||
84 | { |
||
85 | counter = 1; |
||
86 | } |
||
2361 | kulich | 87 | finish = time() + counter; |
2205 | kulich | 88 | |
2361 | kulich | 89 | while (time() < finish) |
2205 | kulich | 90 | { |
91 | } |
||
92 | } |
||
93 | |||
1668 | kulich | 94 | void exit(int e) |
95 | { |
||
96 | if (s) |
||
97 | closesocket(s, 0); |
||
98 | if (e != 0) |
||
99 | { |
||
100 | puts((char *)e); |
||
1393 | Kulich | 101 | } |
1668 | kulich | 102 | ((void (*)(int))0x0000)(e); |
1393 | Kulich | 103 | } |
104 | |||
105 | extern void dns_resolve(void); |
||
1394 | Kulich | 106 | |
1668 | kulich | 107 | unsigned char readcmos(unsigned char r) |
108 | { |
||
109 | disable_interrupt(); |
||
110 | if (is_atm == 2 || is_atm == 3) |
||
111 | { |
||
112 | r = regaddr_ve[r]; |
||
113 | if (r != 0) |
||
114 | { |
||
115 | input(0x55FE); |
||
116 | r = input((r << 8) | 0x00fe); |
||
117 | } |
||
118 | } |
||
119 | else |
||
120 | { |
||
121 | output(0xdef7, r); |
||
122 | r = input(0xbef7); |
||
123 | } |
||
124 | enable_interrupt(); |
||
125 | return r; |
||
1394 | Kulich | 126 | } |
127 | |||
1668 | kulich | 128 | void writecmos(unsigned char r, unsigned char v) |
129 | { |
||
130 | disable_interrupt(); |
||
131 | if (is_atm == 2 || is_atm == 3) |
||
132 | { |
||
133 | r = regaddr_ve[r] + 1; // + 1 |
||
134 | if (r != 0) |
||
135 | { |
||
136 | input(0x55FE); |
||
137 | input((r << 8) | 0x00fe); |
||
138 | input((v << 8) | 0x00fe); |
||
1394 | Kulich | 139 | } |
1668 | kulich | 140 | } |
141 | else |
||
142 | { |
||
143 | output(0xdef7, r); |
||
144 | output(0xbef7, v); |
||
145 | } |
||
146 | enable_interrupt(); |
||
1394 | Kulich | 147 | } |
148 | |||
1393 | Kulich | 149 | void Unix_to_GMT(void) |
150 | { |
||
1668 | kulich | 151 | unsigned char monthLength = 0; |
152 | // ४ ᮢ ᨭ |
||
153 | int days = 0; |
||
154 | secsUnix.ul = secsUnix.ul + GMT * 3600; |
||
1393 | Kulich | 155 | |
1668 | kulich | 156 | second = secsUnix.ul % 60; |
157 | secsUnix.ul /= 60; // now it is minutes |
||
158 | minute = secsUnix.ul % 60; |
||
159 | secsUnix.ul /= 60; // now it is hours |
||
160 | hour = secsUnix.ul % 24; |
||
161 | secsUnix.ul /= 24; // now it is days |
||
162 | weekday = (secsUnix.ul + 4) % 7; // day week, 0-sunday |
||
163 | year = 70; |
||
164 | while (days + ((year % 4) ? 365 : 366) <= secsUnix.ul) |
||
165 | { |
||
166 | days += (year % 4) ? 365 : 366; |
||
167 | year++; |
||
168 | } |
||
169 | secsUnix.ul -= days; // now it is days in this year, starting at 0 |
||
170 | |||
171 | days = 0; |
||
172 | month = 0; |
||
173 | for (month = 0; month < 12; month++) |
||
174 | { |
||
175 | if (month == 1) |
||
176 | { // february |
||
177 | if (year % 4) |
||
178 | monthLength = 28; |
||
179 | else |
||
180 | monthLength = 29; |
||
181 | } |
||
182 | else |
||
183 | monthLength = monthDays[month]; |
||
184 | if (secsUnix.ul >= monthLength) |
||
185 | secsUnix.ul -= monthLength; |
||
186 | else |
||
187 | break; |
||
188 | } |
||
189 | month++; // jan is month 1 |
||
190 | day = secsUnix.ul + 1; // day of month |
||
191 | } |
||
192 | void ntp_resolver(void) |
||
193 | { |
||
194 | unsigned char i, j; |
||
1393 | Kulich | 195 | signed char res; |
196 | int len; |
||
1668 | kulich | 197 | ntp_ia.sin_port = 123 << 8; |
198 | ntp_ia.sin_addr = *dns_resolver((void *)defntp); |
||
199 | if (!ntp_ia.sin_addr.S_un.S_addr) |
||
200 | exit((int)"error: domain name not resolved"); |
||
201 | i = 200; |
||
1393 | Kulich | 202 | inetloop: |
203 | YIELD(); |
||
204 | i--; |
||
1654 | kulich | 205 | YIELD(); |
1668 | kulich | 206 | if (i == 0) |
207 | { |
||
1393 | Kulich | 208 | exit((int)"inet error"); |
209 | } |
||
1668 | kulich | 210 | s = socket(AF_INET, SOCK_DGRAM, 0); |
211 | if (s < 0) |
||
212 | { |
||
213 | s = 0; |
||
1393 | Kulich | 214 | goto inetloop; |
215 | } |
||
1668 | kulich | 216 | memcpy(netbuf, ntpnead, sizeof(ntpnead)); |
1660 | kulich | 217 | |
1668 | kulich | 218 | len = sendto(s, netbuf, 48, 0, &ntp_ia, sizeof(ntp_ia)); |
219 | if (res < 0) |
||
220 | { |
||
221 | closesocket(s, 0); |
||
222 | s = 0; |
||
1393 | Kulich | 223 | goto inetloop; |
224 | } |
||
1668 | kulich | 225 | j = 50; |
226 | while (j) |
||
227 | { |
||
1393 | Kulich | 228 | j--; |
1668 | kulich | 229 | len = recvfrom(s, netbuf, sizeof(netbuf), 0, &ntp_ia, sizeof(ntp_ia)); |
230 | if (len < 0) |
||
231 | { |
||
1393 | Kulich | 232 | YIELD(); |
1660 | kulich | 233 | YIELD(); |
1393 | Kulich | 234 | continue; |
235 | } |
||
236 | break; |
||
237 | } |
||
1668 | kulich | 238 | |
239 | closesocket(s, 0); |
||
240 | s = 0; |
||
241 | if (len <= 0) |
||
242 | { |
||
243 | exit((int)"server error"); |
||
1393 | Kulich | 244 | } |
245 | secsUnix.b[3] = netbuf[40]; |
||
246 | secsUnix.b[2] = netbuf[41]; |
||
247 | secsUnix.b[1] = netbuf[42]; |
||
248 | secsUnix.b[0] = netbuf[43]; |
||
1668 | kulich | 249 | secsUnix.ul -= 2208988800UL; |
1393 | Kulich | 250 | Unix_to_GMT(); |
251 | } |
||
252 | |||
2205 | kulich | 253 | /////////////////////////// |
254 | #include <../common/esp-com.c> |
||
255 | ////////////////////////// |
||
2374 | kulich | 256 | |
257 | int getAnswerInt(int retries) |
||
258 | { |
||
259 | unsigned char key = 0; |
||
260 | while (!getAnswer3() && retries != 0) |
||
261 | { |
||
262 | retries--; |
||
263 | printf("Retry [UART][%u]\r\n", retries); |
||
264 | |||
265 | if (retries == 0) |
||
266 | { |
||
267 | printf("\rAnswer reading timeout? press [Y]/[Enter] to retry, other key for abort. "); |
||
268 | key = getchar(); |
||
269 | switch (key) |
||
270 | { |
||
271 | case 'y': |
||
272 | case 'Y': |
||
273 | case 13: |
||
274 | retries = 1; |
||
275 | break; |
||
276 | default: |
||
277 | return false; |
||
278 | } |
||
279 | } |
||
280 | } |
||
281 | return true; |
||
282 | } |
||
283 | |||
2068 | kulich | 284 | void espntp_resolver(void) |
285 | { |
||
2361 | kulich | 286 | unsigned char retry, retryuart, count = 0; |
287 | unsigned int byte; |
||
288 | unsigned long finish; |
||
2369 | kulich | 289 | unsigned char *count1; |
2068 | kulich | 290 | loadEspConfig(); |
291 | uart_init(divider); |
||
2361 | kulich | 292 | if (!espReBoot()) |
293 | { |
||
294 | puts("\r\nerror ESP init..."); |
||
295 | exit(255); |
||
296 | } |
||
297 | puts("\r\nGetting time..."); |
||
2068 | kulich | 298 | |
2070 | kulich | 299 | // AT+CIPSNTPCFG=1,8,"cn.ntp.org.cn","ntp.sjtu.edu.cn" |
300 | weekday = 0; |
||
301 | month = 0; |
||
302 | day = 0; |
||
303 | hour = 0; |
||
304 | second = 0; |
||
305 | year = 170; |
||
2361 | kulich | 306 | retry = 10; |
307 | retryuart = 3; |
||
308 | sprintf(cmd, "AT+CIPSNTPCFG=1,%u,\"%s\",\"time.google.com\"", GMT, defntp); |
||
2068 | kulich | 309 | sendcommand(cmd); |
2374 | kulich | 310 | // getAnswer3(); // OK |
311 | getAnswerInt(3); |
||
2369 | kulich | 312 | count1 = strstr(netbuf, "ERROR"); |
313 | if (count1) |
||
314 | { |
||
315 | printf("Error. You may need to update your AT-Firmware, to a version that supports AT+CIPSNTPCFG"); |
||
316 | exit(255); |
||
317 | } |
||
318 | |||
2078 | kulich | 319 | retryTime: |
320 | count = 0; |
||
2361 | kulich | 321 | delay(300); |
322 | finish = time() + 5 * 50; |
||
2068 | kulich | 323 | sendcommand("AT+CIPSNTPTIME?"); |
2075 | kulich | 324 | do |
325 | { |
||
2361 | kulich | 326 | byte = uartReadBlock(); |
2079 | kulich | 327 | // printf("[%c]", byte); |
2075 | kulich | 328 | if (byte == timeUpdated[count]) |
329 | { |
||
330 | count++; |
||
2374 | kulich | 331 | // putchar(byte); |
2075 | kulich | 332 | } |
333 | else |
||
334 | { |
||
335 | count = 0; |
||
336 | } |
||
2361 | kulich | 337 | |
338 | if (time() > finish) |
||
339 | { |
||
340 | puts("error getting time..."); |
||
341 | exit(255); |
||
342 | } |
||
2075 | kulich | 343 | } while (count < strlen(timeUpdated)); |
2068 | kulich | 344 | |
2374 | kulich | 345 | if (!getAnswerInt(3)) // TIME |
2361 | kulich | 346 | { |
347 | if (retryuart != 0) |
||
348 | { |
||
349 | retryuart--; |
||
350 | printf("Retry [UART][%u]\r\n", retryuart); |
||
351 | delay(500); |
||
352 | goto retryTime; |
||
353 | } |
||
354 | puts("error getting time..."); |
||
355 | exit(255); |
||
356 | } |
||
357 | |||
2078 | kulich | 358 | strncpy(cmd, netbuf, 3); |
2068 | kulich | 359 | cmd[3] = 0; |
360 | |||
361 | if (cmd[0] == 'S' && cmd[1] == 'u') |
||
362 | { |
||
363 | weekday = 1; |
||
364 | } |
||
365 | else if (cmd[0] == 'M' && cmd[1] == 'o') |
||
366 | { |
||
367 | weekday = 2; |
||
368 | } |
||
369 | else if (cmd[0] == 'T' && cmd[1] == 'u') |
||
370 | { |
||
371 | weekday = 3; |
||
372 | } |
||
373 | else if (cmd[0] == 'W' && cmd[1] == 'e') |
||
374 | { |
||
375 | weekday = 4; |
||
376 | } |
||
377 | else if (cmd[0] == 'T' && cmd[1] == 'h') |
||
378 | { |
||
379 | weekday = 5; |
||
380 | } |
||
381 | else if (cmd[0] == 'F' && cmd[1] == 'r') |
||
382 | { |
||
383 | weekday = 6; |
||
384 | } |
||
385 | else if (cmd[0] == 'S' && cmd[1] == 'a') |
||
386 | { |
||
387 | weekday = 7; |
||
388 | } |
||
389 | |||
2078 | kulich | 390 | strncpy(cmd, netbuf + 4, 3); |
2068 | kulich | 391 | cmd[3] = 0; |
392 | |||
393 | if (cmd[0] == 'J' && cmd[1] == 'a') |
||
394 | { |
||
395 | month = 1; |
||
396 | } |
||
397 | else if (cmd[0] == 'F' && cmd[1] == 'e') |
||
398 | { |
||
399 | month = 2; |
||
400 | } |
||
401 | else if (cmd[0] == 'M' && cmd[2] == 'r') |
||
402 | { |
||
403 | month = 3; |
||
404 | } |
||
405 | else if (cmd[0] == 'A' && cmd[1] == 'p') |
||
406 | { |
||
407 | month = 4; |
||
408 | } |
||
409 | else if (cmd[0] == 'M' && cmd[2] == 'y') |
||
410 | { |
||
411 | month = 5; |
||
412 | } |
||
413 | else if (cmd[0] == 'J' && cmd[2] == 'n') |
||
414 | { |
||
415 | month = 6; |
||
416 | } |
||
417 | else if (cmd[0] == 'J' && cmd[2] == 'l') |
||
418 | { |
||
419 | month = 7; |
||
420 | } |
||
421 | else if (cmd[0] == 'A' && cmd[1] == 'u') |
||
422 | { |
||
423 | month = 8; |
||
424 | } |
||
425 | else if (cmd[0] == 'S' && cmd[1] == 'e') |
||
426 | { |
||
427 | month = 9; |
||
428 | } |
||
429 | else if (cmd[0] == 'O' && cmd[1] == 'c') |
||
430 | { |
||
431 | month = 10; |
||
432 | } |
||
433 | else if (cmd[0] == 'N' && cmd[1] == 'o') |
||
434 | { |
||
435 | month = 11; |
||
436 | } |
||
437 | else if (cmd[0] == 'D' && cmd[1] == 'e') |
||
438 | { |
||
439 | month = 12; |
||
440 | } |
||
441 | |||
2078 | kulich | 442 | strncpy(cmd, netbuf + 8, 2); |
2068 | kulich | 443 | cmd[2] = 0; |
444 | day = atoi(cmd); |
||
445 | |||
2078 | kulich | 446 | strncpy(cmd, netbuf + 11, 2); |
2068 | kulich | 447 | hour = atoi(cmd); |
448 | |||
2078 | kulich | 449 | strncpy(cmd, netbuf + 14, 2); |
2068 | kulich | 450 | minute = atoi(cmd); |
451 | |||
2078 | kulich | 452 | strncpy(cmd, netbuf + 17, 2); |
2068 | kulich | 453 | second = atoi(cmd); |
454 | |||
2078 | kulich | 455 | strncpy(cmd, netbuf + 22, 2); |
2068 | kulich | 456 | cmd[4] = 0; |
457 | year = atoi(cmd) + 100; |
||
2070 | kulich | 458 | |
2361 | kulich | 459 | getAnswer3(); // OK |
2075 | kulich | 460 | |
2079 | kulich | 461 | // printf("day of week:%u Month:%u day:%u hours:%u minutes:%u seconds:%u year:%u\r\n", weekday, month, day, hour, minute, second, year); |
2075 | kulich | 462 | |
2070 | kulich | 463 | if (year == 170) |
2068 | kulich | 464 | { |
2070 | kulich | 465 | YIELD(); |
466 | if (retry != 0) |
||
467 | { |
||
468 | retry--; |
||
2361 | kulich | 469 | printf("Retry [NTP][%u]\r\n", retry); |
2205 | kulich | 470 | delay(500); |
2070 | kulich | 471 | goto retryTime; |
472 | } |
||
473 | puts("error getting time..."); |
||
474 | exit(255); |
||
2068 | kulich | 475 | } |
476 | } |
||
477 | |||
1668 | kulich | 478 | void set_datetime(void) |
479 | { |
||
480 | writecmos(0x0b, readcmos(0x0b) | 6); |
||
481 | writecmos(0x07, day); |
||
482 | writecmos(0x08, month); |
||
483 | if (is_atm == 2 || is_atm == 3) |
||
484 | { |
||
485 | writecmos(0x09, year - 80); |
||
486 | } |
||
487 | else |
||
488 | { |
||
489 | writecmos(0x09, year - 100); |
||
490 | } |
||
1393 | Kulich | 491 | |
1668 | kulich | 492 | writecmos(0x00, second); |
493 | writecmos(0x02, minute); |
||
494 | writecmos(0x04, hour); |
||
1393 | Kulich | 495 | } |
496 | void get_datetime(void) |
||
497 | { |
||
1668 | kulich | 498 | writecmos(0x0b, readcmos(0x0b) | 6); |
499 | second = readcmos(0x00); |
||
500 | minute = readcmos(0x02); |
||
501 | hour = readcmos(0x04); |
||
502 | weekday = readcmos(0x06) - 1; |
||
503 | day = readcmos(0x07); |
||
504 | month = readcmos(0x08); |
||
505 | if (is_atm == 2 || is_atm == 3) |
||
506 | { |
||
2068 | kulich | 507 | year = readcmos(0x09) + 80; |
1668 | kulich | 508 | } |
2068 | kulich | 509 | else |
510 | { |
||
511 | year = readcmos(0x09) + 100; |
||
512 | } |
||
1393 | Kulich | 513 | } |
514 | |||
1668 | kulich | 515 | C_task main(int argc, char *argv[]) |
1393 | Kulich | 516 | { |
1668 | kulich | 517 | unsigned char i = 1; |
1393 | Kulich | 518 | os_initstdio(); |
2374 | kulich | 519 | printf("[TIME2 Build:%s %s]\r\n", __DATE__, __TIME__); |
1393 | Kulich | 520 | is_atm = (unsigned char)OS_GETCONFIG(); |
521 | |||
1668 | kulich | 522 | if (argc == 1) |
523 | { |
||
1393 | Kulich | 524 | get_datetime(); |
525 | puts(help); |
||
526 | } |
||
1668 | kulich | 527 | while (i != argc) |
528 | { |
||
529 | char *p = argv[i]; |
||
530 | if (p[0] != '-') |
||
531 | exit((int)"Wrong parameter. Use -H for help"); |
||
532 | switch (p[1] & 0xdf) |
||
533 | { |
||
534 | case 'T': |
||
535 | get_datetime(); |
||
536 | if (sscanf(p + 2, "%d:%d:%d", &hour, &minute, &second) == 3) |
||
537 | { |
||
538 | disable_interrupt(); |
||
539 | set_datetime(); |
||
540 | enable_interrupt(); |
||
541 | } |
||
542 | break; |
||
543 | case 'D': |
||
544 | get_datetime(); |
||
545 | if (sscanf(p + 2, "%d-%d-%d", &day, &month, &year) == 3) |
||
546 | { |
||
547 | disable_interrupt(); |
||
548 | year -= 1900; |
||
549 | set_datetime(); |
||
550 | enable_interrupt(); |
||
551 | } |
||
552 | break; |
||
553 | case 'N': |
||
554 | defntp = p + 2; |
||
555 | break; |
||
556 | case 'Z': |
||
2369 | kulich | 557 | if (sscanf(p + 2, "%d", &GMT) != 1) |
1668 | kulich | 558 | { |
559 | GMT = 3; |
||
560 | } |
||
561 | break; |
||
562 | case 'H': |
||
563 | exit((int)help); |
||
564 | break; |
||
565 | case 'I': |
||
566 | inet = 1; |
||
567 | break; |
||
2068 | kulich | 568 | case 'E': |
569 | espInet = 1; |
||
570 | break; |
||
571 | |||
1668 | kulich | 572 | default: |
573 | exit((int)"Wrong parameter. Use -H for help"); |
||
1393 | Kulich | 574 | } |
575 | i++; |
||
576 | } |
||
1668 | kulich | 577 | if (inet) |
578 | { |
||
1393 | Kulich | 579 | ntp_resolver(); |
580 | set_datetime(); |
||
1668 | kulich | 581 | writecmos(0x06, weekday + 1); |
1393 | Kulich | 582 | } |
2068 | kulich | 583 | if (espInet) |
584 | { |
||
585 | espntp_resolver(); |
||
586 | set_datetime(); |
||
587 | writecmos(0x06, weekday + 1); |
||
2366 | kulich | 588 | uartFlush(500); |
2068 | kulich | 589 | } |
1393 | Kulich | 590 | puts("Now time:"); |
1668 | kulich | 591 | printf("%02u-%02u-%04u ", day, month, year + 1900); |
592 | printf("%02u:%02u:%02u\r\n", hour, minute, second); |
||
1393 | Kulich | 593 | exit(0); |
594 | return 0; |
||
1668 | kulich | 595 | } |