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

ST7789V2: Add Pimoroni Display HAT Mini 2.0" 320x240 LCD #242

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

Gadgetoid
Copy link

@Gadgetoid Gadgetoid commented Oct 26, 2021

This is ST7789V2 based which is otherwise pretty 1:1 to the other ST7789 boards except the controller has a 320x240 18-bit RAM region and doesn't need this hack (which confused me until I dived in and added ST7789V2 support):

fbcp-ili9341/st7735r.cpp

Lines 89 to 96 in 486a32e

#ifdef ST7789
// The ST7789 controller is actually a unit with 320x240 graphics memory area, but only 240x240 portion
// of it is displayed. Therefore if we wanted to swap row address mode above, writes to Y=0...239 range will actually land in
// memory in row addresses Y = 319-(0...239) = 319...80 range. To view this range, we must scroll the view by +80 units in Y
// direction so that contents of Y=80...319 is displayed instead of Y=0...239.
if ((madctl & MADCTL_ROW_ADDRESS_ORDER_SWAP))
SPI_TRANSFER(0x37/*VSCSAD: Vertical Scroll Start Address of RAM*/, 0, 320 - DISPLAY_WIDTH);
#endif

Supports landscape/portrait orientation. And 0/180 degree rotation.

Configure:

mkdir build
cd build
cmake .. -DPIMORONI_DISPLAY_HAT_MINI=ON -DSPI_BUS_CLOCK_DIVISOR=40 -DDISPLAY_BREAK_ASPECT_RATIO_WHEN_SCALING=ON -DBACKLIGHT_CONTROL=ON

⚠️ Make sure you configure with -DBACKLIGHT_CONTROL=ON to avoid a black screen (see below)

* Add general support for the ST7789V2.
* Add the ST7789V2-based 320x240 Display HAT Mini.

Configure:
cmake .. -DPIMORONI_DISPLAY_HAT_MINI=true -DSPI_BUS_CLOCK_DIVISOR=40 -DDISPLAY_BREAK_ASPECT_RATIO_WHEN_SCALING=ON
@antiero
Copy link

antiero commented Nov 4, 2021

I've compiled this, but I'm only getting a black screen when running with a Raspberry Pi Zero 2 - are there any changes needed to the startup Pi config, or any additional flags that need to be passed to enable the backlight to turn on?

@Gadgetoid
Copy link
Author

Not insofar as I'm aware. I haven't tested on a Pi Zero 2 though. Or- in fact- tested on any Pi but the one I made these changes on, so I'll have to look into that tomorrow time permitting.

@alexanderbsd
Copy link

yes, same for me. a black screen on Zero 2.

@Gadgetoid
Copy link
Author

Gadgetoid commented Nov 5, 2021

Same here, just rebuilt on a fresh SD card on the same Pi that I originally tested with and... black screen of doom. 😬

That'll teach me not to do a clean test. I suspect it's either some missing configuration, or some init that happened on my screen once during testing and isn't getting set in the final build.

Edit: Oh it's even sillier, it really does seem to just be the backlight not actuating!

@Gadgetoid
Copy link
Author

I should probably force it to on, but for the time being you should be able to fix this by blowing away your build dir and configuring with:

cmake .. -DPIMORONI_DISPLAY_HAT_MINI=ON -DSPI_BUS_CLOCK_DIVISOR=40 -DDISPLAY_BREAK_ASPECT_RATIO_WHEN_SCALING=ON -DBACKLIGHT_CONTROL=ON

@antiero
Copy link

antiero commented Nov 7, 2021

Hmm, that seems to make the backlight come on, but I still get a black screen with a fresh Pi Zero 2.. I'm wondering if I have a bad connection?.. When I first plugged in the HAT Mini it showed a full green LED... Now I can make out the red, green and blue components of the LED, not as bright 😕

@Gadgetoid
Copy link
Author

I’ll admit I still haven’t tested on the Zero 2 W (my office is a fridge right now so soldering is going to be painful) so there’s a chance that a fundamental incompatibility is the problem here- I’ve only scratched the surface of this codebase.

It could also easily be a connection issue, or an SPI divider issue, or something else. I’ll try on actual hardware tomorrow just to eliminate your setup being the problem.

st7735r.h Show resolved Hide resolved
st7735r.cpp Show resolved Hide resolved
// 320x240 2.0" ST7789V2 HAT
// https://shop.pimoroni.com/products/display-hat-mini

#ifdef PIMORONI_DISPLAY_HAT_MINI
Copy link
Owner

@juj juj Nov 7, 2021

Choose a reason for hiding this comment

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

