-
Notifications
You must be signed in to change notification settings - Fork 0
/
uart_if.py
205 lines (184 loc) · 6.3 KB
/
uart_if.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#!/usr/bin/python
from __future__ import print_function
from __future__ import unicode_literals
import struct
import sys
import codecs
import time
import serial
class UartIf(object):
RDDST = 0x09 # 8.2.4 Read Display Status (page 92)
RDDMADCTL = 0x0B # 8.2.6 Read Display MADCTL (page 95)
SLPOUT = 0x11 # 8.2.12 Sleep Out (page 101)
DISPON = 0x29 # 8.2.19 Display ON (page 109)
CASET = 0x2A # 8.2.20 Column Address Set (page 110)
PASET = 0x2B # 8.2.21 Page Address Set (page 112)
RAMWR = 0x2C # 8.2.22 Memory Write (page 114)
RGBSET = 0x2D # 8.2.23 Color Set (page 115)
RAMRD = 0x2E # 8.2.24 Memory Read (page 116)
MADCTL = 0x36 # 8.2.29 Memory Access Control (page 127)
COLMOD = 0x3A # 8.2.33 Pixel Format Set (page 134)
Write_Memory_Continue = 0x3C # 8.2.34 Write_Memory_Continue (page 135)
Read_Memory_Continue = 0x3E # 8.2.35 Read_Memory_Continue (page 137)
def __init__(self):
# Non-negative when queueing commands; length of command queue
# -1 : Not queueing commands
self.buflen = -1
self.exc_on_error = True
self.autoflush = True
def send_command(self, c, d):
if self.buflen >= 16:
if not self.autoflush:
print('Buffer full!')
if self.exc_on_error:
raise Exception()
else:
return
else:
print('Flushing')
self.lt24_release()
self.lt24_hold()
if self.buflen >= 0:
self.buflen += 1
s = struct.pack('<BH', c, d)
print('> {}'.format(codecs.encode(s, 'hex_codec')))
self.ser.write(s)
def read_reply_raw(self):
r = self.ser.read(3)
print('< {}'.format(codecs.encode(r, 'hex_codec')))
return r
def read_reply(self, exp_c = None, exp_d = None):
if self.buflen >= 0:
self.expbuf.append((exp_c, exp_d))
return
r = self.read_reply_raw()
if len(r) != 3:
print('Connection dropped!')
if self.exc_on_error:
raise Exception()
else:
return
c, d = struct.unpack(b'<BH', r)
if exp_c is None:
return d
if c != exp_c or (exp_d is not None and d != exp_d):
print(('Response error: expected {}:{}, got {}:{}'
).format(exp_c, exp_d, c, d))
if self.exc_on_error:
raise Exception()
#raise Exception()
return d
def lt24_reset(self, data = 0):
self.send_command(0, data)
time.sleep(0.2)
self.read_reply(0, data)
def lt24_command(self, data):
self.send_command(1, data)
self.read_reply(1, data)
def lt24_write(self, data):
self.send_command(2, data)
self.read_reply(2, data)
def lt24_read_fm(self, data = 0):
self.send_command(3, data)
d = self.read_reply(3)
return d
def lt24_read_id(self, data = 0):
self.send_command(4, data)
d = self.read_reply(4)
return d
def lt24_hold(self, data = 0):
self.send_command(5, data)
self.buflen = 0
self.expbuf = list()
def lt24_release(self, data = 0):
self.buflen = -1
self.send_command(6, data)
for exp_c, exp_d in self.expbuf:
self.read_reply(exp_c, exp_d)
del self.expbuf
def lt24_gpio(self, data):
self.send_command(7, data)
d = self.read_reply(7)
return d
def run(self):
self.ser = serial.Serial('/dev/ttyUSB0', 115200)
self.ser.timeout = 0.1
def trivial_palette(self):
self.lt24_command(self.RGBSET)
for r in range(31):
self.lt24_write(r * 2)
for g in range(63):
self.lt24_write(g)
for b in range(31):
self.lt24_write(b * 2)
def init_lt24(self):
self.lt24_reset()
self.lt24_command(self.MADCTL)
self.lt24_write(0b11101000) # Coordinate change, BGR subpixel order
self.lt24_command(self.COLMOD)
self.lt24_write(0b101) # 16bpp MCU interface
self.trivial_palette()
self.lt24_command(self.SLPOUT)
self.lt24_command(self.DISPON)
def gradient(self, color, length):
if color == 0:
# Red
shift = 11
add = 0
elif color == 1:
# Green
shift = 6
add = 1
else:
# Blue
shift = 0
add = 0
for brightness in range(add, length + add):
pixel = brightness << shift
self.lt24_write(pixel)
def colorbars(self):
self.lt24_command(self.RAMWR)
for colblock in range(3):
for coloffset in range(3):
for elementwidth in range(32):
for rowblock in range(2):
for element in range(3):
color = (element + coloffset) % 3
self.gradient(color, 32)
color = coloffset % 3
self.gradient(color, 32)
color = (coloffset + 1) % 3
self.gradient(color, 16)
for elementwidth in range(32):
for rowblock in range(2):
for element in range(3):
color = element
self.gradient(color, 32)
self.gradient(0, 32)
self.gradient(1, 16)
def pixel_counter(self, n):
"""Write a count in the green subpixel"""
for i in range(n):
self.lt24_write(i << 5)
def read_pixels(self, n):
pixels = list()
for i in range(n // 2):
w1 = self.lt24_read_fm()
w2 = self.lt24_read_fm()
w3 = self.lt24_read_fm()
g1 = (w1 >> 2) & 63
r1 = w1 >> 10
r2 = (w2 >> 2) & 63
b1 = w2 >> 10
b2 = (w3 >> 2) & 63
g2 = w3 >> 10
pixels.append((r1, g1, b1))
pixels.append((r2, g2, b2))
if n % 2:
w1 = self.lt24_read_fm()
w2 = self.lt24_read_fm()
g1 = (w1 >> 2) & 63
r1 = w1 >> 10
b1 = w2 >> 10
pixels.append((r1, g1, b1))
return pixels