static PyObject * py_ds1302_get_time(PyObject *self, PyObject *args) { unsigned char hour, min, sec; hour = from_bcd(time_get(RTC_HOUR)); min = from_bcd(time_get(RTC_MIN)); sec = from_bcd(time_get(RTC_SEC)); return Py_BuildValue("iii", hour, min, sec); }
static PyObject * py_ds1302_get_date(PyObject *self, PyObject *args) { unsigned int year, month, date; year = 2000 + from_bcd(time_get(RTC_YEAR)); month = from_bcd(time_get(RTC_MONTH)); date = from_bcd(time_get(RTC_DATE)); return Py_BuildValue("iii", year, month, date); }
/** * Get the current month and day. * * @param month Pointer to a short to store the month * @param day Pointer to a short to store the day */ void get_date( uint16_t * month, uint16_t * day ) { uint16_t values[128]; /* CMOS dump */ cmos_dump(values); *month = from_bcd(values[8]); *day = from_bcd(values[7]); }
/** * Get the current time. * * @param hours Pointer to a short to store the current hour (/24) * @param minutes Pointer to a short to store the current minute * @param seconds Pointer to a short to store the current second */ void get_time( uint16_t * hours, uint16_t * minutes, uint16_t * seconds ) { uint16_t values[128]; /* CMOS dump */ cmos_dump(values); *hours = from_bcd(values[4]); *minutes = from_bcd(values[2]); *seconds = from_bcd(values[0]); }
static void rtc_set_time(RTCState *s) { struct tm *tm = &s->current_tm; struct domain *d = vrtc_domain(s); unsigned long before, after; /* XXX s_time_t */ ASSERT(spin_is_locked(&s->lock)); before = mktime(get_year(tm->tm_year), tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); tm->tm_sec = from_bcd(s, s->hw.cmos_data[RTC_SECONDS]); tm->tm_min = from_bcd(s, s->hw.cmos_data[RTC_MINUTES]); tm->tm_hour = from_bcd(s, s->hw.cmos_data[RTC_HOURS] & 0x7f); tm->tm_hour = convert_hour(s, tm->tm_hour); tm->tm_wday = from_bcd(s, s->hw.cmos_data[RTC_DAY_OF_WEEK]); tm->tm_mday = from_bcd(s, s->hw.cmos_data[RTC_DAY_OF_MONTH]); tm->tm_mon = from_bcd(s, s->hw.cmos_data[RTC_MONTH]) - 1; tm->tm_year = from_bcd(s, s->hw.cmos_data[RTC_YEAR]) + 100; after = mktime(get_year(tm->tm_year), tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); /* We use the guest's setting of the RTC to define the local-time * offset for this domain. */ d->time_offset_seconds += (after - before); update_domain_wallclock_time(d); /* Also tell qemu-dm about it so it will be remembered for next boot. */ send_timeoffset_req(after - before); }
/* Hours in 12 hour mode are in 1-12 range, not 0-11. * So we need convert it before using it*/ static inline int convert_hour(RTCState *s, int raw) { int hour = from_bcd(s, raw & 0x7f); if (!(s->hw.cmos_data[RTC_REG_B] & RTC_24H)) { hour %= 12; if (raw & 0x80) hour += 12; } return hour; }
int m48_tod_get(int *year, /* 1980-2079 */ int *month, /* 01-12 */ int *day, /* 01-31 */ int *hour, /* 00-23 */ int *minute, /* 00-59 */ int *second) /* 00-59 */ { int y; SYS_TOD_UNPROTECT(); M48_ADDR[CONTROL] |= 0x40; /* Set READ bit */ y = from_bcd(M48_ADDR[YEAR]); *year = y < 80 ? 2000 + y : 1900 + y; *month = from_bcd(M48_ADDR[MONTH]); *day = from_bcd(M48_ADDR[DAY]); /* day_of_week = M48_ADDR[DAY_OF_WEEK] & 0xf; */ *hour = from_bcd(M48_ADDR[HOUR]); *minute = from_bcd(M48_ADDR[MINUTE]); *second = from_bcd(M48_ADDR[SECOND] & 0x7f); M48_ADDR[CONTROL] &= ~0x40; /* Clear READ bit */ SYS_TOD_PROTECT(); return 0; }
static void rtc_set_time(RTCState *s) { struct tm *tm = &s->current_tm; tm->tm_sec = from_bcd(s, s->cmos_data[RTC_SECONDS]); tm->tm_min = from_bcd(s, s->cmos_data[RTC_MINUTES]); tm->tm_hour = from_bcd(s, s->cmos_data[RTC_HOURS] & 0x7f); if (!(s->cmos_data[RTC_REG_B] & 0x02) && (s->cmos_data[RTC_HOURS] & 0x80)) { tm->tm_hour += 12; } tm->tm_wday = from_bcd(s, s->cmos_data[RTC_DAY_OF_WEEK]) - 1; tm->tm_mday = from_bcd(s, s->cmos_data[RTC_DAY_OF_MONTH]); tm->tm_mon = from_bcd(s, s->cmos_data[RTC_MONTH]) - 1; tm->tm_year = from_bcd(s, s->cmos_data[RTC_YEAR]) + s->base_year - 1900; }
int gettimeofday(struct timeval * t, void *z) { uint16_t values[128]; cmos_dump(values); /* Math Time */ uint32_t time = secs_of_years(from_bcd(values[9]) - 1) + secs_of_month(from_bcd(values[8]) - 1, from_bcd(values[9])) + (from_bcd(values[7]) - 1) * 86400 + (from_bcd(values[4])) * 3600 + (from_bcd(values[2])) * 60 + from_bcd(values[0]) + 0; t->tv_sec = time; t->tv_usec = 0; return 0; }
int main (int argc, char *argv[]) { unsigned char b[(MAXDIGITS+1)/2]; freq_t f=0; int digits = 10; int i; if (argc != 2 && argc != 3) { fprintf(stderr,"Usage: %s <freq> [digits]\n",argv[0]); exit(1); } f = (freq_t)atoll(argv[1]); if (argc > 2) { digits = atoi(argv[2]); if (digits > MAXDIGITS) exit(1); } printf("Little Endian mode\n"); printf("Frequency: %"PRIfreq"\n",f); to_bcd(b, f, digits); printf("BCD: %2.2x",b[0]); for (i = 1; i < (digits+1)/2; i++) printf(",%2.2x",b[i]); printf("\nResult after recoding: %llu\n", from_bcd(b, digits)); printf("\nBig Endian mode\n"); printf("Frequency: %"PRIfreq"\n",f); to_bcd_be(b, f, digits); printf("BCD: %2.2x",b[0]); for (i = 1; i < (digits+1)/2; i++) printf(",%2.2x",b[i]); printf("\nResult after recoding: %llu\n", from_bcd_be(b, digits)); return 0; }
static void get_rtc_time(struct rtc_time *rtc_tm) { int cr2; /* * Read date and time from the RTC. We use read method (3). */ spin_lock_irq(&rtc_lock); i2c_start(); i2c_outb(RTC_I2C_ADDRESS | I2C_READ_MASK); cr2 = i2c_inb(I2C_ACK); rtc_tm->tm_sec = i2c_inb(I2C_ACK); rtc_tm->tm_min = i2c_inb(I2C_ACK); rtc_tm->tm_hour = i2c_inb(I2C_ACK); rtc_tm->tm_wday = i2c_inb(I2C_ACK); rtc_tm->tm_mday = i2c_inb(I2C_ACK); rtc_tm->tm_mon = i2c_inb(I2C_ACK); rtc_tm->tm_year = i2c_inb(I2C_NAK); i2c_stop(); spin_unlock_irq(&rtc_lock); if (cr2 & RTC_VDET_MASK) { printk(KERN_WARNING "***RTC BATTERY FAILURE***\n"); } /* Handle century bit */ if (rtc_tm->tm_mon & RTC_Y2K_MASK) { rtc_tm->tm_mon &= ~RTC_Y2K_MASK; rtc_tm->tm_year += 0x100; } rtc_tm->tm_sec = from_bcd(rtc_tm->tm_sec); rtc_tm->tm_min = from_bcd(rtc_tm->tm_min); rtc_tm->tm_hour = from_bcd(rtc_tm->tm_hour); rtc_tm->tm_mday = from_bcd(rtc_tm->tm_mday); rtc_tm->tm_mon = from_bcd(rtc_tm->tm_mon) - 1; rtc_tm->tm_year = from_bcd(rtc_tm->tm_year); rtc_tm->tm_isdst = -1; /* DST not known */ }
/* handle alarm timer */ static void alarm_timer_update(RTCState *s) { uint64_t next_update_time, next_alarm_sec; uint64_t expire_time; int32_t alarm_sec, alarm_min, alarm_hour, cur_hour, cur_min, cur_sec; int32_t hour, min; struct domain *d = vrtc_domain(s); ASSERT(spin_is_locked(&s->lock)); stop_timer(&s->alarm_timer); if (!(s->hw.cmos_data[RTC_REG_C] & RTC_AF) && !(s->hw.cmos_data[RTC_REG_B] & RTC_SET)) { s->current_tm = gmtime(get_localtime(d)); rtc_copy_date(s); alarm_sec = from_bcd(s, s->hw.cmos_data[RTC_SECONDS_ALARM]); alarm_min = from_bcd(s, s->hw.cmos_data[RTC_MINUTES_ALARM]); alarm_hour = convert_hour(s, s->hw.cmos_data[RTC_HOURS_ALARM]); cur_sec = from_bcd(s, s->hw.cmos_data[RTC_SECONDS]); cur_min = from_bcd(s, s->hw.cmos_data[RTC_MINUTES]); cur_hour = convert_hour(s, s->hw.cmos_data[RTC_HOURS]); next_update_time = USEC_PER_SEC - (get_localtime_us(d) % USEC_PER_SEC); next_update_time = next_update_time * NS_PER_USEC + NOW(); if ((s->hw.cmos_data[RTC_HOURS_ALARM] & 0xc0) == 0xc0) { if ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0) { if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec = 1; else if (cur_sec < alarm_sec) next_alarm_sec = alarm_sec - cur_sec; else next_alarm_sec = alarm_sec + SEC_PER_MIN - cur_sec; } else { if (cur_min < alarm_min) { min = alarm_min - cur_min; next_alarm_sec = min * SEC_PER_MIN - cur_sec; if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec += 0; else next_alarm_sec += alarm_sec; } else if (cur_min == alarm_min) { if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec = 1; else if (cur_sec < alarm_sec) next_alarm_sec = alarm_sec - cur_sec; else { min = alarm_min + MIN_PER_HOUR - cur_min; next_alarm_sec = alarm_sec + min * SEC_PER_MIN - cur_sec; } } else { min = alarm_min + MIN_PER_HOUR - cur_min; next_alarm_sec = min * SEC_PER_MIN - cur_sec; if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec += 0; else next_alarm_sec += alarm_sec; } } } else { if (cur_hour < alarm_hour) { hour = alarm_hour - cur_hour; next_alarm_sec = hour * SEC_PER_HOUR - cur_min * SEC_PER_MIN - cur_sec; if ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0) { if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec += 0; else next_alarm_sec += alarm_sec; } else { next_alarm_sec += alarm_min * SEC_PER_MIN; if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec += 0; else next_alarm_sec += alarm_sec; } } else if (cur_hour == alarm_hour) { if ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0) { if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec = 1; else if (cur_sec < alarm_sec) next_alarm_sec = alarm_sec - cur_sec; else next_alarm_sec = alarm_sec + SEC_PER_MIN - cur_sec; } else if (cur_min < alarm_min) { min = alarm_min - cur_min; next_alarm_sec = min * SEC_PER_MIN - cur_sec; if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec += 0; else next_alarm_sec += alarm_sec; } else if (cur_min == alarm_min) { if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec = 1; else if (cur_sec < alarm_sec) next_alarm_sec = alarm_sec - cur_sec; else { hour = alarm_hour + HOUR_PER_DAY - cur_hour; next_alarm_sec = hour * SEC_PER_HOUR - cur_min * SEC_PER_MIN - cur_sec; next_alarm_sec += alarm_min * SEC_PER_MIN + alarm_sec; } } else { hour = alarm_hour + HOUR_PER_DAY - cur_hour; next_alarm_sec = hour * SEC_PER_HOUR - cur_min * SEC_PER_MIN - cur_sec; next_alarm_sec += alarm_min * SEC_PER_MIN; if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec += 0; else next_alarm_sec += alarm_sec; } } else { hour = alarm_hour + HOUR_PER_DAY - cur_hour; next_alarm_sec = hour * SEC_PER_HOUR - cur_min * SEC_PER_MIN - cur_sec; if ((s->hw.cmos_data[RTC_MINUTES_ALARM] & 0xc0) == 0xc0) { if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec += 0; else next_alarm_sec += alarm_sec; } else { next_alarm_sec += alarm_min * SEC_PER_MIN; if ((s->hw.cmos_data[RTC_SECONDS_ALARM] & 0xc0) == 0xc0) next_alarm_sec += 0; else next_alarm_sec += alarm_sec; } } } expire_time = (next_alarm_sec - 1) * NS_PER_SEC + next_update_time; /* release lock before set timer */ spin_unlock(&s->lock); set_timer(&s->alarm_timer, expire_time); /* fetch lock again */ spin_lock(&s->lock); } }
int m48_tod_get_second(void) { return from_bcd(M48_ADDR[SECOND] & 0x7f); }
static void s3c_rtc_write(void *opaque, target_phys_addr_t addr, uint32_t value) { struct s3c_rtc_state_s *s = (struct s3c_rtc_state_s *) opaque; int diff; switch (addr) { case S3C_RTC_CON: s->control = value & 0xf; s->enable = (s->control == 0x1); break; case S3C_RTC_TICNT: s->tick = value; if (s->tick & (1 << 7)) s3c_rtc_tick_mod(s); break; case S3C_RTC_ALM: s->alarm = value; break; case S3C_RTC_ALMSEC: s->almsec = value; break; case S3C_RTC_ALMMIN: s->almmin = value; break; case S3C_RTC_ALMHOUR: s->almhour = value; break; case S3C_RTC_ALMDATE: s->almday = value; break; case S3C_RTC_ALMMON: s->almmon = value; break; case S3C_RTC_ALMYEAR: s->almyear = value; break; case S3C_RTC_RST: s->reset = value & 0xf; break; /* XXX This is not very exact time setting */ case S3C_RTC_BCDSEC: s3c_rtc_update(s); diff = from_bcd(value) - s->tm.tm_sec; s->sec += diff * 1; break; case S3C_RTC_BCDMIN: s3c_rtc_update(s); diff = from_bcd(value) - s->tm.tm_min; s->sec += diff * 60; break; case S3C_RTC_BCDHOUR: s3c_rtc_update(s); diff = from_bcd(value) - s->tm.tm_hour; s->sec += diff * 60 * 60; break; case S3C_RTC_BCDDATE: s3c_rtc_update(s); diff = from_bcd(value) - s->tm.tm_mday; s->sec += diff * 60 * 60 * 24; break; case S3C_RTC_BCDDAY: s3c_rtc_update(s); diff = (value & 7) - s->tm.tm_wday; s->sec += diff * 60 * 60 * 24; break; case S3C_RTC_BCDMON: s3c_rtc_update(s); diff = from_bcd(value) - s->tm.tm_mon - 1; s->sec += diff * 60 * 60 * 24 * 30; break; case S3C_RTC_BCDYEAR: s3c_rtc_update(s); diff = from_bcd(value) - (s->tm.tm_year % 100); s->sec += diff * 60 * 60 * 24 * 365; break; default: printf("%s: Bad register 0x%lx\n", __FUNCTION__, (unsigned long)addr); } }
static void timekeeper_tick( int chip ) { struct timekeeper_chip *c = &timekeeper[ chip ]; int carry; if( ( c->seconds & SECONDS_ST ) != 0 || ( c->control & CONTROL_W ) != 0 ) { return; } carry = inc_bcd( &c->seconds, MASK_SECONDS, 0x00, 0x59 ); if( carry ) { carry = inc_bcd( &c->minutes, MASK_MINUTES, 0x00, 0x59 ); } if( carry ) { carry = inc_bcd( &c->hours, MASK_HOURS, 0x00, 0x23 ); } if( carry ) { UINT8 month; UINT8 year; UINT8 maxdays; static const UINT8 daysinmonth[] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; inc_bcd( &c->day, MASK_DAY, 0x01, 0x07 ); month = from_bcd( c->month ); year = from_bcd( c->year ); if( month == 2 && ( year % 4 ) == 0 ) { maxdays = 0x29; } else if( month >= 1 && month <= 12 ) { maxdays = daysinmonth[ month - 1 ]; } else { maxdays = 0x31; } carry = inc_bcd( &c->date, MASK_DATE, 0x01, maxdays ); } if( carry ) { carry = inc_bcd( &c->month, MASK_MONTH, 0x01, 0x12 ); } if( carry ) { carry = inc_bcd( &c->year, MASK_YEAR, 0x00, 0x99 ); } if( carry ) { carry = inc_bcd( &c->century, MASK_CENTURY, 0x00, 0x99 ); if( c->type == TIMEKEEPER_M48T58 && ( c->day & DAY_CEB ) != 0 ) { c->day ^= DAY_CB; } } if( ( c->control & CONTROL_R ) == 0 ) { counters_to_ram( chip ); } }
void TimeKeeperTick() { #if defined FBA_DEBUG if (!DebugDev_TimeKprInitted) bprintf(PRINT_ERROR, _T("TimeKeeperTick called without init\n")); #endif INT32 carry; if( ( Chip.seconds & SECONDS_ST ) != 0 || ( Chip.control & CONTROL_W ) != 0 ) { return; } carry = inc_bcd( &Chip.seconds, MASK_SECONDS, 0x00, 0x59 ); if( carry ) { carry = inc_bcd( &Chip.minutes, MASK_MINUTES, 0x00, 0x59 ); } if( carry ) { carry = inc_bcd( &Chip.hours, MASK_HOURS, 0x00, 0x23 ); } if( carry ) { UINT8 month; UINT8 year; UINT8 maxdays; static const UINT8 daysinmonth[] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; inc_bcd( &Chip.day, MASK_DAY, 0x01, 0x07 ); month = from_bcd( Chip.month ); year = from_bcd( Chip.year ); if( month == 2 && ( year % 4 ) == 0 ) { maxdays = 0x29; } else if( month >= 1 && month <= 12 ) { maxdays = daysinmonth[ month - 1 ]; } else { maxdays = 0x31; } carry = inc_bcd( &Chip.date, MASK_DATE, 0x01, maxdays ); } if( carry ) { carry = inc_bcd( &Chip.month, MASK_MONTH, 0x01, 0x12 ); } if( carry ) { carry = inc_bcd( &Chip.year, MASK_YEAR, 0x00, 0x99 ); } if( carry ) { carry = inc_bcd( &Chip.century, MASK_CENTURY, 0x00, 0x99 ); if( (Chip.type == TIMEKEEPER_M48T58 || Chip.type == TIMEKEEPER_M48T35) && ( Chip.day & DAY_CEB ) != 0 ) { Chip.day ^= DAY_CB; } } if( ( Chip.control & CONTROL_R ) == 0 ) { counters_to_ram(); } }
static TIMER_CALLBACK( timekeeper_tick ) { timekeeper_state *c = (timekeeper_state *) ptr; int carry; if( ( c->seconds & SECONDS_ST ) != 0 || ( c->control & CONTROL_W ) != 0 ) { return; } carry = inc_bcd( &c->seconds, MASK_SECONDS, 0x00, 0x59 ); if( carry ) { carry = inc_bcd( &c->minutes, MASK_MINUTES, 0x00, 0x59 ); } if( carry ) { carry = inc_bcd( &c->hours, MASK_HOURS, 0x00, 0x23 ); } if( carry ) { UINT8 month; UINT8 year; UINT8 maxdays; static const UINT8 daysinmonth[] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; inc_bcd( &c->day, MASK_DAY, 0x01, 0x07 ); month = from_bcd( c->month ); year = from_bcd( c->year ); if( month == 2 && ( year % 4 ) == 0 ) { maxdays = 0x29; } else if( month >= 1 && month <= 12 ) { maxdays = daysinmonth[ month - 1 ]; } else { maxdays = 0x31; } carry = inc_bcd( &c->date, MASK_DATE, 0x01, maxdays ); } if( carry ) { carry = inc_bcd( &c->month, MASK_MONTH, 0x01, 0x12 ); } if( carry ) { carry = inc_bcd( &c->year, MASK_YEAR, 0x00, 0x99 ); } if( carry ) { carry = inc_bcd( &c->century, MASK_CENTURY, 0x00, 0x99 ); if( c->device->type == M48T35 || c->device->type == M48T58 ) { if( ( c->day & DAY_CEB ) != 0 ) { c->day ^= DAY_CB; } } } if( ( c->control & CONTROL_R ) == 0 ) { counters_to_ram( c ); } }
void timekeeper_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) { if( ( m_seconds & SECONDS_ST ) != 0 || ( m_control & CONTROL_W ) != 0 ) { return; } int carry = inc_bcd( &m_seconds, MASK_SECONDS, 0x00, 0x59 ); if( carry ) { carry = inc_bcd( &m_minutes, MASK_MINUTES, 0x00, 0x59 ); } if( carry ) { carry = inc_bcd( &m_hours, MASK_HOURS, 0x00, 0x23 ); } if( carry ) { UINT8 maxdays; static const UINT8 daysinmonth[] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; inc_bcd( &m_day, MASK_DAY, 0x01, 0x07 ); UINT8 month = from_bcd( m_month ); UINT8 year = from_bcd( m_year ); if( month == 2 && ( year % 4 ) == 0 ) { maxdays = 0x29; } else if( month >= 1 && month <= 12 ) { maxdays = daysinmonth[ month - 1 ]; } else { maxdays = 0x31; } carry = inc_bcd( &m_date, MASK_DATE, 0x01, maxdays ); } if( carry ) { carry = inc_bcd( &m_month, MASK_MONTH, 0x01, 0x12 ); } if( carry ) { carry = inc_bcd( &m_year, MASK_YEAR, 0x00, 0x99 ); } if( carry ) { carry = inc_bcd( &m_century, MASK_CENTURY, 0x00, 0x99 ); if( type() == M48T35 || type() == M48T58 ) { if( ( m_day & DAY_CEB ) != 0 ) { m_day ^= DAY_CB; } } } if( ( m_control & CONTROL_R ) == 0 ) { counters_to_ram(); } }