1e41f4b71Sopenharmony_ci# SPI 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci## Overview 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ciSerial 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. 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ciSPI works in controller/device mode. Generally, there is one SPI controller that controls one or more SPI devices. They are connected via four wires: 9e41f4b71Sopenharmony_ci - SCLK: clock signal output from the SPI controller 10e41f4b71Sopenharmony_ci - MOSI: data output from the SPI controller to a device 11e41f4b71Sopenharmony_ci - MISO: data output from an SPI device to the controller 12e41f4b71Sopenharmony_ci - Chip select (CS): output from the SPI controller to indicate that data is being sent. It is controlled by the SPI controller. 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ciThe 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. 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci **Figure 1** Connection between the SPI controller and devices 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci  19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci- SPI communication is usually initiated by the controller and is performed as follows: 21e41f4b71Sopenharmony_ci 1. The SPI controller selects a device to communicate on the select line. Only one device can be selected at a time. 22e41f4b71Sopenharmony_ci 2. SCLK provides clock signals to the selected device. 23e41f4b71Sopenharmony_ci 3. The SPI controller sends data to the device via MOSI, and receives data from the devices via MISO. 24e41f4b71Sopenharmony_ci 25e41f4b71Sopenharmony_ci- SPI can work in one of the following modes according to the combination of Clock Polarity (CPOL) and Clock Phase (CPHA) of the clock signal: 26e41f4b71Sopenharmony_ci - If both CPOL and CPHA are **0**, the clock signal level is low in the idle state and data is sampled on the first clock edge. 27e41f4b71Sopenharmony_ci - If CPOL is **0** and CPHA is **1**, the clock signal level is low in the idle state and data is sampled on the second clock edge. 28e41f4b71Sopenharmony_ci - If CPOL is **1** and CPHA is **0**, the clock signal level is high in the idle state and data is sampled on the first clock edge. 29e41f4b71Sopenharmony_ci - If both CPOL and CPHA are **1**, the clock signal level is high in the idle state and data is sampled on the second clock edge. 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci- SPI defines a set of common functions for operating an SPI device, including those for: 32e41f4b71Sopenharmony_ci - Obtaining and releasing an SPI device handle. 33e41f4b71Sopenharmony_ci - Reading or writing data of the specified length from or into an SPI device. 34e41f4b71Sopenharmony_ci - Customizing data reading or writing via **SpiMsg**. 35e41f4b71Sopenharmony_ci - Obtaining and setting SPI device attributes. 36e41f4b71Sopenharmony_ci 37e41f4b71Sopenharmony_ci>  **NOTE**<br> 38e41f4b71Sopenharmony_ci> Currently, these functions are only applicable in the communication initiated by the SPI controller. 39e41f4b71Sopenharmony_ci 40e41f4b71Sopenharmony_ci 41e41f4b71Sopenharmony_ci## Available APIs 42e41f4b71Sopenharmony_ci 43e41f4b71Sopenharmony_ci **Table 1** SPI driver APIs 44e41f4b71Sopenharmony_ci 45e41f4b71Sopenharmony_ci| API| Description| 46e41f4b71Sopenharmony_ci| -------- | -------- | 47e41f4b71Sopenharmony_ci| SpiOpen | Opens an SPI device handle.| 48e41f4b71Sopenharmony_ci| SpiClose | Closes an SPI device handle.| 49e41f4b71Sopenharmony_ci| SpiRead | Reads data of the specified length from a device.| 50e41f4b71Sopenharmony_ci| SpiWrite | Writes data of the specified length to a device.| 51e41f4b71Sopenharmony_ci| SpiTransfer | Transfers SPI data.| 52e41f4b71Sopenharmony_ci| SpiSetCfg | Sets SPI device attributes.| 53e41f4b71Sopenharmony_ci| SpiGetCfg | Obtains SPI device attributes.| 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci>  **NOTE**<br> 56e41f4b71Sopenharmony_ci> All APIs described in this document can be called only in kernel mode. 57e41f4b71Sopenharmony_ci 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci## Usage Guidelines 60e41f4b71Sopenharmony_ci 61e41f4b71Sopenharmony_ci 62e41f4b71Sopenharmony_ci### How to Use 63e41f4b71Sopenharmony_ci 64e41f4b71Sopenharmony_ciThe figure below shows the general process of using SPI. 65e41f4b71Sopenharmony_ci 66e41f4b71Sopenharmony_ci **Figure 2** Process of using SPI APIs 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ci  69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci 71e41f4b71Sopenharmony_ci### Opening an SPI Device Handle 72e41f4b71Sopenharmony_ci 73e41f4b71Sopenharmony_ciBefore 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. 74e41f4b71Sopenharmony_ci 75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ci``` 77e41f4b71Sopenharmony_ciDevHandle SpiOpen(const struct SpiDevInfo *info); 78e41f4b71Sopenharmony_ci``` 79e41f4b71Sopenharmony_ci 80e41f4b71Sopenharmony_ci **Table 2** Description of SpiOpen 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci| **Parameter**| **Description**| 83e41f4b71Sopenharmony_ci| -------- | -------- | 84e41f4b71Sopenharmony_ci| info | Pointer to the SPI device descriptor.| 85e41f4b71Sopenharmony_ci| **Return Value**| **Description**| 86e41f4b71Sopenharmony_ci| NULL | The operation failed.| 87e41f4b71Sopenharmony_ci| Device handle| The operation is successful. The SPI device handle obtained is returned.| 88e41f4b71Sopenharmony_ci 89e41f4b71Sopenharmony_ciFor example, open the handle of the SPI device, whose bus number and the CS number are both **0**. 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci``` 93e41f4b71Sopenharmony_cistruct SpiDevInfo spiDevinfo; /* SPI device descriptor. */ 94e41f4b71Sopenharmony_ciDevHandle spiHandle = NULL; /* SPI device handle */ 95e41f4b71Sopenharmony_cispiDevinfo.busNum = 0; /* SPI device bus number. */ 96e41f4b71Sopenharmony_cispiDevinfo.csNum = 0; /* SPI device CS number. */ 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci/* Obtain the SPI device handle. */ 99e41f4b71Sopenharmony_cispiHandle = SpiOpen(&spiDevinfo); 100e41f4b71Sopenharmony_ciif (spiHandle == NULL) { 101e41f4b71Sopenharmony_ci HDF_LOGE("SpiOpen: failed\n"); 102e41f4b71Sopenharmony_ci return; 103e41f4b71Sopenharmony_ci} 104e41f4b71Sopenharmony_ci``` 105e41f4b71Sopenharmony_ci 106e41f4b71Sopenharmony_ci 107e41f4b71Sopenharmony_ci### Obtaining SPI Device Attributes 108e41f4b71Sopenharmony_ci 109e41f4b71Sopenharmony_ciAfter 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. 110e41f4b71Sopenharmony_ci 111e41f4b71Sopenharmony_ci 112e41f4b71Sopenharmony_ci``` 113e41f4b71Sopenharmony_ciint32_t SpiGetCfg(DevHandle handle, struct SpiCfg *cfg); 114e41f4b71Sopenharmony_ci``` 115e41f4b71Sopenharmony_ci 116e41f4b71Sopenharmony_ci **Table 3** Description of SpiGetCfg 117e41f4b71Sopenharmony_ci 118e41f4b71Sopenharmony_ci| **Parameter**| **Description**| 119e41f4b71Sopenharmony_ci| -------- | -------- | 120e41f4b71Sopenharmony_ci| handle | SPI device handle.| 121e41f4b71Sopenharmony_ci| cfg | Pointer to the SPI device attributes.| 122e41f4b71Sopenharmony_ci| **Return Value**| **Description**| 123e41f4b71Sopenharmony_ci| 0 | The operation is successful.| 124e41f4b71Sopenharmony_ci| Negative value | The operation failed.| 125e41f4b71Sopenharmony_ci 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci``` 128e41f4b71Sopenharmony_ciint32_t ret; 129e41f4b71Sopenharmony_cistruct SpiCfg cfg = {0}; /* SPI configuration. */ 130e41f4b71Sopenharmony_ciret = SpiGetCfg(spiHandle, &cfg); /* Obtain SPI device attributes. */ 131e41f4b71Sopenharmony_ciif (ret != 0) { 132e41f4b71Sopenharmony_ci HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); 133e41f4b71Sopenharmony_ci} 134e41f4b71Sopenharmony_ci``` 135e41f4b71Sopenharmony_ci 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci### Setting SPI Device Attributes 138e41f4b71Sopenharmony_ci 139e41f4b71Sopenharmony_ciAfter obtaining the SPI device handle, call **SpiSetCfg** to set SPI device attributes. 140e41f4b71Sopenharmony_ci 141e41f4b71Sopenharmony_ci 142e41f4b71Sopenharmony_ci``` 143e41f4b71Sopenharmony_ciint32_t SpiSetCfg(DevHandle handle, struct SpiCfg *cfg); 144e41f4b71Sopenharmony_ci``` 145e41f4b71Sopenharmony_ci 146e41f4b71Sopenharmony_ci **Table 4** Description of SpiSetCfg 147e41f4b71Sopenharmony_ci 148e41f4b71Sopenharmony_ci| **Parameter**| **Description**| 149e41f4b71Sopenharmony_ci| -------- | -------- | 150e41f4b71Sopenharmony_ci| handle | SPI device handle.| 151e41f4b71Sopenharmony_ci| cfg | Pointer to the SPI device attributes.| 152e41f4b71Sopenharmony_ci| **Return Value**| **Description**| 153e41f4b71Sopenharmony_ci| 0 | The operation is successful.| 154e41f4b71Sopenharmony_ci| Negative value | The operation failed.| 155e41f4b71Sopenharmony_ci 156e41f4b71Sopenharmony_ci 157e41f4b71Sopenharmony_ci``` 158e41f4b71Sopenharmony_ciint32_t ret; 159e41f4b71Sopenharmony_cistruct SpiCfg cfg = {0}; /* SPI configuration. */ 160e41f4b71Sopenharmony_cicfg.mode = SPI_MODE_LOOP; /* Communicate in loop mode. */ 161e41f4b71Sopenharmony_cicfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* Communicate in polling mode. */ 162e41f4b71Sopenharmony_cicfg.maxSpeedHz = 115200; /* Maximum transfer frequency. */ 163e41f4b71Sopenharmony_cicfg.bitsPerWord = 8; /* The width of per word to be read or written is 8 bits. */ 164e41f4b71Sopenharmony_ciret = SpiSetCfg(spiHandle, &cfg); /* Set SPI device attributes. */ 165e41f4b71Sopenharmony_ciif (ret != 0) { 166e41f4b71Sopenharmony_ci HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); 167e41f4b71Sopenharmony_ci} 168e41f4b71Sopenharmony_ci``` 169e41f4b71Sopenharmony_ci 170e41f4b71Sopenharmony_ci 171e41f4b71Sopenharmony_ci### Performing SPI Communication 172e41f4b71Sopenharmony_ci 173e41f4b71Sopenharmony_ci- Write data to an SPI device 174e41f4b71Sopenharmony_ci 175e41f4b71Sopenharmony_ci Call **SpiWrite()** to write data to an SPI device only once. 176e41f4b71Sopenharmony_ci 177e41f4b71Sopenharmony_ci 178e41f4b71Sopenharmony_ci ``` 179e41f4b71Sopenharmony_ci int32_t SpiWrite(DevHandle handle, uint8_t *buf, uint32_t len); 180e41f4b71Sopenharmony_ci ``` 181e41f4b71Sopenharmony_ci 182e41f4b71Sopenharmony_ci **Table 5** Description of SpiWrite 183e41f4b71Sopenharmony_ci 184e41f4b71Sopenharmony_ci| **Parameter**| **Description**| 185e41f4b71Sopenharmony_ci| -------- | -------- | 186e41f4b71Sopenharmony_ci| handle | SPI device handle.| 187e41f4b71Sopenharmony_ci| buf | Pointer to the data to write.| 188e41f4b71Sopenharmony_ci| len | Length of the data to write.| 189e41f4b71Sopenharmony_ci| **Return Value**| **Description**| 190e41f4b71Sopenharmony_ci| 0 | The operation is successful.| 191e41f4b71Sopenharmony_ci| Negative value | The operation failed.| 192e41f4b71Sopenharmony_ci 193e41f4b71Sopenharmony_ci 194e41f4b71Sopenharmony_ci ``` 195e41f4b71Sopenharmony_ci int32_t ret; 196e41f4b71Sopenharmony_ci uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78}; 197e41f4b71Sopenharmony_ci /* Write data of the specified length to an SPI device. */ 198e41f4b71Sopenharmony_ci ret = SpiWrite(spiHandle, wbuff, 4); 199e41f4b71Sopenharmony_ci if (ret != 0) { 200e41f4b71Sopenharmony_ci HDF_LOGE("SpiWrite: failed, ret %d\n", ret); 201e41f4b71Sopenharmony_ci } 202e41f4b71Sopenharmony_ci ``` 203e41f4b71Sopenharmony_ci 204e41f4b71Sopenharmony_ci- Read data from an SPI device 205e41f4b71Sopenharmony_ci 206e41f4b71Sopenharmony_ci Call **SpiRead()** to read data from an SPI device only once. 207e41f4b71Sopenharmony_ci 208e41f4b71Sopenharmony_ci 209e41f4b71Sopenharmony_ci ``` 210e41f4b71Sopenharmony_ci int32_t SpiRead(DevHandle handle, uint8_t *buf, uint32_t len); 211e41f4b71Sopenharmony_ci ``` 212e41f4b71Sopenharmony_ci 213e41f4b71Sopenharmony_ci **Table 6** Description of SpiRead 214e41f4b71Sopenharmony_ci 215e41f4b71Sopenharmony_ci| **Parameter**| **Description**| 216e41f4b71Sopenharmony_ci| -------- | -------- | 217e41f4b71Sopenharmony_ci| handle | SPI device handle.| 218e41f4b71Sopenharmony_ci| buf | Pointer to the data to read.| 219e41f4b71Sopenharmony_ci| len | Length of the data to read.| 220e41f4b71Sopenharmony_ci| **Return Value**| **Description**| 221e41f4b71Sopenharmony_ci| 0 | The operation is successful.| 222e41f4b71Sopenharmony_ci| Negative value| The operation failed.| 223e41f4b71Sopenharmony_ci 224e41f4b71Sopenharmony_ci 225e41f4b71Sopenharmony_ci ``` 226e41f4b71Sopenharmony_ci int32_t ret; 227e41f4b71Sopenharmony_ci uint8_t rbuff[4] = {0}; 228e41f4b71Sopenharmony_ci /* Read data of the specified length from an SPI device. */ 229e41f4b71Sopenharmony_ci ret = SpiRead(spiHandle, rbuff, 4); 230e41f4b71Sopenharmony_ci if (ret != 0) { 231e41f4b71Sopenharmony_ci HDF_LOGE("SpiRead: failed, ret %d\n", ret); 232e41f4b71Sopenharmony_ci } 233e41f4b71Sopenharmony_ci ``` 234e41f4b71Sopenharmony_ci 235e41f4b71Sopenharmony_ci- Perform a custom transfer 236e41f4b71Sopenharmony_ci 237e41f4b71Sopenharmony_ci Call **SpiTransfer()** to perform a custom transfer. 238e41f4b71Sopenharmony_ci 239e41f4b71Sopenharmony_ci 240e41f4b71Sopenharmony_ci ``` 241e41f4b71Sopenharmony_ci int32_t SpiTransfer(DevHandle handle, struct SpiMsg *msgs, uint32_t count); 242e41f4b71Sopenharmony_ci ``` 243e41f4b71Sopenharmony_ci 244e41f4b71Sopenharmony_ci **Table 7** Description of SpiTransfer 245e41f4b71Sopenharmony_ci 246e41f4b71Sopenharmony_ci| **Parameter**| **Description**| 247e41f4b71Sopenharmony_ci| -------- | -------- | 248e41f4b71Sopenharmony_ci| handle | SPI device handle.| 249e41f4b71Sopenharmony_ci| msgs | Pointer to the message array to be transferred.| 250e41f4b71Sopenharmony_ci| count | Number of messages in the message array.| 251e41f4b71Sopenharmony_ci| **Return Value**| **Description**| 252e41f4b71Sopenharmony_ci| 0 | The operation is successful.| 253e41f4b71Sopenharmony_ci| Negative value| The operation failed.| 254e41f4b71Sopenharmony_ci 255e41f4b71Sopenharmony_ci 256e41f4b71Sopenharmony_ci ``` 257e41f4b71Sopenharmony_ci int32_t ret; 258e41f4b71Sopenharmony_ci uint8_t wbuff[1] = {0x12}; 259e41f4b71Sopenharmony_ci uint8_t rbuff[1] = {0}; 260e41f4b71Sopenharmony_ci struct SpiMsg msg; /* Custom message to be transferred. */ 261e41f4b71Sopenharmony_ci msg.wbuf = wbuff; /* Data to write. */ 262e41f4b71Sopenharmony_ci msg.rbuf = rbuff; /* Data to read. */ 263e41f4b71Sopenharmony_ci msg.len = 1; /* The length of the data to read or write is 1 bit. */ 264e41f4b71Sopenharmony_ci msg.csChange = 1; /* Close the CS before the next transfer. */ 265e41f4b71Sopenharmony_ci msg.delayUs = 0; /* No delay before the next transfer. */ 266e41f4b71Sopenharmony_ci msg.speed = 115200; /* Transfer speed. */ 267e41f4b71Sopenharmony_ci /* Perform a custom transfer. The number of messages to be transferred is 1. */ 268e41f4b71Sopenharmony_ci ret = SpiTransfer(spiHandle, &msg, 1); 269e41f4b71Sopenharmony_ci if (ret != 0) { 270e41f4b71Sopenharmony_ci HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); 271e41f4b71Sopenharmony_ci } 272e41f4b71Sopenharmony_ci ``` 273e41f4b71Sopenharmony_ci 274e41f4b71Sopenharmony_ci 275e41f4b71Sopenharmony_ci### Closing an SPI Device Handle 276e41f4b71Sopenharmony_ci 277e41f4b71Sopenharmony_ciAfter the SPI communication, call **SpiClose()** to close the SPI device handle. 278e41f4b71Sopenharmony_ci 279e41f4b71Sopenharmony_ci 280e41f4b71Sopenharmony_ci``` 281e41f4b71Sopenharmony_civoid SpiClose(DevHandle handle); 282e41f4b71Sopenharmony_ci``` 283e41f4b71Sopenharmony_ci 284e41f4b71Sopenharmony_ciThis function releases the resources requested by **MipiDsiOpen**. 285e41f4b71Sopenharmony_ci 286e41f4b71Sopenharmony_ci **Table 8** Description of SpiClose 287e41f4b71Sopenharmony_ci 288e41f4b71Sopenharmony_ci| **Parameter**| **Description**| 289e41f4b71Sopenharmony_ci| -------- | -------- | 290e41f4b71Sopenharmony_ci| handle | SPI device handle.| 291e41f4b71Sopenharmony_ci 292e41f4b71Sopenharmony_ci 293e41f4b71Sopenharmony_ci``` 294e41f4b71Sopenharmony_ciSpiClose(spiHandle); /* Close the SPI device handle. */ 295e41f4b71Sopenharmony_ci``` 296e41f4b71Sopenharmony_ci 297e41f4b71Sopenharmony_ci 298e41f4b71Sopenharmony_ci## Example 299e41f4b71Sopenharmony_ci 300e41f4b71Sopenharmony_ciThe 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. 301e41f4b71Sopenharmony_ci 302e41f4b71Sopenharmony_ci``` 303e41f4b71Sopenharmony_ci#include "hdf_log.h" 304e41f4b71Sopenharmony_ci#include "spi_if.h" 305e41f4b71Sopenharmony_ci 306e41f4b71Sopenharmony_civoid SpiTestSample(void) 307e41f4b71Sopenharmony_ci{ 308e41f4b71Sopenharmony_ci int32_t ret; 309e41f4b71Sopenharmony_ci struct SpiCfg cfg; /* SPI device configuration. */ 310e41f4b71Sopenharmony_ci struct SpiDevInfo spiDevinfo; /* SPI device descriptor. */ 311e41f4b71Sopenharmony_ci DevHandle spiHandle = NULL; /* SPI device handle. */ 312e41f4b71Sopenharmony_ci struct SpiMsg msg; /* Custom message to be transferred. */ 313e41f4b71Sopenharmony_ci uint8_t rbuff[4] = { 0 }; 314e41f4b71Sopenharmony_ci uint8_t wbuff[4] = { 0x12, 0x34, 0x56, 0x78 }; 315e41f4b71Sopenharmony_ci uint8_t wbuff2[4] = { 0xa1, 0xb2, 0xc3, 0xd4 }; 316e41f4b71Sopenharmony_ci 317e41f4b71Sopenharmony_ci spiDevinfo.busNum = 0; /* SPI device bus number. */ 318e41f4b71Sopenharmony_ci spiDevinfo.csNum = 0; /* SPI device CS number. */ 319e41f4b71Sopenharmony_ci spiHandle = SpiOpen(&spiDevinfo); /* Open the SPI device handle based on spiDevinfo. */ 320e41f4b71Sopenharmony_ci if (spiHandle == NULL) { 321e41f4b71Sopenharmony_ci HDF_LOGE("SpiOpen: failed\n"); 322e41f4b71Sopenharmony_ci return; 323e41f4b71Sopenharmony_ci } 324e41f4b71Sopenharmony_ci /* Obtain SPI attributes. */ 325e41f4b71Sopenharmony_ci ret = SpiGetCfg(spiHandle, &cfg); 326e41f4b71Sopenharmony_ci if (ret != 0) { 327e41f4b71Sopenharmony_ci HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret); 328e41f4b71Sopenharmony_ci goto err; 329e41f4b71Sopenharmony_ci } 330e41f4b71Sopenharmony_ci cfg.maxSpeedHz = 115200; /* Set the maximum clock frequency to 115200. */ 331e41f4b71Sopenharmony_ci cfg.bitsPerWord = 8; /* Set the word width to 8 bits. */ 332e41f4b71Sopenharmony_ci /* Set SPI attributes. */ 333e41f4b71Sopenharmony_ci ret = SpiSetCfg(spiHandle, &cfg); 334e41f4b71Sopenharmony_ci if (ret != 0) { 335e41f4b71Sopenharmony_ci HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret); 336e41f4b71Sopenharmony_ci goto err; 337e41f4b71Sopenharmony_ci } 338e41f4b71Sopenharmony_ci /* Write data of the specified length to an SPI device. */ 339e41f4b71Sopenharmony_ci ret = SpiWrite(spiHandle, wbuff, 4); 340e41f4b71Sopenharmony_ci if (ret != 0) { 341e41f4b71Sopenharmony_ci HDF_LOGE("SpiWrite: failed, ret %d\n", ret); 342e41f4b71Sopenharmony_ci goto err; 343e41f4b71Sopenharmony_ci } 344e41f4b71Sopenharmony_ci /* Read data of the specified length from an SPI device. */ 345e41f4b71Sopenharmony_ci ret = SpiRead(spiHandle, rbuff, 4); 346e41f4b71Sopenharmony_ci if (ret != 0) { 347e41f4b71Sopenharmony_ci HDF_LOGE("SpiRead: failed, ret %d\n", ret); 348e41f4b71Sopenharmony_ci goto err; 349e41f4b71Sopenharmony_ci } 350e41f4b71Sopenharmony_ci msg.wbuf = wbuff2; /* Data to write. */ 351e41f4b71Sopenharmony_ci msg.rbuf = rbuff; /* Data to read. */ 352e41f4b71Sopenharmony_ci msg.len = 4; /* Set the length of the data to read or write to 4 bits. */ 353e41f4b71Sopenharmony_ci msg.csChange = 1; /* Close the CS before the next transfer. */ 354e41f4b71Sopenharmony_ci msg.delayUs = 0; /* No delay before the next transfer. */ 355e41f4b71Sopenharmony_ci msg.speed = 115200; /* Transfer speed. */ 356e41f4b71Sopenharmony_ci /* Perform a custom transfer. The number of messages to be transferred is 1. */ 357e41f4b71Sopenharmony_ci ret = SpiTransfer(spiHandle, &msg, 1); 358e41f4b71Sopenharmony_ci if (ret != 0) { 359e41f4b71Sopenharmony_ci HDF_LOGE("SpiTransfer: failed, ret %d\n", ret); 360e41f4b71Sopenharmony_ci goto err; 361e41f4b71Sopenharmony_ci } 362e41f4b71Sopenharmony_cierr: 363e41f4b71Sopenharmony_ci /* Close the SPI device handle. */ 364e41f4b71Sopenharmony_ci SpiClose(spiHandle); 365e41f4b71Sopenharmony_ci} 366e41f4b71Sopenharmony_ci``` 367