Do not give up if writing to the chip's control and status registers fails
during startup. When a brand new chip leaves the factory, it is in a special power-saving mode that disables most functions on the chip to save battery power. The chip is stuck in this mode until the first write to the time registers, which automatically clears the special power-saving mode and starts the oscillator. Also, the day-of-week register in this chip counts 1-7, not 0-6, so write the values accordingly. These changes are based on the patch submitted by Brian Scott, but I elimated warnings since this condition is expected, and added some comments, and so in general blame me for any mistakes. PR: 223642
This commit is contained in:
parent
0dc7c9e635
commit
3102bbe940
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=326750
@ -427,12 +427,18 @@ ds3231_start(void *xdev)
|
||||
device_printf(sc->sc_dev,
|
||||
"WARNING: RTC clock stopped, check the battery.\n");
|
||||
}
|
||||
/* Ack any pending alarm interrupt. */
|
||||
if (ds3231_status_write(sc, 1, 1) != 0)
|
||||
return;
|
||||
/* Always enable the oscillator. */
|
||||
if (ds3231_ctrl_write(sc) != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Ack any pending alarm interrupts and clear the EOSC bit to ensure the
|
||||
* clock runs even when on battery power. Do not give up if these
|
||||
* writes fail, because a factory-fresh chip is in a special mode that
|
||||
* disables much of the chip to save battery power, and the only thing
|
||||
* that gets it out of that mode is writing to the time registers. In
|
||||
* these pristine chips, the EOSC and alarm bits are zero already, so
|
||||
* the first valid write of time will get everything running properly.
|
||||
*/
|
||||
ds3231_status_write(sc, 1, 1);
|
||||
ds3231_ctrl_write(sc);
|
||||
|
||||
/* Temperature. */
|
||||
SYSCTL_ADD_PROC(ctx, tree, OID_AUTO, "temperature",
|
||||
@ -568,7 +574,7 @@ ds3231_settime(device_t dev, struct timespec *ts)
|
||||
data[DS3231_MINS] = TOBCD(ct.min);
|
||||
data[DS3231_HOUR] = TOBCD(ct.hour) | pmflags;
|
||||
data[DS3231_DATE] = TOBCD(ct.day);
|
||||
data[DS3231_WEEKDAY] = ct.dow;
|
||||
data[DS3231_WEEKDAY] = ct.dow + 1;
|
||||
data[DS3231_MONTH] = TOBCD(ct.mon);
|
||||
data[DS3231_YEAR] = TOBCD(ct.year % 100);
|
||||
if (sc->sc_last_c)
|
||||
|
Loading…
Reference in New Issue
Block a user