Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit f0acff6

Browse files
authoredOct 10, 2023
Merge pull request #30 from bablokb/4upstream
timer-support
2 parents d336221 + 4d3cf8b commit f0acff6

File tree

11 files changed

+493
-35
lines changed

11 files changed

+493
-35
lines changed
 

‎README.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ Of course, you must import the library to use it:
7979
.. code:: python3
8080
8181
import time
82-
import adafruit_pcf8523
82+
from adafruit_pcf8523.pcf8523 import PCF8523
8383
8484
All the Adafruit RTC libraries take an instantiated and active I2C object
8585
(from the `board` library) as an argument to their constructor. The way to
@@ -101,7 +101,7 @@ the RTC object:
101101

102102
.. code:: python3
103103
104-
rtc = adafruit_pcf8523.PCF8523(i2c)
104+
rtc = PCF8523(i2c)
105105
106106
Date and time
107107
-------------

‎adafruit_pcf8523/clock.py

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# SPDX-FileCopyrightText: 2016 Philip R. Moyer for Adafruit Industries
2+
# SPDX-FileCopyrightText: 2016 Radomir Dopieralski for Adafruit Industries
3+
# SPDX-FileCopyrightText: Copyright (c) 2023 Bernhard Bablok
4+
#
5+
# SPDX-License-Identifier: MIT
6+
7+
"""
8+
`clock` - PCF8523 Clock module
9+
==============================
10+
11+
This class supports the clkout-feature of the PCF8523-based RTC in CircuitPython.
12+
13+
Functions are included for reading and writing registers to configure
14+
clklout frequency.
15+
16+
The class supports stand-alone usage. In this case, pass an i2-bus object
17+
to the constructor. If used together with the PCF8523 class (rtc), instantiate
18+
the rtc-object first and then pass the i2c_device attribute of the rtc
19+
to the constructor of the clock.
20+
21+
Author(s): Bernhard Bablok
22+
Date: September 2023
23+
24+
Implementation Notes
25+
--------------------
26+
27+
**Hardware:**
28+
29+
* Adafruit `Adalogger FeatherWing - RTC + SD Add-on <https://www.adafruit.com/products/2922>`_
30+
(Product ID: 2922)
31+
* Adafruit `PCF8523 RTC breakout <https://www.adafruit.com/products/3295>`_ (Product ID: 3295)
32+
33+
**Software and Dependencies:**
34+
35+
* Adafruit CircuitPython firmware for the supported boards:
36+
https://circuitpython.org/downloads
37+
38+
* Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
39+
40+
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
41+
42+
**Notes:**
43+
44+
#. Milliseconds are not supported by this RTC.
45+
#. The alarm does not support seconds. It will always fire on full minutes.
46+
#. Datasheet: http://cache.nxp.com/documents/data_sheet/PCF8523.pdf
47+
48+
"""
49+
50+
__version__ = "0.0.0+auto.0"
51+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PCF8523.git"
52+
53+
import time
54+
55+
from adafruit_bus_device.i2c_device import I2CDevice
56+
from adafruit_register import i2c_bits
57+
from micropython import const
58+
59+
try:
60+
from typing import Union
61+
from busio import I2C
62+
except ImportError:
63+
pass
64+
65+
66+
class Clock: # pylint: disable=too-few-public-methods
67+
"""Interface to the clkout of the PCF8523 RTC.
68+
69+
:param I2C i2c_bus: The I2C bus object
70+
"""
71+
72+
clockout_frequency = i2c_bits.RWBits(3, 0x0F, 3) # COF[2:0]
73+
"""Clock output frequencies generated. Default is 32.768kHz.
74+
Possible values are as shown (selection value - frequency).
75+
000 - 32.768khz
76+
001 - 16.384khz
77+
010 - 8.192kHz
78+
011 - 4.096kHz
79+
100 - 1.024kHz
80+
101 - 0.032kHz (32Hz)
81+
110 - 0.001kHz (1Hz)
82+
111 - Disabled
83+
"""
84+
85+
CLOCKOUT_FREQ_32KHZ = const(0b000)
86+
"""Clock frequency of 32 KHz"""
87+
CLOCKOUT_FREQ_16KHZ = const(0b001)
88+
"""Clock frequency of 16 KHz"""
89+
CLOCKOUT_FREQ_8KHZ = const(0b010)
90+
"""Clock frequency of 8 KHz"""
91+
CLOCKOUT_FREQ_4KHZ = const(0b011)
92+
"""Clock frequency of 4 KHz"""
93+
CLOCKOUT_FREQ_1KHZ = const(0b100)
94+
"""Clock frequency of 4 KHz"""
95+
CLOCKOUT_FREQ_32HZ = const(0b101)
96+
"""Clock frequency of 32 Hz"""
97+
CLOCKOUT_FREQ_1HZ = const(0b110)
98+
"""Clock frequency of 1 Hz"""
99+
CLOCKOUT_FREQ_DISABLED = const(0b111)
100+
"""Clock output disabled"""
101+
102+
def __init__(self, i2c: Union[I2C, I2CDevice]) -> None:
103+
if isinstance(i2c, I2CDevice):
104+
self.i2c_device = i2c # reuse i2c_device (from PCF8563-instance)
105+
else:
106+
time.sleep(0.05)
107+
self.i2c_device = I2CDevice(i2c, 0x68)

