Skip to content

Commit

Permalink
Add Waveshare Pico-ResTouch-LCD-2.8 support (#60)
Browse files Browse the repository at this point in the history
This:
- adds a display driver for the Waveshare Pico-ResTouch-LCD-2.8
- refactors the ST7789 codebase somewhat now that we have a second
example
- makes it easier to switch displays in the examples

Thanks to [@JoGeDuBo ](https://github.com/JoGeDuBo) for the information
to make this work.
  • Loading branch information
corranwebster authored Nov 12, 2024
1 parent 062c6e5 commit c1acd33
Show file tree
Hide file tree
Showing 12 changed files with 128 additions and 22 deletions.
6 changes: 4 additions & 2 deletions examples/line_plot_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,9 +162,11 @@ def scale_values(self, data):


async def init_display():
from tempe_displays.st7789.pimoroni import PimoroniDisplay
from tempe_displays.st7789.pimoroni import PimoroniDisplay as Display
# or for Waveshare Pico-ResTouch-LCD-28:
# from tempe_displays.st7789.waveshare import PicoResTouchDisplay as Display

display = PimoroniDisplay(size=(240, 320))
display = Display(size=(240, 320))
display.backlight_pin(1)
await display.init()
return display
Expand Down
6 changes: 4 additions & 2 deletions examples/lines_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,11 @@


async def init_display():
from tempe_displays.st7789.pimoroni import PimoroniDisplay
from tempe_displays.st7789.pimoroni import PimoroniDisplay as Display
# or for Waveshare Pico-ResTouch-LCD-28:
# from tempe_displays.st7789.waveshare import PicoResTouchDisplay as Display

display = PimoroniDisplay(size=(240, 320))
display = Display(size=(240, 320))
display.backlight_pin(1)
await display.init()
return display
Expand Down
6 changes: 4 additions & 2 deletions examples/polar_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,9 +212,11 @@


async def init_display():
from tempe_displays.st7789.pimoroni import PimoroniDisplay
from tempe_displays.st7789.pimoroni import PimoroniDisplay as Display
# or for Waveshare Pico-ResTouch-LCD-28:
# from tempe_displays.st7789.waveshare import PicoResTouchDisplay as Display

display = PimoroniDisplay(size=(240, 320))
display = Display(size=(240, 320))
display.backlight_pin(1)
await display.init()
return display
Expand Down
6 changes: 4 additions & 2 deletions examples/polar_plot_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,11 @@ def scale_values(self, data):


async def init_display():
from tempe_displays.st7789.pimoroni import PimoroniDisplay
from tempe_displays.st7789.pimoroni import PimoroniDisplay as Display
# or for Waveshare Pico-ResTouch-LCD-28:
# from tempe_displays.st7789.waveshare import PicoResTouchDisplay as Display

display = PimoroniDisplay(size=(240, 320))
display = Display(size=(240, 320))
display.backlight_pin(1)
await display.init()
return display
Expand Down
6 changes: 4 additions & 2 deletions examples/scatter_plot_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,11 @@ def scale_values(self, data):


async def init_display():
from tempe_displays.st7789.pimoroni import PimoroniDisplay
from tempe_displays.st7789.pimoroni import PimoroniDisplay as Display
# or for Waveshare Pico-ResTouch-LCD-28:
# from tempe_displays.st7789.waveshare import PicoResTouchDisplay as Display

display = PimoroniDisplay(size=(240, 320))
display = Display(size=(240, 320))
display.backlight_pin(1)
await display.init()
return display
Expand Down
2 changes: 2 additions & 0 deletions examples/scrolled_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ async def init_surface(surface):

async def init_display():
from tempe_displays.st7789.pimoroni import PimoroniDisplay as Display
# or for Waveshare Pico-ResTouch-LCD-28:
# from tempe_displays.st7789.waveshare import PicoResTouchDisplay as Display

display = Display(size=(320, 240))
display.backlight_pin(1)
Expand Down
6 changes: 4 additions & 2 deletions examples/shapes_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,11 @@


async def init_display():
from tempe_displays.st7789.pimoroni import PimoroniDisplay
from tempe_displays.st7789.pimoroni import PimoroniDisplay as Display
# or for Waveshare Pico-ResTouch-LCD-28:
# from tempe_displays.st7789.waveshare import PicoResTouchDisplay as Display

display = PimoroniDisplay(size=(240, 320))
display = Display(size=(240, 320))
display.backlight_pin(1)
await display.init()
return display
Expand Down
6 changes: 4 additions & 2 deletions examples/update_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ async def init_surface(surface):


async def init_display():
from tempe_displays.st7789.pimoroni import PimoroniDisplay
from tempe_displays.st7789.pimoroni import PimoroniDisplay as Display
# or for Waveshare Pico-ResTouch-LCD-28:
# from tempe_displays.st7789.waveshare import PicoResTouchDisplay as Display

display = PimoroniDisplay(size=(240, 320))
display = Display(size=(240, 320))
display.backlight_pin(1)
await display.init(270)
return display
Expand Down
1 change: 1 addition & 0 deletions src/tempe_displays/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
["tempe_displays/st7789/base.py", "github:unital/tempe/src/tempe_displays/st7789/base.py"],
["tempe_displays/st7789/pimoroni.py", "github:unital/tempe/src/tempe_displays/st7789/pimoroni.py"],
["tempe_displays/st7789/spi.py", "github:unital/tempe/src/tempe_displays/st7789/spi.py"]
["tempe_displays/st7789/waveshare.py", "github:unital/tempe/src/tempe_displays/st7789/waveshare.py"],
],
"version": "0.3.dev"
}
10 changes: 10 additions & 0 deletions src/tempe_displays/st7789/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,16 @@ def fill(self, x, y, w, h, color=b"\xff\xff"):
self.write_to_memory(b"")
self.send_iterator(1, (row_bytes for _ in range(h)))

