Skip to content

Instantly share code, notes, and snippets.

@JackNewman12
Last active February 4, 2023 18:52

Revisions

  1. JackNewman12 revised this gist Aug 18, 2019. 1 changed file with 0 additions and 0 deletions.
    Binary file added pulseview.png
    Loading
    Sorry, something went wrong. Reload?
    Sorry, we cannot display this file.
    Sorry, this file is invalid so it cannot be displayed.
  2. JackNewman12 created this gist Aug 18, 2019.
    73 changes: 73 additions & 0 deletions pd.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    import sigrokdecode as srd
    import collections

    # Matches to find.
    # A list of tuples that contain (ByteToMatch, Name)
    Matches = [
    ([0x20, 0x20], "Match One!"),
    ([0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], "Match Two!"),
    ([0xFF, 0xAA, 0xCC, 0x55], "Match Three!"),
    ]

    # Standard Decoder
    class Decoder(srd.Decoder):
    # Decoder stuff that needs to exist for pulseview to be happy
    api_version = 3
    id = "ByteMatch"
    name = "Byte Matcher"
    longname = "A Byte Matcher"
    desc = "This decoder searches for arbitrary set of bytes"
    license = "MIT"
    inputs = ["spi"] # CHANGE THE DECODE YOU WANT TO STACK ONTOP OF
    outputs = []
    tags = ["IC", "Memory"]
    annotations = (("Matches", "Matches"),)
    annotation_rows = (("Matches", "Matches", (0,)),)
    options = ()

    def __init__(self):
    # Circular buffers for keeping track of the last few bytes
    # Make the buffers the size of the largest match
    MaxLength = max([len(bytes) for bytes, name in Matches])
    # The last few bytes
    self.LastBytes = collections.deque(maxlen=MaxLength)
    # The last few start-samples
    self.LastSamples = collections.deque(maxlen=MaxLength)

    def reset(self):
    # Reset the circular buffers
    self.LastBytes.clear()
    self.LastSamples.clear()

    def start(self):
    # Standard Pulseview Stuff
    self.out_ann = self.register(srd.OUTPUT_ANN)

    def decode(self, startSample, endSample, data):
    # Grab the data from your lower level decoder.
    ptype, mosi, miso = data
    # In this case I only care about full bytes from the decoder (DATA).
    # Do not care about indiviual bits (BITS)
    if ptype != "DATA":
    return

    # Keep track of the byte we just saw and the sample it started at (for annotations)
    self.LastBytes.append(miso)
    self.LastSamples.append(startSample)

    # Just search for a match in the array
    for match in Matches:
    data, annotation = match

    # If the last few bytes in the buffers match our target array
    if data == list(self.LastBytes)[-1 * len(data) :]:

    startSample = (
    # Cover edge case where we match on the very first byte in the data
    self.LastSamples[-1 * len(data)]
    if len(self.LastSamples) >= len(data)
    else 0
    )

    # Print the annotation at orignal start sample and the current sample
    self.put(startSample, endSample, self.out_ann, [0, [annotation]])