‎adafruit_pcf8523.py renamed to ‎adafruit_pcf8523/pcf8523.py

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
# SPDX-License-Identifier: MIT
55

66
"""
7-
`adafruit_pcf8523` - PCF8523 Real Time Clock module
8-
====================================================
7+
`pcf8523` - PCF8523 Real Time Clock module
8+
==========================================
99
1010
This library supports the use of the PCF8523-based RTC in CircuitPython. It
1111
contains a base RTC class used by all Adafruit RTC libraries. This base
@@ -39,6 +39,7 @@ class is inherited by the chip-specific subclasses.
3939
**Notes:**
4040
4141
#. Milliseconds are not supported by this RTC.
42+
#. The alarm does not support seconds. It will always fire on full minutes.
4243
#. Datasheet: http://cache.nxp.com/documents/data_sheet/PCF8523.pdf
4344
4445
"""
@@ -106,32 +107,21 @@ class PCF8523:
106107

107108
power_management = i2c_bits.RWBits(3, 0x02, 5)
108109
"""Power management state that dictates battery switchover, power sources
109-
and low battery detection. Defaults to BATTERY_SWITCHOVER_OFF (0b000)."""
110+
and low battery detection. Defaults to BATTERY_SWITCHOVER_OFF (0b111)."""
110111

111112
# The False means that day comes before weekday in the registers. The 0 is
112113
# that the first day of the week is value 0 and not 1.
113114
datetime_register = i2c_bcd_datetime.BCDDateTimeRegister(0x03, False, 0)
114115
"""Current date and time."""
115116

116-
clockout_frequency = i2c_bits.RWBits(3, 0x0F, 3)
117-
"""Clock output frequencies generated. Default is 32.768kHz.
118-
Possible values are as shown (selection value - frequency).
119-
000 - 32.768khz
120-
001 - 16.384khz
121-
010 - 8.192kHz
122-
011 - 4.096kHz
123-
100 - 1.024kHz
124-
101 - 0.032kHz (32Hz)
125-
110 - 0.001kHz (1Hz)
126-
111 - Disabled
127-
"""
128-
129117
# The False means that day and weekday share a register. The 0 is that the
130118
# first day of the week is value 0 and not 1.
131119
alarm = i2c_bcd_alarm.BCDAlarmTimeRegister(
132120
0x0A, has_seconds=False, weekday_shared=False, weekday_start=0
133121
)
134-
"""Alarm time for the first alarm."""
122+
"""Alarm time for the first alarm. Note that the value of the seconds-fields
123+
is ignored, i.e. alarms only fire at full minutes. For short-term
124+
alarms, use a timer instead."""
135125

136126
alarm_interrupt = i2c_bit.RWBit(0x00, 1)
137127
"""True if the interrupt pin will output when alarm is alarming."""
@@ -159,17 +149,6 @@ class PCF8523:
159149
def __init__(self, i2c_bus: I2C):
160150
self.i2c_device = I2CDevice(i2c_bus, 0x68)
161151

162-
# Try and verify this is the RTC we expect by checking the timer B
163-
# frequency control bits which are 1 on reset and shouldn't ever be
164-
# changed.
165-
buf = bytearray(2)
166-
buf[0] = 0x12
167-
with self.i2c_device as i2c:
168-
i2c.write_then_readinto(buf, buf, out_end=1, in_start=1)
169-
170-
if (buf[1] & 0b00000111) != 0b00000111:
171-
raise ValueError("Unable to find PCF8523 at i2c address 0x68.")
172-
173152
@property
174153
def datetime(self) -> struct_time:
175154
"""Gets the current date and time or sets the current date and time then starts the

