Q群:
电话:
邮箱:
地址:
以正点原子探索者STM32F407为例,用SPI接口操作板载flash W25Q128。
-*- Using SPI Bus/Device device drivers
[ ] Enable QSPI mode
[ ] SPI MSD
-*- Using Serial Flash Universal Driver
[*] Using auto probe flash JEDEC SFDP parameter
[*] Using defined supported flash chip information table
[ ] Show more SFUD debug information
[*] Using SPI mode support --->
[ ] Using QSPI mode support ----
[*] Extern flash sfud port cfg --->
[*] Using W25QXX NorFlash
[ ] Using enc28j60 spi net module ----
[ ] Enable SDCARD (SPI) ----
[ ] Enable NRF24L01
(spi1) spi flash bus name
(30) spi flash cs pin
(W25Q128) Extern flash dev name
(spi10) Extern flash bus name
((nor_flash) Extern flash name
(16777216) Extern flash size
(4096) Extern flash block size
(4096) Extern flash page size
保存当前配置,在上一步打开的 OneOS-Cube 工具命令行输入 scons --ide=mdk5 构建工程;
接口 | 说明 |
---|---|
os_spi_bus_attach_device() | 挂载 SPI 设备 |
os_spi_configure() | 配置 SPI 设备 |
os_qspi_configure() | 配置 QSPI 设备 |
os_device_find() | 根据 SPI 设备名称查找设备 |
os_spi_transfer_message() | 自定义传输数据 |
os_spi_transfer() | 传输一次数据 |
os_spi_send() | 发送一次数据 |
os_spi_recv() | 接收一次数据 |
os_spi_send_then_send() | 连续两次发送 |
os_spi_send_then_recv() | 先发送后接收 |
os_qspi_transfer_message() | 传输数据(qspi) |
os_qspi_send_then_recv() | 先发送后接收(qspi) |
os_qspi_send() | 发送一次数据(qspi) |
os_spi_take_bus() | 获取总线 |
os_spi_take() | 选中片选 |
os_spi_message_append() | 增加一条消息 |
os_spi_release() | 释放片选 |
os_spi_release_bus() | 释放总线 |
该函数用于挂载 SPI 设备到已注册的 SPI 总线上,函数原型如下:
os_err_t os_spi_bus_attach_device(struct os_spi_device *device,
const char *name,
const char *bus_name,
void *user_data);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
name | SPI 设备名称 |
bus_name | SPI 总线名称 |
user_data | 用户数据指针 |
返回 | 说明 |
OS_EOK | 成功 |
其他错误码 | 失败 |
该函数用于配置 SPI 设备的传输参数,函数原型如下:
os_err_t os_spi_configure(struct os_spi_device *device, struct os_spi_configuration *cfg);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
cfg | SPI 配置参数指针 |
返回 | 说明 |
OS_EOK | 成功 |
该函数用于配置 QSPI 设备的传输参数,函数原型如下:
os_err_t os_qspi_configure(struct os_qspi_device *device, struct os_qspi_configuration *cfg);
参数 | 说明 |
---|---|
device | QSPI 设备指针 |
cfg | QSPI 配置参数指针 |
返回 | 说明 |
OS_EOK | 成功 |
该函数用于根据 SPI 设备名称查找设备,函数原型如下:
os_device_t *os_device_find(const char *name);
参数 | 说明 |
---|---|
name | 设备名称 |
返回 | 说明 |
设备指针 | 查找到对应设备将返回相应的设备指针 |
OS_NULL | 没有找到相应的设备对象 |
该函数用于 SPI 数据收发,函数原型如下:
struct os_spi_message *os_spi_transfer_message(struct os_spi_device *device, struct os_spi_message *message);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
message | 消息指针 |
返回 | 说明 |
OS_NULL | 传入的message为空 |
非空指针 | 发送成功,返回指向剩余未发送的 message 的指针 |
该函数用于传输一次 SPI 数据,函数原型如下:
os_size_t os_spi_transfer(struct os_spi_device *device, const void *send_buf, void *recv_buf, os_size_t length);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
send_buf | 发送数据缓冲区指针 |
recv_buf | 接收数据缓冲区指针 |
length | 发送/接收 数据字节数 |
返回 | 说明 |
0 | 传输失败 |
非 0 值 | 成功传输的字节数 |
该函数用于发送一次 SPI 数据,忽略接收到的数据,函数原型如下:
OS_INLINE os_size_t os_spi_send(struct os_spi_device *device, const void *send_buf, os_size_t length);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
send_buf | 发送数据缓冲区指针 |
length | 发送数据字节数 |
返回 | 说明 |
0 | 发送失败 |
非 0 值 | 成功发送的字节数 |
该函数用于接收一次 SPI 数据,函数原型如下:
OS_INLINE os_size_t os_spi_recv(struct os_spi_device *device, void *recv_buf, os_size_t length);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
recv_buf | 接收数据缓冲区指针 |
length | 接收数据字节数 |
返回 | 说明 |
0 | 接收失败 |
非 0 值 | 成功接收的字节数 |
该函数用于连续发送 2 个缓冲区的数据,并且中间片选不释放,函数原型如下:
os_err_t os_spi_send_then_send(struct os_spi_device *device,
const void *send_buf1,
os_size_t send_length1,
const void *send_buf2,
os_size_t send_length2);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
send_buf1 | 发送数据缓冲区 1 指针 |
send_length1 | 发送数据缓冲区 1 数据字节数 |
send_buf2 | 发送数据缓冲区 2 指针 |
send_length2 | 发送数据缓冲区 2 数据字节数 |
返回 | 说明 |
OS_EOK | 发送成功 |
OS_EIO | 发送失败 |
该函数用于先发送数据,然后接收从设备发送的数据,并且中间片选不释放,函数原型如下:
os_err_t os_spi_send_then_recv(struct os_spi_device *device,
const void *send_buf,
os_size_t send_length,
void *recv_buf,
os_size_t recv_length);
参数 | 说明 |
---|---|
device | SPI 从设备指针 |
send_buf | 发送数据缓冲区指针 |
send_length | 发送数据缓冲区数据字节数 |
recv_buf | 接收数据缓冲区指针 |
recv_length | 接收数据字节数 |
返回 | 说明 |
OS_EOK | 成功 |
OS_EIO | 失败 |
该函数用于传输 QSPI 消息,函数原型如下:
os_size_t os_qspi_transfer_message(struct os_qspi_device *device, struct os_qspi_message *message);
参数 | 说明 |
---|---|
device | QSPI 设备指针 |
message | 消息指针 |
返回 | 说明 |
实际传输的数据大小 | 实际传输的数据大小 |
该函数用于 QSPI 先发送命令,然后接收从设备的消息 ,函数原型如下:
os_err_t os_qspi_send_then_recv(struct os_qspi_device *device,
const void *send_buf,
os_size_t send_length,
void *recv_buf,
os_size_t recv_length);
参数 | 说明 |
---|---|
device | QSPI 设备指针 |
send_buf | 发送数据缓冲区指针 |
send_length | 发送数据字节数 |
recv_buf | 接收数据缓冲区指针 |
recv_length | 接收数据字节数 |
返回 | 说明 |
实际传输的数据大小 | 成功 |
其他错误码 | 失败 |
send_buf 参数包含了将要发送的命令序列。
该函数用于发送 QSPI 消息序列、数据,函数原型如下:
os_err_t os_qspi_send(struct os_qspi_device *device, const void *send_buf, os_size_t length);
参数 | 说明 |
---|---|
device | QSPI 设备指针 |
send_buf | 发送数据缓冲区指针 |
length | 发送数据字节数 |
返回 | 说明 |
实际传输的数据大小 | 成功 |
其他错误码 | 失败 |
send_buf 参数包含了将要发送的命令序列和数据。
该函数用于占有 SPI 总线,函数原型如下:
os_err_t os_spi_take_bus(struct os_spi_device *device);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
返回 | 说明 |
OS_EOK | 成功 |
错误码 | 失败 |
该函数用于拉低 SPI 片选信号,函数原型如下:
os_err_t os_spi_take(struct os_spi_device *device);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
返回 | 说明 |
OS_EOK | 成功 |
错误码 | 失败 |
该函数用于往 SPI 消息链表里增加一条新的待传输消息,函数原型如下:
OS_INLINE void os_spi_message_append(struct os_spi_message *list, struct os_spi_message *message);
参数 | 说明 |
---|---|
list | 待传输的消息链表节点 |
message | 新增消息指针 |
该函数用于释放 SPI 片选信号,函数原型如下:
os_err_t os_spi_release(struct os_spi_device *device);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
返回 | 说明 |
传输数据长度 | 成功 |
0或错误码 | 失败 |
该函数用于释放总线,函数原型如下:
os_err_t os_spi_release_bus(struct os_spi_device *device);
参数 | 说明 |
---|---|
device | SPI 设备指针 |
返回 | 说明 |
OS_EOK | 成功 |
本例程演示通过SPI设备读取w25q的ID数据:
#include <os_task.h>
#include <drv_cfg.h>
#include <shell.h>
#include <string.h>
#define W25Q_SPI_DEVICE_NAME "qspi10"
static int spi_w25q_test(int argc, char *argv[])
{
struct os_qspi_device *spi_dev_w25q;
char name[OS_NAME_MAX];
os_uint8_t w25x_read_id = 0x90;
os_uint8_t id[5] = {0};
if (argc == 2)
{
strncpy(name, argv[1], OS_NAME_MAX);
}
else
{
strncpy(name, W25Q_SPI_DEVICE_NAME, OS_NAME_MAX);
}
/* find spi device */
spi_dev_w25q = (struct os_qspi_device *)os_device_find(name);
if (!spi_dev_w25q)
{
os_kprintf("spi sample run failed! can't find %s device!\n", name);
}
else
{
/* read flash ID */
os_qspi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
os_kprintf("read w25q ID is:%x%x\n", id[3], id[4]);
}
return 0;
}
SH_CMD_EXPORT(spi_w25q_test, spi_w25q_test, "spi w25q sample");
运行结果如下:
sh>spi_w25q_test qspi10
read w25q ID is:ef17