From: James Carr Date: Thu, 22 Apr 2021 14:01:04 +0000 (+0100) Subject: Initial implementation of I2CDisplay. (Closes #2) X-Git-Tag: 0.6.0^2~5 X-Git-Url: https://git.ayoreis.com/hackapet/Adafruit_Blinka_Displayio.git/commitdiff_plain/94342b1947ee2913c581317d280d9dab4e85f374?ds=inline;hp=--cc Initial implementation of I2CDisplay. (Closes #2) This is based on the work of: * @eteq https://github.com/adafruit/Adafruit_Blinka_Displayio/pull/41 * @wolfmanjm https://github.com/adafruit/Adafruit_Blinka_Displayio/pull/41#issuecomment-804889522 --- 94342b1947ee2913c581317d280d9dab4e85f374 diff --git a/displayio/i2cdisplay.py b/displayio/i2cdisplay.py index fd498a7..238f98d 100644 --- a/displayio/i2cdisplay.py +++ b/displayio/i2cdisplay.py @@ -1,4 +1,7 @@ # SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries +# SPDX-FileCopyrightText: 2020 Erik Tollerud +# SPDX-FileCopyrightText: 2021 Jim Morris +# SPDX-FileCopyrightText: 2021 James Carr # # SPDX-License-Identifier: MIT @@ -13,7 +16,7 @@ displayio for Blinka * Adafruit Blinka: https://github.com/adafruit/Adafruit_Blinka/releases -* Author(s): Melissa LeBlanc-Williams +* Author(s): Melissa LeBlanc-Williams, Erik Tollerud, James Carr """ @@ -21,13 +24,30 @@ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_Blinka_displayio.git" +import time +import busio +import digitalio +import microcontroller + +try: + from typing import Optional + from typing import ReadableBuffer +except ImportError: + pass + + class I2CDisplay: """Manage updating a display over I2C in the background while Python code runs. It doesn’t handle display initialization. """ - def __init__(self, i2c_bus, *, device_address, reset=None): - # pylint: disable=unnecessary-pass + def __init__( + self, + i2c_bus: busio.I2C, + *, + device_address: int, + reset: Optional[microcontroller.Pin] = None + ): """Create a I2CDisplay object associated with the given I2C bus and reset pin. The I2C bus and pins are then in use by the display until displayio.release_displays() is @@ -36,17 +56,65 @@ class I2CDisplay: :py:func`displayio.release_displays` first, otherwise it will error after the first code.py run. """ - pass - def reset(self): - """Performs a hardware reset via the reset pin. Raises an exception if called - when no reset pin is available. + if reset is not None: + self._reset = digitalio.DigitalInOut(reset) + self._reset.switch_to_output(value=True) + else: + self._reset = None + self._i2c = i2c_bus + self._dev_addr = device_address + + def _release(self): + self.reset() + self._i2c.deinit() + if self._reset is not None: + self._reset.deinit() + + def reset(self) -> None: + """ + Performs a hardware reset via the reset pin if one is present. + """ + + if self._reset is None: + return + + self._reset.value = False + time.sleep(0.0001) + self._reset.value = True + + def begin_transaction(self) -> None: + """ + Lock the bus before sending data. """ - raise NotImplementedError("I2CDisplay reset has not been implemented yet") + while not self._i2c.try_lock(): + pass - def send(self, command, data): - """Sends the given command value followed by the full set of data. Display state, - such as vertical scroll, set via send may or may not be reset once the code is + def send(self, command: bool, data: ReadableBuffer) -> None: + """ + Sends the given command value followed by the full set of data. Display state, + such as vertical scroll, set via ``send`` may or may not be reset once the code is done. """ - raise NotImplementedError("I2CDisplay send has not been implemented yet") + + if command: + n = len(data) + if n > 0: + command_bytes = bytearray(n * 2) + for i in range(n): + command_bytes[2 * i] = 0x80 + command_bytes[2 * i + 1] = data[i] + + self._i2c.writeto(self._dev_addr, buffer=command_bytes, stop=True) + + else: + data_bytes = bytearray(len(data) + 1) + data_bytes[0] = 0x40 + data_bytes[1:] = data + self._i2c.writeto(self._dev_addr, buffer=data_bytes, stop=True) + + def end_transaction(self) -> None: + """ + Release the bus after sending data. + """ + self._i2c.unlock()