-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathpcf8523.py
162 lines (114 loc) · 5.46 KB
/
pcf8523.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# SPDX-FileCopyrightText: 2016 Philip R. Moyer for Adafruit Industries
# SPDX-FileCopyrightText: 2016 Radomir Dopieralski for Adafruit Industries
#
# SPDX-License-Identifier: MIT
"""
`pcf8523` - PCF8523 Real Time Clock module
==========================================
This library supports the use of the PCF8523-based RTC in CircuitPython. It
contains a base RTC class used by all Adafruit RTC libraries. This base
class is inherited by the chip-specific subclasses.
Functions are included for reading and writing registers and manipulating
datetime objects.
Author(s): Philip R. Moyer and Radomir Dopieralski for Adafruit Industries.
Date: November 2016
Affiliation: Adafruit Industries
Implementation Notes
--------------------
**Hardware:**
* Adafruit `Adalogger FeatherWing - RTC + SD Add-on <https://www.adafruit.com/products/2922>`_
(Product ID: 2922)
* Adafruit `PCF8523 RTC breakout <https://www.adafruit.com/products/3295>`_ (Product ID: 3295)
**Software and Dependencies:**
* Adafruit CircuitPython firmware for the supported boards:
https://circuitpython.org/downloads
* Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
**Notes:**
#. Milliseconds are not supported by this RTC.
#. The alarm does not support seconds. It will always fire on full minutes.
#. Datasheet: http://cache.nxp.com/documents/data_sheet/PCF8523.pdf
"""
__version__ = "0.0.0+auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PCF8523.git"
from adafruit_bus_device.i2c_device import I2CDevice
from adafruit_register import i2c_bit
from adafruit_register import i2c_bits
from adafruit_register import i2c_bcd_alarm
from adafruit_register import i2c_bcd_datetime
try:
import typing # pylint: disable=unused-import
from busio import I2C
from time import struct_time
except ImportError:
pass
STANDARD_BATTERY_SWITCHOVER_AND_DETECTION = 0b000
BATTERY_SWITCHOVER_OFF = 0b111
class PCF8523:
"""Interface to the PCF8523 RTC.
:param ~busio.I2C i2c_bus: The I2C bus the device is connected to
**Quickstart: Importing and using the device**
Here is an example of using the :class:`PCF8523` class.
First you will need to import the libraries to use the sensor
.. code-block:: python
import time
import board
import adafruit_pcf8523
Once this is done you can define your `board.I2C` object and define your sensor object
.. code-block:: python
i2c = board.I2C() # uses board.SCL and board.SDA
rtc = adafruit_pcf8523.PCF8523(i2c)
Now you can give the current time to the device.
.. code-block:: python
t = time.struct_time((2017, 10, 29, 15, 14, 15, 0, -1, -1))
rtc.datetime = t
You can access the current time accessing the :attr:`datetime` attribute.
.. code-block:: python
current_time = rtc.datetime
"""
lost_power = i2c_bit.RWBit(0x03, 7)
"""True if the device has lost power since the time was set."""
power_management = i2c_bits.RWBits(3, 0x02, 5)
"""Power management state that dictates battery switchover, power sources
and low battery detection. Defaults to BATTERY_SWITCHOVER_OFF (0b111)."""
# The False means that day comes before weekday in the registers. The 0 is
# that the first day of the week is value 0 and not 1.
datetime_register = i2c_bcd_datetime.BCDDateTimeRegister(0x03, False, 0)
"""Current date and time."""
# The False means that day and weekday share a register. The 0 is that the
# first day of the week is value 0 and not 1.
alarm = i2c_bcd_alarm.BCDAlarmTimeRegister(
0x0A, has_seconds=False, weekday_shared=False, weekday_start=0
)
"""Alarm time for the first alarm. Note that the value of the seconds-fields
is ignored, i.e. alarms only fire at full minutes. For short-term
alarms, use a timer instead."""
alarm_interrupt = i2c_bit.RWBit(0x00, 1)
"""True if the interrupt pin will output when alarm is alarming."""
alarm_status = i2c_bit.RWBit(0x01, 3)
"""True if alarm is alarming. Set to False to reset."""
battery_low = i2c_bit.ROBit(0x02, 2)
"""True if the battery is low and should be replaced."""
high_capacitance = i2c_bit.RWBit(0x00, 7)
"""True for high oscillator capacitance (12.5pF), otherwise lower (7pF)"""
calibration_schedule_per_minute = i2c_bit.RWBit(0x0E, 7)
"""False to apply the calibration offset every 2 hours (1 LSB = 4.340ppm);
True to offset every minute (1 LSB = 4.069ppm). The default, False,
consumes less power. See datasheet figures 28-31 for details."""
calibration = i2c_bits.RWBits( # pylint: disable=unexpected-keyword-arg
7, 0xE, 0, signed=True
)
"""Calibration offset to apply, from -64 to +63. See the PCF8523 datasheet
figure 18 for the offset calibration calculation workflow."""
def __init__(self, i2c_bus: I2C):
self.i2c_device = I2CDevice(i2c_bus, 0x68)
@property
def datetime(self) -> struct_time:
"""Gets the current date and time or sets the current date and time then starts the
clock."""
return self.datetime_register
@datetime.setter
def datetime(self, value: struct_time):
# Automatically sets lost_power to false.
self.power_management = STANDARD_BATTERY_SWITCHOVER_AND_DETECTION
self.datetime_register = value