Tutorials and explanations on the MSP430 microprocessor for the uninitiated. This blog is a collection of notes as I learn to use this microprocessor in a scientific laboratory venue and geared specifically to developing science instruments.

08 September 2012

Tutorial 19b: USI SPI

Previously, I hinted at the variety of configurations possible for SPI communication. The MSP430's USI peripheral is very flexible for all of these configurations, so which we use will primarily be determined by the devices we connect to it. That being said, it's important to know how to decide which configuration we need to use.

SPI Modes

There are four primary modes for SPI, depending on the signal's polarity (whether it idles high or low) and its phase (do we read when the clock is low and write when the clock is high, or vice-versa). Common notation for these two values are CPOL and CPHA, respectively. TI, however, uses the values CKPL and CKPH, with CKPH being inverted from the standard definitions for CPHA. (That is, if CPHA = 0, CKPH = 1 and if CPHA = 1, CKPH = 0.)

When CPOL/CKPL = 0, the line idles low. An example of the timing of a mode using low polarity and using clock high to read is shown here. (These example diagrams come from John Davies' excellent book MSP430 Microcontroller Basics.)
Note that we determine the phase by looking at the edge that appears in the middle of a bit. In this example, we see a rising edge in the middle, followed by a falling edge between bits. Whichever edge occurs in the middle of the bit is a read, and the edge between bits is a write, and the order these occur (not which direction the edge is!) determines the phase. This tells us we want to use CPHA = 0 (or CKPH = 1 for the MSP430) which reads first, then writes. This mode is often referred to as either Mode 0,0 or Mode 0.

Mode 0 Timing Diagram
From [Davies, 2008].

Here's another example using CPOL/CKPL = 1, with the line idling high. In this example, the rising edge is still in the middle of the bit, and the falling edge is between, but the write is first and the read second. For this setup we would use CPHA = 1 (or CKPH = 0 for the MSP430). This mode is called Mode 1,1 or Mode 3 (as in 0b11 = 3).

Mode 3 Timing Diagram
From [Davies, 2008].

Now let's look at a real-world example. The Microchip 25AA080C chip is an SPI EEPROM with 1 kB (1024 bytes) of memory. In its datasheet, we see this timing diagram:

The diagram specifies Mode 0,0 (alternatively Mode 1,1), but we can verify that ourselves because (1) the line idles low, and (2) the read occurs before the write. For this device, we want to use CKPL = 0 and CKPH = 1 for the MSP430. Note also that the order of the transmission is specified as MSB first.

Configuring the USI

The USI uses 6 registers in the MSP430. One new thing about these registers that we haven't seen before is that, since each register is only one byte in size, we can also access them as 3 2-byte registers: the USI Control Register (USICTL), the USI Clock and Counter Control Register (USICCTL), and the USI Shift Register (USISR). (Alternatively, you can manipulate each register individually. There are convenient times to use both methods.)

USICTL

The control register is comprised of two parts: USICTL0 and USICTL1. The pertinent bits are described here.

USICTL0 (lower byte)

USIPEx (bits 7-5): these bits enable the USI functions on the MSP430 pins. (The MSP430G2211 and G2231 use pins P1.5-7 for USI functions.) These pins are already connected to other peripherals with the P1SEL register, so they are configured for USI through its own register, each pin individually.

USILSB (bit 4): when set, data is transmitted least significant bit first rather than the default most significant bit first.

USIMST (bit 3): when set, the MSP430 will act in the master role, and SCLK is connected to the USI clock as an output. When cleared (the default configuration), it's in slave mode, and SCLK is an input.

USIOE (bit 1): when set, output is enabled. This function is equivalent to the chip select in other devices; since the MSP430 doesn't have an explicit pin configuration for chip select, it has to be done in software if its use is needed.

USISWRST (bit 0): software reset for the USI; when set, operation is held to allow configuration. This bit must be cleared to start the USI.

USIIE (bit 4): enable interrupts for the USI counter; flags an interrupt when the specified number of bits have been transmitted.

USIIFG (bit 0): interrupt flag for USIIE. This flag can either be cleared automatically or manually, though as we'll see later manual clearing is usually desireable.

USICCTL

The two parts of this register are USICKCTL and USICNT, for the clock and the counter.

USICKCTL (lower byte)

USIDIVx (bits 7-5): Divide clock by powers of two up to 128.

USISSELx (bits 4-2): Source select for the clock. USI has a wide variety of clock possibilities, including the Timer_A capture/compare registers. The variety allows for a lot of fine tuning for the exact transmission speed needed. (These bits are not used if the USI is used in slave mode.)

USISWCLK (bit 0): One option for the clock is to do everything in software. In this case, toggling this bit serves as the clock.

USICNT (upper byte)

USI16B (bit 6): When set, USI will transmit up to 16 bits . When clear, USI will transmit up to 8 bits.

USIIFGCC (bit 5): When set, the interrupt flag must be cleared manually.

USICNTx (bits 4-0): Writing a value to these bits starts transmission, which continues until the number of bits specified is reached (eg. to transmit 6 bits, write 0b00110 to these bits).

USISR

The two byte-sized registers here are USISRL (the lower byte) and USISRH (the upper, or high byte). USISRH is ignored if the USI is configured in 8 bit mode (ie. USI16B is cleared in USICNT).

For the 25AA080C, we'll configure the MSP430 to be in master mode by setting USIMST, and select an appropriate clock speed for transmission. (At 3.3V, the 25AA080C works up to 5 MHz.) Using Mode 0, we'll clear USICKPL and set USICKPH. The commands (which we'll examine in the next tutorial) are 8 bits in length with MSB first, so we'll use the 8-bit shift register mode by clearing USI16B and use MSB first by clearing USILSB. Since we'll need to connect the two data lines and the clock to the EEPROM, we need to be sure to set all of the USIPEx bits. While not essential, we'll also use one extra P1 output to control the chip select for the EEPROM. Got all that? Great. Next time we'll actually do it!

If you're following along exactly, be sure you get an SPI EEPROM device before doing the next post. These are quite inexpensive, and available directly from Microchip. If you use a size other than the 8 kbit one I'm using, most everything will be the same.