diff --git a/adafruit_24lc32.py b/adafruit_24lc32.py index dda7ad3..3e78369 100644 --- a/adafruit_24lc32.py +++ b/adafruit_24lc32.py @@ -31,6 +31,13 @@ import time from micropython import const +try: + from typing import Optional, Union, Sequence + from digitalio import DigitalInOut + from busio import I2C +except ImportError: + pass + __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_24LC32.git" @@ -40,9 +47,19 @@ class EEPROM: """ Driver base for the EEPROM Breakout. + + :param int max_size: The maximum size of the EEPROM + :param bool write_protect: Turns on/off initial write protection + :param DigitalInOut wp_pin: (Optional) Physical pin connected to the ``WP`` breakout pin. + Must be a ``DigitalInOut`` object. """ - def __init__(self, max_size, write_protect=False, wp_pin=None): + def __init__( + self, + max_size: int, + write_protect: bool = False, + wp_pin: Optional[DigitalInOut] = None, + ) -> None: self._max_size = max_size self._wp = write_protect self._wraparound = False @@ -55,7 +72,7 @@ def __init__(self, max_size, write_protect=False, wp_pin=None): self._wp_pin = wp_pin @property - def write_wraparound(self): + def write_wraparound(self) -> bool: """Determines if sequential writes will wrapaound highest memory address (``len(EEPROM) - 1``) address. If ``False``, and a requested write will extend beyond the maximum size, an exception is raised. @@ -63,27 +80,31 @@ def write_wraparound(self): return self._wraparound @write_wraparound.setter - def write_wraparound(self, value): - if not value in (True, False): + def write_wraparound(self, value: bool) -> None: + if not isinstance(value, bool): raise ValueError("Write wraparound must be 'True' or 'False'.") self._wraparound = value @property - def write_protected(self): + def write_protected(self) -> bool: """The status of write protection. Default value on initialization is ``False``. + When a ``WP`` pin is supplied during initialization, or using ``write_protect_pin``, the status is tied to that pin and enables hardware-level protection. + When no ``WP`` pin is supplied, protection is only at the software level in this library. """ return self._wp if self._wp_pin is None else self._wp_pin.value - def __len__(self): + def __len__(self) -> int: """The size of the current EEPROM chip. This is one more than the highest address location that can be read or written to. + .. code-block:: python + eeprom = adafruit_24lc32.EEPROM_I2C() # size returned by len() len(eeprom) @@ -92,9 +113,11 @@ def __len__(self): """ return self._max_size - def __getitem__(self, address): + def __getitem__(self, address: Union[int, slice]) -> bytearray: """Read the value at the given index, or values in a slice. + .. code-block:: python + # read single index eeprom[0] # read values 0 thru 9 with a slice @@ -130,9 +153,13 @@ def __getitem__(self, address): return read_buffer - def __setitem__(self, address, value): + def __setitem__( + self, address: Union[int, slice], value: Union[int, Sequence[int]] + ) -> None: """Write the value at the given starting index. + .. code-block:: python + # write single index eeprom[0] = 1 # write values 0 thru 4 with a list @@ -176,27 +203,36 @@ def __setitem__(self, address, value): self._write(address.start, value, self._wraparound) - def _read_address(self, address, read_buffer): + def _read_address(self, address: int, read_buffer: bytearray) -> bytearray: # Implemented by subclass raise NotImplementedError - def _write(self, start_address, data, wraparound): + def _write( + self, start_address: int, data: Union[int, Sequence[int]], wraparound: bool + ) -> None: # Implemened by subclass raise NotImplementedError class EEPROM_I2C(EEPROM): """I2C class for EEPROM. - :param: ~busio.I2C i2c_bus: The I2C bus the EEPROM is connected to. - :param: int address: I2C address of EEPROM. Default address is ``0x50``. - :param: bool write_protect: Turns on/off initial write protection. - Default is ``False``. - :param: wp_pin: (Optional) Physical pin connected to the ``WP`` breakout pin. - Must be a ``digitalio.DigitalInOut`` object. + + :param ~busio.I2C i2c_bus: The I2C bus the EEPROM is connected to. + :param int address: I2C address of EEPROM. Default address is ``0x50``. + :param bool write_protect: Turns on/off initial write protection. + Default is ``False``. + :param wp_pin: (Optional) Physical pin connected to the ``WP`` breakout pin. + Must be a ``DigitalInOut`` object. """ # pylint: disable=too-many-arguments - def __init__(self, i2c_bus, address=0x50, write_protect=False, wp_pin=None): + def __init__( + self, + i2c_bus: I2C, + address: int = 0x50, + write_protect: bool = False, + wp_pin: Optional[DigitalInOut] = None, + ) -> None: from adafruit_bus_device.i2c_device import ( # pylint: disable=import-outside-toplevel I2CDevice as i2cdev, ) @@ -204,7 +240,7 @@ def __init__(self, i2c_bus, address=0x50, write_protect=False, wp_pin=None): self._i2c = i2cdev(i2c_bus, address) super().__init__(_MAX_SIZE_I2C, write_protect, wp_pin) - def _read_address(self, address, read_buffer): + def _read_address(self, address: int, read_buffer: bytearray) -> bytearray: write_buffer = bytearray(2) write_buffer[0] = address >> 8 write_buffer[1] = address & 0xFF @@ -212,7 +248,13 @@ def _read_address(self, address, read_buffer): i2c.write_then_readinto(write_buffer, read_buffer) return read_buffer - def _write(self, start_address, data, wraparound=False): + def _write( + self, + start_address: int, + data: Union[int, Sequence[int]], + wraparound: bool = False, + ) -> None: + # Decided against using the chip's "Page Write", since that would require # doubling the memory usage by creating a buffer that includes the passed # in data so that it can be sent all in one `i2c.write`. The single-write @@ -248,8 +290,8 @@ def _write(self, start_address, data, wraparound=False): # pylint: disable=no-member @EEPROM.write_protected.setter - def write_protected(self, value): - if value not in (True, False): + def write_protected(self, value: bool) -> None: + if not isinstance(value, bool): raise ValueError("Write protected value must be 'True' or 'False'.") self._wp = value if not self._wp_pin is None: