diff options
Diffstat (limited to 'src/Clock.cpp')
| -rwxr-xr-x | src/Clock.cpp | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/src/Clock.cpp b/src/Clock.cpp new file mode 100755 index 0000000..4f6431d --- /dev/null +++ b/src/Clock.cpp @@ -0,0 +1,217 @@ +/*-------------------------------------------------------------------Clock.cpp + * Authors: Joseph Wayne Dumoulin, Donald Delmar Davis, Suspect Devices + * + * Liscence: "Simplified BSD License" + * + * Copyright (c) 2016, Donald Delmar Davis, Suspect Devices + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in thedocumentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + *----------------------------------------------------------------------------- + * The clock module is about time. + * This includes + * An RTC backed (if avaliable) time module for timestamps + * A shcedular for most tasks. + */ + +#include "Monitor.h" +#include "Clock.h" + + +/* + * notes on sync weirdness. + * + * This class grew out of a system which used external RTC that had to share + * a buss with all sorts of sensors. + * + * Rather than hog the buss a running seconds count was maintained (unixtime) + * and the time variables were updated and the rtc referenced once a minute. + * + * With an internal rtc this gets a little krufty. + * + * On the other hand a less than perfect clock can be implimented on systems + * w/o access to RTCs by counting seconds using whatever millis is using. + * + * this is not currently implimented but we will leave the cruft so it can be. + * + */ + +/* Create an rtc object mebby should be private to the class JOE?? */ + +// add preprocessor code here for non M0 systems. +#ifdef ARDUINO_SAMD_ZERO +RTCZero rtc; +#endif +/* calculate build date and time (this should be referenceable from monitor for SWV ... */ +const byte build_seconds = ((__TIME__[6] - '0') * 10 + __TIME__[7] - '0'); +const byte build_minutes = ((__TIME__[3] - '0') * 10 + __TIME__[4] - '0'); +const byte build_hours = ((__TIME__[0] - '0') * 10 + __TIME__[1] - '0'); + + +const byte build_day = ((__DATE__[4] >= '0') ? (__DATE__[4] - '0') * 10 : 0) + \ + (__DATE__[5] - '0') ; +const byte build_month = ( \ + (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n') ? 1 : \ + (__DATE__[0] == 'F') ? 2 : \ + (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r') ? 3 : \ + (__DATE__[0] == 'A' && __DATE__[1] == 'p') ? 4 : \ + (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y') ? 5 : \ + (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n') ? 6 : \ + (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l') ? 7 : \ + (__DATE__[0] == 'A' && __DATE__[1] == 'u') ? 8 : \ + (__DATE__[0] == 'S') ? 9 : \ + (__DATE__[0] == 'O') ? 10 : \ + (__DATE__[0] == 'N') ? 11 : \ + (__DATE__[0] == 'D') ? 12 : \ + /* error default */ 99 \ + ); +const byte build_year = ( \ + (__DATE__[ 9] - '0') * 10 + \ + (__DATE__[10] - '0') \ + ); + + +Clock clock; + + +void Clock::init() + +{ + + rtc.begin(); // initialize RTC + + // if the rtc is set in the early 00s Set the and date to build time initially + // otherwise assume that the battery was keeping it running appropriately. + if (!rtc.getYear()){ + rtc.setTime(build_hours,build_minutes,build_seconds); + rtc.setDate(build_day, build_month, build_year); + } + + monitor.debug("Clock module initialized"); + monitor.registerAction(_TIM_, &TIM); + monitor.registerAction(_NOW_, &NOW); +} + +// bracket with pre-processor defs .... +bool Clock::RTCIsRunning(void) { + return (RTC->MODE2.CTRL.reg & RTC_MODE2_CTRL_ENABLE); +} + +const uint8_t daysInMonth [] { 31,28,31,30,31,30,31,31,30,31,30,31 }; + +// number of days since 2000/01/01, valid for 2001..2099 +static uint16_t date2days(uint16_t yy, uint8_t mm, uint8_t dd) { + if (yy >= 2000) + yy -= 2000; + uint16_t days = dd; + for (uint8_t i = 1; i < mm; ++i) + days += pgm_read_byte(daysInMonth + i - 1); + if (mm > 2 && yy % 4 == 0) + ++days; + return days + 365 * yy + (yy + 3) / 4 - 1; +} + +static long time2long(uint16_t days, uint8_t hh, uint8_t mm, uint8_t ss) { + return ((days * 24L + hh) * 60 + mm) * 60 + ss; +} + +static uint8_t conv2d(const char* p) { + uint8_t v = 0; + if ('0' <= *p && *p <= '9') + v = *p - '0'; + return 10 * v + *++p - '0'; +} + +void Clock::calcUnixTime(void) { + uint32_t t; + uint16_t days = date2days(yOff, m, d); + t = time2long(days, hh, mm, ss) + SECONDS_FROM_1970_TO_2000 ; + unixtime = t; +} + +static uint8_t bcd2bin (uint8_t val) { return val - 6 * (val >> 4); } +static uint8_t bin2bcd (uint8_t val) { return val + 6 * (val / 10); } + +void Clock::set(time_t t) { + rtc.setEpoch((uint32_t)t); +} + +void Clock::set(const char * dateString) { + //TIM:%02d/%02d/%04d %02d:%02d:%02d" + //TIM:mm/dd/yyyy hh:mm:ss + //0123456789012345678901234 + uint8_t seconds,minutes,hours,days,leap,month; + long int yearoff; + char dateStringBuffer[24]; + strncpy(dateStringBuffer,dateString,23); + dateStringBuffer[2]=dateStringBuffer[5]=dateStringBuffer[10] + =dateStringBuffer[13]=dateStringBuffer[16]=dateStringBuffer[19]='\0'; + seconds = atoi(dateStringBuffer+17); + minutes = atoi(dateStringBuffer+14); + hours = atoi(dateStringBuffer+11);; + days = atoi(dateStringBuffer+3); + month = atoi(dateStringBuffer); + yearoff = atoi(dateStringBuffer+6) - (2000); + monitor.debug("?:%02d/%02d/%04d %02d:%02d:%02d",month,days,yearoff+(2000),hours,minutes,seconds); + rtc.setTime(hours,minutes,seconds); + rtc.setDate(days, month, yearoff); +} + +uint8_t Clock::dayofweek() /* 0 = Sunday */ +{ int y=year(); + int m=month(); + int d=day(); + static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; + y -= m < 3; + return (uint8_t) ((y + y/4 - y/100 + y/400 + t[m-1] + d) % 7); +} + +// populate running values from RTC +void Clock::sync() { + ss = rtc.getSeconds(); + rtcisrunning = 1; //FIXME!!! + mm = rtc.getMinutes(); + hh = rtc.getHours(); + d = rtc.getDay(); + m = rtc.getMonth(); + yOff = rtc.getYear(); +#if DEBUG_SYNC + monitor.debug("RTC: SYNC mm=%d,ss=%d",mm,ss); +#endif + +} + +void Clock::run() { + +} + + +void timeStamp ( char *buffer ) { + sprintf(buffer,"%02d/%02d/%04d %02d:%02d:%02d", + clock.month(), clock.day(), clock.year(), + clock.hour(), clock.minute(), clock.second()); +} + + + + |
