Drivers for the ST7789 and ST7735 controllers

Hello,

I have written a graphics library with drivers for the ST7789 and ST7735 controllers. (In principle, the library can be easily adapted to any controller).

The library uses an frame buffer between the graphic primitives and the controller. Changes made in the frame buffer are transmitted to the controller using SPI transfers under DMA. To reduce transfers, the frame buffer is divided into blocks; only the modified blocks are transferred to the screen.

The graphic primitives are minimalistic but can be extended as needed.

If you find this useful, you can find the source code here:
https://github.com/DADDesign-Projects/DEMO_DaisyGFX_ST7735
https://github.com/DADDesign-Projects/DEMO_DaisyGFX_ST7789

Feel free to contact me if you have any questions or suggestions.

Note: I do not speak English well and I am using an automatic translator. My apologies if this text is not very clear.

Philippe

2 Likes

New Version of DaisySeedGFX Library Released

We are pleased to announce the release of a new version of the DaisySeedGFX library, available here:
https://github.com/DADDesign-Projects/DaisySeedGFX2

What’s New?

This new version introduces:

  • Layer Management: Enhanced graphics capabilities with support for multiple layers and transparency.
  • Font Conversion Utility: A tool to convert TrueType fonts into portable bitmap formats.

This version brings powerful new features and is designed to enhance the graphical capabilities of your projects with the Daisy Seed platform.

Check it out and share your feedback!

3 Likes

Thank you for building this library, its a big help to the community. I was able to get your first version working on my board without much trouble, and I’ve been eager to try out your newest version, but have been unable to get even the demo working. VS code gets hung up when building the SPI files and never makes a .bin file. Any ideas what could be causing the problem?

Did you clone the example with the submodules option recursively?

git clone --recurse-submodules https://github.com/DADDesign-Projects/Demo_DaisySeedGFX2

Normally, all the necessary files are loaded. You just need to open the Demo directory in VS Code and configure the UserConfig.h file, which is located in the directory above Demo.

I just tested the process again to verify, and it works fine. Please keep me updated on your progress, and don’t hesitate to reach out if the issue persists.

Philippe

thanks for responding Philippe, I tried everything exactly as you said to, and I was able to get a .bin file using the 7789 driver config without a problem, which is great, however, I’m using the 7735 controller, and then it wont work when I uncomment that line in the user config file. Thanks for helping, I’m not great with C++, but I’m trying to learn

Hello.
I can’t reproduce the issue on my setup.Can you provide more details:

  • What error messages are you getting?
  • Have you modified anything else in the configuration file, such as the screen dimensions or the mode (7735 controllers usually run in mode 0)?
  • Which development environment are you using (Visual Studio Code, …)?

Philippe

Im using Visual Studio Code, and I have modified the screen dimentions to 160 width and 128 height. I’ve kept the 16bit color mode (if that’s what you mean by mode), and then altering the pinout for the data lines (I’m using the bksheperd hardware so d8-d11 for my outputs).

When I comment out ā€œ#define TFT_CONTROLEUR_TFT 7735 (line 15)ā€ and un-comment out "#define TFT_CONTROLEUR_TFT 7789 (line 14) with all of the same settings above the program works fine and I get a bin file.

