SPI

优质
小牛编辑
131浏览
2023-12-01

SPI设备接口

结构体

struct  rt_spi_message
 SPI消息 更多...
 
struct  rt_spi_configuration
 SPI从设备的配置参数 更多...
 
struct  rt_spi_bus
 SPI总线控制块 更多...
 
struct  rt_spi_ops
 SPI总线的操作方法 更多...
 
struct  rt_spi_device
 SPI从设备 更多...
 

宏定义

#define RT_SPI_CPHA   (1<<0)
 bit[0]:CPHA, 时钟极性
 
#define RT_SPI_CPOL   (1<<1)
 bit[1]:CPOL, 时钟相位
 
#define RT_SPI_LSB   (0<<2)
 bit[2]: LSB位在前
 
#define RT_SPI_MSB   (1<<2)
 bit[2]: MSB位在前
 
#define RT_SPI_MASTER   (0<<3)
 SPI 做主设备
 
#define RT_SPI_SLAVE   (1<<3)
 SPI 做从设备
 
#define RT_SPI_MODE_0   (0 | 0)
 CPOL = 0, CPHA = 0.
 
#define RT_SPI_MODE_1   (0 | RT_SPI_CPHA)
 CPOL = 0, CPHA = 1.
 
#define RT_SPI_MODE_2   (RT_SPI_CPOL | 0)
 CPOL = 1, CPHA = 0.
 
#define RT_SPI_MODE_3   (RT_SPI_CPOL | RT_SPI_CPHA)
 CPOL = 1, CPHA = 1.
 
#define RT_SPI_CS_HIGH   (1<<4)
 片选高电平有效
 
#define RT_SPI_NO_CS   (1<<5)
 不使用片选
 
#define RT_SPI_3WIRE   (1<<6)
 MOSI和MISO共用一根数据线
 
#define RT_SPI_READY   (1<<7)
 从设备拉低暂停
 

函数

rt_err_t rt_spi_bus_register (struct rt_spi_bus *bus, const char *name, const struct rt_spi_ops *ops)
 注册SPI 总线设备
 
rt_err_t rt_spi_bus_attach_device (struct rt_spi_device *device, const char *name, const char *bus_name, void *user_data)
 挂载 SPI 从设备到SPI总线设备上
 
rt_err_t rt_spi_take_bus (struct rt_spi_device *device)
 获取 SPI 总线设备
 
rt_err_t rt_spi_release_bus (struct rt_spi_device *device)
 释放 SPI 总线设备
 
rt_err_t rt_spi_take (struct rt_spi_device *device)
 获取片选
 
rt_err_t rt_spi_release (struct rt_spi_device *device)
 释放片选
 
rt_err_t rt_spi_configure (struct rt_spi_device *device, struct rt_spi_configuration *cfg)
 SPI 从设备配置
 
rt_err_t rt_spi_send_then_recv (struct rt_spi_device *device, const void *send_buf, rt_size_t send_length, void *recv_buf, rt_size_t recv_length)
 先发送后接收数据
 
rt_err_t rt_spi_send_then_send (struct rt_spi_device *device, const void *send_buf1, rt_size_t send_length1, const void *send_buf2, rt_size_t send_length2)
 连续发送两次数据
 
rt_size_t rt_spi_transfer (struct rt_spi_device *device, const void *send_buf, void *recv_buf, rt_size_t length)
 传输一次数据
 
struct rt_spi_messagert_spi_transfer_message (struct rt_spi_device *device, struct rt_spi_message *message)
 多个消息连续传输
 
rt_inline rt_size_t rt_spi_recv (struct rt_spi_device *device, void *recv_buf, rt_size_t length)
 接收数据
 
rt_inline rt_size_t rt_spi_send (struct rt_spi_device *device, const void *send_buf, rt_size_t length)
 发送数据
 
rt_inline void rt_spi_message_append (struct rt_spi_message *list, struct rt_spi_message *message)
 增加一条消息
 

详细描述

SPI设备接口

函数说明

rt_err_t rt_spi_bus_register(struct rt_spi_busbus,
const char * name,
const struct rt_spi_opsops 
)

注册SPI 总线设备

调用此函数可以向系统中注册 SPI 总线设备。

参数
busSPI 总线设备句柄
nameSPI 总线设备名称,一般与硬件控制器名称一致,如:“spi0”
opsSPI 总线设备的操作方法,即 SPI 驱动的实现
返回
RT_EOK 成功;-RT_ERROR 注册失败,已有其他驱动使用该name注册。
rt_err_t rt_spi_bus_attach_device(struct rt_spi_devicedevice,
const char * name,
const char * bus_name,
void * user_data 
)

挂载 SPI 从设备到SPI总线设备上

此函数用于挂载一个SPI设备节点到指定的SPI总线,并内核注册SPI设备节点,并将user_data保存到SPI设备节点的user_data指针里。

参数
deviceSPI 从设备句柄
nameSPI 从设备名称,SPI从设备命名原则为spixy,如spi10表示挂载在总线spi1上的0号设备
bus_nameSPI 总线设备名称
user_data用户数据指针,一般为SPI从设备对应的CS引脚信息,进行数据传输时SPI控制器会操作此引脚进行片选
返回
RT_EOK 成功;-RT_ERROR 已有其他驱动使用name挂载或者bus_name对应的SPI总线设备不存在。
rt_err_t rt_spi_take_bus(struct rt_spi_devicedevice)

