Serial Peripheral Interface \(SPI\) is a serial bus specification used for high-speed, full-duplex, and synchronous communication.
## **Overview**
SPI is developed by Motorola. It is commonly used for communication with flash memory, real-time clocks, sensors, and analog-to-digital \(A/D\) converters.
SPI works in controller/device mode. Generally, there is one SPI controller that controls one or more SPI devices. They are connected via four wires:
Serial Peripheral Interface (SPI) is a serial bus specification used for high-speed, full-duplex, and synchronous communication. SPI is developed by Motorola. It is commonly used for communication with flash memory, real-time clocks, sensors, and analog-to-digital (A/D) converters.
- SCLK: clock signals output from the SPI controller
- MOSI: data output from the SPI controller and input into an SPI device
- MISO: data output from an SPI device and input into the SPI controller
- CS: signals enabled by an SPI device and controlled by the SPI controller
SPI works in controller/device mode. Generally, there is one SPI controller that controls one or more SPI devices. They are connected via four wires:
- SCLK: clock signal output from the SPI controller
- MOSI: data output from the SPI controller to a device
- MISO: data output from an SPI device to the controller
- Chip select (CS): output from the SPI controller to indicate that data is being sent. It is controlled by the SPI controller.
[Figure 1](#fig89085710359) shows the connection between one SPI controller and two SPI devices \(device A and device B\). In this figure, device A and device B share three pins \(SCLK, MISO, and MOSI\) of the controller. CS0 of device A and CS1 of device B are connected to CS0 and CS1 of the controller, respectively.
The figure below shows the connection between one controller and two devices (device A and device B). Device A and device B share three pins (SCLK, MISO, and MOSI) of the controller. CS 0 of device A and CS 1 of device B are connected to CS 0 and CS 1 of the controller, respectively.
<tdclass="cellrowborder"valign="top"width="55.77442255774422%"headers="mcps1.2.4.1.3 "><pid="p8738101941716"><aname="p8738101941716"></a><aname="p8738101941716"></a>Reads data of a specified length from an SPI device.</p>
Before performing SPI communication, call **SpiOpen** to open the SPI device handle. This function returns the device handle of the SPI based on the specified bus number and CS number.
</td>
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p573815197171"><aname="p573815197171"></a><aname="p573815197171"></a>Writes data of a specified length into an SPI device.</p>
| Device handle| The operation is successful. The SPI device handle obtained is returned.|
<tdclass="cellrowborder"valign="top"width="55.77442255774422%"headers="mcps1.2.4.1.3 "><pid="p073910197173"><aname="p073910197173"></a><aname="p073910197173"></a>Sets configuration parameters for an SPI device.</p>
</td>
For example, open the handle of the SPI device, whose bus number and the CS number are both **0**.
<tdclass="cellrowborder"valign="top"headers="mcps1.2.4.1.2 "><pid="p11333649171117"><aname="p11333649171117"></a><aname="p11333649171117"></a>Obtains configuration parameters of an SPI device.</p>
### Obtaining an SPI Device Handle<a name="section1927265711481"></a>
Before performing SPI communication, obtain an SPI device handle by calling **SpiOpen**. This function returns an SPI device handle with a specified bus number and CS number.
<tdclass="cellrowborder"valign="top"width="50%"><pid="p1560441923818"><aname="p1560441923818"></a><aname="p1560441923818"></a>Pointer to the SPI device descriptor.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p760471912388"><aname="p760471912388"></a><aname="p760471912388"></a>Failed to obtain an SPI device handle.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p3604181933818"><aname="p3604181933818"></a><aname="p3604181933818"></a>Returns the pointer to the SPI device handle.</p>
</td>
</tr>
</tbody>
</table>
The following example shows how to obtain an SPI device handle based on the assumption that both the bus number and CS number of the SPI device are **0**.
After obtaining the SPI device handle, obtain the SPI device configuration parameters by calling the following function:
After obtaining the SPI device handle, you need to configure the device attributes. Before configuring the device attributes, you can call **SpiGetCfg** to obtain the device attributes.
<tdclass="cellrowborder"valign="top"width="50%"><pid="p20191192925212"><aname="p20191192925212"></a><aname="p20191192925212"></a>Failed to set SPI device configuration parameters.</p>
</td>
</tr>
</tbody>
</table>
```
```
int32_t ret;
int32_t ret;
struct SpiCfg cfg = {0}; /* SPI configuration information */
struct SpiCfg cfg = {0}; /* SPI configuration. */
cfg.mode = SPI_MODE_LOOP; /* Communication in loopback mode */
cfg.mode = SPI_MODE_LOOP; /* Communicate in loop mode. */
cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* Communication in polling mode */
cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* Communicate in polling mode. */
cfg.maxSpeedHz = 115200; /* Maximum transmission frequency */
cfg.maxSpeedHz = 115200; /* Maximum transfer frequency. */
cfg.bitsPerWord = 8; /* The width of per word to be read or written is 8 bits. */
cfg.bitsPerWord = 8; /* The width of per word to be read or written is 8 bits. */
ret = SpiSetCfg(spiHandle, &cfg); /* Set SPI device configuration parameters. */
ret = SpiSetCfg(spiHandle, &cfg); /* Set SPI device attributes. */
<tdclass="cellrowborder"valign="top"width="50%"><pid="p16905313854"><aname="p16905313854"></a><aname="p16905313854"></a>Length of the data to write.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p1231981611712"><aname="p1231981611712"></a><aname="p1231981611712"></a>Succeeded in writing data into an SPI device.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p93191161174"><aname="p93191161174"></a><aname="p93191161174"></a>Failed to write data into an SPI device.</p>
</td>
</tr>
</tbody>
</table>
```
### Performing SPI Communication
int32_t ret;
uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78};
- Write data to an SPI device
/* Write data of a specific length into an SPI device. */
ret = SpiWrite(spiHandle, wbuff, 4);
Call **SpiWrite()** to write data to an SPI device only once.
<tdclass="cellrowborder"valign="top"width="50%"><pid="p98131811126"><aname="p98131811126"></a><aname="p98131811126"></a>Pointer to the data to read.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p169718191220"><aname="p169718191220"></a><aname="p169718191220"></a>Length of the data to read.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p88118101211"><aname="p88118101211"></a><aname="p88118101211"></a>Succeeded in reading data from an SPI device.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p986183127"><aname="p986183127"></a><aname="p986183127"></a>Failed to read data from an SPI device.</p>
</td>
</tr>
</tbody>
</table>
```
Call **SpiRead()** to read data from an SPI device only once.
int32_t ret;
uint8_t rbuff[4] = {0};
/* Read data of a specific length from an SPI device. */
<tdclass="cellrowborder"valign="top"width="50%"><pid="p202951238218"><aname="p202951238218"></a><aname="p202951238218"></a>Pointer to the message array to be transferred.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p259124622119"><aname="p259124622119"></a><aname="p259124622119"></a>Number of messages in the message array.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p829512237217"><aname="p829512237217"></a><aname="p829512237217"></a>Succeeded in launching the custom transfer.</p>
<tdclass="cellrowborder"valign="top"width="50%"><pid="p1295192312112"><aname="p1295192312112"></a><aname="p1295192312112"></a>Failed to launch the custom transfer.</p>
</td>
</tr>
</tbody>
</table>
```
Call **SpiTransfer()** to perform a custom transfer.
int32_t ret;
uint8_t wbuff[1] = {0x12};
uint8_t rbuff[1] = {0};
```
struct SpiMsg msg; /* Custom message to be transferred */
The following example shows how to obtain an SPI device handle, set the configuration parameters, and then read or write data from or into the SPI device, and finally destroy the SPI device handle.
## Example
The following example shows how to obtain an SPI device handle, set device attributes, and then read or write data from or into the SPI device, and finally close the SPI device handle.
```
```
#include "hdf_log.h"
#include "hdf_log.h"
...
@@ -488,61 +306,61 @@ The following example shows how to obtain an SPI device handle, set the configur
...
@@ -488,61 +306,61 @@ The following example shows how to obtain an SPI device handle, set the configur
void SpiTestSample(void)
void SpiTestSample(void)
{
{
int32_t ret;
int32_t ret;
struct SpiCfg cfg; /* SPI device configuration information */