Exemplo n.º 1
0
/* Will auto-adjust the stored year if required */
void pcf8583_read(struct tm *time) {
  union {
    uint8_t  bytes[5];
    uint16_t words[2];
  } tmp;

  /* Set to default value in case we abort */
  memcpy_P(time, &rtc_default_date, sizeof(struct tm));
  if (rtc_state != RTC_OK)
    return;

  if (i2c_read_registers(PCF8583_ADDR, REG_SECONDS, 5, &tmp))
    return;

  time->tm_sec  = bcd2int(tmp.bytes[0]);
  time->tm_min  = bcd2int(tmp.bytes[1]);
  time->tm_hour = bcd2int(tmp.bytes[2]);
  time->tm_mday = bcd2int(tmp.bytes[3] & 0b00111111);
  time->tm_mon  = bcd2int(tmp.bytes[4] & 0b00011111)-1;
  time->tm_wday = bcd2int(tmp.bytes[4] >> 5);

  /* Check for year rollover */
  tmp.bytes[4] = tmp.bytes[3] >> 6;
  i2c_read_registers(PCF8583_ADDR, REG_YEAR1, 4, &tmp);
  if ((tmp.words[0] & 3) != tmp.bytes[4]) {
    /* Year rolled over, increment until the lower two bits match */
    while ((tmp.words[0] & 3) != tmp.bytes[4]) tmp.words[0]++;
    tmp.words[1] = tmp.words[0] ^ 0xffffU;

    /* Store new year to RTC ram */
    i2c_write_registers(PCF8583_ADDR, REG_YEAR1, 4, &tmp);
  }

  time->tm_year = tmp.words[0]-1900;
}
Exemplo n.º 2
0
//returns the date
void rtc_get_date(Rtc *p_rtc, uint32_t *ul_year, uint32_t *ul_month, uint32_t *ul_day,
		      uint32_t *ul_week){
  uint32_t r;
  twi_packet_t packet_rx;
  uint8_t rx_data [8];
  int dw,dt,mo,yr;
  packet_rx.chip = RTC_ADDRESS;
  packet_rx.addr[0] = 0x3;
  packet_rx.addr_length = 1;
  packet_rx.buffer = rx_data;
  packet_rx.length = 4;
  if((r=twi_master_read(RTC_BASE_TWI, &packet_rx)) != TWI_SUCCESS){
    printf("error in get_date: %d\n",(int)r);
    return;
  }
  //convert from BCD to decimal
  dw=bcd2int(rx_data[0]);
  dt=bcd2int(rx_data[1]);
  mo=bcd2int(rx_data[2]);
  yr=bcd2int(rx_data[3])+2000;
  *ul_year = yr;
  *ul_month= mo;
  *ul_day = dt;
  *ul_week = dw;
  //printf("20%d/%d/%d (%d)\n",yr,mo,dt,dw);
}
Exemplo n.º 3
0
u32 get_rtc_time()
{
	rm_ctx ctx;
	u32    hrs, mins;
	u32    sec;

	btab->p_set_ctx(0x0200, &ctx);
	btab->p_bios_call(0x1A, &ctx);
	hrs  = bcd2int(ctx.ch);
	mins = bcd2int(ctx.cl);
	sec  = bcd2int(ctx.dh);

	return (hrs * 3600) + (mins * 60) + sec;
}
Exemplo n.º 4
0
uint32_t rtc_get_time(void)
{
  uint8_t i;//, pm = 0;
  // 0        1        2      3     4         5       6
  // seconds, minutes, hours, days, weekdays, months, years
  uint8_t date[7];

  if(rtc_get_pon() == 1)
    return 0;

  rtc_read_page(RTC_PAGE_CLOCK, date, 7);

  //if(date[2] & (1<< 6))
  //  PORTB |= (1 << PB4);
  //  pm = 1;
  date[0] &= 0x7f;
  date[1] &= 0x7f;
  date[2] &= 0x3f;
  date[3] &= 0x3f;
  date[4] &= 0x07;
  date[5] &= 0x3f;
  date[6] &= 0x7f;

  for(i = 0; i < 7; i++)
    date[i] = bcd2int(date[i]);

  //if(pm)
  //  date[2] += 12;

  return date_convert2timestamp((int16_t)date[6]+2000, date[5], date[3], date[2], date[1], date[0]);
}
Exemplo n.º 5
0
int cmos_year() {
  // algorthm patended my microsoft. beware!
  // don't read the code below, ah! you already
  // did it. no problem, they can still brainwash you...
  int off = bcd2int(cmos_read(0x9));
  if(off >= 70 )
    return 1990 + off;
  else
    return 2000 + off;
}
Exemplo n.º 6
0
int snapgear_rtc_settimeofday(const struct timeval *tv)
{
    int retval = 0;
    int real_seconds, real_minutes, cmos_minutes;
    unsigned long nowtime;

    if (!use_ds1302) {
        sh_rtc_settimeofday(tv);
        return(0);
    }

    /*
     *	This is called direct from the kernel timer handling code.
     *	It is supposed to synchronize the kernel clock to the RTC.
     */

    nowtime = tv->tv_sec;

#if 1
    printk("SnapGear RTC: snapgear_rtc_settimeofday(nowtime=%ld)\n", nowtime);
#endif

    /* STOP RTC */
    ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) | 0x80);

    cmos_minutes = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));

    /*
     * since we're only adjusting minutes and seconds,
     * don't interfere with hour overflow. This avoids
     * messing with unknown time zones but requires your
     * RTC not to be off by more than 15 minutes
     */
    real_seconds = nowtime % 60;
    real_minutes = nowtime / 60;
    if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
        real_minutes += 30;	/* correct for half hour time zone */
    real_minutes %= 60;

    if (abs(real_minutes - cmos_minutes) < 30) {
        ds1302_writebyte(RTC_ADDR_MIN, int2bcd(real_minutes));
        ds1302_writebyte(RTC_ADDR_SEC, int2bcd(real_seconds));
    } else {
        printk(KERN_WARNING
               "SnapGear RTC: can't update from %d to %d\n",
               cmos_minutes, real_minutes);
        retval = -1;
    }

    /* START RTC */
    ds1302_writebyte(RTC_ADDR_SEC, ds1302_readbyte(RTC_ADDR_SEC) & ~0x80);
    return(0);
}
Exemplo n.º 7
0
//returns unix timestamp 
void rtc_get_time(Rtc *p_rtc, uint32_t *ul_hour, uint32_t *ul_minute, uint32_t *ul_second){
  uint32_t r;
  twi_packet_t packet_rx;
  uint8_t rx_data [8];
  int sc,mn,hr;
  packet_rx.chip = RTC_ADDRESS;
  packet_rx.addr[0] = 0x0;
  packet_rx.addr_length = 1;
  packet_rx.buffer = rx_data;
  packet_rx.length = 3;
  if((r=twi_master_read(RTC_BASE_TWI, &packet_rx)) != TWI_SUCCESS){
    printf("error reading RTC: %d\n",(int)r);
    return;
  }
  //convert from BCD to decimal
  sc=bcd2int(rx_data[0]);
  mn=bcd2int(rx_data[1]);
  hr=bcd2int(rx_data[2]);
  *ul_hour = hr;
  *ul_minute = mn;
  *ul_second = sc;
  //  printf("%d:%d:%d\n",hr,mn,sc);
}
Exemplo n.º 8
0
extern void mvme147_gettod (int *year, int *mon, int *day, int *hour,
                            int *min, int *sec)
{
    m147_rtc->ctrl = RTC_READ;
    *year = bcd2int (m147_rtc->bcd_year);
    *mon = bcd2int (m147_rtc->bcd_mth);
    *day = bcd2int (m147_rtc->bcd_dom);
    *hour = bcd2int (m147_rtc->bcd_hr);
    *min = bcd2int (m147_rtc->bcd_min);
    *sec = bcd2int (m147_rtc->bcd_sec);
    m147_rtc->ctrl = 0;
}
Exemplo n.º 9
0
void ds1302_gettod(int *year, int *mon, int *day, int *hour, int *min, int *sec)
{
#if 0
	printk("ds1302_gettod()\n");
#endif

	*year = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR));
	*mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON));
	*day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE));
	*hour = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR));
	*min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
	*sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
}
Exemplo n.º 10
0
int mvme147_hwclk(int op, struct rtc_time *t)
{
#warning check me!
	if (!op) {
		m147_rtc->ctrl = RTC_READ;
		t->tm_year = bcd2int (m147_rtc->bcd_year);
		t->tm_mon  = bcd2int (m147_rtc->bcd_mth);
		t->tm_mday = bcd2int (m147_rtc->bcd_dom);
		t->tm_hour = bcd2int (m147_rtc->bcd_hr);
		t->tm_min  = bcd2int (m147_rtc->bcd_min);
		t->tm_sec  = bcd2int (m147_rtc->bcd_sec);
		m147_rtc->ctrl = 0;
	}
	return 0;
}
Exemplo n.º 11
0
/* Read the current time from the RTC */
void dsrtc_read(struct tm *time) {
  uint8_t tmp[7];

  /* Set to default value in case we abort */
  memcpy_P(time, &rtc_default_date, sizeof(struct tm));
  if (rtc_state != RTC_OK)
    return;

  if (i2c_read_registers(RTC_ADDR, REG_SECOND, 7, &tmp))
    return;

  time->tm_sec  = bcd2int(tmp[REG_SECOND] & 0x7f);
  time->tm_min  = bcd2int(tmp[REG_MINUTE]);
  time->tm_hour = bcd2int(tmp[REG_HOUR]);
  time->tm_mday = bcd2int(tmp[REG_DOM]);
  time->tm_mon  = bcd2int(tmp[REG_MONTH] & 0x7f) - 1;
  time->tm_wday = bcd2int(tmp[REG_DOW]) - 1;
  time->tm_year = bcd2int(tmp[REG_YEAR]) + 100 * !!(tmp[REG_MONTH] & 0x80) + 100;
  // FIXME: Leap year calculation is wrong in 2100
}
Exemplo n.º 12
0
void snapgear_rtc_gettimeofday(struct timespec *ts)
{
	unsigned int sec, min, hr, day, mon, yr;

	if (!use_ds1302) {
		sh_rtc_gettimeofday(ts);
		return;
	}

 	sec = bcd2int(ds1302_readbyte(RTC_ADDR_SEC));
 	min = bcd2int(ds1302_readbyte(RTC_ADDR_MIN));
 	hr  = bcd2int(ds1302_readbyte(RTC_ADDR_HOUR));
 	day = bcd2int(ds1302_readbyte(RTC_ADDR_DATE));
 	mon = bcd2int(ds1302_readbyte(RTC_ADDR_MON));
 	yr  = bcd2int(ds1302_readbyte(RTC_ADDR_YEAR));

bad_time:
	if (yr > 99 || mon < 1 || mon > 12 || day > 31 || day < 1 ||
	    hr > 23 || min > 59 || sec > 59) {
		printk(KERN_ERR
		       "SnapGear RTC: invalid value, resetting to 1 Jan 2000\n");
		ds1302_writebyte(RTC_ADDR_MIN,  min = 0);
		ds1302_writebyte(RTC_ADDR_HOUR, hr  = 0);
		ds1302_writebyte(RTC_ADDR_DAY,        7);
		ds1302_writebyte(RTC_ADDR_DATE, day = 1);
		ds1302_writebyte(RTC_ADDR_MON,  mon = 1);
		ds1302_writebyte(RTC_ADDR_YEAR, yr  = 0);
		ds1302_writebyte(RTC_ADDR_SEC,  sec = 0);
	}

	ts->tv_sec = mktime(2000 + yr, mon, day, hr, min, sec);
	if (ts->tv_sec < 0) {
#if 0
		printk("BAD TIME %d %d %d %d %d %d\n", yr, mon, day, hr, min, sec);
#endif
		yr = 100;
		goto bad_time;
	}
	ts->tv_nsec = 0;
}
Exemplo n.º 13
0
static void 
print_all_info(int fd, apm_info_t aip, int bioscall_available)
{
	struct apm_bios_arg args;
	int apmerr;
	const char *line_msg[] = { "off-line", "on-line" , "backup power"};

	printf("APM version: %d.%d\n", aip->ai_major, aip->ai_minor);
	printf("APM Management: %s\n", aip->ai_status ? "Enabled" : "Disabled");
	printf("AC Line status: ");
	if (aip->ai_acline == APM_UNKNOWN)
		printf("unknown\n");
	else if (aip->ai_acline > 2)
		printf("invalid value (0x%x)\n", aip->ai_acline);
	else
		printf("%s\n", line_msg[aip->ai_acline]);

	print_batt_stat(aip->ai_batt_stat);
	print_batt_life(aip->ai_batt_life);
	print_batt_time(aip->ai_batt_time);

	if (aip->ai_infoversion >= 1) {
		printf("Number of batteries: ");
		if (aip->ai_batteries == ~0U)
			printf("unknown\n");
		else {
			u_int i;
			struct apm_pwstatus aps;

			printf("%d\n", aip->ai_batteries);
			for (i = 0; i < aip->ai_batteries; ++i) {
				bzero(&aps, sizeof(aps));
				aps.ap_device = PMDV_BATT0 + i;
				if (ioctl(fd, APMIO_GETPWSTATUS, &aps) == -1)
					continue;
				printf("Battery %d:\n", i);
				if (aps.ap_batt_flag & APM_BATT_NOT_PRESENT) {
					printf("not present\n");
					continue;
				}
				printf("\t");
				print_batt_stat(aps.ap_batt_stat);
				printf("\t");
				print_batt_life(aps.ap_batt_life);
				printf("\t");
				print_batt_time(aps.ap_batt_time);
			}
		}
	}

	if (bioscall_available) {
		/*
		 * try to get the suspend timer
		 */
		bzero(&args, sizeof(args));
		args.eax = (APM_BIOS) << 8 | APM_RESUMETIMER;
		args.ebx = PMDV_APMBIOS;
		args.ecx = 0x0001;
		if (ioctl(fd, APMIO_BIOS, &args)) {
			printf("Resume timer: unknown\n");
		} else {
			apmerr = APMERR(args.eax);
			if (apmerr == 0x0d || apmerr == 0x86)
				printf("Resume timer: disabled\n");
			else if (apmerr)
				warnx(
		"failed to get the resume timer: APM error0x%x", apmerr);
			else {
				/*
				 * OK.  We have the time (all bcd).
				 * CH - seconds
				 * DH - hours
				 * DL - minutes
				 * xh(SI) - month (1-12)
				 * xl(SI) - day of month (1-31)
				 * DI - year
				 */
				struct tm tm;
				char buf[1024];
				time_t t;

				tm.tm_sec = bcd2int(xh(args.ecx));
				tm.tm_min = bcd2int(xl(args.edx));
				tm.tm_hour = bcd2int(xh(args.edx));
				tm.tm_mday = bcd2int(xl(args.esi));
				tm.tm_mon = bcd2int(xh(args.esi)) - 1;
				tm.tm_year = bcd2int(args.edi) - 1900;
				if (cmos_wall)
					t = mktime(&tm);
				else
					t = timegm(&tm);
				if (t != -1) {
					tm = *localtime(&t);
					strftime(buf, sizeof(buf), "%c", &tm);
					printf("Resume timer: %s\n", buf);
				} else
					printf("Resume timer: unknown\n");
			}
		}

		/*
		 * Get the ring indicator resume state
		 */
		bzero(&args, sizeof(args));
		args.eax  = (APM_BIOS) << 8 | APM_RESUMEONRING;
		args.ebx = PMDV_APMBIOS;
		args.ecx = 0x0002;
		if (ioctl(fd, APMIO_BIOS, &args) == 0) {
			printf("Resume on ring indicator: %sabled\n",
			    args.ecx ? "en" : "dis");
		}
	}

	if (aip->ai_infoversion >= 1) {
		if (aip->ai_capabilities == 0xff00)
		    return;
		printf("APM Capabilities:\n");
		if (aip->ai_capabilities & 0x01)
			printf("\tglobal standby state\n");
		if (aip->ai_capabilities & 0x02)
			printf("\tglobal suspend state\n");
		if (aip->ai_capabilities & 0x04)
			printf("\tresume timer from standby\n");
		if (aip->ai_capabilities & 0x08)
			printf("\tresume timer from suspend\n");
		if (aip->ai_capabilities & 0x10)
			printf("\tRI resume from standby\n");
		if (aip->ai_capabilities & 0x20)
			printf("\tRI resume from suspend\n");
		if (aip->ai_capabilities & 0x40)
			printf("\tPCMCIA RI resume from standby\n");
		if (aip->ai_capabilities & 0x80)
			printf("\tPCMCIA RI resume from suspend\n");
	}

}
Exemplo n.º 14
0
static int
todds1307_read_rtc(struct rtc_t *rtc)
{
    static	ds1307_state_t	*statep = NULL;
    i2c_transfer_t	*i2c_tp = NULL;
    int i2c_cmd_status = I2C_FAILURE;
    int counter = 4;

    if (!todds1307_attach_done) {
        return (todds1307_prom_getdate(rtc));
    }

    statep = ddi_get_soft_state(ds1307_statep, instance);
    if (statep == NULL) {
        cmn_err(CE_WARN, "todds1307: ddi_get_soft_state failed");
        return (DDI_FAILURE);
    }

    mutex_enter(&todds1307_rd_lock);

    /*
     * Allocate 1 byte for write buffer and 7 bytes for read buffer to
     * to accomodate sec, min, hrs, dayOfWeek, dayOfMonth, year
     */
    if ((i2c_transfer_alloc(statep->ds1307_i2c_hdl, &i2c_tp, 1,
                            7, I2C_SLEEP)) != I2C_SUCCESS) {
        mutex_exit(&todds1307_rd_lock);
        return (DDI_FAILURE);
    }

    do {
        i2c_tp->i2c_version = I2C_XFER_REV;
        i2c_tp->i2c_flags = I2C_WR_RD;
        i2c_tp->i2c_wbuf[0] = (uchar_t)0x00; /* Start from reg 0x00 */
        i2c_tp->i2c_wlen = 1;	/* Write one byte address */
        i2c_tp->i2c_rlen = 7;	/* Read 7 regs */

        if ((i2c_cmd_status = i2c_transfer(statep->ds1307_i2c_hdl,
                                           i2c_tp)) != I2C_SUCCESS) {
            drv_usecwait(I2C_DELAY);
            goto done;
        }
        /* for first read, need to get valid data */
        while (tod_read[0] == -1 && counter > 0) {
            /* move data to static buffer */
            bcopy(i2c_tp->i2c_rbuf, tod_read, 7);

            /* now read again */
            /* Start reading reg from 0x00 */
            i2c_tp->i2c_wbuf[0] = (uchar_t)0x00;
            i2c_tp->i2c_wlen = 1;	/* Write one byte address */
            i2c_tp->i2c_rlen = 7;	/* Read 7 regs */
            if ((i2c_cmd_status = i2c_transfer(statep->ds1307_i2c_hdl,
                                               i2c_tp)) != I2C_SUCCESS) {
                drv_usecwait(I2C_DELAY);
                goto done;
            }
            /* if they are not the same, then read again */
            if (bcmp(tod_read, i2c_tp->i2c_rbuf, 7) != 0) {
                tod_read[0] = -1;
                counter--;
            }
        }

    } while (i2c_tp->i2c_rbuf[0] == 0x59 &&
             /* if seconds register is 0x59 (BCD), add data should match */
             bcmp(&tod_read[1], &i2c_tp->i2c_rbuf[1], 6) != 0 &&
             counter-- > 0);

    if (counter < 0)
        cmn_err(CE_WARN, "i2ctod: TOD Chip failed ??");

    /* move data to static buffer */
    bcopy(i2c_tp->i2c_rbuf, tod_read, 7);


    rtc->rtc_year	= bcd2int(i2c_tp->i2c_rbuf[6]);
    rtc->rtc_mon	= bcd2int(i2c_tp->i2c_rbuf[5]);
    rtc->rtc_dom	= bcd2int(i2c_tp->i2c_rbuf[4]);
    rtc->rtc_dow	= bcd2int(i2c_tp->i2c_rbuf[3]);
    rtc->rtc_hrs	= bcd2int(i2c_tp->i2c_rbuf[2]);
    rtc->rtc_min	= bcd2int(i2c_tp->i2c_rbuf[1]);
    rtc->rtc_sec	= bcd2int(i2c_tp->i2c_rbuf[0]);

done:
    (void) i2c_transfer_free(statep->ds1307_i2c_hdl, i2c_tp);

    mutex_exit(&todds1307_rd_lock);
    return (i2c_cmd_status);
}
Exemplo n.º 15
0
int cmos_month() {
  return bcd2int(cmos_read(0x8));
}
Exemplo n.º 16
0
int cmos_day_of_month() {
  return bcd2int(cmos_read(0x7));
}
Exemplo n.º 17
0
int cmos_day_of_week() {
  return bcd2int(cmos_read(0x6));
}
Exemplo n.º 18
0
int cmos_seconds() {
  return bcd2int(cmos_read(0x0));
}
Exemplo n.º 19
0
int cmos_minutes() {
  return bcd2int(cmos_read(0x2));
}
Exemplo n.º 20
0
int cmos_hours() {
  return bcd2int(cmos_read(0x4));
}