]> Repositories - hackapet/Adafruit_Blinka_Displayio.git/commitdiff
Update begin_transaction
authorMelissa LeBlanc-Williams <melissa@adafruit.com>
Wed, 27 Sep 2023 21:07:29 +0000 (14:07 -0700)
committerMelissa LeBlanc-Williams <melissa@adafruit.com>
Wed, 27 Sep 2023 21:07:29 +0000 (14:07 -0700)
displayio/_constants.py
displayio/_display.py
displayio/_displaycore.py
displayio/_fourwire.py
displayio/_i2cdisplay.py
paralleldisplay.py

index d255dbf4c804cc516bd261ddc23f644131e24b3c..19ecd0f9605b42cc10779f4417038adf0bfb0917 100644 (file)
@@ -21,3 +21,5 @@ BACKLIGHT_PWM = 2
 
 NO_COMMAND = 0x100
 CIRCUITPY_DISPLAY_LIMIT = 1
+
+DELAY = 0x80
index 3f6d7b68d10886be92063abdee51e4205095a2fd..7bfe532b4d0f2c6b55ab26b40f1baeca937da762 100644 (file)
@@ -36,6 +36,7 @@ from ._constants import (
     BACKLIGHT_IN_OUT,
     BACKLIGHT_PWM,
     NO_COMMAND,
+    DELAY,
 )
 
 __version__ = "0.0.0+auto.0"
@@ -43,7 +44,7 @@ __repo__ = "https://github.com/adafruit/Adafruit_Blinka_displayio.git"
 
 
 class Display:
-    # pylint: disable=too-many-instance-attributes
+    # pylint: disable=too-many-instance-attributes, too-many-statements
     """This initializes a display and connects it into CircuitPython. Unlike other objects
     in CircuitPython, Display objects live until ``displayio.release_displays()`` is called.
     This is done so that CircuitPython can use the display itself.
@@ -155,7 +156,42 @@ class Display:
         self._brightness = brightness
         self._auto_refresh = auto_refresh
 
-        self._initialize(init_sequence)
+        i = 0
+        while i < len(init_sequence):
+            command = init_sequence[i]
+            data_size = init_sequence[i + 1]
+            delay = (data_size & DELAY) != 0
+            data_size &= ~DELAY
+            while self._core.begin_transaction():
+                pass
+
+            if self._core.data_as_commands:
+                full_command = bytearray(data_size + 1)
+                full_command[0] = command
+                full_command[1:] = init_sequence[i + 2 : i + 2 + data_size]
+                self._core.send(
+                    DISPLAY_COMMAND,
+                    CHIP_SELECT_TOGGLE_EVERY_BYTE,
+                    full_command,
+                )
+            else:
+                self._core.send(
+                    DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, bytes([command])
+                )
+                self._core.send(
+                    DISPLAY_DATA,
+                    CHIP_SELECT_UNTOUCHED,
+                    init_sequence[i + 2 : i + 2 + data_size],
+                )
+            self._core.end_transaction()
+            delay_time_ms = 10
+            if delay:
+                data_size += 1
+                delay_time_ms = init_sequence[i + 1 + data_size]
+                if delay_time_ms == 255:
+                    delay_time_ms = 500
+            time.sleep(delay_time_ms / 1000)
+            i += 2 + data_size
 
         self._current_group = None
         self._last_refresh_call = 0
@@ -191,38 +227,6 @@ class Display:
         allocate_display(display_instance)
         return display_instance
 
-    def _initialize(self, init_sequence):
-        i = 0
-        while i < len(init_sequence):
-            command = init_sequence[i]
-            data_size = init_sequence[i + 1]
-            delay = (data_size & 0x80) > 0
-            data_size &= ~0x80
-
-            if self._core.data_as_commands:
-                self._core.send(
-                    DISPLAY_COMMAND,
-                    CHIP_SELECT_TOGGLE_EVERY_BYTE,
-                    bytes([command]) + init_sequence[i + 2 : i + 2 + data_size],
-                )
-            else:
-                self._core.send(
-                    DISPLAY_COMMAND, CHIP_SELECT_TOGGLE_EVERY_BYTE, bytes([command])
-                )
-                self._core.send(
-                    DISPLAY_DATA,
-                    CHIP_SELECT_UNTOUCHED,
-                    init_sequence[i + 2 : i + 2 + data_size],
-                )
-            delay_time_ms = 10
-            if delay:
-                data_size += 1
-                delay_time_ms = init_sequence[i + 1 + data_size]
-                if delay_time_ms == 255:
-                    delay_time_ms = 500
-            time.sleep(delay_time_ms / 1000)
-            i += 2 + data_size
-
     def _send_pixels(self, pixels):
         if not self._core.data_as_commands:
             self._core.send(
@@ -455,23 +459,24 @@ class Display:
             elif self._backlight_type == BACKLIGHT_IN_OUT:
                 self._backlight.value = value > 0.99
             elif self._brightness_command is not None:
-                self._core.begin_transaction()
-                if self._core.data_as_commands:
-                    self._core.send(
-                        DISPLAY_COMMAND,
-                        CHIP_SELECT_TOGGLE_EVERY_BYTE,
-                        bytes([self._brightness_command, round(0xFF * value)]),
-                    )
-                else:
-                    self._core.send(
-                        DISPLAY_COMMAND,
-                        CHIP_SELECT_TOGGLE_EVERY_BYTE,
-                        bytes([self._brightness_command]),
-                    )
-                    self._core.send(
-                        DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, round(value * 255)
-                    )
-                self._core.end_transaction()
+                okay = self._core.begin_transaction()
+                if okay:
+                    if self._core.data_as_commands:
+                        self._core.send(
+                            DISPLAY_COMMAND,
+                            CHIP_SELECT_TOGGLE_EVERY_BYTE,
+                            bytes([self._brightness_command, round(0xFF * value)]),
+                        )
+                    else:
+                        self._core.send(
+                            DISPLAY_COMMAND,
+                            CHIP_SELECT_TOGGLE_EVERY_BYTE,
+                            bytes([self._brightness_command]),
+                        )
+                        self._core.send(
+                            DISPLAY_DATA, CHIP_SELECT_UNTOUCHED, round(value * 255)
+                        )
+                    self._core.end_transaction()
             self._brightness = value
         else:
             raise ValueError("Brightness must be between 0.0 and 1.0")
index 42218ec7baa5bb9d32b9251038fdcf442ca43a71..57e8dd604119240e9242f0b9ac7160106f7ccab3 100644 (file)
@@ -397,11 +397,11 @@ class _DisplayCore:
         """
         self._send(data_type, chip_select, data)
 
