Practical
Embedded Java

All About SPI


A practical engineering approach to using embedded Java in real-world applications.


This book is a work in progress...



SPI is a duplex, bitwise serial protocol which was developed by Motorola many years ago. It is widely used to link controllers with slave devices such as analog to digital converters.

SPI Basics
Read the slave device data sheets This sounds simple but it's a recurring support issue. Read the data sheets! They are there for a reason (that is: they contain important information you need to use the part successfully), and most vendors do a good job of documenting their parts (they don't want support headaches). There are four basic SPI modes and a number of subtleties related to them. It's critical to read the slave device data sheets carefully. Don't assume anything. Some SPI slave devices have some non-obvious requirements (eeproms for example have special read and write modes) which are not handled by simple write-one-byte-per-chip-select-cycle SPI code. If in doubt about how to interpret the data sheets, contact the slave device vendor.
SPI devices can vary greatly in terms of data ordering, modes and so forth SPI slave devices can operate in one or more of four basic modes (see #???). The assertion level of slave select can be either high or low. Many devices are programmable in terms of the number of data bits transferred per SPI cycle, bit ordering (least or most significant first), and so forth. There is no "one size fits all" SPI driver. So be sure to read the device data sheets and confirm that your selected SPI devices are compatible. Don't assume that all analog to digital converters will work in the same manner, even if they are from the same manufacturer.
Consider CMOS vs TTL voltage levels SPI devices can have CMOS or TTL voltage levels, and many can operate from 5 volts or considerably less. Read the data sheets to see what your device needs for proper input and output interfacing. Here's an overview of JStamp CMOS and TTL voltage level interfacing (also applies to JStik and SaJe) and a page on TStik interfacing and voltage levels. The same CMOS/TTL rules apply to any standard devices.
Start simple Start talking to to a slave device in the simplest possible fashion to get things working. Then add complexity. Some SPI slaves can be quite complex (eeproms and multi-mode DACs come to mind). Don't try to write and test the whole slave driver at once - get a simple test case working first.
Master/slave Typically SPI systems have one master and one or more slaves, but there's nothing preventing a multi-master SPI system. Slaves are typically polled by the master, but a slave can also emit an interrupt on a separate signal, to tell the master when it needs servicing. There's nothing in the SPI specification to arbitrate between multiple masters, so you would need to figure this out yourself.
Party line MOSI and MISO, or daisy-chained MOSI/MISO

Multiple SPI slaves can share the same MOSI and MISO lines as party lines - each slave has MOSI connected to its data input and MISO connected to its data output. Then only one slave is actually enabled at a time by giving each slave a unique slave chip select. Obviously, for a party line to work, inactive SPI slaves must put their MISO signals into a tri-state (undriven) mode. Beware, because some SPI devices don't do this and therefore can't be daisy chained unless you add your own MISO tristate buffer such as a 74XX125.

Multiple SPI slaves can share MOSI and MISO in a daisy chain fashion if the particular SPI slave devices support such a topology (many do). In a daisy chain, the first slave has MOSI connected to its data input, and its data output (the first slave's MISO) is connected to the next slave's MOSI. This continues to the last slave whose MISO output is connected to the master controller. Then all slaves on this daisy chain share one slave chip select. If you have three slaves - A, B, and C, then data from the master shifts first into and through A, then into and through B and finally, into and through C. If each of these is a 32-bit SPI device then it will take 96 SPI bit cycles to complete one SPI access.

MOSI is almost always required, but MISO can be optional. An output register or digital to analog converter will use MOSI from the master, and this data sets the state or value of the output(s) on the slave. Since it's an output device, there may be no meaningful data coming back from the slave to the master. So you can ignore the MISO signal and not even bother connecting it. This creates a real "bit bucket" - like the proverbial expression - you put data into it but don't get any back. The drawback is that the controller can't directly determine if the slave device is working, or even present. Many SPI devices will echo back (on their MISO outputs) the data they receive on MOSI, so that the master can at least verify that a successful transmission took place.
SPI slave selects are nothing special SPI slave selects are just simple device enable signals. There's nothing magical about them and the timing is typically not critical. Your controller may support only one SPI slave select, for example, but you can use GPIO pins and an optional decoding scheme to add as many more as you wish. For example, on TStik (and all TINI controllers), there is no SPI hardware - SPI support is 100% firmware, using Port pins for all SPI signals. You can therefore add as many SPI slave selects as you wish by modifying the SPI firmware. The Systronix TStik SPI driver supports four slave chip selects, but you could add more using additional Port pins. As another example, JCX uses a CPLD along with some controller I/O pins to create a SPI "addressing" scheme and provide up to 24 SPI slave selects on JStamp and up to 32 on JStik.
SPI can have a native hardware and/or a firmware implementation Since all a SPI master needs to do is emit data synchronized with a clock, this is simple hardware to design. It is much like a simplified UART transmit section. SPI is also easily implemented in firmware, with pseudo code like this:
  1. Assert a slave select
  2. Assert MOSI most significant bit
  3. Toggle the clock
  4. Shift the next data bit onto the MOSI pin
  5. Repeat 3 and 4 until done
  6. negate the slave select
SPI clock is not critical in terms of speed or duty cycle, only the edges matter The only critical timing in SPI is the setup and hold time between MOSI and SCK. The clock period is not important and the period can even vary from cycle to cycle. There is no reason to make the clock 50% duty cycle - this will just needlessly slow your transfer. Changes in clock period will simply make the total cycle time of the entire SPI access vary in length. The only caveat which comes to mind is that some devices such as analog to digital converters, run the track and hold time for a number of SPI clocks, and then begin the data conversion in relation to a clock edge. Track and hold devices always droop over time, so if you elongated the track and hold portion of an ADC cycle by (to be extreme) several orders of magnitude beyond it's minimum time, you will probably find that the conversion accuracy deterioriates. If this is the case for your particular slave device then there is probably a maximum total track and hold time specified in the slave device data sheet.

SPI Signals
SCK - the SPI clock Data shifts to and from a SPI device on clock edges, either rising or falling, depending on the SPI mode. Duty cycle of the clock is generally irrelevent, and the period of the clock does not need to be constant. The edges are what matter.
MOSI - Master Out Slave In

MOSI is the SPI data bit being sent from the master controller to the SPI slave device. The most significant bit is usually shifted out first, but this can vary - so read your data sheets. SPI data must meet setup and hold times from the relevant SCK edge so that it can be properly received by a slave. MOSI is the master data output and is connected to the slave data input. One MOSI signal can be shared by multiple slaves if they each have their own chip select.

A slave's MOSI input can also come from the MISO output of a daisy-chained slave, if all such slaves share the same chip select and are designed to work in this fashion..

MISO - Master In Slave Out MISO is the SPI data coming from the slave back to the master. MISO changes state at SCK edges. The most significant bit is generally shifted in first. Why isn't this called "SOMI" instead? We don't know.
SCS{X} - SPI Slave Chip Select 'X' The SPI slave device chip select is asserted by the master and is used to enable communication with a specific slave device. Other, non-selected devices do not participate in the SPI transmission, even though they may be connected to the same SCK, MOSI, and MISO signals.

 
Systronix® 939 Edison St, Salt Lake City, Utah, USA 84111
Tel +1-801-534-1017, Fax +1-801-534-1019
contact us     Time Zone: MDT (UTC-6)
 

Java and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc. in the U.S. and other countries.
Systronix is independent of Sun Microsystems, Inc.
TStik, JStik, JCX, JStamp, JSimm, JDroid, and JRealTime are trademarks of Systronix, Inc.
1-Wire, iButton and TINI are trademarks of Dallas Semiconductor
Simmstick is a trademark of Dontronics
LEGO® is a trademark of Lego A/S, Denmark