|
| 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) |
0 commit comments