Might there ever be mini display hats from Pimoroni based on other controller technology? If there's a possibility, then maybe this might better be #ifdef PIMORONI_ST7789V2_DISPLAY_HAT_MINI?

If not, then the name lgtm.

Copy link
Author

Choose a reason for hiding this comment

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

That's a possibility. Good point!

@juj
Copy link
Owner

juj commented Nov 7, 2021

The mention of

LCD TE (Tear Effect) pin connected

at https://pinout.xyz/pinout/display_hat_mini# caught my eye.

In original documentation at https://github.com/juj/fbcp-ili9341#about-tearing I wrote these musings

For example, the 4 ILI9341 displays I have can all be run faster than 75MHz so SPI bus
bandwidth-wise all of them would be able to update a full frame in less than a vsync interval,
but it is not possible to synchronize the updates to vsync since the display controllers do not
report it. (If you do know of a display that does actually expose a vsync clock signal even in
SPI mode, you can try implementing support to locking on to it)

It reads like this kind of tear effect pin could be a way to receive the vsync clock. In that case, it would be possible to implement vsync tearing free updates by timing the uploads to avoid straddling the hsync line, if someone wants to give a go at a research project.

I have not seen a SPI based display actually allow receiving vsync, such features have been restricted to the direct RGB displays - though maybe they've done something different on the wiring/controller of display..

@alexanderbsd
Copy link

I’ll admit I still haven’t tested on the Zero 2 W (my office is a fridge right now so soldering is going to be painful) so there’s a chance that a fundamental incompatibility is the problem here- I’ve only scratched the surface of this codebase.

It could also easily be a connection issue, or an SPI divider issue, or something else. I’ll try on actual hardware tomorrow just to eliminate your setup being the problem.

Tested on my Zero 2. The latest cmake options line works well. Now I am thinking about connecting the Hat buttons and with a mouse driver, which is a totally different request.

@Gadgetoid
Copy link
Author

Gadgetoid commented Nov 8, 2021

It's the opposite, in fact, the "TE" pin sends a clock pulse from the display controller to the host when the display reaches a given row- a bit like a scanline interrupt. It's then highly dependend on you being able to respond quickly enough to burst the display data to the screen before it starts the next field.

It can be configured in both V-Blank and V/H-Blank modes, though in practise it's only really useful to consider a vertical "interrupt" (I'm going to call it an interrupt because that's basically what it is) to signal when it's ready for the next frame.

This display is, indeed, the exception to prove the rule: genuine, bonafide, 320x240 pixels, landscape!

@juj If you want one to play with, drop me an email!

@Gadgetoid
Copy link
Author

Tested on my Zero 2. The latest cmake options line works well. Now I am thinking about connecting the Hat buttons and with a mouse driver, which is a totally different request.

Oooh buttons to... a very crude mouse input could work. Though with only four buttons for directions and no button for "push" we're coming up a little short. One of our mini trackballs would also work.

Here's a crude Python example that uses uinput to inject mouse events - https://github.com/pimoroni/trackball-python/blob/master/examples/evdev-mouse.py

@juj
Copy link
Owner

juj commented Nov 10, 2021

the "TE" pin sends a clock pulse from the display controller to the host when the display reaches a given row- a bit like a scanline interrupt. It's then highly dependend on you being able to respond quickly enough to burst the display data to the screen before it starts the next field.

That sounds perfect. It should then be possible to implement flicker free display updates by synchronizing fbcp-ili9341 pixel updates to that signal.

@juj If you want one to play with, drop me an email!

Thanks for the offer! I could get one, but I must say I unfortunately don't have much time to tinker on this front at the moment, so probably doesn't make sense. I'll check again what the situation is after I clear up some of the current projects.

@PaulskPt
Copy link