‎adafruit_pcf8523/timer.py

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
# SPDX-FileCopyrightText: 2016 Philip R. Moyer for Adafruit Industries
2+
# SPDX-FileCopyrightText: 2016 Radomir Dopieralski for Adafruit Industries
3+
# SPDX-FileCopyrightText: Copyright (c) 2023 Bernhard Bablok
4+
#
5+
# SPDX-License-Identifier: MIT
6+
7+
"""
8+
`timer` - PCF8523 Timer module
9+
==============================
10+
11+
This class supports the timer of the PCF8523-based RTC in CircuitPython.
12+
13+
Functions are included for reading and writing registers and manipulating
14+
timer objects.
15+
16+
The PCF8523 support two timers named Tmr_A and Tmr_B in the datasheet.
17+
For compatibility with the PCF8563, the Tmr_A is named timer while the
18+
second timer is named timerB.
19+
20+
The class supports stand-alone usage. In this case, pass an i2-bus object
21+
to the constructor. If used together with the PCF8523 class (rtc), instantiate
22+
the rtc-object first and then pass the i2c_device attribute of the rtc
23+
to the constructor of the timer.
24+
25+
Author(s): Bernhard Bablok
26+
Date: September 2023
27+
28+
Implementation Notes
29+
--------------------
30+
31+
**Hardware:**
32+
33+
* Adafruit `Adalogger FeatherWing - RTC + SD Add-on <https://www.adafruit.com/products/2922>`_
34+
(Product ID: 2922)
35+
* Adafruit `PCF8523 RTC breakout <https://www.adafruit.com/products/3295>`_ (Product ID: 3295)
36+
37+
**Software and Dependencies:**
38+
39+
* Adafruit CircuitPython firmware for the supported boards:
40+
https://circuitpython.org/downloads
41+
42+
* Adafruit's Register library: https://github.com/adafruit/Adafruit_CircuitPython_Register
43+
44+
* Adafruit's Bus Device library: https://github.com/adafruit/Adafruit_CircuitPython_BusDevice
45+
46+
**Notes:**
47+
48+
#. Milliseconds are not supported by this RTC.
49+
#. The alarm does not support seconds. It will always fire on full minutes.
50+
#. Datasheet: http://cache.nxp.com/documents/data_sheet/PCF8523.pdf
51+
52+
"""
53+
54+
__version__ = "0.0.0+auto.0"
55+
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_PCF8523.git"
56+
57+
import time
58+
59+
from adafruit_bus_device.i2c_device import I2CDevice
60+
from adafruit_register import i2c_bit
61+
from adafruit_register import i2c_bits
62+
from micropython import const
63+
64+
try:
65+
from typing import Union
66+
from busio import I2C
67+
except ImportError:
68+
pass
69+
70+
71+
class Timer: # pylint: disable=too-few-public-methods
72+
"""Interface to the timer of the PCF8563 RTC.
73+
74+
:param I2C i2c_bus: The I2C bus object
75+
"""
76+
77+
timer_enabled = i2c_bits.RWBits(2, 0x0F, 1) # TAC[1:0]
78+
"""Configures timer. Possible values:
79+
00 - disabled
80+
01 - enabled as countdown timer
81+
10 - enabled as watchdog timer
82+
11 - disabled
83+
"""
84+
85+
timer_frequency = i2c_bits.RWBits(3, 0x10, 0) # TAQ[2:0]
86+
"""TimerA clock frequency. Default is 1/3600Hz.
87+
Possible values are as shown (selection value - frequency).
88+
000 - 4.096kHz
89+
001 - 64Hz
90+
010 - 1Hz
91+
011 - 1/60Hz
92+
111 - 1/3600Hz
93+
"""
94+
95+
TIMER_FREQ_4KHZ = const(0b000)
96+
"""Timer frequency of 4 KHz"""
97+
TIMER_FREQ_64HZ = const(0b001)
98+
"""Timer frequency of 64 Hz"""
99+
TIMER_FREQ_1HZ = const(0b010)
100+
"""Timer frequency of 1 Hz"""
101+
TIMER_FREQ_1_60HZ = const(0b011)
102+
"""Timer frequency of 1/60 Hz"""
103+
TIMER_FREQ_1_3600HZ = const(0b111)
104+
"""Timer frequency of 1/3600 Hz"""
105+
106+
timer_value = i2c_bits.RWBits(8, 0x11, 0) # T_A[7:0]
107+
""" TimerA value (0-255). The default is undefined.
108+
The total countdown duration is calcuated by
109+
timer_value/timer_frequency. For a higher precision, use higher values
110+
and frequencies, e.g. for a one minute timer you could use
111+
value=1, frequency=1/60Hz or value=60, frequency=1Hz. The
112+
latter will give better results. See the PCF85x3 User's Manual
113+
for details."""
114+
115+
timer_interrupt = i2c_bit.RWBit(0x01, 1) # CTAIE
116+
"""True if the interrupt pin will assert when timer has elapsed.
117+
Defaults to False."""
118+
119+
timer_watchdog = i2c_bit.RWBit(0x01, 2) # WTAIE
120+
"""True if the interrupt pin will output when timer generates a
121+
watchdog-alarm. Defaults to False."""
122+
123+
timer_status = i2c_bit.RWBit(0x01, 6) # CTAF
124+
"""True if timer has elapsed. Set to False to reset."""
125+
126+
timer_pulsed = i2c_bit.RWBit(0x0F, 7) # TAM
127+
"""True if timer asserts INT as a pulse. The default
128+
value False asserts INT permanently."""
129+
130+
timerB_enabled = i2c_bit.RWBit(0x0F, 0) # TBC
131+
"""True if the timerB is enabled. Default is False."""
132+
133+
timerB_frequency = i2c_bits.RWBits(3, 0x12, 0) # TBQ[2:0]
134+
"""TimerB clock frequency. Default is 1/3600Hz.
135+
Possible values are as shown (selection value - frequency).
136+
000 - 4.096kHz
137+
001 - 64Hz
138+
010 - 1Hz
139+
011 - 1/60Hz
140+
111 - 1/3600Hz
141+
"""
142+
143+
timerB_value = i2c_bits.RWBits(8, 0x13, 0) # T_B[7:0]
144+
""" TimerB value (0-255). The default is undefined.
145+
The total countdown duration is calcuated by
146+
timerB_value/timerB_frequency. For a higher precision, use higher values
147+
and frequencies, e.g. for a one minute timer you could use
148+
value=1, frequency=1/60Hz or value=60, frequency=1Hz. The
149+
latter will give better results. See the PCF85x3 User's Manual
150+
for details."""
151+
152+
timerB_interrupt = i2c_bit.RWBit(0x01, 0) # CTBIE
153+
"""True if the interrupt pin will assert when timerB has elapsed.
154+
Defaults to False."""
155+
156+
timerB_status = i2c_bit.RWBit(0x01, 5) # CTBF
157+
"""True if timerB has elapsed. Set to False to reset."""
158+
159+
timerB_pulsed = i2c_bit.RWBit(0x0F, 6) # TBM
160+
"""True if timerB asserts INT as a pulse. The default
161+
value False asserts INT permanently."""
162+
163+
def __init__(self, i2c: Union[I2C, I2CDevice]) -> None:
164+
if isinstance(i2c, I2CDevice):
165+
self.i2c_device = i2c # reuse i2c_device (from PCF8523-instance)
166+
else:
167+
time.sleep(0.05)
168+
self.i2c_device = I2CDevice(i2c, 0x68)

