Hug pid:131183771 by:White
It is still discussed in the Microelectronic System
Click here to view the Microelectronic System review: SPI
The specific transmission details of SPI are clearly explained there, so I will briefly mention it here without going into detail.
Overview
SPI is a synchronous communication protocol developed by Motorola in the 1980s, primarily used for high-speed data transfer between microcontrollers and various peripherals. The design goal of SPI is to achieve high-speed, full-duplex communication, suitable for various applications in embedded systems.
The SPI protocol follows a master-slave architecture, where the master device initiates communication and controls data transfer, while the slave device responds to the master’s requests. Typically, there is one master device and one or more slave devices on a single SPI bus, with only one master device active at any given time.

A typical SPI implementation consists of four lines:
- MOSI (Master Out Slave In): The line for the master device to send data to the slave device.
- MISO (Master In Slave Out): The line for the slave device to send data to the master device.
- SCLK (Serial Clock): The clock signal line generated by the master device.
- CS/SS (Chip Select/Slave Select): The line for the master device to select which slave device to communicate with.
This is a typical four-wire connection for full-duplex SPI, which may vary in other scenarios. For half-duplex SPI connections, MOSI and MISO can share a single line. For SPI devices that only send or only receive, either the MOSI or MISO line can be used. In multi-master SPI connections, the CS/SS line can be multiplexed.
Transmission
SPI is suitable for high-speed data transmission, typically ranging from a few Mbps to several tens of Mbps. The speed of SPI depends on the clock frequency of the master device and the response capability of the slave device. The transmission rate of SPI is usually much faster than that of I2C, making it suitable for applications requiring high-speed data transfer. Since it does not need to transmit addresses and wait for ACK like I2C, SPI has lower transmission latency. Additionally, the full-duplex feature allows SPI to send and receive data simultaneously, further improving transmission efficiency.

For SPI transmission, attention must be paid to the parameters of the SCLK clock, specifically the CPOL (Clock Polarity) and CPHA (Clock Phase) parameters. CPOL determines the idle state of the clock line, while CPHA determines whether the device reads and sends data on the rising or falling edge of the clock. The parameters you use in practice are often determined by the data sheet of the device you choose.

SPI in MBed OS
SPI Master
The API introduction comes from the official documentation of MBed OS.
<span>SPI(PinName mosi, PinName miso, PinName sclk, PinName cs)</span>: Constructor to create an SPI object.<span>mosi</span>: Master device output line.<span>miso</span>: Master device input line.<span>sclk</span>: Master device clock line.<span>cs</span>: Master device chip select line, optional parameter, default is<span>NC</span>(not connected).<span>void format(int bits, int mode)</span>: Set the data format and clock mode of SPI.<span>bits</span>: Number of data bits, typically 8 or 16 bits.<span>mode</span>: Clock mode, with values ranging from 0 to 3, corresponding to combinations of CPOL and CPHA.<span>void frequency(int hz)</span>: Set the clock frequency of SPI.<span>hz</span>: Clock frequency in Hertz.- The default parameter is 1MHz.
<span>int write(const char *tx_buffer, int tx_length, char *rx_buffer, int rx_length)</span>: Send and receive data.<span>tx_buffer</span>: Transmit buffer.<span>tx_length</span>: Length of data to send.<span>rx_buffer</span>: Receive buffer.<span>rx_length</span>: Length of data to receive.- The total number of bytes exchanged is the maximum of
<span>tx_length</span>and<span>rx_length</span>. Any excess bytes are filled with default values. <span>void set_default_write_value(int value)</span>: Set the default write value.<span>value</span>: Default write value, typically 0xFF.- Some SPI devices may send data when no data is being transmitted; this function can set the default write value.
Sample program (from MBed OS 6: SPI)
/*
* Copyright (c) 2006-2020 Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*/
#include "mbed.h"
SPI spi(D11, D12, D13); // mosi, miso, sclk
DigitalOut cs(D0);
int main()
{
// Chip must be deselected
cs = 1;
// Setup the spi for 8 bit data, high steady state clock,
// second edge capture, with a 1MHz clock rate
spi.format(8, 3);
spi.frequency(1000000);
// Select the device by setting chip select low
cs = 0;
// Send 0x8f, the command to read the WHOAMI register
spi.write(0x8F);
// Send a dummy byte to receive the contents of the WHOAMI register
int whoami = spi.write(0x00);
printf("WHOAMI register = 0x%X\n", whoami);
// Deselect the device
cs = 1;
}
SPI Slave
<span>SPISlave(PinName mosi, PinName miso, PinName sclk, PinName cs)</span>: Constructor to create an SPI slave object.<span>mosi</span>: Slave device input line.<span>miso</span>: Slave device output line.<span>sclk</span>: Slave device clock line.<span>cs</span>: Slave device chip select line, optional parameter, default is<span>NC</span>(not connected).<span>void format(int bits, int mode)</span>: Set the data format and clock mode of SPI.<span>bits</span>: Number of data bits, typically 8 or 16 bits.<span>mode</span>: Clock mode, with values ranging from 0 to 3, corresponding to combinations of CPOL and CPHA.<span>void frequency(int hz)</span>: Set the clock frequency of SPI.<span>hz</span>: Clock frequency in Hertz, default parameter is 1MHz.<span>int receive()</span>: Check if there is data to read.- Return value:
<span>0</span>: No data to read.<span>1</span>: Data is available to read.
<span>int read()</span>: Read data.- Return value is the data read.
<span>void reply(int value)</span>: Reply with data.<span>value</span>: The data to reply with.
Sample program (from MBed OS 6: SPI Slave)
/*
* Copyright (c) 2006-2020 Arm Limited and affiliates.
* SPDX-License-Identifier: Apache-2.0
*/
#include "mbed.h"
SPISlave device(D12, D11, D13, D10); // mosi, miso, sclk, ssel
int main()
{
device.reply(0x00); // Prime SPI with first reply
while (1) {
if (device.receive()) {
int v = device.read(); // Read byte from master
v = (v + 1) % 0x100; // Add one to it, modulo 256
device.reply(v); // Make this the next reply
}
}
}

Using SPI to Drive ADXL345

ADXL345 is a three-axis accelerometer that supports SPI and I2C communication. We will use SPI to drive it.
By referring to the ADXL345 data sheet, we understand its driving voltage and software configuration details.

According to the data sheet, the maximum frequency for SPI is 5MHz, with CPOL and CPHA both set to 1, and MB is set to 1 to enable single multi-byte transmission.
This is the timing for writing and reading:

Thus, we can conclude that the driver code for ADXL345 in MBed OS should look like this:



In summary, the register configuration and specific communication content can be found in the ADXL345 data sheet, while the specific implementation of SPI can be found in the MBed OS API documentation. Combine both to achieve normal peripheral communication.
I will not continue to copy the register definitions from the data sheet here.