I was not successful with fbcp-ili9341 on a RPi400 + Pimoroni Flat Hat Hacker board + Pimoroni Display Hat Mini 2.0inch 320x240px (DHM2) with OS bullseye. Next installed OS version buster on a new RPiZero2W with same hw accessories. fbcp-ili9341 built ok (I added the mods by @Gadgetoid. Only raspi-config > 6 Advanced Options > A2 GL Driver > G3 GL (Fake KMS) worked. Full KMS did not work. Put the command to start in /etc/rc.local. The output of fbcp-ili9341 when started 'by hand' ends with: ''All initialized, now running main loop''. It makes the DHM2 to switch on but it shows a frozen image of the last demo app I ran before this evening (see the image).

Question:
What do I have to do to get the desktop onto the DHM2 (as in the video that @Gadgetoid published)? I missed that kind of instruction in the long and very informative README.md of the repo. Or did I look over it?

Btw. the LCD switches off after ca. 30 seconds. When I hit a key on the keyboard the LCD comes up again.
(even when raspi-config/display/screen-blanking is OFF.

IMG_3317

@Gadgetoid
Copy link
Author

Just followed the instructions on a Z2W and it's up and running.

I had to comment out dtoverlay=vc4-kms-v3d in /boot/config.txt and the display worked from brass tacks with Raspbian Bullseye for me.

fbcp does the display blanking if it has control of the backlight - need to omit -DBACKLIGHT_CONTROL=ON and pull the pin some other way. I think you can add `gpio=13=op,dh"

@PaulskPt
Copy link

PaulskPt commented Dec 10, 2021

Hi Philip, Thank you! I now also have bullseye running on the RPiZero2W. Running the pong script is OK. However pygame-demo.py and pygame-basic.py have no video output to the Display Hat Mini 2 that is. Below three screenshots: 1st of boot/config.txt part (btw SPI was ON); the 2nd of pong.py showing the DHM2 with the pong video and in the back filtered output of htop; 3rd the pygame-demo.py without video output and in the back also filtered output of htop. Interesting (for me) is that both scripts appear to open four PID's, so four processes running simultaneously. Or is it a kind of 'artifact' of htop. I didn't see it in top. fbcp-ili9341 was not running

2021-12-10-21h58 08_boot_config txt_onRPiZero2W

2021-12-10_Ping_having_video_output_IMG_3326

2021-12-10_pygame-demo_no_video_IMG_3321

@PaulskPt
Copy link

PaulskPt commented Dec 11, 2021

I don't know if I did it in a correct way:
Because of a CMake warning (see image)

2021-12-11_12h44_CMake_Warning_board_rev_of_hw_unknown

to add a detection to the RPiZero2W, in CMakeLists.txt I added at the end of the MATCHES string: (line 33 ). and the messag(... text (line 34) Then modified also lines 58 and 60.

2021-12-11_14h02_CMake_mods_lines_33-35_and_58-60

dmesg reports the RPiZero2W as "ARMv7", not "ARMv7A" as in CMakeLists.txt. That is why I have some doubt.

Situation after boot:

2021-12-11-142039_1920x1080_scrot

@deathonater
Copy link

deathonater commented Aug 31, 2022

Still having a black screen issue even after using -DBACKLIGHT_CONTROL=ON, the display seems to go blank about a minute or two after initializing. Using a Pi Zero W with the latest version of Raspberry Pi OS.

@Gadgetoid
Copy link
Author

Still having a black screen issue even after using -DBACKLIGHT_CONTROL=ON, the display seems to go blank about a minute or two after initializing. Using a Pi Zero W with the latest version of Raspberry Pi OS.

Does the display work at all? If you're using the Pi Zero W over SSH then I suspect it's turning off because there's no keyboard/mouse input to wake it up. You might want to disable backlight control and just use a dtoverlay or simple script to turn the right pin on.

@deathonater
Copy link

deathonater commented Aug 31, 2022

Still having a black screen issue even after using -DBACKLIGHT_CONTROL=ON, the display seems to go blank about a minute or two after initializing. Using a Pi Zero W with the latest version of Raspberry Pi OS.

Does the display work at all? If you're using the Pi Zero W over SSH then I suspect it's turning off because there's no keyboard/mouse input to wake it up. You might want to disable backlight control and just use a dtoverlay or simple script to turn the right pin on.

I do have a keyboard and mouse connected to the Pi, and I can type and move the cursor, I've also tried the work around to modify the config.txt file to keep the backlight on with pin 13, even after rebooting the display still shuts off.

UPDATE: I have also noticed that instead of going black, the screen will sometimes freeze, and I will need to run the "sudo /home/pi/fbcp-ili9341/build/fbcp-ili9341" command to get it working again. Meanwhile, any mouse movements or typing I do while the display is frozen will appear when the display restarts.

@sesquipedality
Copy link

I have patched the code and installed this on a Pi Zero W. I am getting the backlight turning on, and /dev/fb0 coming into existence, but nothing on screen. Has something broken it?

@martinschaer
Copy link

Worked for me adding -DUSE_DMA_TRANSFERS=OFF on a a Pi Zero W, as suggested here #125

@PaulskPt
Copy link

PaulskPt commented Jul 31, 2023

Update 2023-07-31. After updating the RPi2W O.S. and after cloning the latest version of Pimoroni's repo displayhatmini, and following the steps recomended in README.md the examples (also upgrading pygame): pong.py and pygame.py ran OK

2023-07-31.12.21.02_short.mp4

@sesquipedality
Copy link

sesquipedality commented Jul 31, 2023

Worked for me adding -DUSE_DMA_TRANSFERS=OFF on a a Pi Zero W, as suggested here #125

Yes, thank you, that seems to have done the trick. For reference the cmake line for a Pi Zero W I'm using is:

cmake .. -DPIMORONI_DISPLAY_HAT_MINI=ON -DSPI_BUS_CLOCK_DIVISOR=30 -DDISPLAY_BREAK_ASPECT_RATIO_WHEN_SCALING=ON -DBACKLIGHT_CONTROL=ON -DUSE_DMA_TRANSFERS=OFF -DSTATISTICS=0 -DDISPLAY_ROTATE_180_DEGREES=ON

Backlight control needs to be on for the screen to be illuminated, but screen blanking is unhelpful for my use case, so I also comment out

TURN_DISPLAY_OFF_AFTER_USECS_OF_INACTIVITY

in config.h

@hopg
Copy link

hopg commented Aug 20, 2023

cmake .. -DPIMORONI_DISPLAY_HAT_MINI=ON -DSPI_BUS_CLOCK_DIVISOR=30 -DDISPLAY_BREAK_ASPECT_RATIO_WHEN_SCALING=ON -DBACKLIGHT_CONTROL=ON -DUSE_DMA_TRANSFERS=OFF -DSTATISTICS=0 -DDISPLAY_ROTATE_180_DEGREES=ON

Backlight control needs to be on for the screen to be illuminated, but screen blanking is unhelpful for my use case, so I also comment out

TURN_DISPLAY_OFF_AFTER_USECS_OF_INACTIVITY

in config.h

Hi, I tried this and I still got a black screen. Trying to get this working on a Pi Zero W too.

Are you running Bullseye or something else? Also, would you mind pasting your /boot/config.txt as well please?

Thanks

@PaulskPt
Copy link

PaulskPt commented Aug 20, 2023 via email

@PaulskPt
Copy link

PaulskPt commented Aug 20, 2023 via email

@mikibish
Copy link

Hi, bit of a noob with all this if someone is able to help? Running into a bit of an issue running the "make -j" command, it starts to build a bunch of CXX objects and then starts showing this error a bunch of times: "c++: error: _DST7789V2: No such file or directory"
I've double checked everything and doesn't look like there's any mistakes so not really sure what I've done wrong, did I miss something?

@sesquipedality
Copy link

Hi, bit of a noob with all this if someone is able to help? Running into a bit of an issue running the "make -j" command, it starts to build a bunch of CXX objects and then starts showing this error a bunch of times: "c++: error: _DST7789V2: No such file or directory" I've double checked everything and doesn't look like there's any mistakes so not really sure what I've done wrong, did I miss something?

Hard to say, but did you run the cmake with the leading .. as explained in the build instructions (https://github.com/juj/fbcp-ili9341)? That error looks as though there are missing files, the two most likely causes of which would be not cloning the repository correctly or not running cmake correctly.

@sesquipedality
Copy link

sesquipedality commented Aug 31, 2023

Hi, I don't know if I can answer this e-mail notification. My RPi2W is running Raspbian GNU/Linux 10 (buster) (according to the contents of the file /etc/os-version. I am not using my RPi2W at the moment however I hooked it up. It has WiFi connection but unfortunately it is not in the same subnet so I cannot SSH into the device in this moment. Regards De: hopg @.> Enviada: 20 de agosto de 2023 21:00 Para: juj/fbcp-ili9341 @.> Cc: Paulus H.J. Schulinck @.>; Comment @.> Assunto: Re: [juj/fbcp-ili9341] ST7789V2: Add Pimoroni Display HAT Mini 2.0" 320x240 LCD (PR #242) cmake .. -DPIMORONI_DISPLAY_HAT_MINI=ON -DSPI_BUS_CLOCK_DIVISOR=30 -DDISPLAY_BREAK_ASPECT_RATIO_WHEN_SCALING=ON -DBACKLIGHT_CONTROL=ON -DUSE_DMA_TRANSFERS=OFF -DSTATISTICS=0 -DDISPLAY_ROTATE_180_DEGREES=ON Backlight control needs to be on for the screen to be illuminated, but screen blanking is unhelpful for my use case, so I also comment out TURN_DISPLAY_OFF_AFTER_USECS_OF_INACTIVITY in config.h Hi, I tried this and I still got a black screen. Trying to get this working on a Pi Zero W too. Are you running Bullseye or something else? Also, would you mind pasting your /boot/config.txt as well please? Thanks -

It's running on a more or less stock Raspberry Pi OS, fully patched.

sesquipedality@clio:~ $ more /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
NAME="Raspbian GNU/Linux"
VERSION_ID="11"
VERSION="11 (bullseye)"
VERSION_CODENAME=bullseye
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
sesquipedality@clio:~ $ more /etc/debian_version
11.7
sesquipedality@clio:~ $ uname -a
Linux clio 6.1.21+ #1642 Mon Apr  3 17:19:14 BST 2023 armv6l GNU/Linux

The driver unusually runs as a separate process.

Here. for what it's worth is the config.txt on which the system is running.

# For more options and information see
# http://rpf.io/configtxt
# Some settings may impact device functionality. See link above for details

# uncomment if you get no picture on HDMI for a default "safe" mode
#hdmi_safe=1

# uncomment the following to adjust overscan. Use positive numbers if console
# goes off screen, and negative if there is too much border
#overscan_left=16
#overscan_right=16
#overscan_top=16
#overscan_bottom=16

# uncomment to force a console size. By default it will be display's size minus
# overscan.
#framebuffer_width=1280
#framebuffer_height=720

# uncomment if hdmi display is not detected and composite is being output
hdmi_force_hotplug=1

# uncomment to force a specific HDMI mode (this will force VGA)
#hdmi_group=1
#hdmi_mode=1

# uncomment to force a HDMI mode rather than DVI. This can make audio work in
# DMT (computer monitor) modes
#hdmi_drive=2

# uncomment to increase signal to HDMI, if you have interference, blanking, or
# no display
#config_hdmi_boost=4

# uncomment for composite PAL
#sdtv_mode=2

#uncomment to overclock the arm. 700 MHz is the default.
#arm_freq=800

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Uncomment this to enable infrared communication.
#dtoverlay=gpio-ir,gpio_pin=17
#dtoverlay=gpio-ir-tx,gpio_pin=18

# Additional overlays and parameters are documented /boot/overlays/README

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

# Automatically load overlays for detected cameras
camera_auto_detect=1

# Automatically load overlays for detected DSI displays
display_auto_detect=1

# Enable DRM VC4 V3D driver
#dtoverlay=vc4-kms-v3d
max_framebuffers=2

# Disable compensation for displays with overscan
disable_overscan=1

[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1

[all]

[pi4]
# Run as fast as firmware / board allows
arm_boost=1

[all]

@mikibish
Copy link

Hard to say, but did you run the cmake with the leading .. as explained in the build instructions (https://github.com/juj/fbcp-ili9341)? That error looks as though there are missing files, the two most likely causes of which would be not cloning the repository correctly or not running cmake correctly.

Thanks for the reply.

Yeah definitely did the .. , I redid the cmake command a couple times, trying the dots before and after the build options, as thought their placement could have been the issue but got the same errors each time.
I can try cloning again, but I'm not sure if that would be the issue since I thought this branch is adding DST7789V2 which is why I feel like I missed something here. But if that's the only other possible cause I'm willing to try it, if I clone without deleting what's already there would that just add any missing files or overwrite everything?

I did check through the lines that had to be added and the only place I can see where DST7789V2 appears is on line 212 in CMakeLists.txt, is that right?

@Jeevus3D
Copy link

I successfully got this working today;
Pi Zero W, PiSugar 3 UPS, Display Hat Mini.
Stock Debian Bullseye build from imager with desktop.
CMake built with:
cmake .. -DPIMORONI_DISPLAY_HAT_MINI=ON -DSPI_BUS_CLOCK_DIVISOR=30 -DDISPLAY_BREAK_ASPECT_RATIO_WHEN_SCALING=ON -DBACKLIGHT_CONTROL=ON -DUSE_DMA_TRANSFERS=OFF -DSTATISTICS=0 -DDISPLAY_ROTATE_180_DEGREES=ON

The display does come to life and show mirrored HDMI output ONLY IF I also have a monitor hooked up at the time I run sudo ./fbcp-ili9341 which is kind of expected behavior, but I would like to force HDMI output without a display connected if possible.

I do have all of the requisite lines commented out in the /boot/config.txt file including hdmi_group=4 forcing a 640x480 HDMI resolution that is much more legible than trying to force scale the 1920x1080 output. hdmi_force_hotplug=1 is uncommented per request of the system, I cant remember if it asked when running CMake or make -j.

Now, ideally I would like the display to show the desktop on startup which I don't think will be that hard adding the executable to the rc.local file. However, I can't quite nail down why it only wants to output to the DHM when the HDMI port is occupied and outputting data.

Any guidance is appreciated! Also, if anyone else might be struggling along the way I'm more than happy to help share my setup/configs so we can get this published to the main branch!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.