RT-Thread learning record
1. New Studio Project
2. Brief description of console usage
3. PIN device framework learning
4.UART device framework learning
5.I2C device framework learning
SPI Devices
The SPI driver of RT-Thread currently only supports hardware SPI/QSPI mode.
First, check the SPI driver framework under the Components setting. The options here are QSPI mode, SPI SD card, SPI Flash, SPI Ethernet, and SPI WiFi. I have QSPI FLASH and SPI SD card on board, so I checked both. If the device is not one of the above options, you can skip it directly, as shown in the following figure
Then check the spi device routine under the Samples setting and save. As shown in the figure below, you can see that the spi routine has been added to the project
Open the example file, you can see that the function of this example is to grab the device ID of Flash through SPI. Because my board uses qspi Flash, the example cannot be used and needs to be re-implemented by myself.
First, we turn on the QSPI device driver support in board.h
Then add the pin initialization for QSPI in the board.c file or any other source file. Here I copied it after setting up the generated code under CubeMX, as shown in the figure below:
Imitate the SPI example added earlier and simply write a test routine
#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[2] = {0};
/* 0x31 write status register2 */
write_status2_buf[0] = 0x31;
status = w25qxx_read_status_register2(device);
if (!(status & 0x02))
{
status |= 1 << 1;
w25qxx_write_enable(device);
write_status2_buf[1] = 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_NAME_MAX];
rt_uint8_t w25x_read_id = 0x90;
rt_uint8_t id[5] = {0};
stm32_qspi_bus_attach_device("qspi1", "qspi10", RT_NULL, 4, w25qxx_enter_qspi_mode, RT_NULL);
if (argc == 2)
{
rt_strncpy(name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX);
}
/* Find the spi device and get the device handle*/
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);
/* Method 1: Use rt_spi_send_then_recv() to send a command to read the 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[3], id[4]);
/* Method 2: Use rt_spi_transfer_message() to send a command to read the 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[3], id[4]);
}
}
/* Export to msh command list */
MSH_CMD_EXPORT(qspi_w25q_sample, qspi w25q sample);
Save, compile, and run. You can see that the device ID of the external FLASH has been read.
For SPI testing, you can refer to the sample program provided on the official website. I don’t have the corresponding peripherals to do the testing, so the SD card test will be left for the file system component testing later.
The above is the instruction for using the SPI driver framework.