Skip to content
Closed
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 16 additions & 4 deletions adafruit_bus_device/i2c_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
`adafruit_bus_device.i2c_device` - I2C Bus Device
====================================================
"""
import time

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BusDevice.git"
Expand All @@ -37,6 +38,9 @@ class I2CDevice:
:param ~busio.I2C i2c: The I2C bus the device is on
:param int device_address: The 7 bit device address
:param bool probe: Probe for the device upon object creation, default is true
:param int timeout: the amount of time (in milliseconds) to wait before timing out when trying
to lock, defaults to 250 milliseconds. to disable any timeout set 'timeout=None'.
if the lock times out a RuntimeError will be raised

.. note:: This class is **NOT** built into CircuitPython. See
:ref:`here for install instructions <bus_device_installation>`.
Expand All @@ -59,12 +63,14 @@ class I2CDevice:
device.write(bytes_read)
"""

def __init__(self, i2c, device_address, probe=True):
def __init__(self, i2c, device_address, probe=True, timeout=250):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please go back to floating point seconds. We are trying to be uniform and always use float seconds.


self.i2c = i2c
self._has_write_read = hasattr(self.i2c, "writeto_then_readfrom")
self.device_address = device_address

self.timeout = timeout

if probe:
self.__probe_for_device()

Expand Down Expand Up @@ -113,7 +119,7 @@ def write_then_readinto(
out_end=None,
in_start=0,
in_end=None,
stop=False
stop=False,
):
"""
Write the bytes from ``out_buffer`` to the device, then immediately
Expand Down Expand Up @@ -164,8 +170,14 @@ def write_then_readinto(
# pylint: enable-msg=too-many-arguments

def __enter__(self):
while not self.i2c.try_lock():
pass
if self.timeout is not None:
lock_start_time = time.monotonic_ns()//1000000
while not self.i2c.try_lock():
if self.timeout > (time.monotonic() - lock_start_time):
raise RuntimeError(f"'SPIDevice' lock timed out after {self.timeout} milliseconds")
else:
while not self.i2c.try_lock():
pass
return self

def __exit__(self, exc_type, exc_val, exc_tb):
Expand Down
22 changes: 17 additions & 5 deletions adafruit_bus_device/spi_device.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
`adafruit_bus_device.spi_device` - SPI Bus Device
====================================================
"""
import time

__version__ = "0.0.0-auto.0"
__repo__ = "https://github.com/adafruit/Adafruit_CircuitPython_BusDevice.git"
Expand All @@ -40,6 +41,8 @@ class SPIDevice:
DigitalInOut API.
:param int extra_clocks: The minimum number of clock cycles to cycle the bus after CS is high.
(Used for SD cards.)
:param int timeout: the amount of time (in milliseconds) to wait before timing out when trying
to lock, defaults to 250 milliseconds. to disable any timeout set 'timeout=None'.

.. note:: This class is **NOT** built into CircuitPython. See
:ref:`here for install instructions <bus_device_installation>`.
Expand Down Expand Up @@ -75,29 +78,38 @@ def __init__(
baudrate=100000,
polarity=0,
phase=0,
extra_clocks=0
extra_clocks=0,
timeout=250,
):
self.spi = spi
self.baudrate = baudrate
self.polarity = polarity
self.phase = phase
self.extra_clocks = extra_clocks
self.chip_select = chip_select
self.timeout = timeout
if self.chip_select:
self.chip_select.switch_to_output(value=True)

def __enter__(self):
while not self.spi.try_lock():
pass
if self.timeout is not None:
lock_start_time = time.monotonic_ns()//1000000
while not self.spi.try_lock():
if self.timeout > (time.monotonic() - lock_start_time):
raise RuntimeError(f"'SPIDevice' lock timed out after {self.timeout} milliseconds")
else:
while not self.spi.try_lock():
pass

self.spi.configure(
baudrate=self.baudrate, polarity=self.polarity, phase=self.phase
)
if self.chip_select:
if self.chip_select is not None:
self.chip_select.value = False
return self.spi

def __exit__(self, exc_type, exc_val, exc_tb):
if self.chip_select:
if self.chip_select is not None:
self.chip_select.value = True
if self.extra_clocks > 0:
buf = bytearray(1)
Expand Down