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