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) 反転させることにより、疑似リセットクロックを生成します。
その後は、通常の起動手順に復帰し、以降はこれまでと同様の動作をします。
Diff: edge_utils/edge_time.cpp
- Revision:
- 0:d895cd1cd897
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/edge_utils/edge_time.cpp Tue Apr 03 08:30:29 2018 +0000 @@ -0,0 +1,230 @@ +#include "mbed.h" +#include "edge_time.h" + +static const uint8_t daysInMonth[12] = { + 31, 28, 31, 30, + 31, 30, 31, 31, + 30, 31, 30, 31 +} ; + +const char *nameOfDay[7] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday" +} ; + +uint32_t edge_time = 0 ; +uint32_t utc_offset = 9 * 60 * 60 ; +tm current_time ; +Ticker *tokei = 0 ; + +void inc_sec(void) +{ + __disable_irq() ; // Disable Interrupts + edge_time++ ; + __enable_irq() ; // Enable Interrupts +} + +void init_timer(void) +{ + tokei = new Ticker() ; + tokei->attach(inc_sec, 1.0) ; +} + +void set_time(const uint16_t valueLen, const uint8_t *value) +{ + uint32_t tmp_timestamp = 0 ; + for (int i = 0 ; i < valueLen ; i++ ) { + tmp_timestamp |= (value[i] & 0xFF) << (i * 8) ; + } + edge_time = tmp_timestamp ; + ts2tm(edge_time, ¤t_time) ; +// ts2time(edge_time, ¤t_time) ; +} + +void ts2time(uint32_t timestamp, struct tm *tm) +{ + uint32_t seconds, minutes, hours, days, month, year ; + uint32_t dayOfWeek ; + +// timestamp += (3600 * 9) ; /* +9 hours for JST */ + timestamp += utc_offset ; + + seconds = timestamp % 60 ; + minutes = timestamp / 60 ; + hours = minutes / 60 ; /* +9 for JST */ + minutes -= hours * 60 ; + days = hours / 24 ; + hours -= days * 24 ; + + tm->tm_sec = seconds ; + tm->tm_min = minutes ; + tm->tm_hour = hours ; + tm->tm_mday = days + 1 ; +// tm->tm_mon = month ; +// tm->tm_year = year ; +// tm->tm_wday = dayOfWeek ; +} + +void ts2tm(uint32_t timestamp, struct tm *tm) +{ + uint32_t seconds, minutes, hours, days, month, year ; + uint32_t dayOfWeek ; + +// timestamp += (3600 * 9) ; /* +9 hours for JST */ + timestamp += utc_offset ; + + seconds = timestamp % 60 ; + minutes = timestamp / 60 ; + hours = minutes / 60 ; /* +9 for JST */ + minutes -= hours * 60 ; + days = hours / 24 ; + hours -= days * 24 ; + + /* Unix timestamp start 1-Jan-1970 Thursday */ + year = 1970 ; + dayOfWeek = 4 ; /* Thursday */ + + while(1) { + bool isLeapYear = + (((year % 4) == 0) + &&(((year % 100) != 0) + || ((year % 400) == 0))) ; + uint16_t daysInYear = isLeapYear ? 366 : 365 ; + if (days >= daysInYear) { + dayOfWeek += isLeapYear ? 2 : 1 ; + days -= daysInYear ; + if (dayOfWeek >= 7) { + dayOfWeek -= 7 ; + } + year++ ; + } else { + tm->tm_yday = days ; + dayOfWeek += days ; + dayOfWeek %= 7 ; + + /* calc the month and the day */ + for (month = 0 ; month < 12 ; month++) { + uint8_t dim = daysInMonth[month] ; + + /* add a day to feburary if this is a leap year */ + if ((month == 1) && (isLeapYear)) { + dim++ ; + } + + if (days >= dim) { + days -= dim ; + } else { + break ; + } + } + break ; + } + } + tm->tm_sec = seconds ; + tm->tm_min = minutes ; + tm->tm_hour = hours ; + tm->tm_mday = days + 1 ; + tm->tm_mon = month ; + tm->tm_year = year ; + tm->tm_wday = dayOfWeek ; +} + +void print_time(struct tm *tm) +{ + printf("%02d:%02d:%02d", + tm->tm_hour, + tm->tm_min, + tm->tm_sec ) ; +} + +void print_time(uint32_t thetime) +{ + struct tm timestruct ; + ts2time(thetime, ×truct) ; + print_time(×truct) ; +} + +void print_time(void) +{ + struct tm timestruct ; + ts2time(edge_time, ×truct) ; + print_time(×truct) ; +} + +void print_date(struct tm *tm) +{ + printf("%d/%d/%d %02d:%02d:%02d", + tm->tm_year, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec + ) ; +} + +void print_date_wd(struct tm *tm) +{ + printf("%d/%d/%d %02d:%02d:%02d (%s)", + tm->tm_year, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + nameOfDay[tm->tm_wday] + ) ; +} + +void time2str(struct tm *tm, char *timestr) +{ + sprintf(timestr, "%02d:%02d:%02d", + tm->tm_hour, + tm->tm_min, + tm->tm_sec ) ; +} + +void time2str(char *timestr) +{ + struct tm timestruct ; + ts2time(edge_time, ×truct) ; + time2str(×truct, timestr) ; +} + +int32_t time2seq(uint32_t timestamp) +{ + struct tm timestruct ; + int32_t result ; + ts2time(timestamp, ×truct) ; + result = timestruct.tm_hour * 10000 + + timestruct.tm_min * 100 + + timestruct.tm_sec ; + return(result) ; +} + +void time2seq(uint32_t timestamp, char *timestr) +{ + struct tm timestruct ; + ts2tm(timestamp, ×truct) ; + sprintf(timestr, "%d%02d%02d%02d%02d%02d", + timestruct.tm_year, + timestruct.tm_mon + 1, + timestruct.tm_mday, + timestruct.tm_hour, + timestruct.tm_min, + timestruct.tm_sec + ) ; +} + +void time2date(struct tm *tm, char *datestr) +{ + sprintf(datestr, "%d/%d/%d %02d:%02d:%02d (%s)", + tm->tm_year, + tm->tm_mon + 1, + tm->tm_mday, + tm->tm_hour, + tm->tm_min, + tm->tm_sec, + nameOfDay[tm->tm_wday] + ) ; +} \ No newline at end of file