I2C hang recover function added
Dependencies: UniGraphic mbed vt100
In this version, check_i2c_pins function was added in edge_mgr.cpp.
プログラムの起動時、I2Cモジュールを初期化する前に、I2Cに使用するピンの電位を確認し
もし一方でも Low に張り付いていた場合、SCL を GPIO 出力に設定して
所定回数 (I2C_UNLOCK_TRIAL_CYCLE) 反転させることにより、疑似リセットクロックを生成します。
その後は、通常の起動手順に復帰し、以降はこれまでと同様の動作をします。
edge_utils/edge_time.cpp@0:d895cd1cd897, 2018-04-03 (annotated)
- Committer:
- Rhyme
- Date:
- Tue Apr 03 08:30:29 2018 +0000
- Revision:
- 0:d895cd1cd897
Initial I2C Pin force reset function added
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Rhyme | 0:d895cd1cd897 | 1 | #include "mbed.h" |
Rhyme | 0:d895cd1cd897 | 2 | #include "edge_time.h" |
Rhyme | 0:d895cd1cd897 | 3 | |
Rhyme | 0:d895cd1cd897 | 4 | static const uint8_t daysInMonth[12] = { |
Rhyme | 0:d895cd1cd897 | 5 | 31, 28, 31, 30, |
Rhyme | 0:d895cd1cd897 | 6 | 31, 30, 31, 31, |
Rhyme | 0:d895cd1cd897 | 7 | 30, 31, 30, 31 |
Rhyme | 0:d895cd1cd897 | 8 | } ; |
Rhyme | 0:d895cd1cd897 | 9 | |
Rhyme | 0:d895cd1cd897 | 10 | const char *nameOfDay[7] = { |
Rhyme | 0:d895cd1cd897 | 11 | "Sunday", "Monday", "Tuesday", "Wednesday", |
Rhyme | 0:d895cd1cd897 | 12 | "Thursday", "Friday", "Saturday" |
Rhyme | 0:d895cd1cd897 | 13 | } ; |
Rhyme | 0:d895cd1cd897 | 14 | |
Rhyme | 0:d895cd1cd897 | 15 | uint32_t edge_time = 0 ; |
Rhyme | 0:d895cd1cd897 | 16 | uint32_t utc_offset = 9 * 60 * 60 ; |
Rhyme | 0:d895cd1cd897 | 17 | tm current_time ; |
Rhyme | 0:d895cd1cd897 | 18 | Ticker *tokei = 0 ; |
Rhyme | 0:d895cd1cd897 | 19 | |
Rhyme | 0:d895cd1cd897 | 20 | void inc_sec(void) |
Rhyme | 0:d895cd1cd897 | 21 | { |
Rhyme | 0:d895cd1cd897 | 22 | __disable_irq() ; // Disable Interrupts |
Rhyme | 0:d895cd1cd897 | 23 | edge_time++ ; |
Rhyme | 0:d895cd1cd897 | 24 | __enable_irq() ; // Enable Interrupts |
Rhyme | 0:d895cd1cd897 | 25 | } |
Rhyme | 0:d895cd1cd897 | 26 | |
Rhyme | 0:d895cd1cd897 | 27 | void init_timer(void) |
Rhyme | 0:d895cd1cd897 | 28 | { |
Rhyme | 0:d895cd1cd897 | 29 | tokei = new Ticker() ; |
Rhyme | 0:d895cd1cd897 | 30 | tokei->attach(inc_sec, 1.0) ; |
Rhyme | 0:d895cd1cd897 | 31 | } |
Rhyme | 0:d895cd1cd897 | 32 | |
Rhyme | 0:d895cd1cd897 | 33 | void set_time(const uint16_t valueLen, const uint8_t *value) |
Rhyme | 0:d895cd1cd897 | 34 | { |
Rhyme | 0:d895cd1cd897 | 35 | uint32_t tmp_timestamp = 0 ; |
Rhyme | 0:d895cd1cd897 | 36 | for (int i = 0 ; i < valueLen ; i++ ) { |
Rhyme | 0:d895cd1cd897 | 37 | tmp_timestamp |= (value[i] & 0xFF) << (i * 8) ; |
Rhyme | 0:d895cd1cd897 | 38 | } |
Rhyme | 0:d895cd1cd897 | 39 | edge_time = tmp_timestamp ; |
Rhyme | 0:d895cd1cd897 | 40 | ts2tm(edge_time, ¤t_time) ; |
Rhyme | 0:d895cd1cd897 | 41 | // ts2time(edge_time, ¤t_time) ; |
Rhyme | 0:d895cd1cd897 | 42 | } |
Rhyme | 0:d895cd1cd897 | 43 | |
Rhyme | 0:d895cd1cd897 | 44 | void ts2time(uint32_t timestamp, struct tm *tm) |
Rhyme | 0:d895cd1cd897 | 45 | { |
Rhyme | 0:d895cd1cd897 | 46 | uint32_t seconds, minutes, hours, days, month, year ; |
Rhyme | 0:d895cd1cd897 | 47 | uint32_t dayOfWeek ; |
Rhyme | 0:d895cd1cd897 | 48 | |
Rhyme | 0:d895cd1cd897 | 49 | // timestamp += (3600 * 9) ; /* +9 hours for JST */ |
Rhyme | 0:d895cd1cd897 | 50 | timestamp += utc_offset ; |
Rhyme | 0:d895cd1cd897 | 51 | |
Rhyme | 0:d895cd1cd897 | 52 | seconds = timestamp % 60 ; |
Rhyme | 0:d895cd1cd897 | 53 | minutes = timestamp / 60 ; |
Rhyme | 0:d895cd1cd897 | 54 | hours = minutes / 60 ; /* +9 for JST */ |
Rhyme | 0:d895cd1cd897 | 55 | minutes -= hours * 60 ; |
Rhyme | 0:d895cd1cd897 | 56 | days = hours / 24 ; |
Rhyme | 0:d895cd1cd897 | 57 | hours -= days * 24 ; |
Rhyme | 0:d895cd1cd897 | 58 | |
Rhyme | 0:d895cd1cd897 | 59 | tm->tm_sec = seconds ; |
Rhyme | 0:d895cd1cd897 | 60 | tm->tm_min = minutes ; |
Rhyme | 0:d895cd1cd897 | 61 | tm->tm_hour = hours ; |
Rhyme | 0:d895cd1cd897 | 62 | tm->tm_mday = days + 1 ; |
Rhyme | 0:d895cd1cd897 | 63 | // tm->tm_mon = month ; |
Rhyme | 0:d895cd1cd897 | 64 | // tm->tm_year = year ; |
Rhyme | 0:d895cd1cd897 | 65 | // tm->tm_wday = dayOfWeek ; |
Rhyme | 0:d895cd1cd897 | 66 | } |
Rhyme | 0:d895cd1cd897 | 67 | |
Rhyme | 0:d895cd1cd897 | 68 | void ts2tm(uint32_t timestamp, struct tm *tm) |
Rhyme | 0:d895cd1cd897 | 69 | { |
Rhyme | 0:d895cd1cd897 | 70 | uint32_t seconds, minutes, hours, days, month, year ; |
Rhyme | 0:d895cd1cd897 | 71 | uint32_t dayOfWeek ; |
Rhyme | 0:d895cd1cd897 | 72 | |
Rhyme | 0:d895cd1cd897 | 73 | // timestamp += (3600 * 9) ; /* +9 hours for JST */ |
Rhyme | 0:d895cd1cd897 | 74 | timestamp += utc_offset ; |
Rhyme | 0:d895cd1cd897 | 75 | |
Rhyme | 0:d895cd1cd897 | 76 | seconds = timestamp % 60 ; |
Rhyme | 0:d895cd1cd897 | 77 | minutes = timestamp / 60 ; |
Rhyme | 0:d895cd1cd897 | 78 | hours = minutes / 60 ; /* +9 for JST */ |
Rhyme | 0:d895cd1cd897 | 79 | minutes -= hours * 60 ; |
Rhyme | 0:d895cd1cd897 | 80 | days = hours / 24 ; |
Rhyme | 0:d895cd1cd897 | 81 | hours -= days * 24 ; |
Rhyme | 0:d895cd1cd897 | 82 | |
Rhyme | 0:d895cd1cd897 | 83 | /* Unix timestamp start 1-Jan-1970 Thursday */ |
Rhyme | 0:d895cd1cd897 | 84 | year = 1970 ; |
Rhyme | 0:d895cd1cd897 | 85 | dayOfWeek = 4 ; /* Thursday */ |
Rhyme | 0:d895cd1cd897 | 86 | |
Rhyme | 0:d895cd1cd897 | 87 | while(1) { |
Rhyme | 0:d895cd1cd897 | 88 | bool isLeapYear = |
Rhyme | 0:d895cd1cd897 | 89 | (((year % 4) == 0) |
Rhyme | 0:d895cd1cd897 | 90 | &&(((year % 100) != 0) |
Rhyme | 0:d895cd1cd897 | 91 | || ((year % 400) == 0))) ; |
Rhyme | 0:d895cd1cd897 | 92 | uint16_t daysInYear = isLeapYear ? 366 : 365 ; |
Rhyme | 0:d895cd1cd897 | 93 | if (days >= daysInYear) { |
Rhyme | 0:d895cd1cd897 | 94 | dayOfWeek += isLeapYear ? 2 : 1 ; |
Rhyme | 0:d895cd1cd897 | 95 | days -= daysInYear ; |
Rhyme | 0:d895cd1cd897 | 96 | if (dayOfWeek >= 7) { |
Rhyme | 0:d895cd1cd897 | 97 | dayOfWeek -= 7 ; |
Rhyme | 0:d895cd1cd897 | 98 | } |
Rhyme | 0:d895cd1cd897 | 99 | year++ ; |
Rhyme | 0:d895cd1cd897 | 100 | } else { |
Rhyme | 0:d895cd1cd897 | 101 | tm->tm_yday = days ; |
Rhyme | 0:d895cd1cd897 | 102 | dayOfWeek += days ; |
Rhyme | 0:d895cd1cd897 | 103 | dayOfWeek %= 7 ; |
Rhyme | 0:d895cd1cd897 | 104 | |
Rhyme | 0:d895cd1cd897 | 105 | /* calc the month and the day */ |
Rhyme | 0:d895cd1cd897 | 106 | for (month = 0 ; month < 12 ; month++) { |
Rhyme | 0:d895cd1cd897 | 107 | uint8_t dim = daysInMonth[month] ; |
Rhyme | 0:d895cd1cd897 | 108 | |
Rhyme | 0:d895cd1cd897 | 109 | /* add a day to feburary if this is a leap year */ |
Rhyme | 0:d895cd1cd897 | 110 | if ((month == 1) && (isLeapYear)) { |
Rhyme | 0:d895cd1cd897 | 111 | dim++ ; |
Rhyme | 0:d895cd1cd897 | 112 | } |
Rhyme | 0:d895cd1cd897 | 113 | |
Rhyme | 0:d895cd1cd897 | 114 | if (days >= dim) { |
Rhyme | 0:d895cd1cd897 | 115 | days -= dim ; |
Rhyme | 0:d895cd1cd897 | 116 | } else { |
Rhyme | 0:d895cd1cd897 | 117 | break ; |
Rhyme | 0:d895cd1cd897 | 118 | } |
Rhyme | 0:d895cd1cd897 | 119 | } |
Rhyme | 0:d895cd1cd897 | 120 | break ; |
Rhyme | 0:d895cd1cd897 | 121 | } |
Rhyme | 0:d895cd1cd897 | 122 | } |
Rhyme | 0:d895cd1cd897 | 123 | tm->tm_sec = seconds ; |
Rhyme | 0:d895cd1cd897 | 124 | tm->tm_min = minutes ; |
Rhyme | 0:d895cd1cd897 | 125 | tm->tm_hour = hours ; |
Rhyme | 0:d895cd1cd897 | 126 | tm->tm_mday = days + 1 ; |
Rhyme | 0:d895cd1cd897 | 127 | tm->tm_mon = month ; |
Rhyme | 0:d895cd1cd897 | 128 | tm->tm_year = year ; |
Rhyme | 0:d895cd1cd897 | 129 | tm->tm_wday = dayOfWeek ; |
Rhyme | 0:d895cd1cd897 | 130 | } |
Rhyme | 0:d895cd1cd897 | 131 | |
Rhyme | 0:d895cd1cd897 | 132 | void print_time(struct tm *tm) |
Rhyme | 0:d895cd1cd897 | 133 | { |
Rhyme | 0:d895cd1cd897 | 134 | printf("%02d:%02d:%02d", |
Rhyme | 0:d895cd1cd897 | 135 | tm->tm_hour, |
Rhyme | 0:d895cd1cd897 | 136 | tm->tm_min, |
Rhyme | 0:d895cd1cd897 | 137 | tm->tm_sec ) ; |
Rhyme | 0:d895cd1cd897 | 138 | } |
Rhyme | 0:d895cd1cd897 | 139 | |
Rhyme | 0:d895cd1cd897 | 140 | void print_time(uint32_t thetime) |
Rhyme | 0:d895cd1cd897 | 141 | { |
Rhyme | 0:d895cd1cd897 | 142 | struct tm timestruct ; |
Rhyme | 0:d895cd1cd897 | 143 | ts2time(thetime, ×truct) ; |
Rhyme | 0:d895cd1cd897 | 144 | print_time(×truct) ; |
Rhyme | 0:d895cd1cd897 | 145 | } |
Rhyme | 0:d895cd1cd897 | 146 | |
Rhyme | 0:d895cd1cd897 | 147 | void print_time(void) |
Rhyme | 0:d895cd1cd897 | 148 | { |
Rhyme | 0:d895cd1cd897 | 149 | struct tm timestruct ; |
Rhyme | 0:d895cd1cd897 | 150 | ts2time(edge_time, ×truct) ; |
Rhyme | 0:d895cd1cd897 | 151 | print_time(×truct) ; |
Rhyme | 0:d895cd1cd897 | 152 | } |
Rhyme | 0:d895cd1cd897 | 153 | |
Rhyme | 0:d895cd1cd897 | 154 | void print_date(struct tm *tm) |
Rhyme | 0:d895cd1cd897 | 155 | { |
Rhyme | 0:d895cd1cd897 | 156 | printf("%d/%d/%d %02d:%02d:%02d", |
Rhyme | 0:d895cd1cd897 | 157 | tm->tm_year, |
Rhyme | 0:d895cd1cd897 | 158 | tm->tm_mon + 1, |
Rhyme | 0:d895cd1cd897 | 159 | tm->tm_mday, |
Rhyme | 0:d895cd1cd897 | 160 | tm->tm_hour, |
Rhyme | 0:d895cd1cd897 | 161 | tm->tm_min, |
Rhyme | 0:d895cd1cd897 | 162 | tm->tm_sec |
Rhyme | 0:d895cd1cd897 | 163 | ) ; |
Rhyme | 0:d895cd1cd897 | 164 | } |
Rhyme | 0:d895cd1cd897 | 165 | |
Rhyme | 0:d895cd1cd897 | 166 | void print_date_wd(struct tm *tm) |
Rhyme | 0:d895cd1cd897 | 167 | { |
Rhyme | 0:d895cd1cd897 | 168 | printf("%d/%d/%d %02d:%02d:%02d (%s)", |
Rhyme | 0:d895cd1cd897 | 169 | tm->tm_year, |
Rhyme | 0:d895cd1cd897 | 170 | tm->tm_mon + 1, |
Rhyme | 0:d895cd1cd897 | 171 | tm->tm_mday, |
Rhyme | 0:d895cd1cd897 | 172 | tm->tm_hour, |
Rhyme | 0:d895cd1cd897 | 173 | tm->tm_min, |
Rhyme | 0:d895cd1cd897 | 174 | tm->tm_sec, |
Rhyme | 0:d895cd1cd897 | 175 | nameOfDay[tm->tm_wday] |
Rhyme | 0:d895cd1cd897 | 176 | ) ; |
Rhyme | 0:d895cd1cd897 | 177 | } |
Rhyme | 0:d895cd1cd897 | 178 | |
Rhyme | 0:d895cd1cd897 | 179 | void time2str(struct tm *tm, char *timestr) |
Rhyme | 0:d895cd1cd897 | 180 | { |
Rhyme | 0:d895cd1cd897 | 181 | sprintf(timestr, "%02d:%02d:%02d", |
Rhyme | 0:d895cd1cd897 | 182 | tm->tm_hour, |
Rhyme | 0:d895cd1cd897 | 183 | tm->tm_min, |
Rhyme | 0:d895cd1cd897 | 184 | tm->tm_sec ) ; |
Rhyme | 0:d895cd1cd897 | 185 | } |
Rhyme | 0:d895cd1cd897 | 186 | |
Rhyme | 0:d895cd1cd897 | 187 | void time2str(char *timestr) |
Rhyme | 0:d895cd1cd897 | 188 | { |
Rhyme | 0:d895cd1cd897 | 189 | struct tm timestruct ; |
Rhyme | 0:d895cd1cd897 | 190 | ts2time(edge_time, ×truct) ; |
Rhyme | 0:d895cd1cd897 | 191 | time2str(×truct, timestr) ; |
Rhyme | 0:d895cd1cd897 | 192 | } |
Rhyme | 0:d895cd1cd897 | 193 | |
Rhyme | 0:d895cd1cd897 | 194 | int32_t time2seq(uint32_t timestamp) |
Rhyme | 0:d895cd1cd897 | 195 | { |
Rhyme | 0:d895cd1cd897 | 196 | struct tm timestruct ; |
Rhyme | 0:d895cd1cd897 | 197 | int32_t result ; |
Rhyme | 0:d895cd1cd897 | 198 | ts2time(timestamp, ×truct) ; |
Rhyme | 0:d895cd1cd897 | 199 | result = timestruct.tm_hour * 10000 |
Rhyme | 0:d895cd1cd897 | 200 | + timestruct.tm_min * 100 |
Rhyme | 0:d895cd1cd897 | 201 | + timestruct.tm_sec ; |
Rhyme | 0:d895cd1cd897 | 202 | return(result) ; |
Rhyme | 0:d895cd1cd897 | 203 | } |
Rhyme | 0:d895cd1cd897 | 204 | |
Rhyme | 0:d895cd1cd897 | 205 | void time2seq(uint32_t timestamp, char *timestr) |
Rhyme | 0:d895cd1cd897 | 206 | { |
Rhyme | 0:d895cd1cd897 | 207 | struct tm timestruct ; |
Rhyme | 0:d895cd1cd897 | 208 | ts2tm(timestamp, ×truct) ; |
Rhyme | 0:d895cd1cd897 | 209 | sprintf(timestr, "%d%02d%02d%02d%02d%02d", |
Rhyme | 0:d895cd1cd897 | 210 | timestruct.tm_year, |
Rhyme | 0:d895cd1cd897 | 211 | timestruct.tm_mon + 1, |
Rhyme | 0:d895cd1cd897 | 212 | timestruct.tm_mday, |
Rhyme | 0:d895cd1cd897 | 213 | timestruct.tm_hour, |
Rhyme | 0:d895cd1cd897 | 214 | timestruct.tm_min, |
Rhyme | 0:d895cd1cd897 | 215 | timestruct.tm_sec |
Rhyme | 0:d895cd1cd897 | 216 | ) ; |
Rhyme | 0:d895cd1cd897 | 217 | } |
Rhyme | 0:d895cd1cd897 | 218 | |
Rhyme | 0:d895cd1cd897 | 219 | void time2date(struct tm *tm, char *datestr) |
Rhyme | 0:d895cd1cd897 | 220 | { |
Rhyme | 0:d895cd1cd897 | 221 | sprintf(datestr, "%d/%d/%d %02d:%02d:%02d (%s)", |
Rhyme | 0:d895cd1cd897 | 222 | tm->tm_year, |
Rhyme | 0:d895cd1cd897 | 223 | tm->tm_mon + 1, |
Rhyme | 0:d895cd1cd897 | 224 | tm->tm_mday, |
Rhyme | 0:d895cd1cd897 | 225 | tm->tm_hour, |
Rhyme | 0:d895cd1cd897 | 226 | tm->tm_min, |
Rhyme | 0:d895cd1cd897 | 227 | tm->tm_sec, |
Rhyme | 0:d895cd1cd897 | 228 | nameOfDay[tm->tm_wday] |
Rhyme | 0:d895cd1cd897 | 229 | ) ; |
Rhyme | 0:d895cd1cd897 | 230 | } |