This article on chipKIT software SPI library is written by Gene Apperson, Digilent Inc.
At Digilent we have been working to extend the chipKIT software framework beyond its original Arduino-inspired roots. Recent enhancements enable the framework to be used with many different systems based on PIC32 MCUs. In order to support arbitrary hardware configurations, we implemented a general-purpose Serial Peripheral Interface (SPI) library that does not rely on dedicated hardware peripherals. The Software SPI (SoftSPI) library allows the creation of any number of software based (bit-banged) SPI ports.
Serial Peripheral Interface (SPI) is a four wire synchronous serial interface used by many integrated circuits and electronic devices. SPI devices can operate as either master slave devices. The four SPI signals are generally referred to as Slave Select (SS), Master Out, Slave In (MOSI), Master In, Slave Out (MISO), and Serial Clock (SCK). A master device generates SS, MOSI and SCK, and receives MISO. A slave device receives SS, MOSI, and SCK and generates MISO. The SS signal is used to enable the slave device, and this signal is only significant for slave devices. A master device can use any general purpose I/O pin to generate SS to enable a slave.
The SoftSPI library only supports operation as an SPI master device.
An SPI transaction begins with the master device bringing SS low. When the slave sees SS go low it becomes enabled and waits for the master to send data. The master shifts data out on MOSI and simultaneously shifts data in on MISO. The slave device receives data from the master on its MOSI pin and simultaneously sends data to the master on its MISO pin. Each time the master sends a byte to the slave, it simultaneously receives a byte from the slave. The master generates the clock signal (SCK) that is used to control the shifting of the data in both the master and the slave.
SPI devices can operate using one of four data transfer modes, and one of two shift directions. The transfer modes specify the idle state of the clock signal (idles high or idles low) the active edge of the clock, and the phase relationship between the active edge of the clock signal and the data. The modes are generally called mode 0 through mode 3. The shift direction specifies whether the data is shifted most significant bit first (shift left), or least significant bit first (shift right). The SoftSPI library header file defines symbols used to specify the transfer mode and shift direction. Refer to documentation for the SPI slave device being used to determine the transfer mode and shift direction to use. Most SPI devices use mode 0 with shift left.
The SoftSPI library defines an object class (SoftSPI) that is used to create a separate object instance for each desired SPI port. Each instance of the SoftSPI object class uses four specified digital pins for the SPI signals. The SoftSPI object class supports all four transfer modes, both shift directions, and setting the frequency of the clock signal.
To use the SoftSPI library, an object instance variable of the SoftSPI object class must be created:
/* Declare an instance of the SPI interface object */
SoftSPI spi;
The object instance is initialized using functions to set mode, shift direction and clock speed. In this example, a 6uS delay between bytes is specified to accommodate a joystick peripheral:
/* Define digital pins for the SoftSPI port to use*/
#define pinSS 24
#define pinMOSI 25
#define pinMISO 26
#define pinSCK 27
/* Initialize the SPI port */
spi.begin(pinSS, pinMOSI, pinMISO, pinSCK);
spi.setSpeed(250000);
spi.setMode(SSPI_MODE0);
spi.setDirection(SSPI_SHIFT_LEFT);
spi.setDelay(6); /* delay 6uS between bytes */
Data can then be transferred to a slave device by calling the various data transfer functions. This example communicates with Digilent's PmodJSTK peripheral:
{
uint8_t rgbSnd[5];
uint8_t rgbRcv[5];
int ib;
/* Initialize the transmit buffer */
for (ib = 0; ib < 5; ib++) {
rgbSnd[ib] = 0x50 + ib;
}
rgbSnd[0] = fbLedPmod + 0x80;
// First byte sets the LEDs
/* Bring SS low to begin the transaction */
spi.setSelect(LOW);
/* Wait 10us for Pmod to become ready */
Delay10us();
/* Send the data to the Pmod and get the response */
spi.transfer(5, rgbSnd, rgbRcv);
/* Bring SS high to end the transaction */
spi.setSelect(HIGH);
}
The SoftSPI Library is included with versions of the Multi-Platform IDE (MPIDE) dated 12/15/2011 or later. Complete documentation is available here.