On 2013-07-30 13:54, Clemens Novak wrote:
On 2013-07-29 20:19, Peter Stuge wrote:
Joel Holdsworth wrote:
The patch considers CS# and decodes MOSI / MISO only after a CS#
H-L transition.

What if CS# is tied low?

Yes that's a good point. I can think of some chips that require the
transition for each packet, or even each byte.

Sure, I know of those too.


Some chips don't care and you can tie CS# low.

Right.


I wonder how important it is to deal with all this.

It makes the difference between sigrok being useful and sigrok
not being useful. I think it's important that sigrok is useful.


Maybe the CS# behavior could be optional, defaulted to ignore.

Ignore is also not so great. I would suggest a default of only
sampling when CS# is low, with an option to additionally require
a H->L transition on CS#, but *always* restarting on a new word
whenever a H->L transition is seen, regardless of the option value.


//Peter


I have tried to draw an example with a wordsize of 4 bits, sampling of
MOSI @ rising edge of SCK & a default SCK value of H.


CS# makes a H-L transition -> decoder starts working; CS# goes H after
frame.

     __                           ___
CS#   |_________________________|

     __     __    __    __    _____
SCK   |___|  |__|  |__|  |__|

      _             ______________
MOSI  |___________|


decoder output -> 0011



A CS# H-L transition always starts a new frame (the old frame is left
"unfinished")

     __             ________                       ________
CS#   |___________|        |_____________________|

     __     __    __    __    __    __    __    ________
SCK   |___|  |__|  |__|  |__|  |__|  |__|  |__|

      _             _________________
MOSI  |___________|                 |___________________


decoder output -> 00, 1100



The decoder decodes subsequent frames as long as CS# is low
     __                                                      ___
CS#   |____________________________________________________|

     __     __    __    __    __    __    __    __    __________
SCK   |___|  |__|  |__|  |__|  |__|  |__|  |__|  |__|

      _             __________________
MOSI  |___________|                  |_________________________


decoder output -> 0011, 1000


There is a flag which allows the decoder to ignore additional frames
without another CS# H-L transition.

decoder output MOSI -> 0011


Is that what you have in mind?

Regards - Clemens


------------------------------------------------------------------------------
Get your SQL database under version control now!
Version control is standard for application code, but databases havent
caught up. So what steps can you take to put your SQL databases under
version control? Why should you start doing it? Read more to find out.
http://pubads.g.doubleclick.net/gampad/clk?id=49501711&iu=/4140/ostg.clktrk
_______________________________________________
sigrok-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sigrok-devel


