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
21 from common.srdhelper import SrdIntEnum
23 Pin = SrdIntEnum.from_str('Pin', 'SDCKA SDCKB')
34 class Decoder(srd.Decoder):
38 longname = 'SEGA Maple bus'
39 desc = 'Maple bus peripheral protocol for SEGA Dreamcast.'
43 tags = ['Retro computing']
45 {'id': 'sdcka', 'name': 'SDCKA', 'desc': 'Data/clock line A'},
46 {'id': 'sdckb', 'name': 'SDCKB', 'desc': 'Data/clock line B'},
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'),
55 ('size', 'Data size'),
56 ('source', 'Source AP'),
57 ('dest', 'Destination AP'),
58 ('command', 'Command'),
60 ('checksum', 'Checksum'),
61 ('frame-error', 'Frame error'),
62 ('checksum-error', 'Checksum error'),
63 ('size-error', 'Size error'),
66 ('bits', 'Bits', (0, 1, 2, 3, 4, 5)),
67 ('fields', 'Fields', (6, 7, 8, 9, 10, 11)),
68 ('warnings', 'Warnings', (12, 13, 14)),
71 ('size', 'Data size'),
72 ('source', 'Source AP'),
73 ('dest', 'Destination AP'),
74 ('command', 'Command code'),
76 ('checksum', 'Checksum'),
86 self.out_ann = self.register(srd.OUTPUT_ANN)
87 self.out_binary = self.register(srd.OUTPUT_BINARY)
88 self.pending_bit_pos = None
91 self.put(self.ss, self.es, self.out_ann, data)
94 self.put(self.ss, self.es, self.out_binary, data)
96 def byte_annotation(self, bintype, d):
98 ['%s: %02X' % (name, d) for name in ann[bintype]] + ['%02X' % d]]
101 self.putx([0, ['Start pattern', 'Start', 'S']])
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']])
108 def got_start_with_crc(self):
109 self.putx([2, ['Start pattern with CRC', 'Start CRC', 'SC']])
111 def got_occupancy(self):
112 self.putx([3, ['SDCKB occupancy pattern', 'Occupancy', 'O']])
115 self.putx([4, ['RESET pattern', 'RESET', 'R']])
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]])
121 def got_bit(self, n):
122 self.output_pending_bit()
123 self.data = self.data * 2 + n
125 self.pending_bit_pos = self.samplenum
128 self.output_pending_bit()
132 self.expected_length = 4 * (self.data + 1)
133 bintype = self.length
134 elif self.length == self.expected_length:
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
144 def frame_error(self):
145 self.putx([7, ['Frame error', 'F error', 'FE']])
147 def handle_start(self):
148 self.wait({Pin.SDCKA: 'l', Pin.SDCKB: 'h'})
149 self.ss = self.samplenum
152 sdcka, sdckb = self.wait([{Pin.SDCKB: 'f'}, {Pin.SDCKA: 'r'}])
156 self.es = self.samplenum
162 self.got_start_with_crc()
173 def handle_byte_or_stop(self):
174 self.ss = self.samplenum
175 self.pending_bit_pos = None
181 sdcka, sdckb = self.wait([{Pin.SDCKA: 'f'}, {Pin.SDCKB: 'f'}])
182 self.es = self.samplenum
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
199 elif self.matched[1]:
200 if counta == countb + 1:
203 elif counta == 0 and countb == 0 and sdcka == 1 and initial:
204 self.ss = self.samplenum
209 self.wait({Pin.SDCKA: 'h'})
210 self.es = self.samplenum
216 while not self.handle_start():
219 self.expected_length = 4
221 while self.handle_byte_or_stop():