Embedded systems are becoming less expensive and smaller as they grow more complicated. This is partly due to specialized peripherals often connected to a controller using a serial interface. Although numerous proprietary serial interfaces still exist, standard interfaces like Inter-IC (I2C) and Serial Peripheral Interface (SPI) are gaining popularity.
In particular, SPI is being used on more sophisticated devices because of its higher transfer rate and built-in support on many microcontrollers, microprocessors, and DSPs. It also is possible to write an SPI driver given three general-purpose I/O lines, even permitting the implementation of SPI using the parallel port on a PC. Using a deep-memory, mixed-signal oscilloscope (MSO) simplifies the debugging of the various physical- and command-layer problems that users typically encounter.
SPI basics: Motorola first popularized SPI, a synchronous serial-data protocol, in its 68HCxx microcontrollers. A simple three-wire interface allows smaller size and pin-count parts, resulting in tighter board-area designs. Access to the device is controlled through a chip-select (CS) input, so that any number of devices can share the same bus. Typical SPI peripherals are EEPROMs, analog-to-digital converters (ADCs), thermal-management devices, real-time clocks, and LCD controllers. In addition, SPI can support high data rates of up to 5 Mbits/s, as well as full-duplex communications, though the latter feature is used less frequently.
Debugging the physical-layer interface: Controlling a peripheral with SPI is accomplished in two layers: the physical layer and the command layer. At the physical layer, SPI will let multiple devices exist on its three-wire interface. One device, usually the microcontroller/processor, acts as the master. It controls the data flow, while the peripheral device acts as the slave. One master may simultaneously shift data into multiple slaves, but only one slave may be read at a time. The typical embedded-system arrangement consists of a few different SPI peripherals on a single SPI bus, with CS used to pick the device being controlled (Fig. 1). Occasionally, CS is employed not only to choose the device, but also to initiate a data transfer.
Because SPI isn't a formal standard, a variety of implementations and pseudo-SPI interfaces have arisen. The first area of physical configuration is the clock. A peripheral device usually specifies the maximum clock rate and when the data is clocked for both read and write. Typically, the selection of a master clock rate occurs with a limited number of fixed clock divider rates (e.g., 1/2, 1/8) from the controller's system clock rate. If the data-transfer rate of an SPI peripheral is a primary system design goal, the maximum peripheral clock rate and available dividers may influence the controller clock frequency. Then, the tradeoff of optimal controller clock rate relative to the computational demands must be made.
The next SPI configuration to consider is the four clock configurations, each one a unique combination of clock polarity and clock phase (Fig. 2). The polarity determines the clock line's level when inactive, while phase determines if data is clocked on the rising or falling edge.
The most common configuration among peripherals is a low-polarity clock, in which the peripheral clocks data in on the positive clock edge and out on the negative clock edge. Given that multiple peripherals from various vendors frequently exist on the same SPI, the SPI master is commonly reconfigured for each device on-the-fly as it communicates with different SPI devices. For example, Peripheral #1 might be a serial EEPROM that requires a positive-inactive clock when CS is activated, while Peripheral #2 could be a real-time clock requiring a negative-inactive clock (Fig. 1, again).
Common SPI turn-on problems involve configuring the controller clock rate, phase, and polarity for each peripheral, as they may vary. An MSO is ideal for debugging the SPI physical layer because analog channels are best used on data lines—particularly serial in—for determining when the peripheral is driving the interface in response to a read command. Meanwhile, the digital channels can monitor the clock and CSs.
Often, when viewing serial data streams, the user must perform the role of "mental UART," or converting the serial data to parallel data bytes. Using the time-based vernier to achieve one clock cycle per division simplifies the conversion of the waveform data to a data byte (Fig. 3). Implementing the vernier to align the rising clock edge to the graticule allows easier conversion of the serial data to a byte. SPI devices always send the most significant bit first. In this case, the data sent on the rising clock edge is 00100001 binary, or 21 hexadecimal.
Debugging the command-layer interface: While the SPI physical layer is somewhat standardized, the data layer varies dramatically from device to device, depending on the peripheral's functionality and complexity. But there are some common command techniques.
Frequently, SPI peripherals have numerous internal registers. Users usually send a command consisting of the register address, and a Read or Write bit. The simplest case is the Write, because data to be written usually follows the command byte. The Read is trickier, because the peripheral goes from receiving data to sending data on the next clock edge. An engineer can use the analog channels on an MSO to see the peripheral's output change from three-state to driven, as seen on "D IN" (Fig. 4). Due to the common difficulty in determining a problem in writing to, or reading from, a peripheral, this provides a valuable clue when debugging SPI device programming. The state change tells the user that the peripheral has received a valid command and is responding by sending data.
Another popular command feature is burst mode, also referred to as auto-increment or streaming mode. In this mode, the address of the data is automatically incremented with each read or write, making it possible to efficiently stream data to and from the device. For auto-increment modes, a deep-memory oscilloscope is crucial to see the entire bulk data transfer, as well as to zoom in and pan to verify the individual bytes.