]> sigrok.org Git - libsigrokdecode.git/blame - decoders/maple_bus/pd.py
all decoders: introduce a reset() method
[libsigrokdecode.git] / decoders / maple_bus / pd.py
CommitLineData
4cd8ac1d
MC
1##
2## This file is part of the libsigrokdecode project.
3##
4## Copyright (C) 2017 Marcus Comstedt <marcus@mc.pp.se>
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##
19
20import sigrokdecode as srd
21
22ann = [
23 ['Size', 'L'],
24 ['SrcAP', 'S'],
25 ['DstAP', 'D'],
26 ['Cmd', 'C'],
27 ['Data'],
28 ['Cksum', 'K'],
29]
30
31class Decoder(srd.Decoder):
32 api_version = 3
33 id = 'maple_bus'
34 name = 'Maple bus'
35 longname = 'SEGA Maple bus'
36 desc = 'Maple bus peripheral protocol for SEGA Dreamcast.'
37 license = 'gplv2+'
38 inputs = ['logic']
39 outputs = ['maple_bus']
40 channels = (
41 {'id': 'sdcka', 'name': 'SDCKA', 'desc': 'Data/clock line A'},
42 {'id': 'sdckb', 'name': 'SDCKB', 'desc': 'Data/clock line B'},
43 )
44 annotations = (
45 ('start', 'Start pattern'),
46 ('end', 'End pattern'),
47 ('start-with-crc', 'Start pattern with CRC'),
48 ('occupancy', 'SDCKB occupancy pattern'),
49 ('reset', 'RESET pattern'),
50 ('bit', 'Bit'),
51 ('size', 'Data size'),
52 ('source', 'Source AP'),
53 ('dest', 'Destination AP'),
54 ('command', 'Command'),
55 ('data', 'Data'),
56 ('checksum', 'Checksum'),
57 ('frame-error', 'Frame error'),
58 ('checksum-error', 'Checksum error'),
59 ('size-error', 'Size error'),
60 )
61 annotation_rows = (
62 ('bits', 'Bits', (0, 1, 2, 3, 4, 5)),
63 ('fields', 'Fields', (6, 7, 8, 9, 10, 11)),
64 ('warnings', 'Warnings', (12, 13, 14)),
65 )
66 binary = (
67 ('size', 'Data size'),
68 ('source', 'Source AP'),
69 ('dest', 'Destination AP'),
70 ('command', 'Command code'),
71 ('data', 'Data'),
72 ('checksum', 'Checksum'),
73 )
74
75 def __init__(self):
10aeb8ea
GS
76 self.reset()
77
78 def reset(self):
4cd8ac1d
MC
79 pass
80
81 def start(self):
82 self.out_ann = self.register(srd.OUTPUT_ANN)
83 self.out_binary = self.register(srd.OUTPUT_BINARY)
84 self.pending_bit_pos = None
85
e0e7be8a
UH
86 def putx(self, data):
87 self.put(self.ss, self.es, self.out_ann, data)
88
89 def putb(self, data):
90 self.put(self.ss, self.es, self.out_binary, data)
91
4cd8ac1d
MC
92 def byte_annotation(self, bintype, d):
93 return [bintype + 6,
94 ['%s: %02X' % (name, d) for name in ann[bintype]] + ['%02X' % d]]
95
96 def got_start(self):
e0e7be8a 97 self.putx([0, ['Start pattern', 'Start', 'S']])
4cd8ac1d
MC
98
99 def got_end(self):
e0e7be8a 100 self.putx([1, ['End pattern', 'End', 'E']])
4cd8ac1d 101 if self.length != self.expected_length + 1:
e0e7be8a 102 self.putx([14, ['Size error', 'L error', 'LE']])
4cd8ac1d
MC
103
104 def got_start_with_crc(self):
e0e7be8a 105 self.putx([2, ['Start pattern with CRC', 'Start CRC', 'SC']])
4cd8ac1d
MC
106
107 def got_occupancy(self):
e0e7be8a 108 self.putx([3, ['SDCKB occupancy pattern', 'Occupancy', 'O']])
4cd8ac1d
MC
109
110 def got_reset(self):
e0e7be8a 111 self.putx([4, ['RESET pattern', 'RESET', 'R']])
4cd8ac1d
MC
112
113 def output_pending_bit(self):
114 if self.pending_bit_pos:
115 self.put(self.pending_bit_pos, self.pending_bit_pos, self.out_ann, [5, ['Bit: %d' % self.pending_bit, '%d' % self.pending_bit]])
116
117 def got_bit(self, n):
118 self.output_pending_bit()
119 self.data = self.data * 2 + n
120 self.pending_bit = n
121 self.pending_bit_pos = self.samplenum
122
123 def got_byte(self):
124 self.output_pending_bit()
125 bintype = 4
126 if self.length < 4:
127 if self.length == 0:
128 self.expected_length = 4 * (self.data + 1)
129 bintype = self.length
130 elif self.length == self.expected_length:
131 bintype = 5
132 if self.data != self.checksum:
e0e7be8a 133 self.putx([13, ['Cksum error', 'K error', 'KE']])
4cd8ac1d
MC
134 self.length = self.length + 1
135 self.checksum = self.checksum ^ self.data
e0e7be8a
UH
136 self.putx(self.byte_annotation(bintype, self.data))
137 self.putb([bintype, bytes([self.data])])
4cd8ac1d
MC
138 self.pending_bit_pos = None
139
140 def frame_error(self):
e0e7be8a 141 self.putx([7, ['Frame error', 'F error', 'FE']])
4cd8ac1d
MC
142
143 def handle_start(self):
144 self.wait({0: 'l', 1: 'h'})
145 self.ss = self.samplenum
146 count = 0
147 while True:
148 sdcka, sdckb = self.wait([{1: 'f'}, {0: 'r'}])
149 if self.matched[0]:
150 count = count + 1
151 if self.matched[1]:
152 self.es = self.samplenum
153 if sdckb == 1:
154 if count == 4:
155 self.got_start()
156 return True
157 elif count == 6:
158 self.got_start_with_crc()
159 return True
160 elif count == 8:
161 self.got_occupancy()
162 return False
163 elif count >= 14:
164 self.got_reset()
165 return False
166 self.frame_error()
167 return False
168
169 def handle_byte_or_stop(self):
170 self.ss = self.samplenum
171 self.pending_bit_pos = None
172 initial = True
173 counta = 0
174 countb = 0
175 self.data = 0
176 while countb < 4:
177 sdcka, sdckb = self.wait([{0: 'f'}, {1: 'f'}])
178 self.es = self.samplenum
179 if self.matched[0]:
180 if counta == countb:
181 self.got_bit(sdckb)
182 counta = counta + 1
183 elif counta == 1 and countb == 0 and self.data == 0 and sdckb == 0:
184 self.wait([{0: 'h', 1: 'h'}, {0: 'f'}, {1: 'f'}])
185 self.es = self.samplenum
186 if self.matched[0]:
187 self.got_end()
188 else:
189 self.frame_error()
190 return False
191 else:
192 self.frame_error()
193 return False
194 elif self.matched[1]:
195 if counta == countb + 1:
196 self.got_bit(sdcka)
197 countb = countb + 1
198 elif counta == 0 and countb == 0 and sdcka == 1 and initial:
199 self.ss = self.samplenum
200 initial = False
201 else:
202 self.frame_error()
203 return False
204 self.wait({0: 'h'})
205 self.es = self.samplenum
206 self.got_byte()
207 return True
208
209 def decode(self):
210 while True:
211 while not self.handle_start():
212 pass
213 self.length = 0
214 self.expected_length = 4
215 self.checksum = 0
216 while self.handle_byte_or_stop():
217 pass