X-Git-Url: https://sigrok.org/gitweb/?p=libsigrokdecode.git;a=blobdiff_plain;f=decoders%2Fspi%2Fpd.py;h=25a9f85f9c059b662fefd203f7e364fdd0edfbb2;hp=1ddb119c2729f1c2ff15972db887fc4482e8f15d;hb=1c49e875623918f8893308307f487a1f551daec4;hpb=4fecc5a4bcb036f40e23ab967579334076203c2f diff --git a/decoders/spi/pd.py b/decoders/spi/pd.py index 1ddb119..25a9f85 100644 --- a/decoders/spi/pd.py +++ b/decoders/spi/pd.py @@ -28,14 +28,16 @@ Packet: [, , ] : - - 'DATA': contains the MISO data, contains the MOSI data. + - 'DATA': contains the MOSI data, contains the MISO data. The data is _usually_ 8 bits (but can also be fewer or more bits). Both data items are Python numbers (not strings), or None if the respective channel was not supplied. - - 'BITS': / contain a list of bit values in this MISO/MOSI data + - 'BITS': / contain a list of bit values in this MOSI/MISO data item, and for each of those also their respective start-/endsample numbers. - 'CS CHANGE': is the old CS# pin value, is the new value. - Both data items are Python numbers (0/1), not strings. + Both data items are Python numbers (0/1), not strings. At the beginning of + the decoding a packet is generated with = -1 and being the + initial state of the CS# pin or -1 if the chip select pin is not supplied. Examples: ['CS-CHANGE', 1, 0] @@ -60,6 +62,12 @@ spi_mode = { (1, 1): 3, # Mode 3 } +class SamplerateError(Exception): + pass + +class ChannelError(Exception): + pass + class Decoder(srd.Decoder): api_version = 2 id = 'spi' @@ -110,12 +118,13 @@ class Decoder(srd.Decoder): self.misodata = self.mosidata = 0 self.misobits = [] self.mosibits = [] - self.startsample = -1 + self.ss_block = -1 self.samplenum = -1 self.cs_was_deasserted = False self.oldcs = -1 self.oldpins = None self.have_cs = self.have_miso = self.have_mosi = None + self.no_cs_notification = False def metadata(self, key, value): if key == srd.SRD_CONF_SAMPLERATE: @@ -128,7 +137,7 @@ class Decoder(srd.Decoder): meta=(int, 'Bitrate', 'Bitrate during transfers')) def putw(self, data): - self.put(self.startsample, self.samplenum, self.out_ann, data) + self.put(self.ss_block, self.samplenum, self.out_ann, data) def putdata(self): # Pass MISO and MOSI bits and then data to the next PD up the stack. @@ -169,7 +178,7 @@ class Decoder(srd.Decoder): def handle_bit(self, miso, mosi, clk, cs): # If this is the first bit of a dataword, save its sample number. if self.bitcount == 0: - self.startsample = self.samplenum + self.ss_block = self.samplenum self.cs_was_deasserted = False if self.have_cs: active_low = (self.options['cs_polarity'] == 'active-low') @@ -219,9 +228,9 @@ class Decoder(srd.Decoder): # Meta bitrate. elapsed = 1 / float(self.samplerate) - elapsed *= (self.samplenum - self.startsample + 1) + elapsed *= (self.samplenum - self.ss_block + 1) bitrate = int(1 / elapsed * self.options['wordsize']) - self.put(self.startsample, self.samplenum, self.out_bitrate, bitrate) + self.put(self.ss_block, self.samplenum, self.out_bitrate, bitrate) if self.have_cs and self.cs_was_deasserted: self.putw([4, ['CS# was deasserted during this data word!']]) @@ -258,8 +267,8 @@ class Decoder(srd.Decoder): self.handle_bit(miso, mosi, clk, cs) 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.') # Either MISO or MOSI can be omitted (but not both). CS# is optional. for (self.samplenum, pins) in data: @@ -273,7 +282,11 @@ class Decoder(srd.Decoder): # Either MISO or MOSI (but not both) can be omitted. if not (self.have_miso or self.have_mosi): - raise Exception('Either MISO or MOSI (or both) pins required.') + raise ChannelError('Either MISO or MOSI (or both) pins required.') - self.find_clk_edge(miso, mosi, clk, cs) + # Tell stacked decoders that we don't have a CS# signal. + if not self.no_cs_notification and not self.have_cs: + self.put(0, 0, self.out_python, ['CS-CHANGE', -1, -1]) + self.no_cs_notification = True + self.find_clk_edge(miso, mosi, clk, cs)