## along with this program; if not, see <http://www.gnu.org/licenses/>.
##
+from common.srdhelper import bitpack
import sigrokdecode as srd
class SamplerateError(Exception):
pass
+class Pin:
+ SDQ, = range(1)
+
+class Ann:
+ BIT, BYTE, BREAK, = range(3)
+
class Decoder(srd.Decoder):
api_version = 3
id = 'sdq'
('break', 'Break'),
)
annotation_rows = (
- ('bits', 'Bits', (0,)),
- ('bytes', 'Bytes', (1,)),
- ('breaks', 'Breaks', (2,)),
+ ('bits', 'Bits', (Ann.BIT,)),
+ ('bytes', 'Bytes', (Ann.BYTE,)),
+ ('breaks', 'Breaks', (Ann.BREAK,)),
)
def puts(self, data):
def putbetu(self, data):
self.put(self.bytepos, self.startsample + int(self.bit_width), self.out_ann, data)
- def bits2num(self, bitlist):
- number = 0
- for i in range(len(bitlist)):
- number += bitlist[i] * 2**i
- return number
-
def __init__(self):
self.reset()
def reset(self):
self.samplerate = None
- self.state = 'INIT'
self.startsample = 0
self.bits = []
self.bytepos = 0
def metadata(self, key, value):
if key == srd.SRD_CONF_SAMPLERATE:
self.samplerate = value
- self.bit_width = float(self.samplerate) / float(self.options['bitrate'])
- self.half_bit_width = self.bit_width / 2.0
- self.break_threshold = self.bit_width * 1.2 # Break if the line is low for longer than this
def handle_bit(self, bit):
self.bits.append(bit)
- self.putetu([0, ['Bit: %d' % bit, '%d' % bit]])
+ self.putetu([Ann.BIT, [
+ 'Bit: {:d}'.format(bit),
+ '{:d}'.format(bit),
+ ]])
if len(self.bits) == 8:
- byte = self.bits2num(self.bits)
- self.putbetu([1, ['Byte: %#04x' % byte, '%#04x' % byte]])
+ byte = bitpack(self.bits)
+ self.putbetu([Ann.BYTE, [
+ 'Byte: 0x{:02x}'.format(byte),
+ '0x{:02x}'.format(byte),
+ ]])
self.bits = []
self.bytepos = 0
def handle_break(self):
- self.puts([2, ['Break', 'BR']])
+ self.puts([Ann.BREAK, ['Break', 'BR']])
self.bits = []
self.startsample = self.samplenum
self.bytepos = 0
def decode(self):
if not self.samplerate:
raise SamplerateError('Cannot decode without samplerate.')
+ self.bit_width = float(self.samplerate) / float(self.options['bitrate'])
+ self.half_bit_width = self.bit_width / 2.0
+ # BREAK if the line is low for longer than this.
+ break_threshold = self.bit_width * 1.2
+ # Wait until the line is high before inspecting input data.
+ sdq, = self.wait({Pin.SDQ: 'h'})
while True:
- if self.state == 'INIT':
- sdq, = self.wait({0: 'h'}) # Wait until the line is high before starting
- self.state = 'DATA'
-
- elif self.state == 'DATA':
- sdq, = self.wait({0: 'f'}) # Falling edge
-
- self.startsample = self.samplenum
- if self.bytepos == 0:
- self.bytepos = self.samplenum
-
- sdq, = self.wait({0: 'r'}) # Rising edge
-
- delta = self.samplenum - self.startsample
- if delta > self.break_threshold:
- self.state = 'BREAK'
- elif delta > self.half_bit_width:
- self.handle_bit(0)
- else:
- self.handle_bit(1)
-
- elif self.state == 'BREAK':
+ # Get the length of a low pulse (falling to rising edge).
+ sdq, = self.wait({Pin.SDQ: 'f'})
+ self.startsample = self.samplenum
+ if self.bytepos == 0:
+ self.bytepos = self.samplenum
+ sdq, = self.wait({Pin.SDQ: 'r'})
+
+ # Check for 0 or 1 data bits, or the BREAK symbol.
+ delta = self.samplenum - self.startsample
+ if delta > break_threshold:
self.handle_break()
- self.state = 'DATA'
+ elif delta > self.half_bit_width:
+ self.handle_bit(0)
+ else:
+ self.handle_bit(1)