HardwareSPI

This page describes how to use the built-in SPI ports. It does not describe the SPI protocol itself. For more information about SPI, see the SPI reference.

Getting Started

In order to get started, you’ll first need to define a HardwareSPI variable, which you’ll use to control the SPI port. Do this by putting the line “HardwareSPI spi(number);” with your variables, where number is the SPI port’s number.

Here’s an example (we’ll fill in setup() and loop() later):

// Use SPI port number 1
HardwareSPI spi(1);

void setup() {
   // Your setup code
}

void loop() {
   // Do stuff with SPI
}

Turning the SPI Port On

Now it’s time to turn your SPI port on. Do this with the begin() function (an example is given below).

void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode)

Turn on a SPI port and set its GPIO pin modes for use as master.

SPI port is enabled in full duplex mode, with software slave management.

Parameters:
  • frequency -

    Communication frequency

  • bitOrder -

    Either LSBFIRST (little-endian) or MSBFIRST (big-endian)

  • mode -

    SPI mode to use, one of SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, and SPI_MODE_3.

Note

If you are using SPI port 3 (on a board that supports it; not all do); you’ll need to call disableDebugPorts() before calling begin().

The speed at which the SPI port communicates is configured using a SPIFrequency value:

SPIFrequency enum

Defines the possible SPI communication speeds.

Values:

  • SPI_18MHZ = 0 -

    18 MHz

  • SPI_9MHZ = 1 -

    9 MHz

  • SPI_4_5MHZ = 2 -

    4.5 MHz

  • SPI_2_25MHZ = 3 -

    2.25 MHz

  • SPI_1_125MHZ = 4 -

    1.125 MHz

  • SPI_562_500KHZ = 5 -

    562.500 KHz

  • SPI_281_250KHZ = 6 -

    281.250 KHz

  • SPI_140_625KHZ = 7 -

    140.625 KHz

Note

Due to hardware issues, you can’t use the frequency SPI_140_625KHz with SPI port 1.

The “mode” value determines the clock phase and polarity, like so:

spi_mode enum

SPI mode configuration.

Determines a combination of clock polarity (CPOL), which determines idle state of the clock line, and clock phase (CPHA), which determines which clock edge triggers data capture.

Values:

  • SPI_MODE_0 -

    Clock line idles low (0), data capture on first clock transition.

  • SPI_MODE_1 -

    Clock line idles low (0), data capture on second clock transition.

  • SPI_MODE_2 -

    Clock line idles high (1), data capture on first clock transition.

  • SPI_MODE_3 -

    Clock line idles high (1), data capture on second clock transition.

You’ll need to determine the correct values for frequency, bitOrder, and mode yourself, by consulting the datasheet for the device you’re communicating with. Continuing our example from before, we’ll add a call to begin() to our setup():

// Use SPI port number 1
HardwareSPI spi(1);

void setup() {
    // Turn on the SPI port
    spi.begin(SPI_18MHZ, MSBFIRST, 0);
}

void loop() {
   // Do stuff with SPI
}

If you call begin() with no arguments (as in “spi.begin();”), it’s the same as if you wrote “spi.begin(SPI_1_125MHZ, MSBFIRST, 0);”.

Communicating Over SPI

Now that you’ve got your SPI port set up, it’s time to start communicating. You can send data using HardwareSPI::write(), receive data using HardwareSPI::read(), and do both using HardwareSPI::transfer().

void HardwareSPI::write(byte data)

Send a single byte of data.

Parameters:

  • data: Byte to send
byte HardwareSPI::read()

Get the next available, unread byte. If there aren’t any unread bytes, this function will wait until one is received.

byte HardwareSPI::transfer(byte data)

Send a byte, then return the next byte received.

Parameters:

  • data: Byte to send

Returns: Next unread byte

Continuing our example from before, let’s send a number over SPI and print out whatever we get back over SerialUSB:

// Use SPI port number 1
HardwareSPI spi(1);

void setup() {
    // Turn on the SPI port
    spi.begin(SPI_18MHZ, MSBFIRST, 0);
}

void loop() {
   // Send 245 over SPI, and wait for a response.
   spi.write(245);
   byte response = spi.read();
   // Print out the response received.
   SerialUSB.print("response: ");
   SerialUSB.println(response, DEC);
}

HardwareSPI Class Reference

There are a number of other things you can accomplish with your spi object. A full function listing follows.

class HardwareSPI

Wirish SPI interface.

This implementation uses software slave management, so the caller is responsible for controlling the slave select line.

Public Functions
HardwareSPI(uint32 spiPortNumber)

Parameters:
  • spiPortNumber -

    Number of the SPI port to manage.

void begin(SPIFrequency frequency, uint32 bitOrder, uint32 mode)

Turn on a SPI port and set its GPIO pin modes for use as master.

SPI port is enabled in full duplex mode, with software slave management.

Parameters:
  • frequency -

    Communication frequency

  • bitOrder -

    Either LSBFIRST (little-endian) or MSBFIRST (big-endian)

  • mode -

    SPI mode to use, one of SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, and SPI_MODE_3.

void begin(void)

Equivalent to begin(SPI_1_125MHZ, MSBFIRST, 0).

void beginSlave(uint32 bitOrder, uint32 mode)

Turn on a SPI port and set its GPIO pin modes for use as a slave.

SPI port is enabled in full duplex mode, with software slave management.

Parameters:
  • bitOrder -

    Either LSBFIRST (little-endian) or MSBFIRST(big-endian)

  • mode -

    SPI mode to use

void beginSlave(void)

Equivalent to beginSlave(MSBFIRST, 0).

void end(void)

Disables the SPI port, but leaves its GPIO pin modes unchanged.

uint8 read(void)

Return the next unread byte.

If there is no unread byte waiting, this function will block until one is received.

void read(uint8 * buffer, uint32 length)

Read length bytes, storing them into buffer.

Parameters:
  • buffer -

    Buffer to store received bytes into.

  • length -

    Number of bytes to store in buffer. This function will block until the desired number of bytes have been read.

void write(uint8 data)

Transmit a byte.

Parameters:
  • data -

    Byte to transmit.

void write(const uint8 * buffer, uint32 length)

Transmit multiple bytes.

Parameters:
  • buffer -

    Bytes to transmit.

  • length -

    Number of bytes in buffer to transmit.

uint8 transfer(uint8 data)

Transmit a byte, then return the next unread byte.

This function transmits before receiving.

Parameters:
  • data -

    Byte to transmit.

Return:

Next unread byte.

Deprecated Functions

The following functions are defined for now, but they have been deprecated, and will be removed in a future Maple IDE release. You shouldn’t use them in new programs, and you should change any of your programs which do use them to the up-to-date functions discussed above.

uint8 HardwareSPI::send(uint8* data, uint32 length)

Writes data into the port buffer to be transmitted as soon as possible, where length is the number of bytes to send from data. Returns the last byte shifted back from slave.

uint8 HardwareSPI::send(uint8 data)

Writes the single byte data into the port buffer to be transmitted as soon as possible. Returns the data byte shifted back from the slave.

uint8 HardwareSPI::recv()

Reads a byte from the peripheral. Returns the next byte in the buffer.