Andrew Boyson
/
iot
Backing up an unused program in case of future need
time.cpp@8:45a0205a298f, 2018-12-06 (annotated)
- Committer:
- andrewboyson
- Date:
- Thu Dec 06 11:40:19 2018 +0000
- Revision:
- 8:45a0205a298f
- Parent:
- 7:024ace6d943c
Backing up
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 0:09f915e6f9f6 | 1 | #include "mbed.h" |
andrewboyson | 0:09f915e6f9f6 | 2 | #define ONE_MILLION 1000000 |
andrewboyson | 0:09f915e6f9f6 | 3 | |
andrewboyson | 6:be97d38e0b01 | 4 | static Ticker ticker; |
andrewboyson | 6:be97d38e0b01 | 5 | static volatile uint64_t unixTime16ths; |
andrewboyson | 0:09f915e6f9f6 | 6 | static void tick(void) |
andrewboyson | 0:09f915e6f9f6 | 7 | { |
andrewboyson | 0:09f915e6f9f6 | 8 | unixTime16ths++; |
andrewboyson | 0:09f915e6f9f6 | 9 | } |
andrewboyson | 0:09f915e6f9f6 | 10 | void TimeSet(uint32_t t) |
andrewboyson | 0:09f915e6f9f6 | 11 | { |
andrewboyson | 0:09f915e6f9f6 | 12 | unixTime16ths = (uint64_t)t << 4; |
andrewboyson | 0:09f915e6f9f6 | 13 | } |
andrewboyson | 0:09f915e6f9f6 | 14 | uint32_t TimeGet() |
andrewboyson | 0:09f915e6f9f6 | 15 | { |
andrewboyson | 0:09f915e6f9f6 | 16 | return unixTime16ths >> 4; |
andrewboyson | 0:09f915e6f9f6 | 17 | } |
andrewboyson | 0:09f915e6f9f6 | 18 | void TimeSet16ths(uint64_t t) |
andrewboyson | 0:09f915e6f9f6 | 19 | { |
andrewboyson | 0:09f915e6f9f6 | 20 | unixTime16ths = t; |
andrewboyson | 0:09f915e6f9f6 | 21 | } |
andrewboyson | 0:09f915e6f9f6 | 22 | uint64_t TimeGet16ths() |
andrewboyson | 0:09f915e6f9f6 | 23 | { |
andrewboyson | 0:09f915e6f9f6 | 24 | return unixTime16ths; |
andrewboyson | 6:be97d38e0b01 | 25 | } |
andrewboyson | 7:024ace6d943c | 26 | void TimeToTm(uint32_t time, struct tm* ptm) |
andrewboyson | 7:024ace6d943c | 27 | { |
andrewboyson | 7:024ace6d943c | 28 | int seconds = time % 60; time /= 60; |
andrewboyson | 7:024ace6d943c | 29 | int minutes = time % 60; time /= 60; |
andrewboyson | 7:024ace6d943c | 30 | int hours = time % 24; time /= 24; |
andrewboyson | 7:024ace6d943c | 31 | int daysLeft = time; |
andrewboyson | 7:024ace6d943c | 32 | |
andrewboyson | 7:024ace6d943c | 33 | //Add a year at a time while there is more than a year of days left |
andrewboyson | 7:024ace6d943c | 34 | int year = 1970; //Unix epoch is 1970 |
andrewboyson | 7:024ace6d943c | 35 | int dayOfWeek = 4; //1 Jan 1970 is a Thursday |
andrewboyson | 7:024ace6d943c | 36 | int leapYear; |
andrewboyson | 7:024ace6d943c | 37 | while(1) |
andrewboyson | 7:024ace6d943c | 38 | { |
andrewboyson | 7:024ace6d943c | 39 | //See if it is a leap year |
andrewboyson | 8:45a0205a298f | 40 | leapYear = false; |
andrewboyson | 8:45a0205a298f | 41 | if (year % 4 == 0) leapYear = true; |
andrewboyson | 8:45a0205a298f | 42 | if (year % 100 == 0) leapYear = false; |
andrewboyson | 8:45a0205a298f | 43 | if (year % 400 == 0) leapYear = true; |
andrewboyson | 7:024ace6d943c | 44 | |
andrewboyson | 7:024ace6d943c | 45 | //Find the number of days in this year |
andrewboyson | 7:024ace6d943c | 46 | int daysInYear = leapYear ? 366 : 365; |
andrewboyson | 7:024ace6d943c | 47 | |
andrewboyson | 7:024ace6d943c | 48 | //Stop if this is the final year |
andrewboyson | 7:024ace6d943c | 49 | if (daysLeft < daysInYear) break; |
andrewboyson | 7:024ace6d943c | 50 | |
andrewboyson | 7:024ace6d943c | 51 | //Calculate the current day of the week at the start of the year |
andrewboyson | 7:024ace6d943c | 52 | dayOfWeek += leapYear ? 2 : 1; |
andrewboyson | 7:024ace6d943c | 53 | if (dayOfWeek >= 7) dayOfWeek -= 7; |
andrewboyson | 7:024ace6d943c | 54 | |
andrewboyson | 7:024ace6d943c | 55 | //Move on to the next year |
andrewboyson | 7:024ace6d943c | 56 | daysLeft -= daysInYear; |
andrewboyson | 7:024ace6d943c | 57 | year++; |
andrewboyson | 7:024ace6d943c | 58 | } |
andrewboyson | 7:024ace6d943c | 59 | |
andrewboyson | 8:45a0205a298f | 60 | //Days left contains the days left from the start (1 Jan) of the current year |
andrewboyson | 8:45a0205a298f | 61 | int dayOfYear = daysLeft + 1; |
andrewboyson | 7:024ace6d943c | 62 | dayOfWeek += daysLeft; |
andrewboyson | 7:024ace6d943c | 63 | dayOfWeek %= 7; |
andrewboyson | 7:024ace6d943c | 64 | |
andrewboyson | 7:024ace6d943c | 65 | //Add a month at a time while there is more than a month of days left |
andrewboyson | 8:45a0205a298f | 66 | static char monthlengths[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
andrewboyson | 8:45a0205a298f | 67 | int month = 1; |
andrewboyson | 7:024ace6d943c | 68 | while(1) |
andrewboyson | 7:024ace6d943c | 69 | { |
andrewboyson | 8:45a0205a298f | 70 | int daysInMonth = monthlengths[month-1]; |
andrewboyson | 8:45a0205a298f | 71 | if (month == 2 && leapYear) daysInMonth++; |
andrewboyson | 7:024ace6d943c | 72 | |
andrewboyson | 7:024ace6d943c | 73 | //Stop if this is the last month |
andrewboyson | 7:024ace6d943c | 74 | if (daysLeft < daysInMonth) break; |
andrewboyson | 7:024ace6d943c | 75 | |
andrewboyson | 7:024ace6d943c | 76 | //Move onto next month |
andrewboyson | 7:024ace6d943c | 77 | daysLeft -= daysInMonth; |
andrewboyson | 7:024ace6d943c | 78 | month++; |
andrewboyson | 7:024ace6d943c | 79 | } |
andrewboyson | 8:45a0205a298f | 80 | |
andrewboyson | 8:45a0205a298f | 81 | //Days left contains the days left from the start (1st) of the current month |
andrewboyson | 8:45a0205a298f | 82 | int dayOfMonth = daysLeft + 1; |
andrewboyson | 8:45a0205a298f | 83 | |
andrewboyson | 8:45a0205a298f | 84 | //Find the last Sunday in the month |
andrewboyson | 8:45a0205a298f | 85 | int lastSunday = monthlengths[month-1]; |
andrewboyson | 8:45a0205a298f | 86 | while (lastSunday > 0) |
andrewboyson | 8:45a0205a298f | 87 | { |
andrewboyson | 8:45a0205a298f | 88 | int weekday = (dayOfWeek + lastSunday - dayOfMonth) % 7; |
andrewboyson | 8:45a0205a298f | 89 | if (weekday == 0) break; //Stop when weekday is Sunday |
andrewboyson | 8:45a0205a298f | 90 | lastSunday--; |
andrewboyson | 8:45a0205a298f | 91 | } |
andrewboyson | 8:45a0205a298f | 92 | |
andrewboyson | 8:45a0205a298f | 93 | //Work out if Daylight Saving Time applies |
andrewboyson | 8:45a0205a298f | 94 | int dst; |
andrewboyson | 8:45a0205a298f | 95 | if (month <= 2) dst = false; //Jan, Feb |
andrewboyson | 8:45a0205a298f | 96 | if (month == 3) //Mar - DST true after 1am UTC on the last Sunday in March |
andrewboyson | 8:45a0205a298f | 97 | { |
andrewboyson | 8:45a0205a298f | 98 | if (dayOfMonth < lastSunday) dst = false; |
andrewboyson | 8:45a0205a298f | 99 | if (dayOfMonth == lastSunday) dst = hours >= 1; |
andrewboyson | 8:45a0205a298f | 100 | if (dayOfMonth > lastSunday) dst = true; |
andrewboyson | 8:45a0205a298f | 101 | } |
andrewboyson | 8:45a0205a298f | 102 | if (month >= 4 && month <= 9) dst = true; //Apr, May, Jun, Jul, Aug, Sep |
andrewboyson | 8:45a0205a298f | 103 | if (month == 10) //Oct - DST false after 1am UTC on the last Sunday in October |
andrewboyson | 8:45a0205a298f | 104 | { |
andrewboyson | 8:45a0205a298f | 105 | if (dayOfMonth < lastSunday) dst = true; |
andrewboyson | 8:45a0205a298f | 106 | if (dayOfMonth == lastSunday) dst = hours < 1; |
andrewboyson | 8:45a0205a298f | 107 | if (dayOfMonth > lastSunday) dst = false; |
andrewboyson | 8:45a0205a298f | 108 | } |
andrewboyson | 8:45a0205a298f | 109 | if (month >= 11) dst = false; //Nov, Dec |
andrewboyson | 8:45a0205a298f | 110 | |
andrewboyson | 8:45a0205a298f | 111 | |
andrewboyson | 8:45a0205a298f | 112 | //Set up the broken time TM structure |
andrewboyson | 8:45a0205a298f | 113 | ptm->tm_sec = seconds; // 00 --> 59 |
andrewboyson | 8:45a0205a298f | 114 | ptm->tm_min = minutes; // 00 --> 59 |
andrewboyson | 8:45a0205a298f | 115 | ptm->tm_hour = hours; // 00 --> 23 |
andrewboyson | 8:45a0205a298f | 116 | ptm->tm_mday = dayOfMonth; // 01 --> 31 |
andrewboyson | 8:45a0205a298f | 117 | ptm->tm_mon = month - 1; // 00 --> 11 |
andrewboyson | 8:45a0205a298f | 118 | ptm->tm_year = year - 1900; // Years since 1900 |
andrewboyson | 8:45a0205a298f | 119 | ptm->tm_wday = dayOfWeek; // 0 --> 6 where 0 == Sunday |
andrewboyson | 8:45a0205a298f | 120 | ptm->tm_yday = dayOfYear - 1; // 0 --> 365 |
andrewboyson | 8:45a0205a298f | 121 | ptm->tm_isdst = dst; // +ve if DST, 0 if not DSTime, -ve if the information is not available. Note that 'true' evaluates to +1. |
andrewboyson | 8:45a0205a298f | 122 | |
andrewboyson | 7:024ace6d943c | 123 | } |
andrewboyson | 7:024ace6d943c | 124 | void TimeGetTm(struct tm* ptm) |
andrewboyson | 7:024ace6d943c | 125 | { |
andrewboyson | 7:024ace6d943c | 126 | uint32_t time = TimeGet(); |
andrewboyson | 7:024ace6d943c | 127 | TimeToTm(time, ptm); |
andrewboyson | 7:024ace6d943c | 128 | } |
andrewboyson | 6:be97d38e0b01 | 129 | static Timer timer; |
andrewboyson | 6:be97d38e0b01 | 130 | int TimeScanUs = 0; |
andrewboyson | 6:be97d38e0b01 | 131 | int TimeMain() |
andrewboyson | 6:be97d38e0b01 | 132 | { |
andrewboyson | 6:be97d38e0b01 | 133 | int scanUs = timer.read_us(); |
andrewboyson | 6:be97d38e0b01 | 134 | timer.reset(); |
andrewboyson | 6:be97d38e0b01 | 135 | timer.start(); |
andrewboyson | 6:be97d38e0b01 | 136 | if (scanUs > TimeScanUs) TimeScanUs++; |
andrewboyson | 6:be97d38e0b01 | 137 | if (scanUs < TimeScanUs) TimeScanUs--; |
andrewboyson | 6:be97d38e0b01 | 138 | return 0; |
andrewboyson | 6:be97d38e0b01 | 139 | } |
andrewboyson | 6:be97d38e0b01 | 140 | int TimeInit() |
andrewboyson | 6:be97d38e0b01 | 141 | { |
andrewboyson | 6:be97d38e0b01 | 142 | ticker.attach_us(&tick, ONE_MILLION >> 4); |
andrewboyson | 6:be97d38e0b01 | 143 | timer.stop(); |
andrewboyson | 6:be97d38e0b01 | 144 | timer.reset(); |
andrewboyson | 6:be97d38e0b01 | 145 | return 0; |
andrewboyson | 6:be97d38e0b01 | 146 | } |