X-Git-Url: https://sigrok.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=decoders%2Fcan%2Fpd.py;h=46054cda851865be1abc33c911368cb9761f4832;hb=64d8711976c3e74a4a19beabd505438ce91ac86c;hp=1a99c307c94861acf9deca895d6ef181ab81fb2a;hpb=4539e9ca58966ce3c9cad4801b16c315e86ace01;p=libsigrokdecode.git diff --git a/decoders/can/pd.py b/decoders/can/pd.py index 1a99c30..46054cd 100644 --- a/decoders/can/pd.py +++ b/decoders/can/pd.py @@ -23,7 +23,7 @@ class SamplerateError(Exception): pass class Decoder(srd.Decoder): - api_version = 2 + api_version = 3 id = 'can' name = 'CAN' longname = 'Controller Area Network' @@ -60,7 +60,8 @@ class Decoder(srd.Decoder): ) annotation_rows = ( ('bits', 'Bits', (15, 17)), - ('fields', 'Fields', tuple(range(15)) + (16,)), + ('fields', 'Fields', tuple(range(15))), + ('warnings', 'Warnings', (16,)), ) def __init__(self): @@ -104,12 +105,10 @@ class Decoder(srd.Decoder): self.ss_bit12 = None self.ss_databytebits = [] - # Return True if we reached the desired bit position, False otherwise. - def reached_bit(self, bitnum): + # Determine the position of the next desired bit's sample point. + def get_sample_point(self, bitnum): bitpos = int(self.sof + (self.bit_width * bitnum) + self.bitpos) - if self.samplenum >= bitpos: - return True - return False + return bitpos def is_stuff_bit(self): # CAN uses NRZ encoding and bit stuffing. @@ -154,6 +153,8 @@ class Decoder(srd.Decoder): elif bitnum == (self.last_databit + 16): self.putx([12, ['CRC delimiter: %d' % can_rx, 'CRC d: %d' % can_rx, 'CRC d']]) + if can_rx != 1: + self.putx([16, ['CRC delimiter must be a recessive bit']]) # ACK slot bit (dominant: ACK, recessive: NACK) elif bitnum == (self.last_databit + 17): @@ -164,6 +165,8 @@ class Decoder(srd.Decoder): elif bitnum == (self.last_databit + 18): self.putx([14, ['ACK delimiter: %d' % can_rx, 'ACK d: %d' % can_rx, 'ACK d']]) + if can_rx != 1: + self.putx([16, ['ACK delimiter must be a recessive bit']]) # Remember start of EOF (see below). elif bitnum == (self.last_databit + 19): @@ -172,6 +175,8 @@ class Decoder(srd.Decoder): # End of frame (EOF), 7 recessive bits elif bitnum == (self.last_databit + 25): self.putb([2, ['End of frame', 'EOF', 'E']]) + if self.rawbits[-7:] != [1, 1, 1, 1, 1, 1, 1]: + self.putb([16, ['End of frame (EOF) must be 7 recessive bits']]) self.reset_variables() return True @@ -203,6 +208,8 @@ class Decoder(srd.Decoder): self.putb([10, ['Data length code: %d' % self.dlc, 'DLC: %d' % self.dlc, 'DLC']]) self.last_databit = 18 + (self.dlc * 8) + if self.dlc > 8: + self.putb([16, ['Data length code (DLC) > 8 is not allowed']]) # Remember all databyte bits, except the very last one. elif bitnum in range(19, self.last_databit): @@ -317,9 +324,8 @@ class Decoder(srd.Decoder): # Bit 0: Start of frame (SOF) bit if bitnum == 0: - if can_rx == 0: - self.putx([1, ['Start of frame', 'SOF', 'S']]) - else: + self.putx([1, ['Start of frame', 'SOF', 'S']]) + if can_rx != 0: self.putx([16, ['Start of frame (SOF) must be a dominant bit']]) # Remember start of ID (see below). @@ -332,6 +338,8 @@ class Decoder(srd.Decoder): self.id = int(''.join(str(d) for d in self.bits[1:]), 2) s = '%d (0x%x)' % (self.id, self.id), self.putb([3, ['Identifier: %s' % s, 'ID: %s' % s, 'ID']]) + if (self.id & 0x7f0) == 0x7f0: + self.putb([16, ['Identifier bits 10..4 must not be all recessive']]) # RTR or SRR bit, depending on frame type (gets handled later). elif bitnum == 12: @@ -361,22 +369,19 @@ class Decoder(srd.Decoder): self.curbit += 1 - def decode(self, ss, es, data): + def decode(self): if not self.samplerate: raise SamplerateError('Cannot decode without samplerate.') - for (self.samplenum, pins) in data: - - (can_rx,) = pins + while True: # State machine. if self.state == 'IDLE': # Wait for a dominant state (logic 0) on the bus. - if can_rx == 1: - continue + (can_rx,) = self.wait({0: 'l'}) self.sof = self.samplenum self.state = 'GET BITS' elif self.state == 'GET BITS': # Wait until we're in the correct bit/sampling position. - if not self.reached_bit(self.curbit): - continue + pos = self.get_sample_point(self.curbit) + (can_rx,) = self.wait({'skip': pos - self.samplenum}) self.handle_bit(can_rx)