Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for 1.3" ST7789 (240x240) colour LCD driver #80

Closed
wants to merge 7 commits into from

Conversation

rm-hull
Copy link
Owner

@rm-hull rm-hull commented Jan 13, 2019

Not ready for review yet

https://www.aliexpress.com/item/1-3-inch-IPS-HD-TFT-ST7789-Drive-IC-240-240-SPI-Communication-3-3V-Voltage/32880846744.html

LCD Pin Remarks RPi Pin RPi Function
GND Ground P01-06 GND
VCC +3.3V Power P01-01 3V3
SCL SPI clock P01-23 GPIO 11 (SCLK)
SDA SPI data P01-19 GPIO 10 (MOSI)
RES Reset P01-18 GPIO 24
DC Data/command P01-16 GPIO 23
BLK Backlight control P01-12 GPIO 18 (PCM_CLK)

image

image

@rm-hull rm-hull changed the title ST7789 driver Add support for 1.3" ST7789 driver 240x240px Jan 13, 2019
@rm-hull rm-hull changed the title Add support for 1.3" ST7789 driver 240x240px Add support for 1.3" ST7789 LCD 240x240px Jan 13, 2019
@rm-hull rm-hull changed the title Add support for 1.3" ST7789 LCD 240x240px Add support for 1.3" ST7789 (240x240) LCD colour driver Jan 13, 2019
@rm-hull rm-hull changed the title Add support for 1.3" ST7789 (240x240) LCD colour driver Add support for 1.3" ST7789 (240x240) colour LCD driver Jan 13, 2019
README.rst Outdated
other functionality to support:
Python library interfacing LCD displays with the PCD8544, ST7735, ST7789,
ST7567, HT1621 and UC1701X driver using SPI on the Raspberry Pi and other
linux-based single-board computers - it provides a Pillow-compatible drawing
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

capitalize Linux

@Gadgetoid Gadgetoid mentioned this pull request Sep 17, 2019
@skibum-za
Copy link

I've been trying to use this branch to get a ST7789 device working. However, all I seem to get is :-
from luma.lcd.device import st7789 ModuleNotFoundError: No module named 'luma.lcd'
my pip show has a sumary that includes ST7789 :-

pip3 show luma.lcd Name: luma.lcd Version: 2.0.0 Summary: A library to drive PCD8544, HT1621, ST7735, ST7789, ST7567 and UC1701X-based LCDs Home-page: https://github.com/rm-hull/luma.lcd Author: Richard Hull Author-email: richard.hull@destructuring-bind.org License: MIT Location: /usr/local/lib/python3.7/dist-packages/luma.lcd-2.0.0-py3.7.egg Requires: luma.core Required-by:

the python 2 version says :-

pip show luma.lcd Name: luma.lcd Version: 2.0.0 Summary: A library to drive PCD8544, HT1621, ST7735, ST7789, ST7567 and UC1701X-based LCDs Home-page: https://github.com/rm-hull/luma.lcd Author: Richard Hull Author-email: richard.hull@destructuring-bind.org License: MIT Location: /usr/local/lib/python2.7/dist-packages/luma.lcd-2.0.0-py2.7.egg Requires: luma.core Required-by: luma.examples

I know I'm doing something wrong, so any assistance would be much appreciated.

@rm-hull
Copy link
Owner Author

rm-hull commented Nov 15, 2019

Anything on a brach is definitely a work-in-progress I'm afraid.

Unfortunately I've been greatly sidetracked by work (and moving house, and building an extension on the new house) this year so I've not been able spend anywhere near as much time as I would've liked on this project or my other GitHub projects. I'm not even sure where my collection of RPi's and small screens are .. they will be in a packing box somewhere...

Hopelly come January or February I will be able to start picking things up again

