Skip to content

Commit

Permalink
Split display.py into files for each backend (#930)
Browse files Browse the repository at this point in the history
* split display.py into files for each backend

* update Display.md

* remove unecessary call to displayio.release_displays()

* rename DisplayBackend to DisplayBase

* use relative imports in display extension
  • Loading branch information
Anomalocaridid authored Jan 29, 2024
1 parent 0334a85 commit 5d4e787
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 97 deletions.
9 changes: 6 additions & 3 deletions docs/en/Display.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,10 @@ Here's how you may initialize the extension. Note that this includes examples of
import board
import busio

from kmk.extensions.display import Display, TextEntry, ImageEntry

# For SSD1306
from kmk.extensions.display import Display, SSD1306, TextEntry, ImageEntry
from kmk.extensions.display.ssd1306 import SSD1306

# Replace SCL and SDA according to your hardware configuration.
i2c_bus = busio.I2C(board.GP_SCL, board.GP_SDA)
Expand All @@ -45,7 +47,7 @@ driver = SSD1306(
)

# For SH1106
from kmk.extensions.display import Display, SH1106, TextEntry, ImageEntry
from kmk.extensions.display.sh1106 import SH1106

# Replace SCK and MOSI according to your hardware configuration.
spi_bus = busio.SPI(board.GP_SCK, board.GP_MOSI)
Expand All @@ -60,7 +62,8 @@ driver = SH1106(
)

# For displays initialized by CircuitPython by default
from kmk.extensions.display import Display, BuiltInDisplay, TextEntry, ImageEntry
# IMPORTANT: breaks if a display backend from kmk.extensions.display is also in use
from kmk.extensions.display.builtin import BuiltInDisplay

# Replace display, sleep_command, and wake_command according to your hardware configuration.
driver = BuiltInDisplay(
Expand Down
95 changes: 1 addition & 94 deletions kmk/extensions/display.py → kmk/extensions/display/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import busio
from supervisor import ticks_ms

import displayio
Expand All @@ -12,8 +11,6 @@
from kmk.modules.split import Split, SplitSide
from kmk.utils import clamp

displayio.release_displays()


class TextEntry:
def __init__(
Expand Down Expand Up @@ -76,7 +73,7 @@ def __init__(self, x=0, y=0, image='', layer=None, side=None):
self.side = SplitSide.RIGHT


class DisplayBackend:
class DisplayBase:
def __init__(self):
raise NotImplementedError

Expand Down Expand Up @@ -110,96 +107,6 @@ def root_group(self, group):
self.display.root_group = group


# Intended for displays with drivers built into CircuitPython
# that can be used directly without manual initialization
class BuiltInDisplay(DisplayBackend):
def __init__(self, display=None, sleep_command=None, wake_command=None):
self.display = display
self.sleep_command = sleep_command
self.wake_command = wake_command
self.is_awake = True

def during_bootup(self, width, height, rotation):
self.display.rotation = rotation
return self.display

def deinit(self):
return

def sleep(self):
self.display.bus.send(self.sleep_command, b'')

def wake(self):
self.display.bus.send(self.wake_command, b'')


class SSD1306(DisplayBackend):
def __init__(self, i2c=None, sda=None, scl=None, device_address=0x3C):
self.device_address = device_address
# i2c initialization
self.i2c = i2c
if self.i2c is None:
self.i2c = busio.I2C(scl, sda)

def during_bootup(self, width, height, rotation):
import adafruit_displayio_ssd1306

self.display = adafruit_displayio_ssd1306.SSD1306(
displayio.I2CDisplay(self.i2c, device_address=self.device_address),
width=width,
height=height,
rotation=rotation,
)

return self.display

def deinit(self):
self.i2c.deinit()


class SH1106(DisplayBackend):
def __init__(
self,
spi=None,
sck=None,
mosi=None,
command=None,
chip_select=None,
reset=None,
baudrate=1000000,
):
displayio.release_displays()
self.command = command
self.chip_select = chip_select
self.reset = reset
self.baudrate = baudrate
# spi initialization
self.spi = spi
if self.spi is None:
self.spi = busio.SPI(sck, mosi)

def during_bootup(self, width, height, rotation):
import adafruit_displayio_sh1106

self.display = adafruit_displayio_sh1106.SH1106(
displayio.FourWire(
self.spi,
command=self.command,
chip_select=self.chip_select,
reset=self.reset,
baudrate=self.baudrate,
),
width=width,
height=height,
rotation=rotation,
)

return self.display

def deinit(self):
self.spi.deinit()


class Display(Extension):
def __init__(
self,
Expand Down
24 changes: 24 additions & 0 deletions kmk/extensions/display/builtin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from . import DisplayBase


# Intended for displays with drivers built into CircuitPython
# that can be used directly without manual initialization
class BuiltInDisplay(DisplayBase):
def __init__(self, display=None, sleep_command=None, wake_command=None):
self.display = display
self.sleep_command = sleep_command
self.wake_command = wake_command
self.is_awake = True

def during_bootup(self, width, height, rotation):
self.display.rotation = rotation
return self.display

def deinit(self):
return

def sleep(self):
self.display.bus.send(self.sleep_command, b'')

def wake(self):
self.display.bus.send(self.wake_command, b'')
49 changes: 49 additions & 0 deletions kmk/extensions/display/sh1106.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import busio

import adafruit_displayio_sh1106 # Display-specific library
import displayio

from . import DisplayBase

# Required to initialize this display
displayio.release_displays()


class SH1106(DisplayBase):
def __init__(
self,
spi=None,
sck=None,
mosi=None,
command=None,
chip_select=None,
reset=None,
baudrate=1000000,
):
self.command = command
self.chip_select = chip_select
self.reset = reset
self.baudrate = baudrate
# spi initialization
self.spi = spi
if self.spi is None:
self.spi = busio.SPI(sck, mosi)

def during_bootup(self, width, height, rotation):
self.display = adafruit_displayio_sh1106.SH1106(
displayio.FourWire(
self.spi,
command=self.command,
chip_select=self.chip_select,
reset=self.reset,
baudrate=self.baudrate,
),
width=width,
height=height,
rotation=rotation,
)

return self.display

def deinit(self):
self.spi.deinit()
31 changes: 31 additions & 0 deletions kmk/extensions/display/ssd1306.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import busio

import adafruit_displayio_ssd1306 # Display-specific library
import displayio

from . import DisplayBase

# Required to initialize this display
displayio.release_displays()


class SSD1306(DisplayBase):
def __init__(self, i2c=None, sda=None, scl=None, device_address=0x3C):
self.device_address = device_address
# i2c initialization
self.i2c = i2c
if self.i2c is None:
self.i2c = busio.I2C(scl, sda)

def during_bootup(self, width, height, rotation):
self.display = adafruit_displayio_ssd1306.SSD1306(
displayio.I2CDisplay(self.i2c, device_address=self.device_address),
width=width,
height=height,
rotation=rotation,
)

return self.display

def deinit(self):
self.i2c.deinit()

0 comments on commit 5d4e787

Please sign in to comment.