-    def begin_transaction(self) -> None:
+    def begin_transaction(self) -> bool:
         """
         Begin Bus Transaction
         """
-        self._begin_transaction()
+        return self._begin_transaction()
 
     def end_transaction(self) -> None:
         """
index 142e308cef10b13b01df1b285acb0b59942dcb35..c343e6511a407cdb39c1abfc5df58097b95da4ea 100644 (file)
@@ -132,16 +132,17 @@ class FourWire:
         else:
             self._spi.write(data)
 
-    def _begin_transaction(self):
+    def _begin_transaction(self) -> bool:
         """Begin the SPI transaction by locking, configuring, and setting Chip Select"""
-        while not self._spi.try_lock():
-            pass
+        if not self._spi.try_lock():
+            return False
         self._spi.configure(
             baudrate=self._frequency, polarity=self._polarity, phase=self._phase
         )
         self._chip_select.value = False
+        return True
 
-    def _end_transaction(self):
+    def _end_transaction(self) -> None:
         """End the SPI transaction by unlocking and setting Chip Select"""
         self._chip_select.value = True
         self._spi.unlock()
index e37eb8a659be5b584b28e71777f7b7131b571426..7ec9467e8479865f2af63e4ab9c9fc60c1389369 100644 (file)
@@ -80,10 +80,9 @@ class I2CDisplay:
         time.sleep(0.0001)
         self._reset.value = True
 
-    def _begin_transaction(self) -> None:
+    def _begin_transaction(self) -> bool:
         """Lock the bus before sending data."""
-        while not self._i2c.try_lock():
-            pass
+        return self._i2c.try_lock()
 
     def send(self, command: int, data: ReadableBuffer) -> None:
         """
@@ -109,12 +108,26 @@ class I2CDisplay:
                     command_bytes[2 * i] = 0x80
                     command_bytes[2 * i + 1] = data[i]
 
+            try:
                 self._i2c.writeto(self._dev_addr, buffer=command_bytes)
+            except OSError as error:
+                if error.errno == 121:
+                    raise RuntimeError(
+                        f"I2C write error to 0x{self._dev_addr:02x}"
+                    ) from error
+                raise error
         else:
             data_bytes = bytearray(len(data) + 1)
             data_bytes[0] = 0x40
             data_bytes[1:] = data
-            self._i2c.writeto(self._dev_addr, buffer=data_bytes)
+            try:
+                self._i2c.writeto(self._dev_addr, buffer=data_bytes)
+            except OSError as error:
+                if error.errno == 121:
+                    raise RuntimeError(
+                        f"I2C write error to 0x{self._dev_addr:02x}"
+                    ) from error
+                raise error
 
     def _end_transaction(self) -> None:
         """Release the bus after sending data."""
index 59fb08c91bc06202762f00eb4de4749b79009c33..8cfa87eaa9e01e7ffad68a90655e0a2f94c1a717 100644 (file)
@@ -17,8 +17,9 @@ paralleldisplay for Blinka
 
 """
 
+from typing import Optional
 import microcontroller
-import circuitpython_typing
+from circuitpython_typing import ReadableBuffer
 
 __version__ = "0.0.0+auto.0"
 __repo__ = "https://github.com/adafruit/Adafruit_Blinka_displayio.git"
@@ -37,8 +38,8 @@ class ParallelBus:
         command: microcontroller.Pin,
         chip_select: microcontroller.Pin,
         write: microcontroller.Pin,
-        read: microcontroller.Pin,
-        reset: microcontroller.Pin,
+        read: Optional[microcontroller.Pin],
+        reset: Optional[microcontroller.Pin] = None,
         frequency: int = 30000000,
     ):
         # pylint: disable=unnecessary-pass
@@ -61,9 +62,24 @@ class ParallelBus:
         """
         raise NotImplementedError("ParallelBus reset has not been implemented yet")
 
-    def send(self, command: int, data: circuitpython_typing.ReadableBuffer) -> None:
+    def send(self, command: int, 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("ParallelBus send has not been implemented yet")
+
+    def _send(
+        self,
+        _data_type: int,
+        _chip_select: int,
+        _data: ReadableBuffer,
+    ) -> None:
+        pass
+
+    def _begin_transaction(self) -> bool:
+        # pylint: disable=no-self-use
+        return True
+
+    def _end_transaction(self) -> None:
+        pass