|
80 | 80 | }
|
81 | 81 | */
|
82 | 82 |
|
| 83 | + void RTClock::setTime (tm_t & tmm) { |
| 84 | + time_t mktm = makeTime(tmm); // time will be make to mktm |
| 85 | + setTime(mktm); |
| 86 | + //rtc_set_count(time_stamp); |
| 87 | + } |
| 88 | + |
83 | 89 | void RTClock::setTime (time_t time_stamp) {
|
84 | 90 | rtc_set_count(time_stamp);
|
85 | 91 | }
|
86 | 92 |
|
87 |
| - void RTClock::setTime (struct tm* tm_ptr) { |
88 |
| - rtc_set_count(mktime (tm_ptr)); |
89 |
| - } |
| 93 | +#define LEAP_YEAR(Y) ( ((1970+Y)>0) && !((1970+Y)%4) && ( ((1970+Y)%100) || !((1970+Y)%400) ) ) |
90 | 94 |
|
| 95 | + //----------------------------------------------------------------------------- |
| 96 | +void RTClock::breakTime(time_t timeInput, tm_t & tmm) |
| 97 | +{ |
| 98 | +// break the given time_t into time components |
| 99 | +// this is a more compact version of the C library localtime function |
| 100 | +// note that year is offset from 1970 !!! |
| 101 | + |
| 102 | + uint8_t year; |
| 103 | + uint8_t month, monthLength; |
| 104 | + uint32_t time; |
| 105 | + uint32_t days; |
| 106 | + |
| 107 | + time = (uint32_t)timeInput; |
| 108 | + tmm.second = time % 60; |
| 109 | + time /= 60; // now it is minutes |
| 110 | + tmm.minute = time % 60; |
| 111 | + time /= 60; // now it is hours |
| 112 | + tmm.hour = time % 24; |
| 113 | + time /= 24; // now it is days |
| 114 | + tmm.weekday = ((time + 4) % 7); // Monday is day 1 // + 1; // Sunday is day 1 |
| 115 | + |
| 116 | + year = 0; |
| 117 | + days = 0; |
| 118 | + while((unsigned)(days += (LEAP_YEAR(year) ? 366 : 365)) <= time) { |
| 119 | + year++; |
| 120 | + } |
| 121 | + tmm.year = year; // year is offset from 1970 |
| 122 | + |
| 123 | + days -= LEAP_YEAR(year) ? 366 : 365; |
| 124 | + time -= days; // now it is days in this year, starting at 0 |
| 125 | + |
| 126 | + days = 0; |
| 127 | + month = 0; |
| 128 | + monthLength = 0; |
| 129 | + for (month=0; month<12; month++) { |
| 130 | + if (month==1) { // february |
| 131 | + if (LEAP_YEAR(year)) { |
| 132 | + monthLength=29; |
| 133 | + } else { |
| 134 | + monthLength=28; |
| 135 | + } |
| 136 | + } else { |
| 137 | + monthLength = monthDays[month]; |
| 138 | + } |
| 139 | + |
| 140 | + if (time >= monthLength) { |
| 141 | + time -= monthLength; |
| 142 | + } else { |
| 143 | + break; |
| 144 | + } |
| 145 | + } |
| 146 | + tmm.month = month + 1; // jan is month 1 |
| 147 | + tmm.day = time + 1; // day of month |
| 148 | +} |
| 149 | + |
| 150 | +//----------------------------------------------------------------------------- |
| 151 | +time_t RTClock::makeTime(tm_t & tmm) |
| 152 | +{ |
| 153 | +// assemble time elements into time_t |
| 154 | +// note year argument is offset from 1970 (see macros in time.h to convert to other formats) |
| 155 | +// previous version used full four digit year (or digits since 2000),i.e. 2009 was 2009 or 9 |
| 156 | + |
| 157 | + int i; |
| 158 | + uint32_t seconds; |
| 159 | + |
| 160 | + // seconds from 1970 till 1 jan 00:00:00 of the given year |
| 161 | + seconds = tmm.year*(SECS_PER_DAY * 365); |
| 162 | + for (i = 0; i < tmm.year; i++) { |
| 163 | + if (LEAP_YEAR(i)) { |
| 164 | + seconds += SECS_PER_DAY; // add extra days for leap years |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + // add days for this year, months start from 1 |
| 169 | + for (i = 1; i < tmm.month; i++) { |
| 170 | + if ( (i == 2) && LEAP_YEAR(tmm.year)) { |
| 171 | + seconds += SECS_PER_DAY * 29; |
| 172 | + } else { |
| 173 | + seconds += SECS_PER_DAY * monthDays[i-1]; //monthDay array starts from 0 |
| 174 | + } |
| 175 | + } |
| 176 | + seconds+= (tmm.day-1) * SECS_PER_DAY; |
| 177 | + seconds+= tmm.hour * SECS_PER_HOUR; |
| 178 | + seconds+= tmm.minute * SECS_PER_MIN; |
| 179 | + seconds+= tmm.second; |
| 180 | + return (time_t)seconds; |
| 181 | +} |
| 182 | + |
91 | 183 | time_t RTClock::getTime() {
|
92 | 184 | return rtc_get_count();
|
93 | 185 | }
|
94 |
| - |
95 |
| - struct tm* RTClock::getTime(struct tm* tm_ptr) { |
| 186 | + |
| 187 | + void RTClock::getTime(tm_t & tm_ptr) { |
96 | 188 | time_t res = rtc_get_count();
|
97 |
| - tm_ptr = gmtime(&res); //why not gmtime? |
98 |
| - return tm_ptr; |
| 189 | + breakTime(res, tm_ptr); |
99 | 190 | }
|
100 | 191 |
|
101 | 192 | void RTClock::createAlarm(voidFuncPtr function, time_t alarm_time_t) {
|
102 | 193 | rtc_set_alarm(alarm_time_t); //must be int... for standardization sake.
|
103 | 194 | rtc_attach_interrupt(RTC_ALARM_SPECIFIC_INTERRUPT, function);
|
104 | 195 | }
|
105 | 196 |
|
| 197 | + void RTClock::removeAlarm() { |
| 198 | + rtc_detach_interrupt(RTC_ALARM_SPECIFIC_INTERRUPT); |
| 199 | + } |
| 200 | + |
106 | 201 | void RTClock::attachSecondsInterrupt(voidFuncPtr function) {
|
107 | 202 | rtc_attach_interrupt(RTC_SECONDS_INTERRUPT, function);
|
108 | 203 | }
|
109 | 204 | void RTClock::detachSecondsInterrupt() {
|
110 | 205 | rtc_detach_interrupt(RTC_SECONDS_INTERRUPT);
|
111 | 206 | }
|
112 | 207 |
|
| 208 | + void RTClock::attachAlarmInterrupt(voidFuncPtr function, time_t alarm_time) { // Don't need run RTClock::setAlarmTime(time_t alarm_time) |
| 209 | + rtc_set_alarm(alarm_time); |
| 210 | + rtc_attach_interrupt(RTC_ALARM_GLOBAL_INTERRUPT, function); |
| 211 | + } |
| 212 | + |
| 213 | + void RTClock::attachAlarmInterrupt(voidFuncPtr function) { // Must run RTClock::setAlarmTime (time_t alarm_time or tm_t & alarm_tm) first |
| 214 | + rtc_attach_interrupt(RTC_ALARM_GLOBAL_INTERRUPT, function); |
| 215 | + } |
113 | 216 |
|
114 |
| - void RTClock::createAlarm(voidFuncPtr function, tm* alarm_tm) { |
115 |
| - time_t alarm = mktime(alarm_tm);//convert to time_t |
| 217 | + void RTClock::detachAlarmInterrupt() { |
| 218 | + rtc_detach_interrupt(RTC_ALARM_GLOBAL_INTERRUPT); |
| 219 | + } |
| 220 | + |
| 221 | + void RTClock::createAlarm(voidFuncPtr function, tm_t & alarm_tm) { |
| 222 | + time_t alarm = makeTime(alarm_tm);//convert to time_t |
116 | 223 | createAlarm(function, alarm);
|
117 | 224 | }
|
118 | 225 |
|
119 | 226 | //change alarm time
|
120 |
| - void RTClock::setAlarmTime (tm * tm_ptr) { |
121 |
| - time_t time = mktime(tm_ptr);//convert to time_t |
| 227 | + |
| 228 | + void RTClock::setAlarmTime (tm_t & tm_ptr) { |
| 229 | + time_t time = makeTime(tm_ptr);//convert to time_t |
122 | 230 | rtc_set_alarm(time); //must be int... for standardization sake.
|
123 | 231 | }
|
124 | 232 |
|
|
0 commit comments