2 ## This file is part of the libsigrokdecode project.
4 ## Copyright (C) 2011 Gareth McMullin <gareth@blacksphere.co.nz>
5 ## Copyright (C) 2012-2013 Uwe Hermann <uwe@hermann-uwe.de>
7 ## This program is free software; you can redistribute it and/or modify
8 ## it under the terms of the GNU General Public License as published by
9 ## the Free Software Foundation; either version 2 of the License, or
10 ## (at your option) any later version.
12 ## This program is distributed in the hope that it will be useful,
13 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ## GNU General Public License for more details.
17 ## You should have received a copy of the GNU General Public License
18 ## along with this program; if not, write to the Free Software
19 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 import sigrokdecode as srd
39 - 'J', 'K', 'SE0', or 'SE1'
43 - Note: Symbols like SE0, SE1, and the J that's part of EOP don't yield 'BIT'.
46 # Low-/full-speed symbols.
47 # Note: Low-speed J and K are inverted compared to the full-speed J and K!
50 # (<dp>, <dm>): <symbol/state>
57 # (<dp>, <dm>): <symbol/state>
66 'low-speed': 1500000, # 1.5Mb/s (+/- 1.5%)
67 'full-speed': 12000000, # 12Mb/s (+/- 0.25%)
73 'SE0': [2, ['SE0', '0']],
74 'SE1': [3, ['SE1', '1']],
77 class SamplerateError(Exception):
80 class Decoder(srd.Decoder):
83 name = 'USB signalling'
84 longname = 'Universal Serial Bus (LS/FS) signalling'
85 desc = 'USB (low-speed and full-speed) signalling protocol.'
88 outputs = ['usb_signalling']
90 {'id': 'dp', 'name': 'D+', 'desc': 'USB D+ signal'},
91 {'id': 'dm', 'name': 'D-', 'desc': 'USB D- signal'},
94 {'id': 'signalling', 'desc': 'Signalling',
95 'default': 'full-speed', 'values': ('full-speed', 'low-speed')},
98 ('sym-j', 'J symbol'),
99 ('sym-k', 'K symbol'),
100 ('sym-se0', 'SE0 symbol'),
101 ('sym-se1', 'SE1 symbol'),
102 ('sop', 'Start of packet (SOP)'),
103 ('eop', 'End of packet (EOP)'),
105 ('stuffbit', 'Stuff bit'),
109 ('bits', 'Bits', (4, 5, 6, 7, 8)),
110 ('symbols', 'Symbols', (0, 1, 2, 3)),
114 self.samplerate = None
115 self.oldsym = 'J' # The "idle" state is J.
121 self.samplepos = None
122 self.samplenum_target = None
123 self.samplenum_edge = None
126 self.consecutive_ones = 0
130 self.out_python = self.register(srd.OUTPUT_PYTHON)
131 self.out_ann = self.register(srd.OUTPUT_ANN)
133 def metadata(self, key, value):
134 if key == srd.SRD_CONF_SAMPLERATE:
135 self.samplerate = value
136 self.bitrate = bitrates[self.options['signalling']]
137 self.bitwidth = float(self.samplerate) / float(self.bitrate)
138 self.halfbit = int(self.bitwidth / 2)
140 def putpx(self, data):
141 self.put(self.samplenum, self.samplenum, self.out_python, data)
143 def putx(self, data):
144 self.put(self.samplenum, self.samplenum, self.out_ann, data)
146 def putpm(self, data):
147 s, h = self.samplenum, self.halfbit
148 self.put(self.ss_block - h, s + h, self.out_python, data)
150 def putm(self, data):
151 s, h = self.samplenum, self.halfbit
152 self.put(self.ss_block - h, s + h, self.out_ann, data)
154 def putpb(self, data):
155 s, h = self.samplenum, self.halfbit
156 self.put(self.samplenum_edge, s + h, self.out_python, data)
158 def putb(self, data):
159 s, h = self.samplenum, self.halfbit
160 self.put(self.samplenum_edge, s + h, self.out_ann, data)
162 def set_new_target_samplenum(self):
163 self.samplepos += self.bitwidth;
164 self.samplenum_target = int(self.samplepos)
165 self.samplenum_edge = int(self.samplepos - (self.bitwidth / 2))
167 def wait_for_sop(self, sym):
168 # Wait for a Start of Packet (SOP), i.e. a J->K symbol change.
172 self.consecutive_ones = 0
173 self.samplepos = self.samplenum - (self.bitwidth / 2) + 0.5
174 self.set_new_target_samplenum()
175 self.putpx(['SOP', None])
176 self.putx([4, ['SOP', 'S']])
177 self.state = 'GET BIT'
179 def handle_bit(self, sym, b):
180 if self.consecutive_ones == 6:
183 self.putpb(['STUFF BIT', None])
184 self.putb([7, ['Stuff bit: 0', 'SB: 0', '0']])
185 self.consecutive_ones = 0
187 self.putpb(['ERR', None])
188 self.putb([8, ['Bit stuff error', 'BS ERR', 'B']])
191 # Normal bit (not a stuff bit).
192 self.putpb(['BIT', b])
193 self.putb([6, ['%s' % b]])
195 self.consecutive_ones += 1
197 self.consecutive_ones = 0
199 def get_eop(self, sym):
200 # EOP: SE0 for >= 1 bittime (usually 2 bittimes), then J.
201 self.syms.append(sym)
202 self.putpb(['SYM', sym])
203 self.putb(sym_annotation[sym])
204 self.set_new_target_samplenum()
206 if self.syms[-2:] == ['SE0', 'J']:
208 self.putpm(['EOP', None])
209 self.putm([5, ['EOP', 'E']])
210 self.syms, self.state = [], 'IDLE'
211 self.bitwidth = float(self.samplerate) / float(self.bitrate)
213 def get_bit(self, sym):
215 # Start of an EOP. Change state, run get_eop() for this bit.
216 self.state = 'GET EOP'
217 self.ss_block = self.samplenum
220 self.syms.append(sym)
221 self.putpb(['SYM', sym])
222 b = '0' if self.oldsym != sym else '1'
223 self.putb(sym_annotation[sym])
224 if self.oldsym != sym:
225 edgesym = symbols[self.options['signalling']][tuple(self.edgepins)]
226 if edgesym not in ('SE0', 'SE1'):
228 self.bitwidth = self.bitwidth - (0.001 * self.bitwidth)
229 self.samplepos = self.samplepos - (0.01 * self.bitwidth)
231 self.bitwidth = self.bitwidth + (0.001 * self.bitwidth)
232 self.samplepos = self.samplepos + (0.01 * self.bitwidth)
233 self.handle_bit(sym, b)
234 self.set_new_target_samplenum()
237 def decode(self, ss, es, data):
238 if not self.samplerate:
239 raise SamplerateError('Cannot decode without samplerate.')
240 for (self.samplenum, pins) in data:
242 if self.state == 'IDLE':
243 # Ignore identical samples early on (for performance reasons).
244 if self.oldpins == pins:
247 sym = symbols[self.options['signalling']][tuple(pins)]
248 self.wait_for_sop(sym)
250 elif self.state in ('GET BIT', 'GET EOP'):
251 # Wait until we're in the middle of the desired bit.
252 if self.samplenum == self.samplenum_edge:
254 if self.samplenum < self.samplenum_target:
256 sym = symbols[self.options['signalling']][tuple(pins)]
257 if self.state == 'GET BIT':
259 elif self.state == 'GET EOP':