SPI Digital Waveform Reference Library

Publish Date: Sep 08, 2011 | 6 Ratings | 4.17 out of 5 | Print | 2 Customer Reviews | Submit your review


The Serial Peripheral Interface (SPI) bus is found in wide use for communication and control in integrated circuits. It is becoming an increasingly common requirement that automated test equipment be able to communicate with this protocol. The SPI Digital Waveform (SDW) component provides high-level building blocks that allow a system designer to construct valid SPI waveforms with custom timing and messaging, as well as examples of some simple SPI packets. These waveforms can be generated using any National Instruments hardware-timed digital I/O device. Additionally, they support features of the 6547, 6548, 6551, 6552, and 6556 devices (per-cycle tri-state and hardware compare) that make retrieving and parsing MISO data fast and efficient.

Table of Contents

  1. SPI Specification
  2. The SPI Digital Waveform Component
  3. Using the SDW Library to Generate SPI Signals
  4. Related Articles
  5. Discussion and Feedback

1. SPI Specification

The SPI physical layer protocol, while adhering to a common description in most applications, is not strictly defined by any single governing entity like the IEEE.  A high-level description of the most commonly accepted standards can be found on Wikipedia. The specification to which this library adheres is Freescale Semiconductor's Serial Peripheral Interface (SPIV3) Block Description.

Back to Top

2. The SPI Digital Waveform Component

The NI SPI Digital Waveform component installs a new library into the <user.lib> folder, called SDW.lvlib. This library contains all the API VIs, type definitions, subVIs, and polymorphic instance VIs belonging to the component. The API VIs can be placed on the diagram from the SPI Digital Waveform palette in the User Libraries function palette.

SPI Digital Waveform Palette

The SPI Digital Waveform palette contains three rows of VIs. The top row contains utility functions that handle SDW sessions and data conversion. The middle row contains high-level VIs that build segments of a SPI command. The bottom row contains low-level VIs that add an individual bit to the waveform.

The component also installs an example VI into the Example Finder. (See below.)

Optional SPI Signals

A 4-wire SPI bus requires all four signals -- SCLK, MOSI, MISO, and CS -- to communicate bidirectionally with a slave device. The input signal, MISO, is generated by the SDW library using compare bit states (L, H, X) to take advantage of the Hardware Compare feature of some NI High-Speed Digital Waveform Generator/Analyzer (HSDIO) devices. The MISO signal can be removed from the SPI waveform when using a device that lacks Hardware Compare, such as an NI-DAQmx device. To do so, use the Digital Signal Subset VI on the Functions » Waveform » Digital Waveform palette.


SDW.lvlib contains the following API functions:

Init.vi performs two functions. It coerces timing values to the generating device's sample clock and validates the coerced parameters against the desired SPI clock rate. It then creates the session cluster (SPI Waveform info-fmt0 or SPI Waveform info-fmt1) that is used by the waveform component VIs.

Init.vi is polymorphic in two parameters:

Memory: Its preferred memory action is to preallocate memory for the SPI waveform. This greatly increases the execution speed of the waveform component VIs, but it requires a parameter for how many samples will be used in the waveform. Its alternate action, which is not to preallocate memory, circumvents this requirement at the cost of execution speed.

Transmission format: It configures the session cluster to build a waveform in either CPHA = 0 format (in-phase clock) or CPHA = 1 format (out-of-phase clock). See below for more information on each transmission format.

Close.vi closes the session by converting the SPI waveform info cluster into a digital waveform (DWDT). This DWDT can also optionally be appended to an existing DWDT.

This VI performs two functions specific to the HSDIO line of NI devices. Devices that use the NI-HSDIO driver commonly require waveforms to meet memory alignment. This is specified as a sample quantum, usually 2, 4 or 8 samples. When building the DWDT, the VI coerces the waveform's length to a multiple of the sample quantum by duplicating the last sample repeatedly. The NI 6547, 6548, 6551, 6552, and 6556 devices also feature a Hardware Compare engine that can compare sampled data to an expected waveform in real-time, making the analysis of returned slave messages much more efficient. This VI outputs a list of sample locations that the Hardware Compare engine will have analyzed, so the location of each analyzed bit can be known within the waveform.

Swap.vi performs a single full-duplex transfer of data between the host and the slave device, as is normal for a 4-wire SPI bus. In this action, bits are transferred from the host to the slave on the MOSI line and from the slave to the host on the MISO line using the same set of clock cycles. 

This VI is designed to accommodate the most common register sizes: 8, 16, 32, and 64 bits. It is polymorphic and will adapt to any unsigned integer datatype wired to its inputs (U8, U16, U32, U64). Note that the sizes of the MISO and MOSI data must be equal, as the bits are transferred one-for-one.

Send.vi mimics a half-duplex transfer of data from the host to the slave device. It does this by ignoring bits received on the MISO line. As with Swap.vi, this function is polymorphic to all unsigned numeric datatypes.