"""
def __init__(self, serial_interface=None, rotate=0, **kwargs):
super(st7789, self).__init__(luma.lcd.const.st7789, serial_interface, **kwargs)
self.capabilities(240, 240, rotate)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.capabilities(240, 240, rotate)
self.capabilities(240, 240, rotate, mode="RGB")

Comment on lines +319 to +324
self.set_window(0, 0, w, h)

#packed_image = BitArray().join(BitArray(uint=x & 0x00111111, length=6) for x in image.tobytes()).tobytes()

#self.data(image.tobytes())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self.set_window(0, 0, w, h)
#packed_image = BitArray().join(BitArray(uint=x & 0x00111111, length=6) for x in image.tobytes()).tobytes()
#self.data(image.tobytes())
self.set_window(0, 0, w, h)
image = self.preprocess(image)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested this code on Jetson Nano and I needed to add spi mode = 3 (look at this pr: rm-hull/luma.core#174 )
example initialization:

        from luma.core.interface.serial import spi
        from luma.lcd.device import st7789
        import Jetson.GPIO as GPIO
        GPIO.setmode(GPIO.TEGRA_SOC)
        serial = spi(port=0, device=0, gpio=GPIO, gpio_DC='GPIO_PZ0', gpio_RST='GPIO_PE6', bus_speed_hz=16000000, spi_mode = 3)
        device = st7789(serial, gpio=GPIO, gpio_LIGHT='LCD_BL_PW', rotate=3)

Please note you have to enable the spi port via dtb ( look at https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-3231/index.html#page/Tegra%2520Linux%2520Driver%2520Package%2520Development%2520Guide%2Fhw_setup_jetson_io.html%23 )

Here one of the samples: https://youtu.be/f7amvsklIw0

@Gadgetoid
Copy link
Contributor

Gadgetoid commented Jun 11, 2020

We now have a range of boards - Pirate Audio - that use an ST7789 display and would benefit from this support. I'm similarly stacked at the moment, but I'd be happy to lend an extra pair of eyes for testing/feedback where I can.

For Pirate Audio I'm running with:

python3 example.py --display st7789 --interface spi --gpio-data-command 9 --spi-device 1 --spi-bus-speed 32000000

Some observations:

I usually run Pirate Audio boards are 80MHz (which probably clamps to the nearest available freq on the Pi) since it's a lot of pixels to push at any reasonable framerate. However it looks like Luma will only let me drive up to 32MHz. Might be worth adding support for 62 (62.5 MHz) and 125MHz.

As an aside, since Luma uses runtime asserts the error generated for an "invalid" SPI frequency is a little opaque (The Pi will pick the nearest anyway, not sure about other platforms):

Traceback (most recent call last):
  File "examples/matrix.py", line 69, in <module>
    matrix(get_device())
  File "/home/pi/luma.examples/examples/demo_opts.py", line 63, in get_device
    device = cmdline.create_device(args)
  File "/usr/local/lib/python3.7/dist-packages/luma/core/cmdline.py", line 194, in create_device
    serial = getattr(make_serial(args), args.interface)()
  File "/usr/local/lib/python3.7/dist-packages/luma/core/cmdline.py", line 160, in spi
    gpio=self.gpio or GPIO)
  File "/usr/local/lib/python3.7/dist-packages/luma/core/interface/serial.py", line 276, in __init__
    assert(bus_speed_hz in [mhz * 1000000 for mhz in [0.5, 1, 2, 4, 8, 16, 32]])
AssertionError

--rotate is not supported.

By default the width/height are 128x64 which is incorrect for this display- I can't recall if there's any way for the display width/height defaults to override this?

A purly aesthetic observation is that the code is somewhat opaque- observe these lines:

luma.lcd/luma/lcd/device.py

Lines 234 to 303 in 3eb8c40

self.command(0x36)
self.data([0x70])
self.command(0x3A)
self.data([0x05])
self.command(0xB2)
self.data([0x0C, 0x0C, 0x00, 0x33, 0x33])
self.command(0xB7)
self.data([0x35])
self.command(0xBB)
self.data([0x19])
self.command(0xC0)
self.data([0x2C])
self.command(0xC2)
self.data([0x01])
self.command(0xC3)
self.data([0x12])
self.command(0xC4)
self.data([0x20])
self.command(0xC6)
self.data([0x0F])
self.command(0xD0)
self.data([0xA4, 0xA1])
self.command(0xE0)
self.data([0xD0])
self.data([0x04])
self.data([0x0D])
self.data([0x11])
self.data([0x13])
self.data([0x2B])
self.data([0x3F])
self.data([0x54])
self.data([0x4C])
self.data([0x18])
self.data([0x0D])
self.data([0x0B])
self.data([0x1F])
self.data([0x23])
self.command(0xE1)
self.data([0xD0])
self.data([0x04])
self.data([0x0C])
self.data([0x11])
self.data([0x13])
self.data([0x2C])
self.data([0x3F])
self.data([0x44])
self.data([0x51])
self.data([0x2F])
self.data([0x1F])
self.data([0x1F])
self.data([0x20])
self.data([0x23])
self.command(0x21)
self.command(0x11)
self.command(0x29)

Yes, this problem is systemic in Luma and my code isn't much better (https://github.com/pimoroni/st7789-python/blob/master/library/ST7789/__init__.py), but it might be handy to normalise using defines or comments to indicate what these commands are actually doing.

Sorry, bit of a dump of random things. The code seems to work and successfully drive the ST7789.

@Gadgetoid
Copy link
Contributor

I have rebased this feature branch, implemented the changes kindly suggested by @AlessioMorale and raised a replacement for this PR at #109

@rm-hull
Copy link
Owner Author

rm-hull commented Jun 11, 2020

ok, lets close this PR and focus on #109

@rm-hull rm-hull closed this Jun 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants