2 ## This file is part of the libsigrokdecode project.
4 ## Copyright (C) 2017 Marcus Comstedt <marcus@mc.pp.se>
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.
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.
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/>.
20 import sigrokdecode as srd
31 class Decoder(srd.Decoder):
35 longname = 'SEGA Maple bus'
36 desc = 'Maple bus peripheral protocol for SEGA Dreamcast.'
40 tags = ['Retro computing']
42 {'id': 'sdcka', 'name': 'SDCKA', 'desc': 'Data/clock line A'},
43 {'id': 'sdckb', 'name': 'SDCKB', 'desc': 'Data/clock line B'},
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'),
52 ('size', 'Data size'),
53 ('source', 'Source AP'),
54 ('dest', 'Destination AP'),
55 ('command', 'Command'),
57 ('checksum', 'Checksum'),
58 ('frame-error', 'Frame error'),
59 ('checksum-error', 'Checksum error'),
60 ('size-error', 'Size error'),
63 ('bits', 'Bits', (0, 1, 2, 3, 4, 5)),
64 ('fields', 'Fields', (6, 7, 8, 9, 10, 11)),
65 ('warnings', 'Warnings', (12, 13, 14)),
68 ('size', 'Data size'),
69 ('source', 'Source AP'),
70 ('dest', 'Destination AP'),
71 ('command', 'Command code'),
73 ('checksum', 'Checksum'),
83 self.out_ann = self.register(srd.OUTPUT_ANN)
84 self.out_binary = self.register(srd.OUTPUT_BINARY)
85 self.pending_bit_pos = None
88 self.put(self.ss, self.es, self.out_ann, data)
91 self.put(self.ss, self.es, self.out_binary, data)
93 def byte_annotation(self, bintype, d):
95 ['%s: %02X' % (name, d) for name in ann[bintype]] + ['%02X' % d]]
98 self.putx([0, ['Start pattern', 'Start', 'S']])
101 self.putx([1, ['End pattern', 'End', 'E']])
102 if self.length != self.expected_length + 1:
103 self.putx([14, ['Size error', 'L error', 'LE']])
105 def got_start_with_crc(self):
106 self.putx([2, ['Start pattern with CRC', 'Start CRC', 'SC']])
108 def got_occupancy(self):
109 self.putx([3, ['SDCKB occupancy pattern', 'Occupancy', 'O']])
112 self.putx([4, ['RESET pattern', 'RESET', 'R']])
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]])
118 def got_bit(self, n):
119 self.output_pending_bit()
120 self.data = self.data * 2 + n
122 self.pending_bit_pos = self.samplenum
125 self.output_pending_bit()
129 self.expected_length = 4 * (self.data + 1)
130 bintype = self.length
131 elif self.length == self.expected_length:
133 if self.data != self.checksum:
134 self.putx([13, ['Cksum error', 'K error', 'KE']])
135 self.length = self.length + 1
136 self.checksum = self.checksum ^ self.data
137 self.putx(self.byte_annotation(bintype, self.data))
138 self.putb([bintype, bytes([self.data])])
139 self.pending_bit_pos = None
141 def frame_error(self):
142 self.putx([7, ['Frame error', 'F error', 'FE']])
144 def handle_start(self):
145 self.wait({0: 'l', 1: 'h'})
146 self.ss = self.samplenum
149 sdcka, sdckb = self.wait([{1: 'f'}, {0: 'r'}])
153 self.es = self.samplenum
159 self.got_start_with_crc()
170 def handle_byte_or_stop(self):
171 self.ss = self.samplenum
172 self.pending_bit_pos = None
178 sdcka, sdckb = self.wait([{0: 'f'}, {1: 'f'}])
179 self.es = self.samplenum
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
195 elif self.matched[1]:
196 if counta == countb + 1:
199 elif counta == 0 and countb == 0 and sdcka == 1 and initial:
200 self.ss = self.samplenum
206 self.es = self.samplenum
212 while not self.handle_start():
215 self.expected_length = 4
217 while self.handle_byte_or_stop():