static void ds1216e_latch_regs(rtc_ds1216e_t *context) { time_t latch = (context->inactive) ? context->latch : rtc_get_latch(context->offset); context->clock_regs[DS1216E_REGISTER_CENTISECONDS] = rtc_get_centisecond(1); context->clock_regs[DS1216E_REGISTER_SECONDS] = rtc_get_second(latch, 1); context->clock_regs[DS1216E_REGISTER_MINUTES] = rtc_get_minute(latch, 1); context->clock_regs[DS1216E_REGISTER_HOURS] = (context->hours12) ? 0x80 : 0; if (context->hours12) { context->clock_regs[DS1216E_REGISTER_HOURS] |= rtc_get_hour_am_pm(latch, 1); } else { context->clock_regs[DS1216E_REGISTER_HOURS] |= rtc_get_hour(latch, 1); } context->clock_regs[DS1216E_REGISTER_WEEKDAYS] = (context->inactive) ? 0x20 : 0; context->clock_regs[DS1216E_REGISTER_WEEKDAYS] |= (context->reset) ? 0x10 : 0; context->clock_regs[DS1216E_REGISTER_WEEKDAYS] |= ((rtc_get_weekday(latch) - 1) % 7) + 1; context->clock_regs[DS1216E_REGISTER_MONTHDAYS] = rtc_get_day_of_month(latch, 1); context->clock_regs[DS1216E_REGISTER_MONTHS] = rtc_get_month(latch, 1); context->clock_regs[DS1216E_REGISTER_YEARS] = rtc_get_year(latch, 1); }
static void pcf8583_i2c_start(rtc_pcf8583_t *context) { BYTE tmp; time_t latch = (context->clock_halt) ? context->clock_halt_latch : rtc_get_latch(context->offset); int i; context->clock_regs_for_read[PCF8583_REG_CONTROL] = context->clock_regs[PCF8583_REG_CONTROL]; context->clock_regs_for_read[PCF8583_REG_100TH_SECONDS] = rtc_get_centisecond(1); context->clock_regs_for_read[PCF8583_REG_SECONDS] = rtc_get_second(latch, 1); context->clock_regs_for_read[PCF8583_REG_MINUTES] = rtc_get_minute(latch, 1); tmp = context->am_pm << 7; if (context->am_pm) { tmp |= rtc_get_hour_am_pm(latch, 1); if (tmp & 0x20) { tmp &= 0xdf; tmp |= 0x40; } } else { tmp |= rtc_get_hour(latch, 1); } context->clock_regs_for_read[PCF8583_REG_HOURS] = tmp; tmp = rtc_get_year(latch, 1); tmp &= 3; tmp <<= 6; tmp |= rtc_get_day_of_month(latch, 1); context->clock_regs_for_read[PCF8583_REG_YEARS_MONTH_DAYS] = tmp; tmp = rtc_get_weekday(latch) + 1; tmp &= 7; tmp <<= 5; tmp |= rtc_get_month(latch, 1); context->clock_regs_for_read[PCF8583_REG_WEEK_DAYS_MONTHS] = tmp; context->clock_regs_for_read[PCF8583_REG_TIMER_DAYS] = 0; for (i = PCF8583_REG_ALARM_CONTROL; i <= PCF8583_REG_TIMER_ALARM; ++i) { context->clock_regs_for_read[i] = context->clock_regs[i]; } if (context->read_bit_shift) { make_read_register_train(context); } }
BYTE rtc72421_read(rtc_72421_t *context, BYTE address) { BYTE retval = 0; time_t latch = (context->stop) ? context->latch : rtc_get_latch(context->offset); switch (address & 0xf) { case RTC72421_REGISTER_SECONDS: retval = rtc_get_second(latch, 0); retval %= 10; break; case RTC72421_REGISTER_10SECONDS: retval = rtc_get_second(latch, 0); retval /= 10; break; case RTC72421_REGISTER_MINUTES: retval = rtc_get_minute(latch, 0); retval %= 10; break; case RTC72421_REGISTER_10MINUTES: retval = rtc_get_minute(latch, 0); retval /= 10; break; case RTC72421_REGISTER_HOURS: if (context->hour24) { retval = rtc_get_hour(latch, 0); } else { retval = rtc_get_hour_am_pm(latch, 0); retval &= 0x1f; } retval %= 10; break; case RTC72421_REGISTER_10HOURS: if (context->hour24) { retval = rtc_get_hour(latch, 0); retval /= 10; retval |= 8; } else { retval = rtc_get_hour_am_pm(latch, 0); if (retval > 23) { retval = (retval - 32) / 10; retval |= 4; } else { retval /= 10; } } break; case RTC72421_REGISTER_WEEKDAYS: retval = rtc_get_weekday(latch) - 1; if (retval > 6) { retval = 6; } break; case RTC72421_REGISTER_MONTHDAYS: retval = rtc_get_day_of_month(latch, 0); retval %= 10; break; case RTC72421_REGISTER_10MONTHDAYS: retval = rtc_get_day_of_month(latch, 0); retval /= 10; break; case RTC72421_REGISTER_MONTHS: retval = rtc_get_month(latch, 0); retval %= 10; break; case RTC72421_REGISTER_10MONTHS: retval = rtc_get_month(latch, 0); retval /= 10; break; case RTC72421_REGISTER_YEARS: retval = rtc_get_year(latch, 0); retval %= 10; break; case RTC72421_REGISTER_10YEARS: retval = rtc_get_year(latch, 0); retval /= 10; break; case RTC72421_REGISTER_CTRL2: retval = context->hour24 ? 2 : 0; retval |= context->stop ? 1 : 0; break; } return retval; }
BYTE rtc58321a_read(rtc_58321a_t *context) { BYTE retval = 0; time_t latch = (context->stop) ? context->latch : rtc_get_latch(context->offset[0]); switch (context->address) { case RTC58321A_REGISTER_SECONDS: retval = rtc_get_second(latch, 0); retval %= 10; break; case RTC58321A_REGISTER_10SECONDS: retval = rtc_get_second(latch, 0); retval /= 10; break; case RTC58321A_REGISTER_MINUTES: retval = rtc_get_minute(latch, 0); retval %= 10; break; case RTC58321A_REGISTER_10MINUTES: retval = rtc_get_minute(latch, 0); retval /= 10; break; case RTC58321A_REGISTER_HOURS: if (context->hour24) { retval = rtc_get_hour(latch, 0); } else { retval = rtc_get_hour_am_pm(latch, 0); retval &= 0x1f; } retval %= 10; break; case RTC58321A_REGISTER_10HOURS: if (context->hour24) { retval = rtc_get_hour(latch, 0); retval /= 10; retval |= 0x80; } else { retval = rtc_get_hour_am_pm(latch, 0); if (retval > 23) { retval = (retval - 32) / 10; retval |= 4; } else { retval /= 10; } } break; case RTC58321A_REGISTER_WEEKDAYS: retval = rtc_get_weekday(latch); break; case RTC58321A_REGISTER_MONTHDAYS: retval = rtc_get_day_of_month(latch, 0); retval %= 10; break; case RTC58321A_REGISTER_10MONTHDAYS: retval = rtc_get_day_of_month(latch, 0); retval /= 10; /* TODO: leapyear calculation */ break; case RTC58321A_REGISTER_MONTHS: retval = rtc_get_month(latch, 0); retval %= 10; break; case RTC58321A_REGISTER_10MONTHS: retval = rtc_get_month(latch, 0); retval /= 10; break; case RTC58321A_REGISTER_YEARS: retval = rtc_get_year(latch, 0); retval %= 10; break; case RTC58321A_REGISTER_10YEARS: retval = rtc_get_year(latch, 0); retval /= 10; break; } return retval; }