1.. zephyr:code-sample:: ds3231
2   :name: DS3231 TCXO RTC
3   :relevant-api: counter_interface
4
5   Interact with a DS3231 real-time clock using the counter API and dedicated driver API.
6
7Overview
8********
9
10The `DS3231`_ temperature-compensated real-time clock is a
11high-precision (2 ppm) battery backed clock that maintains civil time
12and supports alarms.  The `Chronodot`_ breakout board can be used to
13test it.
14
15Annotated Example Output
16************************
17
18The sample first displays the boot banner, board name and
19frequency of the local clock used for synchronization, and whether the
20DS3231 has recorded a loss-of-oscillator::
21
22   ***** Booting Zephyr OS build zephyr-v1.14.0-2409-g322d53aedaa0 *****
23   DS3231 on particle_xenon syncclock 1000 Hz
24   .
25   DS3231 has not experienced an oscillator fault
26
27Next, information about the device as a counter is displayed.  The
28counter value is read, and its value formatted as the date, time, day of
29week, and day of year (19 July 2019 is a Friday, and is the 200th day of
302019)::
31
32   Counter at 0x20001a58
33           Max top value: 4294967295 (ffffffff)
34           2 channels
35           1 Hz
36   Top counter value: 4294967295 (ffffffff)
37   Now 1563512509: 2019-07-19 05:01:49 Fri 200
38
39The DS3231 control and status register values are displayed::
40
41   DS3231 ctrl 04 ; ctrl_stat 08
42
43Next, if the sample application option ``CONFIG_APP_SET_ALIGNED_CLOCK``
44is set, the civil time will be advanced to the start of the next hour,
45and the clock will be set to align that time with the time of the boot,
46which in the output below is 34 ms in the past.  The time required to
47synchronize the clock is 967 ms, and the whole second value of one
48second past the hour is written at 1000 ms local uptime::
49
50   Set 2019-07-19 06:00:00.034000000 Fri 200 at 34 ms past: 0
51   Synchronize final: 0 0 in 967 ms
52   wrote sync 0: 1563516001 0 at 1000
53
54Then a synchronization point is read.  This takes 894 ms (it must align
55to an RTC one-second rollover)::
56
57   Synchronize init: 0
58   Synchronize complete in 894 ms: 0 0
59   .
60   read sync 0: 1563516002 0 at 2000
61
62The alarm configuration is read from non-volatile memory and displayed.
63See the ``maxim_ds3231.h`` for interpretation of the integer value and
64flags::
65
66   Alarm 1 flags 0 at 254034017: 0
67   Alarm 2 flags e at 252374400: 0
68
69Five seconds is added to the current time and the civil time
70representation displayed.  The second-resolution alarm is configured to
71fire at that time on the current day-of-week.  The minute-resolution
72alarm is configured to fire once per minute::
73
74   Min Sec base time: 2019-07-19 06:00:07 Fri 200
75   Set sec alarm 90 at 1563516007 ~ 2019-07-19 06:00:07 Fri 200: 5
76   Set min alarm flags f at 1563516007 ~ 2019-07-19 06:00:07 Fri 200: 7
77
78We're now 2.131 ms into the run, at which point the alarms are read back
79and displayed.  Alarms do not include date but can include day-of-week
80or day-of-month; the date is selected to preserve that information::
81
82   2131 ms in: get alarms: 0 0
83   Sec alarm flags 10 at 252914407 ~ 1978-01-06 06:00:07 Fri 006
84   Min alarm flags e at 252374400 ~ 1977-12-31 00:00:00 Sat 365
85
86The second-resolution alarm was signalled, and processed by the
87application at 7.002 s into the run, as scheduled (plus callback
88latency).  The callback uses the counter alarm API to schedule a second
89alarm in 10 seconds::
90
91   Sec signaled at 7002 ms, param 0x20000048, delay 1; set 7
92
93The counter API callback is called at the correct time::
94
95   Counter callback at 17001 ms, id 0, ticks 1563516017, ud 0x20000048
96
97From here on the sample sleeps except when the minute-resolution alarm
98fires, at which point it displays the RTC time; the
99nanosecond-resolution offset in seconds between the RTC time and the
100local time; the local time from ``k_uptime_get()``; and the aggregate
101error between local and RTC time measured in parts-per-million::
102
103   2019-07-19 06:01:00 Fri 200: adj 0.002000000, uptime 0:01:00.002, clk err 34 ppm
104   2019-07-19 06:02:00 Fri 200: adj 0.003000000, uptime 0:02:00.004, clk err 25 ppm
105   2019-07-19 06:03:00 Fri 200: adj 0.005000000, uptime 0:03:00.005, clk err 28 ppm
106   2019-07-19 06:04:00 Fri 200: adj 0.006000000, uptime 0:04:00.007, clk err 25 ppm
107   2019-07-19 06:05:00 Fri 200: adj 0.008000000, uptime 0:05:00.008, clk err 26 ppm
108
109The output shows that the Zephyr system clock is running about 25 ppm
110faster than civil time on this device.  This amount of error is expected
111for this target as the system time derives from a crystal oscillator
112with a similar accuracy.
113
114Building and Running
115********************
116
117Wire a Chronodot to one of the supported boards as specified in the
118corresponding devicetree overlay.
119
120* Particle Xenon
121
122  .. zephyr-app-commands::
123     :zephyr-app: samples/drivers/counter/maxim_ds3231
124     :board: particle-xenon
125     :goals: build
126     :compact:
127
128* NXP Freedom K64F
129
130  .. zephyr-app-commands::
131     :zephyr-app: samples/drivers/counter/maxim_ds3231
132     :board: frdm_k64f
133     :goals: build
134     :compact:
135
136* ST Nucleo L476RG
137
138  .. zephyr-app-commands::
139     :zephyr-app: samples/drivers/counter/maxim_ds3231
140     :board: nucleo_l476rg
141     :goals: build
142     :compact:
143
144* EFR32 Mighty Gecko Thunderboard Sense 2
145
146  .. zephyr-app-commands::
147     :zephyr-app: samples/drivers/counter/maxim_ds3231
148     :board: sltb004a
149     :goals: build
150     :compact:
151
152.. _DS3231:
153   https://www.maximintegrated.com/en/products/analog/real-time-clocks/DS3231.html
154.. _Chronodot:
155   https://www.adafruit.com/product/255
156