一、硬件
1.潘多拉stm32L475开发板/W25Q128/TF卡64M
二、软件环境
1.Win10/rt-thread studio2.2.4/rt-thread 4.1.0
三、参考潘多拉开发板SDK及实例程序
四、操作内容
1.先配置rt-thread 4.1.0最基本功能,通过串口打印信息
2.rt-thread setting->spi/dfs/fatfs
3.tf卡驱动
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_spi.h"
#include "spi_msd.h"
#ifdef BSP_USING_TF_CARD
void HAL_SPI_MspInit(SPI_HandleTypeDef *spiHandle)
{
GPIO_InitTypeDef GPIO_InitStruct;
RT_ASSERT(spiHandle != RT_NULL);
#ifdef BSP_USING_SPI1
if (spiHandle->Instance == SPI1)
{
/* SPI1 clock enable */
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
GPIO_InitStruct.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
#endif
}
void HAL_SPI_MspDeInit(SPI_HandleTypeDef *spiHandle)
{
RT_ASSERT(spiHandle != RT_NULL);
#ifdef BSP_USING_SPI1
if (spiHandle->Instance == SPI1)
{
/* Peripheral clock disable */
__HAL_RCC_SPI1_CLK_DISABLE();
/**SPI1 GPIO Configuration
PA5 ------> SPI1_SCK
PA6 ------> SPI1_MISO
PA7 ------> SPI1_MOSI
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7);
}
#endif
}
static int rt_hw_spi1_tfcard(void)
{
__HAL_RCC_GPIOC_CLK_ENABLE();
rt_hw_spi_device_attach("spi1", "spi10", GPIOC, GPIO_PIN_3);
return msd_init("sd0", "spi10");
}
INIT_COMPONENT_EXPORT(rt_hw_spi1_tfcard);
4.修改board.h文件,打开spi1定义宏
/ -------------------------- SPI CONFIG BEGIN -------------------------- /
/** if you want to use spi bus you can use the following instructions.
STEP 1, open spi driver framework support in the RT-Thread Settings file
STEP 2, define macro related to the spi bus
such as #define BSP_USING_SPI1
STEP 3, copy your spi init function from stm32xxxx_hal_msp.c generated by stm32cubemx to the end of board.c file
such as void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
STEP 4, modify your stm32xxxx_hal_config.h file to support spi peripherals. define macro related to the peripherals
such as #define HAL_SPI_MODULE_ENABLED
*/
#define BSP_USING_SPI1
/ #define BSP_USING_SPI2 /
/ #define BSP_USING_SPI3 /
#define BSP_USING_TF_CARD // 添加
5.main.c文件挂载文件系统
int main(void)
{
int count = 1;
if (dfs_mount("sd0", "/", "elm", 0, 0) == 0)
{
LOG_I("Filesystem initialized!");
} else
{
LOG_E("Failed to initialize filesystem!");
}
while (count++)
{
// LOG_D("Hello RT-Thread!");
rt_thread_mdelay(1000);
}
return RT_EOK;
}
6.编译程序
7.下载程序
8.NM25Q128 flash驱动
board.h中打开宏定义
#define BSP_USING_QSPI
#define BSP_USING_ON_CHIP_FLASH
添加
#define BSP_QSPI_USING_SOFTCS
#define BSP_USING_QSPI_FLASH
fal组件使能
添加drv_qspi_flash.c
#include <board.h>
#include <drv_qspi.h>
#include <rtdevice.h>
#include <rthw.h>
#include <finsh.h>
#ifdef BSP_USING_QSPI_FLASH
#include "spi_flash.h"
#include "spi_flash_sfud.h"
#define QSPI10_CS GET_PIN(E, 11)
void HAL_QSPI_MspInit(QSPI_HandleTypeDef *hqspi)
{
GPIO_InitTypeDef GPIO_InitStruct;
/* QSPI clock enable */
__HAL_RCC_QSPI_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
/* QSPI1 GPIO Configuration
PE10
PE11
PE12
PE13
PE14
PE15
*/
GPIO_InitStruct.Pin = GPIO_PIN_10 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF10_QUADSPI;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}
void HAL_QSPI_MspDeInit(QSPI_HandleTypeDef *hqspi)
{
/* Peripheral clock disable */
__HAL_RCC_QSPI_CLK_DISABLE();
/* QSPI GPIO Configuration
PE10
PE11
PE12
PE13
PE14
PE15
*/
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_10 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15);
}
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)
{
char instruction = 0x06;
rt_qspi_send(device, &instruction, 1);
}
void w25qxx_enter_qspi_mode(struct rt_qspi_device *device)
{
char status = 0;
char instruction = 0x38;
char write_status2_buf[2] = {0};
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
");
rt_thread_mdelay(10);
}
}
static int rt_hw_qspi_flash_with_sfud_init(void)
{
stm32_qspi_bus_attach_device("qspi1", "qspi10", QSPI10_CS, 1, w25qxx_enter_qspi_mode, RT_NULL);
rt_sfud_flash_probe(FAL_USING_NOR_FLASH_DEV_NAME, "qspi10");
if (RT_NULL == rt_sfud_flash_probe(FAL_USING_NOR_FLASH_DEV_NAME, "qspi10"))
{
return -RT_ERROR;
}
return RT_EOK;
}
INIT_COMPONENT_EXPORT(rt_hw_qspi_flash_with_sfud_init);
#if defined(RT_USING_DFS_ELMFAT) && !defined(BSP_USING_SDCARD)
#include <dfs_fs.h>
#define BLK_DEV_NAME FAL_USING_NOR_FLASH_DEV_NAME
int mnt_init(void)
{
rt_thread_delay(RT_TICK_PER_SECOND);
if (dfs_mount(BLK_DEV_NAME, "/", "elm", 0, 0) == 0)
{
rt_kprintf("file system initialization done!
");
}
else
{
if(dfs_mkfs("elm", BLK_DEV_NAME) == 0)
{
if (dfs_mount(BLK_DEV_NAME, "/", "elm", 0, 0) == 0)
{
rt_kprintf("file system initialization done!
");
}
else
{
rt_kprintf("file system initialization failed!
");
}
}
}
return 0;
}
INIT_ENV_EXPORT(mnt_init);
#endif /* defined(RT_USING_DFS_ELMFAT) && !defined(BSP_USING_SDCARD) */
#endif /* BSP_USING_QSPI_FLASH */
添加 fal_flash_sfud_port.c
#include <fal.h>
#include <sfud.h>
#ifdef FAL_USING_SFUD_PORT
#ifdef RT_USING_SFUD
#include <spi_flash_sfud.h>
#endif
#ifndef FAL_USING_NOR_FLASH_DEV_NAME
#define FAL_USING_NOR_FLASH_DEV_NAME "norflash0"
#endif
static int init(void);
static int read(long offset, uint8_t *buf, size_t size);
static int write(long offset, const uint8_t *buf, size_t size);
static int erase(long offset, size_t size);
static sfud_flash_t sfud_dev = NULL;
struct fal_flash_dev nor_flash0 =
{
.name = FAL_USING_NOR_FLASH_DEV_NAME,
.addr = 0,
.len = 8 * 1024 * 1024,
.blk_size = 4096,
.ops = {init, read, write, erase},
.write_gran = 1
};
static int init(void)
{
#ifdef RT_USING_SFUD
sfud_dev = rt_sfud_flash_find_by_dev_name(FAL_USING_NOR_FLASH_DEV_NAME);
#else
extern sfud_flash sfud_norflash0;
sfud_dev = &sfud_norflash0;
#endif
if (NULL == sfud_dev)
{
return -1;
}
nor_flash0.blk_size = sfud_dev->chip.erase_gran;
nor_flash0.len = sfud_dev->chip.capacity;
return 0;
}
static int read(long offset, uint8_t *buf, size_t size)
{
assert(sfud_dev);
assert(sfud_dev->init_ok);
sfud_read(sfud_dev, nor_flash0.addr + offset, size, buf);
return size;
}
static int write(long offset, const uint8_t *buf, size_t size)
{
assert(sfud_dev);
assert(sfud_dev->init_ok);
if (sfud_write(sfud_dev, nor_flash0.addr + offset, size, buf) != SFUD_SUCCESS)
{
return -1;
}
return size;
}
static int erase(long offset, size_t size)
{
assert(sfud_dev);
assert(sfud_dev->init_ok);
if (sfud_erase(sfud_dev, nor_flash0.addr + offset, size) != SFUD_SUCCESS)
{
return -1;
}
return size;
}
#endif /* FAL_USING_SFUD_PORT */
在main.c文件中初始fal
/*
Copyright (c) 2006-2022, RT-Thread Development Team
SPDX-License-Identifier: Apache-2.0
Change Logs:
Date Author Notes
2022-07-10 RT-Thread first version
*/
#include <rtthread.h>
#include <fal.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
int main(void)
{
/*
int count = 1;
while (count++)
{
LOG_D("Hello RT-Thread!");
rt_thread_mdelay(1000);
}
*/
fal_init();
return RT_EOK;
}
原作者:hnhebing