Standard Library: DSPI

Overview

The Digilent SPI (DSPI) library provides an alternative interface to the standard chipKIT SPI library (SPI) for accessing SPI ports. The DSPI library provides access to all hardware SPI ports supported by the board in use and provides the ability to perform buffered and interrupt driven transfers.

The 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 devices or as 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 transmits 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 DSPI library only supports operation as an SPI master device.

An SPI transaction begins with the master device bringing SS low. When the slave ses 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. In general, 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) 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.

PIC32 microcontrollers support all four transfer modes, but only support shifting the data to the left (most significant bit first). The DSPI library header file defines symbols used to specify the transfer mode, and default SPI clock rate. Refer to documentation for the SPI slave device being used to determine the transfer mode and shift direction required by the device. Most SPI devices use mode 0 with shift left. The DSPI library can’t be used to access SPI devices that require the data to be shifted to the right (least significant bit first). In this case, the SoftSPI library can be used instead.

The DSPI library defines an object class (DSPI0, DSPI1, etc.) for each hardware SPI port supported by the board in use. These are used to create one or more object instances used to access the SPI ports. The symbol NUM_DSPI_PORTS is defined for each board and can be used to determine the number of DSPI ports available on the board. To use the DSPI library, an object instance variable of the appropriate DSPIx object class must be created. The object instance is initialized by calling the begin function() and then using other functions to set mode, and clock speed if necessary. Data can then be transferred to a slave device by calling the various data transfer functions.

Defined Interface Symbols

The following symbols are defined in the SoftSPI header file (SoftSPI.h) and can be used with the various configuration functions:

Transfer Mode Values:

  • DSPI_MODE0
  • DSPI_MODE1
  • DSPI_MODE2
  • DSPI_MODE3

Default Clock Speed Value:

_DSPI_SPD_DEFAULT default SPI clock speed, 1Mhz

The SPI port being used is automatically configured for DSPI_MODE0 and with the clock speed set to _DSPI_SPD_DEFAULT when the port is initialized by calling the begin() function.

DSPI Functions

Initialization and Setup Functions:

The following functions are used to initialize the SPI port for operation:

Data Transfer Functions:

The following functions are used to transfer data to and/or from the SPI slave device:

Interrupt Control and Interrupt Data Transfer Functions:

The following functions are used to manage transferring data to and/or from an SPI slave device in the background using interrupts. The enableInterruptTransfer() function must be called before any of the interrupt driven data transfer functions are called. The disableInterruptTransfer() function should be called when interrupt driven transfers are no longer going to be performed.

An interrupt driven transfer function will schedule the transfer to occur in the background and then return immediately. The data transfer will not have been completed when the function returns. The transCount() function can be used to determine the number of bytes remaining to be transferred. The transfer is complete when transCount() returns 0.

An interrupt driven transfer can be cancelled before it has completed by calling the cancelIntTransfer() function. Once an interrupt driven transfer has begun, no other transfers on that SPI port can be performed until it has completed or been cancelled.

The buffers involved in an interrupt driven transfer must remain valid and must not be modified once a transfer has begun until it has completed or been cancelled. In particular, the buffers involved must not be automatic local variables within a function unless control will remain in that function until the transfer is completed. Automatic local variables within a function are stored on the process stack, and the memory is freed when the function returns. In this case, the DSPI interrupt transfer routines will be reading and writing to undefined memory resulting in unpredictable operation and generally causing the system to crash. In general only static buffers should be used for interrupt transfers.