Skip to content

Commit 0ca479b

Browse files
authored
Merge pull request #238 from BrianPugh/ili9341-generic
Generic/ili9341 Driver
2 parents a69f4b5 + aac1d62 commit 0ca479b

File tree

2 files changed

+220
-0
lines changed

2 files changed

+220
-0
lines changed

driver/generic/ili9xxx-test.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import time
2+
3+
from machine import SPI, Pin
4+
5+
from ili9xxx import Ili9341_hw
6+
7+
8+
def build_rect_buf(w, h, inner=[0x00, 0x00]):
9+
top = b"\xFF\xFF" * w
10+
body = (b"\xFF\xFF\xFF" + bytes(inner) * (w - 3) + b"\xFF\xFF\xFF") * (h - 3)
11+
bot = b"\xFF\xFF" * w
12+
return top + body + bot
13+
14+
15+
spi = SPI(
16+
0,
17+
baudrate=24_000_000,
18+
sck=Pin(18),
19+
mosi=Pin(19),
20+
miso=Pin(16),
21+
)
22+
lcd = Ili9341_hw(spi=spi, cs=17, dc=15, rst=14)
23+
24+
lcd.set_backlight(30)
25+
for rot in (0, 1, 2, 3):
26+
lcd.apply_rotation(rot)
27+
28+
lcd.clear(0x0000)
29+
# 1/4 screen pixels square with white border red backgorund
30+
w, h = lcd.width // 4, lcd.height // 8
31+
bmp = build_rect_buf(w, h, [0x03, 0x03])
32+
t0 = time.ticks_us()
33+
lcd.blit(w, h, w, h, bmp)
34+
t1 = time.ticks_us()
35+
bmp = build_rect_buf(lcd.width, lcd.height // 20, [0x09, 0x09])
36+
lcd.blit(0, 0, lcd.width, lcd.height // 20, bmp)
37+
38+
print("Maximum FPS @24MHz:", 24e6 / (320 * 240 * 16)) # FPS = F/(W*H*BPP)
39+
print(
40+
"Achieved FPS:", 1 / (16 * (t1 - t0) * 1e-6)
41+
) # Note: Test only draws 1/16 of the sreen area
42+
43+
print("Draw TSC calibration pattern")
44+
w, h, wu, hu = lcd.width // 10, lcd.height // 10, lcd.width // 5, lcd.height // 5
45+
bmp = build_rect_buf(w, h, [0xA0, 0xF0])
46+
lcd.blit(wu, hu, w, h, bmp)
47+
lcd.blit(4 * wu, hu, w, h, bmp)
48+
lcd.blit(4 * wu, 4 * hu, w, h, bmp)
49+
lcd.blit(wu, 4 * hu, w, h, bmp)
50+
time.sleep(0.5)

driver/generic/ili9xxx.py

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
"""Generic ILI9xxx drivers.
2+
3+
This code is licensed under MIT license.
4+
5+
Adapted from:
6+
https://github.com/rdagger/micropython-ili9341
7+
8+
The following code snippet will instantiate the driver and
9+
automatically register it to lvgl. Adjust the SPI bus and
10+
pin configurations to match your hardware setup::
11+
12+
import ili9xxx
13+
from machine import SPI, Pin
14+
spi = SPI(0, baudrate=24_000_000, sck=Pin(18), mosi=Pin(19), miso=Pin(16))
15+
drv = ili9xxx.Ili9341(spi=spi, dc=15, cs=17, rst=14)
16+
"""
17+
from micropython import const
18+
19+
import st77xx
20+
21+
# Command constants from ILI9341 datasheet
22+
_NOP = const(0x00) # No-op
23+
_SWRESET = const(0x01) # Software reset
24+
_RDDID = const(0x04) # Read display ID info
25+
_RDDST = const(0x09) # Read display status
26+
_SLPIN = const(0x10) # Enter sleep mode
27+
_SLPOUT = const(0x11) # Exit sleep mode
28+
_PTLON = const(0x12) # Partial mode on
29+
_NORON = const(0x13) # Normal display mode on
30+
_RDMODE = const(0x0A) # Read display power mode
31+
_RDMADCTL = const(0x0B) # Read display MADCTL
32+
_RDPIXFMT = const(0x0C) # Read display pixel format
33+
_RDIMGFMT = const(0x0D) # Read display image format
34+
_RDSELFDIAG = const(0x0F) # Read display self-diagnostic
35+
_INVOFF = const(0x20) # Display inversion off
36+
_INVON = const(0x21) # Display inversion on
37+
_GAMMASET = const(0x26) # Gamma set
38+
_DISPLAY_OFF = const(0x28) # Display off
39+
_DISPLAY_ON = const(0x29) # Display on
40+
_SET_COLUMN = const(0x2A) # Column address set
41+
_SET_PAGE = const(0x2B) # Page address set
42+
_WRITE_RAM = const(0x2C) # Memory write
43+
_READ_RAM = const(0x2E) # Memory read
44+
_PTLAR = const(0x30) # Partial area
45+
_VSCRDEF = const(0x33) # Vertical scrolling definition
46+
_MADCTL = const(0x36) # Memory access control
47+
_VSCRSADD = const(0x37) # Vertical scrolling start address
48+
_PIXFMT = const(0x3A) # COLMOD: Pixel format set
49+
_WRITE_DISPLAY_BRIGHTNESS = const(0x51) # Brightness hardware dependent!
50+
_READ_DISPLAY_BRIGHTNESS = const(0x52)
51+
_WRITE_CTRL_DISPLAY = const(0x53)
52+
_READ_CTRL_DISPLAY = const(0x54)
53+
_WRITE_CABC = const(0x55) # Write Content Adaptive Brightness Control
54+
_READ_CABC = const(0x56) # Read Content Adaptive Brightness Control
55+
_WRITE_CABC_MINIMUM = const(0x5E) # Write CABC Minimum Brightness
56+
_READ_CABC_MINIMUM = const(0x5F) # Read CABC Minimum Brightness
57+
_FRMCTR1 = const(0xB1) # Frame rate control (In normal mode/full colors)
58+
_FRMCTR2 = const(0xB2) # Frame rate control (In idle mode/8 colors)
59+
_FRMCTR3 = const(0xB3) # Frame rate control (In partial mode/full colors)
60+
_INVCTR = const(0xB4) # Display inversion control
61+
_DFUNCTR = const(0xB6) # Display function control
62+
_PWCTR1 = const(0xC0) # Power control 1
63+
_PWCTR2 = const(0xC1) # Power control 2
64+
_PWCTRA = const(0xCB) # Power control A
65+
_PWCTRB = const(0xCF) # Power control B
66+
_VMCTR1 = const(0xC5) # VCOM control 1
67+
_VMCTR2 = const(0xC7) # VCOM control 2
68+
_RDID1 = const(0xDA) # Read ID 1
69+
_RDID2 = const(0xDB) # Read ID 2
70+
_RDID3 = const(0xDC) # Read ID 3
71+
_RDID4 = const(0xDD) # Read ID 4
72+
_GMCTRP1 = const(0xE0) # Positive gamma correction
73+
_GMCTRN1 = const(0xE1) # Negative gamma correction
74+
_DTCA = const(0xE8) # Driver timing control A
75+
_DTCB = const(0xEA) # Driver timing control B
76+
_POSC = const(0xED) # Power on sequence control
77+
_ENABLE3G = const(0xF2) # Enable 3 gamma control
78+
_PUMPRC = const(0xF7) # Pump ratio control
79+
80+
_MADCTL_MY = const(0x80) # page address order (0: top to bottom; 1: bottom to top)
81+
_MADCTL_MX = const(0x40) # column address order (0: left to right; 1: right to left)
82+
_MADCTL_MV = const(0x20) # page/column order (0: normal mode 1; reverse mode)
83+
_MADCTL_ML = const(
84+
0x10
85+
) # line address order (0: refresh to to bottom; 1: refresh bottom to top)
86+
_MADCTL_BGR = const(0x08) # colors are BGR (not RGB)
87+
_MADCTL_RTL = const(0x04) # refresh right to left
88+
89+
_MADCTL_ROTS = (
90+
const(_MADCTL_MX), # 0 = portrait
91+
const(_MADCTL_MV), # 1 = landscape
92+
const(_MADCTL_MY), # 2 = inverted portrait
93+
const(_MADCTL_MX | _MADCTL_MY | _MADCTL_MV), # 3 = inverted landscape
94+
)
95+
96+
ILI9XXX_PORTRAIT = st77xx.ST77XX_PORTRAIT
97+
ILI9XXX_LANDSCAPE = st77xx.ST77XX_LANDSCAPE
98+
ILI9XXX_INV_PORTRAIT = st77xx.ST77XX_INV_PORTRAIT
99+
ILI9XXX_INV_LANDSCAPE = st77xx.ST77XX_INV_LANDSCAPE
100+
101+
102+
class Ili9341_hw(st77xx.St77xx_hw):
103+
def __init__(self, **kw):
104+
"""ILI9341 TFT Display Driver.
105+
106+
Requires ``LV_COLOR_DEPTH=16`` when building lv_micropython to function.
107+
"""
108+
super().__init__(
109+
res=(240, 320),
110+
suppRes=[
111+
(240, 320),
112+
],
113+
model=None,
114+
suppModel=None,
115+
bgr=False,
116+
**kw,
117+
)
118+
119+
def config_hw(self):
120+
self._run_seq(
121+
[
122+
(_SLPOUT, None, 100),
123+
(_PWCTRB, b"\x00\xC1\x30"), # Pwr ctrl B
124+
(_POSC, b"\x64\x03\x12\x81"), # Pwr on seq. ctrl
125+
(_DTCA, b"\x85\x00\x78"), # Driver timing ctrl A
126+
(_PWCTRA, b"\x39\x2C\x00\x34\x02"), # Pwr ctrl A
127+
(_PUMPRC, b"\x20"), # Pump ratio control
128+
(_DTCB, b"\x00\x00"), # Driver timing ctrl B
129+
(_PWCTR1, b"\x23"), # Pwr ctrl 1
130+
(_PWCTR2, b"\x10"), # Pwr ctrl 2
131+
(_VMCTR1, b"\x3E\x28"), # VCOM ctrl 1
132+
(_VMCTR2, b"\x86"), # VCOM ctrl 2
133+
(_VSCRSADD, b"\x00"), # Vertical scrolling start address
134+
(_PIXFMT, b"\x55"), # COLMOD: Pixel format
135+
(_FRMCTR1, b"\x00\x18"), # Frame rate ctrl
136+
(_DFUNCTR, b"\x08\x82\x27"),
137+
(_ENABLE3G, b"\x00"), # Enable 3 gamma ctrl
138+
(_GAMMASET, b"\x01"), # Gamma curve selected
139+
(
140+
_GMCTRP1,
141+
b"\x0F\x31\x2B\x0C\x0E\x08\x4E\xF1\x37\x07\x10\x03\x0E\x09\x00",
142+
),
143+
(
144+
_GMCTRN1,
145+
b"\x00\x0E\x14\x03\x11\x07\x31\xC1\x48\x08\x0F\x0C\x31\x36\x0F",
146+
),
147+
(_SLPOUT, None, 100),
148+
(_DISPLAY_ON, None),
149+
]
150+
)
151+
152+
def apply_rotation(self, rot):
153+
self.rot = rot
154+
if (self.rot % 2) == 0:
155+
self.width, self.height = self.res
156+
else:
157+
self.height, self.width = self.res
158+
self.write_register(
159+
_MADCTL,
160+
bytes([_MADCTL_BGR | _MADCTL_ROTS[self.rot % 4]]),
161+
)
162+
163+
164+
class Ili9341(Ili9341_hw, st77xx.St77xx_lvgl):
165+
def __init__(self, doublebuffer=True, factor=4, **kw):
166+
"""See :obj:`Ili9341_hw` for the meaning of the parameters."""
167+
import lvgl as lv
168+
169+
Ili9341_hw.__init__(self, **kw)
170+
st77xx.St77xx_lvgl.__init__(self, doublebuffer, factor)

0 commit comments

Comments
 (0)