Receive.vi mimics a half-duplex transfer of data to the host from the slave device. It does this by holding the MOSI line low while clocking data in on the MISO line. It is assumed that the slave device is ignoring the MOSI line while this happens. As with Swap.vi, this function is polymorphic to all unsigned numeric datatypes.

Add First Bit.vi adds samples to the waveform that comprise the first clocked bit of a multi-bit SPI transfer. Preceding this clocked bit is the assertion of the appropriate chip-select (CS) line; this is also added to the waveform.

Add Middle Bit.vi adds samples to the waveform that comprise neither the first nor the last bit of a multi-bit SPI transfer. For example, in a byte transfer (8 bits), this function is used to add bits [6..1] (or [1..6] for LSB-first data) to the waveform. These bits do not affect the CS lines, unlike bits 0 and 7, which are thus handled by other functions.

Add Last Bit.vi adds samples to the waveform that comprise the last clocked bit of a multi-bit SPI transfer. Succeeding this clocked bit is the deassertion of the appropriate chip-select (CS) line; this is also added to the waveform.

Add CS Idle Time.vi adds samples to the waveform that allow the chip-select lines to remain idle for a fixed amount of time in between transfers. (This is a requirement for some slave devices.)

Interpret Data.vi is a low-level function that converts a bitfield of data into an array of digital data that is compatible with the Digital Waveform Datatype (DWDT). For the MOSI signal, it turns bits into an array of the drive states [1, 0]. For the MISO signal, it turns them into an array of the compare states [H, L]. The output array of bits is used by successive calls to the Add First Bit, Add Middle Bit, and Add Last Bit VIs, providing the MOSI and MISO states in each call.

This VI is designed to accommodate the most common register sizes: 8, 16, 32, and 64 bits. It is polymorphic and will adapt to any unsigned integer datatype wired to its inputs (U8, U16, U32, U64).

Installed Examples

An example VI is installed by this component. To open it using the NI Example Finder, select "Browse according to Directory Structure" and navigate to the SPI Digital Waveform folder. It can also be found at the installation path <lvdir>/examples/SPI Digital Waveform.

Back to Top

3. Using the SDW Library to Generate SPI Signals

Because the API VIs build a waveform by appending segments to each other, they can be called in sequence to construct a SPI packet dynamically. For example, a packet that transmits a byte of data to each of two slave devices is shown. The waveform data is broken down into the pertinent component parts. (Note that this is a half-duplex transmission, so the MISO line is ignored.)

A pair of byte transmissions to separate slave devices

Shown below are the VIs used to build this waveform. They are called in the exact same sequence as the waveform they construct. The Init and Close VIs are used to gather timing information and to convert the waveform to a DWDT.

Code used to generate a single-byte transmit packet

This provides an intuitive interface for test designers, as well as a modular API that can be wrapped into higher-level functions that build custom packets for specific slave devices, needing only the transmitted or expected data and slave address as inputs.

For applications that have uncommon register sizes (not a multiple of 8 bits), the low-level VIs can be used to construct a compliant waveform. For an example of how this is done, simply look inside one of the high-level VIs (Swap, Send, and Receive).

Clock Phase and Polarity

To remain flexible enough to work with many implementations of the I/O logic, the SPI protocol can toggle its serial clock phase and polarity.  The parameters that control this are CPHA (for Clock PHAse), and CPOL (for Clock POLarity). The CPOL parameter defines the base state of the clock at the beginning of each packet, high or low. The CPHA parameter defines when data is loaded into the slave device's output register to be sampled by the host. This affects the timing of the transmission waveform.  When CPHA = 0, Format 0 is used. When CPHA = 1, Format 1 is used.

(For detailed information on how the waveform timing is affected by these two parameters, refer to the specification resources linked above.)

The SDW API accommodates clock phase shifting through polymorphism.  Every function in the API is a passively polymorphic VI, adapting to the session cluster that is passed into it. The developer needs only to select the transmission format (Format 0 or Format 1) when placing the Init VI.  Every subsequent API call in the logic chain will then adapt to the session cluster that is output by the Init function and build a waveform that corresponds to that format.

Back to Top

4. Related Articles

This whitepaper explains the use of the IDW library functions in isolation. For an explanation of their use in conjunction with NI-DAQmx or NI-HSDIO based devices, refer to:

NI Systems Engineering has also created additional components for other serial protocols:

Back to Top

5. Discussion and Feedback

This component was created by the NI Systems Engineering group.

We welcome discussion and feedback about this component. The SPI Digital Waveform Library thread is available on the NI Discussion Forums for questions, comments, and suggestions.

Back to Top

Customer Reviews
2 Reviews | Submit your review

Needs Linux/Mac implementation  - Feb 8, 2010

Installable exe makes it useless for non-windows users.

  - Apr 10, 2009

Submit your feedback on the discussion forum linked above. We do not monitor this page for comments

Bookmark & Share










Rate this document

Answered Your Question?
Yes No