SPI使用指导
使用流程
使用SPI的一般流程如图1所示。
图 1 SPI使用流程图

获取SPI设备句柄
在使用SPI进行通信时,首先要调用SpiOpen获取SPI设备句柄,该函数会返回指定总线号和片选号的SPI设备句柄。
struct DevHandle *SpiOpen(const struct SpiDevInfo *info);
表 1 SpiOpen参数和返回值描述
| 参数 | 参数描述 |
| info | SPI设备描述符 |
| 返回值 | 返回值描述 |
| NULL | 获取SPI设备句柄失败 |
| 设备句柄 | 对应的SPI设备句柄 |
假设系统中的SPI设备总线号为0,片选号为0,获取该SPI设备句柄的示例如下:
1. struct SpiDevInfo spiDevinfo; /* SPI设备描述符 */
2. struct DevHandle *spiHandle = NULL; /* SPI设备句柄*/
3. spiDevinfo.busNum = 0; /* SPI设备总线号 */
4. spiDevinfo.csNum = 0; /* SPI设备片选号 */
6. /* 获取SPI设备句柄 */
7. spiHandle = SpiOpen(&spiDevinfo);
8. if (spiHandle == NULL) {
9. HDF_LOGE("SpiOpen: failed\n");
10. return;
11. }
获取SPI设备属性
在获取到SPI设备句柄之后,需要配置SPI设备属性。配置SPI设备属性之前,可以先获取SPI设备属性,获取SPI设备属性的函数如下所示:
int32_t SpiGetCfg(struct DevHandle *handle, struct SpiCfg *cfg);
表 2 SpiGetCfg参数和返回值描述
| 参数 | 参数描述 |
| handle | SPI设备句柄 |
| cfg | SPI设备配置参数 |
| 返回值 | 返回值描述 |
| 0 | 获取配置成功 |
| 负数 | 获取配置失败 |
1. int32_t ret;
2. struct SpiCfg cfg = {0}; /* SPI配置信息*/
3. ret = SpiGetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */
4. if (ret != 0) {
5. HDF_LOGE("SpiGetCfg: failed, ret %d\n", ret);
6. }
配置SPI设备属性
在获取到SPI设备句柄之后,需要配置SPI设备属性,配置SPI设备属性的函数如下所示:
int32_t SpiSetCfg(struct DevHandle *handle, struct SpiCfg *cfg);
表 3 SpiSetCfg参数和返回值描述
| 参数 | 参数描述 |
| handle | SPI设备句柄 |
| cfg | SPI设备配置参数 |
| 返回值 | 返回值描述 |
| 0 | 配置成功 |
| 负数 | 配置失败 |
1. int32_t ret;
2. struct SpiCfg cfg = {0}; /* SPI配置信息*/
3. cfg.mode = SPI_MODE_LOOP; /* 以回环模式进行通信 */
4. cfg.transferMode = PAL_SPI_POLLING_TRANSFER; /* 以轮询的方式进行通信 */
5. cfg.maxSpeedHz = 115200; /* 最大传输频率 */
6. cfg.bitsPerWord = 8; /* 读写位宽为8个比特 */
7. ret = SpiSetCfg(spiHandle, &cfg); /* 配置SPI设备属性 */
8. if (ret != 0) {
9. HDF_LOGE("SpiSetCfg: failed, ret %d\n", ret);
10. }
进行SPI通信
- 向SPI设备写入指定长度的数据
如果只向SPI设备写一次数据,则可以通过以下函数完成:
int32_t SpiWrite(struct DevHandle *handle, uint8_t *buf, uint32_t len);
表 4 SpiWrite参数和返回值描述
| 参数 | 参数描述 |
| handle | SPI设备句柄 |
| buf | 待写入数据的指针 |
| len | 待写入的数据长度 |
| 返回值 | 返回值描述 |
| 0 | 写入成功 |
| 负数 | 写入失败 |
1. int32_t ret;
2. uint8_t wbuff[4] = {0x12, 0x34, 0x56, 0x78};
3. /* 向SPI设备写入指定长度的数据 */
4. ret = SpiWrite(spiHandle, wbuff, 4);
5. if (ret != 0) {
6. HDF_LOGE("SpiWrite: failed, ret %d\n", ret);
7. }
- 从SPI设备读取指定长度的数据
如果只读取一次数据,则可以通过以下函数完成:
int32_t SpiRead(struct DevHandle *handle, uint8_t *buf, uint32_t len);
表 5 SpiRead参数和返回值描述
| 参数 | 参数描述 |
| handle | SPI设备句柄 |
| buf | 待读取数据的指针 |
| len | 待读取的数据长度 |
| 返回值 | 返回值描述 |
| 0 | 读取成功 |
| 负数 | 读取失败 |
1. int32_t ret;
2. uint8_t rbuff[4] = {0};
3. /* 从SPI设备读取指定长度的数据 */
4. ret = SpiRead(spiHandle, rbuff, 4);
5. if (ret != 0) {
6. HDF_LOGE("SpiRead: failed, ret %d\n", ret);
7. }
- 自定义传输
如果需要发起一次自定义传输,则可以通过以下函数完成:
int32_t SpiTransfer(struct DevHandle *handle, struct SpiMsg *msgs, uint32_t count);
表 6 SpiTransfer参数和返回值描述
| 参数 | 参数描述 |
| handle | SPI设备句柄 |
| msgs | 待传输数据的数组 |
| count | msgs数组长度 |
| 返回值 | 返回值描述 |
| 0 | 执行成功 |
| 负数 | 执行失败 |
1. int32_t ret;
2. uint8_t wbuff[1] = {0x12};
3. uint8_t rbuff[1] = {0};
4. struct SpiMsg msg; /* 自定义传输的消息*/
5. msg.wbuf = wbuff; /* 写入的数据 */
6. msg.rbuf = rbuff; /* 读取的数据 */
7. msg.len = 1; /* 读取、写入数据的长度都是1 */
8. msg.csChange = 1; /* 进行下一次传输前关闭片选 */
9. msg.delayUs = 0; /* 进行下一次传输前不进行延时 */
10. msg.speed = 115200; /* 本次传输的速度 */
11. /* 进行一次自定义传输,传输的msg个数为1 */
12. ret = SpiTransfer(spiHandle, &msg, 1);
13. if (ret != 0) {
14. HDF_LOGE("SpiTransfer: failed, ret %d\n", ret);
15. }
销毁SPI设备句柄
SPI通信完成之后,需要销毁SPI设备句柄,销毁SPI设备句柄的函数如下所示:
void SpiClose(struct DevHandle *handle);
该函数会释放掉申请的资源。
表 7 SpiClose参数描述
| 参数 | 参数描述 |
| handle | SPI设备句柄 |
1. SpiClose(spiHandle); /* 销毁SPI设备句柄 */
