]> sigrok.org Git - libsigrokdecode.git/blame - decoders/st7735/pd.py
configure.ac: Also check for Python 3.7.
[libsigrokdecode.git] / decoders / st7735 / pd.py
CommitLineData
f62e32bc
AA
1##
2## This file is part of the libsigrokdecode project.
3##
4## Copyright (C) 2018 Aleksander Alekseev <afiskon@gmail.com>
5##
6## This program is free software; you can redistribute it and/or modify
7## it under the terms of the GNU General Public License as published by
8## the Free Software Foundation; either version 2 of the License, or
9## (at your option) any later version.
10##
11## This program is distributed in the hope that it will be useful,
12## but WITHOUT ANY WARRANTY; without even the implied warranty of
13## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14## GNU General Public License for more details.
15##
16## You should have received a copy of the GNU General Public License
17## along with this program; if not, see <http://www.gnu.org/licenses/>.
18
19import sigrokdecode as srd
20
21MAX_DATA_LEN = 128
22
23# Command ID -> name, short description
24META = {
25 0x00: {'name': 'NOP ', 'desc': 'No operation'},
26 0x01: {'name': 'SWRESET', 'desc': 'Software reset'},
27 0x04: {'name': 'RDDID ', 'desc': 'Read display ID'},
28 0x09: {'name': 'RDDST ', 'desc': 'Read display status'},
29 0x10: {'name': 'SLPIN ', 'desc': 'Sleep in & booster off'},
30 0x11: {'name': 'SLPOUT ', 'desc': 'Sleep out & booster on'},
31 0x12: {'name': 'PTLON ', 'desc': 'Partial mode on'},
32 0x13: {'name': 'NORON ', 'desc': 'Partial off (normal)'},
33 0x20: {'name': 'INVOFF ', 'desc': 'Display inversion off'},
34 0x21: {'name': 'INVON ', 'desc': 'Display inversion on'},
35 0x28: {'name': 'DISPOFF', 'desc': 'Display off'},
36 0x29: {'name': 'DISPON ', 'desc': 'Display on'},
37 0x2A: {'name': 'CASET ', 'desc': 'Column address set'},
38 0x2B: {'name': 'RASET ', 'desc': 'Row address set'},
39 0x2C: {'name': 'RAMWR ', 'desc': 'Memory write'},
40 0x2E: {'name': 'RAMRD ', 'desc': 'Memory read'},
41 0x30: {'name': 'PTLAR ', 'desc': 'Partial start/end address set'},
42 0x36: {'name': 'MADCTL ', 'desc': 'Memory data address control'},
43 0x3A: {'name': 'COLMOD ', 'desc': 'Interface pixel format'},
44 0xB1: {'name': 'FRMCTR1', 'desc': 'Frame rate control (in normal mode / full colors)'},
45 0xB2: {'name': 'FRMCTR2', 'desc': 'Frame rate control (in idle mode / 8-colors)'},
46 0xB3: {'name': 'FRMCTR3', 'desc': 'Frame rate control (in partial mode / full colors) '},
47 0xB4: {'name': 'INVCTR ', 'desc': 'Display inversion control'},
48 0xB6: {'name': 'DISSET5', 'desc': 'Display function set 5'},
49 0xC0: {'name': 'PWCTR1 ', 'desc': 'Power control 1'},
50 0xC1: {'name': 'PWCTR2 ', 'desc': 'Power control 2'},
51 0xC2: {'name': 'PWCTR3 ', 'desc': 'Power control 3'},
52 0xC3: {'name': 'PWCTR4 ', 'desc': 'Power control 4'},
53 0xC4: {'name': 'PWCTR5 ', 'desc': 'Power control 5'},
54 0xC5: {'name': 'VMCTR1 ', 'desc': 'VCOM control 1'},
55 0xDA: {'name': 'RDID1 ', 'desc': 'Read ID1'},
56 0xDB: {'name': 'RDID2 ', 'desc': 'Read ID2'},
57 0xDC: {'name': 'RDID3 ', 'desc': 'Read ID3'},
58 0xDD: {'name': 'RDID4 ', 'desc': 'Read ID4'},
59 0xFC: {'name': 'PWCTR6 ', 'desc': 'Power control 6'},
60 0xE0: {'name': 'GMCTRP1', 'desc': 'Gamma \'+\'polarity correction characteristics setting'},
61 0xE1: {'name': 'GMCTRN1', 'desc': 'Gamma \'-\'polarity correction characteristics setting'},
62}
63
64class Ann:
65 BITS, CMD, DATA, DESC = range(4)
66
67class Decoder(srd.Decoder):
68 api_version = 3
69 id = 'st7735'
70 name = 'ST7735'
71 longname = 'Sitronix ST7735'
72 desc = 'Sitronix ST7735 TFT controller protocol.'
73 license = 'gplv2+'
74 inputs = ['logic']
75 outputs = ['st7735']
76 channels = (
77 {'id': 'cs', 'name': 'CS#', 'desc': 'Chip-select'},
78 {'id': 'clk', 'name': 'CLK', 'desc': 'Clock'},
79 {'id': 'mosi', 'name': 'MOSI', 'desc': 'Master out, slave in'},
80 {'id': 'dc', 'name': 'DC', 'desc': 'Data or command'}
81 )
82 annotations = (
83 ('bit', 'Bit'),
84 ('command', 'Command'),
85 ('data', 'Data'),
86 ('description', 'Description'),
87 )
88 annotation_rows = (
89 ('bits', 'Bits', (Ann.BITS,)),
90 ('fields', 'Fields', (Ann.CMD, Ann.DATA)),
91 ('description', 'Description', (Ann.DESC,)),
92 )
93
94 def __init__(self):
95 self.reset()
96
97 def reset(self):
f62e32bc
AA
98 self.accum_byte = 0
99 self.accum_bits_num = 0
100 self.bit_ss = -1
101 self.byte_ss = -1
102 self.current_bit = -1
103
ef10cea7
UH
104 def start(self):
105 self.out_ann = self.register(srd.OUTPUT_ANN)
106
f62e32bc
AA
107 def put_desc(self, ss, es, cmd, data):
108 if cmd == -1:
109 return
110 if META[cmd]:
111 self.put(ss, es, self.out_ann, [Ann.DESC,
112 ['%s: %s' % (META[cmd]['name'].strip(), META[cmd]['desc'])]])
113 else:
114 # Default description:
115 dots = ''
116 if len(data) == MAX_DATA_LEN:
117 data = data[:-1]
118 dots = '...'
119 data_str = '(none)'
120 if len(data) > 0:
121 data_str = ' '.join(['%02X' % b for b in data])
122 self.put(ss, es, self.out_ann, [Ann.DESC,
123 ['Unknown command: %02X. Data: %s%s' % (cmd, data_str, dots)]])
124
125 def decode(self):
126 current_cmd = -1
127 current_data = []
128 desc_ss = -1
129 desc_es = -1
ef10cea7 130 self.reset()
f62e32bc
AA
131 while True:
132 # Check data on both CLK edges.
133 (cs, clk, mosi, dc) = self.wait({1: 'e'})
134
135 if cs == 1: # Wait for CS = low, ignore the rest.
ef10cea7 136 self.reset()
f62e32bc
AA
137 continue
138
139 if clk == 1:
140 # Read one bit.
141 self.bit_ss = self.samplenum
142 if self.accum_bits_num == 0:
143 self.byte_ss = self.samplenum
144 self.current_bit = mosi
145
146 if (clk == 0) and (self.current_bit >= 0):
147 # Process one bit.
148 self.put(self.bit_ss, self.samplenum, self.out_ann,
149 [Ann.BITS, [str(self.current_bit)]])
150 self.accum_byte = (self.accum_byte << 1) | self.current_bit # MSB-first.
151 self.accum_bits_num += 1
152 if self.accum_bits_num == 8:
153 # Process one byte.
154 ann = Ann.DATA if dc else Ann.CMD # DC = low for commands.
155 self.put(self.byte_ss, self.samplenum, self.out_ann,
156 [ann, ['%02X' % self.accum_byte]])
157 if ann == Ann.CMD:
158 self.put_desc(desc_ss, desc_es, current_cmd, current_data)
159 desc_ss = self.byte_ss
160 desc_es = self.samplenum # For cmds without data.
161 current_cmd = self.accum_byte
162 current_data = []
163 else:
164 if len(current_data) < MAX_DATA_LEN:
165 current_data += [self.accum_byte]
166 desc_es = self.samplenum
167
168 self.accum_bits_num = 0
169 self.accum_byte = 0
170 self.byte_ss = -1
171 self.current_bit = -1
172 self.bit_ss = -1