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
- Committer:
- gaku_miyagawa
- Date:
- 2018-06-18
- Revision:
- 2:de22987be9ba
- Parent:
- 0:d895cd1cd897
File content as of revision 2:de22987be9ba:
#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] ) ; }