Skip to content

Commit 172d8bb

Browse files
Add files via upload
1 parent 58bbb92 commit 172d8bb

File tree

1 file changed

+209
-0
lines changed

1 file changed

+209
-0
lines changed

lib/st7789py_parallel.py

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# Extended Class to use TFT ST7789 in parallel bus
2+
3+
from micropython import const
4+
from utime import sleep_ms, sleep_us
5+
from machine import Pin
6+
7+
## Pins (wiring) example and description
8+
#ST7789 STM32F407VGT6
9+
#LCD_RST <---> 3.3V #LCD reset control pin, active low, used to force a hardware reset of the board, if unused need be plug on 3.3V
10+
#LCD_CS <---> GND #LCD chip select control pin, active low, if used only one LCD can be plug on GND
11+
#LCD_RS <---> PD13 #LCD register command / data selection control pin, comand active low, data active high
12+
#LCD_WR <---> PD5 #LCD write control pin, active low
13+
#LCD_RD <---> PD4 #LCD read control pin, active low
14+
#GND <---> GND
15+
#5V <---> 5V
16+
17+
#LCD_D2 <---> PD0
18+
#LCD_D3 <---> PD1
19+
#LCD_D4 <---> PE7
20+
#LCD_D5 <---> PE8
21+
#LCD_D6 <---> PE9
22+
#LCD_D7 <---> PE10
23+
#LCD_D0 <---> PD14
24+
#LCD_D1 <---> PD15
25+
26+
## DEFINE PINS CONST
27+
_LCD_RST = const(None) #LCD reset control pin, active low
28+
_LCD_CS = const(None) #LCD chip select control pin, active low
29+
_LCD_RS = const(4) #LCD register command / data selection control pin, comand active low, data active high
30+
_LCD_WR = const(5) #LCD write control pin, active low
31+
_LCD_RD = const(None) #LCD read control pin, active low
32+
33+
_LCD_D0 = const(12)
34+
_LCD_D1 = const(_LCD_D0 + 1)
35+
_LCD_D2 = const(_LCD_D0 + 2)
36+
_LCD_D3 = const(_LCD_D0 + 3)
37+
_LCD_D4 = const(_LCD_D0 + 4)
38+
_LCD_D5 = const(_LCD_D0 + 5)
39+
_LCD_D6 = const(_LCD_D0 + 6)
40+
_LCD_D7 = const(_LCD_D0 + 7)
41+
42+
## ESP32 GPIO REGISTERS
43+
_ESP32_GPIO_OUT_REG = const(0x3FF44004) # GPIO0-31 output value. (R/W), 32 bits from rigth to left ref pins numbers from 0 to 31
44+
_ESP32_GPIO_OUT_W1TS_REG = const(0x3FF44008) # GPIO0-31 output set register. For every bit that is 1 in the value written here, the corresponding bit in GPIO_OUT_REG will be set. (WO)
45+
_ESP32_GPIO_OUT_W1TC_REG = const(0x3FF4400C) # GPIO0-31 output clear register. For every bit that is 1 in the value written here, the corresponding bit in GPIO_OUT_REG will be cleared. (WO)
46+
47+
_ESP32_GPIO_OUT1_REG = const(0x3FF44010) # GPIO32-39 output value. (R/W), 32 bits from rigth to left ref pins numbers from 32 to 39
48+
_ESP32_GPIO_OUT1_W1TS_REG = const(0x3FF44014) # GPIO32-39 output set register. For every bit that is 1 in the value written here, the corresponding bit in GPIO_OUT_REG will be set. (WO)
49+
_ESP32_GPIO_OUT1_W1TC_REG = const(0x3FF44018) # GPIO32-39 output clear register. For every bit that is 1 in the value written here, the corresponding bit in GPIO_OUT_REG will be cleared. (WO)
50+
51+
_ESP32_GPIO_IN_REG = const(0x3FF4403C) #GPIO 0-31 input register (RO)
52+
_ESP32_GPIO_IN1_REG = const(0x3FF44040) #GPIO 32-39 input register (RO)
53+
54+
from st7789py import *
55+
56+
_ENCODE_PIXEL = const(">H")
57+
_ENCODE_POS = const(">HH")
58+
_DECODE_PIXEL = const(">BBB")
59+
60+
def _encode_pos(x, y):
61+
"""Encode a postion into bytes."""
62+
return struct.pack(_ENCODE_POS, x, y)
63+
64+
65+
def _encode_pixel(color):
66+
"""Encode a pixel color into bytes."""
67+
return struct.pack(_ENCODE_PIXEL, color)
68+
69+
class ST7789_PARALLEL(ST7789):
70+
def __init__(self, width:(int) = 320, height:(int) = 240, rotation=0,
71+
rst_pin:(int,None) = _LCD_RST, # LCD reset control pin
72+
cs_pin:(int,None) = _LCD_CS, # LCD chip select control pin
73+
rs_pin:(int,None) = _LCD_RS, #**Required** LCD register command / data selection control pin,
74+
wr_pin:(int,None) = _LCD_WR, #**Required** LCD write control pin, active low
75+
rd_pin:(int,None) = _LCD_RD, # LCD read control pin, active low
76+
d0_pin:(int,None) = _LCD_D0 #**Required** LCD D0 pin, all otherpins will be pick seguentially after this.
77+
):
78+
if height != 240 or width not in [320, 240, 135]:
79+
raise ValueError("Unsupported display. 320x240, 240x240 and 135x240 are supported.")
80+
if rs_pin is None:
81+
raise ValueError("rs pin (data/command) is required.")
82+
if d0_pin is None or (d0_pin + 8) > 31 :
83+
raise ValueError("d0_pin is required, need to be continuos and bellow 23, the rest of data pins will be assign seguentially, ex, d0_pin = 12, d1_pin=13, ... ")
84+
85+
for x in (rst_pin, cs_pin, rs_pin, wr_pin, rd_pin, d0_pin):
86+
if x != None and ((x<0) or (x>44)) :
87+
raise ValueError("Pins numbers need to between 0 and 44")
88+
89+
90+
self.rst_pin_mask = self.cs_pin_mask = self.rs_pin_mask = (_ESP32_GPIO_OUT_REG, 0b0)
91+
self.wr_pin_mask = self.rd_pin_mask = self.d_pin_mask = self.rst_pin_mask
92+
93+
self.rst_pin = self.reset = rst_pin
94+
if rst_pin != None :
95+
self.rst_pin = self.reset = Pin(rst_pin, Pin.OUT, value=1)
96+
if rst_pin < 32 :
97+
self.rst_pin_mask = (_ESP32_GPIO_OUT_REG, 1 << rst_pin)
98+
else :
99+
self.rst_pin_mask = (_ESP32_GPIO_OUT1_REG, 1 << rst_pin-32)
100+
101+
self.cs_pin = self.cs = cs_pin
102+
if cs_pin != None :
103+
self.cs_pin = self.cs = Pin(cs_pin,Pin.OUT, value=1)
104+
if cs_pin < 32 :
105+
self.cs_pin_mask = (_ESP32_GPIO_OUT_REG, 1 << cs_pin)
106+
else :
107+
self.cs_pin_mask = (_ESP32_GPIO_OUT1_REG, 1 << cs_pin-32)
108+
109+
self.rs_pin = self.dc = rs_pin
110+
if rs_pin != None :
111+
self.rs_pin = self.dc = Pin(rs_pin, Pin.OUT, value=0)
112+
if rs_pin < 32 :
113+
self.rs_pin_mask = (_ESP32_GPIO_OUT_REG, 1 << rs_pin)
114+
else :
115+
self.rs_pin_mask = (_ESP32_GPIO_OUT1_REG, 1 << rs_pin-32)
116+
117+
self.wr_pin = wr_pin
118+
if wr_pin != None :
119+
self.wr_pin = Pin(wr_pin, Pin.OUT, value=1)
120+
if wr_pin < 32 :
121+
self.wr_pin_mask = (_ESP32_GPIO_OUT_REG, 1 << wr_pin)
122+
else :
123+
self.wr_pin_mask = (_ESP32_GPIO_OUT1_REG, 1 << wr_pin-32)
124+
125+
self.rd_pin = rd_pin
126+
if rd_pin != None :
127+
self.rd_pin = Pin(rd_pin, Pin.OUT, value=1)
128+
if rd_pin < 32 :
129+
self.rd_pin_mask = (_ESP32_GPIO_OUT_REG, 1 << rd_pin)
130+
else :
131+
self.rd_pin_mask = (_ESP32_GPIO_OUT1_REG, 1 << rd_pin-32)
132+
133+
self.d_pin = []
134+
for x in range(0, 8) :
135+
self.d_pin.append(Pin(d0_pin + x, Pin.OUT, value=0))
136+
self.d_pin_mask = (_ESP32_GPIO_OUT_REG, 0b11111111 << d0_pin)
137+
self.d0_pin = d0_pin
138+
139+
self._display_width = self.width = width
140+
self._display_height = self.height = height
141+
self.xstart = 0
142+
self.ystart = 0
143+
144+
self.backlight = None
145+
self._rotation = rotation % 4
146+
147+
self.hard_reset()
148+
self.soft_reset()
149+
self.sleep_mode(False)
150+
151+
self._set_color_mode(COLOR_MODE_65K | COLOR_MODE_16BIT)
152+
time.sleep_ms(50)
153+
self.rotation(self._rotation)
154+
self.inversion_mode(False)
155+
time.sleep_ms(10)
156+
self._write(ST7789_NORON)
157+
time.sleep_ms(10)
158+
self.fill(0)
159+
self._write(ST7789_DISPON)
160+
time.sleep_ms(500)
161+
162+
@micropython.viper
163+
def _write_v(self, data: ptr8, size:int, repeat:int):
164+
gpio_data = ptr32(self.d_pin_mask[0])
165+
gpio_wr = ptr32(self.wr_pin_mask[0])
166+
wr_pin_mask = int(self.wr_pin_mask[1])
167+
d_pin_mask = int(self.d_pin_mask[1])
168+
d0_pin = int(self.d0_pin)
169+
for _ in range(0,repeat):
170+
for x in range(0,size):
171+
gpio_data[2] = d_pin_mask
172+
gpio_data[1] = int(data[x] << d0_pin)
173+
gpio_wr[2] = wr_pin_mask
174+
gpio_wr[1] = wr_pin_mask
175+
176+
@micropython.native
177+
def _write(self, command=None, data=None, repeat=1):
178+
"""ParallelSPI write to the device: commands and data."""
179+
if self.cs:
180+
self.cs.off()
181+
182+
if command is not None:
183+
self.dc.off()
184+
if command is not None:
185+
command=bytearray([command])
186+
self._write_v(command,len(command), repeat)
187+
if data is not None:
188+
self.dc.on()
189+
if data is not None:
190+
self._write_v(data,len(data), repeat)
191+
if self.cs:
192+
self.cs.on()
193+
194+
def fill_rect(self, x, y, width, height, color):
195+
"""
196+
Draw a rectangle at the given location, size and filled with color.
197+
198+
Args:
199+
x (int): Top left corner x coordinate
200+
y (int): Top left corner y coordinate
201+
width (int): Width in pixels
202+
height (int): Height in pixels
203+
color (int): 565 encoded color
204+
"""
205+
self._set_window(x, y, x + width - 1, y + height - 1)
206+
pixel = _encode_pixel(color)
207+
208+
self._write(None,pixel,width * height)
209+

0 commit comments

Comments
 (0)