跳转至

SPINAND 使用参考


REVISION HISTORY

Revision No.
Description
Date
1.0
  • Initial release
  • 11/18/2024
    1.1
  • 更新模板并新增API描述
  • 11/25/2025

    1. 概述

    SPINAN是使用SPI进行数据存取的NAND flash。

    本文主要介绍Rtos和Linux系统下对SPINAND flash进行数据存取。

    2. 功能描述

    • 控制器自带两个片选,并且支持GPIO片选,可多个flash分时操作

    • 支持continue read模式

    • 支持四线读写模式

    • 时钟支持12Mhz、54Mhz、86Mhz、104Mhz四个档位

    支持最大80Mhz clock DTR快速读取,不同chip状况如下表

    | **chipname**  | **DTR 支持状况** |
    | ------------- | ---------------- |
    | iford         | yes              |
    | souffle       | yes              |
    | ifado         | no               |
    | pcupid        | no               |
    | ibopper       | no               |
    | ifackel       | yes              |
    

    3. 硬件连接介绍

    4. Rtos用法介绍

    4.1. Rtos Config配置

    Rtos使用SPINAND,需要配置:

    CONFIG_FSP_QSPI_SUPPORT=y
    CONFIG_FLASH_SUPPORT=y
    CONFIG_SSTAR_NAND=y
    

    进入rtos/proj目录,make menuconfig选择的配置如下:

    BSP Driver Options  --->
        [*] Support fsp_qspi driver
    
    BSP Driver Options  --->
        [*] Support Flash driver
        [*]   SPINAND
    

    4.2. Rtos SYS配置

    4.2.1. fsp_qspi节点配置

    <fsp_qspi0>
        [cs_num_u8] 2;
        [cs_mode_u8] 0;
        [engine_u8] 0;
        [ext_num_u8] 0;
        [cs_ext_u32] 0;
        [dma_u8] 1;
        [reg_u32_u16] 0x1F201A00 0x100, 0x1F201C00 0x100;
    
    属性 描述 备注
    cs_num_u8 用于标记控制器自带的片选数量 不需要修改
    cs_mode_u8 用于指定cs使用软件还是硬件控制 可根据需要修改
    engine_u8 用于指定控制器的编号 禁止修改
    ext_num_u8 用于指定使用GPIO作为片选的数量 可根据需要修改
    cs_ext_u32 用于指定除Engine自带的cs外要使用的pad index 和ext_num配合使用
    dma_u8 用于指定是否使能DMA模式 可根据需要修改
    reg_u32_u16 用于指定fspi和qspi寄存器的bank地址 不需要修改

    4.2.2. spinand节点配置

    <nandflash0>
        [engine_u8] 0;
        [cs_select_u8] 0;
    
    属性 描述 备注
    engine_u8 用于指定使用的控制器编号 不需要修改
    cs_select_u8 用于指定使用的片选编号 不需要修改

    5. Linux用法介绍

    5.1. Linux Config配置

    Linux使用SPINAND,需要配置:

    CONFIG_FSP_QSPI_SUPPORT=y
    CONFIG_FLASH_SUPPORT=y
    CONFIG_SSTAR_NAND=y
    

    进入kernel目录,make menuconfig选择的配置如下:

    Device Drivers  --->
        [*] Sstar SoC platform drivers  --->
            <*>   Sigmastar FSP-QSPI Driver
    
    Device Drivers  --->
        [*] Sstar SoC platform drivers  --->
            <*>   SigmaStar FLASH
            <*>     SPINAND
    

    5.2 dtsi节点说明

    5.2.1. fsp_qspi节点配置

    fsp-qspi0 {
        compatible = "sstar,fsp-qspi";
        reg = <0x1F201A00 0x200>, <0x1F201C00 0x200>;
        clocks = <&CLK_fsp_qspi>, <&CLK_spi_nonpm>, <&CLK_spi_synth_pll>;
        cs-num = <2>;
        cs-mode = <0>;
        cs-ext = <PAD_GPIO0>;
        engine = <0>;
        dma = <1>;
        status = "ok";
    };
    
    属性 描述 备注
    compatible 用于匹配驱动进行驱动注册,需与代码中一致 禁止修改
    reg 用于指定fsp qspi寄存器bank的地址 不需要修改
    clocks 用于指定使用的时钟源 不需要更改
    cs-num 用于标记控制器自带的片选数量 不需要更改
    cs-mode 用于指定cs使用软件还是硬件控制 可根据需要修改
    cs-ext 用于指定除Engine自带的cs外要使用的pad index 可根据需要修改
    engine 用于指定控制器的编号 不需要更改
    dma 用于指定是否使能DMA模式 可根据需要修改
    status 用于指定是否使能fsp qspi驱动 可根据需要修改

    5.2.2. spinand节点配置

    nandflash0 {
        compatible = "sstar-nandflash";
        engine = <0>;
        cs-select = <0>;
        status = "ok";
    };
    
    属性 描述 备注
    compatible 用于匹配驱动进行驱动注册,需与代码中一致 禁止修改
    engine 用于指定控制器的编号 不需要更改
    cs-select 用于指定使用的片选编号 不需要修改
    status 用于指定是否使能fsp qspi驱动 可根据需要修改

    6. API 参考

    6.1. Linux用法

    linux用法对接标准MTD设备,按照MTD操作方式对flash进行存取。

    6.2. Rtos用法

    Rtos路径:proj/sc/driver/sysdriver_common/flash/drv_part.h

    API名 功能
    sstar_part_mark_active 标记启动分区
    sstar_part_get 获取分区信息
    sstar_part_get_active 获取主分区信息
    sstar_part_get_nm 根据分区号获取分区信息
    sstar_part_get_nm_by_dev 根据设备名和分区号获取分区信息
    sstar_part_get_dev 根据设备名获取对应设备的分区信息
    sstar_part_is_support_xzdec 判断是否支持xz解压
    sstar_part_load 读取分区数据
    sstar_part_load_to_xzdec 读取分区数据并进行xz解压
    sstar_part_program 对分区进行数据写入
    sstar_part_erase 擦除分区数据
    sstar_part_block_isbad 判断分区某位置是否为坏块

    6.2.1. sstar_part_mark_active

    • 功能

      标记启动分区

    • 语法

      u8 sstar_part_mark_active(u8 *part_name, u8 trunk);
      
    • 形参

      参数名称 描述 输入/输出
      part_name 分区名字 输入
      trunk 主备份分区标志 输入
    • 返回值

      • 0:失败。

      • 非0:成功。

    • 依赖

      • 头文件:drv_part.h

    6.2.2. sstar_part_get

    • 功能

      获取分区信息

    • 语法

      u8 sstar_part_get(u8 *part_name, u8 trunk, struct sstar_part *part);
      
    • 形参

      参数名称 描述 输入/输出
      part_name 分区名字 输入
      trunk 主备份分区标志 输入
      part 分区信息结构体 输出
    • 返回值

      • 0:失败。

      • 1:成功。

    • 依赖

      • 头文件:drv_part.h

    6.2.3. sstar_part_get_active

    • 功能

      获取主分区信息

    • 语法

      u8 sstar_part_get_active(u8 *part_name, struct sstar_part *part);
      
    • 形参

      参数名称 描述 输入/输出
      part_name 分区名字 输入
      part 分区信息结构体 输出
    • 返回值

      • 0:失败。

      • 1:成功。

    • 依赖

      • 头文件:drv_part.h

    6.2.4. sstar_part_get_nm

    • 功能

      根据分区号获取分区信息

    • 语法

      u8 sstar_part_get_nm(u8 part_id, struct sstar_part *part);
      
    • 形参

      参数名称 描述 输入/输出
      part_id 分区号 输入
      part 分区信息结构体 输出
    • 返回值

      • 0:失败。

      • 1:成功。

    • 依赖

      • 头文件:drv_part.h

    6.2.5. sstar_part_get_nm_by_dev

    • 功能

      根据设备名和分区号获取分区信息

    • 语法

      u8 sstar_part_get_nm_by_dev(u8 *dev_name, u8 part_id, struct sstar_part *part);
      
    • 形参

      参数名称 描述 输入/输出
      dev_name 设备名 输入
      part_id 分区号 输入
      part 分区信息结构体 输出
    • 返回值

      • 0:失败。

      • 1:成功。

    • 依赖

      • 头文件:drv_part.h

    6.2.6. sstar_part_get_dev

    • 功能

      根据设备名获取对应设备的分区信息

    • 语法

      u8 sstar_part_get_dev(u8 *dev_name, struct sstar_part *part);
      
    • 形参

      参数名称 描述 输入/输出
      dev_name 设备名 输入
      part 分区信息结构体 输出
    • 返回值

      • 0:失败。

      • 1:成功。

    • 依赖

      • 头文件:drv_part.h

    6.2.7. sstar_part_is_support_xzdec

    • 功能

      判断是否支持xz解压

    • 语法

      u8 sstar_part_is_support_xzdec(struct sstar_part *part);
      
    • 返回值

      • 0:不支持。

      • 1:支持。

    • 形参

      参数名称 描述 输入/输出
      part 分区信息结构体 输入
    • 依赖

      • 头文件:drv_part.h

    6.2.8. sstar_part_load

    • 功能

      读取分区数据

    • 语法

      u32 sstar_part_load(struct sstar_part *part, u32 u32_offset, u8 *pu8_data, u32 u32_size);
      
    • 返回值

      • 0:失败。

      • u32_size:成功。

    • 形参

      参数名称 描述 输入/输出
      part 分区信息结构体 输入
      u32_offset 分区内偏移 输入
      pu8_data 数据存放BUFF 输入
      u32_size 数据读取的大小 输入
    • 依赖

      • 头文件:drv_part.h

    6.2.9. sstar_part_load_to_xzdec

    • 功能

      读取分区数据并进行xz解压

    • 语法

      u32 sstar_part_load_to_xzdec(struct sstar_part *part, u32 u32_offset, u8 *pu8_data, u32 u32_size);
      
    • 返回值

      • 0:失败。

      • u32_size:成功。

    • 形参

      参数名称 描述 输入/输出
      part 分区信息结构体 输入
      u32_offset 分区内偏移 输入
      pu8_data 数据存放BUFF 输入
      u32_size 数据读取的大小 输入
    • 依赖

      • 头文件:drv_part.h

    6.2.10. sstar_part_program

    • 功能

      对分区进行数据写入

    • 语法

      u32 sstar_part_program(struct sstar_part *part, u32 u32_offset, u8 *pu8_data, u32 u32_size);
      
    • 返回值

      • 0:失败。

      • u32_size:成功。

    • 形参

      参数名称 描述 输入/输出
      part 分区信息结构体 输入
      u32_offset 分区内偏移 输入
      pu8_data 数据存放BUFF 输入
      u32_size 数据写入的大小 输入
    • 依赖

      • 头文件:drv_part.h
    • 注意

      • 必须先对写入的范围数据进行擦擦除
      • 擦除是按块擦除的,经典值是0x20000,举例擦除地址0x20020,大小0x800,实际擦除的物理地址0x20000~0x40000

    6.2.11. sstar_part_erase

    • 功能

      对分区进行数据擦除

    • 语法

      u32 sstar_part_erase(struct sstar_part *part, u32 u32_offset, u32 u32_size);
      
    • 返回值

      • 0:失败。

      • u32_size:成功。

    • 形参

      参数名称 描述 输入/输出
      part 分区信息结构体 输入
      u32_offset 分区内偏移 输入
      u32_size 数据写入的大小 输入
    • 依赖

      • 头文件:drv_part.h
    • 注意

      • 擦除是按块擦除的,经典值是0x20000,举例擦除地址0x20020,大小0x800,实际擦除的物理地址0x20000~0x40000

    6.2.12. sstar_part_block_isbad

    • 功能

      判断分区某位置是否为坏块

    • 语法

      u32 sstar_part_block_isbad(struct sstar_part *part, u32 u32_offset);
      
    • 返回值

      • 0:好块。

      • 1:坏块。

    • 形参

      参数名称 描述 输入/输出
      part 分区信息结构体 输入
      u32_offset 分区内偏移 输入
    • 依赖

      • 头文件:drv_part.h

    7. 数据结构说明

    相关数据结构定义如下

    数据类型 定义
    sstar_part 功能相关配置
    sstar_part_device 行偏移配置

    7.1. sstar_part

    • 说明

      记录分区信息。

    • 定义

      struct sstar_part
      {
          u8                        trunk;
          u8                        backup_trunk;
          u32                       offset;
          u32                       size;
          u32                       block_size;
          const u8 *                part_name;
          struct sstar_part_device *part_dev;
      };
      
    • 成员

      成员名称 描述
      trunk 主分区标志
      backup_trunk 备份分区标志
      offset 分区偏移
      size 分区大小
      block_size 分区一个块的大小
      part_name 分区名
      part_dev 分区设备结构体

    7.2. part_dev

    • 说明

      分区设备结构体,记录分区操作方法。

    • 定义

      struct sstar_part_device
      {
          u8    engine;
          u8    cs_select;
          u8    xzdec_en;
          u8    dev_name[8];
          u32   capacity;
          u32   erase_size;
          void *handle;
          u32 (*read_skip_bad)(void *, u32, u32, u32, u8 *);
          u32 (*read_to_xzdec_skip_bad)(void *, u32, u32, u32, u8 *);
          u32 (*write_skip_bad)(void *, u32, u32, u32, u8 *);
          u32 (*erase_skip_bad)(void *, u32, u32, u32);
          u32 (*block_isbad)(void *, u32);
      };
      
    • 成员

      成员名称 描述
      engine 使用的控制器编号
      cs_select 使用的片选编号
      xzdec_en 是否支持xz解压
      dev_name[8] 分区设备名
      capacity 物理存储器总大小
      erase_size 擦除一个块的大小
      handle 私有句柄
      (*read_skip_bad) 读取函数
      (*read_to_xzdec_skip_bad) 读取数据并xz解压函数
      (*write_skip_bad) 写数据函数
      (*erase_skip_bad) 擦除数据函数
      (*block_isbad) 判断坏块函数

    8. 测试用例说明

    1. Linux参考:mtdutils使用方法(开源工具,可在linux开发社区获取)

    2. Rtos参考: proj/sc/system/env_util/src/env_util.c