Bod has asked for the wisdom of the Perl Monks concerning the following question:

WoW! Just realised I haven't been on PM for far too long...where does the time go???
I've not been developing anything new recently as my time has been spent in other parts of the business...

Anyway, enough rambling...

As a bit of a hobby project, I'm trying to make a RaspberryPi power this LCD unit. Pretty much new ground for me, and I'm hoping to learn more about Debian and some of the lower-level Perl modules through this...

I've followed the instructions to get the LCD connected and the C demo program works so I know both the RaspberryPi and the LCD work and are connected together correctly.

So I'm left with several options on how to tackle this...here are some of them I've thought of, no doubt there are others:

So far, I've installed RPi::WiringPi which was a mission to do...

But, I haven't managed to get any code to operate the LCD.

Who has experience of this kind of LCD unit and which approach would you start with?

Replies are listed 'Best First'.
Re: ST7789V2 LCD Controller
by afoken (Chancellor) on Aug 18, 2024 at 22:25 UTC

    Some notes on connecting a display to the Raspi. The Raspi has three (or four) conventional display interfaces:

    • The most obvious one is HDMI. Connect any cheap box with HDMI input and you'll get an image. Behind the scenes, HDMI is quite complex, but there is so much ready-to-use hardware that you don't have to think about it. The HDMI output is controlled natively by Linux, it looks like a cheap graphics card on a PC to Linux. Some Raspis even have two HDMI outputs.
    • There is a composite video output that you could connect to many, many old TVs and many monitors. It is an analog signal, which limits the usable resolution to about SDTV. Like the HDMI output(s), Linux and the graphics hardware take care of this output. The output is on the headphone jack, on a dedicated cinch connector, or on some pads, depending on the Raspi model.
    • There is a DSI (Display Serial Interface) on a flatflex connector. It is designed to control "embedded" displays, typically with a resistive or capacitive touch interface (connected via I²C). Like HDMI, Linux and the graphics hardware take care of this output. It basically behaves like a laptop or tablet display.
    • The graphics hardware can also use the GPIO pins with a hand full of resistors or a better DAC to generate a VGA RGB signal. This costs you all available GPIOs, so you rarely go this way. But as before, Linux and the graphics hardware take care of the VGA output.

    The ST7789V2 is controlled via SPI, using a custom protocol (that I seem to remember from similar displays at work). The Raspi graphics hardware won't help you with that. You could write a frame buffer driver for the Linux kernel, or a "graphics card" driver for X11 or Wayland to support this display. Or you directly write pixel from your application via SPI to the ST7789V2, like you would do on an Arduino or any other microcontroller.

    <Update>

    Looking at the website once more, it seems soneone actually has implemented a kernel mode framebuffer driver for that display, using several tricks (DMA, partial refresh) to get reasonable frame rates over an inadequate interface.

    </Update>

    Having an independent display may be useful (no bluescreen on that display), but on a Raspi, I would use DSI or HDMI. There are tons of well-tested code to handle everything to draw on a DSI or HDMI display, including 2D and 3D acceleration, font rendering, and so on. No need to reinvent the wheel.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
      The most obvious one is HDMI

      I'm using a RaspberryPi Zero which, unlike it's bigger brothers, doesn't have HDMI :(

      Space is a bit limited on this project, hence the Zero and a tiny display.

        "I'm using a RaspberryPi Zero which, unlike it's bigger brothers, doesn't have HDMI"

        You should read the specs of what you bought, this is wrong.

Re: ST7789V2 LCD Controller
by afoken (Chancellor) on Aug 18, 2024 at 22:02 UTC
    ... which approach would you start with?

    The website you linked to has several examples for Raspi and Arduino. Study the code. Way down on the page are links to a schematic and the ST7789V2 datasheet.

    Schematics are primitive, just level converters and a voltage regulator connected between the "public" interface to the outside world and the LCD controller. LCD backlight is PWM controlled by the outside interface (pin 1). Other signals look like I²C (SDA, SCL), there is also a chip select (CS), data/control switch (D/C), and a reset line (RST). Reading the Spec at the top of the web page lists SPI, not I²C as control interface. So SDA should be named MOSI, SCL should be named CLK, and having a CS line makes total sense with SPI. Note that there is no MISO, as usual for many LCDs. They are write-only devices.

    On top of the website, you can see a timing diagram sending 16 bit RGB565 pixel data. This is how you write into display memory - pixel by pixel, with D/C set high. With a little bit of luck, there is a way to move to a selected pixel before writing, probably by setting D/C low.

    The ST7789V2 datasheet starts with a lot of electrical stuff, the serial interface is documented in chapter 8.4 and following explaining low-level SPI, Commands are in chapter 9. Note that you can not read back from the display, the required data line (MISO) is not available at the outside interface.

    So this is how I would start. Read the website, the datasheet, the example code. Example code often stinks and most times lacks any error checks. Datasheets omit little details and sometimes are plain wrong. Get used to it.

    Alexander

    --
    Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: ST7789V2 LCD Controller
by cavac (Prior) on Aug 19, 2024 at 08:26 UTC
Re: ST7789V2 LCD Controller
by Bod (Parson) on Sep 28, 2024 at 21:41 UTC

    Not wanting to delve into C programming just yet (I had to do some C++ at uni and didn't get very far!), I have been trying to approach the problem with just Perl. This is what I have got.

    use strict; use warnings; use RPi::SPI; # Initialize SPI: bus 0, 8 MHz my $spi = RPi::SPI->new(0, 8000000); # Reset display (if necessary) sub reset_display { # Handle reset } # Send command to the display sub send_command { my ($cmd) = @_; my $data = \[ $cmd ]; # Create an array reference for a single co +mmand byte print "Sending command\n"; $spi->rw($data, 1); # Send command via SPI } # Send data to the display (ensure data is an array reference) sub send_data { my ($data_ref) = @_; print "Sending data\n"; $spi->rw($data_ref); # Send data via SPI } # Initialize the display (according to the display's datasheet) sub init_display { send_command(0x01); # Command: software reset } reset_display(); init_display();

    I'm getting an error from $spi->rw($data, 1); that doesn't seem to make sense. The error is data param must be an array reference but the RPi::SPI documentation says that rw takes buf (arrayref) and len (integer). It doesn't mention a data parameter and I am giving it an arrayref and an integer!

    I've searched the source code and the error text is not there.

    Some help debugging this would be appreciated please

      my $data = \[ $cmd ]; # Create an array reference for a single comman +d byte

      should be

      my $data = [ $cmd ]; # Create an array reference for a single command + byte

      You were sending a reference to a reference to an array :(