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