caroline11 发表于 2021-4-25 08:19:39

RT-Thread设备框架学习之SPI设备

RT-Thread学习记录
1.Studio新建工程

2.控制台使用简述

3.PIN设备框架学习

4.UART设备框架学习

5.I2C设备框架学习

SPI设备
RT-Thread的SPI驱动目前只支持硬件SPI/QSPI模式。

首先在Components设置项下勾选SPI驱动框架,这里几个可选项分别为QSPI模式、SPI SD卡、SPI Flash、SPI以太网、SPI WiFi、这边我板载了QSPI的FLASH和SPI SD卡,所以两个都勾选了,如果设备不是以上选项可以直接跳过,如下图


然后在Samples设置项下勾选spi device例程, 保存,如下图可以看到spi的例程已添加入工程

打开例程文件,可以看到该例程的功能是通过SPI方式夺取Flash的设备ID,因为我板卡用的是qspi的Flash,所以例程不能用,需要自己重新实现。

首先我们先在board.h打开QSPI设备驱动的支持




然后在board.c文件或者其他任意源文件,添加对QSPI的引脚初始化,这边我先是在CubeMX下设置生成了代码之后拷贝过来的,具体如下图所示:


模仿之前添加进来的SPI例子简单的写一个测试例程

#include <rtthread.h>
#include <rtdevice.h>
#include "drv_qspi.h"

#define W25Q_SPI_DEVICE_NAME   "qspi10"

char w25qxx_read_status_register2(struct rt_qspi_device *device)
{
    /* 0x35 read status register2 */
    char instruction = 0x35, status;

    rt_qspi_send_then_recv(device, &instruction, 1, &status, 1);

    return status;
}

void w25qxx_write_enable(struct rt_qspi_device *device)
{
    /* 0x06 write enable */
    char instruction = 0x06;

    rt_qspi_send(device, &instruction, 1);
}

void w25qxx_enter_qspi_mode(struct rt_qspi_device *device)
{
    char status = 0;
    /* 0x38 enter qspi mode */
    char instruction = 0x38;
    char write_status2_buf = {0};

    /* 0x31 write status register2 */
    write_status2_buf = 0x31;

    status = w25qxx_read_status_register2(device);
    if (!(status & 0x02))
    {
      status |= 1 << 1;
      w25qxx_write_enable(device);
      write_status2_buf = status;
      rt_qspi_send(device, &write_status2_buf, 2);
      rt_qspi_send(device, &instruction, 1);
      rt_kprintf("flash already enter qspi mode\n");
      rt_thread_mdelay(10);
    }
}

//static void usr_spi_hw_config(struct rt_spi_device* device)
//{
//    struct rt_spi_configuration cfg;
//
//    cfg.data_width = 8;
//    cfg.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
//    cfg.max_hz = 50 * 1000 *1000;                           /* 50M */
//
//    rt_spi_configure(device, &cfg);
//}

static void usr_qspi_hw_config(struct rt_qspi_device* device)
{
    struct rt_qspi_configuration cfg;

    cfg.parent.data_width = 8;
    cfg.parent.mode = RT_SPI_MASTER | RT_SPI_MODE_0 | RT_SPI_MSB;
    cfg.parent.max_hz = 50 * 1000 *1000;    /* 20M */

    cfg.medium_size = 0x1000000;
    cfg.ddr_mode = 0;
    cfg.qspi_dl_width = 4;
    rt_qspi_configure(device, &cfg);
}

static void qspi_w25q_sample(int argc, char *argv[])
{
    struct rt_qspi_device *spi_dev_w25q;
    char name;
    rt_uint8_t w25x_read_id = 0x90;
    rt_uint8_t id = {0};


    stm32_qspi_bus_attach_device("qspi1", "qspi10", RT_NULL, 4, w25qxx_enter_qspi_mode, RT_NULL);

    if (argc == 2)
    {
      rt_strncpy(name, argv, RT_NAME_MAX);
    }
    else
    {
      rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX);
    }

    /* 查找 spi 设备获取设备句柄 */
    spi_dev_w25q = (struct rt_qspi_device *)rt_device_find(name);
    if (!spi_dev_w25q)
    {
      rt_kprintf("spi sample run failed! can't find %s device!\n", name);
    }
    else
    {
      usr_qspi_hw_config(spi_dev_w25q);

      /* 方式1:使用 rt_spi_send_then_recv()发送命令读取ID */
      rt_qspi_send_then_recv(spi_dev_w25q, &w25x_read_id, 1, id, 5);
      rt_kprintf("use rt_qspi_send_then_recv() read w25q ID is:%x%x\n", id, id);

      /* 方式2:使用 rt_spi_transfer_message()发送命令读取ID */
//      struct rt_qspi_message msg1, msg2;
//
//      msg1.send_buf   = &w25x_read_id;
//      msg1.recv_buf   = RT_NULL;
//      msg1.length   = 1;
//      msg1.cs_take    = 1;
//      msg1.cs_release = 0;
//      msg1.next       = &msg2;
//
//      msg2.send_buf   = RT_NULL;
//      msg2.recv_buf   = id;
//      msg2.length   = 5;
//      msg2.cs_take    = 0;
//      msg2.cs_release = 1;
//      msg2.next       = RT_NULL;

//      rt_qspi_transfer_message(spi_dev_w25q, &msg1);
//      rt_kprintf("use rt_spi_transfer_message() read w25q ID is:%x%x\n", id, id);

    }
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(qspi_w25q_sample, qspi w25q sample);


保存,编译,运行,可以看到已经能读取到外部FLASH的设备ID


SPI的测试可以参考官网提供的示例程序,我这边没有相应的外设做测试,SD卡这个测试留到之后的文件系统组件一起测试。

以上就是SPI驱动框架的使用说明。

页: [1]
查看完整版本: RT-Thread设备框架学习之SPI设备