X-Git-Url: https://sigrok.org/gitweb/?p=libsigrokdecode.git;a=blobdiff_plain;f=decoders%2Fcan%2Fpd.py;h=5d27b28d23105db1096d813ddd782dd986f9611d;hp=aa49c56beccdf5575bc0d4629904e2b71155b2e0;hb=2d9e1115baa6a5806e4ecfa435cc06395afc2337;hpb=b177af15bc15f8a68635975dbaa02d41458eb0de diff --git a/decoders/can/pd.py b/decoders/can/pd.py index aa49c56..5d27b28 100644 --- a/decoders/can/pd.py +++ b/decoders/can/pd.py @@ -37,7 +37,8 @@ class Decoder(srd.Decoder): {'id': 'can_rx', 'name': 'CAN RX', 'desc': 'CAN bus line'}, ) options = ( - {'id': 'bitrate', 'desc': 'Bitrate (bits/s)', 'default': 1000000}, + {'id': 'nominal_bitrate', 'desc': 'Nominal Bitrate (bits/s)', 'default': 1000000}, + {'id': 'fast_bitrate', 'desc': 'Fast Bitrate (bits/s)', 'default': 2000000}, {'id': 'sample_point', 'desc': 'Sample point (%)', 'default': 70.0}, ) annotations = ( @@ -65,7 +66,6 @@ class Decoder(srd.Decoder): ('fields', 'Fields', tuple(range(15))), ('warnings', 'Warnings', (16,)), ) - fd = False def __init__(self): self.reset() @@ -83,7 +83,7 @@ class Decoder(srd.Decoder): 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.bit_width = float(self.samplerate) / float(self.options['nominal_bitrate']) self.sample_point = (self.bit_width / 100.0) * self.options['sample_point'] # Generic helper for CAN bit annotations. @@ -99,6 +99,10 @@ class Decoder(srd.Decoder): def put12(self, data): self.putg(self.ss_bit12, self.ss_bit12, data) + # Single-CAN-bit annotation using the samplenum of CAN bit 32. + def put32(self, data): + self.putg(self.ss_bit32, self.ss_bit32, data) + # Multi-CAN-bit annotation from self.ss_block to current samplenum. def putb(self, data): self.putg(self.ss_block, self.samplenum, data) @@ -112,7 +116,10 @@ class Decoder(srd.Decoder): self.last_databit = 999 # Positive value that bitnum+x will never match self.ss_block = None self.ss_bit12 = None + self.ss_bit32 = None self.ss_databytebits = [] + self.fd = False + self.rtr = None # Poor man's clock synchronization. Use signal edges which change to # dominant state in rather simple ways. This naive approach is neither @@ -308,6 +315,8 @@ class Decoder(srd.Decoder): # Remember start of EID (see below). if bitnum == 14: self.ss_block = self.samplenum + self.fd = False + self.dlc_start = 35 # Bits 14-31: Extended identifier (EID[17..0]) elif bitnum == 31: @@ -328,34 +337,58 @@ class Decoder(srd.Decoder): # Bit 32: Remote transmission request (RTR) bit # Data frame: dominant, remote frame: recessive # Remote frames do not contain a data field. + + # Remember start of RTR (see below). if bitnum == 32: - rtr = 'remote' if can_rx == 1 else 'data' - self.putx([8, ['Remote transmission request: %s frame' % rtr, - 'RTR: %s frame' % rtr, 'RTR']]) + self.ss_bit32 = self.samplenum + self.rtr = can_rx + + if not self.fd: + rtr = 'remote' if can_rx == 1 else 'data' + self.putx([8, ['Remote transmission request: %s frame' % rtr, + 'RTR: %s frame' % rtr, 'RTR']]) # Bit 33: RB1 (reserved bit) elif bitnum == 33: - self.putx([7, ['Reserved bit 1: %d' % can_rx, - 'RB1: %d' % can_rx, 'RB1']]) + self.fd = True if can_rx else False + + if self.fd: + self.dlc_start = 37 + self.putx([7, ['Flexible Data Format: %d' % can_rx, + 'FDF: %d' % can_rx, 'FDF']]) + + self.put32([7, ['Reserved bit 1: %d' % self.rtr, + 'RB1: %d' % self.rtr, 'RB1']]) + else: + self.putx([7, ['Reserved bit 1: %d' % can_rx, + 'RB1: %d' % can_rx, 'RB1']]) # Bit 34: RB0 (reserved bit) elif bitnum == 34: self.putx([7, ['Reserved bit 0: %d' % can_rx, 'RB0: %d' % can_rx, 'RB0']]) + elif bitnum == 35 and self.fd: + self.putx([7, ['Bit rate switch: %d' % can_rx, + 'BRS: %d' % can_rx, 'BRS']]) + + elif bitnum == 36 and self.fd: + self.putx([7, ['Error state indicator: %d' % can_rx, + 'ESI: %d' % can_rx, 'ESI']]) + # Remember start of DLC (see below). - elif bitnum == 35: + elif bitnum == self.dlc_start: self.ss_block = self.samplenum # Bits 35-38: Data length code (DLC), in number of bytes (0-8). - elif bitnum == 38: - self.dlc = int(''.join(str(d) for d in self.bits[35:38 + 1]), 2) + elif bitnum == self.dlc_start + 3: + self.dlc = int(''.join(str(d) for d in self.bits[self.dlc_start:self.dlc_start + 4]), 2) self.putb([10, ['Data length code: %d' % self.dlc, 'DLC: %d' % self.dlc, 'DLC']]) - self.last_databit = 38 + (self.dlc2len(self.dlc) * 8) + self.last_databit = self.dlc_start + 3 + (self.dlc2len(self.dlc) * 8) # Remember all databyte bits, except the very last one. - elif bitnum in range(39, self.last_databit): + elif bitnum in range(self.dlc_start + 4, self.last_databit): self.ss_databytebits.append(self.samplenum) # Bits 39-X: Data field (0-8 bytes, depending on DLC) @@ -363,7 +396,7 @@ class Decoder(srd.Decoder): elif bitnum == self.last_databit: self.ss_databytebits.append(self.samplenum) # Last databyte bit. for i in range(self.dlc2len(self.dlc)): - x = 38 + (8 * i) + 1 + x = self.dlc_start + 4 + (8 * i) b = int(''.join(str(d) for d in self.bits[x:x + 8]), 2) ss = self.ss_databytebits[i * 8] es = self.ss_databytebits[((i + 1) * 8) - 1]