Skip to content

Commit 93e37b2

Browse files
author
Yidi Lin
committed
Add supoort for GC9A01 and WaveShare 1.28 inch GC9A01 240x240 ISP display module
1 parent 98e7a58 commit 93e37b2

File tree

6 files changed

+236
-0
lines changed

6 files changed

+236
-0
lines changed

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,12 @@ elseif(MPI3501)
265265
if (USE_DMA_TRANSFERS)
266266
message(FATAL_ERROR "DMA is unfortunately not possible with MPI3501. Please disable with -DUSE_DMA_TRANSFERS=OFF.")
267267
endif()
268+
elseif(WAVESHARE_GC9A01)
269+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGC9A01 -DWAVESHARE_GC9A01")
270+
message(STATUS "Targeting WaveShare 240x240 1.28inch IPS LCD Hat with GC9A01 controller")
271+
elseif(GC9A01)
272+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGC9A01")
273+
message(STATUS "Targeting GC9A01")
268274
else()
269275
message(FATAL_ERROR "Please specify which display controller to use on command line to CMake!")
270276
endif()

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ The following LCD displays have been tested:
6666
- [WaveShare 128x128, 1.44inch LCD display HAT for Raspberry Pi](https://www.waveshare.com/1.44inch-lcd-hat.htm) with ST7735S controller
6767
- [KeDei 3.5 inch SPI TFTLCD 480*320 16bit/18bit version 6.3 2018/4/9](https://github.com/juj/fbcp-ili9341/issues/40) with MPI3501 controller
6868
- Unbranded 2.8" 320x240 display with ILI9340 controller
69+
- [WaveShare 240×240, General 1.28inch Round LCD Display Module, 65K RGB](https://www.waveshare.com/product/1.28inch-lcd-module.htm) with GC9A01 controller
6970

7071
### Installation
7172

@@ -120,6 +121,7 @@ When using one of the displays that stack on top of the Pi that are already reco
120121
- `-DWAVESHARE_ST7789VW_HAT=ON`: If specified, targets a [240x240, 1.3inch IPS LCD display HAT for Raspberry Pi](https://www.waveshare.com/1.3inch-lcd-hat.htm) with ST7789VW display controller.
121122
- `-DWAVESHARE_ST7735S_HAT=ON`: If specified, targets a [128x128, 1.44inch LCD display HAT for Raspberry Pi](https://www.waveshare.com/1.3inch-lcd-hat.htm) with ST7735S display controller.
122123
- `-DKEDEI_V63_MPI3501=ON`: If specified, targets a [KeDei 3.5 inch SPI TFTLCD 480*320 16bit/18bit version 6.3 2018/4/9](https://github.com/juj/fbcp-ili9341/issues/40) display with MPI3501 display controller.
124+
- `-DWAVESHARE_GC9A01=ON`: If specified, targets a [WaveShare 240×240, General 1.28inch Round LCD Display Module, 65K RGB](https://www.waveshare.com/product/1.28inch-lcd-module.htm) with GC9A01 display controller
123125

124126
###### If you wired the display to the Pi yourself
125127

@@ -137,6 +139,7 @@ If you connected wires directly on the Pi instead of using a Hat from the above
137139
- `-DILI9486L=ON`: If you have a ILI9486L display, pass this directive. Note that ILI9486 and ILI9486L are quite different, mutually incompatible controller chips, so be careful here identifying which one you have. (or just try both, should not break if you misidentified)
138140
- `-DILI9488=ON`: If you have a ILI9488 display, pass this directive.
139141
- `-DMPI3501=ON`: If specified, targets a display with MPI3501 display controller.
142+
- `-DGC9A01=ON`: If you have a GC9A01 display, pass this directive.
140143

141144
And additionally, pass the following to customize the GPIO pin assignments you used:
142145

display.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include "mz61581.h"
2424
#elif defined(MPI3501)
2525
#include "mpi3501.h"
26+
#elif defined(GC9A01)
27+
#include "gc9a01.h"
2628
#else
2729
#error Please reconfigure CMake with your display controller directive set!
2830
#endif

gc9a01.cpp

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
#include "config.h"
2+
3+
#if defined(GC9A01)
4+
5+
#include "spi.h"
6+
7+
#include <memory.h>
8+
#include <stdio.h>
9+
10+
void InitGC9A01()
11+
{
12+
// If a Reset pin is defined, toggle it briefly high->low->high to enable the device. Some devices do not have a reset pin, in which case compile with GPIO_TFT_RESET_PIN left undefined.
13+
#if defined(GPIO_TFT_RESET_PIN) && GPIO_TFT_RESET_PIN >= 0
14+
printf("Resetting display at reset GPIO pin %d\n", GPIO_TFT_RESET_PIN);
15+
SET_GPIO_MODE(GPIO_TFT_RESET_PIN, 1);
16+
SET_GPIO(GPIO_TFT_RESET_PIN);
17+
usleep(120 * 1000);
18+
CLEAR_GPIO(GPIO_TFT_RESET_PIN);
19+
usleep(120 * 1000);
20+
SET_GPIO(GPIO_TFT_RESET_PIN);
21+
usleep(120 * 1000);
22+
#endif
23+
24+
// Do the initialization with a very low SPI bus speed, so that it will succeed even if the bus speed chosen by the user is too high.
25+
spi->clk = 34;
26+
__sync_synchronize();
27+
28+
BEGIN_SPI_COMMUNICATION();
29+
{
30+
// The init sequence reference:
31+
// https://www.waveshare.com/wiki/File:LCD_Module_code.zip
32+
// File: RaspberryPi/c/lib/LCD/LCD_1in28.c
33+
SPI_TRANSFER(0xEF);
34+
SPI_TRANSFER(0xEB, 0x14);
35+
36+
SPI_TRANSFER(0xFE);
37+
SPI_TRANSFER(0xEF);
38+
39+
SPI_TRANSFER(0xEB, 0x14);
40+
41+
SPI_TRANSFER(0x84, 0x40);
42+
43+
SPI_TRANSFER(0x85, 0xFF);
44+
45+
SPI_TRANSFER(0x86, 0xFF);
46+
47+
SPI_TRANSFER(0x87, 0xFF);
48+
49+
SPI_TRANSFER(0x88, 0x0A);
50+
51+
SPI_TRANSFER(0x89, 0x21);
52+
53+
SPI_TRANSFER(0x8A, 0x00);
54+
55+
SPI_TRANSFER(0x8B, 0x80);
56+
57+
SPI_TRANSFER(0x8C, 0x01);
58+
59+
SPI_TRANSFER(0x8D, 0x01);
60+
61+
SPI_TRANSFER(0x8E, 0xFF);
62+
63+
SPI_TRANSFER(0x8F, 0xFF);
64+
65+
66+
SPI_TRANSFER(0xB6, 0x00, 0x20);
67+
68+
SPI_TRANSFER(0x36, 0x08);//Set as vertical screen
69+
70+
SPI_TRANSFER(0x3A, 0x05);
71+
72+
73+
SPI_TRANSFER(0x90, 0x08, 0x08, 0x08, 0x08);
74+
75+
SPI_TRANSFER(0xBD, 0x06);
76+
77+
SPI_TRANSFER(0xBC, 0x00);
78+
79+
SPI_TRANSFER(0xFF, 0x60, 0x01, 0x04);
80+
81+
SPI_TRANSFER(0xC3, 0x13);
82+
83+
SPI_TRANSFER(0xC4, 0x13);
84+
85+
SPI_TRANSFER(0xC9, 0x22);
86+
87+
SPI_TRANSFER(0xBE, 0x11);
88+
89+
SPI_TRANSFER(0xE1, 0x10, 0x0E);
90+
91+
SPI_TRANSFER(0xDF, 0x21, 0x0c, 0x02);
92+
93+
SPI_TRANSFER(0xF0, 0x45, 0x09, 0x08, 0x08, 0x26, 0x2A);
94+
95+
SPI_TRANSFER(0xF1, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6F);
96+
97+
98+
SPI_TRANSFER(0xF2, 0x45, 0x09, 0x08, 0x08, 0x26, 0x2A);
99+
100+
SPI_TRANSFER(0xF3, 0x43, 0x70, 0x72, 0x36, 0x37, 0x6F);
101+
102+
SPI_TRANSFER(0xED, 0x1B, 0x0B);
103+
104+
SPI_TRANSFER(0xAE, 0x77);
105+
106+
SPI_TRANSFER(0xCD, 0x63);
107+
108+
109+
SPI_TRANSFER(0x70, 0x07, 0x07, 0x04, 0x0E, 0x0F, 0x09, 0x07, 0x08, 0x03);
110+
111+
SPI_TRANSFER(0xE8, 0x34);
112+
113+
SPI_TRANSFER(0x62, 0x18, 0x0D, 0x71, 0xED, 0x70, 0x70, 0x18, 0x0F, 0x71, 0xEF, 0x70, 0x70);
114+
115+
SPI_TRANSFER(0x63, 0x18, 0x11, 0x71, 0xF1, 0x70, 0x70, 0x18, 0x13, 0x71, 0xF3, 0x70, 0x70);
116+
117+
SPI_TRANSFER(0x64, 0x28, 0x29, 0xF1, 0x01, 0xF1, 0x00, 0x07);
118+
119+
SPI_TRANSFER(0x66, 0x3C, 0x00, 0xCD, 0x67, 0x45, 0x45, 0x10, 0x00, 0x00, 0x00);
120+
121+
SPI_TRANSFER(0x67, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x01, 0x54, 0x10, 0x32, 0x98);
122+
123+
SPI_TRANSFER(0x74, 0x10, 0x85, 0x80, 0x00, 0x00, 0x4E, 0x00);
124+
125+
SPI_TRANSFER(0x98, 0x3e, 0x07);
126+
127+
SPI_TRANSFER(0x35);
128+
129+
SPI_TRANSFER(0x21);
130+
131+
SPI_TRANSFER(0x11);
132+
usleep(120 * 1000);
133+
SPI_TRANSFER(0x29);
134+
usleep(20 * 1000);
135+
136+
ClearScreen();
137+
}
138+
#ifndef USE_DMA_TRANSFERS // For DMA transfers, keep SPI CS & TA active.
139+
END_SPI_COMMUNICATION();
140+
#endif
141+
142+
// And speed up to the desired operation speed finally after init is done.
143+
usleep(10 * 1000); // Delay a bit before restoring CLK, or otherwise this has been observed to cause the display not init if done back to back after the clear operation above.
144+
spi->clk = SPI_BUS_CLOCK_DIVISOR;
145+
}
146+
147+
void TurnBacklightOn()
148+
{
149+
#if defined(GPIO_TFT_BACKLIGHT) && defined(BACKLIGHT_CONTROL)
150+
SET_GPIO_MODE(GPIO_TFT_BACKLIGHT, 0x01); // Set backlight pin to digital 0/1 output mode (0x01) in case it had been PWM controlled
151+
SET_GPIO(GPIO_TFT_BACKLIGHT); // And turn the backlight on.
152+
#endif
153+
}
154+
155+
void TurnBacklightOff()
156+
{
157+
#if defined(GPIO_TFT_BACKLIGHT) && defined(BACKLIGHT_CONTROL)
158+
SET_GPIO_MODE(GPIO_TFT_BACKLIGHT, 0x01); // Set backlight pin to digital 0/1 output mode (0x01) in case it had been PWM controlled
159+
CLEAR_GPIO(GPIO_TFT_BACKLIGHT); // And turn the backlight off.
160+
#endif
161+
}
162+
163+
void TurnDisplayOff()
164+
{
165+
TurnBacklightOff();
166+
}
167+
168+
void TurnDisplayOn()
169+
{
170+
TurnBacklightOn();
171+
}
172+
173+
void DeinitSPIDisplay()
174+
{
175+
ClearScreen();
176+
SPI_TRANSFER(/*Display OFF*/ 0x28);
177+
TurnBacklightOff();
178+
}
179+
180+
#endif

gc9a01.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#pragma once
2+
3+
#if defined(GC9A01)
4+
5+
// Data specific to the GC9A01 controller
6+
#define DISPLAY_SET_CURSOR_X 0x2A
7+
#define DISPLAY_SET_CURSOR_Y 0x2B
8+
#define DISPLAY_WRITE_PIXELS 0x2C
9+
10+
#define MUST_SEND_FULL_CURSOR_WINDOW
11+
12+
#define DISPLAY_NATIVE_WIDTH 240
13+
#define DISPLAY_NATIVE_HEIGHT 240
14+
15+
#define ALL_TASKS_SHOULD_DMA
16+
#define UPDATE_FRAMES_WITHOUT_DIFFING
17+
18+
#ifdef WAVESHARE_GC9A01
19+
#include "waveshare_gc9a01.h"
20+
#endif
21+
22+
#define InitSPIDisplay InitGC9A01
23+
24+
void InitGC9A01(void);
25+
26+
#endif

waveshare_gc9a01.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#pragma once
2+
3+
// Data specific to WaveShare 240x240, 1.28 inch ISP LCD GC9A01, https://www.waveshare.net/w/upload/5/5e/GC9A01A.pdf
4+
#ifdef WAVESHARE_GC9A01
5+
6+
#if !defined(GPIO_TFT_DATA_CONTROL)
7+
#define GPIO_TFT_DATA_CONTROL 25
8+
#endif
9+
10+
#if !defined(GPIO_TFT_BACKLIGHT)
11+
#define GPIO_TFT_BACKLIGHT 18
12+
#endif
13+
14+
#if !defined(GPIO_TFT_RESET_PIN)
15+
#define GPIO_TFT_RESET_PIN 27
16+
#endif
17+
18+
#undef DISPLAY_OUTPUT_LANDSCAPE
19+
#endif

0 commit comments

Comments
 (0)