获取 SPI 总线设备

用户调用此函数来获取SPI总线设备,并设置SPI总线设备的工作模式和参数。

参数
deviceSPI 从设备句柄
返回
成功则返回RT_EOK;错误则返回错误码。
rt_err_t rt_spi_release_bus(struct rt_spi_devicedevice)

释放 SPI 总线设备

用户可以调用此函数来释放SPI总线设备。

参数
deviceSPI 从设备句柄
返回
成功则返回RT_EOK;错误则返回错误码。
rt_err_t rt_spi_take(struct rt_spi_devicedevice)

获取片选

调用此函数可以片选SPI设备。

参数
deviceSPI 从设备句柄
返回
0 获取成功,片选开始。
rt_err_t rt_spi_release(struct rt_spi_devicedevice)

释放片选

调用此函数可以释放被片选SPI设备。

参数
deviceSPI 从设备句柄
返回
0 释放成功,片选结束。
rt_err_t rt_spi_configure(struct rt_spi_devicedevice,
struct rt_spi_configurationcfg 
)

SPI 从设备配置

本函数用于配置SPI 从设备的时钟、数据宽度等要求,通常需要配置SPI模式、频率参数。

参数
deviceSPI 从设备句柄
cfgSPI 配置参数指针
返回
RT_EOK 配置成功。
rt_err_t rt_spi_send_then_recv(struct rt_spi_devicedevice,
const void * send_buf,
rt_size_t send_length,
void * recv_buf,
rt_size_t recv_length 
)

先发送后接收数据

本函数适合从SPI外设中读取一块数据,本函数中会先发送一些数据(如命令和地址),然后再接收指定长度的数据。此函数等同于调用rt_spi_transfer_message()传输2条消息。

参数
deviceSPI 从设备句柄
send_buf发送缓冲区数据指针
send_length发送缓冲区数据字节数
recv_buf接收缓冲区数据指针,spi 是全双工的,支持同时收发
recv_length接收缓冲区数据字节数
返回
RT_EOK 成功,-RT_EIO 失败。
示例:
spi_w25q_sample.c.
rt_err_t rt_spi_send_then_send(struct rt_spi_devicedevice,
const void * send_buf1,
rt_size_t send_length1,
const void * send_buf2,
rt_size_t send_length2 
)

连续发送两次数据

如果需要先后连续发送2个缓冲区的数据,并且中间片选不释放,可以调用此函数。 本函数适合向SPI从设备中写入一块数据,第一次先发送命令和地址等数据,第二次再发送指定长度的数据。

参数
deviceSPI 从设备句柄
send_buf1发送缓冲区1数据指针
send_length1发送缓冲区1数据字节数
send_buf2发送缓冲区2数据指针
send_length2发送缓冲区2数据字节数
返回
RT_EOK 成功,-RT_EIO 失败。
rt_size_t rt_spi_transfer(struct rt_spi_devicedevice,
const void * send_buf,
void * recv_buf,
rt_size_t length 
)

传输一次数据

此函数可以传输传输一次数据。此函数等同于调用rt_spi_transfer_message()传输一条消息,开始发送数据时片选选中,函数返回时释放片选。

参数
deviceSPI 从设备句柄
send_buf发送缓冲区指针
recv_buf接收缓冲区指针
length发送 / 接收 数据字节数
返回
实际传输的字节数
struct rt_spi_message* rt_spi_transfer_message(struct rt_spi_devicedevice,
struct rt_spi_messagemessage 
)

多个消息连续传输

此函数可以传输一连串消息,用户可以很灵活的设置message结构体各参数的数值,从而可以很方便的控制数据传输方式。

参数
deviceSPI 从设备句柄
message消息指针
返回
RT_NULL 消息列表发送成功,发送失败返回指向剩余未发送的消息的指针。
示例:
spi_w25q_sample.c.
rt_inline rt_size_t rt_spi_recv(struct rt_spi_devicedevice,
void * recv_buf,
rt_size_t length 
)

接收数据

调用此函数接受数据并保存到recv_buf指向的缓冲区。此函数是对rt_spi_transfer()函数的封装。 SPI协议里面只能由MASTER主动产生时钟,因此,在接收数据时,会发送dummy。

参数
deviceSPI 从设备句柄
recv_buf接收缓冲区指针
length接受数据的字节数
返回
实际接收的字节数。
rt_inline rt_size_t rt_spi_send(struct rt_spi_devicedevice,
const void * send_buf,
rt_size_t length 
)

发送数据

调用此函数发送send_buf指向的缓冲区的数据,忽略接收到的数据。 此函数是对rt_spi_transfer()函数的封装,开始发送数据时片选选中,函数返回时释放片选。

参数
deviceSPI 从设备句柄
send_buf发送缓冲区指针
length发送数据的字节数
返回
实际发送的字节数。
rt_inline void rt_spi_message_append(struct rt_spi_messagelist,
struct rt_spi_messagemessage 
)

增加一条消息

使用rt_spi_transfer_message()传输消息时, 所有待传输的消息都是以单向链表的形式连接起来的,可使用如下函数往消息链表里增加一条新的待传输消息。

参数
list消息链表指针
message消息指针