]> the.earth.li Git - esp8266-clock.git/blobdiff - clock.c
Update for SDK 2.2.1 with system compiler
[esp8266-clock.git] / clock.c
diff --git a/clock.c b/clock.c
index 02bc1b56c55780fdcd8eec7aa3129d028bbbb400..e8df6699ba50d133818dfb128a16aac09733ffe4 100644 (file)
--- a/clock.c
+++ b/clock.c
 #include <mem.h>
 #include <osapi.h>
 
-#include "espmissingincludes.h"
-
 #include "clock.h"
 
+#define NTP_SERVER     "uk.pool.ntp.org"
 #define NTP_TIMEOUT_MS 5000
 
 static uint32_t sys_last_ticks;
 static uint32_t sys_delta;
 static os_timer_t ntp_timeout;
-static struct espconn *pCon = NULL;
 
-uint8 ntp_server[] = {87, 124, 126, 49};
+static ip_addr_t ntp_server_ip;
 
 typedef struct {
        uint8 options;
@@ -90,8 +88,16 @@ uint32_t ICACHE_FLASH_ATTR get_time(void)
        return sys_ticks / 1000000 + sys_delta;
 }
 
+bool ICACHE_FLASH_ATTR is_leap(uint32_t year)
+{
+       return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
+}
+
 void ICACHE_FLASH_ATTR breakdown_time(uint32_t time, struct tm *result)
 {
+       uint32_t era, doe, yoe, mp;
+
+       /* Do the time component */
        result->tm_sec = time % 60;
        time /= 60;
        result->tm_min = time % 60;
@@ -99,11 +105,33 @@ void ICACHE_FLASH_ATTR breakdown_time(uint32_t time, struct tm *result)
        result->tm_hour = time % 24;
        time /= 24;
 
-       result->tm_year = time / (365 * 4 + 1) * 4 + 70;
-       time %= 365 * 4 + 1;
+       /* Now time is the number of days since 1970-01-01 (a Thursday) */
+       result->tm_wday = (time + 4) % 7;
+
+       /* Below from http://howardhinnant.github.io/date_algorithms.html */
+       time += 719468;
+       era = time / 146097;
+       doe = time - era * 146097;
+       yoe = (doe - doe / 1460 + doe / 36524 - doe / 146096) / 365;
+
+       result->tm_year = yoe + era * 400;
+       result->tm_yday = doe - (365 * yoe + yoe / 4 - yoe / 100);
+       mp = (5 * result->tm_yday + 2) / 153;
+       result->tm_mday = result->tm_yday - (153 * mp + 2) / 5 + 1;
+       result->tm_mon = mp + (mp < 10 ? 2 : -10);
+       if (result->tm_mon <=2)
+               result->tm_year++;
+
+       /* result->tm_yday is March 1st indexed at this point; fix up */
+       result->tm_yday += 28 + 31;
+       if (is_leap(result->tm_year))
+               result->tm_yday++;
 }
 
-static void ICACHE_FLASH_ATTR ntp_udp_timeout(void *arg) {
+static void ICACHE_FLASH_ATTR ntp_udp_timeout(void *arg)
+{
+       struct espconn *pCon = (struct espconn *) arg;
+
        os_timer_disarm(&ntp_timeout);
        os_printf("NTP timeout.\n");
 
@@ -119,6 +147,7 @@ static void ICACHE_FLASH_ATTR ntp_udp_timeout(void *arg) {
 static void ICACHE_FLASH_ATTR ntp_udp_recv(void *arg, char *pdata,
        unsigned short len)
 {
+       struct espconn *pCon = (struct espconn *) arg;
        uint32_t timestamp;
        ntp_t *ntp;
        struct tm dt;
@@ -139,8 +168,9 @@ static void ICACHE_FLASH_ATTR ntp_udp_recv(void *arg, char *pdata,
 
        // Print it out
        breakdown_time(timestamp, &dt);
-       os_printf("%04d %02d:%02d:%02d (%u)\r\n", dt.tm_year, dt.tm_hour,
-               dt.tm_min, dt.tm_sec, timestamp);
+       os_printf("%04d-%02d-%02d %02d:%02d:%02d (%u)\r\n",
+               dt.tm_year, dt.tm_mon + 1, dt.tm_mday,
+               dt.tm_hour, dt.tm_min, dt.tm_sec, timestamp);
 
        // clean up connection
        if (pCon) {
@@ -151,20 +181,26 @@ static void ICACHE_FLASH_ATTR ntp_udp_recv(void *arg, char *pdata,
        }
 }
 
-void ICACHE_FLASH_ATTR ntp_get_time(void)
+void ICACHE_FLASH_ATTR ntp_got_dns(const char *name, ip_addr_t *ip, void *arg)
 {
        ntp_t ntp;
+       struct espconn *pCon = (struct espconn *) arg;
+
+       if (ip == NULL) {
+               os_printf("NTP DNS request failed.\n");
+               os_free(pCon);
+               return;
+       }
 
        os_printf("Sending NTP request.\n");
 
        // Set up the UDP "connection"
-       pCon = (struct espconn *) os_zalloc(sizeof(struct espconn));
        pCon->type = ESPCONN_UDP;
        pCon->state = ESPCONN_NONE;
        pCon->proto.udp = (esp_udp *) os_zalloc(sizeof(esp_udp));
        pCon->proto.udp->local_port = espconn_port();
        pCon->proto.udp->remote_port = 123;
-       os_memcpy(pCon->proto.udp->remote_ip, ntp_server, 4);
+       os_memcpy(pCon->proto.udp->remote_ip, &ip->addr, 4);
 
        // Create a really simple NTP request packet
        os_memset(&ntp, 0, sizeof(ntp_t));
@@ -181,6 +217,15 @@ void ICACHE_FLASH_ATTR ntp_get_time(void)
        espconn_sent(pCon, (uint8_t *) &ntp, sizeof(ntp_t));
 }
 
+void ICACHE_FLASH_ATTR ntp_get_time(void)
+{
+       struct espconn *pCon = NULL;
+
+       os_printf("Sending DNS request for NTP server.\n");
+       pCon = (struct espconn *) os_zalloc(sizeof(struct espconn));
+       espconn_gethostbyname(pCon, NTP_SERVER, &ntp_server_ip, ntp_got_dns);
+}
+
 void ICACHE_FLASH_ATTR rtc_init(void)
 {
        sys_last_ticks = system_get_time();