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