async def init(self):
await self.soft_reset()
self.tearing_effect_on(0)
self.set_color_mode(0x05)
self.set_porch_control(0x0C, 0x0C, 0x00, 0x33, 0x33)
self.set_lcm_control(0x2C)
self.set_vdv_vrh_enable(0x01)
self.set_vrh(0x12)
self.set_vdv(0x20)

def blit(self, buf, x, y, w, h, stride=None):
self._blit565(buf, x, y, w, h, stride)

Expand Down
10 changes: 2 additions & 8 deletions src/tempe_displays/st7789/pimoroni.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,16 +47,10 @@ def __init__(
super().__init__(spi, cs_pin, dc_pin, size, reset_pin)

async def init(self, rotation=0):
await super().init()

# Adapted from PicoGraphics code
# See https://github.com/pimoroni/pimoroni-pico/blob/24971349fcb3f92269c7f469b6c716e568941874/drivers/st7789/st7789.cpp#L49-L118
await self.soft_reset()
self.tearing_effect_on(0)
self.set_color_mode(0x05)
self.set_porch_control(0x0C, 0x0C, 0x00, 0x33, 0x33)
self.set_lcm_control(0x2C)
self.set_vdv_vrh_enable(0x01)
self.set_vrh(0x12)
self.set_vdv(0x20)
self.set_power_control_1(0xA4, 0xA1)
self.set_frame_rate_control(0x0F) # turn it way down ~39 fps

Expand Down
85 changes: 85 additions & 0 deletions src/tempe_displays/st7789/waveshare.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# SPDX-FileCopyrightText: 2024-present Unital Software <info@unital.dev>
#
# SPDX-License-Identifier: MIT

from machine import SPI, Pin

from .base import MADCTL_MV, MADCTL_MX, MADCTL_MY, MADCTL_MH
from .spi import ST7789_SPI


class PicoResTouchDisplay(ST7789_SPI):
"""Waveshare Pico-ResTouch-LCD-2.8.
This should work for any other Waveshare devices with similar pinouts.
See: https://github.com/orgs/micropython/discussions/16194
"""

def __init__(
self,
spi=None,
cs_pin=9,
dc_pin=8,
backlight_pin=13,
size=(320, 240),
reset_pin=15,
):
if spi is None:
spi = SPI(
0,
baudrate=62_500_000,
phase=1,
polarity=1,
sck=Pin(10, Pin.OUT),
mosi=Pin(11, Pin.OUT),
)
if isinstance(cs_pin, int):
cs_pin = Pin(cs_pin, Pin.OUT, value=1)
if isinstance(dc_pin, int):
dc_pin = Pin(dc_pin, Pin.OUT)
if isinstance(backlight_pin, int):
backlight_pin = Pin(backlight_pin, Pin.OUT)
self.backlight_pin = backlight_pin
super().__init__(spi, cs_pin, dc_pin, size, reset_pin)

async def init(self, rotation=0):
await super().init()
self.set_power_control_1(0xA4, 0xA1)
self.set_frame_rate_control(0x0F) # turn it way down ~39 fps

# Same as PicoDisplay, but work: https://github.com/orgs/micropython/discussions/16194
self.set_gate_control(0x35)
self.set_vcom(0x1F)
self.set_positive_gamma(
b"\xD0\x08\x11\x08\x0C\x15\x39\x33\x50\x36\x13\x14\x29\x2D"
)
self.set_negative_gamma(
b"\xD0\x08\x10\x08\x06\x06\x39\x44\x51\x0B\x16\x14\x2F\x31"
)
if self.size == (240, 360):
# portrait
rotation = (rotation + 90) % 360
if rotation in {90, 270}:
self.size = (240, 320)
else:
self.size = (320, 240)

await self.inversion(True)
await self.sleep(False)
await self.normal_on()

if rotation == 90:
self.memory_data_access_control(MADCTL_MH | MADCTL_MX | MADCTL_MY)
self.x_offset = 240 - self.size[0]
self.y_offset = 320 - self.size[1]
elif rotation == 180:
self.memory_data_access_control(MADCTL_MH | MADCTL_MV | MADCTL_MY)
self.x_offset = 320 - self.size[0]
self.y_offset = 240 - self.size[1]
elif rotation == 270:
self.memory_data_access_control(MADCTL_MH)
else:
self.memory_data_access_control(MADCTL_MV | MADCTL_MX)

self.clear()
await self.display_on()

0 comments on commit c1acd33

Please sign in to comment.