X-Git-Url: https://git.ayoreis.com/hackapet/Adafruit_Blinka_Displayio.git/blobdiff_plain/138d74a3457378ca0f684654f7cc4d6b8ce0301a..6cac6de7a1ed297eaf22b03e1512cdf347146a62:/displayio/i2cdisplay.py diff --git a/displayio/i2cdisplay.py b/displayio/i2cdisplay.py index 21fa371..409e0a5 100644 --- a/displayio/i2cdisplay.py +++ b/displayio/i2cdisplay.py @@ -1,24 +1,9 @@ -# The MIT License (MIT) +# SPDX-FileCopyrightText: 2020 Melissa LeBlanc-Williams for Adafruit Industries +# SPDX-FileCopyrightText: 2020 Erik Tollerud +# SPDX-FileCopyrightText: 2021 Jim Morris +# SPDX-FileCopyrightText: 2021 James Carr # -# Copyright (c) 2020 Melissa LeBlanc-Williams for Adafruit Industries -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice shall be included in -# all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -# THE SOFTWARE. +# SPDX-License-Identifier: MIT """ `displayio.i2cdisplay` @@ -31,14 +16,23 @@ 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 """ __version__ = "0.0.0-auto.0" __repo__ = "https://github.com/adafruit/Adafruit_Blinka_displayio.git" -# pylint: disable=unnecessary-pass, unused-argument + +import time +import busio +import digitalio +import microcontroller + +try: + from typing import Optional +except ImportError: + pass class I2CDisplay: @@ -46,7 +40,13 @@ class I2CDisplay: It doesn’t handle display initialization. """ - def __init__(self, i2c_bus, *, device_address, reset=None): + 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 @@ -55,17 +55,68 @@ 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. """ - pass + 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, *, toggle_every_byte=False) -> None: + # pylint: disable=unused-argument + """ + 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. """ - pass + # NOTE: we have to have a toggle_every_byte parameter, which we ignore, + # because Display._write() sets it regardless of bus type. + + 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()