栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

SFUD 一款嵌入式SPI FLASH驱动组件

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SFUD 一款嵌入式SPI FLASH驱动组件

SFUD 一款嵌入式SPI FLASH驱动组件

源仓库:https://github.com/armink/SFUD
移植例程仓库:https://gitee.com/ll0_0ll/Packages-practice

简介 1.功能

通常要驱动SPI Flash要根据厂家的手册写好各种接口,而这个组件通过SFDP标准,只要适配几个接口它就可以自己去获取那些厂家的操作命令,然后调用它的接口就可以驱动flash了。这样一来驱动写起来会简单点,而来换flash时改动也会少点。

2.SFDP

什么是 SFDP :它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B (点击这里查看)。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数。

具体可参考这篇文章:SFDP(Serial Flash Discoverable Parameters)_高桥凉介。的博客-CSDN博客

不支持 SFDP 怎么办 :如果该 Flash 不支持 SFDP 标准,SFUD 会查询配置文件 ( /sfud/inc/sfud_flash_def.h ) 中提供的 Flash 参数信息表 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 2.5 添加库目前不支持的 Flash)。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。

3.主要特点

主要特点:支持 SPI/QSPI 接口、面向对象(同时支持多个 Flash 对象)、可灵活裁剪、扩展性强、支持 4 字节地址
资源占用:

  • 标准占用:RAM:0.2KB ROM:5.5KB
  • 最小占用:RAM:0.1KB ROM:3.6KB
移植 1.准备

芯片:STM32F103xE W25Q128
外设:SPI2 UART1
软件:串口调试工具

2.适配接口

需要适配的接口都在sfud_port.c中

static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, size_t read_size);

static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, uint8_t *read_buf, size_t read_size);

sfud_err sfud_spi_port_init(sfud_flash *flash);

void sfud_log_debug(const char *file, const long line, const char *format, ...);

void sfud_log_info(const char *format, ...);

3.适配步骤
  1. 定义flash对象(sfud_cfg.h)
enum {
    SFUD_XXXX_DEVICE_INDEX = 0,
};

#define SFUD_FLASH_DEVICE_TABLE                                                
{                                                                              
    [SFUD_XXXX_DEVICE_INDEX] = {.name = "TEST", .spi.name = "SPI2"},           
}
  1. 适配接口(sfud_port.c)
sfud_err sfud_spi_port_init(sfud_flash *flash)
{
    sfud_err result = SFUD_SUCCESS;

    switch (flash->index)
    {
    case SFUD_XXXX_DEVICE_INDEX:
    {
        spi2_init();
        
        flash->spi.wr = spi_write_read;
        flash->spi.lock = spi_lock;
        flash->spi.unlock = spi_unlock;
        
        flash->retry.delay = retry_delay_100us;
        
        flash->retry.times = 3 * 10000;

        break;
    }
    }
    return result;
}


static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf,
                               size_t write_size, uint8_t *read_buf,
                               size_t read_size)
{
    sfud_err result = SFUD_SUCCESS;
    uint8_t send_data, read_data;

    if (write_size)
    {
        SFUD_ASSERT(write_buf);
    }
    if (read_size)
    {
        SFUD_ASSERT(read_buf);
    }

    SPI_FLASH_CS_EN();
    for (size_t i = 0, retry_times; i < write_size + read_size; i++)
    {
        
        if (i < write_size)
        {
            send_data = *write_buf++;
        }
        else
        {
            send_data = SFUD_DUMMY_DATA;
        }
        
        retry_times = 1000;
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET)
        {
            SFUD_RETRY_PROCESS(NULL, retry_times, result);
        }
        if (result != SFUD_SUCCESS)
        {
            goto exit;
        }
        SPI_I2S_SendData(SPI2, send_data);
        
        retry_times = 1000;
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET)
        {
            SFUD_RETRY_PROCESS(NULL, retry_times, result);
        }
        if (result != SFUD_SUCCESS)
        {
            goto exit;
        }
        read_data = SPI_I2S_ReceiveData(SPI2);
        
        if (i >= write_size)
        {
            *read_buf++ = read_data;
        }
    }

exit:
    SPI_FLASH_CS_DIS();

    return result;
}

  1. 调用接口(可在sfud.h中查看可供调用的API)
int main(void)
{
    sfud_flash *flash;
    sfud_err result = SFUD_ERR_NOT_FOUND;
    uint8_t sfud_Write_buf[] = "SFUD TEST!";
    uint8_t sfud_Read_buf[30];
    uint32_t addr = 0x00000000;
    size_t size = sizeof(sfud_Write_buf);

    
    single_uart_init();
    printf("enter sfud testrn");

    flash = sfud_get_device(SFUD_XXXX_DEVICE_INDEX);

    if (sfud_device_init(flash) == SFUD_SUCCESS)
        printf("SFUD Init Successrn");
    else
        printf("SFUD Init Failedrn");
    
    result = sfud_erase(flash, addr, size);
    if (result == SFUD_SUCCESS)
    {
        printf("Erase the %s flash data finish. Start from 0x%08X, size is %zu.rn", flash->name,
               addr, size);
    }
    else
    {
        printf("Erase the %s flash data failed.rn", flash->name);
    }

    result = sfud_write(flash, addr, size, sfud_Write_buf);
    if (result == SFUD_SUCCESS)
    {
        printf("Write the %s flash data finish. Start from 0x%08X, size is %zu.rn", flash->name,
               addr, size);
    }
    else
    {
        printf("Write the %s flash data failed.rn", flash->name);

    }

    result = sfud_read(flash, addr, size, sfud_Read_buf);
    if (result == SFUD_SUCCESS)
    {
        printf("Read the %s flash data success. Start from 0x%08X, size is %zu.rn", flash->name,
               addr, size);
        printf("The data is:%s", sfud_Read_buf);
        printf("rn");
    }
    else
    {
        printf("Read the %s flash data failed.rn", flash->name);
    }
    

    while(1);
}

  1. 打印信息

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/269441.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号