void maple_get_rtc_time(struct rtc_time *tm) { do { tm->tm_sec = maple_clock_read(RTC_SECONDS); tm->tm_min = maple_clock_read(RTC_MINUTES); tm->tm_hour = maple_clock_read(RTC_HOURS); tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH); tm->tm_mon = maple_clock_read(RTC_MONTH); tm->tm_year = maple_clock_read(RTC_YEAR); } while (tm->tm_sec != maple_clock_read(RTC_SECONDS)); if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { tm->tm_sec = bcd2bin(tm->tm_sec); tm->tm_min = bcd2bin(tm->tm_min); tm->tm_hour = bcd2bin(tm->tm_hour); tm->tm_mday = bcd2bin(tm->tm_mday); tm->tm_mon = bcd2bin(tm->tm_mon); tm->tm_year = bcd2bin(tm->tm_year); } if ((tm->tm_year + 1900) < 1970) tm->tm_year += 100; GregorianDay(tm); }
/* read clock time from DS1306 and return it in *tmp */ int rtc_get (struct rtc_time *tmp) { volatile immap_t *immap = (immap_t *) CFG_IMMR; unsigned char spi_byte; /* Data Byte */ init_spi (); /* set port B for software SPI */ /* Now we can enable the DS1306 RTC */ immap->im_cpm.cp_pbdat |= PB_SPI_CE; udelay (10); /* Shift out the address (0) of the time in the Clock Chip */ soft_spi_send (0); /* Put the clock readings into the rtc_time structure */ tmp->tm_sec = bcd2bin (soft_spi_read ()); /* Read seconds */ tmp->tm_min = bcd2bin (soft_spi_read ()); /* Read minutes */ /* Hours are trickier */ spi_byte = soft_spi_read (); /* Read Hours into temporary value */ if (spi_byte & 0x40) { /* 12 hour mode bit is set (time is in 1-12 format) */ if (spi_byte & 0x20) { /* since PM we add 11 to get 0-23 for hours */ tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) + 11; } else { /* since AM we subtract 1 to get 0-23 for hours */ tmp->tm_hour = (bcd2bin (spi_byte & 0x1F)) - 1; } } else { /* Otherwise, 0-23 hour format */ tmp->tm_hour = (bcd2bin (spi_byte & 0x3F)); } soft_spi_read (); /* Read and discard Day of week */ tmp->tm_mday = bcd2bin (soft_spi_read ()); /* Read Day of the Month */ tmp->tm_mon = bcd2bin (soft_spi_read ()); /* Read Month */ /* Read Year and convert to this century */ tmp->tm_year = bcd2bin (soft_spi_read ()) + 2000; /* Now we can disable the DS1306 RTC */ immap->im_cpm.cp_pbdat &= ~PB_SPI_CE; /* Disable DS1306 Chip */ udelay (10); GregorianDay (tmp); /* Determine the day of week */ debug ("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday, tmp->tm_hour, tmp->tm_min, tmp->tm_sec); return 0; }
/* * 函数名:Time_Adjust * 描述 :时间调节 * 输入 :用于读取RTC时间的结构体指针 * 输出 :无 * 调用 :外部调用 */ void Time_Adjust(struct rtc_time *tm) { /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); /* Get time entred by the user on the hyperterminal */ Time_Regulate(tm); /* Get wday */ GregorianDay(tm); /* 修改当前RTC计数寄存器内容 */ RTC_SetCounter(mktimev(tm)); /* Wait until last write operation on RTC registers has finished */ RTC_WaitForLastTask(); }
void maple_get_rtc_time(struct rtc_time *tm) { int uip, i; /* The Linux interpretation of the CMOS clock register contents: * When the Update-In-Progress (UIP) flag goes from 1 to 0, the * RTC registers show the second which has precisely just started. * Let's hope other operating systems interpret the RTC the same way. */ /* Since the UIP flag is set for about 2.2 ms and the clock * is typically written with a precision of 1 jiffy, trying * to obtain a precision better than a few milliseconds is * an illusion. Only consistency is interesting, this also * allows to use the routine for /dev/rtc without a potential * 1 second kernel busy loop triggered by any reader of /dev/rtc. */ for (i = 0; i<1000000; i++) { uip = maple_clock_read(RTC_FREQ_SELECT); tm->tm_sec = maple_clock_read(RTC_SECONDS); tm->tm_min = maple_clock_read(RTC_MINUTES); tm->tm_hour = maple_clock_read(RTC_HOURS); tm->tm_mday = maple_clock_read(RTC_DAY_OF_MONTH); tm->tm_mon = maple_clock_read(RTC_MONTH); tm->tm_year = maple_clock_read(RTC_YEAR); uip |= maple_clock_read(RTC_FREQ_SELECT); if ((uip & RTC_UIP)==0) break; } if (!(maple_clock_read(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { BCD_TO_BIN(tm->tm_sec); BCD_TO_BIN(tm->tm_min); BCD_TO_BIN(tm->tm_hour); BCD_TO_BIN(tm->tm_mday); BCD_TO_BIN(tm->tm_mon); BCD_TO_BIN(tm->tm_year); } if ((tm->tm_year + 1900) < 1970) tm->tm_year += 100; GregorianDay(tm); }
void to_tm(u32 tim, struct rtc_time * tm) { register u32 i; register long hms, day; day = tim / SECDAY; hms = tim % SECDAY; /* Hours, minutes, seconds are easy */ tm->tm_hour = hms / 3600; tm->tm_min = (hms % 3600) / 60; tm->tm_sec = (hms % 3600) % 60; /* Number of years in days */ /*算出当前年份,起始的计数年份为1970年*/ for (i = STARTOFTIME; day >= days_in_year(i); i++) { day -= days_in_year(i); } tm->tm_year = i; /* Number of months in days left */ /*计算当前的月份*/ if (leapyear(tm->tm_year)) { days_in_month(FEBRUARY) = 29; } for (i = 1; day >= days_in_month(i); i++) { day -= days_in_month(i); } days_in_month(FEBRUARY) = 28; tm->tm_mon = i; /* Days are what is left over (+1) from all that. *//*计算当前日期*/ tm->tm_mday = day + 1; /* * Determine the day of week */ GregorianDay(tm); }
int rtc_get(struct rtc_time *rtc) { uchar sec, min, hour, mday, month, year; /* Reading counts register latches the current RTC calendar count. * This guranties the coherence of the read during aprox 500 ms */ sec = rtc_read (DA9052_COUNTS_REG); if (!(sec & DA9052_COUNTS_MONITOR)) { puts("*** ERROR: " DEV_NAME " - incorrect date/time (Power was lost)\n"); } min = rtc_read (DA9052_COUNTMI_REG); hour = rtc_read (DA9052_COUNTH_REG); mday = rtc_read (DA9052_COUNTD_REG); month = rtc_read (DA9052_COUNTMO_REG); year = rtc_read (DA9052_COUNTY_REG); DBG ("Get RTC year: %02d mon: %02d mday: %02d " "hr: %02d min: %02d sec: %02d\n", year, month, mday, hour, min, sec); rtc->tm_sec = sec & DA9052_COUNTS_COUNTSEC; rtc->tm_min = min & DA9052_COUNTMI_COUNTMIN; rtc->tm_hour = hour & DA9052_COUNTH_COUNTHOUR; rtc->tm_mday = mday & DA9052_COUNTD_COUNTDAY; rtc->tm_mon = month & DA9052_COUNTMO_COUNTMONTH; rtc->tm_year = (year & DA9052_COUNTY_COUNTYEAR) + 2000; /* Compute the the day of week, not available in the RTC registers */ GregorianDay(rtc); DBG ("Get DATE: %4d-%02d-%02d TIME: %2d:%02d:%02d\n", rtc->tm_year, rtc->tm_mon, rtc->tm_mday, rtc->tm_hour, rtc->tm_min, rtc->tm_sec); return 0; }
/* * Convert date string: MMDDhhmm[[CC]YY][.ss] * * Some basic checking for valid values is done, but this will not catch * all possible error conditions. */ int mk_date (char *datestr, struct rtc_time *tmp) { int len, val; char *ptr; ptr = strchr (datestr,'.'); len = strlen (datestr); /* Set seconds */ if (ptr) { int sec; *ptr++ = '\0'; if ((len - (ptr - datestr)) != 2) return (-1); len = strlen (datestr); if (cnvrt2 (ptr, &sec)) return (-1); tmp->tm_sec = sec; } else { tmp->tm_sec = 0; } if (len == 12) { /* MMDDhhmmCCYY */ int year, century; if (cnvrt2 (datestr+ 8, ¢ury) || cnvrt2 (datestr+10, &year) ) { return (-1); } tmp->tm_year = 100 * century + year; } else if (len == 10) { /* MMDDhhmmYY */ int year, century; century = tmp->tm_year / 100; if (cnvrt2 (datestr+ 8, &year)) return (-1); tmp->tm_year = 100 * century + year; } switch (len) { case 8: /* MMDDhhmm */ /* fall thru */ case 10: /* MMDDhhmmYY */ /* fall thru */ case 12: /* MMDDhhmmCCYY */ if (cnvrt2 (datestr+0, &val) || val > 12) { break; } tmp->tm_mon = val; if (cnvrt2 (datestr+2, &val) || val > ((tmp->tm_mon==2) ? 29 : 31)) { break; } tmp->tm_mday = val; if (cnvrt2 (datestr+4, &val) || val > 23) { break; } tmp->tm_hour = val; if (cnvrt2 (datestr+6, &val) || val > 59) { break; } tmp->tm_min = val; /* calculate day of week */ GregorianDay (tmp); return (0); default: break; } return (-1); }