From c34b5108a720256239e980fe87bc275d183395c8 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 19 Nov 2015 14:54:30 -0600 Subject: [PATCH] RTC: Fix system time initialization when using an exernal RTC. Fix some bugs in the DS1307/DS3231 RTC driver --- configs | 2 +- drivers/timers/Kconfig | 21 ++++- drivers/timers/Make.defs | 2 +- drivers/timers/ds3231.c | 93 ++++++++++++++++------ drivers/timers/ds3231.h | 141 +++++++++++++++++---------------- include/nuttx/timers/ds3231.h | 10 +-- sched/clock/clock_initialize.c | 6 +- 7 files changed, 172 insertions(+), 103 deletions(-) diff --git a/configs b/configs index 165837ff2a..388caf6346 160000 --- a/configs +++ b/configs @@ -1 +1 @@ -Subproject commit 165837ff2aa39c6cb478223c0b1bbec4a42dadc6 +Subproject commit 388caf63466f447ce0fc6924dc50e79b9ba70cf8 diff --git a/drivers/timers/Kconfig b/drivers/timers/Kconfig index 95167ecd8f..6f8de15273 100644 --- a/drivers/timers/Kconfig +++ b/drivers/timers/Kconfig @@ -118,16 +118,31 @@ config RTC_IOCTL endif # RTC_DRIVER -config RTC_DS3XXX +config RTC_EXTERNAL + bool "External RTC Support" + default n + ---help--- + In modern MCUs, the RTC is usually implement as an internal + peripheral to the MCU. An option is to use an external RTC + connected to the MCU typically via SPI or I2C. + + If an external RTC is connect to the MCU through some bus, then the + RTC will not be available to the system until after the system + fully boots up and is able to access the bus. In that case, this + setting must be included to suppress attempts to initialize the RTC + early in the boot sequence. + +config RTC_DSXXXX bool "DS3231/DS1307 RTC Driver" default n select I2C select I2C_TRANSFER + select RTC_EXTERNAL select RTC_DATETIME ---help--- Enables support for the Maxim Integrated DS3231 I2C RTC timer. -if RTC_DS3XXX +if RTC_DSXXXX choice prompt "Maxim Integrated RTC" @@ -150,7 +165,7 @@ config DS3231_I2C_FREQUENCY default 400000 range 1 4000000 -endif # RTC_DS3XXX +endif # RTC_DSXXXX endif # RTC menuconfig WATCHDOG diff --git a/drivers/timers/Make.defs b/drivers/timers/Make.defs index f52599e1f8..0707c244a6 100644 --- a/drivers/timers/Make.defs +++ b/drivers/timers/Make.defs @@ -51,7 +51,7 @@ ifeq ($(CONFIG_TIMER),y) TMRVPATH = :timers endif -ifeq ($(CONFIG_RTC_DS3XXX),y) +ifeq ($(CONFIG_RTC_DSXXXX),y) CSRCS += ds3231.c TMRDEPPATH = --dep-path timers TMRVPATH = :timers diff --git a/drivers/timers/ds3231.c b/drivers/timers/ds3231.c index d3c122f273..9704a7a2c7 100644 --- a/drivers/timers/ds3231.c +++ b/drivers/timers/ds3231.c @@ -50,7 +50,7 @@ #include "ds3231.h" -#ifdef CONFIG_RTC_DS3XXX +#ifdef CONFIG_RTC_DSXXXX /************************************************************************************ * Pre-processor Definitions @@ -192,7 +192,7 @@ static uint8_t rtc_bin2bcd(int value) } /************************************************************************************ - * Name: rtc_bin2bcd + * Name: rtc_bcd2bin * * Description: * Convert from 2 digit BCD to binary. @@ -216,13 +216,13 @@ static int rtc_bcd2bin(uint8_t value) ************************************************************************************/ /************************************************************************************ - * Name: ds3xxx_rtc_initialize + * Name: dsxxxx_rtc_initialize * * Description: * Initialize the hardware RTC per the selected configuration. This function is * called once during the OS initialization sequence by board-specific logic. * - * After ds3xxx_rtc_initialize() is called, the OS function clock_synchronize() + * After dsxxxx_rtc_initialize() is called, the OS function clock_synchronize() * should also be called to synchronize the system timer to a hardware RTC. That * operation is normally performed automatically by the system during clock * initialization. However, when an external RTC is used, the board logic will @@ -237,7 +237,7 @@ static int rtc_bcd2bin(uint8_t value) * ************************************************************************************/ -int ds3xxx_rtc_initialize(FAR struct i2c_dev_s *i2c) +int dsxxxx_rtc_initialize(FAR struct i2c_dev_s *i2c) { /* Remember the i2c device and claim that the RTC is enabled */ @@ -278,9 +278,31 @@ int up_rtc_getdatetime(FAR struct tm *tp) int tmp; int ret; + /* If this function is called before the RTC has been initialized (and it will be), + * then just return the data/time of the epoch, 12:00 am, Jan 1, 1970. + */ + + if (!g_rtc_enabled) + { + tp->tm_sec = 0; + tp->tm_min = 0; + tp->tm_hour = 0; + +#if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) + /* Jan 1, 1970 was a Thursday */ + + tp->tm_wday = 4; +#endif + + tp->tm_mday = 1; + tp->tm_mon = 0; + tp->tm_year = 70; + return -EAGAIN; + } + /* Select to begin reading at the seconds register */ - secaddr = DS3XXX_TIME_SECR; + secaddr = DSXXXX_TIME_SECR; msg[0].addr = DS3231_I2C_ADDRESS; msg[0].flags = 0; @@ -326,40 +348,42 @@ int up_rtc_getdatetime(FAR struct tm *tp) return ret; } } - while (buffer[0] > seconds); + while ((buffer[0] & DSXXXX_TIME_SEC_BCDMASK) > + (seconds & DSXXXX_TIME_SEC_BCDMASK)); /* Format the return time */ /* Return seconds (0-61) */ - tp->tm_sec = rtc_bcd2bin(buffer[0] & DS3XXX_TIME_SEC_BCDMASK); + tp->tm_sec = rtc_bcd2bin(buffer[0] & DSXXXX_TIME_SEC_BCDMASK); /* Return minutes (0-59) */ - tp->tm_min = rtc_bcd2bin(buffer[1] & DS3XXX_TIME_MIN_BCDMASK); + tp->tm_min = rtc_bcd2bin(buffer[1] & DSXXXX_TIME_MIN_BCDMASK); /* Return hour (0-23). This assumes 24-hour time was set. */ - tp->tm_hour = rtc_bcd2bin(buffer[2] & DS3XXX_TIME_HOUR24_BCDMASK); + tp->tm_hour = rtc_bcd2bin(buffer[2] & DSXXXX_TIME_HOUR24_BCDMASK); #if defined(CONFIG_LIBC_LOCALTIME) || defined(CONFIG_TIME_EXTENDED) /* Return the day of the week (0-6) */ - tp->tm_wday = (rtc_bcd2bin(buffer[3]) & DS3XXX_TIME_DAY_MASK) - 1; + tp->tm_wday = (rtc_bcd2bin(buffer[3]) & DSXXXX_TIME_DAY_MASK) - 1; #endif /* Return the day of the month (1-31) */ - tp->tm_mday = rtc_bcd2bin(buffer[4] & DS3XXX_TIME_DATE_BCDMASK); + tp->tm_mday = rtc_bcd2bin(buffer[4] & DSXXXX_TIME_DATE_BCDMASK); /* Return the month (0-11) */ - tp->tm_mon = rtc_bcd2bin(buffer[5] & DS3XXX_TIME_MONTH_BCDMASK) - 1; + tp->tm_mon = rtc_bcd2bin(buffer[5] & DSXXXX_TIME_MONTH_BCDMASK) - 1; - /* Return the years since 1990 */ + /* Return the years since 1900 */ - tmp = rtc_bcd2bin(buffer[5] & DS3XXX_TIME_YEAR_BCDMASK); + tmp = rtc_bcd2bin(buffer[6] & DSXXXX_TIME_YEAR_BCDMASK); - if ((buffer[6] & DS3XXX_TIME_CENTURY_MASK) == DS3XXX_TIME_1900) +#ifdef CONFIG_RTC_DS3231 + if ((buffer[5] & DS3231_TIME_CENTURY_MASK) == DS3231_TIME_1900) { tp->tm_year = tmp; } @@ -367,6 +391,11 @@ int up_rtc_getdatetime(FAR struct tm *tp) { tp->tm_year = tmp + 100; } +#else + /* No century indicator. The RTC will hold years since 1970 */ + + tp->tm_year = tmp + 70; +#endif rtc_dumptime(tp, "Returning"); return OK; @@ -398,6 +427,15 @@ int up_rtc_settime(FAR const struct timespec *tp) uint8_t year; int ret; + /* If this function is called before the RTC has been initialized then just return + * an error. + */ + + if (!g_rtc_enabled) + { + return -EAGAIN; + } + rtc_dumptime(tp, "Setting time"); /* Get the broken out time */ @@ -429,7 +467,7 @@ int up_rtc_settime(FAR const struct timespec *tp) /* Construct the message */ /* Write starting with the seconds regiser */ - buffer[0] = DS3XXX_TIME_SECR; + buffer[0] = DSXXXX_TIME_SECR; /* Save seconds (0-59) converted to BCD */ @@ -441,7 +479,7 @@ int up_rtc_settime(FAR const struct timespec *tp) /* Save hour (0-23) with 24-hour time indicatin */ - buffer[3] = rtc_bin2bcd(newtm.tm_hour) | DS3XXX_TIME_24; + buffer[3] = rtc_bin2bcd(newtm.tm_hour) | DSXXXX_TIME_24; /* Save the day of the week (1-7) */ @@ -455,30 +493,38 @@ int up_rtc_settime(FAR const struct timespec *tp) buffer[5] = rtc_bin2bcd(newtm.tm_mday); +#ifdef CONFIG_RTC_DS3231 /* Handle years in the 20th vs the 21st century */ if (newtm.tm_year < 100) { /* Convert years in the range 1900-1999 */ - century = DS3XXX_TIME_1900; + century = DS3231_TIME_1900; year = newtm.tm_year; } else { /* Convert years in the range 2000-2099 */ - century = DS3XXX_TIME_2000; + century = DS3231_TIME_2000; year = newtm.tm_year - 100; } +#else + /* Use years since 1970 */ + + century = 0; + year = newtm.tm_year - 70; +#endif + /* Save the month (1-12) with century */ buffer[6] = rtc_bin2bcd(newtm.tm_mon + 1) | century; /* Save the year */ - buffer[7] = year; + buffer[7] = rtc_bin2bcd(year); /* Setup the I2C message */ @@ -517,9 +563,10 @@ int up_rtc_settime(FAR const struct timespec *tp) return ret; } } - while (buffer[1] > seconds); + while ((buffer[1] & DSXXXX_TIME_SEC_BCDMASK) > + (seconds & DSXXXX_TIME_SEC_BCDMASK)); return OK; } -#endif /* CONFIG_RTC_DS3XXX */ +#endif /* CONFIG_RTC_DSXXXX */ diff --git a/drivers/timers/ds3231.h b/drivers/timers/ds3231.h index 57ea6f5bec..3c7a64ecab 100644 --- a/drivers/timers/ds3231.h +++ b/drivers/timers/ds3231.h @@ -46,80 +46,85 @@ * Pre-processor Definitions ****************************************************************************/ -#define DS3XXX_TIME_SECR 0x00 /* Seconds register */ -# define DS3XXX_TIME_SEC_SHIFT 0 /* Bits 0-3: Seconds, range 0-9 */ -# define DS3XXX_TIME_SEC_MASK (15 << DS3XXX_TIME_SEC_SHIFT) -# define DS3XXX_TIME_SEC(n) ((uint8_t)(n) << DS3XXX_TIME_SEC_SHIFT) -# define DS3XXX_TIME_10SEC_SHIFT 4 /* Bits 4-6: 10 seconds, range 0-5 */ -# define DS3XXX_TIME_10SEC_MASK (7 << DS3XXX_TIME_10SEC_SHIFT) -# define DS3XXX_TIME_10SEC(n) ((uint8_t)(n) << DS3XXX_TIME_10SEC_SHIFT) -# define DS3XXX_TIME_SEC_BCDMASK (DS3XXX_TIME_SEC_MASK | DS3XXX_TIME_10SEC_MASK) +#define DSXXXX_TIME_SECR 0x00 /* Seconds register */ +# define DSXXXX_TIME_SEC_SHIFT 0 /* Bits 0-3: Seconds, range 0-9 */ +# define DSXXXX_TIME_SEC_MASK (15 << DSXXXX_TIME_SEC_SHIFT) +# define DSXXXX_TIME_SEC(n) ((uint8_t)(n) << DSXXXX_TIME_SEC_SHIFT) +# define DSXXXX_TIME_10SEC_SHIFT 4 /* Bits 4-6: 10 seconds, range 0-5 */ +# define DSXXXX_TIME_10SEC_MASK (7 << DSXXXX_TIME_10SEC_SHIFT) +# define DSXXXX_TIME_10SEC(n) ((uint8_t)(n) << DSXXXX_TIME_10SEC_SHIFT) +# define DSXXXX_TIME_SEC_BCDMASK (DSXXXX_TIME_SEC_MASK | DSXXXX_TIME_10SEC_MASK) +#ifdef CONFIG_RTC_DS1307 +# define DS1307_TIME_CH (1 << 7) /* Bit 7: Clock halt */ +#endif -#define DS3XXX_TIME_MINR 0x01 /* Minutes register */ -# define DS3XXX_TIME_MIN_SHIFT 0 /* Bits 0-3: Minutes, range 0-9 */ -# define DS3XXX_TIME_MIN_MASK (15 << DS3XXX_TIME_MIN_SHIFT) -# define DS3XXX_TIME_MIN(n) ((uint8_t)(n) << DS3XXX_TIME_MIN_SHIFT) -# define DS3XXX_TIME_10MIN_SHIFT 4 /* Bits 4-6: 10 minutes, range 0-5 */ -# define DS3XXX_TIME_10MIN_MASK (7 << DS3XXX_TIME_10MIN_SHIFT) -# define DS3XXX_TIME_10MIN(n) ((uint8_t)(n) << DS3XXX_TIME_10MIN_SHIFT) -# define DS3XXX_TIME_MIN_BCDMASK (DS3XXX_TIME_MIN_MASK | DS3XXX_TIME_10MIN_MASK) +#define DSXXXX_TIME_MINR 0x01 /* Minutes register */ +# define DSXXXX_TIME_MIN_SHIFT 0 /* Bits 0-3: Minutes, range 0-9 */ +# define DSXXXX_TIME_MIN_MASK (15 << DSXXXX_TIME_MIN_SHIFT) +# define DSXXXX_TIME_MIN(n) ((uint8_t)(n) << DSXXXX_TIME_MIN_SHIFT) +# define DSXXXX_TIME_10MIN_SHIFT 4 /* Bits 4-6: 10 minutes, range 0-5 */ +# define DSXXXX_TIME_10MIN_MASK (7 << DSXXXX_TIME_10MIN_SHIFT) +# define DSXXXX_TIME_10MIN(n) ((uint8_t)(n) << DSXXXX_TIME_10MIN_SHIFT) +# define DSXXXX_TIME_MIN_BCDMASK (DSXXXX_TIME_MIN_MASK | DSXXXX_TIME_10MIN_MASK) -#define DS3XXX_TIME_HOURR 0x02 /* Hours register */ -# define DS3XXX_TIME_HOUR_SHIFT 0 /* Bits 0-3: Hours, range 0-9 */ -# define DS3XXX_TIME_HOUR_MASK (15 << DS3XXX_TIME_HOUR_SHIFT) -# define DS3XXX_TIME_HOUR(n) ((uint8_t)(n) << DS3XXX_TIME_HOUR_SHIFT) -# define DS3XXX_TIME_10HOUR12_SHIFT 4 /* Bit 4: 10 hours, range 0-1 */ -# define DS3XXX_TIME_10HOUR12_MASK (1 << DS3XXX_TIME_10HOUR12_SHIFT) -# define DS3XXX_TIME_10HOUR12(n) ((uint8_t)(n) << DS3XXX_TIME_10HOUR12_SHIFT) -# define DS3XXX_TIME_10HOUR24_SHIFT 4 /* Bits 4-5: 10 hours, range 0-2 */ -# define DS3XXX_TIME_10HOUR24_MASK (3 << DS3XXX_TIME_10HOUR24_SHIFT) -# define DS3XXX_TIME_10HOUR24(n) ((uint8_t)(n) << DS3XXX_TIME_10HOUR24_SHIFT) -# define DS3XXX_TIME_HOUR12_BCDMASK (DS3XXX_TIME_HOUR_MASK | DS3XXX_TIME_10HOUR12_MASK) -# define DS3XXX_TIME_HOUR24_BCDMASK (DS3XXX_TIME_HOUR_MASK | DS3XXX_TIME_10HOUR24_MASK) -# define DS3XXX_TIME_AMPM_SHIFT 5 /* Bit 5: AM/PM Indication */ -# define DS3XXX_TIME_AMPM_MASK (1 << DS3XXX_TIME_AMPM_SHIFT) -# define DS3XXX_TIME_AM ((uint8_t)(0) << DS3XXX_TIME_AMPM_SHIFT) -# define DS3XXX_TIME_PM ((uint8_t)(1) << DS3XXX_TIME_AMPM_SHIFT) -# define DS3XXX_TIME_1224_SHIFT 6 /* Bit 6: 12/24 Indication */ -# define DS3XXX_TIME_1224_MASK (1 << DS3XXX_TIME_1224_SHIFT) -# define DS3XXX_TIME_24 ((uint8_t)(0) << DS3XXX_TIME_1224_SHIFT) -# define DS3XXX_TIME_12 ((uint8_t)(1) << DS3XXX_TIME_1224_SHIFT) +#define DSXXXX_TIME_HOURR 0x02 /* Hours register */ +# define DSXXXX_TIME_HOUR_SHIFT 0 /* Bits 0-3: Hours, range 0-9 */ +# define DSXXXX_TIME_HOUR_MASK (15 << DSXXXX_TIME_HOUR_SHIFT) +# define DSXXXX_TIME_HOUR(n) ((uint8_t)(n) << DSXXXX_TIME_HOUR_SHIFT) +# define DSXXXX_TIME_10HOUR12_SHIFT 4 /* Bit 4: 10 hours, range 0-1 */ +# define DSXXXX_TIME_10HOUR12_MASK (1 << DSXXXX_TIME_10HOUR12_SHIFT) +# define DSXXXX_TIME_10HOUR12(n) ((uint8_t)(n) << DSXXXX_TIME_10HOUR12_SHIFT) +# define DSXXXX_TIME_10HOUR24_SHIFT 4 /* Bits 4-5: 10 hours, range 0-2 */ +# define DSXXXX_TIME_10HOUR24_MASK (3 << DSXXXX_TIME_10HOUR24_SHIFT) +# define DSXXXX_TIME_10HOUR24(n) ((uint8_t)(n) << DSXXXX_TIME_10HOUR24_SHIFT) +# define DSXXXX_TIME_HOUR12_BCDMASK (DSXXXX_TIME_HOUR_MASK | DSXXXX_TIME_10HOUR12_MASK) +# define DSXXXX_TIME_HOUR24_BCDMASK (DSXXXX_TIME_HOUR_MASK | DSXXXX_TIME_10HOUR24_MASK) +# define DSXXXX_TIME_AMPM_SHIFT 5 /* Bit 5: AM/PM Indication */ +# define DSXXXX_TIME_AMPM_MASK (1 << DSXXXX_TIME_AMPM_SHIFT) +# define DSXXXX_TIME_AM ((uint8_t)(0) << DSXXXX_TIME_AMPM_SHIFT) +# define DSXXXX_TIME_PM ((uint8_t)(1) << DSXXXX_TIME_AMPM_SHIFT) +# define DSXXXX_TIME_1224_SHIFT 6 /* Bit 6: 12/24 Indication */ +# define DSXXXX_TIME_1224_MASK (1 << DSXXXX_TIME_1224_SHIFT) +# define DSXXXX_TIME_24 ((uint8_t)(0) << DSXXXX_TIME_1224_SHIFT) +# define DSXXXX_TIME_12 ((uint8_t)(1) << DSXXXX_TIME_1224_SHIFT) -#define DS3XXX_TIME_DAYR 0x03 /* Day of the week register */ -# define DS3XXX_TIME_DAY_SHIFT 0 /* Bits 0-3: Day of the week, range 1-7 */ -# define DS3XXX_TIME_DAY_MASK (7 << DS3XXX_TIME_DAY_SHIFT) -# define DS3XXX_TIME_DAY(n) ((uint8_t)(n) << DS3XXX_TIME_DAY_SHIFT) +#define DSXXXX_TIME_DAYR 0x03 /* Day of the week register */ +# define DSXXXX_TIME_DAY_SHIFT 0 /* Bits 0-3: Day of the week, range 1-7 */ +# define DSXXXX_TIME_DAY_MASK (7 << DSXXXX_TIME_DAY_SHIFT) +# define DSXXXX_TIME_DAY(n) ((uint8_t)(n) << DSXXXX_TIME_DAY_SHIFT) -#define DS3XXX_TIME_DATER 0x04 /* Date register */ -# define DS3XXX_TIME_DATE_SHIFT 0 /* Bits 0-3: Days, range 0-9 */ -# define DS3XXX_TIME_DATE_MASK (15 << DS3XXX_TIME_DATE_SHIFT) -# define DS3XXX_TIME_DATE(n) ((uint8_t)(n) << DS3XXX_TIME_DATE_SHIFT) -# define DS3XXX_TIME_10DATE_SHIFT 4 /* Bits 4-5: 10 days, range 0-5 */ -# define DS3XXX_TIME_10DATE_MASK (3 << DS3XXX_TIME_10DATE_SHIFT) -# define DS3XXX_TIME_10DATE(n) ((uint8_t)(n) << DS3XXX_TIME_10DATE_SHIFT) -# define DS3XXX_TIME_DATE_BCDMASK (DS3XXX_TIME_DATE_MASK | DS3XXX_TIME_10DATE_MASK) +#define DSXXXX_TIME_DATER 0x04 /* Date register */ +# define DSXXXX_TIME_DATE_SHIFT 0 /* Bits 0-3: Days, range 0-9 */ +# define DSXXXX_TIME_DATE_MASK (15 << DSXXXX_TIME_DATE_SHIFT) +# define DSXXXX_TIME_DATE(n) ((uint8_t)(n) << DSXXXX_TIME_DATE_SHIFT) +# define DSXXXX_TIME_10DATE_SHIFT 4 /* Bits 4-5: 10 days, range 0-5 */ +# define DSXXXX_TIME_10DATE_MASK (3 << DSXXXX_TIME_10DATE_SHIFT) +# define DSXXXX_TIME_10DATE(n) ((uint8_t)(n) << DSXXXX_TIME_10DATE_SHIFT) +# define DSXXXX_TIME_DATE_BCDMASK (DSXXXX_TIME_DATE_MASK | DSXXXX_TIME_10DATE_MASK) -#define DS3XXX_TIME_MONTHR 0x05 /* Month register */ -# define DS3XXX_TIME_MONTH_SHIFT 0 /* Bits 0-3: Month, range 0-9 */ -# define DS3XXX_TIME_MONTH_MASK (15 << DS3XXX_TIME_MONTH_SHIFT) -# define DS3XXX_TIME_MONTH(n) ((uint8_t)(n) << DS3XXX_TIME_MONTH_SHIFT) -# define DS3XXX_TIME_10MONTH_SHIFT 4 /* Bit 4: 10 month, range 0-1 */ -# define DS3XXX_TIME_10MONTH_MASK (1 << DS3XXX_TIME_10MONTH_SHIFT) -# define DS3XXX_TIME_10MONTH(n) ((uint8_t)(n) << DS3XXX_TIME_10MONTH_SHIFT) -# define DS3XXX_TIME_MONTH_BCDMASK (DS3XXX_TIME_MONTH_MASK | DS3XXX_TIME_10MONTH_MASK) -# define DS3XXX_TIME_CENTURY_SHIFT 7 /* Bit 7: AM/PM Indication */ -# define DS3XXX_TIME_CENTURY_MASK (1 << DS3XXX_TIME_CENTURY_SHIFT) -# define DS3XXX_TIME_1900 ((uint8_t)(0) << DS3XXX_TIME_CENTURY_SHIFT) -# define DS3XXX_TIME_2000 ((uint8_t)(1) << DS3XXX_TIME_CENTURY_SHIFT) +#define DSXXXX_TIME_MONTHR 0x05 /* Month register */ +# define DSXXXX_TIME_MONTH_SHIFT 0 /* Bits 0-3: Month, range 0-9 */ +# define DSXXXX_TIME_MONTH_MASK (15 << DSXXXX_TIME_MONTH_SHIFT) +# define DSXXXX_TIME_MONTH(n) ((uint8_t)(n) << DSXXXX_TIME_MONTH_SHIFT) +# define DSXXXX_TIME_10MONTH_SHIFT 4 /* Bit 4: 10 month, range 0-1 */ +# define DSXXXX_TIME_10MONTH_MASK (1 << DSXXXX_TIME_10MONTH_SHIFT) +# define DSXXXX_TIME_10MONTH(n) ((uint8_t)(n) << DSXXXX_TIME_10MONTH_SHIFT) +# define DSXXXX_TIME_MONTH_BCDMASK (DSXXXX_TIME_MONTH_MASK | DSXXXX_TIME_10MONTH_MASK) +#ifdef CONFIG_RTC_DS3231 +# define DS3231_TIME_CENTURY_SHIFT 7 /* Bit 7: Century Indication */ +# define DS3231_TIME_CENTURY_MASK (1 << DS3231_TIME_CENTURY_SHIFT) +# define DS3231_TIME_1900 ((uint8_t)(0) << DS3231_TIME_CENTURY_SHIFT) +# define DS3231_TIME_2000 ((uint8_t)(1) << DS3231_TIME_CENTURY_SHIFT) +#endif -#define DS3XXX_TIME_YEARR 0x06 /* Date register */ -# define DS3XXX_TIME_YEAR_SHIFT 0 /* Bits 0-3: Year, range 0-9 */ -# define DS3XXX_TIME_YEAR_MASK (15 << DS3XXX_TIME_YEAR_SHIFT) -# define DS3XXX_TIME_YEAR(n) ((uint8_t)(n) << DS3XXX_TIME_YEAR_SHIFT) -# define DS3XXX_TIME_10YEAR_SHIFT 4 /* Bits 4-7: 10 year, range 0-9 */ -# define DS3XXX_TIME_10YEAR_MASK (15 << DS3XXX_TIME_10YEAR_SHIFT) -# define DS3XXX_TIME_10YEAR(n) ((uint8_t)(n) << DS3XXX_TIME_10YEAR_SHIFT) -# define DS3XXX_TIME_YEAR_BCDMASK (DS3XXX_TIME_YEAR_MASK | DS3XXX_TIME_10YEAR_MASK) +#define DSXXXX_TIME_YEARR 0x06 /* Date register */ +# define DSXXXX_TIME_YEAR_SHIFT 0 /* Bits 0-3: Year, range 0-9 */ +# define DSXXXX_TIME_YEAR_MASK (15 << DSXXXX_TIME_YEAR_SHIFT) +# define DSXXXX_TIME_YEAR(n) ((uint8_t)(n) << DSXXXX_TIME_YEAR_SHIFT) +# define DSXXXX_TIME_10YEAR_SHIFT 4 /* Bits 4-7: 10 year, range 0-9 */ +# define DSXXXX_TIME_10YEAR_MASK (15 << DSXXXX_TIME_10YEAR_SHIFT) +# define DSXXXX_TIME_10YEAR(n) ((uint8_t)(n) << DSXXXX_TIME_10YEAR_SHIFT) +# define DSXXXX_TIME_YEAR_BCDMASK (DSXXXX_TIME_YEAR_MASK | DSXXXX_TIME_10YEAR_MASK) #ifdef CONFIG_RTC_DS1307 # define DS1307_CR 0x07 /* Control register */ diff --git a/include/nuttx/timers/ds3231.h b/include/nuttx/timers/ds3231.h index 1dec1ab7df..b3f239e3ad 100644 --- a/include/nuttx/timers/ds3231.h +++ b/include/nuttx/timers/ds3231.h @@ -42,7 +42,7 @@ #include -#ifdef CONFIG_RTC_DS3XXX +#ifdef CONFIG_RTC_DSXXXX /**************************************************************************** * Public Function Prototypes @@ -57,13 +57,13 @@ extern "C" #endif /************************************************************************************ - * Name: ds3xxx_rtc_initialize + * Name: dsxxxx_rtc_initialize * * Description: * Initialize the hardware RTC per the selected configuration. This function is * called once during the OS initialization sequence by board-specific logic. * - * After ds3xxx_rtc_initialize() is called, the OS function clock_synchronize() + * After dsxxxx_rtc_initialize() is called, the OS function clock_synchronize() * should also be called to synchronize the system timer to a hardware RTC. That * operation is normally performed automatically by the system during clock * initialization. However, when an external RTC is used, the board logic will @@ -79,12 +79,12 @@ extern "C" ************************************************************************************/ struct i2c_dev_s; /* Forward reference */ -int ds3xxx_rtc_initialize(FAR struct i2c_dev_s *i2c); +int dsxxxx_rtc_initialize(FAR struct i2c_dev_s *i2c); #undef EXTERN #ifdef __cplusplus } #endif -#endif /* CONFIG_RTC_DS3XXX */ +#endif /* CONFIG_RTC_DSXXXX */ #endif /* __INCLUDE_NUTTX_TIMERS_DS3231_H */ diff --git a/sched/clock/clock_initialize.c b/sched/clock/clock_initialize.c index 1871e90d2b..de855e3bc6 100644 --- a/sched/clock/clock_initialize.c +++ b/sched/clock/clock_initialize.c @@ -201,9 +201,11 @@ static void clock_inittime(void) void clock_initialize(void) { - /* Initialize the RTC hardware */ + /* Initialize the internal RTC hardware. Initialization of external RTC + * must be deferred until the system has booted. + */ -#ifdef CONFIG_RTC +#if defined(CONFIG_RTC) && !defined(CONFIG_RTC_EXTERNAL) up_rtcinitialize(); #endif