A short update / additional information on this: I attached an sr file (0: CS#, 1: MOSI, 3: SCK) which is cut off at the beginning; i.e. the first "block" contains only 6 bits (instead of eight).

If I decode this signal with

sigrok-cli -i spi_atmega32_cutoff.sr -P spi:wordsize=8:miso=1:mosi=1:sck=3:cs=0

it outputs:
...
spi: "MOSI: 0x59, MISO: 0x59"
...
spi: "MOSI: 0x5d, MISO: 0x5d"
...

Looking at the capture, you can see that the decoder combines 6 bits from the "block" 1 with 2 bits from "block" 2; yielding a value of 0x59. The it takes 6 bits from "block" 2 and 2 bits from "block" 3 yielding a value of 0x5d.

The proposal is to ignore all data before a CS# 1-0 transition. The attached python file does this by means of a state variable 'state'. A 1-0 transition of CS# arms the decoder (setting 'state' to 'start'), which decodes until CS# goes 1 again (setting 'state' to 'stop'). On the same signal it yields the following results:

...
spi: "MOSI: 0x57, MISO: 0x57
...
spi: "MOSI: 0x58, MISO: 0x58
...

I'm not sure whether my idea catches all adge cases - please let me know what you think.

Regards - Clemens

Attachment: spi_atmega32_cutoff.sr
Description: Zip archive

##
## This file is part of the libsigrokdecode project.
##
## Copyright (C) 2011 Gareth McMullin <[email protected]>
## Copyright (C) 2012 Uwe Hermann <[email protected]>
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
## the Free Software Foundation; either version 2 of the License, or
## (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## 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
##

# sigrok-cli -i spi_atmega32_00_play.sr -P mine:wordsize=8:miso=1:mosi=1:sck=2:cs=0 | less


# SPI protocol decoder

import sigrokdecode as srd

# Key: (CPOL, CPHA). Value: SPI mode.
# Clock polarity (CPOL) = 0/1: Clock is low/high when inactive.
# Clock phase (CPHA) = 0/1: Data is valid on the leading/trailing clock edge.
spi_mode = {
    (0, 0): 0, # Mode 0
    (0, 1): 1, # Mode 1
    (1, 0): 2, # Mode 2
    (1, 1): 3, # Mode 3
}

# Annotation formats
ANN_HEX = 0

class Decoder(srd.Decoder):
    api_version = 1
    id = 'mine'
    name = 'MINE'
    longname = 'Serial Peripheral Interface'
    desc = 'Full-duplex, synchronous, serial bus.'
    license = 'gplv2+'
    inputs = ['logic']
    outputs = ['spi']
    probes = [
        {'id': 'miso', 'name': 'MISO',
         'desc': 'SPI MISO line (Master in, slave out)'},
        {'id': 'mosi', 'name': 'MOSI',
         'desc': 'SPI MOSI line (Master out, slave in)'},
        {'id': 'sck', 'name': 'CLK', 'desc': 'SPI clock line'},
        {'id': 'cs', 'name': 'CS#', 'desc': 'SPI CS (chip select) line'},
    ]
    optional_probes = [] # TODO
    options = {
        'cs_polarity': ['CS# polarity', 'active-low'],
        'cpol': ['Clock polarity', 0],
        'cpha': ['Clock phase', 0],
        'bitorder': ['Bit order within the SPI data', 'msb-first'],
        'wordsize': ['Word size of SPI data', 8], # 1-64?
    }
    annotations = [
        ['Hex', 'SPI data bytes in hex format'],
    ]

    def __init__(self):
        self.oldsck = 1
        self.bitcount = 0
        self.mosidata = 0
        self.misodata = 0
        self.bytesreceived = 0
        self.samplenum = -1
        self.cs_was_deasserted_during_data_word = 0
        self.oldcs = -1
        self.oldpins = None
        self.state = "stop"

    def start(self, metadata):
        self.out_proto = self.add(srd.OUTPUT_PROTO, 'spi')
        self.out_ann = self.add(srd.OUTPUT_ANN, 'spi')

    def report(self):
        return 'SPI: %d bytes received' % self.bytesreceived

    def decode(self, ss, es, data):
        # TODO: Either MISO or MOSI could be optional. CS# is optional.
        for (self.samplenum, pins) in data:

            # Ignore identical samples early on (for performance reasons).
            if self.oldpins == pins:
                continue
            self.oldpins, (miso, mosi, sck, cs) = pins, pins

            if self.oldcs != cs:
                # Send all CS# pin value changes.
                self.put(self.samplenum, self.samplenum, self.out_proto,
                         ['CS-CHANGE', self.oldcs, cs])
                self.put(self.samplenum, self.samplenum, self.out_ann,
                         [0, ['CS-CHANGE @ %d: %d->%d' % (self.samplenum, self.oldcs, cs)]])
                self.oldcs = cs
                if cs == 0:
                    self.state = "start"
                if cs == 1:
                    self.state = "stop"
                    # Reset decoder state.
                    self.mosidata = 0
                    self.misodata = 0
                    self.bitcount = 0
                    continue


            # Ignore sample if the clock pin hasn't changed.
            if sck == self.oldsck:
                continue

            if self.state == "start":

                self.oldsck = sck
    
                # Sample data on rising/falling clock edge (depends on mode).
                mode = spi_mode[self.options['cpol'], self.options['cpha']]
                if mode == 0 and sck == 0:   # Sample on rising clock edge
                        continue
                elif mode == 1 and sck == 1: # Sample on falling clock edge
                        continue
                elif mode == 2 and sck == 1: # Sample on falling clock edge
                        continue
                elif mode == 3 and sck == 0: # Sample on rising clock edge
                        continue
    
                # If this is the first bit, save its sample number.
                if self.bitcount == 0:
                    self.start_sample = self.samplenum
                    active_low = (self.options['cs_polarity'] == 'active-low')
                    deasserted = cs if active_low else not cs
                    if deasserted:
                        self.cs_was_deasserted_during_data_word = 1
    
                ws = self.options['wordsize']
    
                # Receive MOSI bit into our shift register.
                if self.options['bitorder'] == 'msb-first':
                    self.mosidata |= mosi << (ws - 1 - self.bitcount)
                else:
                    self.mosidata |= mosi << self.bitcount
    
                # Receive MISO bit into our shift register.
                if self.options['bitorder'] == 'msb-first':
                    self.misodata |= miso << (ws - 1 - self.bitcount)
                else:
                    self.misodata |= miso << self.bitcount
    
                self.bitcount += 1
    
                # Continue to receive if not enough bits were received, yet.
                if self.bitcount != ws:
                    continue
    
                self.put(self.start_sample, self.samplenum, self.out_proto,
                         ['DATA', self.mosidata, self.misodata])
                self.put(self.start_sample, self.samplenum, self.out_ann,
                         [ANN_HEX, ['MOSI: 0x%02x, MISO: 0x%02x, StartSample: %d, StopSample: %d' % (self.mosidata,
                         self.misodata, self.start_sample, self.samplenum)]])
    
                if self.cs_was_deasserted_during_data_word:
                    self.put(self.start_sample, self.samplenum, self.out_ann,
                             [ANN_HEX, ['WARNING: CS# was deasserted during this '
                             'SPI data byte!']])
    
                # Reset decoder state.
                self.mosidata = 0
                self.misodata = 0
                self.bitcount = 0
    
                # Keep stats for summary.
                self.bytesreceived += 1
------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
_______________________________________________
sigrok-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sigrok-devel

Reply via email to