Last active
February 4, 2023 18:52
-
-
Save JackNewman12/0f3a0dbe556ee8ea8bcaffc530d20885 to your computer and use it in GitHub Desktop.
A quick pulseview decoder for matching a series of bytes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for your quick reply Jack. I'll keep trying.
Simon