void rtc72421_write(rtc_72421_t *context, BYTE address, BYTE data) { time_t latch = (context->stop) ? context->latch : rtc_get_latch(context->offset); BYTE real_data = data & 0xf; BYTE new_data; switch (address & 0xf) { case RTC72421_REGISTER_SECONDS: new_data = rtc_get_second(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_second(new_data, latch, 0); } else { context->offset = rtc_set_second(new_data, context->offset, 0); } break; case RTC72421_REGISTER_10SECONDS: new_data = rtc_get_second(latch, 0); new_data %= 10; new_data += ((real_data & 7) * 10); if (context->stop) { context->latch = rtc_set_latched_second(new_data, latch, 0); } else { context->offset = rtc_set_second(new_data, context->offset, 0); } break; case RTC72421_REGISTER_MINUTES: new_data = rtc_get_minute(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_minute(new_data, latch, 0); } else { context->offset = rtc_set_minute(new_data, context->offset, 0); } break; case RTC72421_REGISTER_10MINUTES: new_data = rtc_get_minute(latch, 0); new_data %= 10; new_data += ((real_data & 7) * 10); if (context->stop) { context->latch = rtc_set_latched_minute(new_data, latch, 0); } else { context->offset = rtc_set_minute(new_data, context->offset, 0); } break; case RTC72421_REGISTER_HOURS: if (context->hour24) { new_data = rtc_get_hour(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_hour(new_data, latch, 0); } else { context->offset = rtc_set_hour(new_data, context->offset, 0); } } else { new_data = rtc_get_hour_am_pm(latch, 0); if (new_data >= 32) { new_data -= 32; new_data /= 10; new_data *= 10; new_data += (LIMIT_9(real_data) + 32); } else { new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); } if (context->stop) { context->latch = rtc_set_latched_hour_am_pm(new_data, latch, 0); } else { context->offset = rtc_set_hour_am_pm(new_data, context->offset, 0); } } break; case RTC72421_REGISTER_10HOURS: if (real_data & 8) { new_data = rtc_get_hour(latch, 0); new_data %= 10; new_data += ((real_data & 3) * 10); context->hour24 = 1; if (context->stop) { context->latch = rtc_set_latched_hour(new_data, latch, 0); } else { context->offset = rtc_set_hour(new_data, context->offset, 0); } } else { real_data &= 7; new_data = rtc_get_hour_am_pm(latch, 0); if (new_data >= 32) { new_data -= 32; } new_data %= 10; new_data += ((real_data & 3) * 10); if (real_data & 4) { new_data += 32; } context->hour24 = 0; if (context->stop) { context->latch = rtc_set_latched_hour_am_pm(new_data, latch, 0); } else { context->offset = rtc_set_hour_am_pm(new_data, context->offset, 0); } } break; case RTC72421_REGISTER_WEEKDAYS: if (context->stop) { context->latch = rtc_set_latched_weekday(((real_data + 1) & 7), latch); } else { context->offset = rtc_set_weekday(((real_data + 1) & 7), context->offset); } break; case RTC72421_REGISTER_MONTHDAYS: new_data = rtc_get_day_of_month(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_day_of_month(new_data, latch, 0); } else { context->offset = rtc_set_day_of_month(new_data, context->offset, 0); } break; case RTC72421_REGISTER_10MONTHDAYS: new_data = rtc_get_day_of_month(latch, 0); new_data %= 10; new_data += ((real_data & 3) * 10); if (context->stop) { context->latch = rtc_set_latched_day_of_month(new_data, latch, 0); } else { context->offset = rtc_set_day_of_month(new_data, context->offset, 0); } break; case RTC72421_REGISTER_MONTHS: new_data = rtc_get_month(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_month(new_data, latch, 0); } else { context->offset = rtc_set_month(new_data, context->offset, 0); } break; case RTC72421_REGISTER_10MONTHS: new_data = rtc_get_month(latch, 0); new_data %= 10; new_data += ((real_data & 1) * 10); if (context->stop) { context->latch = rtc_set_latched_month(new_data, latch, 0); } else { context->offset = rtc_set_month(new_data, context->offset, 0); } break; case RTC72421_REGISTER_YEARS: new_data = rtc_get_year(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_year(new_data, latch, 0); } else { context->offset = rtc_set_year(new_data, context->offset, 0); } break; case RTC72421_REGISTER_10YEARS: new_data = rtc_get_year(latch, 0); new_data %= 10; new_data += (LIMIT_9(real_data) * 10); if (context->stop) { context->latch = rtc_set_latched_year(new_data, latch, 0); } else { context->offset = rtc_set_year(new_data, context->offset, 0); } break; case RTC72421_REGISTER_CTRL2: context->hour24 = (real_data & 4) ? 1: 0; if (real_data & 2) { context->stop = 1; context->latch = rtc_get_latch(context->offset); } else { context->stop = 0; context->offset = context->offset - (rtc_get_latch(0) - (context->latch - context->offset)); } break; } }
void rtc58321a_write_data(rtc_58321a_t *context, BYTE data) { time_t latch = (context->stop) ? context->latch : rtc_get_latch(context->offset[0]); BYTE real_data = data & 0xf; BYTE new_data; switch (context->address) { case RTC58321A_REGISTER_SECONDS: new_data = rtc_get_second(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_second(new_data, latch, 0); } else { context->offset[0] = rtc_set_second(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_10SECONDS: new_data = rtc_get_second(latch, 0); new_data %= 10; new_data += ((real_data & 7) * 10); if (context->stop) { context->latch = rtc_set_latched_second(new_data, latch, 0); } else { context->offset[0] = rtc_set_second(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_MINUTES: new_data = rtc_get_minute(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_minute(new_data, latch, 0); } else { context->offset[0] = rtc_set_minute(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_10MINUTES: new_data = rtc_get_minute(latch, 0); new_data %= 10; new_data += ((real_data & 7) * 10); if (context->stop) { context->latch = rtc_set_latched_minute(new_data, latch, 0); } else { context->offset[0] = rtc_set_minute(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_HOURS: if (context->hour24) { new_data = rtc_get_hour(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_hour(new_data, latch, 0); } else { context->offset[0] = rtc_set_hour(new_data, context->offset[0], 0); } } else { new_data = rtc_get_hour_am_pm(latch, 0); if (new_data >= 32) { new_data -= 32; new_data /= 10; new_data *= 10; new_data += (LIMIT_9(real_data) + 32); } else { new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); } if (context->stop) { context->latch = rtc_set_latched_hour_am_pm(new_data, latch, 0); } else { context->offset[0] = rtc_set_hour_am_pm(new_data, context->offset[0], 0); } } break; case RTC58321A_REGISTER_10HOURS: if (real_data & 8) { new_data = rtc_get_hour(latch, 0); new_data %= 10; new_data += ((real_data & 3) * 10); context->hour24 = 1; if (context->stop) { context->latch = rtc_set_latched_hour(new_data, latch, 0); } else { context->offset[0] = rtc_set_hour(new_data, context->offset[0], 0); } } else { real_data &= 7; new_data = rtc_get_hour_am_pm(latch, 0); if (new_data >= 32) { new_data -= 32; } new_data %= 10; new_data += ((real_data & 3) * 10); if (real_data & 4) { new_data += 32; } context->hour24 = 0; if (context->stop) { context->latch = rtc_set_latched_hour_am_pm(new_data, latch, 0); } else { context->offset[0] = rtc_set_hour_am_pm(new_data, context->offset[0], 0); } } break; case RTC58321A_REGISTER_WEEKDAYS: if (context->stop) { context->latch = rtc_set_latched_weekday((real_data & 7), latch); } else { context->offset[0] = rtc_set_weekday((real_data & 7), context->offset[0]); } break; case RTC58321A_REGISTER_MONTHDAYS: new_data = rtc_get_day_of_month(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_day_of_month(new_data, latch, 0); } else { context->offset[0] = rtc_set_day_of_month(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_10MONTHDAYS: new_data = rtc_get_day_of_month(latch, 0); new_data %= 10; new_data += ((real_data & 3) * 10); if (context->stop) { context->latch = rtc_set_latched_day_of_month(new_data, latch, 0); } else { context->offset[0] = rtc_set_day_of_month(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_MONTHS: new_data = rtc_get_month(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_month(new_data, latch, 0); } else { context->offset[0] = rtc_set_month(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_10MONTHS: new_data = rtc_get_month(latch, 0); new_data %= 10; new_data += ((real_data & 1) * 10); if (context->stop) { context->latch = rtc_set_latched_month(new_data, latch, 0); } else { context->offset[0] = rtc_set_month(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_YEARS: new_data = rtc_get_year(latch, 0); new_data /= 10; new_data *= 10; new_data += LIMIT_9(real_data); if (context->stop) { context->latch = rtc_set_latched_year(new_data, latch, 0); } else { context->offset[0] = rtc_set_year(new_data, context->offset[0], 0); } break; case RTC58321A_REGISTER_10YEARS: new_data = rtc_get_year(latch, 0); new_data %= 10; new_data += (LIMIT_9(real_data) * 10); if (context->stop) { context->latch = rtc_set_latched_year(new_data, latch, 0); } else { context->offset[0] = rtc_set_year(new_data, context->offset[0], 0); } break; } }