Clock with Real-Time Clock (RTC-8564) and I2C LCD module(SB1062B).
Dependencies: DebouncedEdgeIn I2cLCD_cursor Rtc8564 mbed beep
Model/Clock.cpp@4:75ed86b78045, 2014-02-23 (annotated)
- Committer:
- togayan
- Date:
- Sun Feb 23 00:16:54 2014 +0000
- Revision:
- 4:75ed86b78045
- Parent:
- 3:061cccf4093a
1st release.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
togayan | 1:f8713c387a68 | 1 | #include "Clock.h" |
togayan | 1:f8713c387a68 | 2 | |
togayan | 1:f8713c387a68 | 3 | using Model::Clock; |
togayan | 1:f8713c387a68 | 4 | |
togayan | 1:f8713c387a68 | 5 | Clock::Clock(I_NotifyUpdate* notifyUpdate, I_SetPresentTime* setPresentTime) |
togayan | 1:f8713c387a68 | 6 | :m_notifyUpdate(notifyUpdate), |
togayan | 2:6f0158399eff | 7 | m_setPresentTime(setPresentTime), |
togayan | 2:6f0158399eff | 8 | m_mode(CLOCK) |
togayan | 1:f8713c387a68 | 9 | { |
togayan | 1:f8713c387a68 | 10 | } |
togayan | 1:f8713c387a68 | 11 | |
togayan | 3:061cccf4093a | 12 | void Clock::addSetMode(I_SetMode* setMode) |
togayan | 3:061cccf4093a | 13 | { |
togayan | 3:061cccf4093a | 14 | m_setModes.push_back(setMode); |
togayan | 3:061cccf4093a | 15 | } |
togayan | 3:061cccf4093a | 16 | |
togayan | 1:f8713c387a68 | 17 | void Clock::initialize() |
togayan | 1:f8713c387a68 | 18 | { |
togayan | 2:6f0158399eff | 19 | m_dateTime.tm_year = 100; // 2000-01-01 |
togayan | 2:6f0158399eff | 20 | m_dateTime.tm_mon = 0; |
togayan | 2:6f0158399eff | 21 | m_dateTime.tm_mday = 1; |
togayan | 2:6f0158399eff | 22 | m_dateTime.tm_wday = 6; // Saturday |
togayan | 2:6f0158399eff | 23 | m_dateTime.tm_hour = 0; // 00:00:00 |
togayan | 2:6f0158399eff | 24 | m_dateTime.tm_min = 0; |
togayan | 2:6f0158399eff | 25 | m_dateTime.tm_sec = 0; |
togayan | 2:6f0158399eff | 26 | m_dateTime.tm_isdst = -1; |
togayan | 1:f8713c387a68 | 27 | } |
togayan | 1:f8713c387a68 | 28 | |
togayan | 1:f8713c387a68 | 29 | void Clock::renew() |
togayan | 1:f8713c387a68 | 30 | { |
togayan | 2:6f0158399eff | 31 | if(m_mode != CLOCK) return; |
togayan | 2:6f0158399eff | 32 | |
togayan | 1:f8713c387a68 | 33 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 1:f8713c387a68 | 34 | } |
togayan | 1:f8713c387a68 | 35 | |
togayan | 4:75ed86b78045 | 36 | struct tm* Clock::getDateTime() { |
togayan | 1:f8713c387a68 | 37 | return &m_dateTime; |
togayan | 1:f8713c387a68 | 38 | } |
togayan | 1:f8713c387a68 | 39 | |
togayan | 2:6f0158399eff | 40 | void Clock::requestModeChange() |
togayan | 2:6f0158399eff | 41 | { |
togayan | 2:6f0158399eff | 42 | switch(m_mode) { |
togayan | 2:6f0158399eff | 43 | case CLOCK: |
togayan | 2:6f0158399eff | 44 | m_mode = SET_YEAR; |
togayan | 2:6f0158399eff | 45 | break; |
togayan | 2:6f0158399eff | 46 | case SET_YEAR: |
togayan | 2:6f0158399eff | 47 | m_mode = SET_MONTH; |
togayan | 2:6f0158399eff | 48 | break; |
togayan | 2:6f0158399eff | 49 | case SET_MONTH: |
togayan | 2:6f0158399eff | 50 | m_mode = SET_DAY; |
togayan | 2:6f0158399eff | 51 | break; |
togayan | 2:6f0158399eff | 52 | case SET_DAY: |
togayan | 2:6f0158399eff | 53 | m_mode = SET_HOUR; |
togayan | 2:6f0158399eff | 54 | break; |
togayan | 2:6f0158399eff | 55 | case SET_HOUR: |
togayan | 2:6f0158399eff | 56 | m_mode = SET_MINUTE; |
togayan | 2:6f0158399eff | 57 | break; |
togayan | 2:6f0158399eff | 58 | case SET_MINUTE: |
togayan | 2:6f0158399eff | 59 | m_mode = SET_SECOND; |
togayan | 2:6f0158399eff | 60 | break; |
togayan | 2:6f0158399eff | 61 | case SET_SECOND: |
togayan | 2:6f0158399eff | 62 | m_mode = CLOCK; |
togayan | 2:6f0158399eff | 63 | m_setPresentTime->setPresentTime(); |
togayan | 2:6f0158399eff | 64 | break; |
togayan | 2:6f0158399eff | 65 | default: |
togayan | 2:6f0158399eff | 66 | break; |
togayan | 2:6f0158399eff | 67 | } |
togayan | 2:6f0158399eff | 68 | notifyMode(); |
togayan | 2:6f0158399eff | 69 | } |
togayan | 2:6f0158399eff | 70 | |
togayan | 2:6f0158399eff | 71 | void Clock::requestIncrementValue() |
togayan | 2:6f0158399eff | 72 | { |
togayan | 2:6f0158399eff | 73 | switch(m_mode) { |
togayan | 2:6f0158399eff | 74 | case SET_YEAR: |
togayan | 2:6f0158399eff | 75 | m_dateTime.tm_year++; |
togayan | 2:6f0158399eff | 76 | if(m_dateTime.tm_year >= 200) { |
togayan | 2:6f0158399eff | 77 | m_dateTime.tm_year = 100; |
togayan | 2:6f0158399eff | 78 | } |
togayan | 2:6f0158399eff | 79 | decideDayOfMonth(); |
togayan | 2:6f0158399eff | 80 | decideDayOfWeek(); |
togayan | 2:6f0158399eff | 81 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 82 | break; |
togayan | 2:6f0158399eff | 83 | case SET_MONTH: |
togayan | 2:6f0158399eff | 84 | m_dateTime.tm_mon++; |
togayan | 2:6f0158399eff | 85 | if(m_dateTime.tm_mon >= 12) { |
togayan | 2:6f0158399eff | 86 | m_dateTime.tm_mon = 0; |
togayan | 2:6f0158399eff | 87 | } |
togayan | 2:6f0158399eff | 88 | decideDayOfMonth(); |
togayan | 2:6f0158399eff | 89 | decideDayOfWeek(); |
togayan | 2:6f0158399eff | 90 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 91 | break; |
togayan | 2:6f0158399eff | 92 | case SET_DAY: |
togayan | 2:6f0158399eff | 93 | m_dateTime.tm_mday++; |
togayan | 2:6f0158399eff | 94 | if(m_dateTime.tm_mday > getDays()) { |
togayan | 2:6f0158399eff | 95 | m_dateTime.tm_mday = 1; |
togayan | 2:6f0158399eff | 96 | } |
togayan | 2:6f0158399eff | 97 | decideDayOfWeek(); |
togayan | 2:6f0158399eff | 98 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 99 | break; |
togayan | 2:6f0158399eff | 100 | case SET_HOUR: |
togayan | 2:6f0158399eff | 101 | m_dateTime.tm_hour++; |
togayan | 2:6f0158399eff | 102 | if(m_dateTime.tm_hour >= 24) { |
togayan | 2:6f0158399eff | 103 | m_dateTime.tm_hour = 0; |
togayan | 2:6f0158399eff | 104 | } |
togayan | 2:6f0158399eff | 105 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 106 | break; |
togayan | 2:6f0158399eff | 107 | case SET_MINUTE: |
togayan | 2:6f0158399eff | 108 | m_dateTime.tm_min++; |
togayan | 2:6f0158399eff | 109 | if(m_dateTime.tm_min >= 60) { |
togayan | 2:6f0158399eff | 110 | m_dateTime.tm_min = 0; |
togayan | 2:6f0158399eff | 111 | } |
togayan | 2:6f0158399eff | 112 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 113 | break; |
togayan | 2:6f0158399eff | 114 | case SET_SECOND: |
togayan | 2:6f0158399eff | 115 | m_dateTime.tm_sec++; |
togayan | 2:6f0158399eff | 116 | if(m_dateTime.tm_sec >= 60) { |
togayan | 2:6f0158399eff | 117 | m_dateTime.tm_sec = 0; |
togayan | 2:6f0158399eff | 118 | } |
togayan | 2:6f0158399eff | 119 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 120 | break; |
togayan | 2:6f0158399eff | 121 | default: |
togayan | 2:6f0158399eff | 122 | break; |
togayan | 2:6f0158399eff | 123 | } |
togayan | 2:6f0158399eff | 124 | } |
togayan | 2:6f0158399eff | 125 | |
togayan | 2:6f0158399eff | 126 | void Clock::requestDecrementValue() |
togayan | 2:6f0158399eff | 127 | { |
togayan | 2:6f0158399eff | 128 | switch(m_mode) { |
togayan | 2:6f0158399eff | 129 | case SET_YEAR: |
togayan | 2:6f0158399eff | 130 | if(m_dateTime.tm_year <= 100) { |
togayan | 2:6f0158399eff | 131 | m_dateTime.tm_year = 200; |
togayan | 2:6f0158399eff | 132 | } |
togayan | 2:6f0158399eff | 133 | m_dateTime.tm_year--; |
togayan | 2:6f0158399eff | 134 | decideDayOfMonth(); |
togayan | 2:6f0158399eff | 135 | decideDayOfWeek(); |
togayan | 2:6f0158399eff | 136 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 137 | break; |
togayan | 2:6f0158399eff | 138 | case SET_MONTH: |
togayan | 2:6f0158399eff | 139 | if(m_dateTime.tm_mon < 0) { |
togayan | 2:6f0158399eff | 140 | m_dateTime.tm_mon = 12; |
togayan | 2:6f0158399eff | 141 | } |
togayan | 2:6f0158399eff | 142 | m_dateTime.tm_mon--; |
togayan | 2:6f0158399eff | 143 | decideDayOfMonth(); |
togayan | 2:6f0158399eff | 144 | decideDayOfWeek(); |
togayan | 2:6f0158399eff | 145 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 146 | break; |
togayan | 2:6f0158399eff | 147 | case SET_DAY: |
togayan | 2:6f0158399eff | 148 | if(m_dateTime.tm_mday <= 1) { |
togayan | 2:6f0158399eff | 149 | m_dateTime.tm_mday = getDays() + 1; |
togayan | 2:6f0158399eff | 150 | } |
togayan | 2:6f0158399eff | 151 | m_dateTime.tm_mday--; |
togayan | 2:6f0158399eff | 152 | decideDayOfWeek(); |
togayan | 2:6f0158399eff | 153 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 154 | break; |
togayan | 2:6f0158399eff | 155 | case SET_HOUR: |
togayan | 2:6f0158399eff | 156 | if(m_dateTime.tm_hour <= 0) { |
togayan | 2:6f0158399eff | 157 | m_dateTime.tm_hour = 24; |
togayan | 2:6f0158399eff | 158 | } |
togayan | 2:6f0158399eff | 159 | m_dateTime.tm_hour--; |
togayan | 2:6f0158399eff | 160 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 161 | break; |
togayan | 2:6f0158399eff | 162 | case SET_MINUTE: |
togayan | 2:6f0158399eff | 163 | if(m_dateTime.tm_min <= 0) { |
togayan | 2:6f0158399eff | 164 | m_dateTime.tm_min = 60; |
togayan | 2:6f0158399eff | 165 | } |
togayan | 2:6f0158399eff | 166 | m_dateTime.tm_min--; |
togayan | 2:6f0158399eff | 167 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 168 | break; |
togayan | 2:6f0158399eff | 169 | case SET_SECOND: |
togayan | 2:6f0158399eff | 170 | if(m_dateTime.tm_sec <= 0) { |
togayan | 2:6f0158399eff | 171 | m_dateTime.tm_sec = 60; |
togayan | 2:6f0158399eff | 172 | } |
togayan | 2:6f0158399eff | 173 | m_dateTime.tm_sec--; |
togayan | 2:6f0158399eff | 174 | m_notifyUpdate->dateTimeUpdated(); |
togayan | 2:6f0158399eff | 175 | break; |
togayan | 2:6f0158399eff | 176 | default: |
togayan | 2:6f0158399eff | 177 | break; |
togayan | 2:6f0158399eff | 178 | } |
togayan | 2:6f0158399eff | 179 | } |
togayan | 2:6f0158399eff | 180 | |
togayan | 2:6f0158399eff | 181 | void Clock::notifyMode() |
togayan | 2:6f0158399eff | 182 | { |
togayan | 4:75ed86b78045 | 183 | for(std::vector<I_SetMode*>::iterator it = m_setModes.begin(); it != m_setModes.end(); ++it) { |
togayan | 3:061cccf4093a | 184 | (*it)->mode(m_mode); |
togayan | 3:061cccf4093a | 185 | } |
togayan | 2:6f0158399eff | 186 | } |
togayan | 2:6f0158399eff | 187 | |
togayan | 2:6f0158399eff | 188 | int Clock::getDays() |
togayan | 2:6f0158399eff | 189 | { |
togayan | 2:6f0158399eff | 190 | const int days[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; |
togayan | 2:6f0158399eff | 191 | int year = m_dateTime.tm_year + 1900; |
togayan | 2:6f0158399eff | 192 | int month = m_dateTime.tm_mon + 1; |
togayan | 4:75ed86b78045 | 193 | |
togayan | 2:6f0158399eff | 194 | int lastd = days[month - 1]; |
togayan | 2:6f0158399eff | 195 | if( month == 2 ) { |
togayan | 2:6f0158399eff | 196 | if( year % 4 == 0 && year % 100 != 0 || year % 400 == 0 ) |
togayan | 4:75ed86b78045 | 197 | lastd = 29; |
togayan | 2:6f0158399eff | 198 | } |
togayan | 2:6f0158399eff | 199 | return lastd; |
togayan | 2:6f0158399eff | 200 | } |
togayan | 2:6f0158399eff | 201 | |
togayan | 2:6f0158399eff | 202 | void Clock::decideDayOfMonth() |
togayan | 2:6f0158399eff | 203 | { |
togayan | 4:75ed86b78045 | 204 | if(m_dateTime.tm_mday > getDays()) { |
togayan | 2:6f0158399eff | 205 | m_dateTime.tm_mday = getDays(); |
togayan | 2:6f0158399eff | 206 | } |
togayan | 2:6f0158399eff | 207 | } |
togayan | 2:6f0158399eff | 208 | |
togayan | 2:6f0158399eff | 209 | void Clock::decideDayOfWeek() |
togayan | 2:6f0158399eff | 210 | { |
togayan | 2:6f0158399eff | 211 | if (mktime(&m_dateTime) == (time_t)(-1)) { |
togayan | 2:6f0158399eff | 212 | m_dateTime.tm_wday = 7; |
togayan | 2:6f0158399eff | 213 | } |
togayan | 2:6f0158399eff | 214 | return; |
togayan | 2:6f0158399eff | 215 | } |