From c20af88b28bd681defdfe31ec59b204950e7d5c5 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Sun, 21 Jul 2019 21:11:55 -0700 Subject: [PATCH 01/35] CHANGELOG.md: Fix typo 'TB' -> 'TZ' --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59f5cd6ec..819825061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # Changelog * Unreleased -* 0.5 (2019-07-21, TB DB version 2019a, beta) +* 0.5 (2019-07-21, TZ DB version 2019a, beta) * Remove over-engineered `SystemClockHeartbeatLoop` and `SystemClockHeartbeatLoop` and replace with just a call to `SystemClock::keepAlive()`. From cf300b84ee65f2f2c987051527e57118127f88d8 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 07:42:01 -0700 Subject: [PATCH 02/35] README.md: Fix type 'is can be' -> 'can be' --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c1d40cdbc..d4d2529d9 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ be converted to another timezone. The library also provides a SystemClock that can be synchronized from a more reliable external time source, such as an [NTP](https://en.wikipedia.org/wiki/Network_Time_Protocol) server or a [DS3231 RTC](https://www.maximintegrated.com/en/products/analog/real-time-clocks/DS3231.html) -chip. This library is can be an alternative to the [Arduino +chip. This library can be an alternative to the [Arduino Time](https://github.com/PaulStoffregen/Time) and [Arduino Timezone](https://github.com/JChristensen/Timezone) libraries. From cca8519c56cfa75a1884a40c43685ebfc43b855d Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 07:42:49 -0700 Subject: [PATCH 03/35] libraries.properties: Change category from 'Other' to 'Timing' --- library.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library.properties b/library.properties index caad65996..6a71050f8 100644 --- a/library.properties +++ b/library.properties @@ -4,6 +4,6 @@ author=Brian T. Park maintainer=Brian T. Park sentence=Date, time, clock, and TZ Database timezones for Arduino. paragraph=Date and time classes for Arduino that support timezones from the TZ Database, and a system clock that can synchronize from an NTP server or an RTC chip. -category=Other +category=Timing url=https://github.com/bxparks/AceTime architectures=* From 1e74ce69c6dc1d03df80452f61a827bc9ec52b7a Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 07:44:38 -0700 Subject: [PATCH 04/35] README.md: Rephrase slightly to make more clear that internal class are not normally used by app developers --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d4d2529d9..7ec05589f 100644 --- a/README.md +++ b/README.md @@ -59,7 +59,7 @@ C++ namespaces: * `ace_time::clock::NtpTimeProvider` * `ace_time::clock::SystemClockSyncCoroutine` * `ace_time::clock::SystemClockSyncLoop` -* internal helper classes (normally unused by app developers) +* internal helper classes (not normally used by app developers) * `ace_time::basic::ZoneContext` * `ace_time::basic::ZoneEra` * `ace_time::basic::ZoneInfo` From e09d1353836d5605bddc1f4876f99d217f613afe Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 08:14:42 -0700 Subject: [PATCH 05/35] README.md: Add information about zoneId and ZoneManager --- README.md | 69 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 7ec05589f..c721576f2 100644 --- a/README.md +++ b/README.md @@ -83,28 +83,28 @@ individual (year, month, day, hour, minute, second) components, and the The Epoch in AceTime is defined to be 2000-01-01T00:00:00Z, in contrast to the Epoch in Unix which is 1970-01-01T00:00:00Z. Internally, the current time is represented as "seconds from Epoch" stored as a 32-bit signed integer -(`acetime_t` aliased to `int32_t`). Internally, the smallest 32-bit signed +(`acetime_t` aliased to `int32_t`). The smallest 32-bit signed integer (`-2^31`) is used to indicate an internal Error condition, so the -smallest valid `acetime_t` value is `-2^31+1`. The largest valid value is -`2^31-1`. Therefore, the range of dates that the `acetime_t` type can handle is +range of valid `acetime_t` value is `-2^31+1` to `2^31-1`. +Therefore, the range of dates that the `acetime_t` type can handle is 1931-12-13T20:45:53Z to 2068-01-19T03:14:07Z (inclusive). (In contrast, the 32-bit Unix `time_t` range is 1901-12-13T20:45:52Z to 2038-01-19T03:14:07Z). The various date classes (`LocalDate`, `LocalDateTime`, `OffsetDateTime`, -`ZonedDateTime`) store the year component as a signed 8-bit integer offset from -the year 2000. The range of this integer is -128 to +127, but -128 is used to -indicate an internal Error condition, so the actual range is -127 to +127. -Therefore, these classes can represent dates from 1873-01-01T00:00:00 to +`ZonedDateTime`) store the year component internally as a signed 8-bit integer +offset from the year 2000. The range of this integer is -128 to +127, but -128 +is used to indicate an internal Error condition, so the actual range is -127 to ++127. Therefore, these classes can represent dates from 1873-01-01T00:00:00 to 2127-12-31T23:59:59 (inclusive). Notice that these classes can represent all dates that can be expressed by the `acetime_t` type, but the reverse is not true. There are date objects that cannot be converted into a valid `acetime_t` value. To be safe, users of this library should stay at least 1 day away from the lower and upper limits of `acetime_t` (i.e. stay within the year 1932 to -2067, inclusive). +2067 inclusive). -The `ZonedDateTime` class works with the `TimeZone` class to provide access to -the TZ Database and allow conversions to other timezones using the -`ZonedDateTime::convertToTimeZone()` method. +The `ZonedDateTime` class works with the `TimeZone` class to implement the DST +transition rules defined by the TZ Database. It also allows conversions to other +timezones using the `ZonedDateTime::convertToTimeZone()` method. The library provides 2 sets of zoneinfo files created from the IANA TZ Database: @@ -117,9 +117,10 @@ The library provides 2 sets of zoneinfo files created from the IANA TZ Database: the TZ Database (essentially the entire database) intended to be used with the `ExtendedZoneProcessor` class. -These zoneinfo files have been validated to match the UTC offsets calculated -using the Python [pytz](https://pypi.org/project/pytz/) library from the year -2000 until 2037 (inclusive), and using the [Java 11 +These zoneinfo files (and the `ZoneProcessor` classes which calculate the UTC +offsets and DST transitions) have been validated to match the UTC offsets +calculated using the Python [pytz](https://pypi.org/project/pytz/) library from +the year 2000 until 2037 (inclusive), and using the [Java 11 Time](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html) library from year 2000 to 2049 (inclusive). Custom datasets with smaller or larger range of years may be generated by developers using scripts provided in @@ -127,10 +128,22 @@ this library (although this is not documented currently). The target application may be compiled against the custom dataset instead of using `zonedb::` and `zonedbx::` zone files provided in this library. -It is expected that an application using AceTime will use only a small subset of -these timezones at the same time (1 to 3 zones have been tested). The C++ -compiler will include only the subset of zoneinfo files needed to support those -timezones, instead of compiling in the entire TZ database. +It is expected that most applications using AceTime will use only a small number +of timezones at the same time (1 to 3 zones have been extensively tested) and +that this set is known at compile-time. The C++ compiler will include only the +subset of zoneinfo files needed to support those timezones, instead of compiling +in the entire TZ Database. But on microcontrollers with enough memory, the +`ZoneManager` can be used to load the entire TZ Database into the app and +the `TimeZone` objects can be dynamically created as needed. + +Each timezone in the TZ Database is identified by its fully qualified zone name +(e.g. `"America/Los_Angeles"`). On small microcontroller environments, these +strings can consume precious memory (e.g. 30 bytes for +`"America/Argentina/Buenos_Aires"`) and are not convenient to serialize over the +network or to save to EEPROM. Therefore, the AceTime library provides each +timezone with an alternative `zoneId` identifier of type `uint32_t` which is +guaranteed to be unique and stable. A `TimeZone` object can be saved as a +`zoneId` and then recreated using the `ZoneManager::createFromZoneId()` method. The `ace_time::clock` classes collaborate together to implement the SystemClock which can obtain its time from various sources, such as a DS3231 RTC @@ -139,20 +152,22 @@ from accurate clock sources can be expensive, so the `SystemClock` uses the built-in `millis()` function to provide fast access to a reasonably accurate clock, but synchronizes to more accurate clocks periodically. -This library does not perform dynamic allocation of memory, in other words, -it does not call the `new` operator nor the `malloc()` function, and it does not -use the Arduino `String` class. Everything it needs is allocated statically at -initialization time. +This library does not perform dynamic allocation of memory so that it can be +used in small microcontroller environments. In other words, it does not call the +`new` operator nor the `malloc()` function, and it does not use the Arduino +`String` class. Everything it needs is allocated statically at initialization +time. The zoneinfo files are stored in flash memory (using the `PROGMEM` compiler -directive) whenever possible so that they do not consume static RAM: +directive) if the microcontroller allows it (e.g. AVR, ESP8266) so that they do +not consume static RAM: * 270 timezones supported by `BasicZoneProcessor`consume: - * 14 kB of flash on an 8-bit processor - * 21 kB of flash on a 32-bit processor + * 14 kB of flash on an 8-bit processor (AVR) + * 21 kB of flash on a 32-bit processor (ESP8266) * 387 timezones supported by `ExtendedZoneProcessor` consume: - * 23 kB of flash on an 8-bit processor - * 37 kB of flash on a 32-bit processor + * 23 kB of flash on an 8-bit processor (AVR) + * 37 kB of flash on a 32-bit processor (ESP8266) Normally a small application will use only a small number of timezones. The AceTime library with one timezone using the `BasicZoneProcessor` and the From f2468fd380dfe907358e489a619923b79e930c6c Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 14:12:26 -0700 Subject: [PATCH 06/35] src: Add initial support for Arduino Zero using SAMD21; clobber SERIAL_PORT_MONITOR, move into .cpp files --- examples/HelloDateTime/HelloDateTime.ino | 74 +++++++++---------- .../HelloSystemClock/HelloSystemClock.ino | 10 +-- src/ace_time/BasicZoneProcessor.h | 1 - src/ace_time/ExtendedZoneProcessor.cpp | 1 + src/ace_time/ExtendedZoneProcessor.h | 2 +- src/ace_time/clock/NtpTimeProvider.cpp | 6 +- src/ace_time/clock/SystemClock.cpp | 10 +++ src/ace_time/clock/SystemClock.h | 10 ++- src/ace_time/common/flash.cpp | 15 ++++ src/ace_time/common/flash.h | 48 ++++++------ src/ace_time/common/logger.cpp | 40 ++++++++++ src/ace_time/common/logger.h | 31 ++------ 12 files changed, 153 insertions(+), 95 deletions(-) create mode 100644 src/ace_time/clock/SystemClock.cpp create mode 100644 src/ace_time/common/logger.cpp diff --git a/examples/HelloDateTime/HelloDateTime.ino b/examples/HelloDateTime/HelloDateTime.ino index 85e211190..dead08627 100644 --- a/examples/HelloDateTime/HelloDateTime.ino +++ b/examples/HelloDateTime/HelloDateTime.ino @@ -32,8 +32,8 @@ void setup() { #if defined(ARDUINO) delay(1000); #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while (!Serial); // Wait until Serial is ready - Leonardo/Micro + SERIAL_PORT_MONITOR.begin(115200); + while (!SERIAL_PORT_MONITOR); // Wait until Serial is ready - Leonardo/Micro auto pacificTz = TimeZone::forZoneInfo(&zonedb::kZoneAmerica_Los_Angeles, &pacificProcessor); @@ -45,63 +45,63 @@ void setup() { auto startTime = ZonedDateTime::forComponents( 2019, 3, 10, 3, 0, 0, pacificTz); - Serial.print(F("Epoch Seconds: ")); + SERIAL_PORT_MONITOR.print(F("Epoch Seconds: ")); acetime_t epochSeconds = startTime.toEpochSeconds(); - Serial.println(epochSeconds); + SERIAL_PORT_MONITOR.println(epochSeconds); - Serial.print(F("Unix Seconds: ")); + SERIAL_PORT_MONITOR.print(F("Unix Seconds: ")); acetime_t unixSeconds = startTime.toUnixSeconds(); - Serial.println(unixSeconds); + SERIAL_PORT_MONITOR.println(unixSeconds); - Serial.println(F("=== Los Angeles")); + SERIAL_PORT_MONITOR.println(F("=== Los Angeles")); auto pacificTime = ZonedDateTime::forEpochSeconds(epochSeconds, pacificTz); - Serial.print(F("Time: ")); - pacificTime.printTo(Serial); - Serial.println(); + SERIAL_PORT_MONITOR.print(F("Time: ")); + pacificTime.printTo(SERIAL_PORT_MONITOR); + SERIAL_PORT_MONITOR.println(); - Serial.print(F("Day of Week: ")); - Serial.println( + SERIAL_PORT_MONITOR.print(F("Day of Week: ")); + SERIAL_PORT_MONITOR.println( common::DateStrings().dayOfWeekLongString(pacificTime.dayOfWeek())); // Print info about UTC offset TimeOffset offset = pacificTime.timeOffset(); - Serial.print(F("Total UTC Offset: ")); - offset.printTo(Serial); - Serial.println(); + SERIAL_PORT_MONITOR.print(F("Total UTC Offset: ")); + offset.printTo(SERIAL_PORT_MONITOR); + SERIAL_PORT_MONITOR.println(); // Print info about the current time zone - Serial.print(F("Zone: ")); - pacificTz.printTo(Serial); - Serial.println(); + SERIAL_PORT_MONITOR.print(F("Zone: ")); + pacificTz.printTo(SERIAL_PORT_MONITOR); + SERIAL_PORT_MONITOR.println(); // Print the current time zone abbreviation, e.g. "PST" or "PDT" - Serial.print(F("Abbreviation: ")); - pacificTz.printAbbrevTo(Serial, epochSeconds); - Serial.println(); + SERIAL_PORT_MONITOR.print(F("Abbreviation: ")); + pacificTz.printAbbrevTo(SERIAL_PORT_MONITOR, epochSeconds); + SERIAL_PORT_MONITOR.println(); // Create from epoch seconds. London is still on standard time. auto londonTime = ZonedDateTime::forEpochSeconds(epochSeconds, londonTz); - Serial.println(F("=== London")); - Serial.print(F("Time: ")); - londonTime.printTo(Serial); - Serial.println(); + SERIAL_PORT_MONITOR.println(F("=== London")); + SERIAL_PORT_MONITOR.print(F("Time: ")); + londonTime.printTo(SERIAL_PORT_MONITOR); + SERIAL_PORT_MONITOR.println(); // Print info about the current time zone - Serial.print(F("Zone: ")); - londonTz.printTo(Serial); - Serial.println(); + SERIAL_PORT_MONITOR.print(F("Zone: ")); + londonTz.printTo(SERIAL_PORT_MONITOR); + SERIAL_PORT_MONITOR.println(); // Print the current time zone abbreviation, e.g. "PST" or "PDT" - Serial.print(F("Abbreviation: ")); - londonTz.printAbbrevTo(Serial, epochSeconds); - Serial.println(); - - Serial.println(F("=== Compare ZonedDateTime")); - Serial.print(F("pacificTime.compareTo(londonTime): ")); - Serial.println(pacificTime.compareTo(londonTime)); - Serial.print(F("pacificTime == londonTime: ")); - Serial.println((pacificTime == londonTime) ? "true" : "false"); + SERIAL_PORT_MONITOR.print(F("Abbreviation: ")); + londonTz.printAbbrevTo(SERIAL_PORT_MONITOR, epochSeconds); + SERIAL_PORT_MONITOR.println(); + + SERIAL_PORT_MONITOR.println(F("=== Compare ZonedDateTime")); + SERIAL_PORT_MONITOR.print(F("pacificTime.compareTo(londonTime): ")); + SERIAL_PORT_MONITOR.println(pacificTime.compareTo(londonTime)); + SERIAL_PORT_MONITOR.print(F("pacificTime == londonTime: ")); + SERIAL_PORT_MONITOR.println((pacificTime == londonTime) ? "true" : "false"); #ifndef ARDUINO exit(0); diff --git a/examples/HelloSystemClock/HelloSystemClock.ino b/examples/HelloSystemClock/HelloSystemClock.ino index 30baa656f..cc71be8d8 100644 --- a/examples/HelloSystemClock/HelloSystemClock.ino +++ b/examples/HelloSystemClock/HelloSystemClock.ino @@ -1,6 +1,6 @@ /* * A program to demonstrate the use of AceTime SystemClock. It should print the - * following on the Serial port every 2 seconds: + * following on the SERIAL_PORT_MONITOR port every 2 seconds: * * 2019-06-17T19:50:00-07:00[America/Los_Angeles] * 2019-06-17T19:50:02-07:00[America/Los_Angeles] @@ -22,8 +22,8 @@ SystemClock systemClock(nullptr /*sync*/, nullptr /*backup*/); void setup() { delay(1000); - Serial.begin(115200); - while (!Serial); // Wait until Serial is ready - Leonardo/Micro + SERIAL_PORT_MONITOR.begin(115200); + while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro systemClock.setup(); @@ -46,8 +46,8 @@ void printCurrentTime() { auto pacificTz = TimeZone::forZoneInfo(&zonedb::kZoneAmerica_Los_Angeles, &pacificProcessor); auto pacificTime = ZonedDateTime::forEpochSeconds(now, pacificTz); - pacificTime.printTo(Serial); - Serial.println(); + pacificTime.printTo(SERIAL_PORT_MONITOR); + SERIAL_PORT_MONITOR.println(); } void loop() { diff --git a/src/ace_time/BasicZoneProcessor.h b/src/ace_time/BasicZoneProcessor.h index 063dc9063..96d6fcdbf 100644 --- a/src/ace_time/BasicZoneProcessor.h +++ b/src/ace_time/BasicZoneProcessor.h @@ -6,7 +6,6 @@ #ifndef ACE_TIME_BASIC_ZONE_PROCESSOR_H #define ACE_TIME_BASIC_ZONE_PROCESSOR_H -#include #include // strchr() #include #include "internal/ZonePolicy.h" diff --git a/src/ace_time/ExtendedZoneProcessor.cpp b/src/ace_time/ExtendedZoneProcessor.cpp index 9902615a3..f790228a1 100644 --- a/src/ace_time/ExtendedZoneProcessor.cpp +++ b/src/ace_time/ExtendedZoneProcessor.cpp @@ -3,6 +3,7 @@ * Copyright (c) 2019 Brian T. Park */ +#include #include "LocalDate.h" #include "ExtendedZone.h" #include "ExtendedZoneProcessor.h" diff --git a/src/ace_time/ExtendedZoneProcessor.h b/src/ace_time/ExtendedZoneProcessor.h index 89bdcafad..1bba898d0 100644 --- a/src/ace_time/ExtendedZoneProcessor.h +++ b/src/ace_time/ExtendedZoneProcessor.h @@ -6,9 +6,9 @@ #ifndef ACE_TIME_EXTENDED_ZONE_PROCESSOR_H #define ACE_TIME_EXTENDED_ZONE_PROCESSOR_H -#include #include // memcpy() #include +#include "common/flash.h" #include "internal/ZonePolicy.h" #include "internal/ZoneInfo.h" #include "common/logger.h" diff --git a/src/ace_time/clock/NtpTimeProvider.cpp b/src/ace_time/clock/NtpTimeProvider.cpp index 48c075598..188f940cb 100644 --- a/src/ace_time/clock/NtpTimeProvider.cpp +++ b/src/ace_time/clock/NtpTimeProvider.cpp @@ -3,6 +3,8 @@ * Copyright (c) 2018 Brian T. Park */ +#include +#include "../common/flash.h" #include "NtpTimeProvider.h" #if defined(ESP8266) || defined(ESP32) @@ -31,8 +33,8 @@ void NtpTimeProvider::setup(const char* ssid, const char* password) { #if ACE_TIME_NTP_TIME_PROVIDER_DEBUG == 1 #if defined(ESP8266) - Serial.print(F("Local port: ")); - Serial.println(mUdp.localPort()); + SERIAL_PORT_MONITOR.print(F("Local port: ")); + SERIAL_PORT_MONITOR.println(mUdp.localPort()); #endif #endif diff --git a/src/ace_time/clock/SystemClock.cpp b/src/ace_time/clock/SystemClock.cpp new file mode 100644 index 000000000..c5ed46fec --- /dev/null +++ b/src/ace_time/clock/SystemClock.cpp @@ -0,0 +1,10 @@ +#include // millis() +#include "SystemClock.h" + +namespace ace_time { +namespace clock { + +unsigned long SystemClock::millis() const { return ::millis(); } + +} +} diff --git a/src/ace_time/clock/SystemClock.h b/src/ace_time/clock/SystemClock.h index bac3ed5e4..9d06d5419 100644 --- a/src/ace_time/clock/SystemClock.h +++ b/src/ace_time/clock/SystemClock.h @@ -6,10 +6,8 @@ #ifndef ACE_TIME_SYSTEM_CLOCK_H #define ACE_TIME_SYSTEM_CLOCK_H -#include // millis() #include #include "../common/TimingStats.h" -#include "../common/logger.h" #include "TimeKeeper.h" namespace ace_time { @@ -132,8 +130,12 @@ class SystemClock: public TimeKeeper { bool isInit() const { return mIsInit; } protected: - /** Return the Arduino millis(). Override for unit testing. */ - virtual unsigned long millis() const { return ::millis(); } + /** + * Return the Arduino millis(). Override for unit testing. + * This is defined in the .cpp file to avoid include in + * the header, which avoids a multiple #define error. + */ + virtual unsigned long millis() const; private: friend class SystemClockSyncCoroutine; diff --git a/src/ace_time/common/flash.cpp b/src/ace_time/common/flash.cpp index a717dbd81..63af87714 100644 --- a/src/ace_time/common/flash.cpp +++ b/src/ace_time/common/flash.cpp @@ -25,3 +25,18 @@ const char* strrchr_P(const char* s, int c) { } #endif + +int acetime_strcmp_PP(const char* a, const char* b) { + if (a == b) { return 0; } + if (a == nullptr) { return -1; } + if (b == nullptr) { return 1; } + + while (true) { + uint8_t ca = pgm_read_byte(a); + uint8_t cb = pgm_read_byte(b); + if (ca != cb) return (int) ca - (int) cb; + if (ca == '\0') return 0; + a++; + b++; + } +} diff --git a/src/ace_time/common/flash.h b/src/ace_time/common/flash.h index 81781d14a..6b8bcb887 100644 --- a/src/ace_time/common/flash.h +++ b/src/ace_time/common/flash.h @@ -9,10 +9,7 @@ #include #include -/** - * Use PROGMEM for zonedb and zonedbx zoneinfo files. Controls how - * ACE_TIME_PROGMEM macro gets expanded. - */ +/** Determine if zonedb and zonedbx zoneinfo files are placed in PROGMEM. */ #define ACE_TIME_USE_PROGMEM 1 #if ACE_TIME_USE_PROGMEM #define ACE_TIME_PROGMEM PROGMEM @@ -23,24 +20,43 @@ // Include the correct pgmspace.h depending on architecture. Define a // consistent acetime_strcmp_P() which can be passed as a function pointer // into the ZoneManager template class. -#if defined(__AVR__) +#if defined(ARDUINO_ARCH_AVR) #include #define FPSTR(p) (reinterpret_cast(p)) #define acetime_strcmp_P strcmp_P + +#elif defined(ARDUINO_ARCH_SAMD) + #include + #define FPSTR(p) (reinterpret_cast(p)) + + // strcmp_P(a,b) is defined to be strcmp(a,b), but we need a function + // pointer, so map it directly to strcmp() + #define acetime_strcmp_P strcmp + + // All other SAMD boards define SERIAL_PORT_MONITOR as SerialUSB, except for + // the Zero, which defines it to be Serial, which doesn't work. Clobber it. + #if defined(ARDUINO_SAMD_ZERO) + #undef SERIAL_PORT_MONITOR + #define SERIAL_PORT_MONITOR SerialUSB + #endif + #elif defined(TEENSYDUINO) #include #define FPSTR(p) (reinterpret_cast(p)) // Teensyduino defines strcmp_P(a, b) as strcmp(a,b), which cannot be // passed as a function pointer, so we have to use strcmp() directly. #define acetime_strcmp_P strcmp + #elif defined(ESP8266) #include - // ESP8266 2.5.2 defines strcmp_P() as a macro, so we have to provide a real + + // ESP8266 2.5.2 defines strcmp_P() as a macro function, but we need a real // function. inline int acetime_strcmp_P(const char* str1, const char* str2P) { return strcmp_P((str1), (str2P)); } + // ESP8266 2.5.2 doesn't have these so provide our own implementation. extern "C" { const char* strchr_P(const char* s, int c); const char* strrchr_P(const char* s, int c); @@ -48,12 +64,13 @@ #elif defined(ESP32) #include - // Fix incorrect definition of FPSTR in ESP32, see + // Fix incorrect definition of FPSTR in ESP32 1.0.2. See // https://github.com/espressif/arduino-esp32/issues/1371 #undef FPSTR #define FPSTR(p) (reinterpret_cast(p)) #define acetime_strcmp_P strcmp_P + // ESP32 1.0.2 doesn't have these so provide our own implementation. extern "C" { const char* strchr_P(const char* s, int c); const char* strrchr_P(const char* s, int c); @@ -63,6 +80,8 @@ #include #define FPSTR(p) (reinterpret_cast(p)) #define acetime_strcmp_P strcmp_P + #define SERIAL_PORT_MONITOR Serial + #else #error Unsupported platform #endif @@ -71,19 +90,6 @@ * Compare 2 strings in flash memory. None of the various strXxx_P() functions * work when both strings are in flash memory. */ -inline int acetime_strcmp_PP(const char* a, const char* b) { - if (a == b) { return 0; } - if (a == nullptr) { return -1; } - if (b == nullptr) { return 1; } - - while (true) { - uint8_t ca = pgm_read_byte(a); - uint8_t cb = pgm_read_byte(b); - if (ca != cb) return (int) ca - (int) cb; - if (ca == '\0') return 0; - a++; - b++; - } -} +int acetime_strcmp_PP(const char* a, const char* b); #endif diff --git a/src/ace_time/common/logger.cpp b/src/ace_time/common/logger.cpp new file mode 100644 index 000000000..00a0ed36f --- /dev/null +++ b/src/ace_time/common/logger.cpp @@ -0,0 +1,40 @@ +#include +#include "flash.h" +#include "logger.h" + +namespace ace_time { +namespace logging { + +void vprintf(const char *fmt, va_list args) { + char buf[192]; + vsnprintf(buf, 192, fmt, args); + SERIAL_PORT_MONITOR.print(buf); +} + +/** A print() that works for Arduino using the built-in vsnprintf(). */ +void print(const char* fmt, ...) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); +} + +/** + * Log the lower 16-bits of millis(), then print the log message using its fmt + * and arguments. Automatically prints a newline. + */ +void println(const char *fmt, ... ) { + va_list args; + va_start(args, fmt); + vprintf(fmt, args); + va_end(args); + SERIAL_PORT_MONITOR.println(); +} + +/** Print a newline. */ +inline void println() { + SERIAL_PORT_MONITOR.println(); +} + +} +} diff --git a/src/ace_time/common/logger.h b/src/ace_time/common/logger.h index b70a00c52..2818109cb 100644 --- a/src/ace_time/common/logger.h +++ b/src/ace_time/common/logger.h @@ -6,47 +6,30 @@ /* * Implement logger::print() and logger::println() that accept formatting * strings like printf(). I finally got tired of writing multiple lines of - * Serial.print() for debugging. + * SERIAL_PORT_MONITOR.print() for debugging. */ #ifndef ACE_TIME_COMMON_LOGGING_H #define ACE_TIME_COMMON_LOGGING_H +#include + namespace ace_time { namespace logging { -#include - -inline void vprintf(const char *fmt, va_list args) { - char buf[192]; - vsnprintf(buf, 192, fmt, args); - Serial.print(buf); -} +void vprintf(const char *fmt, va_list args); /** A print() that works for Arduino using the built-in vsnprintf(). */ -inline void print(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); -} +void print(const char* fmt, ...); /** * Log the lower 16-bits of millis(), then print the log message using its fmt * and arguments. Automatically prints a newline. */ -inline void println(const char *fmt, ... ) { - va_list args; - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - Serial.println(); -} +void println(const char *fmt, ... ); /** Print a newline. */ -inline void println() { - Serial.println(); -} +void println(); } } From b675951b29916c7a8802cb7cdcfd6e3d3c7ac31b Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 14:31:58 -0700 Subject: [PATCH 07/35] tests: Change Serial -> SERIAL_PORT_MONITOR to work on Arduino Zero (SAMD21) --- tests/BasicZoneProcessorTest/BasicZoneProcessorTest.ino | 6 +++--- tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino | 6 +++--- tests/CommonTest/CommonTest.ino | 6 +++--- .../ExtendedZoneProcessorMoreTest.ino | 6 +++--- .../ExtendedZoneProcessorTest.ino | 6 +++--- .../ExtendedZoneRegistrarTest.ino | 6 +++--- tests/HardwareTest/HardwareTest.ino | 6 +++--- tests/LocalDateTest/LocalDateTest.ino | 6 +++--- tests/LocalDateTimeTest/LocalDateTimeTest.ino | 6 +++--- tests/LocalTimeTest/LocalTimeTest.ino | 6 +++--- tests/OffsetDateTimeTest/OffsetDateTimeTest.ino | 6 +++--- tests/SystemClockTest/SystemClockTest.ino | 6 +++--- tests/TimeOffsetTest/TimeOffsetTest.ino | 6 +++--- tests/TimePeriodTest/TimePeriodTest.ino | 6 +++--- tests/TimeZoneExtendedTest/TimeZoneExtendedTest.ino | 8 ++++---- tests/TimeZoneTest/TimeZoneTest.ino | 6 +++--- tests/TransitionStorageTest/TransitionStorageTest.ino | 6 +++--- tests/ZoneProcessorCacheTest/ZoneProcessorCacheTest.ino | 6 +++--- tests/ZonedDateTimeBasicTest/ZonedDateTimeBasicTest.ino | 6 +++--- .../ZonedDateTimeExtendedTest.ino | 6 +++--- tests/ZonedDateTimeTest/ZonedDateTimeTest.ino | 6 +++--- .../BasicValidationUsingJavaTest.ino | 6 +++--- .../BasicValidationUsingPythonTest.ino | 6 +++--- .../ExtendedValidationUsingJavaTest.ino | 6 +++--- .../ExtendedValidationUsingPythonTest.ino | 6 +++--- 25 files changed, 76 insertions(+), 76 deletions(-) diff --git a/tests/BasicZoneProcessorTest/BasicZoneProcessorTest.ino b/tests/BasicZoneProcessorTest/BasicZoneProcessorTest.ino index ab8b527c2..072201d28 100644 --- a/tests/BasicZoneProcessorTest/BasicZoneProcessorTest.ino +++ b/tests/BasicZoneProcessorTest/BasicZoneProcessorTest.ino @@ -303,10 +303,10 @@ test(BasicZoneProcessorTest, kZoneAmerica_Los_Angeles_outOfBounds) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino b/tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino index fee1596ca..218a66211 100644 --- a/tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino +++ b/tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino @@ -162,10 +162,10 @@ test(BasicZoneRegistrarTest_Unsorted, linearSearch) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/CommonTest/CommonTest.ino b/tests/CommonTest/CommonTest.ino index 6d713d4a2..e2f5bc7ff 100644 --- a/tests/CommonTest/CommonTest.ino +++ b/tests/CommonTest/CommonTest.ino @@ -125,11 +125,11 @@ test(incrementMod) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/ExtendedZoneProcessorMoreTest/ExtendedZoneProcessorMoreTest.ino b/tests/ExtendedZoneProcessorMoreTest/ExtendedZoneProcessorMoreTest.ino index 114cd7663..c7fd07414 100644 --- a/tests/ExtendedZoneProcessorMoreTest/ExtendedZoneProcessorMoreTest.ino +++ b/tests/ExtendedZoneProcessorMoreTest/ExtendedZoneProcessorMoreTest.ino @@ -83,10 +83,10 @@ test(ExtendedZoneProcessorTest, kZoneAmerica_Los_Angeles_outOfBounds) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/ExtendedZoneProcessorTest/ExtendedZoneProcessorTest.ino b/tests/ExtendedZoneProcessorTest/ExtendedZoneProcessorTest.ino index 5f304f873..35eb381bf 100644 --- a/tests/ExtendedZoneProcessorTest/ExtendedZoneProcessorTest.ino +++ b/tests/ExtendedZoneProcessorTest/ExtendedZoneProcessorTest.ino @@ -747,10 +747,10 @@ test(ExtendedZoneProcessorTest, setZoneInfo) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only #if 0 TestRunner::exclude("*"); diff --git a/tests/ExtendedZoneRegistrarTest/ExtendedZoneRegistrarTest.ino b/tests/ExtendedZoneRegistrarTest/ExtendedZoneRegistrarTest.ino index 970904383..83e33d7bb 100644 --- a/tests/ExtendedZoneRegistrarTest/ExtendedZoneRegistrarTest.ino +++ b/tests/ExtendedZoneRegistrarTest/ExtendedZoneRegistrarTest.ino @@ -70,10 +70,10 @@ test(ExtendedZoneRegistrarTest, getZoneInfoForId_not_found) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/HardwareTest/HardwareTest.ino b/tests/HardwareTest/HardwareTest.ino index 0434a51fc..dee13936f 100644 --- a/tests/HardwareTest/HardwareTest.ino +++ b/tests/HardwareTest/HardwareTest.ino @@ -82,10 +82,10 @@ test(dateTimeEqual) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/LocalDateTest/LocalDateTest.ino b/tests/LocalDateTest/LocalDateTest.ino index a87b4a3a4..528b81553 100644 --- a/tests/LocalDateTest/LocalDateTest.ino +++ b/tests/LocalDateTest/LocalDateTest.ino @@ -445,10 +445,10 @@ test(LocalDateTest, decrementOneDay_error) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/LocalDateTimeTest/LocalDateTimeTest.ino b/tests/LocalDateTimeTest/LocalDateTimeTest.ino index bb98e412a..b5342dd71 100644 --- a/tests/LocalDateTimeTest/LocalDateTimeTest.ino +++ b/tests/LocalDateTimeTest/LocalDateTimeTest.ino @@ -311,10 +311,10 @@ test(LocalDateTimeTest, forDateString_errors) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/LocalTimeTest/LocalTimeTest.ino b/tests/LocalTimeTest/LocalTimeTest.ino index a51daf266..5b8a2a5ae 100644 --- a/tests/LocalTimeTest/LocalTimeTest.ino +++ b/tests/LocalTimeTest/LocalTimeTest.ino @@ -102,10 +102,10 @@ test(LocalTimeTest, fortimeString_invalid) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/OffsetDateTimeTest/OffsetDateTimeTest.ino b/tests/OffsetDateTimeTest/OffsetDateTimeTest.ino index c5745c81e..6543bea66 100644 --- a/tests/OffsetDateTimeTest/OffsetDateTimeTest.ino +++ b/tests/OffsetDateTimeTest/OffsetDateTimeTest.ino @@ -389,10 +389,10 @@ test(OffsetDateTimeTest, forDateString_errors) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/SystemClockTest/SystemClockTest.ino b/tests/SystemClockTest/SystemClockTest.ino index a305bc937..007ebbda0 100644 --- a/tests/SystemClockTest/SystemClockTest.ino +++ b/tests/SystemClockTest/SystemClockTest.ino @@ -213,10 +213,10 @@ testF(SystemClockSyncCoroutineTest, sync) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/TimeOffsetTest/TimeOffsetTest.ino b/tests/TimeOffsetTest/TimeOffsetTest.ino index fd9dfa3e4..d4f7bd3c4 100644 --- a/tests/TimeOffsetTest/TimeOffsetTest.ino +++ b/tests/TimeOffsetTest/TimeOffsetTest.ino @@ -136,10 +136,10 @@ test(TimeOffsetMutationTest, increment15Minutes) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/TimePeriodTest/TimePeriodTest.ino b/tests/TimePeriodTest/TimePeriodTest.ino index fd54f0a21..d2340842a 100644 --- a/tests/TimePeriodTest/TimePeriodTest.ino +++ b/tests/TimePeriodTest/TimePeriodTest.ino @@ -101,10 +101,10 @@ test(TimePeriodTest, negate) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/TimeZoneExtendedTest/TimeZoneExtendedTest.ino b/tests/TimeZoneExtendedTest/TimeZoneExtendedTest.ino index ed9242f4c..3273ed30f 100644 --- a/tests/TimeZoneExtendedTest/TimeZoneExtendedTest.ino +++ b/tests/TimeZoneExtendedTest/TimeZoneExtendedTest.ino @@ -39,7 +39,7 @@ test(TimeZoneExtendedTest, createFor) { assertTrue(a == aa); assertTrue(b == bb); - assertEqual(0x1e2a7654U, bb.getZoneId()); + assertEqual((uint32_t) 0x1e2a7654, bb.getZoneId()); } test(TimeZoneExtendedTest, Los_Angeles) { @@ -73,10 +73,10 @@ test(TimeZoneExtendedTest, Los_Angeles) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/TimeZoneTest/TimeZoneTest.ino b/tests/TimeZoneTest/TimeZoneTest.ino index d7ff158da..48b7347d5 100644 --- a/tests/TimeZoneTest/TimeZoneTest.ino +++ b/tests/TimeZoneTest/TimeZoneTest.ino @@ -340,10 +340,10 @@ test(TimeZoneTest, operatorEqualEqual_directZone) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/TransitionStorageTest/TransitionStorageTest.ino b/tests/TransitionStorageTest/TransitionStorageTest.ino index 25a49958c..6e4938c94 100644 --- a/tests/TransitionStorageTest/TransitionStorageTest.ino +++ b/tests/TransitionStorageTest/TransitionStorageTest.ino @@ -280,10 +280,10 @@ test(TransitionStorageTest, resetCandidatePool) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/ZoneProcessorCacheTest/ZoneProcessorCacheTest.ino b/tests/ZoneProcessorCacheTest/ZoneProcessorCacheTest.ino index 9d1be6284..bceb3e994 100644 --- a/tests/ZoneProcessorCacheTest/ZoneProcessorCacheTest.ino +++ b/tests/ZoneProcessorCacheTest/ZoneProcessorCacheTest.ino @@ -58,10 +58,10 @@ test(ExtendedZoneProcessorCacheTest, getZoneProcessor) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/ZonedDateTimeBasicTest/ZonedDateTimeBasicTest.ino b/tests/ZonedDateTimeBasicTest/ZonedDateTimeBasicTest.ino index 5559030a8..34236fbcb 100644 --- a/tests/ZonedDateTimeBasicTest/ZonedDateTimeBasicTest.ino +++ b/tests/ZonedDateTimeBasicTest/ZonedDateTimeBasicTest.ino @@ -117,10 +117,10 @@ test(ZonedDateTimeBasicTest, linked_zones) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/ZonedDateTimeExtendedTest/ZonedDateTimeExtendedTest.ino b/tests/ZonedDateTimeExtendedTest/ZonedDateTimeExtendedTest.ino index 5a1797703..473d7ad39 100644 --- a/tests/ZonedDateTimeExtendedTest/ZonedDateTimeExtendedTest.ino +++ b/tests/ZonedDateTimeExtendedTest/ZonedDateTimeExtendedTest.ino @@ -118,10 +118,10 @@ test(ZonedDateTimeExtendedTest, linked_zones) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/ZonedDateTimeTest/ZonedDateTimeTest.ino b/tests/ZonedDateTimeTest/ZonedDateTimeTest.ino index d6491503e..87e6373ca 100644 --- a/tests/ZonedDateTimeTest/ZonedDateTimeTest.ino +++ b/tests/ZonedDateTimeTest/ZonedDateTimeTest.ino @@ -283,10 +283,10 @@ test(DateTimeMutationTest, increment) { void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only } void loop() { diff --git a/tests/validation/BasicValidationUsingJavaTest/BasicValidationUsingJavaTest.ino b/tests/validation/BasicValidationUsingJavaTest/BasicValidationUsingJavaTest.ino index 244c72f5d..0d9b5b2ea 100644 --- a/tests/validation/BasicValidationUsingJavaTest/BasicValidationUsingJavaTest.ino +++ b/tests/validation/BasicValidationUsingJavaTest/BasicValidationUsingJavaTest.ino @@ -16,10 +16,10 @@ using namespace ace_time; void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only #if 0 TestRunner::exclude("*"); diff --git a/tests/validation/BasicValidationUsingPythonTest/BasicValidationUsingPythonTest.ino b/tests/validation/BasicValidationUsingPythonTest/BasicValidationUsingPythonTest.ino index 8555984af..797d2d631 100644 --- a/tests/validation/BasicValidationUsingPythonTest/BasicValidationUsingPythonTest.ino +++ b/tests/validation/BasicValidationUsingPythonTest/BasicValidationUsingPythonTest.ino @@ -16,10 +16,10 @@ using namespace ace_time; void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only #if 0 TestRunner::exclude("*"); diff --git a/tests/validation/ExtendedValidationUsingJavaTest/ExtendedValidationUsingJavaTest.ino b/tests/validation/ExtendedValidationUsingJavaTest/ExtendedValidationUsingJavaTest.ino index d3bc971f9..815c45d50 100644 --- a/tests/validation/ExtendedValidationUsingJavaTest/ExtendedValidationUsingJavaTest.ino +++ b/tests/validation/ExtendedValidationUsingJavaTest/ExtendedValidationUsingJavaTest.ino @@ -16,10 +16,10 @@ using namespace ace_time; void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only #if 0 TestRunner::exclude("*"); diff --git a/tests/validation/ExtendedValidationUsingPythonTest/ExtendedValidationUsingPythonTest.ino b/tests/validation/ExtendedValidationUsingPythonTest/ExtendedValidationUsingPythonTest.ino index 0f453b1ab..ea1ff96bf 100644 --- a/tests/validation/ExtendedValidationUsingPythonTest/ExtendedValidationUsingPythonTest.ino +++ b/tests/validation/ExtendedValidationUsingPythonTest/ExtendedValidationUsingPythonTest.ino @@ -16,10 +16,10 @@ using namespace ace_time; void setup() { #if defined(ARDUINO) - delay(1000); // wait for stability on some boards to prevent garbage Serial + delay(1000); // wait for stability on some boards to prevent garbage SERIAL_PORT_MONITOR #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while(!Serial); // for the Arduino Leonardo/Micro only + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while(!SERIAL_PORT_MONITOR); // for the Arduino Leonardo/Micro only #if 0 TestRunner::exclude("*"); From 612997bffbe1c884ee28934615890beb790ad664 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 14:57:30 -0700 Subject: [PATCH 08/35] examples: Support Arduino Zero (SAMD21) by using SERIAL_PORT_MONITOR; some still broken since SAMD21 has no EEPROM --- examples/AutoBenchmark/AutoBenchmark.ino | 112 +++++++++--------- examples/AutoBenchmark/Benchmark.cpp | 92 +++++++------- .../CommandLineClock/CommandLineClock.ino | 18 +-- examples/ComparisonBenchmark/Benchmark.cpp | 54 +++++---- .../ComparisonBenchmark.ino | 4 +- examples/CrcEepromDemo/CrcEepromDemo.ino | 26 ++-- examples/HelloDateTime/HelloDateTime.ino | 4 +- .../HelloSystemClockCoroutine.ino | 10 +- examples/OledClock/Controller.h | 28 ++--- examples/OledClock/OledClock.ino | 22 ++-- examples/OledClock/Presenter.h | 6 +- examples/OledClock/config.h | 2 +- examples/WorldClock/WorldClock.ino | 10 +- tests/auniter.ini | 10 ++ 14 files changed, 207 insertions(+), 191 deletions(-) diff --git a/examples/AutoBenchmark/AutoBenchmark.ino b/examples/AutoBenchmark/AutoBenchmark.ino index 0f934dc81..18179e7f5 100644 --- a/examples/AutoBenchmark/AutoBenchmark.ino +++ b/examples/AutoBenchmark/AutoBenchmark.ino @@ -16,99 +16,99 @@ void setup() { delay(1000); #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while (!Serial); // Wait until Serial is ready - Leonardo/Micro + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro // ace_time primitives - Serial.print(F("sizeof(LocalDate): ")); - Serial.println(sizeof(LocalDate)); + SERIAL_PORT_MONITOR.print(F("sizeof(LocalDate): ")); + SERIAL_PORT_MONITOR.println(sizeof(LocalDate)); - Serial.print(F("sizeof(LocalTime): ")); - Serial.println(sizeof(LocalTime)); + SERIAL_PORT_MONITOR.print(F("sizeof(LocalTime): ")); + SERIAL_PORT_MONITOR.println(sizeof(LocalTime)); - Serial.print(F("sizeof(LocalDateTime): ")); - Serial.println(sizeof(LocalDateTime)); + SERIAL_PORT_MONITOR.print(F("sizeof(LocalDateTime): ")); + SERIAL_PORT_MONITOR.println(sizeof(LocalDateTime)); - Serial.print(F("sizeof(TimeOffset): ")); - Serial.println(sizeof(TimeOffset)); + SERIAL_PORT_MONITOR.print(F("sizeof(TimeOffset): ")); + SERIAL_PORT_MONITOR.println(sizeof(TimeOffset)); - Serial.print(F("sizeof(OffsetDateTime): ")); - Serial.println(sizeof(OffsetDateTime)); + SERIAL_PORT_MONITOR.print(F("sizeof(OffsetDateTime): ")); + SERIAL_PORT_MONITOR.println(sizeof(OffsetDateTime)); - Serial.print(F("sizeof(BasicZoneProcessor): ")); - Serial.println(sizeof(BasicZoneProcessor)); + SERIAL_PORT_MONITOR.print(F("sizeof(BasicZoneProcessor): ")); + SERIAL_PORT_MONITOR.println(sizeof(BasicZoneProcessor)); - Serial.print(F("sizeof(ExtendedZoneProcessor): ")); - Serial.println(sizeof(ExtendedZoneProcessor)); + SERIAL_PORT_MONITOR.print(F("sizeof(ExtendedZoneProcessor): ")); + SERIAL_PORT_MONITOR.println(sizeof(ExtendedZoneProcessor)); - Serial.print(F("sizeof(BasicZoneRegistrar): ")); - Serial.println(sizeof(BasicZoneRegistrar)); + SERIAL_PORT_MONITOR.print(F("sizeof(BasicZoneRegistrar): ")); + SERIAL_PORT_MONITOR.println(sizeof(BasicZoneRegistrar)); - Serial.print(F("sizeof(ExtendedZoneRegistrar): ")); - Serial.println(sizeof(ExtendedZoneRegistrar)); + SERIAL_PORT_MONITOR.print(F("sizeof(ExtendedZoneRegistrar): ")); + SERIAL_PORT_MONITOR.println(sizeof(ExtendedZoneRegistrar)); - Serial.print(F("sizeof(BasicZoneManager<1>): ")); - Serial.println(sizeof(BasicZoneManager<1>)); + SERIAL_PORT_MONITOR.print(F("sizeof(BasicZoneManager<1>): ")); + SERIAL_PORT_MONITOR.println(sizeof(BasicZoneManager<1>)); - Serial.print(F("sizeof(ExtendedZoneManager<1>): ")); - Serial.println(sizeof(ExtendedZoneManager<1>)); + SERIAL_PORT_MONITOR.print(F("sizeof(ExtendedZoneManager<1>): ")); + SERIAL_PORT_MONITOR.println(sizeof(ExtendedZoneManager<1>)); - Serial.print(F("sizeof(TimeZone): ")); - Serial.println(sizeof(TimeZone)); + SERIAL_PORT_MONITOR.print(F("sizeof(TimeZone): ")); + SERIAL_PORT_MONITOR.println(sizeof(TimeZone)); - Serial.print(F("sizeof(ZonedDateTime): ")); - Serial.println(sizeof(ZonedDateTime)); + SERIAL_PORT_MONITOR.print(F("sizeof(ZonedDateTime): ")); + SERIAL_PORT_MONITOR.println(sizeof(ZonedDateTime)); - Serial.print(F("sizeof(TimePeriod): ")); - Serial.println(sizeof(TimePeriod)); + SERIAL_PORT_MONITOR.print(F("sizeof(TimePeriod): ")); + SERIAL_PORT_MONITOR.println(sizeof(TimePeriod)); // ace_time::clock classes - Serial.print(F("sizeof(clock::SystemClock): ")); - Serial.println(sizeof(clock::SystemClock)); + SERIAL_PORT_MONITOR.print(F("sizeof(clock::SystemClock): ")); + SERIAL_PORT_MONITOR.println(sizeof(clock::SystemClock)); #ifdef ARDUINO - Serial.print(F("sizeof(clock::DS3231TimeKeeper): ")); - Serial.println(sizeof(clock::DS3231TimeKeeper)); + SERIAL_PORT_MONITOR.print(F("sizeof(clock::DS3231TimeKeeper): ")); + SERIAL_PORT_MONITOR.println(sizeof(clock::DS3231TimeKeeper)); #if defined(ESP8266) || defined(ESP32) - Serial.print(F("sizeof(clock::NtpTimeProvider): ")); - Serial.println(sizeof(clock::NtpTimeProvider)); + SERIAL_PORT_MONITOR.print(F("sizeof(clock::NtpTimeProvider): ")); + SERIAL_PORT_MONITOR.println(sizeof(clock::NtpTimeProvider)); #endif #endif - Serial.print(F("sizeof(clock::SystemClockSyncLoop): ")); - Serial.println(sizeof(clock::SystemClockSyncLoop)); + SERIAL_PORT_MONITOR.print(F("sizeof(clock::SystemClockSyncLoop): ")); + SERIAL_PORT_MONITOR.println(sizeof(clock::SystemClockSyncLoop)); - Serial.print(F("sizeof(clock::SystemClockSyncCoroutine): ")); - Serial.println(sizeof(clock::SystemClockSyncCoroutine)); + SERIAL_PORT_MONITOR.print(F("sizeof(clock::SystemClockSyncCoroutine): ")); + SERIAL_PORT_MONITOR.println(sizeof(clock::SystemClockSyncCoroutine)); // ace_time::basic and ace_time::extended classes - Serial.print(F("sizeof(basic::ZoneContext): ")); - Serial.println(sizeof(basic::ZoneContext)); + SERIAL_PORT_MONITOR.print(F("sizeof(basic::ZoneContext): ")); + SERIAL_PORT_MONITOR.println(sizeof(basic::ZoneContext)); - Serial.print(F("sizeof(basic::ZoneEra): ")); - Serial.println(sizeof(basic::ZoneEra)); + SERIAL_PORT_MONITOR.print(F("sizeof(basic::ZoneEra): ")); + SERIAL_PORT_MONITOR.println(sizeof(basic::ZoneEra)); - Serial.print(F("sizeof(basic::ZoneInfo): ")); - Serial.println(sizeof(basic::ZoneInfo)); + SERIAL_PORT_MONITOR.print(F("sizeof(basic::ZoneInfo): ")); + SERIAL_PORT_MONITOR.println(sizeof(basic::ZoneInfo)); - Serial.print(F("sizeof(basic::ZoneRule): ")); - Serial.println(sizeof(basic::ZoneRule)); + SERIAL_PORT_MONITOR.print(F("sizeof(basic::ZoneRule): ")); + SERIAL_PORT_MONITOR.println(sizeof(basic::ZoneRule)); - Serial.print(F("sizeof(basic::ZonePolicy): ")); - Serial.println(sizeof(basic::ZonePolicy)); + SERIAL_PORT_MONITOR.print(F("sizeof(basic::ZonePolicy): ")); + SERIAL_PORT_MONITOR.println(sizeof(basic::ZonePolicy)); - Serial.print(F("sizeof(basic::Transition): ")); - Serial.println(sizeof(basic::Transition)); + SERIAL_PORT_MONITOR.print(F("sizeof(basic::Transition): ")); + SERIAL_PORT_MONITOR.println(sizeof(basic::Transition)); - Serial.print(F("sizeof(extended::Transition): ")); - Serial.println(sizeof(extended::Transition)); + SERIAL_PORT_MONITOR.print(F("sizeof(extended::Transition): ")); + SERIAL_PORT_MONITOR.println(sizeof(extended::Transition)); - Serial.print(F("sizeof(extended::ZoneMatch): ")); - Serial.println(sizeof(extended::ZoneMatch)); + SERIAL_PORT_MONITOR.print(F("sizeof(extended::ZoneMatch): ")); + SERIAL_PORT_MONITOR.println(sizeof(extended::ZoneMatch)); runBenchmarks(); #ifndef ARDUINO diff --git a/examples/AutoBenchmark/Benchmark.cpp b/examples/AutoBenchmark/Benchmark.cpp index f331896a7..d6b12754d 100644 --- a/examples/AutoBenchmark/Benchmark.cpp +++ b/examples/AutoBenchmark/Benchmark.cpp @@ -7,8 +7,10 @@ using namespace ace_time; using ace_time::common::printPad3; -#if defined(AVR) +#if defined(ARDUINO_ARCH_AVR) const uint32_t COUNT = 2500; +#elif defined(ARDUINO_ARCH_SAMD) +const uint32_t COUNT = 10000; #elif defined(ESP8266) const uint32_t COUNT = 10000; #elif defined(ESP32) @@ -16,9 +18,11 @@ const uint32_t COUNT = 100000; #elif defined(TEENSYDUINO) const uint32_t COUNT = 100000; #elif !defined(ARDUINO) +// Linux or MacOS const uint32_t COUNT = 100000; #else - #error Unsupported platform +// A generic Arduino board that we have not looked at. +const uint32_t COUNT = 10000; #endif const uint32_t MILLIS_TO_NANO_PER_ITERATION = ((uint32_t) 1000000 / COUNT); @@ -133,16 +137,16 @@ unsigned long runLambda(uint32_t count, F&& lambda) { } void printPad3(uint16_t val, char padChar) { - if (val < 100) Serial.print(padChar); - if (val < 10) Serial.print(padChar); - Serial.print(val); + if (val < 100) SERIAL_PORT_MONITOR.print(padChar); + if (val < 10) SERIAL_PORT_MONITOR.print(padChar); + SERIAL_PORT_MONITOR.print(val); } void printPad4(uint16_t val, char padChar) { - if (val < 1000) Serial.print(padChar); - if (val < 100) Serial.print(padChar); - if (val < 10) Serial.print(padChar); - Serial.print(val); + if (val < 1000) SERIAL_PORT_MONITOR.print(padChar); + if (val < 100) SERIAL_PORT_MONITOR.print(padChar); + if (val < 10) SERIAL_PORT_MONITOR.print(padChar); + SERIAL_PORT_MONITOR.print(val); } // Given total elapsed time in millis, print micros per iteration as a floating @@ -154,14 +158,14 @@ void printPad4(uint16_t val, char padChar) { // occurs. static void printMicrosPerIteration(long elapsedMillis) { if (elapsedMillis < 0) { - Serial.print(F(" -0.000")); + SERIAL_PORT_MONITOR.print(F(" -0.000")); return; } unsigned long nanos = elapsedMillis * MILLIS_TO_NANO_PER_ITERATION; uint16_t whole = nanos / 1000; uint16_t frac = nanos % 1000; printPad4(whole, ' '); - Serial.print('.'); + SERIAL_PORT_MONITOR.print('.'); printPad3(frac, '0'); } @@ -170,9 +174,9 @@ static void runEmptyLoop() { unsigned long tickMillis = millis(); disableOptimization(tickMillis); }); - Serial.print(FPSTR(EMPTY_LOOP_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(EMPTY_LOOP_LABEL)); printMicrosPerIteration(emptyLoopMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // LocalDate::forEpochDays() @@ -188,9 +192,9 @@ static void runLocalDateForEpochDays() { }); long elapsedMillis = localDateForDaysMillis - emptyLoopMillis; - Serial.print(FPSTR(LOCAL_DATE_FOR_EPOCH_DAYS_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(LOCAL_DATE_FOR_EPOCH_DAYS_LABEL)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // LocalDate::toEpochDays() @@ -208,9 +212,9 @@ static void runLocalDateToEpochDays() { }); long elapsedMillis = localDateToEpochDaysMillis - forEpochDaysMillis; - Serial.print(FPSTR(LOCAL_DATE_TO_EPOCH_DAYS_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(LOCAL_DATE_TO_EPOCH_DAYS_LABEL)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // LocalDate::dayOfWeek() @@ -229,9 +233,9 @@ static void runLocalDateDaysOfWeek() { }); long elapsedMillis = localDateDayOfWeekMillis - forEpochDaysMillis; - Serial.print(FPSTR(LOCAL_DATE_DAY_OF_WEEK_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(LOCAL_DATE_DAY_OF_WEEK_LABEL)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // OffsetDateTime::forEpochSeconds() @@ -248,9 +252,9 @@ static void runOffsetDateTimeForEpochSeconds() { }); long elapsedMillis = localDateForDaysMillis - emptyLoopMillis; - Serial.print(FPSTR(OFFSET_DATE_TIME_FOR_EPOCH_SECONDS_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(OFFSET_DATE_TIME_FOR_EPOCH_SECONDS_LABEL)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // OffsetDateTime::toEpochSeconds() @@ -270,9 +274,9 @@ static void runOffsetDateTimeToEpochSeconds() { }); long elapsedMillis = localDateToEpochDaysMillis - forEpochDaysMillis; - Serial.print(FPSTR(OFFSET_DATE_TIME_TO_EPOCH_SECONDS_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(OFFSET_DATE_TIME_TO_EPOCH_SECONDS_LABEL)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // ZonedDateTime::forEpochSeconds(seconds) @@ -289,9 +293,9 @@ static void runZonedDateTimeForEpochSeconds() { }); long elapsedMillis = forEpochSecondsMillis - emptyLoopMillis; - Serial.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_LABEL)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // ZonedDateTime::toEpochDays() @@ -311,9 +315,9 @@ static void runZonedDateTimeToEpochDays() { }); long elapsedMillis = toEpochDaysMillis - forEpochSecondsMillis; - Serial.print(FPSTR(DATE_TIME_TO_EPOCH_DAYS_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(DATE_TIME_TO_EPOCH_DAYS_LABEL)); printMicrosPerIteration(elapsedMillis < 0 ? 0 : elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // ZonedDateTime::toEpochSeconds() @@ -333,9 +337,9 @@ static void runZonedDateTimeToEpochSeconds() { }); long elapsedMillis = toEpochSecondsMillis - forEpochSecondsMillis; - Serial.print(FPSTR(DATE_TIME_TO_EPOCH_SECONDS_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(DATE_TIME_TO_EPOCH_SECONDS_LABEL)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } static const acetime_t kTwoYears = 2 * 365 * 24 * 3600L; @@ -370,9 +374,9 @@ static void runZonedDateTimeForEpochSecondsBasicZoneManager() { }); long elapsedMillis = forEpochSecondsMillis - emptyLoopMillis; - Serial.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_BASIC_NO_CACHE)); + SERIAL_PORT_MONITOR.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_BASIC_NO_CACHE)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // ZonedDateTime::forEpochSeconds(seconds, tz) cached @@ -393,9 +397,9 @@ static void runZonedDateTimeForEpochSecondsBasicZoneManagerCached() { }); long elapsedMillis = forEpochSecondsMillis - emptyLoopMillis; - Serial.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_BASIC_CACHED)); + SERIAL_PORT_MONITOR.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_BASIC_CACHED)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } static const extended::ZoneInfo* const kExtendedZoneRegistry[] @@ -430,9 +434,9 @@ static void runZonedDateTimeForEpochSecondsExtendedZoneManager() { }); long elapsedMillis = forEpochSecondsMillis - emptyLoopMillis; - Serial.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_EXTENDED_NO_CACHE)); + SERIAL_PORT_MONITOR.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_EXTENDED_NO_CACHE)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } // ZonedDateTime::forEpochSeconds(seconds, tz) cached ExtendedZoneManager @@ -454,18 +458,18 @@ static void runZonedDateTimeForEpochSecondsExtendedZoneManagerCached() { }); long elapsedMillis = forEpochSecondsMillis - emptyLoopMillis; - Serial.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_EXTENDED_CACHED)); + SERIAL_PORT_MONITOR.print(FPSTR(DATE_TIME_FOR_EPOCH_SECONDS_EXTENDED_CACHED)); printMicrosPerIteration(elapsedMillis); - Serial.println(FPSTR(COL_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(COL_DIVIDER)); } void runBenchmarks() { - Serial.println(FPSTR(TOP)); - Serial.println(FPSTR(HEADER)); - Serial.println(FPSTR(ROW_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(TOP)); + SERIAL_PORT_MONITOR.println(FPSTR(HEADER)); + SERIAL_PORT_MONITOR.println(FPSTR(ROW_DIVIDER)); runEmptyLoop(); - Serial.println(FPSTR(ROW_DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(ROW_DIVIDER)); runLocalDateForEpochDays(); runLocalDateToEpochDays(); @@ -483,8 +487,8 @@ void runBenchmarks() { runZonedDateTimeForEpochSecondsExtendedZoneManager(); runZonedDateTimeForEpochSecondsExtendedZoneManagerCached(); - Serial.println(FPSTR(BOTTOM)); + SERIAL_PORT_MONITOR.println(FPSTR(BOTTOM)); - Serial.print(F("Number of iterations per run: ")); - Serial.println(COUNT); + SERIAL_PORT_MONITOR.print(F("Number of iterations per run: ")); + SERIAL_PORT_MONITOR.println(COUNT); } diff --git a/examples/CommandLineClock/CommandLineClock.ino b/examples/CommandLineClock/CommandLineClock.ino index 94d1fe024..febdb4d13 100644 --- a/examples/CommandLineClock/CommandLineClock.ino +++ b/examples/CommandLineClock/CommandLineClock.ino @@ -1,5 +1,5 @@ /* - * A simple command line (i.e. ascii clock using the Serial line. Useful for + * A simple command line (i.e. ascii clock using the SERIAL_PORT_MONITOR line. Useful for * debugging. Requires no additional hardware in the simple case. Optionally * depends on the DS3231 RTC chip, or an NTP client. * @@ -384,7 +384,7 @@ uint8_t const NUM_COMMANDS = sizeof(COMMANDS) / sizeof(CommandHandler*); uint8_t const BUF_SIZE = 64; uint8_t const ARGV_SIZE = 5; CommandManager commandManager( - COMMANDS, NUM_COMMANDS, Serial, "> "); + COMMANDS, NUM_COMMANDS, SERIAL_PORT_MONITOR, "> "); //--------------------------------------------------------------------------- // Main setup and loop @@ -392,7 +392,7 @@ CommandManager commandManager( void setup() { // Wait for stability on some boards. - // 1000ms needed for Serial. + // 1000ms needed for SERIAL_PORT_MONITOR. // 2000ms needed for Wire, I2C or SSD1306 (don't know which one). delay(2000); @@ -401,12 +401,12 @@ void setup() { TXLED0; // LED off #endif - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while (!Serial); // Wait until Serial is ready - Leonardo/Micro - Serial.println(F("setup(): begin")); + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro + SERIAL_PORT_MONITOR.println(F("setup(): begin")); - Serial.print(F("sizeof(StoredInfo): ")); - Serial.println(sizeof(StoredInfo)); + SERIAL_PORT_MONITOR.print(F("sizeof(StoredInfo): ")); + SERIAL_PORT_MONITOR.println(sizeof(StoredInfo)); Wire.begin(); Wire.setClock(400000L); @@ -435,7 +435,7 @@ void setup() { commandManager.setupCoroutine(F("commandManager")); CoroutineScheduler::setup(); - Serial.println(F("setup(): end")); + SERIAL_PORT_MONITOR.println(F("setup(): end")); } void loop() { diff --git a/examples/ComparisonBenchmark/Benchmark.cpp b/examples/ComparisonBenchmark/Benchmark.cpp index da4157741..683167e44 100644 --- a/examples/ComparisonBenchmark/Benchmark.cpp +++ b/examples/ComparisonBenchmark/Benchmark.cpp @@ -16,8 +16,10 @@ using namespace ace_time; -#if defined(AVR) +#if defined(ARDUINO_ARCH_AVR) const uint32_t COUNT = 2000; +#elif defined(ARDUINO_ARCH_SAMD) +const uint32_t COUNT = 10000; #elif defined(ESP8266) const uint32_t COUNT = 10000; #elif defined(ESP32) || defined(TEENSYDUINO) @@ -114,9 +116,9 @@ unsigned long runLambda(acetime_t startSeconds, F&& lambda) { } void printPad3(uint16_t val, char padChar) { - if (val < 100) Serial.print(padChar); - if (val < 10) Serial.print(padChar); - Serial.print(val); + if (val < 100) SERIAL_PORT_MONITOR.print(padChar); + if (val < 10) SERIAL_PORT_MONITOR.print(padChar); + SERIAL_PORT_MONITOR.print(val); } const uint32_t MILLIS_TO_NANO_PER_ITERATION = ( 1000000 / COUNT); @@ -130,14 +132,14 @@ const uint32_t MILLIS_TO_NANO_PER_ITERATION = ( 1000000 / COUNT); // occurs. void printMicrosPerIteration(long elapsedMillis) { if (elapsedMillis < 0) { - Serial.print(F(" -0.000")); + SERIAL_PORT_MONITOR.print(F(" -0.000")); return; } unsigned long nanos = elapsedMillis * MILLIS_TO_NANO_PER_ITERATION; uint16_t whole = nanos / 1000; uint16_t frac = nanos % 1000; printPad3(whole, ' '); - Serial.print('.'); + SERIAL_PORT_MONITOR.print('.'); printPad3(frac, '0'); } @@ -147,9 +149,9 @@ void runEmptyLoop() { disableOptimization(seconds); }); - Serial.print(FPSTR(EMPTY_LOOP_LABEL)); + SERIAL_PORT_MONITOR.print(FPSTR(EMPTY_LOOP_LABEL)); printMicrosPerIteration(baseMillis); - Serial.println(FPSTR(ENDING)); + SERIAL_PORT_MONITOR.println(FPSTR(ENDING)); } // AceTime library: LocalDateTime::forEpochSeconds() @@ -162,9 +164,9 @@ void runAceTimeForEpochSeconds() { disableOptimization(seconds); }); - Serial.print(FPSTR(ACE_TIME_FOR_EPOCH_SECONDS)); + SERIAL_PORT_MONITOR.print(FPSTR(ACE_TIME_FOR_EPOCH_SECONDS)); printMicrosPerIteration(elapsedMillis - baseMillis); - Serial.println(FPSTR(ENDING)); + SERIAL_PORT_MONITOR.println(FPSTR(ENDING)); } // AceTime library: LocalDateTime::toEpochSeconds() @@ -179,9 +181,9 @@ void runAceTimeToEpochSeconds() { disableOptimization(dt); }); - Serial.print(FPSTR(ACE_TIME_TO_EPOCH_SECONDS)); + SERIAL_PORT_MONITOR.print(FPSTR(ACE_TIME_TO_EPOCH_SECONDS)); printMicrosPerIteration(elapsedMillis - baseMillis); - Serial.println(FPSTR(ENDING)); + SERIAL_PORT_MONITOR.println(FPSTR(ENDING)); } // Time library: breakTime() @@ -197,9 +199,9 @@ void runTimeLibBreakTime() { disableOptimization(seconds); }); - Serial.print(FPSTR(ARDUINO_TIME_BREAK_TIME)); + SERIAL_PORT_MONITOR.print(FPSTR(ARDUINO_TIME_BREAK_TIME)); printMicrosPerIteration(elapsedMillis - baseMillis); - Serial.println(FPSTR(ENDING)); + SERIAL_PORT_MONITOR.println(FPSTR(ENDING)); } // Time library: makeTime() @@ -218,30 +220,30 @@ void runTimeLibMakeTime() { disableOptimization(tm); }); - Serial.print(FPSTR(ARDUINO_TIME_MAKE_TIME)); + SERIAL_PORT_MONITOR.print(FPSTR(ARDUINO_TIME_MAKE_TIME)); printMicrosPerIteration(elapsedMillis - baseMillis); - Serial.println(FPSTR(ENDING)); + SERIAL_PORT_MONITOR.println(FPSTR(ENDING)); } void runBenchmarks() { - Serial.println(FPSTR(TOP)); - Serial.println(FPSTR(HEADER)); - Serial.println(FPSTR(DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(TOP)); + SERIAL_PORT_MONITOR.println(FPSTR(HEADER)); + SERIAL_PORT_MONITOR.println(FPSTR(DIVIDER)); runEmptyLoop(); - Serial.println(FPSTR(DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(DIVIDER)); runAceTimeForEpochSeconds(); runTimeLibBreakTime(); - Serial.println(FPSTR(DIVIDER)); + SERIAL_PORT_MONITOR.println(FPSTR(DIVIDER)); runAceTimeToEpochSeconds(); runTimeLibMakeTime(); - Serial.println(FPSTR(BOTTOM)); + SERIAL_PORT_MONITOR.println(FPSTR(BOTTOM)); // Print some stats - Serial.print("Number of iterations per run: "); - Serial.println(COUNT); - Serial.print("Delta seconds: "); - Serial.println(DELTA_SECONDS); + SERIAL_PORT_MONITOR.print("Number of iterations per run: "); + SERIAL_PORT_MONITOR.println(COUNT); + SERIAL_PORT_MONITOR.print("Delta seconds: "); + SERIAL_PORT_MONITOR.println(DELTA_SECONDS); } diff --git a/examples/ComparisonBenchmark/ComparisonBenchmark.ino b/examples/ComparisonBenchmark/ComparisonBenchmark.ino index 30284254f..7a6d636b7 100644 --- a/examples/ComparisonBenchmark/ComparisonBenchmark.ino +++ b/examples/ComparisonBenchmark/ComparisonBenchmark.ino @@ -9,8 +9,8 @@ void setup() { delay(1000); - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while (!Serial); // Wait until Serial is ready - Leonardo/Micro + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro runBenchmarks(); } diff --git a/examples/CrcEepromDemo/CrcEepromDemo.ino b/examples/CrcEepromDemo/CrcEepromDemo.ino index 01bf31441..4be6a19f7 100644 --- a/examples/CrcEepromDemo/CrcEepromDemo.ino +++ b/examples/CrcEepromDemo/CrcEepromDemo.ino @@ -16,31 +16,31 @@ CrcEeprom crcEeprom; void setup() { delay(1000); - Serial.begin(115200); - while (!Serial); + SERIAL_PORT_MONITOR.begin(115200); + while (!SERIAL_PORT_MONITOR); crcEeprom.begin(32); Info info; - Serial.print("Original info: "); - Serial.print("startTime: "); Serial.print(info.startTime); - Serial.print("; interval: "); Serial.println(info.interval); + SERIAL_PORT_MONITOR.print("Original info: "); + SERIAL_PORT_MONITOR.print("startTime: "); SERIAL_PORT_MONITOR.print(info.startTime); + SERIAL_PORT_MONITOR.print("; interval: "); SERIAL_PORT_MONITOR.println(info.interval); - Serial.println("Writing Info struct"); + SERIAL_PORT_MONITOR.println("Writing Info struct"); uint16_t writtenSize = crcEeprom.writeWithCrc(0, &info, sizeof(info)); - Serial.print("Written size: "); Serial.println(writtenSize); + SERIAL_PORT_MONITOR.print("Written size: "); SERIAL_PORT_MONITOR.println(writtenSize); - Serial.println("Clearing info struct"); + SERIAL_PORT_MONITOR.println("Clearing info struct"); info.startTime = 0; info.interval = 0; - Serial.println("Reading back Info struct"); + SERIAL_PORT_MONITOR.println("Reading back Info struct"); bool isValid = crcEeprom.readWithCrc(0, &info, sizeof(info)); - Serial.print("isValid: "); Serial.println(isValid); + SERIAL_PORT_MONITOR.print("isValid: "); SERIAL_PORT_MONITOR.println(isValid); - Serial.print("info: "); - Serial.print("startTime: "); Serial.print(info.startTime); - Serial.print("; interval: "); Serial.println(info.interval); + SERIAL_PORT_MONITOR.print("info: "); + SERIAL_PORT_MONITOR.print("startTime: "); SERIAL_PORT_MONITOR.print(info.startTime); + SERIAL_PORT_MONITOR.print("; interval: "); SERIAL_PORT_MONITOR.println(info.interval); } void loop() {} diff --git a/examples/HelloDateTime/HelloDateTime.ino b/examples/HelloDateTime/HelloDateTime.ino index dead08627..05cc3da07 100644 --- a/examples/HelloDateTime/HelloDateTime.ino +++ b/examples/HelloDateTime/HelloDateTime.ino @@ -1,6 +1,6 @@ /* * A program to demonstrate the use of AceTime classes. It should print the - * following on the Serial port: + * following on the SERIAL_PORT_MONITOR port: * * Epoch Seconds: 605527200 * Unix Seconds: 1552212000 @@ -33,7 +33,7 @@ void setup() { delay(1000); #endif SERIAL_PORT_MONITOR.begin(115200); - while (!SERIAL_PORT_MONITOR); // Wait until Serial is ready - Leonardo/Micro + while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro auto pacificTz = TimeZone::forZoneInfo(&zonedb::kZoneAmerica_Los_Angeles, &pacificProcessor); diff --git a/examples/HelloSystemClockCoroutine/HelloSystemClockCoroutine.ino b/examples/HelloSystemClockCoroutine/HelloSystemClockCoroutine.ino index c7bc04eaf..6cc50e923 100644 --- a/examples/HelloSystemClockCoroutine/HelloSystemClockCoroutine.ino +++ b/examples/HelloSystemClockCoroutine/HelloSystemClockCoroutine.ino @@ -1,6 +1,6 @@ /* * Identical to HelloSystemClock, but using AceRoutine coroutines. - * Should print the following on the Serial port every 2 seconds: + * Should print the following on the SERIAL_PORT_MONITOR port every 2 seconds: * * 2019-06-17T19:50:00-07:00[America/Los_Angeles] * 2019-06-17T19:50:02-07:00[America/Los_Angeles] @@ -28,8 +28,8 @@ SystemClockSyncCoroutine systemClockSyncCoroutine(systemClock); void setup() { delay(1000); - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while (!Serial); // Wait until Serial is ready - Leonardo/Micro + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro systemClock.setup(); @@ -55,8 +55,8 @@ void printCurrentTime() { auto pacificTz = TimeZone::forZoneInfo(&zonedb::kZoneAmerica_Los_Angeles, &pacificProcessor); auto pacificTime = ZonedDateTime::forEpochSeconds(now, pacificTz); - pacificTime.printTo(Serial); - Serial.println(); + pacificTime.printTo(SERIAL_PORT_MONITOR); + SERIAL_PORT_MONITOR.println(); } COROUTINE(print) { diff --git a/examples/OledClock/Controller.h b/examples/OledClock/Controller.h index 10f609a46..4507b2301 100644 --- a/examples/OledClock/Controller.h +++ b/examples/OledClock/Controller.h @@ -80,7 +80,7 @@ class Controller { void modeButtonPress() { #if ENABLE_SERIAL == 1 - Serial.println(F("modeButtonPress()")); + SERIAL_PORT_MONITOR.println(F("modeButtonPress()")); #endif switch (mMode) { // Cycle through the 3 main screens. @@ -133,7 +133,7 @@ class Controller { void modeButtonLongPress() { #if ENABLE_SERIAL == 1 - Serial.println(F("modeButtonLongPress()")); + SERIAL_PORT_MONITOR.println(F("modeButtonLongPress()")); #endif switch (mMode) { case MODE_DATE_TIME: @@ -175,7 +175,7 @@ class Controller { void changeButtonPress() { #if ENABLE_SERIAL == 1 - Serial.println(F("changeButtonPress()")); + SERIAL_PORT_MONITOR.println(F("changeButtonPress()")); #endif switch (mMode) { // Switch 12/24 modes if in MODE_DATA_TIME @@ -357,7 +357,7 @@ class Controller { /** Transfer info from ChangingClockInfo to ClockInfo. */ void saveClockInfo() { #if ENABLE_SERIAL == 1 - Serial.println(F("saveClockInfo()")); + SERIAL_PORT_MONITOR.println(F("saveClockInfo()")); #endif mClockInfo = mChangingClockInfo; preserveClockInfo(mCrcEeprom, mClockInfo); @@ -367,7 +367,7 @@ class Controller { static void preserveClockInfo(hw::CrcEeprom& crcEeprom, const ClockInfo& clockInfo) { #if ENABLE_SERIAL == 1 - Serial.println(F("preserveClockInfo()")); + SERIAL_PORT_MONITOR.println(F("preserveClockInfo()")); #endif StoredInfo storedInfo; storedInfo.hourMode = clockInfo.hourMode; @@ -379,18 +379,18 @@ class Controller { /** Restore clockInfo from storedInfo. */ void restoreClockInfo(ClockInfo& clockInfo, const StoredInfo& storedInfo) { #if ENABLE_SERIAL == 1 - Serial.println(F("restoreClockInfo()")); - Serial.print(F("hourMode: ")); Serial.println(storedInfo.hourMode); - Serial.print(F("type: ")); Serial.println(storedInfo.timeZoneData.type); + SERIAL_PORT_MONITOR.println(F("restoreClockInfo()")); + SERIAL_PORT_MONITOR.print(F("hourMode: ")); SERIAL_PORT_MONITOR.println(storedInfo.hourMode); + SERIAL_PORT_MONITOR.print(F("type: ")); SERIAL_PORT_MONITOR.println(storedInfo.timeZoneData.type); if (storedInfo.type == TimeZoneData::kTypeManual) { - Serial.print(F("std: ")); - Serial.println(storedInfo.timeZoneData.stdOffsetCode); - Serial.print(F("dst: ")); - Serial.println(storedInfo.timeZoneData.dstOffsetCode); + SERIAL_PORT_MONITOR.print(F("std: ")); + SERIAL_PORT_MONITOR.println(storedInfo.timeZoneData.stdOffsetCode); + SERIAL_PORT_MONITOR.print(F("dst: ")); + SERIAL_PORT_MONITOR.println(storedInfo.timeZoneData.dstOffsetCode); } else if (storedInfo.type == TimeZoneData::kTypeZoneId) { - Serial.print(F("zoneId: 0x")); Serial.println(storedInfo.zoneId, 16); + SERIAL_PORT_MONITOR.print(F("zoneId: 0x")); SERIAL_PORT_MONITOR.println(storedInfo.zoneId, 16); } else { - Serial.println(F("")); + SERIAL_PORT_MONITOR.println(F("")); } #endif clockInfo.hourMode = storedInfo.hourMode; diff --git a/examples/OledClock/OledClock.ino b/examples/OledClock/OledClock.ino index 4cb7bdc39..958c346ca 100644 --- a/examples/OledClock/OledClock.ino +++ b/examples/OledClock/OledClock.ino @@ -171,7 +171,7 @@ COROUTINE(checkButton) { void setup() { // Wait for stability on some boards. - // 1000ms needed for Serial. + // 1000ms needed for SERIAL_PORT_MONITOR. // 1500ms needed for Wire, I2C or SSD1306 (don't know which one). delay(2000); @@ -182,15 +182,15 @@ void setup() { #endif #if ENABLE_SERIAL == 1 - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while (!Serial); // Wait until Serial is ready - Leonardo/Micro - Serial.println(F("setup(): begin")); - Serial.print(F("sizeof(ClockInfo): ")); - Serial.println(sizeof(ClockInfo)); - Serial.print(F("sizeof(StoredInfo): ")); - Serial.println(sizeof(StoredInfo)); - Serial.print(F("sizeof(RenderingInfo): ")); - Serial.println(sizeof(RenderingInfo)); + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro + SERIAL_PORT_MONITOR.println(F("setup(): begin")); + SERIAL_PORT_MONITOR.print(F("sizeof(ClockInfo): ")); + SERIAL_PORT_MONITOR.println(sizeof(ClockInfo)); + SERIAL_PORT_MONITOR.print(F("sizeof(StoredInfo): ")); + SERIAL_PORT_MONITOR.println(sizeof(StoredInfo)); + SERIAL_PORT_MONITOR.print(F("sizeof(RenderingInfo): ")); + SERIAL_PORT_MONITOR.println(sizeof(RenderingInfo)); #endif Wire.begin(); @@ -215,7 +215,7 @@ void setup() { CoroutineScheduler::setup(); #if ENABLE_SERIAL == 1 - Serial.println(F("setup(): end")); + SERIAL_PORT_MONITOR.println(F("setup(): end")); #endif } diff --git a/examples/OledClock/Presenter.h b/examples/OledClock/Presenter.h index fc1f4daa3..c573709a4 100644 --- a/examples/OledClock/Presenter.h +++ b/examples/OledClock/Presenter.h @@ -107,7 +107,7 @@ class Presenter { void displayDateTime() const { #if ENABLE_SERIAL == 1 - Serial.println(F("displayDateTime()")); + SERIAL_PORT_MONITOR.println(F("displayDateTime()")); #endif mOled.setFont(fixed_bold10x15); const ZonedDateTime& dateTime = mRenderingInfo.dateTime; @@ -181,7 +181,7 @@ class Presenter { void displayTimeZone() const { #if ENABLE_SERIAL - Serial.println(F("displayTimeZone()")); + SERIAL_PORT_MONITOR.println(F("displayTimeZone()")); #endif mOled.setFont(fixed_bold10x15); @@ -265,7 +265,7 @@ class Presenter { void displayAbout() const { #if ENABLE_SERIAL == 1 - Serial.println(F("displayAbout()")); + SERIAL_PORT_MONITOR.println(F("displayAbout()")); #endif mOled.setFont(SystemFont5x7); diff --git a/examples/OledClock/config.h b/examples/OledClock/config.h index 0b917e91a..9a55c8497 100644 --- a/examples/OledClock/config.h +++ b/examples/OledClock/config.h @@ -9,7 +9,7 @@ #define EEPROM_SIZE 32 -// Set to 1 to print debugging info to Serial +// Set to 1 to print debugging info to SERIAL_PORT_MONITOR #define ENABLE_SERIAL 0 // Set to 1 to force the ClockInfo to its initial state diff --git a/examples/WorldClock/WorldClock.ino b/examples/WorldClock/WorldClock.ino index e783c4ea3..983ca007e 100644 --- a/examples/WorldClock/WorldClock.ino +++ b/examples/WorldClock/WorldClock.ino @@ -194,7 +194,7 @@ COROUTINE(checkButton) { void setup() { // Wait for stability on some boards. - // 1000ms needed for Serial. + // 1000ms needed for SERIAL_PORT_MONITOR. // 1500ms needed for Wire, I2C or SSD1306 (don't know which one). delay(2000); @@ -205,9 +205,9 @@ void setup() { #endif #if ENABLE_SERIAL == 1 - Serial.begin(115200); // ESP8266 default of 74880 not supported on Linux - while (!Serial); // Wait until Serial is ready - Leonardo/Micro - Serial.println(F("setup(): begin")); + SERIAL_PORT_MONITOR.begin(115200); // ESP8266 default of 74880 not supported on Linux + while (!SERIAL_PORT_MONITOR); // Wait until SERIAL_PORT_MONITOR is ready - Leonardo/Micro + SERIAL_PORT_MONITOR.println(F("setup(): begin")); #endif Wire.begin(); @@ -226,7 +226,7 @@ void setup() { CoroutineScheduler::setup(); #if ENABLE_SERIAL == 1 - Serial.println(F("setup(): end")); + SERIAL_PORT_MONITOR.println(F("setup(): end")); #endif } diff --git a/tests/auniter.ini b/tests/auniter.ini index 69c2ee54b..bdfdee21a 100644 --- a/tests/auniter.ini +++ b/tests/auniter.ini @@ -5,6 +5,7 @@ promicro16 = SparkFun:avr:promicro:cpu=16MHzatmega32U4 nodemcuv2 = esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600 esp32 = esp32:esp32:esp32:PartitionScheme=default,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,DebugLevel=none + zero = arduino:samd:arduino_zero_native # Disable ExtendedZoneRegistrarTest since they do not fit in an Uno [env:uno] @@ -27,6 +28,15 @@ preprocessor = -DAUNITER_MICRO exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock +# SAMD M0 Mini. Does not have EEPROM.h, so cannot compile OledClock, WorldClock +# and CommandLineClock. Might be possible later with +# https://github.com/cmaglie/FlashStorage. +[env:zero] + board = zero + locking = false + preprocessor = -DAUNITER_ZERO + exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock|WorldClock|CommandLineClock + # Disable ComparisonBenchmark on ESP8266 due to broken Arduino Time Library. [env:esp8266] board = nodemcuv2 From 32ff04a2f3561d2828b9c536e1a795268a671200 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 16:14:05 -0700 Subject: [PATCH 09/35] USER_GUIDE.md: Add note that SERIAL_MONITOR_PORT is clobbered to be 'SerialUSB' to support Arduino Zero compatible clones --- USER_GUIDE.md | 12 ++++++++++++ src/ace_time/common/flash.h | 8 ++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 9716425ac..4affe8196 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -2577,3 +2577,15 @@ did not think it would fit inside an Arduino controller. is created with a `TimeZone` associated with `kZoneUS_Pacific`, the `ZonedDateTime::printTo()` will print "[America/Los_Angeles]" not "[US/Pacific]". +* Arduino Zero and SAMD21 Clones + * Some amount of support for the Arduino Zero (and other SAMD21 boards) + have been added. The original Arduino Zero has + [2 USB ports](https://www.arduino.cc/en/Guide/ArduinoZero). The + Programming port is connected to `Serial` object and the Native port is + connected to `SerialUSB` object. AceTime assumes that you are always using + the "Native USB Port" on the Arduino Zero, and redefines the + `SERIAL_MONITOR_PORT` macro to be `SerialUSB`. This is the correct setting + on the "Ardunio SAMD21 M0 Mini" clones claiming to be compatible with the + Arduino Zero. However, if you are using a real Arduino Zero, and using the + Programming Port, then you must edit `src/ace_time/common/flash.h` and + comment out the code that clobbers the `SERIAL_MONITOR_PORT` macro. diff --git a/src/ace_time/common/flash.h b/src/ace_time/common/flash.h index 6b8bcb887..ba6b8ac04 100644 --- a/src/ace_time/common/flash.h +++ b/src/ace_time/common/flash.h @@ -33,9 +33,13 @@ // pointer, so map it directly to strcmp() #define acetime_strcmp_P strcmp - // All other SAMD boards define SERIAL_PORT_MONITOR as SerialUSB, except for - // the Zero, which defines it to be Serial, which doesn't work. Clobber it. + // The Arduino Zero using "Native USB Port" uses SerialUSB, but + // SERIAL_PORT_MONITOR continues to point to Serial, which causes nothing to + // appear on the Serial Monitor. Clobber SERIAL_PORT_MONITOR to point to + // SerialUSB. This is the correct setting on the Chinese SAMD21 M0 Mini + // clones which claim to be compatible with the Arduino Zero. #if defined(ARDUINO_SAMD_ZERO) + #warning Setting SERIAL_PORT_MONITOR to SerialUSB #undef SERIAL_PORT_MONITOR #define SERIAL_PORT_MONITOR SerialUSB #endif From 45080793d44ed7a53cb42b3c483634fd44a42615 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 16:20:54 -0700 Subject: [PATCH 10/35] README.md: Add note about some problems with Arduino Zero (SAMD21) type boards --- README.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c721576f2..2678eea8c 100644 --- a/README.md +++ b/README.md @@ -419,7 +419,7 @@ library will work fine under MacOS and Windows, but I have not tested them. ### Hardware -The library is tested on the following hardware before each release: +The library is fully tested on the following boards: * Arduino Nano clone (16 MHz ATmega328P) * SparkFun Pro Micro clone (16 MHz ATmega32U4) @@ -430,6 +430,13 @@ I will occasionally test on the following hardware as a sanity check: * Teensy 3.2 (72 MHz ARM Cortex-M4) +The following boards may have some incompatibilities: + +* Arduino Zero compatible SAMD21 M0 Mini (48 MHz ARM Cortex-M0+) + * All unit tests pass. + * Some sketches in `examples` do not compile because the SAMD21 does + not have an EEPROM. + ## Changelog See [CHANGELOG.md](CHANGELOG.md). From 1b6ea1d4bd0ed2561e3353daf0e1da5b5be14d27 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 16:54:35 -0700 Subject: [PATCH 11/35] src: Fix compile for ESP32 by adding SERIAL_PORT_MONITOR --- src/ace_time/common/flash.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ace_time/common/flash.h b/src/ace_time/common/flash.h index ba6b8ac04..ee782b285 100644 --- a/src/ace_time/common/flash.h +++ b/src/ace_time/common/flash.h @@ -80,6 +80,9 @@ const char* strrchr_P(const char* s, int c); } + // ESP32 does not define SERIAL_PORT_MONITOR + #define SERIAL_PORT_MONITOR Serial + #elif defined(__linux__) or defined(__APPLE__) #include #define FPSTR(p) (reinterpret_cast(p)) From 175adbbebc8cf36b418194aa2e2466bb9f0bdb17 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 16:55:31 -0700 Subject: [PATCH 12/35] AutoBenchmark: Update all benchmarks using new version 0.5 (forgot to update before release); add numbers for SAMD21 Arduino Zero compatible --- examples/AutoBenchmark/README.md | 200 ++++++++++++++++++++----------- 1 file changed, 133 insertions(+), 67 deletions(-) diff --git a/examples/AutoBenchmark/README.md b/examples/AutoBenchmark/README.md index 2353aa2a3..ee9a45eed 100644 --- a/examples/AutoBenchmark/README.md +++ b/examples/AutoBenchmark/README.md @@ -23,19 +23,22 @@ sizeof(LocalTime): 3 sizeof(LocalDateTime): 6 sizeof(TimeOffset): 1 sizeof(OffsetDateTime): 7 -sizeof(ZoneProcessor): 3 sizeof(BasicZoneProcessor): 99 sizeof(ExtendedZoneProcessor): 397 -sizeof(TimeZone): 3 -sizeof(ZonedDateTime): 10 +sizeof(BasicZoneRegistrar): 5 +sizeof(ExtendedZoneRegistrar): 5 +sizeof(BasicZoneManager<1>): 107 +sizeof(ExtendedZoneManager<1>): 405 +sizeof(TimeZone): 5 +sizeof(ZonedDateTime): 12 sizeof(TimePeriod): 4 sizeof(clock::SystemClock): 17 sizeof(clock::DS3231TimeKeeper): 3 -sizeof(clock::SystemClockSyncLoop): 14 -sizeof(clock::SystemClockSyncCoroutine): 31 +sizeof(clock::SystemClockSyncLoop): 10 +sizeof(clock::SystemClockSyncCoroutine): 29 sizeof(basic::ZoneContext): 6 sizeof(basic::ZoneEra): 11 -sizeof(basic::ZoneInfo): 8 +sizeof(basic::ZoneInfo): 12 sizeof(basic::ZoneRule): 9 sizeof(basic::ZonePolicy): 6 sizeof(basic::Transition): 18 @@ -51,22 +54,79 @@ CPU: |--------------------------------------------------|----------| | Empty loop | 5.200 | |--------------------------------------------------|----------| -| LocalDate::forEpochDays() | 216.400 | -| LocalDate::toEpochDays() | 57.600 | -| LocalDate::dayOfWeek() | 50.000 | +| LocalDate::forEpochDays() | 216.800 | +| LocalDate::toEpochDays() | 57.200 | +| LocalDate::dayOfWeek() | 50.400 | | OffsetDateTime::forEpochSeconds() | 320.800 | -| OffsetDateTime::toEpochSeconds() | 85.600 | -| ZonedDateTime::toEpochSeconds() | 87.200 | -| ZonedDateTime::toEpochDays() | 72.800 | -| ZonedDateTime::forEpochSeconds(UTC) | 332.000 | -| ZonedDateTime::forEpochSeconds(Basic nocache) | 1134.800 | -| ZonedDateTime::forEpochSeconds(Basic cached) | 610.800 | -| ZonedDateTime::forEpochSeconds(Extended nocache) | 1966.000 | -| ZonedDateTime::forEpochSeconds(Extended cached) | 608.800 | +| OffsetDateTime::toEpochSeconds() | 86.400 | +| ZonedDateTime::toEpochSeconds() | 87.600 | +| ZonedDateTime::toEpochDays() | 73.200 | +| ZonedDateTime::forEpochSeconds(UTC) | 334.000 | +| ZonedDateTime::forEpochSeconds(Basic nocache) | 1139.200 | +| ZonedDateTime::forEpochSeconds(Basic cached) | 618.000 | +| ZonedDateTime::forEpochSeconds(Extended nocache) | 1962.000 | +| ZonedDateTime::forEpochSeconds(Extended cached) | 615.600 | +--------------------------------------------------+----------+ Number of iterations per run: 2500 ``` +## SAMD21 M0 Mini (Arduino Zero Compatible) + +IDE: Arduino 1.8.9 (SAMD Core 1.8.3) + +Memory: +``` +sizeof(LocalDate): 3 +sizeof(LocalTime): 3 +sizeof(LocalDateTime): 6 +sizeof(TimeOffset): 1 +sizeof(OffsetDateTime): 7 +sizeof(BasicZoneProcessor): 156 +sizeof(ExtendedZoneProcessor): 500 +sizeof(BasicZoneRegistrar): 12 +sizeof(ExtendedZoneRegistrar): 12 +sizeof(BasicZoneManager<1>): 176 +sizeof(ExtendedZoneManager<1>): 520 +sizeof(TimeZone): 12 +sizeof(ZonedDateTime): 20 +sizeof(TimePeriod): 4 +sizeof(clock::SystemClock): 24 +sizeof(clock::DS3231TimeKeeper): 8 +sizeof(clock::SystemClockSyncLoop): 16 +sizeof(clock::SystemClockSyncCoroutine): 48 +sizeof(basic::ZoneContext): 8 +sizeof(basic::ZoneEra): 24 +sizeof(basic::ZoneInfo): 20 +sizeof(basic::ZoneRule): 9 +sizeof(basic::ZonePolicy): 16 +sizeof(basic::Transition): 28 +sizeof(extended::Transition): 48 +sizeof(extended::ZoneMatch): 16 +``` + +CPU: +``` ++--------------------------------------------------+----------+ +| Method | micros | +|--------------------------------------------------|----------| +| Empty loop | 1.700 | +|--------------------------------------------------|----------| +| LocalDate::forEpochDays() | 14.900 | +| LocalDate::toEpochDays() | 7.600 | +| LocalDate::dayOfWeek() | 7.500 | +| OffsetDateTime::forEpochSeconds() | 21.500 | +| OffsetDateTime::toEpochSeconds() | 13.800 | +| ZonedDateTime::toEpochSeconds() | 14.000 | +| ZonedDateTime::toEpochDays() | 12.300 | +| ZonedDateTime::forEpochSeconds(UTC) | 24.300 | +| ZonedDateTime::forEpochSeconds(Basic nocache) | 177.400 | +| ZonedDateTime::forEpochSeconds(Basic cached) | 49.900 | +| ZonedDateTime::forEpochSeconds(Extended nocache) | 333.200 | +| ZonedDateTime::forEpochSeconds(Extended cached) | 50.600 | ++--------------------------------------------------+----------+ +Number of iterations per run: 10000 +``` + ## ESP8266 IDE: Arduino 1.8.9 (ESP Core 2.5.2) @@ -79,11 +139,14 @@ sizeof(LocalTime): 3 sizeof(LocalDateTime): 6 sizeof(TimeOffset): 1 sizeof(OffsetDateTime): 7 -sizeof(ZoneProcessor): 8 sizeof(BasicZoneProcessor): 156 sizeof(ExtendedZoneProcessor): 500 -sizeof(TimeZone): 8 -sizeof(ZonedDateTime): 16 +sizeof(BasicZoneRegistrar): 12 +sizeof(ExtendedZoneRegistrar): 12 +sizeof(BasicZoneManager<1>): 176 +sizeof(ExtendedZoneManager<1>): 520 +sizeof(TimeZone): 12 +sizeof(ZonedDateTime): 20 sizeof(TimePeriod): 4 sizeof(clock::SystemClock): 24 sizeof(clock::DS3231TimeKeeper): 8 @@ -92,7 +155,7 @@ sizeof(clock::SystemClockSyncLoop): 16 sizeof(clock::SystemClockSyncCoroutine): 48 sizeof(basic::ZoneContext): 8 sizeof(basic::ZoneEra): 24 -sizeof(basic::ZoneInfo): 16 +sizeof(basic::ZoneInfo): 20 sizeof(basic::ZoneRule): 9 sizeof(basic::ZonePolicy): 16 sizeof(basic::Transition): 28 @@ -109,20 +172,19 @@ CPU: | Empty loop | 5.100 | |--------------------------------------------------|----------| | LocalDate::forEpochDays() | 7.600 | -| LocalDate::toEpochDays() | 4.300 | -| LocalDate::dayOfWeek() | 4.000 | -| OffsetDateTime::forEpochSeconds() | 12.600 | -| OffsetDateTime::toEpochSeconds() | 7.100 | -| ZonedDateTime::toEpochSeconds() | 6.900 | -| ZonedDateTime::toEpochDays() | 6.100 | -| ZonedDateTime::forEpochSeconds(UTC) | 13.300 | -| ZonedDateTime::forEpochSeconds(Basic nocache) | 91.600 | -| ZonedDateTime::forEpochSeconds(Basic cached) | 25.900 | -| ZonedDateTime::forEpochSeconds(Extended nocache) | 175.900 | -| ZonedDateTime::forEpochSeconds(Extended cached) | 25.800 | +| LocalDate::toEpochDays() | 4.200 | +| LocalDate::dayOfWeek() | 4.100 | +| OffsetDateTime::forEpochSeconds() | 12.500 | +| OffsetDateTime::toEpochSeconds() | 7.000 | +| ZonedDateTime::toEpochSeconds() | 7.100 | +| ZonedDateTime::toEpochDays() | 6.000 | +| ZonedDateTime::forEpochSeconds(UTC) | 13.500 | +| ZonedDateTime::forEpochSeconds(Basic nocache) | 93.500 | +| ZonedDateTime::forEpochSeconds(Basic cached) | 27.600 | +| ZonedDateTime::forEpochSeconds(Extended nocache) | 178.200 | +| ZonedDateTime::forEpochSeconds(Extended cached) | 27.300 | +--------------------------------------------------+----------+ Number of iterations per run: 10000 - ``` ## ESP32 @@ -137,11 +199,14 @@ sizeof(LocalTime): 3 sizeof(LocalDateTime): 6 sizeof(TimeOffset): 1 sizeof(OffsetDateTime): 7 -sizeof(ZoneProcessor): 8 sizeof(BasicZoneProcessor): 156 sizeof(ExtendedZoneProcessor): 500 -sizeof(TimeZone): 8 -sizeof(ZonedDateTime): 16 +sizeof(BasicZoneRegistrar): 12 +sizeof(ExtendedZoneRegistrar): 12 +sizeof(BasicZoneManager<1>): 176 +sizeof(ExtendedZoneManager<1>): 520 +sizeof(TimeZone): 12 +sizeof(ZonedDateTime): 20 sizeof(TimePeriod): 4 sizeof(clock::SystemClock): 24 sizeof(clock::DS3231TimeKeeper): 8 @@ -150,7 +215,7 @@ sizeof(clock::SystemClockSyncLoop): 16 sizeof(clock::SystemClockSyncCoroutine): 48 sizeof(basic::ZoneContext): 8 sizeof(basic::ZoneEra): 24 -sizeof(basic::ZoneInfo): 16 +sizeof(basic::ZoneInfo): 20 sizeof(basic::ZoneRule): 9 sizeof(basic::ZonePolicy): 16 sizeof(basic::Transition): 28 @@ -166,18 +231,18 @@ CPU: |--------------------------------------------------|----------| | Empty loop | 1.400 | |--------------------------------------------------|----------| -| LocalDate::forEpochDays() | 0.460 | +| LocalDate::forEpochDays() | 0.470 | | LocalDate::toEpochDays() | 0.390 | -| LocalDate::dayOfWeek() | 0.440 | -| OffsetDateTime::forEpochSeconds() | 1.010 | -| OffsetDateTime::toEpochSeconds() | 1.390 | -| ZonedDateTime::toEpochSeconds() | 1.420 | -| ZonedDateTime::toEpochDays() | 1.110 | -| ZonedDateTime::forEpochSeconds(UTC) | 1.450 | -| ZonedDateTime::forEpochSeconds(Basic nocache) | 14.840 | -| ZonedDateTime::forEpochSeconds(Basic cached) | 2.550 | -| ZonedDateTime::forEpochSeconds(Extended nocache) | 31.160 | -| ZonedDateTime::forEpochSeconds(Extended cached) | 2.520 | +| LocalDate::dayOfWeek() | 0.410 | +| OffsetDateTime::forEpochSeconds() | 1.020 | +| OffsetDateTime::toEpochSeconds() | 1.400 | +| ZonedDateTime::toEpochSeconds() | 1.410 | +| ZonedDateTime::toEpochDays() | 1.070 | +| ZonedDateTime::forEpochSeconds(UTC) | 1.550 | +| ZonedDateTime::forEpochSeconds(Basic nocache) | 14.940 | +| ZonedDateTime::forEpochSeconds(Basic cached) | 2.820 | +| ZonedDateTime::forEpochSeconds(Extended nocache) | 30.990 | +| ZonedDateTime::forEpochSeconds(Extended cached) | 2.760 | +--------------------------------------------------+----------+ Number of iterations per run: 100000 ``` @@ -198,11 +263,14 @@ sizeof(LocalTime): 3 sizeof(LocalDateTime): 6 sizeof(TimeOffset): 1 sizeof(OffsetDateTime): 7 -sizeof(ZoneProcessor): 8 sizeof(BasicZoneProcessor): 156 sizeof(ExtendedZoneProcessor): 500 -sizeof(TimeZone): 8 -sizeof(ZonedDateTime): 16 +sizeof(BasicZoneRegistrar): 12 +sizeof(ExtendedZoneRegistrar): 12 +sizeof(BasicZoneManager<1>): 176 +sizeof(ExtendedZoneManager<1>): 520 +sizeof(TimeZone): 12 +sizeof(ZonedDateTime): 20 sizeof(TimePeriod): 4 sizeof(clock::SystemClock): 24 sizeof(clock::DS3231TimeKeeper): 8 @@ -210,34 +278,32 @@ sizeof(clock::SystemClockSyncLoop): 16 sizeof(clock::SystemClockSyncCoroutine): 48 sizeof(basic::ZoneContext): 8 sizeof(basic::ZoneEra): 24 -sizeof(basic::ZoneInfo): 16 +sizeof(basic::ZoneInfo): 20 sizeof(basic::ZoneRule): 9 sizeof(basic::ZonePolicy): 16 sizeof(basic::Transition): 28 sizeof(extended::Transition): 48 sizeof(extended::ZoneMatch): 16 ``` - CPU: - ``` +--------------------------------------------------+----------+ | Method | micros | |--------------------------------------------------|----------| -| Empty loop | 0.570 | +| Empty loop | 0.580 | |--------------------------------------------------|----------| -| LocalDate::forEpochDays() | 1.150 | -| LocalDate::toEpochDays() | 0.910 | -| LocalDate::dayOfWeek() | 1.590 | -| OffsetDateTime::forEpochSeconds() | 1.900 | -| OffsetDateTime::toEpochSeconds() | 0.680 | -| ZonedDateTime::toEpochSeconds() | 0.500 | -| ZonedDateTime::toEpochDays() | 0.500 | -| ZonedDateTime::forEpochSeconds(UTC) | 2.230 | -| ZonedDateTime::forEpochSeconds(Basic nocache) | 28.290 | -| ZonedDateTime::forEpochSeconds(Basic cached) | 5.530 | -| ZonedDateTime::forEpochSeconds(Extended nocache) | 64.400 | -| ZonedDateTime::forEpochSeconds(Extended cached) | 5.450 | +| LocalDate::forEpochDays() | 1.390 | +| LocalDate::toEpochDays() | 0.720 | +| LocalDate::dayOfWeek() | 1.340 | +| OffsetDateTime::forEpochSeconds() | 1.970 | +| OffsetDateTime::toEpochSeconds() | 0.450 | +| ZonedDateTime::toEpochSeconds() | 0.590 | +| ZonedDateTime::toEpochDays() | 0.210 | +| ZonedDateTime::forEpochSeconds(UTC) | 2.270 | +| ZonedDateTime::forEpochSeconds(Basic nocache) | 29.200 | +| ZonedDateTime::forEpochSeconds(Basic cached) | 6.060 | +| ZonedDateTime::forEpochSeconds(Extended nocache) | 65.930 | +| ZonedDateTime::forEpochSeconds(Extended cached) | 6.160 | +--------------------------------------------------+----------+ Number of iterations per run: 100000 ``` From 263fae31a27b3017962c469775d5ec1b0b52b109 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 17:35:05 -0700 Subject: [PATCH 13/35] src/clock: Add 'extern C unsigned long millis()' in headers to avoid out-of-order inclusion of --- src/ace_time/clock/NtpTimeProvider.cpp | 28 ------------------- src/ace_time/clock/NtpTimeProvider.h | 27 +++++++++++++++++- src/ace_time/clock/SystemClock.cpp | 10 ------- src/ace_time/clock/SystemClock.h | 10 +++---- src/ace_time/clock/SystemClockSyncCoroutine.h | 2 ++ src/ace_time/clock/SystemClockSyncLoop.h | 2 ++ 6 files changed, 34 insertions(+), 45 deletions(-) delete mode 100644 src/ace_time/clock/SystemClock.cpp diff --git a/src/ace_time/clock/NtpTimeProvider.cpp b/src/ace_time/clock/NtpTimeProvider.cpp index 188f940cb..66a18426f 100644 --- a/src/ace_time/clock/NtpTimeProvider.cpp +++ b/src/ace_time/clock/NtpTimeProvider.cpp @@ -3,7 +3,6 @@ * Copyright (c) 2018 Brian T. Park */ -#include #include "../common/flash.h" #include "NtpTimeProvider.h" @@ -14,33 +13,6 @@ namespace clock { const char NtpTimeProvider::kNtpServerName[] = "us.pool.ntp.org"; -// Moved from. h to .cpp because F() strings in inline contexts under ESP8266 -// causes problems with other F() strings. -void NtpTimeProvider::setup(const char* ssid, const char* password) { - uint16_t startMillis = millis(); - WiFi.begin(ssid, password); - while (WiFi.status() != WL_CONNECTED) { - uint16_t elapsedMillis = millis() - startMillis; - if (elapsedMillis >= kConnectTimeoutMillis) { - mIsSetUp = false; - return; - } - - delay(500); - } - - mUdp.begin(mLocalPort); - -#if ACE_TIME_NTP_TIME_PROVIDER_DEBUG == 1 - #if defined(ESP8266) - SERIAL_PORT_MONITOR.print(F("Local port: ")); - SERIAL_PORT_MONITOR.println(mUdp.localPort()); - #endif -#endif - - mIsSetUp = true; -} - } } diff --git a/src/ace_time/clock/NtpTimeProvider.h b/src/ace_time/clock/NtpTimeProvider.h index ae6a0a216..9dff5db96 100644 --- a/src/ace_time/clock/NtpTimeProvider.h +++ b/src/ace_time/clock/NtpTimeProvider.h @@ -22,6 +22,8 @@ #define ACE_TIME_NTP_TIME_PROVIDER_DEBUG 0 #endif +extern "C" unsigned long millis(); + namespace ace_time { namespace clock { @@ -66,7 +68,30 @@ class NtpTimeProvider: public TimeProvider { mRequestTimeout(requestTimeout) {} /** Set up using the provided ssid and password. */ - void setup(const char* ssid, const char* password); + void setup(const char* ssid, const char* password) { + uint16_t startMillis = millis(); + WiFi.begin(ssid, password); + while (WiFi.status() != WL_CONNECTED) { + uint16_t elapsedMillis = millis() - startMillis; + if (elapsedMillis >= kConnectTimeoutMillis) { + mIsSetUp = false; + return; + } + + delay(500); + } + + mUdp.begin(mLocalPort); + + #if ACE_TIME_NTP_TIME_PROVIDER_DEBUG == 1 + #if defined(ESP8266) + SERIAL_PORT_MONITOR.print(F("Local port: ")); + SERIAL_PORT_MONITOR.println(mUdp.localPort()); + #endif + #endif + + mIsSetUp = true; + } const char* getServer() const { return mServer; } diff --git a/src/ace_time/clock/SystemClock.cpp b/src/ace_time/clock/SystemClock.cpp deleted file mode 100644 index c5ed46fec..000000000 --- a/src/ace_time/clock/SystemClock.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include // millis() -#include "SystemClock.h" - -namespace ace_time { -namespace clock { - -unsigned long SystemClock::millis() const { return ::millis(); } - -} -} diff --git a/src/ace_time/clock/SystemClock.h b/src/ace_time/clock/SystemClock.h index 9d06d5419..2626d9a58 100644 --- a/src/ace_time/clock/SystemClock.h +++ b/src/ace_time/clock/SystemClock.h @@ -10,6 +10,8 @@ #include "../common/TimingStats.h" #include "TimeKeeper.h" +extern "C" unsigned long millis(); + namespace ace_time { namespace clock { @@ -130,12 +132,8 @@ class SystemClock: public TimeKeeper { bool isInit() const { return mIsInit; } protected: - /** - * Return the Arduino millis(). Override for unit testing. - * This is defined in the .cpp file to avoid include in - * the header, which avoids a multiple #define error. - */ - virtual unsigned long millis() const; + /** Return the Arduino millis(). Override for unit testing. */ + virtual unsigned long millis() const { return ::millis(); } private: friend class SystemClockSyncCoroutine; diff --git a/src/ace_time/clock/SystemClockSyncCoroutine.h b/src/ace_time/clock/SystemClockSyncCoroutine.h index b623bfb0c..68e0f619b 100644 --- a/src/ace_time/clock/SystemClockSyncCoroutine.h +++ b/src/ace_time/clock/SystemClockSyncCoroutine.h @@ -10,6 +10,8 @@ #include "../common/TimingStats.h" #include "SystemClock.h" +extern "C" unsigned long millis(); + class SystemClockSyncCoroutineTest; namespace ace_time { diff --git a/src/ace_time/clock/SystemClockSyncLoop.h b/src/ace_time/clock/SystemClockSyncLoop.h index bc31ed15a..b3a1d504f 100644 --- a/src/ace_time/clock/SystemClockSyncLoop.h +++ b/src/ace_time/clock/SystemClockSyncLoop.h @@ -9,6 +9,8 @@ #include #include "SystemClock.h" +extern "C" unsigned long millis(); + namespace ace_time { namespace clock { From b8d1142c892c3600f0c1e9b5ec55d1b5afd47ad8 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 18:00:47 -0700 Subject: [PATCH 14/35] src: Rename logger.* to logging.* for consistency --- src/ace_time/BasicZoneProcessor.h | 2 +- src/ace_time/ExtendedZoneProcessor.h | 2 +- src/ace_time/clock/NtpTimeProvider.h | 2 +- src/ace_time/common/{logger.cpp => logging.cpp} | 2 +- src/ace_time/common/{logger.h => logging.h} | 6 +++--- .../BasicValidationUsingJavaTest/TransitionTest.h | 2 +- .../BasicValidationUsingPythonTest/TransitionTest.h | 2 +- .../ExtendedValidationUsingJavaTest/TransitionTest.h | 2 +- .../ExtendedValidationUsingPythonTest/TransitionTest.h | 2 +- 9 files changed, 11 insertions(+), 11 deletions(-) rename src/ace_time/common/{logger.cpp => logging.cpp} (97%) rename src/ace_time/common/{logger.h => logging.h} (74%) diff --git a/src/ace_time/BasicZoneProcessor.h b/src/ace_time/BasicZoneProcessor.h index 96d6fcdbf..a4f2efe90 100644 --- a/src/ace_time/BasicZoneProcessor.h +++ b/src/ace_time/BasicZoneProcessor.h @@ -11,7 +11,7 @@ #include "internal/ZonePolicy.h" #include "internal/ZoneInfo.h" #include "internal/Brokers.h" -#include "common/logger.h" +#include "common/logging.h" #include "TimeOffset.h" #include "LocalDate.h" #include "OffsetDateTime.h" diff --git a/src/ace_time/ExtendedZoneProcessor.h b/src/ace_time/ExtendedZoneProcessor.h index 1bba898d0..524a678cc 100644 --- a/src/ace_time/ExtendedZoneProcessor.h +++ b/src/ace_time/ExtendedZoneProcessor.h @@ -11,7 +11,7 @@ #include "common/flash.h" #include "internal/ZonePolicy.h" #include "internal/ZoneInfo.h" -#include "common/logger.h" +#include "common/logging.h" #include "TimeOffset.h" #include "LocalDate.h" #include "OffsetDateTime.h" diff --git a/src/ace_time/clock/NtpTimeProvider.h b/src/ace_time/clock/NtpTimeProvider.h index 9dff5db96..eef029acf 100644 --- a/src/ace_time/clock/NtpTimeProvider.h +++ b/src/ace_time/clock/NtpTimeProvider.h @@ -15,7 +15,7 @@ #include #endif #include -#include "../common/logger.h" +#include "../common/logging.h" #include "TimeKeeper.h" #ifndef ACE_TIME_NTP_TIME_PROVIDER_DEBUG diff --git a/src/ace_time/common/logger.cpp b/src/ace_time/common/logging.cpp similarity index 97% rename from src/ace_time/common/logger.cpp rename to src/ace_time/common/logging.cpp index 00a0ed36f..c63e219d7 100644 --- a/src/ace_time/common/logger.cpp +++ b/src/ace_time/common/logging.cpp @@ -1,6 +1,6 @@ #include #include "flash.h" -#include "logger.h" +#include "logging.h" namespace ace_time { namespace logging { diff --git a/src/ace_time/common/logger.h b/src/ace_time/common/logging.h similarity index 74% rename from src/ace_time/common/logger.h rename to src/ace_time/common/logging.h index 2818109cb..aeee0b19d 100644 --- a/src/ace_time/common/logger.h +++ b/src/ace_time/common/logging.h @@ -4,9 +4,9 @@ */ /* - * Implement logger::print() and logger::println() that accept formatting - * strings like printf(). I finally got tired of writing multiple lines of - * SERIAL_PORT_MONITOR.print() for debugging. + * Implement logging::printf() that accept formatting strings like printf(). I + * finally got tired of writing multiple lines of SERIAL_PORT_MONITOR.print() + * for debugging. */ #ifndef ACE_TIME_COMMON_LOGGING_H diff --git a/tests/validation/BasicValidationUsingJavaTest/TransitionTest.h b/tests/validation/BasicValidationUsingJavaTest/TransitionTest.h index e86d648b0..d639ea8e9 100644 --- a/tests/validation/BasicValidationUsingJavaTest/TransitionTest.h +++ b/tests/validation/BasicValidationUsingJavaTest/TransitionTest.h @@ -3,7 +3,7 @@ #include #include "ValidationDataType.h" -#include "ace_time/common/logger.h" +#include "ace_time/common/logging.h" #define DEBUG 0 diff --git a/tests/validation/BasicValidationUsingPythonTest/TransitionTest.h b/tests/validation/BasicValidationUsingPythonTest/TransitionTest.h index e86d648b0..d639ea8e9 100644 --- a/tests/validation/BasicValidationUsingPythonTest/TransitionTest.h +++ b/tests/validation/BasicValidationUsingPythonTest/TransitionTest.h @@ -3,7 +3,7 @@ #include #include "ValidationDataType.h" -#include "ace_time/common/logger.h" +#include "ace_time/common/logging.h" #define DEBUG 0 diff --git a/tests/validation/ExtendedValidationUsingJavaTest/TransitionTest.h b/tests/validation/ExtendedValidationUsingJavaTest/TransitionTest.h index c36d1a51e..ae38ae193 100644 --- a/tests/validation/ExtendedValidationUsingJavaTest/TransitionTest.h +++ b/tests/validation/ExtendedValidationUsingJavaTest/TransitionTest.h @@ -3,7 +3,7 @@ #include #include "ValidationDataType.h" -#include "ace_time/common/logger.h" +#include "ace_time/common/logging.h" #define DEBUG 0 diff --git a/tests/validation/ExtendedValidationUsingPythonTest/TransitionTest.h b/tests/validation/ExtendedValidationUsingPythonTest/TransitionTest.h index c36d1a51e..ae38ae193 100644 --- a/tests/validation/ExtendedValidationUsingPythonTest/TransitionTest.h +++ b/tests/validation/ExtendedValidationUsingPythonTest/TransitionTest.h @@ -3,7 +3,7 @@ #include #include "ValidationDataType.h" -#include "ace_time/common/logger.h" +#include "ace_time/common/logging.h" #define DEBUG 0 From 40536b7d2e86b956d5f88e554ba9607ece26a9ea Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 21:48:42 -0700 Subject: [PATCH 15/35] src/flash.h: Move #warning from flash.h to flash.cpp to print it out just once --- src/ace_time/common/flash.cpp | 5 +++++ src/ace_time/common/flash.h | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ace_time/common/flash.cpp b/src/ace_time/common/flash.cpp index 63af87714..d89e6a2dd 100644 --- a/src/ace_time/common/flash.cpp +++ b/src/ace_time/common/flash.cpp @@ -1,5 +1,10 @@ #include "flash.h" +// Print out a warning about SERIAL_PORT_MONITOR, just once +#if defined(ARDUINO_SAMD_ZERO) + #warning Setting SERIAL_PORT_MONITOR to SerialUSB +#endif + #if defined(ESP8266) || defined(ESP32) const char* strchr_P(const char* s, int c) { diff --git a/src/ace_time/common/flash.h b/src/ace_time/common/flash.h index ee782b285..133e5129b 100644 --- a/src/ace_time/common/flash.h +++ b/src/ace_time/common/flash.h @@ -39,7 +39,6 @@ // SerialUSB. This is the correct setting on the Chinese SAMD21 M0 Mini // clones which claim to be compatible with the Arduino Zero. #if defined(ARDUINO_SAMD_ZERO) - #warning Setting SERIAL_PORT_MONITOR to SerialUSB #undef SERIAL_PORT_MONITOR #define SERIAL_PORT_MONITOR SerialUSB #endif From 3c109c21232942f8bc47ff9d80f64c948f7d0d2f Mon Sep 17 00:00:00 2001 From: Brian Park Date: Mon, 22 Jul 2019 23:29:27 -0700 Subject: [PATCH 16/35] src/flash.h: Remove clobbering hack for SERIAL_PORT_MONITOR; recommend using SparkFun board configurations for SAMD21 boards --- USER_GUIDE.md | 40 ++++++++++++++++++++++++----------- src/ace_time/common/flash.cpp | 6 ++++-- src/ace_time/common/flash.h | 11 +++++----- 3 files changed, 37 insertions(+), 20 deletions(-) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 4affe8196..918b5c94d 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -2577,15 +2577,31 @@ did not think it would fit inside an Arduino controller. is created with a `TimeZone` associated with `kZoneUS_Pacific`, the `ZonedDateTime::printTo()` will print "[America/Los_Angeles]" not "[US/Pacific]". -* Arduino Zero and SAMD21 Clones - * Some amount of support for the Arduino Zero (and other SAMD21 boards) - have been added. The original Arduino Zero has - [2 USB ports](https://www.arduino.cc/en/Guide/ArduinoZero). The - Programming port is connected to `Serial` object and the Native port is - connected to `SerialUSB` object. AceTime assumes that you are always using - the "Native USB Port" on the Arduino Zero, and redefines the - `SERIAL_MONITOR_PORT` macro to be `SerialUSB`. This is the correct setting - on the "Ardunio SAMD21 M0 Mini" clones claiming to be compatible with the - Arduino Zero. However, if you are using a real Arduino Zero, and using the - Programming Port, then you must edit `src/ace_time/common/flash.h` and - comment out the code that clobbers the `SERIAL_MONITOR_PORT` macro. +* Arduino Zero and SAMD21 Boards + * Some amount of support for the SAMD21 boards + (which all identify themselves as `ARDUINO_SAMD_ZERO`) has been added. + * If you are using an original Arduino Zero and using the "Native USB Port", + you may encounter problems with nothing showing up on the Serial Monitor. + * The original Arduino Zero has [2 USB + ports](https://www.arduino.cc/en/Guide/ArduinoZero). The Programming + port is connected to `Serial` object and the Native port is connected + to `SerialUSB` object. You can select either the "Arduino/Genuino Zero + (Programming Port)" or the "Arduino/Genuino Zero (Native USB Port)" on + the Board Manager selector in the Arduino IDEA. Unfortunately, if you + select "(Native USB Port)", the `SERIAL_MONITOR_PORT` macro *should* + be defined to be `SerialUSB`, but it continues to point to `Serial`, + which means that nothing will show up on the Serial Monitor. + * You may be able to fix this by setting + `ACE_TIME_CLOBBER_SERIAL_PORT_MONITOR` to `1` in + `src/ace_time/common/flash.h`. (I do not test this option often, so it + may be broke.) + * If you are using a SAMD21 development or breakout board, or one of the + many clones called something like "Ardunio SAMD21 M0 Mini" (this is what I + have), I have found things working better using the SparkFun + configurations. Download "SparkFun SAMD Boards" using the Board Manager, + then select the board labeled "SparkFun SAMD Mini Breakout". These + boards have only a single USB connector, and the `SERIAL_PORT_MONITOR` + will be properly defined to be `SerialUSB`. + * The SAMD21 microcontroller does not provide any EEPROM. Therefore, + some of the more realistic example apps (e.g. CommandLineClock, OledClock, + and WorldClock) do not build on the SAMD21. diff --git a/src/ace_time/common/flash.cpp b/src/ace_time/common/flash.cpp index d89e6a2dd..3cfbf726d 100644 --- a/src/ace_time/common/flash.cpp +++ b/src/ace_time/common/flash.cpp @@ -1,8 +1,10 @@ #include "flash.h" -// Print out a warning about SERIAL_PORT_MONITOR, just once +// There are many different boards which identify themselves as +// ARDUINO_SAMD_ZERO. The original Arduino Zero is bit broken with regards to +// the definition of SERIAL_PORT_MONITOR, so warn the user about that. #if defined(ARDUINO_SAMD_ZERO) - #warning Setting SERIAL_PORT_MONITOR to SerialUSB + #warning See USER_GUIDE.md about SERIAL_PORT_MONITOR if using an Arduino Zero (ignore if using a dev board from SparkFun or others) #endif #if defined(ESP8266) || defined(ESP32) diff --git a/src/ace_time/common/flash.h b/src/ace_time/common/flash.h index 133e5129b..e381cd6ea 100644 --- a/src/ace_time/common/flash.h +++ b/src/ace_time/common/flash.h @@ -33,12 +33,11 @@ // pointer, so map it directly to strcmp() #define acetime_strcmp_P strcmp - // The Arduino Zero using "Native USB Port" uses SerialUSB, but - // SERIAL_PORT_MONITOR continues to point to Serial, which causes nothing to - // appear on the Serial Monitor. Clobber SERIAL_PORT_MONITOR to point to - // SerialUSB. This is the correct setting on the Chinese SAMD21 M0 Mini - // clones which claim to be compatible with the Arduino Zero. - #if defined(ARDUINO_SAMD_ZERO) + // Set this to 1 to clobber SERIAL_PORT_MONITOR to SerialUSB on + // an original Arduino Zero when using the Native port. See USER_GUIDE.md for + // more info. + #define ACE_TIME_CLOBBER_SERIAL_PORT_MONITOR 0 + #if ACE_TIME_CLOBBER_SERIAL_PORT_MONITOR && defined(ARDUINO_SAMD_ZERO) #undef SERIAL_PORT_MONITOR #define SERIAL_PORT_MONITOR SerialUSB #endif From f372e363a5d24299e59337c34afc777f404a7f49 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 10:15:12 -0700 Subject: [PATCH 17/35] src/DateStrings.cpp: Put (char*) pointers into PROGMEM as well, saving 42 bytes of RAM --- src/ace_time/common/DateStrings.cpp | 8 ++++++-- src/ace_time/common/DateStrings.h | 19 ++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/ace_time/common/DateStrings.cpp b/src/ace_time/common/DateStrings.cpp index 80878c548..682a02b85 100644 --- a/src/ace_time/common/DateStrings.cpp +++ b/src/ace_time/common/DateStrings.cpp @@ -22,7 +22,9 @@ static const char kOctober[] PROGMEM = "October"; static const char kNovember[] PROGMEM = "November"; static const char kDecember[] PROGMEM = "December"; -const char* const DateStrings::kMonthNames[] = { +// Place pointers into PROGMEM as well, saving 26 bytes of RAM. +// Use getStringAt() to access. +const char* const DateStrings::kMonthNames[] PROGMEM = { kError, kJanuary, kFebruary, kMarch, kApril, kMay, kJune, kJuly, kAugust, kSeptember, kOctober, kNovember, kDecember }; @@ -38,8 +40,10 @@ static const char kFriday[] PROGMEM = "Friday"; static const char kSaturday[] PROGMEM = "Saturday"; static const char kSunday[] PROGMEM = "Sunday"; +// Place pointers into PROGMEM as well, saving 16 bytes of RAM. +// Use getStringAt() to access. // ISO8601 says Monday=1, Sunday=7. -const char* const DateStrings::kDayOfWeekNames[] = { +const char* const DateStrings::kDayOfWeekNames[] PROGMEM = { kError, kMonday, kTuesday, kWednesday, kThursday, kFriday, kSaturday, kSunday }; diff --git a/src/ace_time/common/DateStrings.h b/src/ace_time/common/DateStrings.h index 73aa7bf0a..6634954fd 100644 --- a/src/ace_time/common/DateStrings.h +++ b/src/ace_time/common/DateStrings.h @@ -31,20 +31,24 @@ class DateStrings { */ static const uint8_t kBufferSize = 10; - /** Number of prefix characters to use to create a short name. */ + /** + * Number of prefix characters to use to create a short name. + * kShortNameLength < kBufferSize must be true. + */ static const uint8_t kShortNameLength = 3; /** Return the long month name. 0=Error, 1=January, 12=December. */ const char* monthLongString(uint8_t month) { uint8_t index = (month < kNumMonthNames) ? month : 0; - strcpy_P(mBuffer, kMonthNames[index]); + strncpy_P(mBuffer, getStringAt(kMonthNames, index), kBufferSize); + mBuffer[kBufferSize - 1] = '\0'; return mBuffer; } /** Return the short month name. 0=Err, 1=Jan, 12=Dec. */ const char* monthShortString(uint8_t month) { uint8_t index = (month < kNumMonthNames) ? month : 0; - strncpy_P(mBuffer, kMonthNames[index], kShortNameLength); + strncpy_P(mBuffer, getStringAt(kMonthNames, index), kShortNameLength); mBuffer[kShortNameLength] = '\0'; return mBuffer; } @@ -52,19 +56,24 @@ class DateStrings { /** Return the short dayOfWeek name. 0=Error, 1=Monday, 7=Sunday. */ const char* dayOfWeekLongString(uint8_t dayOfWeek) { uint8_t index = (dayOfWeek < kNumDayOfWeekNames) ? dayOfWeek : 0; - strcpy_P(mBuffer, kDayOfWeekNames[index]); + strncpy_P(mBuffer, getStringAt(kDayOfWeekNames, index), kBufferSize); + mBuffer[kBufferSize - 1] = '\0'; return mBuffer; } /** Return the short dayOfWeek name. 0=Err, 1=Mon, 7=Sun. */ const char* dayOfWeekShortString(uint8_t dayOfWeek) { uint8_t index = (dayOfWeek < kNumDayOfWeekNames) ? dayOfWeek : 0; - strncpy_P(mBuffer, kDayOfWeekNames[index], kShortNameLength); + strncpy_P(mBuffer, getStringAt(kDayOfWeekNames, index), kShortNameLength); mBuffer[kShortNameLength] = '\0'; return mBuffer; } private: + static const char* getStringAt(const char* const* strings, uint8_t i) { + return (const char*) pgm_read_ptr(&strings[i]); + } + static const char * const kDayOfWeekNames[]; static const char * const kMonthNames[]; static const uint8_t kNumDayOfWeekNames; From dc3af0af5042a9423ce59908d256ccf2d7a61105 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 10:37:54 -0700 Subject: [PATCH 18/35] src: Rename flash.h to compat.h; regenerate zonedb files --- USER_GUIDE.md | 13 +++++++------ src/AceTime.h | 2 +- src/ace_time/BasicZone.h | 2 +- src/ace_time/ExtendedZone.h | 2 +- src/ace_time/ExtendedZoneProcessor.h | 2 +- src/ace_time/ZoneRegistrar.h | 2 +- src/ace_time/ZonedDateTime.h | 2 +- src/ace_time/clock/NtpTimeProvider.cpp | 2 +- src/ace_time/common/DateStrings.h | 2 +- src/ace_time/common/{flash.cpp => compat.cpp} | 6 +++--- src/ace_time/common/{flash.h => compat.h} | 13 +++++++++++-- src/ace_time/common/logging.cpp | 2 +- src/ace_time/internal/Brokers.h | 2 +- src/ace_time/zonedb/zone_infos.cpp | 2 +- src/ace_time/zonedb/zone_policies.cpp | 2 +- src/ace_time/zonedb/zone_registry.cpp | 2 +- src/ace_time/zonedbx/zone_infos.cpp | 2 +- src/ace_time/zonedbx/zone_policies.cpp | 2 +- src/ace_time/zonedbx/zone_registry.cpp | 2 +- .../BasicZoneRegistrarTest.ino | 2 +- .../zonedb2018g/zone_infos.cpp | 2 +- .../zonedb2018g/zone_policies.cpp | 2 +- .../zonedb2018g/zone_registry.cpp | 2 +- .../zonedbx2018g/zone_infos.cpp | 2 +- .../zonedbx2018g/zone_policies.cpp | 2 +- .../zonedbx2018g/zone_registry.cpp | 2 +- tests/validation/Makefile | 2 +- tools/argenerator.py | 8 ++++---- 28 files changed, 49 insertions(+), 39 deletions(-) rename src/ace_time/common/{flash.cpp => compat.cpp} (85%) rename src/ace_time/common/{flash.h => compat.h} (88%) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 918b5c94d..e37e61167 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -1454,10 +1454,11 @@ static ExtendedZoneManager<2> zoneManager(kZoneRegistrySize, kZoneRegistry); ``` The `ACE_TIME_PROGMEM` macro is defined in -[flash.h](src/ace_time/common/flash.h) and indicates whether the ZoneInfo files -are stored in normal RAM or flash memory (i.e. `PROGMEM`). It must be used for -custom zoneRegistries because the `BasicZoneManager` and `ExtendedZoneManager` -expect to find them in static RAM or flash memory according to this macro. +[compat.h](src/ace_time/common/compat.h) and indicates whether the ZoneInfo +files are stored in normal RAM or flash memory (i.e. `PROGMEM`). It must be used +for custom zoneRegistries because the `BasicZoneManager` and +`ExtendedZoneManager` expect to find them in static RAM or flash memory +according to this macro. See [CommandLineClock](examples/CommandLineClock/) for an example of how these custom registries can be created and used. @@ -2593,8 +2594,8 @@ did not think it would fit inside an Arduino controller. which means that nothing will show up on the Serial Monitor. * You may be able to fix this by setting `ACE_TIME_CLOBBER_SERIAL_PORT_MONITOR` to `1` in - `src/ace_time/common/flash.h`. (I do not test this option often, so it - may be broke.) + `src/ace_time/common/compat.h`. (I do not test this option often, so + it may be broke.) * If you are using a SAMD21 development or breakout board, or one of the many clones called something like "Ardunio SAMD21 M0 Mini" (this is what I have), I have found things working better using the SparkFun diff --git a/src/AceTime.h b/src/AceTime.h index 88d27c43f..06460e4e5 100644 --- a/src/AceTime.h +++ b/src/AceTime.h @@ -13,7 +13,7 @@ #ifndef ACE_TIME_ACE_TIME_H #define ACE_TIME_ACE_TIME_H -#include "ace_time/common/flash.h" +#include "ace_time/common/compat.h" #include "ace_time/common/common.h" #include "ace_time/common/DateStrings.h" #include "ace_time/internal/ZoneContext.h" diff --git a/src/ace_time/BasicZone.h b/src/ace_time/BasicZone.h index f6a886881..f73826645 100644 --- a/src/ace_time/BasicZone.h +++ b/src/ace_time/BasicZone.h @@ -8,7 +8,7 @@ #include "internal/ZoneInfo.h" #include "internal/Brokers.h" -#include "common/flash.h" +#include "common/compat.h" class __FlashStringHelper; diff --git a/src/ace_time/ExtendedZone.h b/src/ace_time/ExtendedZone.h index ad625ea2f..f23125385 100644 --- a/src/ace_time/ExtendedZone.h +++ b/src/ace_time/ExtendedZone.h @@ -8,7 +8,7 @@ #include "internal/ZoneInfo.h" #include "internal/Brokers.h" -#include "common/flash.h" +#include "common/compat.h" class __FlashStringHelper; diff --git a/src/ace_time/ExtendedZoneProcessor.h b/src/ace_time/ExtendedZoneProcessor.h index 524a678cc..be7d54c48 100644 --- a/src/ace_time/ExtendedZoneProcessor.h +++ b/src/ace_time/ExtendedZoneProcessor.h @@ -8,7 +8,7 @@ #include // memcpy() #include -#include "common/flash.h" +#include "common/compat.h" #include "internal/ZonePolicy.h" #include "internal/ZoneInfo.h" #include "common/logging.h" diff --git a/src/ace_time/ZoneRegistrar.h b/src/ace_time/ZoneRegistrar.h index 5dfe59bb3..5187029c9 100644 --- a/src/ace_time/ZoneRegistrar.h +++ b/src/ace_time/ZoneRegistrar.h @@ -8,7 +8,7 @@ #include #include // strcmp(), strcmp_P() -#include "common/flash.h" +#include "common/compat.h" #include "internal/ZoneInfo.h" #include "internal/Brokers.h" diff --git a/src/ace_time/ZonedDateTime.h b/src/ace_time/ZonedDateTime.h index 32fb87251..2e1ad13b8 100644 --- a/src/ace_time/ZonedDateTime.h +++ b/src/ace_time/ZonedDateTime.h @@ -7,7 +7,7 @@ #define ACE_TIME_ZONED_DATE_TIME_H #include -#include "common/flash.h" +#include "common/compat.h" #include "OffsetDateTime.h" #include "TimeZone.h" diff --git a/src/ace_time/clock/NtpTimeProvider.cpp b/src/ace_time/clock/NtpTimeProvider.cpp index 66a18426f..cb7ef6445 100644 --- a/src/ace_time/clock/NtpTimeProvider.cpp +++ b/src/ace_time/clock/NtpTimeProvider.cpp @@ -3,7 +3,7 @@ * Copyright (c) 2018 Brian T. Park */ -#include "../common/flash.h" +#include "../common/compat.h" #include "NtpTimeProvider.h" #if defined(ESP8266) || defined(ESP32) diff --git a/src/ace_time/common/DateStrings.h b/src/ace_time/common/DateStrings.h index 6634954fd..9bd290613 100644 --- a/src/ace_time/common/DateStrings.h +++ b/src/ace_time/common/DateStrings.h @@ -8,7 +8,7 @@ #include #include -#include "flash.h" +#include "compat.h" namespace ace_time { namespace common { diff --git a/src/ace_time/common/flash.cpp b/src/ace_time/common/compat.cpp similarity index 85% rename from src/ace_time/common/flash.cpp rename to src/ace_time/common/compat.cpp index 3cfbf726d..a734fedb1 100644 --- a/src/ace_time/common/flash.cpp +++ b/src/ace_time/common/compat.cpp @@ -1,8 +1,8 @@ -#include "flash.h" +#include "compat.h" // There are many different boards which identify themselves as -// ARDUINO_SAMD_ZERO. The original Arduino Zero is bit broken with regards to -// the definition of SERIAL_PORT_MONITOR, so warn the user about that. +// ARDUINO_SAMD_ZERO. The original Arduino Zero using Native USB Port +// does not set SERIAL_PORT_MONITOR correctly, so warn the user. #if defined(ARDUINO_SAMD_ZERO) #warning See USER_GUIDE.md about SERIAL_PORT_MONITOR if using an Arduino Zero (ignore if using a dev board from SparkFun or others) #endif diff --git a/src/ace_time/common/flash.h b/src/ace_time/common/compat.h similarity index 88% rename from src/ace_time/common/flash.h rename to src/ace_time/common/compat.h index e381cd6ea..ed2f08999 100644 --- a/src/ace_time/common/flash.h +++ b/src/ace_time/common/compat.h @@ -3,8 +3,17 @@ * Copyright (c) 2018 Brian T. Park */ -#ifndef ACE_TIME_COMMON_FLASH_H -#define ACE_TIME_COMMON_FLASH_H +#ifndef ACE_TIME_COMMON_COMPAT_H +#define ACE_TIME_COMMON_COMPAT_H + +/** + * @file compat.h + * + * Macros and definitions that provide a consistency layer among the various + * Arduino boards for compatibility. Most of this is caused by inconsistent, + * incomplete, or sometimes incorrect emulation of the AVR PROGMEM macro and + * its related str*_P() functions in . + */ #include #include diff --git a/src/ace_time/common/logging.cpp b/src/ace_time/common/logging.cpp index c63e219d7..44cc446a1 100644 --- a/src/ace_time/common/logging.cpp +++ b/src/ace_time/common/logging.cpp @@ -1,5 +1,5 @@ #include -#include "flash.h" +#include "compat.h" #include "logging.h" namespace ace_time { diff --git a/src/ace_time/internal/Brokers.h b/src/ace_time/internal/Brokers.h index 39de88be3..547974254 100644 --- a/src/ace_time/internal/Brokers.h +++ b/src/ace_time/internal/Brokers.h @@ -37,7 +37,7 @@ * BasicZoneProcessor and ExtendedZoneProcessor respectively. */ -#include "../common/flash.h" +#include "../common/compat.h" #include "ZoneInfo.h" namespace ace_time { diff --git a/src/ace_time/zonedb/zone_infos.cpp b/src/ace_time/zonedb/zone_infos.cpp index d8267e3a6..c239bd89a 100644 --- a/src/ace_time/zonedb/zone_infos.cpp +++ b/src/ace_time/zonedb/zone_infos.cpp @@ -13,7 +13,7 @@ // // DO NOT EDIT -#include +#include #include "zone_policies.h" #include "zone_infos.h" diff --git a/src/ace_time/zonedb/zone_policies.cpp b/src/ace_time/zonedb/zone_policies.cpp index 8a34ec3eb..b720f538b 100644 --- a/src/ace_time/zonedb/zone_policies.cpp +++ b/src/ace_time/zonedb/zone_policies.cpp @@ -12,7 +12,7 @@ // // DO NOT EDIT -#include +#include #include "zone_policies.h" namespace ace_time { diff --git a/src/ace_time/zonedb/zone_registry.cpp b/src/ace_time/zonedb/zone_registry.cpp index ff9c36b7c..b6695e6a7 100644 --- a/src/ace_time/zonedb/zone_registry.cpp +++ b/src/ace_time/zonedb/zone_registry.cpp @@ -7,7 +7,7 @@ // // DO NOT EDIT -#include +#include #include "zone_infos.h" #include "zone_registry.h" diff --git a/src/ace_time/zonedbx/zone_infos.cpp b/src/ace_time/zonedbx/zone_infos.cpp index fa8c32e2a..dd144fdec 100644 --- a/src/ace_time/zonedbx/zone_infos.cpp +++ b/src/ace_time/zonedbx/zone_infos.cpp @@ -13,7 +13,7 @@ // // DO NOT EDIT -#include +#include #include "zone_policies.h" #include "zone_infos.h" diff --git a/src/ace_time/zonedbx/zone_policies.cpp b/src/ace_time/zonedbx/zone_policies.cpp index 3c0364ea9..00df2e2ae 100644 --- a/src/ace_time/zonedbx/zone_policies.cpp +++ b/src/ace_time/zonedbx/zone_policies.cpp @@ -12,7 +12,7 @@ // // DO NOT EDIT -#include +#include #include "zone_policies.h" namespace ace_time { diff --git a/src/ace_time/zonedbx/zone_registry.cpp b/src/ace_time/zonedbx/zone_registry.cpp index ea1f88640..1b0d7faa3 100644 --- a/src/ace_time/zonedbx/zone_registry.cpp +++ b/src/ace_time/zonedbx/zone_registry.cpp @@ -7,7 +7,7 @@ // // DO NOT EDIT -#include +#include #include "zone_infos.h" #include "zone_registry.h" diff --git a/tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino b/tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino index 218a66211..45772acab 100644 --- a/tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino +++ b/tests/BasicZoneRegistrarTest/BasicZoneRegistrarTest.ino @@ -2,7 +2,7 @@ #include #include -#include +#include using namespace aunit; using namespace ace_time; diff --git a/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_infos.cpp b/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_infos.cpp index 963107f0c..705e6c386 100644 --- a/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_infos.cpp +++ b/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_infos.cpp @@ -13,7 +13,7 @@ // // DO NOT EDIT -#include +#include #include "zone_policies.h" #include "zone_infos.h" diff --git a/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_policies.cpp b/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_policies.cpp index 5a5032b78..f0c5a553f 100644 --- a/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_policies.cpp +++ b/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_policies.cpp @@ -12,7 +12,7 @@ // // DO NOT EDIT -#include +#include #include "zone_policies.h" namespace ace_time { diff --git a/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_registry.cpp b/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_registry.cpp index 75c398c4f..03aebbd09 100644 --- a/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_registry.cpp +++ b/tests/validation/BasicValidationUsingJavaTest/zonedb2018g/zone_registry.cpp @@ -7,7 +7,7 @@ // // DO NOT EDIT -#include +#include #include "zone_infos.h" #include "zone_registry.h" diff --git a/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_infos.cpp b/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_infos.cpp index 480e71bc4..832d5f892 100644 --- a/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_infos.cpp +++ b/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_infos.cpp @@ -13,7 +13,7 @@ // // DO NOT EDIT -#include +#include #include "zone_policies.h" #include "zone_infos.h" diff --git a/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_policies.cpp b/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_policies.cpp index d8a6bbc0c..e39d052d0 100644 --- a/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_policies.cpp +++ b/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_policies.cpp @@ -12,7 +12,7 @@ // // DO NOT EDIT -#include +#include #include "zone_policies.h" namespace ace_time { diff --git a/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_registry.cpp b/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_registry.cpp index 83f6439a8..26c09e4ae 100644 --- a/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_registry.cpp +++ b/tests/validation/ExtendedValidationUsingJavaTest/zonedbx2018g/zone_registry.cpp @@ -7,7 +7,7 @@ // // DO NOT EDIT -#include +#include #include "zone_infos.h" #include "zone_registry.h" diff --git a/tests/validation/Makefile b/tests/validation/Makefile index 9e50c60ba..b7af866f7 100644 --- a/tests/validation/Makefile +++ b/tests/validation/Makefile @@ -7,6 +7,6 @@ clean: runtests: for i in */Makefile ; do $$(dirname $$i)/$$(dirname $$i).out ; done -validation: +zonedb: make -C BasicValidationUsingJavaTest/zonedb2018g/ make -C ExtendedValidationUsingJavaTest/zonedbx2018g/ diff --git a/tools/argenerator.py b/tools/argenerator.py index 8fd85909d..51730f271 100644 --- a/tools/argenerator.py +++ b/tools/argenerator.py @@ -201,7 +201,7 @@ class ZonePoliciesGenerator: // // DO NOT EDIT -#include +#include #include "zone_policies.h" namespace ace_time {{ @@ -557,7 +557,7 @@ class ZoneInfosGenerator: // // DO NOT EDIT -#include +#include #include "zone_policies.h" #include "zone_infos.h" @@ -861,7 +861,7 @@ class ZoneStringsGenerator: // // DO NOT EDIT -#include +#include #include "zone_strings.h" namespace ace_time {{ @@ -981,7 +981,7 @@ class ZoneRegistryGenerator: // // DO NOT EDIT -#include +#include #include "zone_infos.h" #include "zone_registry.h" From 7325f6c4ff79f5fbbf7b198f41db7ece4dab621b Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 11:12:22 -0700 Subject: [PATCH 19/35] tests/auniter.ini: Rename 'env:zero' to 'env:samd'; add verbose descriptions of various boards --- tests/auniter.ini | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/tests/auniter.ini b/tests/auniter.ini index bdfdee21a..5ce277aa5 100644 --- a/tests/auniter.ini +++ b/tests/auniter.ini @@ -1,11 +1,17 @@ # Board aliases [boards] +# "Arduino/Genuino Uno" uno = arduino:avr:uno +# "Arduino Nano ATmega328P (Old Bootloader)" nano = arduino:avr:nano:cpu=atmega328old +# "SparkFun Pro Micro" 16MHz promicro16 = SparkFun:avr:promicro:cpu=16MHzatmega32U4 +# "NodeMCU 1.0 (ESP-12E)" for generic ESP8266 module nodemcuv2 = esp8266:esp8266:nodemcuv2:xtal=80,vt=flash,exception=disabled,eesz=4M,ip=lm2f,dbg=Disabled,lvl=None____,wipe=none,baud=921600 +# "ESP32 Dev Module" for EzSBC ESP32 board esp32 = esp32:esp32:esp32:PartitionScheme=default,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,DebugLevel=none - zero = arduino:samd:arduino_zero_native +# "SparkFun SAMD21 Mini Breakout", also identifies as ARDUINO_SAMD_ZERO + samd = SparkFun:samd:samd21_mini # Disable ExtendedZoneRegistrarTest since they do not fit in an Uno [env:uno] @@ -28,14 +34,12 @@ preprocessor = -DAUNITER_MICRO exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock -# SAMD M0 Mini. Does not have EEPROM.h, so cannot compile OledClock, WorldClock -# and CommandLineClock. Might be possible later with -# https://github.com/cmaglie/FlashStorage. -[env:zero] - board = zero +# SAMD M0 Mini does not have EEPROM.h, so cannot compile OledClock, WorldClock +[env:samd] + board = samd locking = false - preprocessor = -DAUNITER_ZERO - exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock|WorldClock|CommandLineClock + preprocessor = -DAUNITER_SAMD + exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock|WorldClock # Disable ComparisonBenchmark on ESP8266 due to broken Arduino Time Library. [env:esp8266] From af365f14b1782ce841d69353fcb36a3911cd4965 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 11:13:22 -0700 Subject: [PATCH 20/35] CommandLineClock: Make PersistentStore.h be a no-op for SAMD21 boards; now compiles --- examples/CommandLineClock/PersistentStore.h | 24 ++++++++++++++++++--- examples/CommandLineClock/config.h | 4 ++++ src/ace_time/hw/CrcEeprom.h | 12 +++++++---- 3 files changed, 33 insertions(+), 7 deletions(-) diff --git a/examples/CommandLineClock/PersistentStore.h b/examples/CommandLineClock/PersistentStore.h index b8cd2adad..bb8ee91cc 100644 --- a/examples/CommandLineClock/PersistentStore.h +++ b/examples/CommandLineClock/PersistentStore.h @@ -2,7 +2,9 @@ #define COMMAND_LINE_CLOCK_PERSISTENT_STORE_H #include -#include +#if ! defined(ARDUINO_ARCH_SAMD) + #include +#endif #include "config.h" #include "StoredInfo.h" @@ -11,32 +13,48 @@ using namespace ace_time; class PersistentStore { public: void setup() { + #if ! defined(ARDUINO_ARCH_SAMD) // Needed for ESP32 mCrcEeprom.begin(kEepromSize); + #endif } + #if defined(ARDUINO_ARCH_SAMD) + bool readStoredInfo(StoredInfo& /*storedInfo*/) const { + return false; + } + #else bool readStoredInfo(StoredInfo& storedInfo) const { bool isValid = mCrcEeprom.readWithCrc(kStoredInfoEepromAddress, &storedInfo, sizeof(StoredInfo)); -#if TIME_SOURCE_TYPE == TIME_SOURCE_TYPE_NTP + #if TIME_SOURCE_TYPE == TIME_SOURCE_TYPE_NTP storedInfo.ssid[StoredInfo::kSsidMaxLength - 1] = '\0'; storedInfo.password[StoredInfo::kPasswordMaxLength - 1] = '\0'; -#endif + #endif return isValid; } + #endif + #if defined(ARDUINO_ARCH_SAMD) + uint16_t writeStoredInfo(const StoredInfo& /*storedInfo*/) const { + return 0; + } + #else uint16_t writeStoredInfo(const StoredInfo& storedInfo) const { return mCrcEeprom.writeWithCrc(kStoredInfoEepromAddress, &storedInfo, sizeof(StoredInfo)); } + #endif private: + #if ! defined(ARDUINO_ARCH_SAMD) static const uint16_t kStoredInfoEepromAddress = 0; // Must be greater than (sizeof(StoredInfo) + 4). static const uint8_t kEepromSize = sizeof(StoredInfo) + 4; hw::CrcEeprom mCrcEeprom; + #endif }; #endif diff --git a/examples/CommandLineClock/config.h b/examples/CommandLineClock/config.h index 106718cf6..40c89b883 100644 --- a/examples/CommandLineClock/config.h +++ b/examples/CommandLineClock/config.h @@ -33,6 +33,10 @@ #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231 #define ENABLE_TIME_ZONE_TYPE_BASIC 1 #define ENABLE_TIME_ZONE_TYPE_EXTENDED 0 +#elif defined(AUNITER_SAMD) + #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231 + #define ENABLE_TIME_ZONE_TYPE_BASIC 1 + #define ENABLE_TIME_ZONE_TYPE_EXTENDED 1 #elif defined(AUNITER_ESP8266) #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_NTP #define ENABLE_TIME_ZONE_TYPE_BASIC 1 diff --git a/src/ace_time/hw/CrcEeprom.h b/src/ace_time/hw/CrcEeprom.h index 5c27768cc..7790ccc4c 100644 --- a/src/ace_time/hw/CrcEeprom.h +++ b/src/ace_time/hw/CrcEeprom.h @@ -8,14 +8,18 @@ #if defined(ARDUINO) -#include -#include - +// EEPROM is supported only on certain Arduino boards. In particular, many +// (most?) Arduino Zero compatible boards cannot support EEPROM even on Flash +// emulation because the version of the SAMD21 chip on the board doesn't +// support RWW (read-while-write). #if !defined(AVR) && !defined(ESP8266) && !defined(ESP32) && \ !defined(TEENSYDUINO) - #error Unsupported board type + #error Unsupported architecture #endif +#include +#include + namespace ace_time { namespace hw { From 04e286aa8500fa79fbbcf8637795749517077489 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 16:39:23 -0700 Subject: [PATCH 21/35] CommandLineClock: Combine 'sync' and 'sync_status' commands --- CHANGELOG.md | 6 ++ .../CommandLineClock/CommandLineClock.ino | 79 +++++++++---------- src/ace_time/clock/SystemClock.h | 1 + 3 files changed, 43 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 819825061..c2ed92ada 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,12 @@ # Changelog * Unreleased + * Add documentation about the ZoneManager into `USER_GUIDE.md`. + * Move `DateStrings` string pointers into PROGMEM, saving 42 bytes of RAM. + * Use `SERIAL_PORT_MONITOR` instead of `Serial` everywhere for portability + across different Arduino boards. + * Support SAMD21 boards except for functionality that requires EEPROM which + is missing from the SAMD21 chip. * 0.5 (2019-07-21, TZ DB version 2019a, beta) * Remove over-engineered `SystemClockHeartbeatLoop` and `SystemClockHeartbeatLoop` and replace with just a call to diff --git a/examples/CommandLineClock/CommandLineClock.ino b/examples/CommandLineClock/CommandLineClock.ino index febdb4d13..0fb089e23 100644 --- a/examples/CommandLineClock/CommandLineClock.ino +++ b/examples/CommandLineClock/CommandLineClock.ino @@ -26,8 +26,9 @@ * timezone [manual {offset} | dst (on | off)] | * basic [list] | extended [list] ] * Print or set the currently active TimeZone. - * sync_status - * Print the status of the SystemClockSyncLoop helper. + * sync [status] + * Sync the SystemClock from its external source, or print its sync + status. * wifi (status | connect | config [ssid password]) * Print the ESP8266 or ESP32 wifi connection info. * Connect to the wifi network. @@ -132,26 +133,6 @@ class DateCommand: public CommandHandler { } }; -/** - * Sync command - force SystemClock to sync with its time source - * Usage: - * sync - */ -class SyncCommand: public CommandHandler { - public: - SyncCommand(): - CommandHandler("sync", nullptr) {} - - void run(Print& printer, int /*argc*/, const char** /*argv*/) - const override { - controller.sync(); - printer.print(F("Date set to: ")); - ZonedDateTime currentDateTime = controller.getCurrentDateTime(); - currentDateTime.printTo(printer); - printer.println(); - } -}; - /** * Timezone command. * Usage: @@ -249,31 +230,49 @@ class TimezoneCommand: public CommandHandler { } }; -#if SYNC_TYPE == SYNC_TYPE_MANUAL - /** - * Sync status command. + * Sync command - force SystemClock to sync with its time source * Usage: - * sync_status - print the sync status + * sync */ -class SyncStatusCommand: public CommandHandler { +class SyncCommand: public CommandHandler { public: - SyncStatusCommand(SystemClockSyncLoop& systemClockSyncLoop): - CommandHandler("sync_status", nullptr), - mSystemClockSyncLoop(systemClockSyncLoop) {} + SyncCommand(SystemClock& systemClock): + CommandHandler("sync", "[status]"), + mSystemClock(systemClock) {} - void run(Print& printer, int /*argc*/, const char** /*argv*/) + void run(Print& printer, int argc, const char** argv) const override { - printer.print(F("Seconds since last sync: ")); - printer.println(mSystemClockSyncLoop.getSecondsSinceLastSync()); + if (argc == 1) { + controller.sync(); + printer.print(F("Date set to: ")); + ZonedDateTime currentDateTime = controller.getCurrentDateTime(); + currentDateTime.printTo(printer); + printer.println(); + return; + } + + SHIFT; + if (strcmp(argv[0], "status") == 0) { + printer.print(F("Seconds since last sync: ")); + if (mSystemClock.isInit()) { + acetime_t ago = mSystemClock.getNow() + - mSystemClock.getLastSyncTime(); + printer.println(ago); + } else { + printer.println(F("")); + } + return; + } + + printer.print(F("Unknown argument: ")); + printer.println(argv[0]); } private: - SystemClockSyncLoop& mSystemClockSyncLoop; + SystemClock& mSystemClock; }; -#endif - #if TIME_SOURCE_TYPE == TIME_SOURCE_TYPE_NTP /** @@ -357,22 +356,16 @@ class WifiCommand: public CommandHandler { // Create a list of CommandHandlers. ListCommand listCommand; DateCommand dateCommand; -SyncCommand syncCommand; +SyncCommand syncCommand(systemClock); TimezoneCommand timezoneCommand; #if TIME_SOURCE_TYPE == TIME_SOURCE_TYPE_NTP WifiCommand wifiCommand(controller, ntpTimeProvider); #endif -#if SYNC_TYPE == SYNC_TYPE_MANUAL -SyncStatusCommand syncStatusCommand(systemClockSyncLoop); -#endif const CommandHandler* const COMMANDS[] = { &listCommand, &dateCommand, &syncCommand, -#if SYNC_TYPE == SYNC_TYPE_MANUAL - &syncStatusCommand, -#endif &timezoneCommand, #if TIME_SOURCE_TYPE == TIME_SOURCE_TYPE_NTP &wifiCommand, diff --git a/src/ace_time/clock/SystemClock.h b/src/ace_time/clock/SystemClock.h index 2626d9a58..9aad63dfb 100644 --- a/src/ace_time/clock/SystemClock.h +++ b/src/ace_time/clock/SystemClock.h @@ -93,6 +93,7 @@ class SystemClock: public TimeKeeper { mEpochSeconds = epochSeconds; mPrevMillis = millis(); mIsInit = true; + mLastSyncTime = epochSeconds; backupNow(epochSeconds); } From 57cb40fe9ec95ce2a7990839f0b8f02e8a67dda2 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 16:46:09 -0700 Subject: [PATCH 22/35] CommandLineClock: Use F() strings for Commands subclasses from CommandHandler, saving 128 bytes of RAM on an AVR --- examples/CommandLineClock/CommandLineClock.ino | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/CommandLineClock/CommandLineClock.ino b/examples/CommandLineClock/CommandLineClock.ino index 0fb089e23..6e7cce896 100644 --- a/examples/CommandLineClock/CommandLineClock.ino +++ b/examples/CommandLineClock/CommandLineClock.ino @@ -94,7 +94,7 @@ Controller controller(persistentStore, systemClock); class ListCommand: public CommandHandler { public: ListCommand(): - CommandHandler("list", nullptr) {} + CommandHandler(F("list"), nullptr) {} void run(Print& printer, int /*argc*/, const char** /*argv*/) const override { @@ -111,7 +111,7 @@ class ListCommand: public CommandHandler { class DateCommand: public CommandHandler { public: DateCommand(): - CommandHandler("date", "[dateString]") {} + CommandHandler(F("date"), F("[dateString]")) {} void run(Print& printer, int argc, const char** argv) const override { if (argc == 1) { @@ -146,15 +146,15 @@ class DateCommand: public CommandHandler { class TimezoneCommand: public CommandHandler { public: TimezoneCommand(): - CommandHandler("timezone", - "manual {offset} | " + CommandHandler(F("timezone"), + F("manual {offset} | " #if ENABLE_TIME_ZONE_TYPE_BASIC "basic [list | {index}] | " #endif #if ENABLE_TIME_ZONE_TYPE_EXTENDED "extended [list | {index}] | " #endif - "dst {on | off}]") {} + "dst {on | off}]")) {} void run(Print& printer, int argc, const char** argv) const override { if (argc == 1) { @@ -238,7 +238,7 @@ class TimezoneCommand: public CommandHandler { class SyncCommand: public CommandHandler { public: SyncCommand(SystemClock& systemClock): - CommandHandler("sync", "[status]"), + CommandHandler(F("sync"), F("[status]")), mSystemClock(systemClock) {} void run(Print& printer, int argc, const char** argv) @@ -287,8 +287,8 @@ class WifiCommand: public CommandHandler { WifiCommand( Controller& controller, NtpTimeProvider& ntpTimeProvider): - CommandHandler( - "wifi", "status | (config [ssid password]) | connect" ), + CommandHandler(F("wifi"), + F("status | (config [ssid password]) | connect") ), mController(controller), mNtpTimeProvider(ntpTimeProvider) {} From 0d63a454940903be9f68b3965e0c7a3456c166d9 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 17:20:19 -0700 Subject: [PATCH 23/35] CommandLineClock: Use new SHIFT_ARGC_ARGV() macro and isArgEqual() with Flash string to save another 44 bytes of RAM on an AVR --- .../CommandLineClock/CommandLineClock.ino | 55 +++++++++---------- 1 file changed, 26 insertions(+), 29 deletions(-) diff --git a/examples/CommandLineClock/CommandLineClock.ino b/examples/CommandLineClock/CommandLineClock.ino index 6e7cce896..30edbb039 100644 --- a/examples/CommandLineClock/CommandLineClock.ino +++ b/examples/CommandLineClock/CommandLineClock.ino @@ -87,16 +87,13 @@ Controller controller(persistentStore, systemClock); // AceRoutine CLI commands //--------------------------------------------------------------------------- -/** Shift command arguments to the left by one token. */ -#define SHIFT do { argv++; argc--; } while (false) - /** List the coroutines known by the CoroutineScheduler. */ class ListCommand: public CommandHandler { public: ListCommand(): CommandHandler(F("list"), nullptr) {} - void run(Print& printer, int /*argc*/, const char** /*argv*/) + void run(Print& printer, int /*argc*/, const char* const* /*argv*/) const override { CoroutineScheduler::list(printer); } @@ -113,13 +110,13 @@ class DateCommand: public CommandHandler { DateCommand(): CommandHandler(F("date"), F("[dateString]")) {} - void run(Print& printer, int argc, const char** argv) const override { + void run(Print& printer, int argc, const char* const* argv) const override { if (argc == 1) { ZonedDateTime nowDate = controller.getCurrentDateTime(); nowDate.printTo(printer); printer.println(); } else { - SHIFT; + SHIFT_ARGC_ARGV(argc, argv); ZonedDateTime newDate = ZonedDateTime::forDateString(argv[0]); if (newDate.isError()) { printer.println(F("Invalid date")); @@ -156,7 +153,7 @@ class TimezoneCommand: public CommandHandler { #endif "dst {on | off}]")) {} - void run(Print& printer, int argc, const char** argv) const override { + void run(Print& printer, int argc, const char* const* argv) const override { if (argc == 1) { const TimeZone& timeZone = controller.getTimeZone(); timeZone.printTo(printer); @@ -164,9 +161,9 @@ class TimezoneCommand: public CommandHandler { return; } - SHIFT; - if (strcmp(argv[0], "manual") == 0) { - SHIFT; + SHIFT_ARGC_ARGV(argc, argv); + if (isArgEqual(argv[0], F("manual"))) { + SHIFT_ARGC_ARGV(argc, argv); if (argc == 0) { printer.print(F("'timezone manual' requires 'offset'")); return; @@ -181,9 +178,9 @@ class TimezoneCommand: public CommandHandler { controller.getTimeZone().printTo(printer); printer.println(); #if ENABLE_TIME_ZONE_TYPE_BASIC - } else if (strcmp(argv[0], "basic") == 0) { - SHIFT; - if (argc != 0 && strcmp(argv[0], "list") == 0) { + } else if (isArgEqual(argv[0], F("basic"))) { + SHIFT_ARGC_ARGV(argc, argv); + if (argc != 0 && isArgEqual(argv[0], F("list"))) { controller.printBasicZonesTo(printer); } else { int16_t zoneIndex = (argc == 0) ? 0 : atoi(argv[0]); @@ -194,9 +191,9 @@ class TimezoneCommand: public CommandHandler { } #endif #if ENABLE_TIME_ZONE_TYPE_EXTENDED - } else if (strcmp(argv[0], "extended") == 0) { - SHIFT; - if (argc != 0 && strcmp(argv[0], "list") == 0) { + } else if (isArgEqual(argv[0], F("extended"))) { + SHIFT_ARGC_ARGV(argc, argv); + if (argc != 0 && isArgEqual(argv[0], F("list"))) { controller.printExtendedZonesTo(printer); } else { int16_t zoneIndex = (argc == 0) ? 0 : atoi(argv[0]); @@ -206,17 +203,17 @@ class TimezoneCommand: public CommandHandler { printer.println(); } #endif - } else if (strcmp(argv[0], "dst") == 0) { - SHIFT; + } else if (isArgEqual(argv[0], F("dst"))) { + SHIFT_ARGC_ARGV(argc, argv); if (argc == 0) { printer.print(F("DST: ")); printer.println(controller.isDst() ? F("on") : F("off")); return; } - if (strcmp(argv[0], "on") == 0) { + if (isArgEqual(argv[0], F("on"))) { controller.setDst(true); - } else if (strcmp(argv[0], "off") == 0) { + } else if (isArgEqual(argv[0], F("off"))) { controller.setDst(false); } else { printer.print(F("'timezone dst' must be either 'on' or 'off'")); @@ -241,7 +238,7 @@ class SyncCommand: public CommandHandler { CommandHandler(F("sync"), F("[status]")), mSystemClock(systemClock) {} - void run(Print& printer, int argc, const char** argv) + void run(Print& printer, int argc, const char* const* argv) const override { if (argc == 1) { controller.sync(); @@ -252,8 +249,8 @@ class SyncCommand: public CommandHandler { return; } - SHIFT; - if (strcmp(argv[0], "status") == 0) { + SHIFT_ARGC_ARGV(argc, argv); + if (isArgEqual(argv[0], F("status"))) { printer.print(F("Seconds since last sync: ")); if (mSystemClock.isInit()) { acetime_t ago = mSystemClock.getNow() @@ -293,12 +290,12 @@ class WifiCommand: public CommandHandler { mNtpTimeProvider(ntpTimeProvider) {} - void run(Print& printer, int argc, const char** argv) const override { - SHIFT; + void run(Print& printer, int argc, const char* const* argv) const override { + SHIFT_ARGC_ARGV(argc, argv); if (argc == 0) { printer.println(F("Must give either 'status' or 'config' command")); - } else if (strcmp(argv[0], "config") == 0) { - SHIFT; + } else if (isArgEqual(argv[0], F("config"))) { + SHIFT_ARGC_ARGV(argc, argv); if (argc == 0) { if (mController.isStoredInfoValid()) { // print ssid and password @@ -319,14 +316,14 @@ class WifiCommand: public CommandHandler { } else { printer.println(F("Wifi config command requires 2 arguments")); } - } else if (strcmp(argv[0], "status") == 0) { + } else if (isArgEqual(argv[0], F("status"))) { printer.print(F("NtpTimeProvider::isSetup(): ")); printer.println(mNtpTimeProvider.isSetup() ? F("true") : F("false")); printer.print(F("NTP Server: ")); printer.println(mNtpTimeProvider.getServer()); printer.print(F("WiFi IP address: ")); printer.println(WiFi.localIP()); - } else if (strcmp(argv[0], "connect") == 0) { + } else if (isArgEqual(argv[0], F("connect"))) { connect(printer); } else { printer.print(F("Unknown wifi command: ")); From f8797f60fd1d9b25f857f51eece2f21d7067e648 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 17:47:05 -0700 Subject: [PATCH 24/35] OledClock: Move EEPROM logic into new PersistentStore.h, and disable EEPROM for SAMD21; OledClock works on SAMD21! --- examples/OledClock/Controller.h | 23 +++++------ examples/OledClock/OledClock.ino | 13 ++---- examples/OledClock/PersistentStore.h | 60 ++++++++++++++++++++++++++++ examples/OledClock/config.h | 5 +++ tests/auniter.ini | 4 +- 5 files changed, 81 insertions(+), 24 deletions(-) create mode 100644 examples/OledClock/PersistentStore.h diff --git a/examples/OledClock/Controller.h b/examples/OledClock/Controller.h index 4507b2301..5dc196d96 100644 --- a/examples/OledClock/Controller.h +++ b/examples/OledClock/Controller.h @@ -2,11 +2,11 @@ #define OLED_CLOCK_CONTROLLER_H #include -#include #include "config.h" #include "ClockInfo.h" #include "RenderingInfo.h" #include "StoredInfo.h" +#include "PersistentStore.h" #include "Presenter.h" using namespace ace_time; @@ -31,14 +31,14 @@ class Controller { /** * Constructor. + * @param persistentStore stores objects into the EEPROM with CRC * @param timeKeeper source of the current time - * @param crcEeprom stores objects into the EEPROM with CRC * @param presenter renders the date and time info to the screen */ - Controller(TimeKeeper& timeKeeper, hw::CrcEeprom& crcEeprom, + Controller(PersistentStore& persistentStore, TimeKeeper& timeKeeper, Presenter& presenter): + mPersistentStore(persistentStore), mTimeKeeper(timeKeeper), - mCrcEeprom(crcEeprom), mPresenter(presenter) #if TIME_ZONE_TYPE == TIME_ZONE_TYPE_BASIC \ || TIME_ZONE_TYPE == TIME_ZONE_TYPE_EXTENDED @@ -49,8 +49,7 @@ class Controller { void setup() { // Restore from EEPROM to retrieve time zone. StoredInfo storedInfo; - bool isValid = mCrcEeprom.readWithCrc(kStoredInfoEepromAddress, - &storedInfo, sizeof(StoredInfo)); + bool isValid = mPersistentStore.readStoredInfo(storedInfo); #if FORCE_INITIALIZE setupClockInfo(); #else @@ -181,7 +180,7 @@ class Controller { // Switch 12/24 modes if in MODE_DATA_TIME case MODE_DATE_TIME: mClockInfo.hourMode ^= 0x1; - preserveClockInfo(mCrcEeprom, mClockInfo); + preserveClockInfo(mClockInfo); break; case MODE_CHANGE_YEAR: @@ -360,20 +359,18 @@ class Controller { SERIAL_PORT_MONITOR.println(F("saveClockInfo()")); #endif mClockInfo = mChangingClockInfo; - preserveClockInfo(mCrcEeprom, mClockInfo); + preserveClockInfo(mClockInfo); } /** Save the clock info into EEPROM. */ - static void preserveClockInfo(hw::CrcEeprom& crcEeprom, - const ClockInfo& clockInfo) { + void preserveClockInfo(const ClockInfo& clockInfo) { #if ENABLE_SERIAL == 1 SERIAL_PORT_MONITOR.println(F("preserveClockInfo()")); #endif StoredInfo storedInfo; storedInfo.hourMode = clockInfo.hourMode; storedInfo.timeZoneData = clockInfo.timeZone.toTimeZoneData(); - crcEeprom.writeWithCrc(kStoredInfoEepromAddress, &storedInfo, - sizeof(StoredInfo)); + mPersistentStore.writeStoredInfo(storedInfo); } /** Restore clockInfo from storedInfo. */ @@ -448,8 +445,8 @@ class Controller { restoreClockInfo(mClockInfo, storedInfo); } + PersistentStore& mPersistentStore; TimeKeeper& mTimeKeeper; - hw::CrcEeprom& mCrcEeprom; Presenter& mPresenter; #if TIME_ZONE_TYPE == TIME_ZONE_TYPE_BASIC diff --git a/examples/OledClock/OledClock.ino b/examples/OledClock/OledClock.ino index 958c346ca..4abe9af59 100644 --- a/examples/OledClock/OledClock.ino +++ b/examples/OledClock/OledClock.ino @@ -28,8 +28,8 @@ #include #include #include -#include #include "config.h" +#include "PersistentStore.h" #include "Presenter.h" #include "Controller.h" @@ -38,12 +38,6 @@ using namespace ace_routine; using namespace ace_time; using namespace ace_time::clock; -//------------------------------------------------------------------ -// Configure CrcEeprom. -//------------------------------------------------------------------ - -hw::CrcEeprom crcEeprom; - //------------------------------------------------------------------ // Configure various TimeKeepers and TimeProviders. //------------------------------------------------------------------ @@ -85,8 +79,9 @@ void setupOled() { // Create controller/presenter pair. //------------------------------------------------------------------ +PersistentStore persistentStore; Presenter presenter(oled); -Controller controller(systemClock, crcEeprom, presenter); +Controller controller(persistentStore, systemClock, presenter); //------------------------------------------------------------------ // Render the Clock periodically. @@ -195,7 +190,6 @@ void setup() { Wire.begin(); Wire.setClock(400000L); - crcEeprom.begin(EEPROM_SIZE); setupAceButton(); setupOled(); @@ -210,6 +204,7 @@ void setup() { #endif systemClock.setup(); controller.setup(); + persistentStore.setup(); systemClockSync.setupCoroutine(F("s")); CoroutineScheduler::setup(); diff --git a/examples/OledClock/PersistentStore.h b/examples/OledClock/PersistentStore.h new file mode 100644 index 000000000..07ee5e964 --- /dev/null +++ b/examples/OledClock/PersistentStore.h @@ -0,0 +1,60 @@ +#ifndef OLED_CLOCK_PERSISTENT_STORE_H +#define OLED_CLOCK_PERSISTENT_STORE_H + +#include +#if ! defined(ARDUINO_ARCH_SAMD) + #include +#endif +#include "config.h" +#include "StoredInfo.h" + +using namespace ace_time; + +class PersistentStore { + public: + void setup() { + #if ! defined(ARDUINO_ARCH_SAMD) + // Needed for ESP32 + mCrcEeprom.begin(kEepromSize); + #endif + } + + #if defined(ARDUINO_ARCH_SAMD) + bool readStoredInfo(StoredInfo& /*storedInfo*/) const { + return false; + } + #else + bool readStoredInfo(StoredInfo& storedInfo) const { + bool isValid = mCrcEeprom.readWithCrc(kStoredInfoEepromAddress, + &storedInfo, sizeof(StoredInfo)); + #if TIME_SOURCE_TYPE == TIME_SOURCE_TYPE_NTP + storedInfo.ssid[StoredInfo::kSsidMaxLength - 1] = '\0'; + storedInfo.password[StoredInfo::kPasswordMaxLength - 1] = '\0'; + #endif + return isValid; + } + #endif + + #if defined(ARDUINO_ARCH_SAMD) + uint16_t writeStoredInfo(const StoredInfo& /*storedInfo*/) const { + return 0; + } + #else + uint16_t writeStoredInfo(const StoredInfo& storedInfo) const { + return mCrcEeprom.writeWithCrc(kStoredInfoEepromAddress, &storedInfo, + sizeof(StoredInfo)); + } + #endif + + private: + #if ! defined(ARDUINO_ARCH_SAMD) + static const uint16_t kStoredInfoEepromAddress = 0; + + // Must be >= (sizeof(StoredInfo) + 4). + static const uint8_t kEepromSize = sizeof(StoredInfo) + 4; + + hw::CrcEeprom mCrcEeprom; + #endif +}; + +#endif diff --git a/examples/OledClock/config.h b/examples/OledClock/config.h index 9a55c8497..a8c7dbcc7 100644 --- a/examples/OledClock/config.h +++ b/examples/OledClock/config.h @@ -46,6 +46,11 @@ #define CHANGE_BUTTON_PIN 3 #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231 #define OLED_REMAP false +#elif defined(AUNITER_SAMD) + #define MODE_BUTTON_PIN 11 + #define CHANGE_BUTTON_PIN 10 + #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231 + #define OLED_REMAP true #elif defined(AUNITER_ESP8266) || defined(AUNITER_ESP_MINDER) #define MODE_BUTTON_PIN D4 #define CHANGE_BUTTON_PIN D3 diff --git a/tests/auniter.ini b/tests/auniter.ini index 5ce277aa5..48d86375c 100644 --- a/tests/auniter.ini +++ b/tests/auniter.ini @@ -34,12 +34,12 @@ preprocessor = -DAUNITER_MICRO exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock -# SAMD M0 Mini does not have EEPROM.h, so cannot compile OledClock, WorldClock +# SAMD M0 Mini does not have EEPROM so cannot compile WorldClock currently. [env:samd] board = samd locking = false preprocessor = -DAUNITER_SAMD - exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock|WorldClock + exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|WorldClock # Disable ComparisonBenchmark on ESP8266 due to broken Arduino Time Library. [env:esp8266] From 7c05544b165a9ffce34b654a29dbf5dbc2ef723c Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 20:52:00 -0700 Subject: [PATCH 25/35] OledClock: Fix buid failure for ESP32 due to copy-and-paste error from CommandLineClock --- examples/OledClock/PersistentStore.h | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/examples/OledClock/PersistentStore.h b/examples/OledClock/PersistentStore.h index 07ee5e964..2179be72a 100644 --- a/examples/OledClock/PersistentStore.h +++ b/examples/OledClock/PersistentStore.h @@ -19,32 +19,27 @@ class PersistentStore { #endif } - #if defined(ARDUINO_ARCH_SAMD) + #if defined(ARDUINO_ARCH_SAMD) bool readStoredInfo(StoredInfo& /*storedInfo*/) const { return false; } - #else + #else bool readStoredInfo(StoredInfo& storedInfo) const { - bool isValid = mCrcEeprom.readWithCrc(kStoredInfoEepromAddress, + return mCrcEeprom.readWithCrc(kStoredInfoEepromAddress, &storedInfo, sizeof(StoredInfo)); - #if TIME_SOURCE_TYPE == TIME_SOURCE_TYPE_NTP - storedInfo.ssid[StoredInfo::kSsidMaxLength - 1] = '\0'; - storedInfo.password[StoredInfo::kPasswordMaxLength - 1] = '\0'; - #endif - return isValid; } - #endif + #endif - #if defined(ARDUINO_ARCH_SAMD) + #if defined(ARDUINO_ARCH_SAMD) uint16_t writeStoredInfo(const StoredInfo& /*storedInfo*/) const { return 0; } - #else + #else uint16_t writeStoredInfo(const StoredInfo& storedInfo) const { return mCrcEeprom.writeWithCrc(kStoredInfoEepromAddress, &storedInfo, sizeof(StoredInfo)); } - #endif + #endif private: #if ! defined(ARDUINO_ARCH_SAMD) From 7bdd8eb455a431d11d3ef49d7d870d6e111528e2 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 21:24:52 -0700 Subject: [PATCH 26/35] USER_GUIDE.md: Add link to instructions for installing SparkFun SAMD boards --- USER_GUIDE.md | 10 ++++++---- examples/MemoryBenchmark/collect.sh | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/USER_GUIDE.md b/USER_GUIDE.md index e37e61167..58e7dee4a 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -2599,10 +2599,12 @@ did not think it would fit inside an Arduino controller. * If you are using a SAMD21 development or breakout board, or one of the many clones called something like "Ardunio SAMD21 M0 Mini" (this is what I have), I have found things working better using the SparkFun - configurations. Download "SparkFun SAMD Boards" using the Board Manager, - then select the board labeled "SparkFun SAMD Mini Breakout". These - boards have only a single USB connector, and the `SERIAL_PORT_MONITOR` - will be properly defined to be `SerialUSB`. + configurations. Download "SparkFun SAMD Boards" using the Board Manager + by following the [SparkFun Boards + Installation](https://github.com/sparkfun/Arduino_Boards), then select the + board labeled "SparkFun SAMD Mini Breakout". These boards have only a + single USB connector, and the `SERIAL_PORT_MONITOR` will be properly + defined to be `SerialUSB`. * The SAMD21 microcontroller does not provide any EEPROM. Therefore, some of the more realistic example apps (e.g. CommandLineClock, OledClock, and WorldClock) do not build on the SAMD21. diff --git a/examples/MemoryBenchmark/collect.sh b/examples/MemoryBenchmark/collect.sh index 5d25612ee..38d3eb82c 100755 --- a/examples/MemoryBenchmark/collect.sh +++ b/examples/MemoryBenchmark/collect.sh @@ -4,7 +4,7 @@ # and collects the flash memory and static RAM usage for each of # the FEATURE (0..10). # -# Usage: collect.sh {board} ... +# Usage: collect.sh {board} {result_file} # # Creates a ${board}.out file containing: # From d2dd65b9dacdddc528f3563f17421f40d1d194c4 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 22:08:00 -0700 Subject: [PATCH 27/35] examples: Update various config.h to behave better when using Arduino IDE in interactive mode --- examples/CommandLineClock/config.h | 2 +- examples/OledClock/config.h | 12 +++++++----- examples/WorldClock/config.h | 9 +++++---- src/ace_time/common/compat.cpp | 2 +- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/examples/CommandLineClock/config.h b/examples/CommandLineClock/config.h index 40c89b883..2b97a36b1 100644 --- a/examples/CommandLineClock/config.h +++ b/examples/CommandLineClock/config.h @@ -21,7 +21,7 @@ // ExtendedZoneProcessor at the same time. #ifndef AUNITER - #warning Using Arduino IDE configuration + // Arduino IDE in interactive mode #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231 #define ENABLE_TIME_ZONE_TYPE_BASIC 1 #define ENABLE_TIME_ZONE_TYPE_EXTENDED 1 diff --git a/examples/OledClock/config.h b/examples/OledClock/config.h index a8c7dbcc7..f5affcbb2 100644 --- a/examples/OledClock/config.h +++ b/examples/OledClock/config.h @@ -26,12 +26,14 @@ #define TIME_SOURCE_TYPE_DS3231 1 #define TIME_SOURCE_TYPE_NTP 2 #define TIME_SOURCE_TYPE_BOTH 3 -#ifndef AUNITER - #define AUNITER_MICRO_MINDER - #warning Using default AUNITER_MICRO_MINDER -#endif -#if defined(AUNITER_NANO) +#ifndef AUNITER + // Arduino IDE in interactive mode + #define MODE_BUTTON_PIN 2 + #define CHANGE_BUTTON_PIN 3 + #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231 + #define OLED_REMAP false +#elif defined(AUNITER_NANO) #define MODE_BUTTON_PIN 2 #define CHANGE_BUTTON_PIN 3 #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231 diff --git a/examples/WorldClock/config.h b/examples/WorldClock/config.h index 39b1041bf..41b48b702 100644 --- a/examples/WorldClock/config.h +++ b/examples/WorldClock/config.h @@ -7,9 +7,10 @@ #define ENABLE_SERIAL 0 -// This program should compile for most target environments, including -// AVR, ESP8266, and ESP32. The parameters below are for a Pro Micro -// with 3 OLED displays. +// This program should compile for most target environments, including AVR, +// ESP8266, and ESP32. The parameters below are for the specific device that I +// built which has a Pro Micro with 3 OLED displays using SPI, a DS3231 over +// I2C, and 2 buttons. #define MODE_BUTTON_PIN 8 #define CHANGE_BUTTON_PIN 9 #define TIME_SOURCE_TYPE TIME_SOURCE_TYPE_DS3231 @@ -20,7 +21,7 @@ #define OLED_RST_PIN 4 #define OLED_DC_PIN 10 -// Whether to use ManualTimeZone or AutoTimeZone +// Whether to use Manual TimeZone, Basic TimeZone or Extended TimeZone. #define TIME_ZONE_TYPE_MANUAL 0 #define TIME_ZONE_TYPE_BASIC 1 #define TIME_ZONE_TYPE_EXTENDED 2 diff --git a/src/ace_time/common/compat.cpp b/src/ace_time/common/compat.cpp index a734fedb1..97cd3f333 100644 --- a/src/ace_time/common/compat.cpp +++ b/src/ace_time/common/compat.cpp @@ -4,7 +4,7 @@ // ARDUINO_SAMD_ZERO. The original Arduino Zero using Native USB Port // does not set SERIAL_PORT_MONITOR correctly, so warn the user. #if defined(ARDUINO_SAMD_ZERO) - #warning See USER_GUIDE.md about SERIAL_PORT_MONITOR if using an Arduino Zero (ignore if using a dev board from SparkFun or others) + #warning Arduino Zero may need SERIAL_PORT_MONITOR fixed (see USER_GUIDE.md) #endif #if defined(ESP8266) || defined(ESP32) From 1569b955e9e82f7da2eeb17d7eb9879f7ac8f512 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 22:20:05 -0700 Subject: [PATCH 28/35] README.md, USE_GUIDE.md: Note that SAMD is a fully supported board --- README.md | 21 +++++++++------------ USER_GUIDE.md | 14 +++++++------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 2678eea8c..534dce84d 100644 --- a/README.md +++ b/README.md @@ -403,10 +403,12 @@ See the [AceTime User Guide](USER_GUIDE.md) for information on: This library was developed and tested using: * [Arduino IDE 1.8.9](https://www.arduino.cc/en/Main/Software) -* [Arduino AVR Core 1.6.23](https://github.com/arduino/ArduinoCore-avr) -* [SparkFun AVR Core 1.1.12](https://github.com/sparkfun/Arduino_Boards) -* [ESP8266 Arduino Core 2.5.2](https://github.com/esp8266/Arduino) -* [ESP32 Arduino Core 1.0.2](https://github.com/espressif/arduino-esp32) +* [Arduino AVR Boards 1.6.23](https://github.com/arduino/ArduinoCore-avr) +* [Arduino SAMD Boards 1.8.3](https://github.com/arduino/ArduinoCore-samd) +* [SparkFun AVR Boards 1.1.12](https://github.com/sparkfun/Arduino_Boards) +* [SparkFun SAMD Boards 1.6.2](https://github.com/sparkfun/Arduino_Boards) +* [ESP8266 Arduino 2.5.2](https://github.com/esp8266/Arduino) +* [ESP32 Arduino 1.0.2](https://github.com/espressif/arduino-esp32) * [Teensydino 1.46](https://www.pjrc.com/teensy/td_download.html) It should work with [PlatformIO](https://platformio.org/) but I have @@ -419,24 +421,19 @@ library will work fine under MacOS and Windows, but I have not tested them. ### Hardware -The library is fully tested on the following boards: +The library is extensively tested on the following boards: * Arduino Nano clone (16 MHz ATmega328P) * SparkFun Pro Micro clone (16 MHz ATmega32U4) * WeMos D1 Mini clone (ESP-12E module, 80 MHz ESP8266) * ESP32 dev board (ESP-WROOM-32 module, 240 MHz dual core Tensilica LX6) +* SAMD21 M0 Mini (48 MHz ARM Cortex-M0+) (compatible with Arduino Zero) (See + notes in the [USER_GUIDE.md](USER_GUIDE.md) for some potential issues.) I will occasionally test on the following hardware as a sanity check: * Teensy 3.2 (72 MHz ARM Cortex-M4) -The following boards may have some incompatibilities: - -* Arduino Zero compatible SAMD21 M0 Mini (48 MHz ARM Cortex-M0+) - * All unit tests pass. - * Some sketches in `examples` do not compile because the SAMD21 does - not have an EEPROM. - ## Changelog See [CHANGELOG.md](CHANGELOG.md). diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 58e7dee4a..254d7f9a5 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -2579,8 +2579,8 @@ did not think it would fit inside an Arduino controller. `ZonedDateTime::printTo()` will print "[America/Los_Angeles]" not "[US/Pacific]". * Arduino Zero and SAMD21 Boards - * Some amount of support for the SAMD21 boards - (which all identify themselves as `ARDUINO_SAMD_ZERO`) has been added. + * SAMD21 boards (which all identify themselves as `ARDUINO_SAMD_ZERO`) are + fully supported, but there are some tricky points. * If you are using an original Arduino Zero and using the "Native USB Port", you may encounter problems with nothing showing up on the Serial Monitor. * The original Arduino Zero has [2 USB @@ -2599,12 +2599,12 @@ did not think it would fit inside an Arduino controller. * If you are using a SAMD21 development or breakout board, or one of the many clones called something like "Ardunio SAMD21 M0 Mini" (this is what I have), I have found things working better using the SparkFun - configurations. Download "SparkFun SAMD Boards" using the Board Manager - by following the [SparkFun Boards + Boards instead of the Arduino Zero board. Download "SparkFun SAMD Boards" + using the Board Manager by following the [SparkFun Boards Installation](https://github.com/sparkfun/Arduino_Boards), then select the board labeled "SparkFun SAMD Mini Breakout". These boards have only a single USB connector, and the `SERIAL_PORT_MONITOR` will be properly defined to be `SerialUSB`. - * The SAMD21 microcontroller does not provide any EEPROM. Therefore, - some of the more realistic example apps (e.g. CommandLineClock, OledClock, - and WorldClock) do not build on the SAMD21. + * The SAMD21 microcontroller does *not* provide any EEPROM. Therefore, + this feature is disabled in the apps under `examples` (e.g. + `CommandLineClock`, `OledClock`, and `WorldClock`) which use this feature. From 4905cd02c51c0ea3c9dda21805642aa1c2d38335 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 22:26:29 -0700 Subject: [PATCH 29/35] tests/TimeZoneTest: Fix broken compile on SAMD21 due to different integer size --- tests/TimeZoneTest/TimeZoneTest.ino | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/TimeZoneTest/TimeZoneTest.ino b/tests/TimeZoneTest/TimeZoneTest.ino index 48b7347d5..44c101de7 100644 --- a/tests/TimeZoneTest/TimeZoneTest.ino +++ b/tests/TimeZoneTest/TimeZoneTest.ino @@ -173,7 +173,7 @@ test(TimeZoneBasicTest, createFor) { assertTrue(a == aa); assertTrue(b == bb); - assertEqual(0x1e2a7654U, bb.getZoneId()); + assertEqual((uint32_t) 0x1e2a7654U, bb.getZoneId()); } test(TimeZoneBasicTest, Los_Angeles) { @@ -244,7 +244,7 @@ test(TimeZoneDataTest, basicManaged) { &zonedb::kZoneAmerica_Los_Angeles); auto tzd = tz.toTimeZoneData(); assertEqual(TimeZoneData::kTypeZoneId, tzd.type); - assertEqual(0xb7f7e8f2, tzd.zoneId); + assertEqual((uint32_t) 0xb7f7e8f2, tzd.zoneId); auto tzCycle = basicZoneManager.createForTimeZoneData(tzd); assertTrue(tz == tzCycle); @@ -256,7 +256,7 @@ test(TimeZoneDataTest, extendedManaged) { &zonedbx::kZoneAmerica_Los_Angeles); auto tzd = tz.toTimeZoneData(); assertEqual(TimeZoneData::kTypeZoneId, tzd.type); - assertEqual(0xb7f7e8f2, tzd.zoneId); + assertEqual((uint32_t) 0xb7f7e8f2, tzd.zoneId); auto tzCycle = extendedZoneManager.createForTimeZoneData(tzd); assertTrue(tz == tzCycle); @@ -269,10 +269,10 @@ test(TimeZoneDataTest, crossed) { &zonedbx::kZoneAmerica_Los_Angeles); auto tzd = tz.toTimeZoneData(); assertEqual(TimeZoneData::kTypeZoneId, tzd.type); - assertEqual(0xb7f7e8f2, tzd.zoneId); + assertEqual((uint32_t) 0xb7f7e8f2, tzd.zoneId); auto tzCycle = basicZoneManager.createForTimeZoneData(tzd); - assertTrue(tz.getZoneId() == tzCycle.getZoneId()); + assertEqual(tz.getZoneId(), tzCycle.getZoneId()); assertEqual(TimeZone::kTypeBasicManaged, tzCycle.getType()); } #endif From 76a7e819f77a1b5a1b26668b237c793ad1d232b1 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 22:32:53 -0700 Subject: [PATCH 30/35] tests/ExtendedZoneProcessorTest: Fix SAMD compiler warnings about empty DateTuple --- .../ExtendedZoneProcessorTest.ino | 34 +++++++++++-------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/tests/ExtendedZoneProcessorTest/ExtendedZoneProcessorTest.ino b/tests/ExtendedZoneProcessorTest/ExtendedZoneProcessorTest.ino index 35eb381bf..dcdc38111 100644 --- a/tests/ExtendedZoneProcessorTest/ExtendedZoneProcessorTest.ino +++ b/tests/ExtendedZoneProcessorTest/ExtendedZoneProcessorTest.ino @@ -398,6 +398,8 @@ test(ExtendedZoneProcessorTest, getMostRecentPriorYear) { } test(ExtendedZoneProcessorTest, compareTransitionToMatchFuzzy) { + const DateTuple EMPTY_DATE = { 0, 0, 0, 0, 0}; + const ZoneMatch match = { {0, 1, 1, 0, 'w'} /* startDateTime */, {1, 1, 1, 0, 'w'} /* untilDateTime */, @@ -407,7 +409,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatchFuzzy) { Transition transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {-1, 11, 1, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(-1, ExtendedZoneProcessor::compareTransitionToMatchFuzzy( &transition, &match)); @@ -415,7 +417,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatchFuzzy) { transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {-1, 12, 1, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(1, ExtendedZoneProcessor::compareTransitionToMatchFuzzy( &transition, &match)); @@ -423,7 +425,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatchFuzzy) { transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {0, 1, 1, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(1, ExtendedZoneProcessor::compareTransitionToMatchFuzzy( &transition, &match)); @@ -431,7 +433,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatchFuzzy) { transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {1, 1, 1, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(1, ExtendedZoneProcessor::compareTransitionToMatchFuzzy( &transition, &match)); @@ -439,7 +441,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatchFuzzy) { transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {1, 2, 1, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(1, ExtendedZoneProcessor::compareTransitionToMatchFuzzy( &transition, &match)); @@ -447,7 +449,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatchFuzzy) { transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {1, 3, 1, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(2, ExtendedZoneProcessor::compareTransitionToMatchFuzzy( &transition, &match)); @@ -455,6 +457,8 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatchFuzzy) { test(ExtendedZoneProcessorTest, compareTransitionToMatch) { + const DateTuple EMPTY_DATE = { 0, 0, 0, 0, 0}; + const ZoneMatch match = { {0, 1, 1, 0, 'w'} /*startDateTime*/, {1, 1, 1, 0, 'w'} /*untilDateTime*/, @@ -464,7 +468,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatch) { Transition transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {-1, 12, 31, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(-1, ExtendedZoneProcessor::compareTransitionToMatch( &transition, &match)); @@ -472,7 +476,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatch) { transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {0, 1, 1, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(0, ExtendedZoneProcessor::compareTransitionToMatch( &transition, &match)); @@ -480,7 +484,7 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatch) { transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {0, 1, 2, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(1, ExtendedZoneProcessor::compareTransitionToMatch( &transition, &match)); @@ -488,13 +492,15 @@ test(ExtendedZoneProcessorTest, compareTransitionToMatch) { transition = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {1, 1, 2, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertEqual(2, ExtendedZoneProcessor::compareTransitionToMatch( &transition, &match)); } test(ExtendedZoneProcessorTest, processActiveTransition) { + const DateTuple EMPTY_DATE = { 0, 0, 0, 0, 0}; + Transition* prior = nullptr; const ZoneMatch match = { {0, 1, 1, 0, 'w'} /*startDateTime*/, @@ -506,7 +512,7 @@ test(ExtendedZoneProcessorTest, processActiveTransition) { Transition transition0 = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {-1, 12, 31, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; ExtendedZoneProcessor::processActiveTransition(&match, &transition0, &prior); assertTrue(transition0.active); @@ -516,7 +522,7 @@ test(ExtendedZoneProcessorTest, processActiveTransition) { Transition transition1 = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {0, 1, 1, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; ExtendedZoneProcessor::processActiveTransition(&match, &transition1, &prior); assertTrue(transition1.active); @@ -526,7 +532,7 @@ test(ExtendedZoneProcessorTest, processActiveTransition) { Transition transition2 = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {0, 1, 2, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; ExtendedZoneProcessor::processActiveTransition(&match, &transition2, &prior); assertTrue(transition2.active); @@ -536,7 +542,7 @@ test(ExtendedZoneProcessorTest, processActiveTransition) { Transition transition3 = { &match /*match*/, extended::ZoneRuleBroker(nullptr) /*rule*/, {1, 1, 2, 0, 'w'} /*transitionTime*/, - {}, {}, {}, {0}, {0}, 0, false, 0, 0 + EMPTY_DATE, EMPTY_DATE, EMPTY_DATE, {0}, {0}, 0, false, 0, 0 }; assertFalse(transition3.active); assertTrue(prior == &transition1); From 4cecff6fe60c3b9701c51335609b535ed45ac5e7 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 22:41:49 -0700 Subject: [PATCH 31/35] tests/auniter.ini: Disable CrcEepromDemo for SAMD (no EEPROM), but add *ZoneRegistrarTest since SAMD21 has enough flash --- tests/auniter.ini | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auniter.ini b/tests/auniter.ini index 48d86375c..819ec8aa3 100644 --- a/tests/auniter.ini +++ b/tests/auniter.ini @@ -26,20 +26,20 @@ exclude = BasicValidation.*Test|ExtendedValidation.*Test|ExtendedZoneRegistrarTest -# Disable *ZoneRegistrarTest, *ZoneRegistrarTest, and OledClock which are too -# big for a Pro Micro. +# Disable BasicZoneRegistrarTest, ExtendedZoneRegistrarTest, and OledClock +# which are too big for a Pro Micro. [env:micro] board = promicro16 locking = false preprocessor = -DAUNITER_MICRO exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock -# SAMD M0 Mini does not have EEPROM so cannot compile WorldClock currently. +# SAMD M0 Mini does not have EEPROM, disable tests or apps which require it. [env:samd] board = samd locking = false preprocessor = -DAUNITER_SAMD - exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|WorldClock + exclude = BasicValidation.*Test|ExtendedValidation.*Test|CrcEepromDemo|WorldClock # Disable ComparisonBenchmark on ESP8266 due to broken Arduino Time Library. [env:esp8266] From ce41ddc3e0ae4020e44651f47788d228c5bc1836 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Tue, 23 Jul 2019 23:01:00 -0700 Subject: [PATCH 32/35] test/auniter.ini: Disable ComparisonBenchmark on SAMD because does not compile on it --- tests/auniter.ini | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/auniter.ini b/tests/auniter.ini index 819ec8aa3..54f144ac6 100644 --- a/tests/auniter.ini +++ b/tests/auniter.ini @@ -35,11 +35,13 @@ exclude = BasicValidation.*Test|ExtendedValidation.*Test|*ZoneRegistrarTest|OledClock # SAMD M0 Mini does not have EEPROM, disable tests or apps which require it. +# Disable ComparisonBenchmark because the Ardunio Time Library does not compile +# on a SAMD. [env:samd] board = samd locking = false preprocessor = -DAUNITER_SAMD - exclude = BasicValidation.*Test|ExtendedValidation.*Test|CrcEepromDemo|WorldClock + exclude = BasicValidation.*Test|ExtendedValidation.*Test|ComparisonBenchmark|CrcEepromDemo|WorldClock # Disable ComparisonBenchmark on ESP8266 due to broken Arduino Time Library. [env:esp8266] From 9f6bc2d4d3a9e72feb79d6a598c7de898406c7ce Mon Sep 17 00:00:00 2001 From: Brian Park Date: Wed, 24 Jul 2019 08:37:40 -0700 Subject: [PATCH 33/35] MemoryBenchmark: Add memory consumption numbers for SAMD21 board --- examples/MemoryBenchmark/README.md | 37 ++++++++++++++++++++++++++---- examples/MemoryBenchmark/samd.txt | 11 +++++++++ 2 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 examples/MemoryBenchmark/samd.txt diff --git a/examples/MemoryBenchmark/README.md b/examples/MemoryBenchmark/README.md index e193f4837..c082bfe43 100644 --- a/examples/MemoryBenchmark/README.md +++ b/examples/MemoryBenchmark/README.md @@ -16,7 +16,7 @@ hand since Teensyduino does not seem to allow headless operation.) * AceTime 0.5 * Arduino IDE 1.8.9 -* AVR Core 1.6.23 +* Arduino AVR Boards 1.6.23 ``` +--------------------------------------------------------------+ @@ -42,7 +42,7 @@ hand since Teensyduino does not seem to allow headless operation.) * AceTime 0.5 * Arduino IDE 1.8.9 -* AVR Core 1.6.23 +* SparkFun AVR Boards 1.1.12 ``` +--------------------------------------------------------------+ @@ -64,12 +64,39 @@ hand since Teensyduino does not seem to allow headless operation.) +--------------------------------------------------------------+ ``` +## SAMD21 M0 Mini + +* AceTime 0.5.1 +* Arduino IDE 1.8.9 +* SparkFun SAMD Boards 1.6.2 + +``` ++--------------------------------------------------------------+ +| Functionality | flash/ram | Delta | +|---------------------------------+--------------+-------------| +| Baseline | 10072/ 0 | 0/ 0 | +|---------------------------------+--------------+-------------| +| LocalDateTime | 10928/ 0 | 856/ 0 | +| ZonedDateTime | 11168/ 0 | 1096/ 0 | +| Basic TimeZone | 15060/ 0 | 4988/ 0 | +| Basic TimeZone (2 zones) | 15460/ 0 | 5388/ 0 | +| Basic TimeZone (all zones) | 37260/ 0 | 27188/ 0 | +| Extended TimeZone | 16764/ 0 | 6692/ 0 | +| Extended TimeZone (2 zones) | 17212/ 0 | 7140/ 0 | +| Extended TimeZone (all zones) | 54852/ 0 | 44780/ 0 | +|---------------------------------+--------------+-------------| +| SystemClock | 13208/ 0 | 3136/ 0 | +| SystemClock+Basic TimeZone | 16636/ 0 | 6564/ 0 | ++--------------------------------------------------------------+ +``` + +(SAMD compiler does not produce RAM usage numbers.) + ## ESP8266 * AceTime 0.5 * Arduino IDE 1.8.9 -* ESP8266 Core 2.5.2 -* ESP32 Core 1.0.2 +* ESP8266 Boards 2.5.2 ``` +--------------------------------------------------------------+ @@ -95,7 +122,7 @@ hand since Teensyduino does not seem to allow headless operation.) * AceTime 0.5 * Arduino IDE 1.8.9 -* ESP32 Core 1.0.2 +* ESP32 Boards 1.0.2 ``` +--------------------------------------------------------------+ diff --git a/examples/MemoryBenchmark/samd.txt b/examples/MemoryBenchmark/samd.txt new file mode 100644 index 000000000..9c423542a --- /dev/null +++ b/examples/MemoryBenchmark/samd.txt @@ -0,0 +1,11 @@ +0 10072 262144 +1 10928 262144 +2 11168 262144 +3 15060 262144 +4 15460 262144 +5 37260 262144 +6 16764 262144 +7 17212 262144 +8 54852 262144 +9 13208 262144 +10 16636 262144 From b1af7a2943a57b24a79471cda8f16af4df125356 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Wed, 24 Jul 2019 08:40:46 -0700 Subject: [PATCH 34/35] Bump version to 0.5.1 --- CHANGELOG.md | 5 ++--- README.md | 2 +- USER_GUIDE.md | 2 +- docs/doxygen.cfg | 2 +- library.properties | 2 +- src/AceTime.h | 4 ++-- 6 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2ed92ada..7d50d9a62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,11 @@ # Changelog -* Unreleased +* 0.5.1 (2019-07-24, TZ DB version 2019a, beta) * Add documentation about the ZoneManager into `USER_GUIDE.md`. * Move `DateStrings` string pointers into PROGMEM, saving 42 bytes of RAM. * Use `SERIAL_PORT_MONITOR` instead of `Serial` everywhere for portability across different Arduino boards. - * Support SAMD21 boards except for functionality that requires EEPROM which - is missing from the SAMD21 chip. + * Support SAMD21 boards except for EEPROM which SAMD21 does not support. * 0.5 (2019-07-21, TZ DB version 2019a, beta) * Remove over-engineered `SystemClockHeartbeatLoop` and `SystemClockHeartbeatLoop` and replace with just a call to diff --git a/README.md b/README.md index 534dce84d..4527b8367 100644 --- a/README.md +++ b/README.md @@ -196,7 +196,7 @@ Conversion from an epochSeconds to date-time components including timezone * 2.5 microseconds on an ESP32, * 6 microseconds on a Teensy 3.2. -**Version**: 0.5 (2019-07-21, TZ DB version 2019a, beta) +**Version**: 0.5.1 (2019-07-24, TZ DB version 2019a, beta) **Status**: Fully functional. Added `ZoneManager` for dynamic binding of zoneName or zoneId to the TimeZone. diff --git a/USER_GUIDE.md b/USER_GUIDE.md index 254d7f9a5..4d87389ae 100644 --- a/USER_GUIDE.md +++ b/USER_GUIDE.md @@ -2,7 +2,7 @@ See the [README.md](README.md) for introductory background. -Version: 0.5 (2019-07-21, TZ DB version 2019a, beta) +Version: 0.5.1 (2019-07-24, TZ DB version 2019a, beta) ## Installation diff --git a/docs/doxygen.cfg b/docs/doxygen.cfg index 67141395f..b4cae7edd 100644 --- a/docs/doxygen.cfg +++ b/docs/doxygen.cfg @@ -38,7 +38,7 @@ PROJECT_NAME = "AceTime" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 0.5 +PROJECT_NUMBER = 0.5.1 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/library.properties b/library.properties index 6a71050f8..ec2eb6470 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=AceTime -version=0.5 +version=0.5.1 author=Brian T. Park maintainer=Brian T. Park sentence=Date, time, clock, and TZ Database timezones for Arduino. diff --git a/src/AceTime.h b/src/AceTime.h index 06460e4e5..a519842a0 100644 --- a/src/AceTime.h +++ b/src/AceTime.h @@ -59,7 +59,7 @@ #endif // Version format: xxyyzz == "xx.yy.zz" -#define ACE_TIME_VERSION 500 -#define ACE_TIME_VERSION_STRING "0.5" +#define ACE_TIME_VERSION 501 +#define ACE_TIME_VERSION_STRING "0.5.1" #endif From 885082acd7bca93de7a1cac32f5706a2923f9880 Mon Sep 17 00:00:00 2001 From: Brian Park Date: Wed, 24 Jul 2019 08:41:33 -0700 Subject: [PATCH 35/35] docs: Regenerate doxygen for 0.5.1 --- docs/html/AceTime_8h_source.html | 5 +- docs/html/BasicZoneProcessor_8cpp_source.html | 2 +- docs/html/BasicZoneProcessor_8h_source.html | 48 ++-- docs/html/BasicZone_8h_source.html | 5 +- docs/html/Brokers_8h.html | 18 +- docs/html/Brokers_8h__dep__incl.md5 | 2 +- docs/html/Brokers_8h__incl.map | 14 +- docs/html/Brokers_8h__incl.md5 | 2 +- docs/html/Brokers_8h__incl.png | Bin 23008 -> 25781 bytes docs/html/Brokers_8h_source.html | 4 +- docs/html/CrcEeprom_8h_source.html | 4 +- docs/html/DS3231TimeKeeper_8h_source.html | 2 +- docs/html/DS3231_8cpp_source.html | 2 +- docs/html/DS3231_8h_source.html | 2 +- docs/html/DateStrings_8cpp_source.html | 4 +- docs/html/DateStrings_8h_source.html | 15 +- .../ExtendedZoneProcessor_8cpp_source.html | 8 +- .../html/ExtendedZoneProcessor_8h_source.html | 13 +- docs/html/ExtendedZone_8h_source.html | 5 +- docs/html/HardwareDateTime_8cpp_source.html | 2 +- docs/html/HardwareDateTime_8h_source.html | 2 +- docs/html/HardwareTemperature_8h_source.html | 2 +- docs/html/LocalDateTime_8cpp_source.html | 2 +- docs/html/LocalDateTime_8h_source.html | 2 +- docs/html/LocalDate_8cpp_source.html | 4 +- docs/html/LocalDate_8h_source.html | 2 +- docs/html/LocalTime_8cpp_source.html | 2 +- docs/html/LocalTime_8h_source.html | 2 +- docs/html/NtpTimeProvider_8cpp_source.html | 4 +- docs/html/NtpTimeProvider_8h_source.html | 4 +- docs/html/OffsetDateTime_8cpp_source.html | 2 +- docs/html/OffsetDateTime_8h_source.html | 2 +- docs/html/README_8md_source.html | 2 +- .../SystemClockSyncCoroutine_8h_source.html | 10 +- docs/html/SystemClockSyncLoop_8h_source.html | 12 +- docs/html/SystemClock_8h_source.html | 14 +- docs/html/TimeKeeper_8h_source.html | 2 +- docs/html/TimeOffset_8cpp_source.html | 2 +- docs/html/TimeOffset_8h_source.html | 2 +- docs/html/TimePeriod_8cpp_source.html | 2 +- docs/html/TimePeriod_8h_source.html | 2 +- docs/html/TimeProvider_8h_source.html | 2 +- docs/html/TimeZoneData_8h_source.html | 2 +- docs/html/TimeZone_8cpp_source.html | 2 +- docs/html/TimeZone_8h_source.html | 4 +- docs/html/TimingStats_8h_source.html | 2 +- docs/html/ZoneContext_8h_source.html | 2 +- docs/html/ZoneContext_8inc_source.html | 2 +- docs/html/ZoneInfo_8h_source.html | 2 +- docs/html/ZoneInfo_8inc_source.html | 2 +- docs/html/ZoneManager_8h_source.html | 2 +- docs/html/ZonePolicy_8h_source.html | 2 +- docs/html/ZonePolicy_8inc_source.html | 2 +- docs/html/ZoneProcessorCache_8h_source.html | 6 +- docs/html/ZoneProcessor_8h_source.html | 4 +- docs/html/ZoneRegistrar_8h_source.html | 6 +- docs/html/ZonedDateTime_8cpp_source.html | 2 +- docs/html/ZonedDateTime_8h_source.html | 5 +- docs/html/_2zone__infos_8cpp_source.html | 5 +- docs/html/_2zone__infos_8h_source.html | 2 +- docs/html/_2zone__policies_8cpp_source.html | 5 +- docs/html/_2zone__policies_8h_source.html | 2 +- docs/html/_2zone__registry_8cpp_source.html | 5 +- docs/html/_2zone__registry_8h_source.html | 2 +- docs/html/annotated.html | 2 +- .../classace__time_1_1BasicZone-members.html | 2 +- docs/html/classace__time_1_1BasicZone.html | 2 +- ...ace__time_1_1BasicZoneManager-members.html | 2 +- .../classace__time_1_1BasicZoneManager.html | 2 +- ...e__time_1_1BasicZoneProcessor-members.html | 2 +- .../classace__time_1_1BasicZoneProcessor.html | 22 +- ...me_1_1BasicZoneProcessorCache-members.html | 2 +- ...sace__time_1_1BasicZoneProcessorCache.html | 2 +- ...lassace__time_1_1ExtendedZone-members.html | 2 +- docs/html/classace__time_1_1ExtendedZone.html | 2 +- ...__time_1_1ExtendedZoneManager-members.html | 2 +- ...classace__time_1_1ExtendedZoneManager.html | 2 +- ...time_1_1ExtendedZoneProcessor-members.html | 2 +- ...assace__time_1_1ExtendedZoneProcessor.html | 6 +- ...1_1ExtendedZoneProcessorCache-members.html | 2 +- ...e__time_1_1ExtendedZoneProcessorCache.html | 2 +- .../classace__time_1_1LocalDate-members.html | 2 +- docs/html/classace__time_1_1LocalDate.html | 2 +- ...assace__time_1_1LocalDateTime-members.html | 2 +- .../html/classace__time_1_1LocalDateTime.html | 2 +- .../classace__time_1_1LocalTime-members.html | 2 +- docs/html/classace__time_1_1LocalTime.html | 2 +- ...ssace__time_1_1OffsetDateTime-members.html | 2 +- .../classace__time_1_1OffsetDateTime.html | 2 +- .../classace__time_1_1TimeOffset-members.html | 2 +- docs/html/classace__time_1_1TimeOffset.html | 2 +- .../classace__time_1_1TimePeriod-members.html | 2 +- docs/html/classace__time_1_1TimePeriod.html | 2 +- .../classace__time_1_1TimeZone-members.html | 2 +- docs/html/classace__time_1_1TimeZone.html | 2 +- ...classace__time_1_1ZoneManager-members.html | 2 +- docs/html/classace__time_1_1ZoneManager.html | 2 +- ...assace__time_1_1ZoneProcessor-members.html | 2 +- .../html/classace__time_1_1ZoneProcessor.html | 2 +- ...e__time_1_1ZoneProcessorCache-members.html | 2 +- .../classace__time_1_1ZoneProcessorCache.html | 2 +- ...ime_1_1ZoneProcessorCacheImpl-members.html | 2 +- ...ssace__time_1_1ZoneProcessorCacheImpl.html | 4 +- ...assace__time_1_1ZoneRegistrar-members.html | 2 +- .../html/classace__time_1_1ZoneRegistrar.html | 2 +- ...assace__time_1_1ZonedDateTime-members.html | 2 +- .../html/classace__time_1_1ZonedDateTime.html | 2 +- ..._time_1_1clock_1_1SystemClock-members.html | 2 +- ...lassace__time_1_1clock_1_1SystemClock.html | 10 +- ...k_1_1SystemClockSyncCoroutine-members.html | 2 +- ..._1_1clock_1_1SystemClockSyncCoroutine.html | 8 +- ...1clock_1_1SystemClockSyncLoop-members.html | 2 +- ..._time_1_1clock_1_1SystemClockSyncLoop.html | 10 +- ...__time_1_1clock_1_1TimeKeeper-members.html | 2 +- ...classace__time_1_1clock_1_1TimeKeeper.html | 2 +- ...time_1_1clock_1_1TimeProvider-members.html | 2 +- ...assace__time_1_1clock_1_1TimeProvider.html | 2 +- ...time_1_1common_1_1DateStrings-members.html | 2 +- ...assace__time_1_1common_1_1DateStrings.html | 13 +- ...common_1_1DirectZoneEraBroker-members.html | 2 +- ...time_1_1common_1_1DirectZoneEraBroker.html | 2 +- ...ommon_1_1DirectZoneInfoBroker-members.html | 2 +- ...ime_1_1common_1_1DirectZoneInfoBroker.html | 2 +- ...mon_1_1DirectZonePolicyBroker-members.html | 2 +- ...e_1_1common_1_1DirectZonePolicyBroker.html | 2 +- ...n_1_1DirectZoneRegistryBroker-members.html | 2 +- ...1_1common_1_1DirectZoneRegistryBroker.html | 2 +- ...ommon_1_1DirectZoneRuleBroker-members.html | 2 +- ...ime_1_1common_1_1DirectZoneRuleBroker.html | 2 +- ...1common_1_1FlashZoneEraBroker-members.html | 2 +- ..._time_1_1common_1_1FlashZoneEraBroker.html | 2 +- ...common_1_1FlashZoneInfoBroker-members.html | 2 +- ...time_1_1common_1_1FlashZoneInfoBroker.html | 2 +- ...mmon_1_1FlashZonePolicyBroker-members.html | 2 +- ...me_1_1common_1_1FlashZonePolicyBroker.html | 2 +- ...on_1_1FlashZoneRegistryBroker-members.html | 2 +- ..._1_1common_1_1FlashZoneRegistryBroker.html | 2 +- ...common_1_1FlashZoneRuleBroker-members.html | 2 +- ...time_1_1common_1_1FlashZoneRuleBroker.html | 2 +- ...time_1_1common_1_1TimingStats-members.html | 2 +- ...assace__time_1_1common_1_1TimingStats.html | 2 +- ...extended_1_1TransitionStorage-members.html | 2 +- ...time_1_1extended_1_1TransitionStorage.html | 2 +- docs/html/classes.html | 2 +- docs/html/common_8h_source.html | 2 +- docs/html/compat_8cpp_source.html | 81 +++++++ docs/html/compat_8h.html | 208 ++++++++++++++++++ docs/html/compat_8h__dep__incl.map | 33 +++ docs/html/compat_8h__dep__incl.md5 | 1 + docs/html/compat_8h__dep__incl.png | Bin 0 -> 203176 bytes docs/html/compat_8h__incl.map | 2 + docs/html/compat_8h__incl.md5 | 1 + docs/html/compat_8h__incl.png | Bin 0 -> 6521 bytes docs/html/compat_8h_source.html | 80 +++++++ docs/html/dir_000001_000003.html | 75 +++++++ docs/html/dir_000001_000005.html | 2 +- docs/html/dir_000002_000003.html | 75 +++++++ docs/html/dir_000005_000003.html | 75 +++++++ docs/html/dir_000006_000003.html | 75 +++++++ docs/html/dir_000007_000003.html | 75 +++++++ .../dir_173dd563440c1e02d7e3957b90659cd7.html | 25 ++- ...r_173dd563440c1e02d7e3957b90659cd7_dep.map | 23 +- ...r_173dd563440c1e02d7e3957b90659cd7_dep.md5 | 2 +- ...r_173dd563440c1e02d7e3957b90659cd7_dep.png | Bin 5626 -> 11074 bytes .../dir_1a3db1509c5a81eeb8e8fbfe5ac0febc.html | 13 +- ...r_1a3db1509c5a81eeb8e8fbfe5ac0febc_dep.map | 6 + ...r_1a3db1509c5a81eeb8e8fbfe5ac0febc_dep.md5 | 1 + ...r_1a3db1509c5a81eeb8e8fbfe5ac0febc_dep.png | Bin 0 -> 2972 bytes .../dir_50235a35a18cf9820d15ab2ee5526aee.html | 13 +- ...r_50235a35a18cf9820d15ab2ee5526aee_dep.map | 6 + ...r_50235a35a18cf9820d15ab2ee5526aee_dep.md5 | 1 + ...r_50235a35a18cf9820d15ab2ee5526aee_dep.png | Bin 0 -> 3501 bytes .../dir_68267d1309a1af8e8297ef4c3efbcdba.html | 2 +- .../dir_710a5327734d15938c9752b39a7d94e5.html | 2 +- .../dir_a39208a208c368a08eb059033749c10e.html | 13 +- ...r_a39208a208c368a08eb059033749c10e_dep.map | 6 + ...r_a39208a208c368a08eb059033749c10e_dep.md5 | 1 + ...r_a39208a208c368a08eb059033749c10e_dep.png | Bin 0 -> 3012 bytes .../dir_afb2025690de77b1a5b5001a410c869c.html | 9 +- .../dir_b09928b61a970651c46b44aee9ef9d8f.html | 13 +- ...r_b09928b61a970651c46b44aee9ef9d8f_dep.map | 6 + ...r_b09928b61a970651c46b44aee9ef9d8f_dep.md5 | 1 + ...r_b09928b61a970651c46b44aee9ef9d8f_dep.png | Bin 0 -> 3403 bytes docs/html/files.html | 139 ++++++------ docs/html/flash_8cpp_source.html | 79 ------- docs/html/flash_8h_source.html | 79 ------- docs/html/functions.html | 2 +- docs/html/functions_0x7e.html | 2 +- docs/html/functions_b.html | 2 +- docs/html/functions_c.html | 2 +- docs/html/functions_d.html | 2 +- docs/html/functions_e.html | 2 +- docs/html/functions_f.html | 2 +- docs/html/functions_func.html | 2 +- docs/html/functions_func_0x7e.html | 2 +- docs/html/functions_func_b.html | 2 +- docs/html/functions_func_c.html | 2 +- docs/html/functions_func_d.html | 2 +- docs/html/functions_func_e.html | 2 +- docs/html/functions_func_f.html | 2 +- docs/html/functions_func_g.html | 2 +- docs/html/functions_func_h.html | 2 +- docs/html/functions_func_i.html | 2 +- docs/html/functions_func_k.html | 2 +- docs/html/functions_func_l.html | 2 +- docs/html/functions_func_m.html | 2 +- docs/html/functions_func_o.html | 2 +- docs/html/functions_func_p.html | 2 +- docs/html/functions_func_r.html | 2 +- docs/html/functions_func_s.html | 2 +- docs/html/functions_func_t.html | 4 +- docs/html/functions_func_y.html | 2 +- docs/html/functions_func_z.html | 2 +- docs/html/functions_g.html | 2 +- docs/html/functions_h.html | 2 +- docs/html/functions_i.html | 2 +- docs/html/functions_k.html | 2 +- docs/html/functions_l.html | 2 +- docs/html/functions_m.html | 2 +- docs/html/functions_n.html | 2 +- docs/html/functions_o.html | 2 +- docs/html/functions_p.html | 2 +- docs/html/functions_r.html | 2 +- docs/html/functions_rela.html | 2 +- docs/html/functions_s.html | 2 +- docs/html/functions_t.html | 4 +- docs/html/functions_u.html | 2 +- docs/html/functions_vars.html | 2 +- docs/html/functions_y.html | 2 +- docs/html/functions_z.html | 2 +- docs/html/globals.html | 79 +++++++ docs/html/globals_defs.html | 76 +++++++ docs/html/globals_func.html | 76 +++++++ docs/html/graph_legend.html | 2 +- docs/html/hierarchy.html | 2 +- docs/html/index.html | 2 +- docs/html/inherits.html | 2 +- .../html/local__date__mutation_8h_source.html | 2 +- docs/html/logger_8h_source.html | 80 ------- docs/html/logging_8cpp_source.html | 81 +++++++ docs/html/logging_8h_source.html | 80 +++++++ ..._AceTime_src_ace_time_internal_README.html | 2 +- docs/html/menudata.js | 6 +- docs/html/pages.html | 2 +- docs/html/search/all_0.js | 2 + docs/html/search/all_11.js | 4 +- docs/html/search/all_2.js | 1 + docs/html/search/defines_0.html | 26 +++ docs/html/search/defines_0.js | 4 + docs/html/search/files_1.html | 26 +++ docs/html/search/files_1.js | 4 + docs/html/search/functions_0.js | 1 + docs/html/search/functions_10.js | 4 +- docs/html/search/searchdata.js | 11 +- ...ructace__time_1_1TimeZoneData-members.html | 2 +- .../html/structace__time_1_1TimeZoneData.html | 2 +- ...ce__time_1_1basic_1_1MonthDay-members.html | 2 +- .../structace__time_1_1basic_1_1MonthDay.html | 4 +- ...__time_1_1basic_1_1Transition-members.html | 2 +- ...tructace__time_1_1basic_1_1Transition.html | 18 +- ..._time_1_1basic_1_1ZoneContext-members.html | 2 +- ...ructace__time_1_1basic_1_1ZoneContext.html | 2 +- ...ace__time_1_1basic_1_1ZoneEra-members.html | 2 +- .../structace__time_1_1basic_1_1ZoneEra.html | 2 +- ...ce__time_1_1basic_1_1ZoneInfo-members.html | 2 +- .../structace__time_1_1basic_1_1ZoneInfo.html | 2 +- ...__time_1_1basic_1_1ZonePolicy-members.html | 2 +- ...tructace__time_1_1basic_1_1ZonePolicy.html | 2 +- ...ce__time_1_1basic_1_1ZoneRule-members.html | 2 +- .../structace__time_1_1basic_1_1ZoneRule.html | 2 +- ...time_1_1extended_1_1DateTuple-members.html | 2 +- ...uctace__time_1_1extended_1_1DateTuple.html | 2 +- ...ime_1_1extended_1_1Transition-members.html | 2 +- ...ctace__time_1_1extended_1_1Transition.html | 2 +- ...1_1extended_1_1YearMonthTuple-members.html | 2 +- ...e__time_1_1extended_1_1YearMonthTuple.html | 2 +- ...me_1_1extended_1_1ZoneContext-members.html | 2 +- ...tace__time_1_1extended_1_1ZoneContext.html | 2 +- ...__time_1_1extended_1_1ZoneEra-members.html | 2 +- ...tructace__time_1_1extended_1_1ZoneEra.html | 2 +- ..._time_1_1extended_1_1ZoneInfo-members.html | 2 +- ...ructace__time_1_1extended_1_1ZoneInfo.html | 2 +- ...time_1_1extended_1_1ZoneMatch-members.html | 2 +- ...uctace__time_1_1extended_1_1ZoneMatch.html | 2 +- ...ime_1_1extended_1_1ZonePolicy-members.html | 2 +- ...ctace__time_1_1extended_1_1ZonePolicy.html | 2 +- ..._time_1_1extended_1_1ZoneRule-members.html | 2 +- ...ructace__time_1_1extended_1_1ZoneRule.html | 2 +- .../time__offset__mutation_8h_source.html | 2 +- .../time__period__mutation_8h_source.html | 2 +- docs/html/util_8h_source.html | 2 +- docs/html/zone__infos_8cpp_source.html | 5 +- docs/html/zone__infos_8h_source.html | 2 +- docs/html/zone__policies_8cpp_source.html | 5 +- docs/html/zone__policies_8h_source.html | 2 +- docs/html/zone__registry_8cpp_source.html | 5 +- docs/html/zone__registry_8h_source.html | 2 +- ...zoned__date__time__mutation_8h_source.html | 2 +- 298 files changed, 1821 insertions(+), 710 deletions(-) create mode 100644 docs/html/compat_8cpp_source.html create mode 100644 docs/html/compat_8h.html create mode 100644 docs/html/compat_8h__dep__incl.map create mode 100644 docs/html/compat_8h__dep__incl.md5 create mode 100644 docs/html/compat_8h__dep__incl.png create mode 100644 docs/html/compat_8h__incl.map create mode 100644 docs/html/compat_8h__incl.md5 create mode 100644 docs/html/compat_8h__incl.png create mode 100644 docs/html/compat_8h_source.html create mode 100644 docs/html/dir_000001_000003.html create mode 100644 docs/html/dir_000002_000003.html create mode 100644 docs/html/dir_000005_000003.html create mode 100644 docs/html/dir_000006_000003.html create mode 100644 docs/html/dir_000007_000003.html create mode 100644 docs/html/dir_1a3db1509c5a81eeb8e8fbfe5ac0febc_dep.map create mode 100644 docs/html/dir_1a3db1509c5a81eeb8e8fbfe5ac0febc_dep.md5 create mode 100644 docs/html/dir_1a3db1509c5a81eeb8e8fbfe5ac0febc_dep.png create mode 100644 docs/html/dir_50235a35a18cf9820d15ab2ee5526aee_dep.map create mode 100644 docs/html/dir_50235a35a18cf9820d15ab2ee5526aee_dep.md5 create mode 100644 docs/html/dir_50235a35a18cf9820d15ab2ee5526aee_dep.png create mode 100644 docs/html/dir_a39208a208c368a08eb059033749c10e_dep.map create mode 100644 docs/html/dir_a39208a208c368a08eb059033749c10e_dep.md5 create mode 100644 docs/html/dir_a39208a208c368a08eb059033749c10e_dep.png create mode 100644 docs/html/dir_b09928b61a970651c46b44aee9ef9d8f_dep.map create mode 100644 docs/html/dir_b09928b61a970651c46b44aee9ef9d8f_dep.md5 create mode 100644 docs/html/dir_b09928b61a970651c46b44aee9ef9d8f_dep.png delete mode 100644 docs/html/flash_8cpp_source.html delete mode 100644 docs/html/flash_8h_source.html create mode 100644 docs/html/globals.html create mode 100644 docs/html/globals_defs.html create mode 100644 docs/html/globals_func.html delete mode 100644 docs/html/logger_8h_source.html create mode 100644 docs/html/logging_8cpp_source.html create mode 100644 docs/html/logging_8h_source.html create mode 100644 docs/html/search/defines_0.html create mode 100644 docs/html/search/defines_0.js create mode 100644 docs/html/search/files_1.html create mode 100644 docs/html/search/files_1.js diff --git a/docs/html/AceTime_8h_source.html b/docs/html/AceTime_8h_source.html index 6c4e53fe4..93d524718 100644 --- a/docs/html/AceTime_8h_source.html +++ b/docs/html/AceTime_8h_source.html @@ -22,7 +22,7 @@
AceTime -  0.5 +  0.5.1
Date and time classes for Arduino that support timezones from the TZ Database, and a system clock that can synchronize from an NTP server or an RTC chip.
@@ -68,7 +68,8 @@
AceTime.h
-
1 /*
2  * MIT License
3  * Copyright (c) 2018 Brian T. Park
4  */
5 
13 #ifndef ACE_TIME_ACE_TIME_H
14 #define ACE_TIME_ACE_TIME_H
15 
16 #include "ace_time/common/flash.h"
17 #include "ace_time/common/common.h"
18 #include "ace_time/common/DateStrings.h"
19 #include "ace_time/internal/ZoneContext.h"
20 #include "ace_time/internal/ZoneInfo.h"
21 #include "ace_time/internal/ZonePolicy.h"
22 #include "ace_time/zonedb/zone_policies.h"
23 #include "ace_time/zonedb/zone_infos.h"
24 #include "ace_time/zonedb/zone_registry.h"
25 #include "ace_time/zonedbx/zone_policies.h"
26 #include "ace_time/zonedbx/zone_infos.h"
27 #include "ace_time/zonedbx/zone_registry.h"
28 #include "ace_time/ZoneRegistrar.h"
29 #include "ace_time/LocalDate.h"
30 #include "ace_time/local_date_mutation.h"
31 #include "ace_time/LocalTime.h"
32 #include "ace_time/LocalDateTime.h"
33 #include "ace_time/TimeOffset.h"
34 #include "ace_time/time_offset_mutation.h"
35 #include "ace_time/OffsetDateTime.h"
36 #include "ace_time/ZoneProcessor.h"
37 #include "ace_time/BasicZoneProcessor.h"
38 #include "ace_time/ExtendedZoneProcessor.h"
39 #include "ace_time/ZoneProcessorCache.h"
40 #include "ace_time/ZoneManager.h"
41 #include "ace_time/TimeZoneData.h"
42 #include "ace_time/TimeZone.h"
43 #include "ace_time/BasicZone.h"
44 #include "ace_time/ExtendedZone.h"
45 #include "ace_time/ZonedDateTime.h"
46 #include "ace_time/zoned_date_time_mutation.h"
47 #include "ace_time/TimePeriod.h"
48 #include "ace_time/time_period_mutation.h"
49 #include "ace_time/clock/TimeProvider.h"
50 #include "ace_time/clock/TimeKeeper.h"
51 #include "ace_time/clock/NtpTimeProvider.h"
52 #include "ace_time/clock/DS3231TimeKeeper.h"
53 #include "ace_time/clock/SystemClock.h"
54 #include "ace_time/clock/SystemClockSyncLoop.h"
55 
56 // activate only if <AceRoutine.h> is included before this header
57 #ifdef ACE_ROUTINE_VERSION
58  #include "ace_time/clock/SystemClockSyncCoroutine.h"
59 #endif
60 
61 // Version format: xxyyzz == "xx.yy.zz"
62 #define ACE_TIME_VERSION 500
63 #define ACE_TIME_VERSION_STRING "0.5"
64 
65 #endif
+
1 /*
2  * MIT License
3  * Copyright (c) 2018 Brian T. Park
4  */
5 
13 #ifndef ACE_TIME_ACE_TIME_H
14 #define ACE_TIME_ACE_TIME_H
15 
16 #include "ace_time/common/compat.h"
17 #include "ace_time/common/common.h"
18 #include "ace_time/common/DateStrings.h"
19 #include "ace_time/internal/ZoneContext.h"
20 #include "ace_time/internal/ZoneInfo.h"
21 #include "ace_time/internal/ZonePolicy.h"
22 #include "ace_time/zonedb/zone_policies.h"
23 #include "ace_time/zonedb/zone_infos.h"
24 #include "ace_time/zonedb/zone_registry.h"
25 #include "ace_time/zonedbx/zone_policies.h"
26 #include "ace_time/zonedbx/zone_infos.h"
27 #include "ace_time/zonedbx/zone_registry.h"
28 #include "ace_time/ZoneRegistrar.h"
29 #include "ace_time/LocalDate.h"
30 #include "ace_time/local_date_mutation.h"
31 #include "ace_time/LocalTime.h"
32 #include "ace_time/LocalDateTime.h"
33 #include "ace_time/TimeOffset.h"
34 #include "ace_time/time_offset_mutation.h"
35 #include "ace_time/OffsetDateTime.h"
36 #include "ace_time/ZoneProcessor.h"
37 #include "ace_time/BasicZoneProcessor.h"
38 #include "ace_time/ExtendedZoneProcessor.h"
39 #include "ace_time/ZoneProcessorCache.h"
40 #include "ace_time/ZoneManager.h"
41 #include "ace_time/TimeZoneData.h"
42 #include "ace_time/TimeZone.h"
43 #include "ace_time/BasicZone.h"
44 #include "ace_time/ExtendedZone.h"
45 #include "ace_time/ZonedDateTime.h"
46 #include "ace_time/zoned_date_time_mutation.h"
47 #include "ace_time/TimePeriod.h"
48 #include "ace_time/time_period_mutation.h"
49 #include "ace_time/clock/TimeProvider.h"
50 #include "ace_time/clock/TimeKeeper.h"
51 #include "ace_time/clock/NtpTimeProvider.h"
52 #include "ace_time/clock/DS3231TimeKeeper.h"
53 #include "ace_time/clock/SystemClock.h"
54 #include "ace_time/clock/SystemClockSyncLoop.h"
55 
56 // activate only if <AceRoutine.h> is included before this header
57 #ifdef ACE_ROUTINE_VERSION
58  #include "ace_time/clock/SystemClockSyncCoroutine.h"
59 #endif
60 
61 // Version format: xxyyzz == "xx.yy.zz"
62 #define ACE_TIME_VERSION 501
63 #define ACE_TIME_VERSION_STRING "0.5.1"
64 
65 #endif
Macros and definitions that provide a consistency layer among the various Arduino boards for compatib...
+