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.
Contents
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
}
Now it’s time to turn your SPI port on. Do this with the begin() function (an example is given below).
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: |
|
---|
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:
Defines the possible SPI communication speeds.
Values:
18 MHz
9 MHz
4.5 MHz
2.25 MHz
1.125 MHz
562.500 KHz
281.250 KHz
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 configuration.
A SPI mode determines a combination of the idle state of the clock line (the clock polarity, or “CPOL”), and which clock edge triggers data capture (the clock phase, or “CPHA”).
Values:
Clock idles low, data captured on rising edge (first transition)
Clock idles low, data captured on falling edge (second transition)
Clock idles high, data captured on falling edge (first transition)
Clock idles high, data captured on rising edge (second transition)
Same as SPI_MODE_LOW_RISING.
Same as SPI_MODE_LOW_FALLING.
Same as SPI_MODE_HIGH_FALLING.
Same as SPI_MODE_HIGH_RISING.
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);”.
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().
Get the next available, unread byte. If there aren’t any unread bytes, this function will wait until one is received.
Send a byte, then return the next byte received.
Parameters:
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);
}
There are a number of other things you can accomplish with your spi object. A full function listing follows.
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.
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.
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.