-
-
Save JackNewman12/0f3a0dbe556ee8ea8bcaffc530d20885 to your computer and use it in GitHub Desktop.
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]]) |
Hi Simon,
Wow this is ancient history for sure and forgot I even posted this script.
So in the sigrokdecoder (at least in the 3+ year old version I was using) you would get decode()
called for various inputs.
In this case you would get 8x callbacks for each item in the bits
field (the blue line in the decoder), and you would then get 1x callback with the data
field (in this case I would have told sigrock that my SPI bus had 8 bit transactions).
I only cared about matching the hexidecimal string. i.e. a buggy message from a device or the start of a custom header. So there was no use processing the BITS
field.
No idea what sigrock looks like these days but my best guess is you would need to replace:
ptype, mosi, miso = data
if ptype != "DATA":
return
with
ptype, tx, rx= data
if ptype != "RX": # or TX if you want that
return
to get it working for UART.
But thats just a guess.
Regards,
Jack
Thanks for your quick reply Jack. I'll keep trying.
Simon
Hi Jack,
I've tried modifying your byte-matcher to stack on top of UART, but I cannot get it working.
I realise this is probably ancient history for you (3 years since you published this), but is there any chance you could explain what changes are necessary?
I am unsure what to change the following section to:
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
Regards,
Simon
NZ