Skip to content

Commit

Permalink
Merge pull request #11 from tekktrik/doc/add-typing
Browse files Browse the repository at this point in the history
Add typing and other tweaks
  • Loading branch information
FoamyGuy committed Jan 24, 2022
2 parents c5275bd + 62aff88 commit b710d97
Showing 1 changed file with 63 additions and 21 deletions.
84 changes: 63 additions & 21 deletions adafruit_24lc32.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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
Expand All @@ -55,35 +72,39 @@ 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.
"""
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)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -176,43 +203,58 @@ 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,
)

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
with self._i2c as i2c:
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
Expand Down Expand Up @@ -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:
Expand Down

0 comments on commit b710d97

Please sign in to comment.