SPI使用指导

使用流程

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

图 1 SPI使用流程图

SPI使用指导 - 图1

获取SPI设备句柄

在使用SPI进行通信时,首先要调用SpiOpen获取SPI设备句柄,该函数会返回指定总线号和片选号的SPI设备句柄。

struct DevHandle *SpiOpen(const struct SpiDevInfo *info);

表 1 SpiOpen参数和返回值描述

参数

参数描述

info

SPI设备描述符

返回值

返回值描述

NULL

获取SPI设备句柄失败

设备句柄

对应的SPI设备句柄

假设系统中的SPI设备总线号为0,片选号为0,获取该SPI设备句柄的示例如下:

  1. structSpiDevInfo spiDevinfo;/* SPI设备描述符 */
  2. structDevHandle*spiHandle = NULL;/* SPI设备句柄*/
  3. spiDevinfo.busNum =0;/* SPI设备总线号 */
  4. spiDevinfo.csNum =0;/* SPI设备片选号 */
  5. /* 获取SPI设备句柄 */
  6. spiHandle =SpiOpen(&spiDevinfo);
  7. if(spiHandle == NULL){
  8. HDF_LOGE("SpiOpen: failed\n");
  9. return;
  10. }

获取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. structSpiCfg 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. structSpiCfg 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. structSpiMsg 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设备句柄 */