‎docs/api.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11

2-
.. automodule:: adafruit_pcf8523
2+
.. automodule:: adafruit_pcf8523.pcf8523
3+
:members:
4+
5+
.. automodule:: adafruit_pcf8523.timer
6+
:members:
7+
8+
.. automodule:: adafruit_pcf8523.clock
39
:members:

‎docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
# Uncomment the below if you use native CircuitPython modules such as
4545
# digitalio, micropython and busio. List the modules you use. Without it, the
4646
# autodoc module docs will fail to generate with a warning.
47-
# autodoc_mock_imports = ["adafruit_bus_device", "adafruit_register"]
47+
autodoc_mock_imports = ["adafruit_bus_device", "adafruit_register"]
4848

4949
# Add any paths that contain templates here, relative to this directory.
5050
templates_path = ["_templates"]

‎examples/pcf8523_clockout.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# SPDX-FileCopyrightText: 2023 Bernhard Bablok
2+
# SPDX-License-Identifier: MIT
3+
4+
# Simple demo for clockout-mode (square-wave generation)
5+
# Note that for 32kHz, the duty-cycle is from 60:40 to 40:60, thus
6+
# it is not a perfect square wave (see datasheet 8.9.1.2)
7+
8+
import time
9+
import board
10+
import busio
11+
import countio
12+
from digitalio import Pull
13+
from adafruit_pcf8523.clock import Clock
14+
15+
PIN_SDA = board.GP2 # connect to RTC
16+
PIN_SCL = board.GP3 # connect to RTC
17+
# use board.SCL and board.SDA if available
18+
19+
i2c = busio.I2C(PIN_SCL, PIN_SDA)
20+
# or i2c = board.I2C() if available
21+
clock = Clock(i2c)
22+
23+
# pin must support countio
24+
PIN_COUT = board.GP5
25+
counter = countio.Counter(pin=PIN_COUT, edge=countio.Edge.RISE, pull=Pull.UP)
26+
DURATION = 10
27+
28+
# Main loop:
29+
while True:
30+
# disable clockout
31+
print(f"testing disabled clock for {DURATION} seconds")
32+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_DISABLED
33+
counter.reset()
34+
time.sleep(DURATION)
35+
print(f"clock-pulses: {counter.count}")
36+
print(f"clock-freq: {counter.count/DURATION}")
37+
38+
# test 32kHz
39+
print(f"testing 32 kHz clock for {DURATION} seconds")
40+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_32KHZ
41+
counter.reset()
42+
time.sleep(DURATION)
43+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_DISABLED
44+
print(f"clock-pulses: {counter.count}")
45+
print(f"clock-freq: {counter.count/DURATION}")
46+
47+
# test 4kHz
48+
print(f"testing 4 kHz clock for {DURATION} seconds")
49+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_4KHZ
50+
counter.reset()
51+
time.sleep(DURATION)
52+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_DISABLED
53+
print(f"clock-pulses: {counter.count}")
54+
print(f"clock-freq: {counter.count/DURATION}")
55+
56+
# test 1Hz
57+
print(f"testing 1 Hz clock for {DURATION} seconds")
58+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_1HZ
59+
counter.reset()
60+
time.sleep(DURATION)
61+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_DISABLED
62+
print(f"clock-pulses: {counter.count}")
63+
print(f"clock-freq: {counter.count/DURATION}")

