查询qspi配置过程
文件路径: /drivers/board.h
/*-------------------------- QSPI CONFIG BEGIN --------------------------*/
/** if you want to use qspi you can use the following instruc
tions.
*
* STEP 1, open qspi driver framework support in the RT-Thread Settings file
*
* STEP 2, define macro related to the qspi
* such as #define BSP_USING_QSPI
*
* STEP 3, copy your qspi init function from
STM32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
* such as void HAL_QSPI_MspInit(QSPI_HandleTypeDef* hqspi)
*
* STEP 4, modify your stm32xxxx_hal_config.h file to support qspi peripherals. define macro related to the peripherals
* such as #define HAL_QSPI_MODULE_ENABLED
*
*/
#define BSP_USING_QSPI
注释中详细描述了qspi配置过程,
1使能rtt qspi驱动
打开 RT-Thread Settings 选择SPI功能后,右键详细配置:分别勾选
|
|---->设备驱动程序
| |---->使能SPI总线/设备驱动程序 √
| |---->使能QSPI模式 √
2 使能使用 qspi bsp
打开 /drivers/board.h 使能 #define BSP_USING_QSPI
3 初始化qspi硬件
通过 stm32cubemx工具使能qspi硬件,在一下路径
CoreSrcstm32f7xx_hal_msp.c中将HAL_QSPI_MspInit拷贝到 /drivers/board.c中
void HAL_QSPI_MspInit(QSPI_HandleTypeDef* qspiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(qspiHandle->Instance==QUADSPI)
{
/* QUADSPI clock enable */
__HAL_RCC_QSPI_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**QUADSPI GPIO Configuration
PE2 ------> QUADSPI_BK1_IO2
PB2 ------> QUADSPI_CLK
PB10 ------> QUADSPI_BK1_NCS
PD11 ------> QUADSPI_BK1_IO0
PD12 ------> QUADSPI_BK1_IO1
PD13 ------> QUADSPI_BK1_IO3
*/
GPIO_InitStruct.Pin = GPIO_PIN_2;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF9_QUADSPI;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
}
4 打开相应的HAL库
打开 /drivers/ stm32f7xx_hal_conf.h 使能 #define HAL_QSPI_MODULE_ENABLED 使能 #define HAL_SPI_MODULE_ENABLED
5 编译验证
烧录,在串口终端输入/demo>list_device
qspi1 SPI Bus 0
uart1 Character Device 2
pin Miscellaneous Device 0
可以看到spi总线
挂载W25qspi设备
添加 qspiflash挂载代码 ```c /**
读取qspi状态寄存器2
@param device : qspi设备
@Return / 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; } /**
qspi写使能
@param device : qspi设备 / void w25qxx_write_enable(struct rt_qspi_device device) { / 0x06 write enable / char instruction = 0x06; rt_qspi_send(device, &instruction, 1);//发送数据 } /**
使能qspi模式
@param device : qspi设备 / 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);//读取状态寄存器2 if (!(status & 0x02))//判读当前flash
通信模式 {
status |= 1 << 1;
w25qxx_write_enable(device); //w25q写使能
write_status2_buf[1] = status; //写状态寄存器
rt_qspi_send(device, &write_status2_buf, 2);//
rt_qspi_send(device, &instruction, 1);//设置qspi模式
rt_kprintf("flash already enter qspi moden");
rt_thread_mdelay(10);
} }
/* 挂在设备到qspi总线上
@return 挂载状态 / static rt_err_t rt_hw_qspi_flash_with_sfud_init(void) { /W25Q256挂在qspi总线上*/ rt_err_t ret = stm32_qspi_bus_attach_device(“qspi1”, “qspi10”, RT_NULL, 4, w25qxx_enter_qspi_mode, RT_NULL); if (ret != RT_EOK) {
rt_kprintf("qspi attach device failedn");
return -RT_ERROR;
} rt_kprintf(“qspi attach device successn”); return RT_EOK; }
/设备自动初始化 / INIT_DEVICE_EXPORT(rt_hw_qspi_flash_with_sfud_init);
- 编译验证
烧录,在串口终端输入
**list_device**
```c
device type ref count
-------- -------------------- ----------
qspi10 SPI Device 0
qspi1 SPI Bus 0
uart1 Character Device 2
pin Miscellaneous Device 0
可以看到spi总线 和 QSPI设备
设备id读取测试
#define W25Q_SPI_DEVICE_NAME "qspi10"
static void qspi_w25q_sample(int argc, char *argv[])
{
struct rt_spi_device *qspi_dev_w25q;
char name[RT_NAME_MAX];
rt_uint8_t w25x_read_id = 0x90;
rt_uint8_t id[5] = {0};
if (argc == 2)
{
rt_strncpy(name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(name, W25Q_SPI_DEVICE_NAME, RT_NAME_MAX);
}
/* 查找 spi 设备获取设备句柄 */
qspi_dev_w25q = (struct rt_spi_device *)rt_device_find(name);//根据 SPI 设备名称查找设备获取设备句柄
if (!qspi_dev_w25q)
{
rt_kprintf("qspi sample run failed! can't find %s device!n", name);
}
else
{
/* 方式1:使用 rt_spi_send_then_recv()发送命令读取ID */
rt_qspi_send_then_recv(qspi_dev_w25q, &w25x_read_id, 1, id, 5);//先发送后接收数据id
rt_kprintf("use rt_qspi_send_then_recv() read w25q ID is:%x%xn", id[3], id[4]);
}
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(qspi_w25q_sample, qspi w25q sample);
创建 快设备
使能 SFUD 打开 RT-Thread Settings 选择SPI功能后,右键详细配置:分别勾选
|
|---->设备驱动程序
| |---->使能SPI总线/设备驱动程序 √
| |---->使能QSPI模式 √
| |---->使能串行Flash通用驱动程序(SFUD) √
| |---->使能QSPI模式 √
| |---->使能自动探针探测Flsh JEDEC SFDP √
| |---->使能Flash 芯片信息表 √
添加创建快设备代码 ```c /**
创建块设备
@return / static int rt_hw_qspi_block_device_init(void) { / W25Q256 注册为快设备*/ if (RT_NULL == rt_sfud_flash_probe(“W25Q256”, “qspi10”)) {
rt_kprintf("flash sfud failedn");
return -RT_ERROR;
} rt_kprintf(“flash sfud successn”); return RT_EOK; }
/设备自动初始化 / INIT_DEVICE_EXPORT(rt_hw_qspi_block_device_init);
- 编译验证
烧录,在串口终端输入
**list_device**
```c
device type ref count
-------- -------------------- ----------
W25Q256 Block Device 0
qspi10 SPI Device 0
qspi1 SPI Bus 0
uart1 Character Device 2
pin Miscellaneous Device 0
可以看到spi总线 和 QSPI设备 快设备
挂载文件系统
使能 fatfs 打开 RT-Thread Settings 选择fatfs功能后,右键详细配置:分别勾选
|
|---->设备虚拟文件系统
| |---->使能设备虚拟文件系统 √
| |---->使能elm chan FatFs √
| |---->elm chan 的FatFs,通用Fat 文件系统模块
| |---->设置要处理的最大扇区大小 4096(根据flash参数决定)
添加挂载文件系统代码
static int mnt_init(void)
{
dfs_mkfs("elm", "W25Q256");//格式化设备
if(dfs_mount("W25Q256", "/", "elm", 0, 0)==0)//挂载文件
{
rt_kprintf("dfs mount successrn");
return RT_EOK;
}else {
rt_kprintf("dfs mount failedrn");
return -RT_ERROR;
}
}
/* 组件自动初始化 */
INIT_COMPONENT_EXPORT(mnt_init);
编译验证 烧录,在串口终端输入 ls
Directory /:
原作者:lyq308152569