![](/media/cache/profiles/1f50893f80d6830d62765ffad7721742.50x50_q85.jpg)
A general demonstration color etch-a-sketch program using the QVGA TFT with HX8347D controller, Orange Board. Saves touchscreen calibaration data saved in tft.ini. Creates /local/tft.ini if missing. Also included is an Ethernet NTP client to update the RTC. Assumes all other Orange Board devices attached: Text LCD, SDHC Flash, Ethernet.
Dependencies: EthernetNetIf TextLCD mbed
TinySTNP/TinySNTP.cpp@0:e065ca40f28a, 2011-08-01 (annotated)
- Committer:
- loopsva
- Date:
- Mon Aug 01 16:29:58 2011 +0000
- Revision:
- 0:e065ca40f28a
Inititial Release
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
loopsva | 0:e065ca40f28a | 1 | /* |
loopsva | 0:e065ca40f28a | 2 | * mbed Tiny SNTP(NTP) Client |
loopsva | 0:e065ca40f28a | 3 | * Copyright (c) 2011 Hiroshi Suga |
loopsva | 0:e065ca40f28a | 4 | * Released under the MIT License: http://mbed.org/license/mit |
loopsva | 0:e065ca40f28a | 5 | */ |
loopsva | 0:e065ca40f28a | 6 | |
loopsva | 0:e065ca40f28a | 7 | /** @file |
loopsva | 0:e065ca40f28a | 8 | * @brief Tiny DNS Resolver |
loopsva | 0:e065ca40f28a | 9 | */ |
loopsva | 0:e065ca40f28a | 10 | |
loopsva | 0:e065ca40f28a | 11 | #include "mbed.h" |
loopsva | 0:e065ca40f28a | 12 | #include "EthernetNetIf.h" |
loopsva | 0:e065ca40f28a | 13 | #include "UDPSocket.h" |
loopsva | 0:e065ca40f28a | 14 | #include "DNSRequest.h" |
loopsva | 0:e065ca40f28a | 15 | #include "TinySNTP.h" |
loopsva | 0:e065ca40f28a | 16 | |
loopsva | 0:e065ca40f28a | 17 | // host to network short |
loopsva | 0:e065ca40f28a | 18 | #define htons( x ) ( (( (x) << 8 ) & 0xFF00) | (( (x) >> 8 ) & 0x00FF) ) |
loopsva | 0:e065ca40f28a | 19 | #define ntohs( x ) htons(x) |
loopsva | 0:e065ca40f28a | 20 | // host to network long |
loopsva | 0:e065ca40f28a | 21 | #define htonl( x ) ( (( (x) << 24 ) & 0xFF000000) \ |
loopsva | 0:e065ca40f28a | 22 | | (( (x) << 8 ) & 0x00FF0000) \ |
loopsva | 0:e065ca40f28a | 23 | | (( (x) >> 8 ) & 0x0000FF00) \ |
loopsva | 0:e065ca40f28a | 24 | | (( (x) >> 24 ) & 0x000000FF) ) |
loopsva | 0:e065ca40f28a | 25 | #define ntohl( x ) htonl(x) |
loopsva | 0:e065ca40f28a | 26 | |
loopsva | 0:e065ca40f28a | 27 | static UDPSocket *sntp; |
loopsva | 0:e065ca40f28a | 28 | static volatile unsigned long sntptime; |
loopsva | 0:e065ca40f28a | 29 | static volatile int dns_status; |
loopsva | 0:e065ca40f28a | 30 | extern EthernetNetIf eth; |
loopsva | 0:e065ca40f28a | 31 | |
loopsva | 0:e065ca40f28a | 32 | int createSntpRequest (char *buf) { |
loopsva | 0:e065ca40f28a | 33 | struct SNTPPacket *sntp; |
loopsva | 0:e065ca40f28a | 34 | |
loopsva | 0:e065ca40f28a | 35 | sntp = (struct SNTPPacket *)buf; |
loopsva | 0:e065ca40f28a | 36 | memset(sntp, 0, sizeof(struct SNTPPacket)); |
loopsva | 0:e065ca40f28a | 37 | sntp->info = 0x1b; // Ver.3, client |
loopsva | 0:e065ca40f28a | 38 | sntp->txTm_s = htonl(NTP_TIMESTAMP_DELTA + time(NULL)); |
loopsva | 0:e065ca40f28a | 39 | |
loopsva | 0:e065ca40f28a | 40 | return sizeof(struct SNTPPacket); |
loopsva | 0:e065ca40f28a | 41 | } |
loopsva | 0:e065ca40f28a | 42 | |
loopsva | 0:e065ca40f28a | 43 | int getSntpResponse (const char *buf, uint32_t *tim) { |
loopsva | 0:e065ca40f28a | 44 | struct SNTPPacket *sntp; |
loopsva | 0:e065ca40f28a | 45 | uint32_t now; |
loopsva | 0:e065ca40f28a | 46 | // long int delay, offset; |
loopsva | 0:e065ca40f28a | 47 | |
loopsva | 0:e065ca40f28a | 48 | sntp = (struct SNTPPacket *)buf; |
loopsva | 0:e065ca40f28a | 49 | if ((sntp->info & 0x3f) == 0x1c || (sntp->info & 0x3f) == 0x24) { |
loopsva | 0:e065ca40f28a | 50 | // Ver.3or4, Server |
loopsva | 0:e065ca40f28a | 51 | |
loopsva | 0:e065ca40f28a | 52 | now = htonl(NTP_TIMESTAMP_DELTA + time(NULL)); |
loopsva | 0:e065ca40f28a | 53 | /* |
loopsva | 0:e065ca40f28a | 54 | delay = (now - sntp->origTm_s) - (sntp->rxTm_s - sntp->txTm_s); |
loopsva | 0:e065ca40f28a | 55 | offset = ((sntp->rxTm_s - sntp->origTm_s) + (sntp->txTm_s - now)); |
loopsva | 0:e065ca40f28a | 56 | |
loopsva | 0:e065ca40f28a | 57 | *tim = ntohl(sntp->txTm_s) - NTP_TIMESTAMP_DELTA + (delay / 2); |
loopsva | 0:e065ca40f28a | 58 | */ |
loopsva | 0:e065ca40f28a | 59 | *tim = ntohl(sntp->txTm_s) - NTP_TIMESTAMP_DELTA; |
loopsva | 0:e065ca40f28a | 60 | #ifdef DEBUG |
loopsva | 0:e065ca40f28a | 61 | printf("now %08x\r\n", ntohl(now)); |
loopsva | 0:e065ca40f28a | 62 | printf("ref %08x\r\n", ntohl(sntp->refTm_s)); |
loopsva | 0:e065ca40f28a | 63 | printf("orig %08x\r\n", ntohl(sntp->origTm_s)); |
loopsva | 0:e065ca40f28a | 64 | printf("rx %08x\r\n", ntohl(sntp->rxTm_s)); |
loopsva | 0:e065ca40f28a | 65 | printf("tx %08x\r\n", ntohl(sntp->txTm_s)); |
loopsva | 0:e065ca40f28a | 66 | // printf("delay %d / offset %d\r\n", delay, offset); |
loopsva | 0:e065ca40f28a | 67 | #endif |
loopsva | 0:e065ca40f28a | 68 | return 0; |
loopsva | 0:e065ca40f28a | 69 | } |
loopsva | 0:e065ca40f28a | 70 | |
loopsva | 0:e065ca40f28a | 71 | return -1; |
loopsva | 0:e065ca40f28a | 72 | } |
loopsva | 0:e065ca40f28a | 73 | |
loopsva | 0:e065ca40f28a | 74 | void isr_dns (DNSReply r) { |
loopsva | 0:e065ca40f28a | 75 | |
loopsva | 0:e065ca40f28a | 76 | #ifdef DEBUG |
loopsva | 0:e065ca40f28a | 77 | printf("dns(%d)\r\n", r); |
loopsva | 0:e065ca40f28a | 78 | #endif |
loopsva | 0:e065ca40f28a | 79 | if (DNS_FOUND) { |
loopsva | 0:e065ca40f28a | 80 | dns_status = 1; |
loopsva | 0:e065ca40f28a | 81 | } else { |
loopsva | 0:e065ca40f28a | 82 | dns_status = -1; |
loopsva | 0:e065ca40f28a | 83 | } |
loopsva | 0:e065ca40f28a | 84 | } |
loopsva | 0:e065ca40f28a | 85 | |
loopsva | 0:e065ca40f28a | 86 | void isr_sntp (UDPSocketEvent e) { |
loopsva | 0:e065ca40f28a | 87 | char buf[100]; |
loopsva | 0:e065ca40f28a | 88 | Host dsthost; |
loopsva | 0:e065ca40f28a | 89 | int len; |
loopsva | 0:e065ca40f28a | 90 | |
loopsva | 0:e065ca40f28a | 91 | if (e == UDPSOCKET_READABLE) { |
loopsva | 0:e065ca40f28a | 92 | // recv responce; |
loopsva | 0:e065ca40f28a | 93 | len = sntp->recvfrom(buf, sizeof(buf), &dsthost); |
loopsva | 0:e065ca40f28a | 94 | #ifdef DEBUG |
loopsva | 0:e065ca40f28a | 95 | for (int i = 0; i < len; i ++) { |
loopsva | 0:e065ca40f28a | 96 | printf(" %02x", (unsigned char)buf[i]); |
loopsva | 0:e065ca40f28a | 97 | } |
loopsva | 0:e065ca40f28a | 98 | puts("\r"); |
loopsva | 0:e065ca40f28a | 99 | #endif |
loopsva | 0:e065ca40f28a | 100 | if (len >= sizeof(struct SNTPPacket)) { |
loopsva | 0:e065ca40f28a | 101 | getSntpResponse(buf, (uint32_t*)&sntptime); |
loopsva | 0:e065ca40f28a | 102 | } |
loopsva | 0:e065ca40f28a | 103 | } |
loopsva | 0:e065ca40f28a | 104 | } |
loopsva | 0:e065ca40f28a | 105 | |
loopsva | 0:e065ca40f28a | 106 | int ntpdate (const char* name, uint32_t *tim) { |
loopsva | 0:e065ca40f28a | 107 | UDPSocketErr err; |
loopsva | 0:e065ca40f28a | 108 | Host sntphost; |
loopsva | 0:e065ca40f28a | 109 | Timer timeout; |
loopsva | 0:e065ca40f28a | 110 | char buf[100]; |
loopsva | 0:e065ca40f28a | 111 | int i, len; |
loopsva | 0:e065ca40f28a | 112 | |
loopsva | 0:e065ca40f28a | 113 | sntptime = 0; |
loopsva | 0:e065ca40f28a | 114 | sntp = new UDPSocket; |
loopsva | 0:e065ca40f28a | 115 | sntp->setOnEvent(isr_sntp); |
loopsva | 0:e065ca40f28a | 116 | |
loopsva | 0:e065ca40f28a | 117 | sntphost.setName(name); |
loopsva | 0:e065ca40f28a | 118 | { |
loopsva | 0:e065ca40f28a | 119 | // resolv |
loopsva | 0:e065ca40f28a | 120 | DNSRequest dns; |
loopsva | 0:e065ca40f28a | 121 | dns_status = 0; |
loopsva | 0:e065ca40f28a | 122 | dns.setOnReply(isr_dns); |
loopsva | 0:e065ca40f28a | 123 | if (dns.resolve(&sntphost) != DNS_OK) goto exit; |
loopsva | 0:e065ca40f28a | 124 | timeout.reset(); |
loopsva | 0:e065ca40f28a | 125 | timeout.start(); |
loopsva | 0:e065ca40f28a | 126 | while (timeout.read_ms() < NTP_TIMEOUT) { |
loopsva | 0:e065ca40f28a | 127 | if (dns_status) break; |
loopsva | 0:e065ca40f28a | 128 | Net::poll(); |
loopsva | 0:e065ca40f28a | 129 | } |
loopsva | 0:e065ca40f28a | 130 | timeout.stop(); |
loopsva | 0:e065ca40f28a | 131 | if (dns_status <= 0) goto exit; |
loopsva | 0:e065ca40f28a | 132 | #ifdef DEBUG |
loopsva | 0:e065ca40f28a | 133 | printf("%s [%d.%d.%d.%d]\r\n", sntphost.getName(), (unsigned char)sntphost.getIp()[0], (unsigned char)sntphost.getIp()[1], (unsigned char)sntphost.getIp()[2], (unsigned char)sntphost.getIp()[3]); |
loopsva | 0:e065ca40f28a | 134 | #endif |
loopsva | 0:e065ca40f28a | 135 | } |
loopsva | 0:e065ca40f28a | 136 | sntphost.setPort(NTP_PORT); |
loopsva | 0:e065ca40f28a | 137 | |
loopsva | 0:e065ca40f28a | 138 | // send request |
loopsva | 0:e065ca40f28a | 139 | len = createSntpRequest(buf); |
loopsva | 0:e065ca40f28a | 140 | #ifdef DEBUG |
loopsva | 0:e065ca40f28a | 141 | for (int i = 0; i < len; i ++) { |
loopsva | 0:e065ca40f28a | 142 | printf(" %02x", (unsigned char)buf[i]); |
loopsva | 0:e065ca40f28a | 143 | } |
loopsva | 0:e065ca40f28a | 144 | puts("\r"); |
loopsva | 0:e065ca40f28a | 145 | #endif |
loopsva | 0:e065ca40f28a | 146 | sntp->sendto(buf, len, &sntphost); |
loopsva | 0:e065ca40f28a | 147 | |
loopsva | 0:e065ca40f28a | 148 | // wait responce |
loopsva | 0:e065ca40f28a | 149 | i = 0; |
loopsva | 0:e065ca40f28a | 150 | timeout.reset(); |
loopsva | 0:e065ca40f28a | 151 | timeout.start(); |
loopsva | 0:e065ca40f28a | 152 | while (timeout.read_ms() < NTP_TIMEOUT) { |
loopsva | 0:e065ca40f28a | 153 | if (sntptime) { |
loopsva | 0:e065ca40f28a | 154 | *tim = sntptime; |
loopsva | 0:e065ca40f28a | 155 | break; |
loopsva | 0:e065ca40f28a | 156 | } |
loopsva | 0:e065ca40f28a | 157 | if (timeout.read_ms() / 5000 < i) { |
loopsva | 0:e065ca40f28a | 158 | sntp->sendto(buf, len, &sntphost); |
loopsva | 0:e065ca40f28a | 159 | i ++; |
loopsva | 0:e065ca40f28a | 160 | } |
loopsva | 0:e065ca40f28a | 161 | Net::poll(); |
loopsva | 0:e065ca40f28a | 162 | } |
loopsva | 0:e065ca40f28a | 163 | timeout.stop(); |
loopsva | 0:e065ca40f28a | 164 | |
loopsva | 0:e065ca40f28a | 165 | exit: |
loopsva | 0:e065ca40f28a | 166 | sntp->resetOnEvent(); |
loopsva | 0:e065ca40f28a | 167 | delete sntp; |
loopsva | 0:e065ca40f28a | 168 | |
loopsva | 0:e065ca40f28a | 169 | return sntptime ? 0 : -1; |
loopsva | 0:e065ca40f28a | 170 | } |