‎examples/pcf8523_simpletest.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88

99
import time
1010
import board
11-
import adafruit_pcf8523
11+
from adafruit_pcf8523.pcf8523 import PCF8523
1212

1313
i2c = board.I2C() # uses board.SCL and board.SDA
1414
# i2c = board.STEMMA_I2C() # For using the built-in STEMMA QT connector on a microcontroller
15-
rtc = adafruit_pcf8523.PCF8523(i2c)
15+
rtc = PCF8523(i2c)
1616

1717
# Lookup table for names of days (nicer printing).
1818
days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")

‎examples/pcf8523_timer_flag.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# SPDX-FileCopyrightText: 2023 Bernhard Bablok
2+
# SPDX-License-Identifier: MIT
3+
4+
# Simple demo for timer operation using the timer-flag
5+
6+
import time
7+
import board
8+
import busio
9+
from adafruit_pcf8523.timer import Timer
10+
from adafruit_pcf8523.clock import Clock
11+
12+
LOW_FREQ_TIMER = 10
13+
HIGH_FREQ_TIMER = 0.02
14+
HIGH_FREQ_TIME = 10
15+
PIN_SDA = board.GP2
16+
PIN_SCL = board.GP3
17+
# use board.SCL and board.SDA if available
18+
19+
i2c = busio.I2C(PIN_SCL, PIN_SDA)
20+
# or i2c = board.I2C() if available
21+
timer = Timer(i2c)
22+
clock = Clock(timer.i2c_device)
23+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_DISABLED
24+
25+
# Main loop:
26+
while True:
27+
print("low-frequency timer: checking timer-flag")
28+
timer.timer_enabled = False
29+
timer.timer_status = False
30+
timer.timer_frequency = timer.TIMER_FREQ_1HZ
31+
timer.timer_value = LOW_FREQ_TIMER
32+
start = time.monotonic()
33+
timer.timer_enabled = True
34+
while not timer.timer_status and time.monotonic() - start < LOW_FREQ_TIMER + 1:
35+
pass
36+
if not timer.timer_status:
37+
# shoud not happen!
38+
print(f"error: timer did not fire within {LOW_FREQ_TIMER+1} seconds!")
39+
else:
40+
elapsed = time.monotonic() - start
41+
print(f"elapsed: {elapsed}")
42+
43+
print("high-frequency timer: checking timer-flag")
44+
timer.timer_enabled = False
45+
timer.timer_status = False
46+
timer.timer_frequency = timer.TIMER_FREQ_4KHZ
47+
timer.timer_value = min(round(HIGH_FREQ_TIMER * 4096), 255)
48+
counter = 0
49+
start = time.monotonic()
50+
end = start + HIGH_FREQ_TIME
51+
timer.timer_enabled = True
52+
while time.monotonic() < end:
53+
if not timer.timer_status:
54+
continue
55+
timer.timer_status = False
56+
counter += 1
57+
if counter > 0:
58+
mean_interval = (time.monotonic() - start) / counter
59+
print(f"interval requested: {HIGH_FREQ_TIMER}")
60+
print(f"interval observed: {mean_interval} (mean of {counter} alarms)")
61+
else:
62+
print(f"error: timer did not fire within {HIGH_FREQ_TIME} seconds!")
63+
print("error: timer did not fire")

