Port to gpiod/gpiodevice.

This commit is contained in:
Phil Howard
2023-11-03 13:59:18 +00:00
parent 47fc5e1c78
commit 8e6cee4ef8
10 changed files with 86 additions and 84 deletions

View File

@@ -24,9 +24,9 @@ import time
from PIL import Image, ImageDraw
import ST7735 as ST7735
import st7735
SPI_SPEED_MHZ = 10 # Higher speed = higher framerate
SPI_SPEED_MHZ = 4 # Higher speed = higher framerate
if len(sys.argv) > 1:
SPI_SPEED_MHZ = int(sys.argv[1])
@@ -41,11 +41,11 @@ Running at: {}MHz
""".format(SPI_SPEED_MHZ))
# Create ST7735 LCD display class.
disp = ST7735.ST7735(
disp = st7735.ST7735(
port=0,
cs=ST7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc=9,
backlight=19, # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="PIN21",
backlight="PIN35", # 18 for back BG slot, 19 for front BG slot.
rotation=90,
spi_speed_hz=SPI_SPEED_MHZ * 1000000
)

View File

@@ -23,7 +23,7 @@ import time
from PIL import Image
import ST7735
import st7735
print("""
gif.py - Display a gif on the LCD.
@@ -39,11 +39,11 @@ else:
sys.exit(0)
# Create TFT LCD display class.
disp = ST7735.ST7735(
disp = st7735.ST7735(
port=0,
cs=ST7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc=9,
backlight=19, # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="GPIO9",
backlight="GPIO19", # 18 for back BG slot, 19 for front BG slot.
spi_speed_hz=4000000
)

View File

@@ -22,7 +22,7 @@ import sys
from PIL import Image
import ST7735 as ST7735
import st7735
print("""
image.py - Display an image on the LCD.
@@ -38,11 +38,11 @@ if len(sys.argv) < 2:
image_file = sys.argv[1]
# Create ST7735 LCD display class.
disp = ST7735.ST7735(
disp = st7735.ST7735(
port=0,
cs=ST7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc=9,
backlight=19, # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="GPIO9",
backlight="GPIO19", # 18 for back BG slot, 19 for front BG slot.
rotation=90,
spi_speed_hz=4000000
)

View File

@@ -2,16 +2,16 @@ import time
from PIL import Image, ImageDraw, ImageFont
import ST7735
import st7735
MESSAGE = "Hello World! How are you today?"
# Create ST7735 LCD display class.
disp = ST7735.ST7735(
disp = st7735.ST7735(
port=0,
cs=ST7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc=9,
backlight=19, # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="GPIO9",
backlight="GPIO19", # 18 for back BG slot, 19 for front BG slot.
rotation=90,
spi_speed_hz=10000000
)

View File

@@ -20,7 +20,7 @@
# THE SOFTWARE.
from PIL import Image, ImageDraw, ImageFont
import ST7735
import st7735
print("""
shapes.py - Display test shapes on the LCD using PIL.
@@ -31,11 +31,11 @@ breakout into the rear slot.
""")
# Create ST7735 LCD display class.
disp = ST7735.ST7735(
disp = st7735.ST7735(
port=0,
cs=ST7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc=9,
backlight=19, # 18 for back BG slot, 19 for front BG slot.
cs=st7735.BG_SPI_CS_FRONT, # BG_SPI_CSB_BACK or BG_SPI_CS_FRONT
dc="GPIO9",
backlight="GPIO19", # 18 for back BG slot, 19 for front BG slot.
rotation=90,
spi_speed_hz=4000000
)

View File

@@ -20,12 +20,17 @@
# THE SOFTWARE.
import numbers
import time
import numpy as np
import RPi.GPIO as GPIO
import spidev
__version__ = "0.0.5"
import spidev
import gpiod
import gpiodevice
from gpiod.line import Direction, Value
__version__ = '0.0.5'
OUTL = gpiod.LineSettings(direction=Direction.OUTPUT, output_value=Value.INACTIVE)
BG_SPI_CS_BACK = 0
BG_SPI_CS_FRONT = 1
@@ -121,9 +126,9 @@ class ST7735(object):
height=ST7735_TFTHEIGHT, rotation=90, offset_left=None, offset_top=None, invert=True, bgr=True, spi_speed_hz=4000000):
"""Create an instance of the display using SPI communication.
Must provide the GPIO pin number for the D/C pin and the SPI driver.
Must provide the GPIO pin label for the D/C pin and the SPI driver.
Can optionally provide the GPIO pin number for the reset pin as the rst parameter.
Can optionally provide the GPIO pin label for the reset pin as the rst parameter.
:param port: SPI port number
:param cs: SPI chip-select number (0 or 1 for BCM
@@ -139,9 +144,6 @@ class ST7735(object):
"""
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BCM)
self._spi = spidev.SpiDev(port, cs)
self._spi.mode = 0
self._spi.lsbfirst = False
@@ -167,20 +169,22 @@ class ST7735(object):
self._offset_top = offset_top
gpiodevice.friendly_errors = True
# Set DC as output.
GPIO.setup(dc, GPIO.OUT)
self._dc_lines, self._dc_line = gpiodevice.get_pin(dc, "st7735-dc", OUTL)
# Setup backlight as output (if provided).
self._backlight = backlight
if backlight is not None:
GPIO.setup(backlight, GPIO.OUT)
GPIO.output(backlight, GPIO.LOW)
self._bl_lines, self._bl_line = gpiodevice.get_pin(backlight, "st7735-bl", OUTL)
self._bl_lines.set_value(self._bl_line, Value.INACTIVE)
time.sleep(0.1)
GPIO.output(backlight, GPIO.HIGH)
self._bl_lines.set_value(self._bl_line, Value.ACTIVE)
# Setup reset as output (if provided).
if rst is not None:
GPIO.setup(rst, GPIO.OUT)
self._rst_lines, self._rst_line = gpiodevice.get_pin(rst, "st7735-rst", OUTL)
self.reset()
self._init()
@@ -192,7 +196,7 @@ class ST7735(object):
single SPI transaction, with a default of 4096.
"""
# Set DC low for command, high for data.
GPIO.output(self._dc, is_data)
self._dc_lines.set_value(self._dc_line, Value.ACTIVE if is_data else Value.INACTIVE)
# Convert scalar argument to list so either can be passed as parameter.
if isinstance(data, numbers.Number):
data = [data & 0xFF]
@@ -201,7 +205,7 @@ class ST7735(object):
def set_backlight(self, value):
"""Set the backlight on/off."""
if self._backlight is not None:
GPIO.output(self._backlight, value)
self._bl_lines.set_value(self._bl_line, Value.ACTIVE if value else Value.INACTIVE)
def display_off(self):
self.command(ST7735_DISPOFF)
@@ -234,11 +238,11 @@ class ST7735(object):
def reset(self):
"""Reset the display, if reset pin is connected."""
if self._rst is not None:
GPIO.output(self._rst, 1)
self._rst_lines.set_value(self._rst_line, Value.ACTIVE)
time.sleep(0.500)
GPIO.output(self._rst, 0)
self._rst_lines.set_value(self._rst_line, Value.INACTIVE)
time.sleep(0.500)
GPIO.output(self._rst, 1)
self._rst_lines.set_value(self._rst_line, Value.ACTIVE)
time.sleep(0.500)
def _init(self):

View File

@@ -16,16 +16,21 @@ def st7735():
@pytest.fixture(scope='function', autouse=False)
def GPIO():
"""Mock RPi.GPIO module."""
GPIO = mock.MagicMock()
# Fudge for Python < 37 (possibly earlier)
sys.modules['RPi'] = mock.Mock()
sys.modules['RPi'].GPIO = GPIO
sys.modules['RPi.GPIO'] = GPIO
yield GPIO
del sys.modules['RPi']
del sys.modules['RPi.GPIO']
def gpiod():
"""Mock gpiod module."""
sys.modules['gpiod'] = mock.MagicMock()
sys.modules['gpiod.line'] = mock.MagicMock()
yield sys.modules['gpiod']
del sys.modules['gpiod']
@pytest.fixture(scope='function', autouse=False)
def gpiodevice():
"""Mock gpiodevice module."""
sys.modules['gpiodevice'] = mock.MagicMock()
sys.modules['gpiodevice'].get_pin.return_value = (mock.Mock(), 0)
yield sys.modules['gpiodevice']
del sys.modules['gpiodevice']
@pytest.fixture(scope='function', autouse=False)

View File

@@ -1,10 +1,10 @@
def test_128_64_0(GPIO, spidev, numpy, st7735):
def test_128_64_0(gpiodevice, gpiod, spidev, numpy, st7735):
display = st7735.ST7735(port=0, cs=0, dc=24, width=128, height=64, rotation=0)
assert display.width == 128
assert display.height == 64
def test_128_64_90(GPIO, spidev, numpy, st7735):
def test_128_64_90(gpiodevice, gpiod, spidev, numpy, st7735):
display = st7735.ST7735(port=0, cs=0, dc=24, width=128, height=64, rotation=90)
assert display.width == 64
assert display.height == 128

View File

@@ -1,7 +1,7 @@
import mock
def test_display(GPIO, spidev, numpy, st7735):
def test_display(gpiodevice, gpiod, spidev, numpy, st7735):
display = st7735.ST7735(port=0, cs=0, dc=24)
numpy.dstack().flatten().tolist.return_value = [0xff, 0x00, 0xff, 0x00]
display.display(mock.MagicMock())
@@ -9,10 +9,10 @@ def test_display(GPIO, spidev, numpy, st7735):
spidev.SpiDev().xfer3.assert_called_with([0xff, 0x00, 0xff, 0x00])
def test_color565(GPIO, spidev, numpy, st7735):
def test_color565(gpiodevice, gpiod, spidev, numpy, st7735):
assert st7735.color565(255, 255, 255) == 0xFFFF
def test_image_to_data(GPIO, spidev, numpy, st7735):
def test_image_to_data(gpiodevice, gpiod, spidev, numpy, st7735):
numpy.dstack().flatten().tolist.return_value = []
assert st7735.image_to_data(mock.MagicMock()) == []

View File

@@ -1,38 +1,31 @@
import mock
def test_setup(GPIO, spidev, numpy, st7735):
display = st7735.ST7735(port=0, cs=0, dc=24)
del display
def test_setup(gpiodevice, gpiod, spidev, numpy, st7735):
_ = st7735.ST7735(port=0, cs=0, dc="GPIO24")
GPIO.output.assert_has_calls([
mock.call(24, True),
mock.call(24, False)
gpiodevice.get_pin.assert_has_calls([
mock.call("GPIO24", "st7735-dc", st7735.OUTL)
], any_order=True)
def test_setup_no_invert(GPIO, spidev, numpy, st7735):
display = st7735.ST7735(port=0, cs=0, dc=24, invert=False)
del display
def test_setup_no_invert(gpiodevice, gpiod, spidev, numpy, st7735):
_ = st7735.ST7735(port=0, cs=0, dc="GPIO24", invert=False)
def test_setup_with_backlight(GPIO, spidev, numpy, st7735):
display = st7735.ST7735(port=0, cs=0, dc=24, backlight=4)
GPIO.setup.assert_called_with(4, GPIO.OUT)
def test_setup_with_backlight(gpiodevice, gpiod, spidev, numpy, st7735):
display = st7735.ST7735(port=0, cs=0, dc="GPIO24", backlight="GPIO4")
display.set_backlight(GPIO.HIGH)
display.set_backlight(True)
GPIO.output.assert_has_calls([
mock.call(4, GPIO.LOW),
mock.call(4, GPIO.HIGH),
# Dozens of falls with True/False here
# due to _init() being called and the display
# setup setting the command/data pin
mock.call(4, GPIO.HIGH)
gpiodevice.get_pin.assert_has_calls([
mock.call("GPIO4", "st7735-bl", st7735.OUTL)
], any_order=True)
def test_setup_with_reset(GPIO, spidev, numpy, st7735):
display = st7735.ST7735(port=0, cs=0, dc=24, rst=4)
GPIO.setup.assert_called_with(4, GPIO.OUT)
del display
def test_setup_with_reset(gpiodevice, gpiod, spidev, numpy, st7735):
_ = st7735.ST7735(port=0, cs=0, dc=24, rst="GPIO4")
gpiodevice.get_pin.assert_has_calls([
mock.call("GPIO4", "st7735-rst", st7735.OUTL)
], any_order=True)