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