uint8_t rtc_read_second (void) { while (is_update_in_progress ()) expensive_nop (); uint8_t second = read (reg_second); uint8_t b = read (reg_b); if (!(b & flag_binary)) second = (second & 0x0F) + ((second / 16) * 10); return second; }
bool x86_rtc_read(x86_rtc_data_t *dest) { if (!valid) { return false; } unsigned old_status = irq_disable(); while (is_update_in_progress()) { __asm__ volatile ("pause"); } uint8_t b = x86_cmos_read(RTC_REG_B); do { dest->second = x86_cmos_read(RTC_REG_SECOND); dest->minute = x86_cmos_read(RTC_REG_MINUTE); dest->hour = x86_cmos_read(RTC_REG_HOUR); dest->day = x86_cmos_read(RTC_REG_DAY); dest->month = x86_cmos_read(RTC_REG_MONTH); dest->year = x86_cmos_read(RTC_REG_YEAR); dest->century = bcd2binary(x86_cmos_read(RTC_REG_CENTURY)); } while (dest->second != x86_cmos_read(RTC_REG_SECOND)); if (dest->century == 0) { dest->century = 20; // safe guess } if (!(b & RTC_REG_B_BIN)) { dest->second = bcd2binary(dest->second); dest->minute = bcd2binary(dest->minute); dest->hour = ((dest->hour & 0x0F) + (((dest->hour & 0x70) / 16) * 10)) | (dest->hour & 0x80); dest->day = bcd2binary(dest->day); dest->month = bcd2binary(dest->month); dest->year = bcd2binary(dest->year); } if (!(b & RTC_REG_B_24H) && (dest->hour & 0x80)) { dest->hour = ((dest->hour & 0x7F) + 12) % 24; } irq_restore(old_status); return true; }
bool rtc_read (struct rtc_data *dest) { bool old_intr_level = intr_get_and_set_off (); while (is_update_in_progress ()) expensive_nop (); uint8_t second = read (reg_second); uint8_t minute = read (reg_minute); uint8_t hour = read (reg_hour); uint8_t day = read (reg_day); uint8_t month = read (reg_month); uint8_t year = read (reg_year); uint8_t b = read (reg_b); if (!(b & flag_binary)) { second = (second & 0x0F) + ((second / 16) * 10); minute = (minute & 0x0F) + ((minute / 16) * 10); hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80); day = (day & 0x0F) + ((day / 16) * 10); month = (month & 0x0F) + ((month / 16) * 10); year = (year & 0x0F) + ((year / 16) * 10); } if (!(b & flag_24h) && (hour & 0x80)) hour = ((hour & 0x7F) + 12) % 24; dest->second = second; dest->minute = minute; dest->hour = hour; dest->day = day; dest->month = month; dest->year = year; intr_set (old_intr_level); return true; }