]> sigrok.org Git - libsigrokdecode.git/blobdiff - decoders/can/pd.py
can: Add warnings for various invalid bits and fields.
[libsigrokdecode.git] / decoders / can / pd.py
index e425575433510c3edea2512d0b707404134af4d9..f1adef1ada54560bda815689ec5f0301051e095c 100644 (file)
 ## GNU General Public License for more details.
 ##
 ## You should have received a copy of the GNU General Public License
-## along with this program; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+## along with this program; if not, see <http://www.gnu.org/licenses/>.
 ##
 
 import sigrokdecode as srd
 
+class SamplerateError(Exception):
+    pass
+
 class Decoder(srd.Decoder):
     api_version = 2
     id = 'can'
@@ -54,9 +56,15 @@ class Decoder(srd.Decoder):
         ('ack-delimiter', 'ACK delimiter'),
         ('stuff-bit', 'Stuff bit'),
         ('warnings', 'Human-readable warnings'),
+        ('bit', 'Bit'),
+    )
+    annotation_rows = (
+        ('bits', 'Bits', (15, 17)),
+        ('fields', 'Fields', tuple(range(15))),
+        ('warnings', 'Warnings', (16,)),
     )
 
-    def __init__(self, **kwargs):
+    def __init__(self):
         self.samplerate = None
         self.reset_variables()
 
@@ -112,8 +120,6 @@ class Decoder(srd.Decoder):
             return False
 
         # Stuff bit. Keep it in self.rawbits, but drop it from self.bits.
-        self.putx([15, ['Stuff bit: %d' % self.rawbits[-1],
-                        'SB: %d' % self.rawbits[-1], 'SB']])
         self.bits.pop() # Drop last bit.
         return True
 
@@ -149,6 +155,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):
@@ -159,6 +167,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):
@@ -167,6 +177,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
 
@@ -198,6 +210,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):
@@ -302,20 +316,18 @@ class Decoder(srd.Decoder):
         # Get the index of the current CAN frame bit (without stuff bits).
         bitnum = len(self.bits) - 1
 
-        # For debugging.
-        # self.putx([0, ['Bit %d (CAN bit %d): %d' % \
-        #           (self.curbit, bitnum, can_rx)]])
-
         # If this is a stuff bit, remove it from self.bits and ignore it.
         if self.is_stuff_bit():
+            self.putx([15, [str(can_rx)]])
             self.curbit += 1 # Increase self.curbit (bitnum is not affected).
             return
+        else:
+            self.putx([17, [str(can_rx)]])
 
         # 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).
@@ -328,6 +340,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:
@@ -358,8 +372,8 @@ class Decoder(srd.Decoder):
         self.curbit += 1
 
     def decode(self, ss, es, data):
-        if self.samplerate is None:
-            raise Exception("Cannot decode without samplerate.")
+        if not self.samplerate:
+            raise SamplerateError('Cannot decode without samplerate.')
         for (self.samplenum, pins) in data:
 
             (can_rx,) = pins
@@ -376,4 +390,3 @@ class Decoder(srd.Decoder):
                 if not self.reached_bit(self.curbit):
                     continue
                 self.handle_bit(can_rx)
-