When I comment out line 14 and un-comment out line 15 and use the 7735 config, this is the error I’m getting in the terminal when I execute the make clean then make command: ā€œIn file included from …/DaisySeedGFX2/TFT_SPI.cpp:10:
…/DaisySeedGFX2/ST7735_Defines.h:100:6: error: ā€˜TFT_SPI’ has not been declared
100 | void TFT_SPI::Initialise(){
| ^~~~~~~
…/DaisySeedGFX2/ST7735_Defines.h: In function ā€˜void Initialise()’:
…/DaisySeedGFX2/ST7735_Defines.h:103:5: error: ā€˜SendCommand’ was not declared in this scope; did you mean ā€˜SDMMC_SendCommand’?
103 | SendCommand(ST7735_SWRESET); // 1: Software reset, 0 args, w/delay
| ^~~~~~~~~~~
| SDMMC_SendCommand
…/DaisySeedGFX2/ST7735_Defines.h:109:7: error: ā€˜SendData’ was not declared in this scope
109 | SendData(0x01);
| ^~~~~~~~
make: *** […/LibDaisy/core/Makefile:286: build/TFT_SPI.o] Error 1ā€

I’m happy to send any more data you need

Hello

I just found the issue: there is a missing reference to the DadGFX namespace in the file ST7735_Defines.h at line 100.

// --------------------------------------------------------------------------  
// Initialization of the ST7735-type screen  
void DadGFX::TFT_SPI::Initialise() {

ST7735 displays generally operate in Mode 0, check the SPI mode in the configuration file UserConfig.h at line 30.

#define TFT_SPI_MODE Mode0  // SPI mode (Mode 0: CPOL = 0, CPHA = 0)

If you are using the demo, you may need to adjust it to match your screen dimensions.

Feel free to reach out if you encounter any other issues with the library, and keep me updated on your project’s progress.

Philippe

Yep that was the problem. I got stuff is appearing on my screen now. Thanks so much for the help. Now I’m working on optimization.

I am noticing that while the circle moves around the screen, somtimes the blue background renders black after the circle passes over it then stays that way until it updates again. Is that an issue that could be solved by changing the FIFO buffer?

Hello

I have never encountered this issue, and I don’t believe it is related to the FIFO (if the FIFO is full, the program simply waits). Here are a few possible causes to investigate:

  • SPI connection issue → Try reducing the SPI speed by setting TFT_SPI_BaudPrescaler to PS_8 in UserConfig.h.

  • Layer sizing issue → Check the code, especially the lines that define the layer size, which should be adjusted:


DECLARE_LAYER(BackgroundLayer, 320, 240);
DECLARE_LAYER(TextLayer, 250, 100)
  • Cache issue with ā€œBlocFrameā€ (although I don’t think this is likely) → Try placing ā€œBlocFrameā€ in the DMA_BUFFER section.

File: cDisplay.h, line 23:

DadGFX::sColor DMA_BUFFER_MEM_SECTION  DisplayName##BlocFrame[BLOC_HEIGHT][BLOC_WIDTH];

Let me know if you find anything, and thanks for your feedback.

Philippe

Thanks Phillippe for sharing this!

I’m trying to get it to work.
Connected CS(D7), Reset(D2), AO/DC(D1), MOSI(D10), SCK(D8) and the connections all seem good.
Setup the user config. And then ran the demo at:
GitHub - DADDesign-Projects/Demo_DaisySeedGFX2: Demonstrates how to use the "DaisySeedGFX2" graphics library..
Sadly at the moment i get no response from the screen. But also no warnings or errors.
As far as i am able to debug now the SPI gets initialized without an error.
Also tried all SPI modes without any difference.
And checked that the screen is working (on an ESP32).

Hello Marcel,

I don’t have enough information from your message to make a proper diagnosis. The only thing I can point out is that my driver does not handle the CS pin—you need to pull this pin to ground.

Beyond that, could you provide more details? What is the controller type of your screen—ST7735 or ST7789? Which library are you using on the ESP32, and with what configuration?

Which demo are you using: Demo or DemoUseFlashMemory? For the latter, you first need to load the contents of the Image and Font folders into the flash memory. In both cases, are you correctly configuring the UserConfig.h file located at the root of the Demo_DaisySeedGFX2 directory?

Let me know how your progress is going.

Philippe

It’s a ST7735 using the Demo (so not with flash mem.). With the ESP i use TFT_eSPI lib setup as a ā€˜Black Tab’. I’ve tried with CS to ground and several permutations of the settings below.

The config I use is this:


#pragma once // Prevents multiple inclusions of this header file

#define TFT_WIDTH 128  // Screen width in pixels
#define TFT_HEIGHT 160 // Screen height in pixels

#define TFT_CONTROLEUR_TFT 7735 // Uncomment to use the ILI7735 controller
#define TEST1 7789              // Test definition, redundant but illustrative

#define TFT_COLOR 16 // Use 16-bit color mode (default)

#define TFT_SPI_PORT SPI_1         // SPI port used for the display
#define TFT_SPI_MODE Mode0        // SPI mode (Mode 3: CPOL = 1, CPHA = 1)
#define TFT_SPI_BaudPrescaler PS_2 // SPI baud rate prescaler

#define TFT_MOSI D10 // SPI MOSI (Master Out, Slave In) pin
#define TFT_NSS D7   // SPI NSS (Slave Select) pin
#define TFT_SCLK D8  // SPI clock (SCLK) pin
#define TFT_DC D21   // Data/Command control pin
#define TFT_RST D20  // Reset pin for the display

#define NB_BLOC_WIDTH 16                        // Number of blocks horizontally
#define NB_BLOC_HEIGHT 20                       // Number of blocks vertically
#define NB_BLOCS NB_BLOC_WIDTH *NB_BLOC_HEIGHT  // Total number of blocks
#define BLOC_WIDTH TFT_WIDTH / NB_BLOC_WIDTH    // Width of each block in pixels
#define BLOC_HEIGHT TFT_HEIGHT / NB_BLOC_HEIGHT // Height of each block in pixels

#define SIZE_FIFO 5 // Number of blocks in the FIFO buffer

I did try a different, more basic ST7735 driver from RadicalTeapot and did manage to get some response from the screen, but it was garbled.

Hello Marcel,

The parameters seem correct, but you may need to reduce the transmission speed by setting TFT_SPI_BaudPrescaler to PS_16, then PS_8…
If that doesn’t work, could you try testing version 1 of the library: DEMO_DaisyGFX_ST7735 GitHub - DADDesign-Projects/DEMO_DaisyGFX_ST7735: Demonstrates how to use the "DaisySeedGFX" graphics library with an ST7735 TFT controller?

I’m checking on my side if there are any configuration differences with the TFT_eSPI library when set up as a ā€œBlack Tab.ā€

Philippe

st7735

Success!
Wind up it was the CS that needed to be connected to GND indeed.
Thanks for helping so quickly.
And please excuse the poor gif quality, actually looks pretty good IRL.
It almost feels like im seeing motion blur??
Only thing to notice was the white line on the right side moving up and down with the ball.

But I’m ecstatic and very gratful!

Hello Marcel,

Thanks for your feedback! I’m glad to hear that it’s working for you.

The demo is designed for a 320x240 screen, so you’ll need to adjust the code in main to see the full pseudo ping-pong game, especially the paddle that follows the ball.

Philippe

1 Like

Ah that makes sense!

I am having great fun, but a bit confused about orientation.
I need it in portrait (128x160) so switched it to:

__Display.setOrientation(Rotation::Degre_0);

Now I get some noise on the bottom part of the screen, which seems logical since the background layer now has the wrong dimensions. So changing that:

DECLARE_LAYER(BackgroundLayer, 128, 160)

Now the whole screen is noise…
Wondering how the UserConfig.h plays a part in this. There the setting remains as it was:

#define TFT_WIDTH 128  // Screen width in pixels
#define TFT_HEIGHT 160 // Screen height in pixels

Should I adjust these?

Hello Marcel,

Do not modify the UserConfig.h file. Here is a working code snippet:

DECLARE_LAYER(BackgroundLayer, 128, 160)  
...  
__Display.setOrientation(Rotation::Degre_0);  
DadGFX::cLayer* pBackground = ADD_LAYER(BackgroundLayer, 0, 0, 1);  
pBackground->drawFillRect(0, 0, 128, 160, DadGFX::sColor(9, 111, 148, 255));  

Philippe

Still the same garbled screen…

I don’t understand.
You also need to call __Display.flush();
Could you show your code?