‎examples/pcf8523_timer_interrupt.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# SPDX-FileCopyrightText: 2023 Bernhard Bablok
2+
# SPDX-License-Identifier: MIT
3+
4+
# Simple demo for timer operation, using the interrupt-pin
5+
6+
import time
7+
import board
8+
import busio
9+
from digitalio import DigitalInOut, Direction, Pull
10+
from adafruit_pcf8523.timer import Timer
11+
from adafruit_pcf8523.clock import Clock
12+
13+
LOW_FREQ_TIMER = 10
14+
HIGH_FREQ_TIMER = 0.02
15+
HIGH_FREQ_TIME = 10
16+
PIN_INT = board.GP5
17+
PIN_SDA = board.GP2
18+
PIN_SCL = board.GP3
19+
# use board.SCL and board.SDA if available
20+
21+
i2c = busio.I2C(PIN_SCL, PIN_SDA)
22+
# or i2c = board.I2C() if available
23+
timer = Timer(i2c)
24+
clock = Clock(timer.i2c_device)
25+
clock.clockout_frequency = clock.CLOCKOUT_FREQ_DISABLED
26+
27+
# interrupt pin
28+
intpin = DigitalInOut(PIN_INT)
29+
intpin.direction = Direction.INPUT
30+
intpin.pull = Pull.UP
31+
32+
# Main loop:
33+
timer.pulsed = False
34+
timer.timer_interrupt = True
35+
while True:
36+
print("low-frequency timer: checking interrupt")
37+
timer.timer_enabled = False
38+
timer.timer_status = False
39+
timer.timer_frequency = timer.TIMER_FREQ_1HZ
40+
timer.timer_value = LOW_FREQ_TIMER
41+
start = time.monotonic()
42+
timer.timer_enabled = True
43+
while intpin.value and time.monotonic() - start < LOW_FREQ_TIMER + 1:
44+
pass
45+
if intpin.value:
46+
# shoud not happen!
47+
print(f"error: timer did not fire within {LOW_FREQ_TIMER+1} seconds!")
48+
else:
49+
elapsed = time.monotonic() - start
50+
print(f"elapsed: {elapsed}")
51+
52+
print("high-frequency timer: checking interrupt")
53+
timer.timer_enabled = False
54+
timer.timer_status = False
55+
timer.timer_frequency = timer.TIMER_FREQ_4KHZ
56+
timer.timer_value = min(round(HIGH_FREQ_TIMER * 4096), 255)
57+
counter = 0
58+
start = time.monotonic()
59+
end = start + HIGH_FREQ_TIME
60+
timer.timer_enabled = True
61+
while time.monotonic() < end:
62+
if intpin.value:
63+
continue
64+
timer.timer_status = False
65+
counter += 1
66+
if counter > 0:
67+
mean_interval = (time.monotonic() - start) / counter
68+
print(f"interval requested: {HIGH_FREQ_TIMER}")
69+
print(f"interval observed: {mean_interval} (mean of {counter} alarms)")
70+
else:
71+
print(f"error: timer did not fire within {HIGH_FREQ_TIME} seconds!")
72+
print("error: timer did not fire")

‎pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ classifiers = [
4242
dynamic = ["dependencies", "optional-dependencies"]
4343

4444
[tool.setuptools]
45-
py-modules = ["adafruit_pcf8523"]
45+
packages = ["adafruit_pcf8523"]
4646

4747
[tool.setuptools.dynamic]
4848
dependencies = {file = ["requirements.txt"]}

0 commit comments

Comments
 (0)
Please sign in to comment.