class DS3231: """Interface to the DS3231 RTC.""" lost_power = i2c_bit.RWBit(0x0f, 7) """True if the device has lost power since the time was set.""" disable_oscillator = i2c_bit.RWBit(0x0e, 7) """True if the oscillator is disabled.""" datetime_register = i2c_bcd_datetime.BCDDateTimeRegister(0x00) """Current date and time.""" alarm1 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x07) """Alarm time for the first alarm.""" alarm1_interrupt = i2c_bit.RWBit(0x0e, 0) """True if the interrupt pin will output when alarm1 is alarming.""" alarm1_status = i2c_bit.RWBit(0x0f, 0) """True if alarm1 is alarming. Set to False to reset.""" alarm2 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x0b, has_seconds=False) """Alarm time for the second alarm.""" alarm2_interrupt = i2c_bit.RWBit(0x0e, 1) """True if the interrupt pin will output when alarm2 is alarming.""" alarm2_status = i2c_bit.RWBit(0x0f, 1) """True if alarm2 is alarming. Set to False to reset.""" def __init__(self, i2c): self.i2c_device = I2CDevice(i2c, 0x68) # Try and verify this is the RTC we expect by checking the rate select # control bits which are 1 on reset and shouldn't ever be changed. buf = bytearray(2) buf[0] = 0x0e with self.i2c_device as i2c_device: i2c_device.write(buf, end=1, stop=False) i2c_device.readinto(buf, start=1) if (buf[1] & 0b00011000) != 0b00011000: raise ValueError("Unable to find DS3231 at i2c address 0x68.") @property def datetime(self): """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): self.datetime_register = value self.disable_oscillator = False self.lost_power = False
class DS3231: """Interface to the DS3231 RTC.""" lost_power = i2c_bit.RWBit(0x0F, 7) """True if the device has lost power since the time was set.""" disable_oscillator = i2c_bit.RWBit(0x0E, 7) """True if the oscillator is disabled.""" datetime_register = i2c_bcd_datetime.BCDDateTimeRegister(0x00) """Current date and time.""" alarm1 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x07) """Alarm time for the first alarm.""" alarm1_interrupt = i2c_bit.RWBit(0x0E, 0) """True if the interrupt pin will output when alarm1 is alarming.""" alarm1_status = i2c_bit.RWBit(0x0F, 0) """True if alarm1 is alarming. Set to False to reset.""" alarm2 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x0B, has_seconds=False) """Alarm time for the second alarm.""" alarm2_interrupt = i2c_bit.RWBit(0x0E, 1) """True if the interrupt pin will output when alarm2 is alarming.""" alarm2_status = i2c_bit.RWBit(0x0F, 1) """True if alarm2 is alarming. Set to False to reset.""" def __init__(self, i2c): self.i2c_device = I2CDevice(i2c, 0x68) @property def datetime(self): """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): self.datetime_register = value self.disable_oscillator = False self.lost_power = False
class PCF8523: """Interface to the PCF8523 RTC.""" 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 (0b000).""" # 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.""" 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.""" def __init__(self, i2c_bus): self.i2c_device = I2CDevice(i2c_bus, 0x68) # Try and verify this is the RTC we expect by checking the timer B # frequency control bits which are 1 on reset and shouldn't ever be # changed. buf = bytearray(2) buf[0] = 0x12 with self.i2c_device as i2c: i2c.write(buf, end=1, stop=False) i2c.readinto(buf, start=1) if (buf[1] & 0b00000111) != 0b00000111: raise ValueError("Unable to find PCF8523 at i2c address 0x68.") @property def datetime(self): """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): # Automatically sets lost_power to false. self.power_management = STANDARD_BATTERY_SWITCHOVER_AND_DETECTION self.datetime_register = value
class DS3231: """Interface to the DS3231 RTC.""" lost_power = i2c_bit.RWBit(0x0F, 7) """True if the device has lost power since the time was set.""" disable_oscillator = i2c_bit.RWBit(0x0E, 7) """True if the oscillator is disabled.""" datetime_register = i2c_bcd_datetime.BCDDateTimeRegister(0x00) """Current date and time.""" alarm1 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x07) """Alarm time for the first alarm.""" alarm1_interrupt = i2c_bit.RWBit(0x0E, 0) """True if the interrupt pin will output when alarm1 is alarming.""" alarm1_status = i2c_bit.RWBit(0x0F, 0) """True if alarm1 is alarming. Set to False to reset.""" alarm2 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x0B, has_seconds=False) """Alarm time for the second alarm.""" alarm2_interrupt = i2c_bit.RWBit(0x0E, 1) """True if the interrupt pin will output when alarm2 is alarming.""" alarm2_status = i2c_bit.RWBit(0x0F, 1) """True if alarm2 is alarming. Set to False to reset.""" _calibration = i2c_bits.RWBits(8, 0x10, 0, 8, signed=True) _temperature = i2c_bits.RWBits( 10, 0x11, 6, register_width=2, lsb_first=False, signed=True ) _busy = i2c_bit.ROBit(0x0F, 2) _conv = i2c_bit.RWBit(0x0E, 5) def __init__(self, i2c): self.i2c_device = I2CDevice(i2c, 0x68) @property def datetime(self): """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): self.datetime_register = value self.disable_oscillator = False self.lost_power = False @property def temperature(self): """Returns the last temperature measurement. Temperature is updated only every 64 seconds, or when a conversion is forced.""" return self._temperature / 4 def force_temperature_conversion(self): """Forces a conversion and returns the new temperature""" while self._busy: pass # Wait for any normal in-progress conversion to complete self._conv = True while self._conv: pass # Wait for manual conversion request to complete return self.temperature @property def calibration(self): """Calibrate the frequency of the crystal oscillator by adding or removing capacitance. The datasheet calls this the Aging Offset. Calibration values range from -128 to 127; each step is approximately 0.1ppm, and positive values decrease the frequency (increase the period). When set, a temperature conversion is forced so the result of calibration can be seen directly at the 32kHz pin immediately""" return self._calibration @calibration.setter def calibration(self, value): self._calibration = value self.force_temperature_conversion()
class PCF8523: """Interface to the PCF8523 RTC.""" 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 (0b000).""" # 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.""" 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(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): self.i2c_device = I2CDevice(i2c_bus, 0x68) # Try and verify this is the RTC we expect by checking the timer B # frequency control bits which are 1 on reset and shouldn't ever be # changed. buf = bytearray(2) buf[0] = 0x12 with self.i2c_device as i2c: i2c.write_then_readinto(buf, buf, out_end=1, in_start=1) if (buf[1] & 0b00000111) != 0b00000111: raise ValueError("Unable to find PCF8523 at i2c address 0x68.") @property def datetime(self): """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): # Automatically sets lost_power to false. self.power_management = STANDARD_BATTERY_SWITCHOVER_AND_DETECTION self.datetime_register = value
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 (0b000).""" # 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.""" 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) # Try and verify this is the RTC we expect by checking the timer B # frequency control bits which are 1 on reset and shouldn't ever be # changed. buf = bytearray(2) buf[0] = 0x12 with self.i2c_device as i2c: i2c.write_then_readinto(buf, buf, out_end=1, in_start=1) if (buf[1] & 0b00000111) != 0b00000111: raise ValueError("Unable to find PCF8523 at i2c address 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
class DS3231: """Interface to the DS3231 RTC. :param ~busio.I2C i2c: The I2C bus the device is connected to **Quickstart: Importing and using the device** Here is an example of using the :class:`DS3231` class. First you will need to import the libraries to use the sensor .. code-block:: python import time import board import adafruit_ds3231 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_ds3231.DS3231(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(0x0F, 7) """True if the device has lost power since the time was set.""" disable_oscillator = i2c_bit.RWBit(0x0E, 7) """True if the oscillator is disabled.""" datetime_register = i2c_bcd_datetime.BCDDateTimeRegister(0x00) """Current date and time.""" alarm1 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x07) """Alarm time for the first alarm.""" alarm1_interrupt = i2c_bit.RWBit(0x0E, 0) """True if the interrupt pin will output when alarm1 is alarming.""" alarm1_status = i2c_bit.RWBit(0x0F, 0) """True if alarm1 is alarming. Set to False to reset.""" alarm2 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x0B, has_seconds=False) """Alarm time for the second alarm.""" alarm2_interrupt = i2c_bit.RWBit(0x0E, 1) """True if the interrupt pin will output when alarm2 is alarming.""" alarm2_status = i2c_bit.RWBit(0x0F, 1) """True if alarm2 is alarming. Set to False to reset.""" # pylint: disable=unexpected-keyword-arg _calibration = i2c_bits.RWBits(8, 0x10, 0, 1, signed=True) _temperature = i2c_bits.RWBits( 10, 0x11, 6, register_width=2, lsb_first=False, signed=True ) # pylint: enable=unexpected-keyword-arg _busy = i2c_bit.ROBit(0x0F, 2) _conv = i2c_bit.RWBit(0x0E, 5) def __init__(self, i2c: I2C) -> None: self.i2c_device = I2CDevice(i2c, 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) -> None: self.datetime_register = value self.disable_oscillator = False self.lost_power = False @property def temperature(self) -> float: """Returns the last temperature measurement. Temperature is updated only every 64 seconds, or when a conversion is forced.""" return self._temperature / 4 def force_temperature_conversion(self) -> float: """Forces a conversion and returns the new temperature""" while self._busy: pass # Wait for any normal in-progress conversion to complete self._conv = True while self._conv: pass # Wait for manual conversion request to complete return self.temperature @property def calibration(self) -> int: """Calibrate the frequency of the crystal oscillator by adding or removing capacitance. The datasheet calls this the Aging Offset. Calibration values range from -128 to 127; each step is approximately 0.1ppm, and positive values decrease the frequency (increase the period). When set, a temperature conversion is forced so the result of calibration can be seen directly at the 32kHz pin immediately""" return self._calibration @calibration.setter def calibration(self, value: int) -> None: self._calibration = value self.force_temperature_conversion()
class PCF8523: """Interface to the PCF8523 RTC.""" lost_power = i2c_bit.RWBit(0x03, 7) """True if the device has lost power since the time was set.""" disable_oscillator = i2c_bit.RWBit(0x00, 5) """True if the oscillator is disabled.""" _square_wave_control = i2c_bits.RWBits(3, 0x0F, 3) """reg 0x0F, bits 3:5 identify the square wave frequency""" _r13b0 = i2c_bit.ROBit(0x13, 0) """reg 0x13, bit 0 used to distinguish ds3231""" _r3fb0 = i2c_bit.RWBit(0x3f, 0) """reg 0x3f, bit 0 used to distinguish between ds1307 and pcf8523""" 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.""" 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): self.i2c_device = I2CDevice(i2c_bus, 0x68) chip = self.chip_identity expected = self.__class__.__name__ if chip != expected: raise RuntimeError( 'Expected {}, found {} at i2c address 0x68'.format( expected, chip)) @property def chip_identity(self): """identify the RTC chip (distinguishes among DS1307, PCF8523 and DS3231)""" try: r13b0 = self._r13b0 except OSError: return 'DS3231' else: r3fb0 = self._r3fb0 self._r3fb0 = not r3fb0 if r3fb0 != self._r3fb0: self._r3fb0 = r3fb0 return 'DS1307' return 'PCF8523' @property def datetime(self): """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): # Required to enable switching to battery self.power_management = STANDARD_BATTERY_SWITCHOVER_AND_DETECTION # Automatically sets lost_power to false. self.datetime_register = value self.disable_oscillator = False @property def square_wave_frequency(self): """Return the square wave frequency, 0 if not enabled""" value = self._square_wave_control freqs = (1, 32, 1024, 4096, 8192, 16384, 32768, 0) return freqs[value] @square_wave_frequency.setter def square_wave_frequency(self, frequency): available_frequencies = { 0: 7, 1: 6, 32: 5, 1024: 4, 4096: 3, 8192: 2, 16384: 1, 32768: 0 } try: code = available_frequencies[frequency] self._square_wave_control = code except KeyError: raise ValueError( 'square wave frequency {} not available'.format(frequency))
class DS3231: """Interface to the DS3231 RTC.""" lost_power = i2c_bit.RWBit(0x0F, 7) """True if the device has lost power since the time was set.""" disable_oscillator = i2c_bit.RWBit(0x0E, 7) """True if the oscillator is disabled.""" datetime_register = i2c_bcd_datetime.BCDDateTimeRegister(0x00) """Current date and time.""" alarm1 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x07) """Alarm time for the first alarm.""" alarm1_interrupt = i2c_bit.RWBit(0x0E, 0) """True if the interrupt pin will output when alarm1 is alarming.""" alarm1_status = i2c_bit.RWBit(0x0F, 0) """True if alarm1 is alarming. Set to False to reset.""" alarm2 = i2c_bcd_alarm.BCDAlarmTimeRegister(0x0B, has_seconds=False) """Alarm time for the second alarm.""" alarm2_interrupt = i2c_bit.RWBit(0x0E, 1) """True if the interrupt pin will output when alarm2 is alarming.""" alarm2_status = i2c_bit.RWBit(0x0F, 1) """True if alarm2 is alarming. Set to False to reset.""" _square_wave_control = i2c_bits.RWBits(3, 0x0E, 2) """reg 0x0e, bits 3:4 identify the square wave frequency, bit 2 is disable""" _r13b0 = i2c_bit.ROBit(0x13, 0) """reg 0x13, bit 0 used to distinguish ds3231""" _r3fb0 = i2c_bit.RWBit(0x3f, 0) """reg 0x3f, bit 0 used to distinguish between ds1307 and pcf8523""" # pylint: disable=unexpected-keyword-arg _calibration = i2c_bits.RWBits(8, 0x10, 0, 1, signed=True) _temperature = i2c_bits.RWBits( 10, 0x11, 6, register_width=2, lsb_first=False, signed=True ) # pylint: enable=unexpected-keyword-arg _busy = i2c_bit.ROBit(0x0F, 2) _conv = i2c_bit.RWBit(0x0E, 5) def __init__(self, i2c): self.i2c_device = I2CDevice(i2c, 0x68) chip = self.chip_identity expected = self.__class__.__name__ if chip != expected: raise RuntimeError('Expected {}, found {}'.format(expected, chip)) @property def chip_identity(self): """identify the RTC chip (distinguishes among DS1307, PCF8523 and DS3231)""" try: r13b0 = self._r13b0 except OSError: return 'DS3231' else: r3fb0 = self._r3fb0 self._r3fb0 = not r3fb0 if r3fb0 != self._r3fb0: self._r3fb0 = r3fb0 return 'DS1307' return 'PCF8523' @property def datetime(self): """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): self.datetime_register = value self.disable_oscillator = False self.lost_power = False @property def temperature(self): """Returns the last temperature measurement. Temperature is updated only every 64 seconds, or when a conversion is forced.""" return self._temperature / 4 def force_temperature_conversion(self): """Forces a conversion and returns the new temperature""" while self._busy: pass # Wait for any normal in-progress conversion to complete self._conv = True while self._conv: pass # Wait for manual conversion request to complete return self.temperature @property def square_wave_frequency(self): """Return the square wave frequency, 0 if not enabled""" value = self._square_wave_control freqs = (1, 0, 1024, 0, 4096, 0, 8192, 0) return freqs[value] @square_wave_frequency.setter def square_wave_frequency(self, frequency): available_frequencies = {0: 1, 1: 0, 1024: 2, 4096: 4, 8192: 6} try: code = available_frequencies[frequency] self._square_wave_control = code except KeyError: raise ValueError('square wave frequency {} not available'.format(frequency)) @property def calibration(self): """Calibrate the frequency of the crystal oscillator by adding or removing capacitance. The datasheet calls this the Aging Offset. Calibration values range from -128 to 127; each step is approximately 0.1ppm, and positive values decrease the frequency (increase the period). When set, a temperature conversion is forced so the result of calibration can be seen directly at the 32kHz pin immediately""" return self._calibration @calibration.setter def calibration(self, value): self._calibration = value self.force_temperature_conversion()