]> sigrok.org Git - libsigrokdecode.git/blame_incremental - decoders/maple_bus/pd.py
avr_isp: Add more parts
[libsigrokdecode.git] / decoders / maple_bus / pd.py
... / ...
CommitLineData
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
21from common.srdhelper import SrdIntEnum
22
23Pin = SrdIntEnum.from_str('Pin', 'SDCKA SDCKB')
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']
42 outputs = []
43 tags = ['Retro computing']
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):
80 self.reset()
81
82 def reset(self):
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
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
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):
101 self.putx([0, ['Start pattern', 'Start', 'S']])
102
103 def got_end(self):
104 self.putx([1, ['End pattern', 'End', 'E']])
105 if self.length != self.expected_length + 1:
106 self.putx([14, ['Size error', 'L error', 'LE']])
107
108 def got_start_with_crc(self):
109 self.putx([2, ['Start pattern with CRC', 'Start CRC', 'SC']])
110
111 def got_occupancy(self):
112 self.putx([3, ['SDCKB occupancy pattern', 'Occupancy', 'O']])
113
114 def got_reset(self):
115 self.putx([4, ['RESET pattern', 'RESET', 'R']])
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:
137 self.putx([13, ['Cksum error', 'K error', 'KE']])
138 self.length = self.length + 1
139 self.checksum = self.checksum ^ self.data
140 self.putx(self.byte_annotation(bintype, self.data))
141 self.putb([bintype, bytes([self.data])])
142 self.pending_bit_pos = None
143
144 def frame_error(self):
145 self.putx([7, ['Frame error', 'F error', 'FE']])
146
147 def handle_start(self):
148 self.wait({Pin.SDCKA: 'l', Pin.SDCKB: 'h'})
149 self.ss = self.samplenum
150 count = 0
151 while True:
152 sdcka, sdckb = self.wait([{Pin.SDCKB: 'f'}, {Pin.SDCKA: 'r'}])
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:
181 sdcka, sdckb = self.wait([{Pin.SDCKA: 'f'}, {Pin.SDCKB: 'f'}])
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:
188 self.wait([{Pin.SDCKA: 'h', Pin.SDCKB: 'h'},
189 {Pin.SDCKA: 'f'}, {Pin.SDCKB: 'f'}])
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
209 self.wait({Pin.SDCKA: 'h'})
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