Skip to content

Commit 4cf72e7

Browse files
committed
Add libc time functions
Merging igrr/axtls-8266#1 by @Juppit into the core
1 parent 11340a5 commit 4cf72e7

File tree

4 files changed

+166
-19
lines changed

4 files changed

+166
-19
lines changed

cores/esp8266/Arduino.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ void ets_intr_unlock();
153153
// level (0-15), interrupts of the given level and above will be active
154154
// level 15 will disable ALL interrupts,
155155
// level 0 will enable ALL interrupts,
156-
//
156+
//
157157
#define xt_rsil(level) (__extension__({uint32_t state; __asm__ __volatile__("rsil %0," __STRINGIFY(level) : "=a" (state)); state;}))
158158
#define xt_wsr_ps(state) __asm__ __volatile__("wsr %0,ps; isync" :: "a" (state) : "memory")
159159

@@ -271,6 +271,8 @@ long random(long, long);
271271
void randomSeed(unsigned long);
272272
long map(long, long, long, long, long);
273273

274+
extern "C" void configTime(int timezone, int daylightOffset_sec,
275+
const char* server1, const char* server2 = nullptr, const char* server3 = nullptr);
274276

275277
#endif
276278

cores/esp8266/libc_replacements.c

-18
Original file line numberDiff line numberDiff line change
@@ -393,24 +393,6 @@ int* __errno(void) {
393393
return &errno_var;
394394
}
395395

396-
397-
char * ctime(const time_t *clock) {
398-
return 0;
399-
}
400-
401-
time_t time(time_t * t) {
402-
return 0;
403-
}
404-
405-
int gettimeofday(void *tp, void *tzp) {
406-
return 0;
407-
}
408-
409-
time_t mktime(struct tm *timp) {
410-
return 0;
411-
}
412-
413-
414396
/*
415397
* begin newlib/string/strlcpy.c
416398
*

cores/esp8266/time.c

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
/*
2+
* time.c - ESP8266-specific functions for SNTP
3+
* Copyright (c) 2015 Peter Dobler. All rights reserved.
4+
* This file is part of the esp8266 core for Arduino environment.
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
* This library is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the GNU Lesser General Public License for more details.
13+
* You should have received a copy of the GNU Lesser General Public
14+
* License along with this library; if not, write to the Free Software
15+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16+
*
17+
*/
18+
19+
#include <time.h>
20+
#include "sntp.h"
21+
22+
23+
#ifndef _TIMEVAL_DEFINED
24+
#define _TIMEVAL_DEFINED
25+
struct timeval {
26+
time_t tv_sec;
27+
suseconds_t tv_usec;
28+
};
29+
#endif
30+
31+
extern char* sntp_asctime(const struct tm *t);
32+
extern struct tm* sntp_localtime(const time_t *clock);
33+
34+
// time gap in seconds from 01.01.1900 (NTP time) to 01.01.1970 (UNIX time)
35+
#define DIFF1900TO1970 2208988800UL
36+
37+
static int s_daylightOffset_sec = 0;
38+
static int s_timezone_sec = 0;
39+
static time_t s_bootTime = 0;
40+
41+
// calculate offset used in gettimeofday
42+
static void ensureBootTimeIsSet()
43+
{
44+
if (!s_bootTime)
45+
{
46+
time_t now = sntp_get_current_timestamp();
47+
if (now)
48+
{
49+
s_bootTime = - millis() / 1000;
50+
}
51+
}
52+
}
53+
54+
static void setServer(int id, const char* name_or_ip)
55+
{
56+
if (name_or_ip)
57+
{
58+
//TODO: check whether server is given by name or IP
59+
sntp_setservername(0, (char*) name_or_ip);
60+
}
61+
}
62+
63+
void configTime(int timezone, int daylightOffset_sec, const char* server1, const char* server2, const char* server3)
64+
{
65+
sntp_stop();
66+
67+
setServer(0, server1);
68+
setServer(1, server2);
69+
setServer(2, server3);
70+
71+
s_timezone_sec = timezone;
72+
s_daylightOffset_sec = daylightOffset_sec;
73+
sntp_set_timezone(timezone/3600);
74+
sntp_init();
75+
}
76+
77+
int clock_gettime(clockid_t unused, struct timespec *tp)
78+
{
79+
tp->tv_sec = millis() / 1000;
80+
tp->tv_nsec = micros() * 1000;
81+
return 0;
82+
}
83+
84+
// seconds since 1970
85+
time_t mktime(struct tm *t)
86+
{
87+
// system_mktime expects month in range 1..12
88+
#define START_MONTH 1
89+
return DIFF1900TO1970 + system_mktime(t->tm_year, t->tm_mon + START_MONTH, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
90+
}
91+
92+
time_t time(time_t * t)
93+
{
94+
time_t seconds = sntp_get_current_timestamp();
95+
ensureBootTimeIsSet();
96+
if (t)
97+
{
98+
*t = seconds;
99+
}
100+
return seconds;
101+
}
102+
103+
char* asctime(const struct tm *t)
104+
{
105+
return sntp_asctime(t);
106+
}
107+
108+
struct tm* localtime(const time_t *clock)
109+
{
110+
return sntp_localtime(clock);
111+
}
112+
113+
char* ctime(const time_t *t)
114+
{
115+
struct tm* p_tm = localtime(t);
116+
char* result = asctime(p_tm);
117+
return result;
118+
}
119+
120+
int gettimeofday(struct timeval *tp, void *tzp)
121+
{
122+
if (tp)
123+
{
124+
ensureBootTimeIsSet();
125+
tp->tv_sec = (s_bootTime + millis()) / 1000;
126+
tp->tv_usec = micros() * 1000;
127+
}
128+
}

tests/Time/Time.ino

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#include <ESP8266WiFi.h>
2+
#include <time.h>
3+
4+
const char* ssid = "..........";
5+
const char* password = "..........";
6+
7+
int timezone = 3;
8+
int dst = 0;
9+
10+
void setup() {
11+
Serial.begin(115200);
12+
Serial.setDebugOutput(true);
13+
14+
WiFi.mode(WIFI_STA);
15+
WiFi.begin(ssid, password);
16+
Serial.println("\nConnecting to WiFi");
17+
while (WiFi.status() != WL_CONNECTED) {
18+
Serial.print(".");
19+
delay(1000);
20+
}
21+
22+
configTime(3 * 3600, 0, "pool.ntp.org", "time.nist.gov");
23+
Serial.println("\nWaiting for time");
24+
while (!time(nullptr)) {
25+
Serial.print(".");
26+
delay(1000);
27+
}
28+
Serial.println("");
29+
}
30+
31+
void loop() {
32+
time_t now = time(nullptr);
33+
Serial.println(ctime(&now));
34+
delay(1000);
35+
}

0 commit comments

Comments
 (0)