rt-thread/bsp/phytium/libraries/standalone/doc/reference/driver/fnand.md

448 lines
15 KiB
Markdown
Raw Normal View History

<!--
* Copyright : (C) 2022 Phytium Information Technology, Inc.
* All Rights Reserved.
*
* This program is OPEN SOURCE software: you can redistribute it and/or modify it
* under the terms of the Phytium Public License as published by the Phytium Technology Co.,Ltd,
* either version 1.0 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the Phytium Public License for more details.
*
*
* FilePath: fnand.md
* Date: 2022-06-07 19:57:17
* LastEditTime: 2022-06-07 19:57:18
* Description: This file is for
*
* Modify History:
* Ver Who Date Changes
* ----- ------ -------- --------------------------------------
-->
# 驱动概述
- NAND 作为廉价的存储介质在大文件的存储场景中占有重要的地位由此在嵌入式方案中如何将此驱动做稳定做易用尤为重要。NAND 控制器驱动具有以下特性:
1. 支持模式 Toggle 介质模式
2. 支持模式时序配置 ,同步模式,异步模式
3. 支持请求之间时间间隔
4. 采用dma 数据方式进行传输
5. 支持时序模式下的高频时钟采样相位调节
6. 支持硬件ECC纠错
当前NAND 驱动控制器主要为用户提供了以下功能接口:
1. NAND 控制器状态初始化函数
2. NAND 介质扫描接口
3. NAND 介质page读/写接口块擦除接口spare space 读写接口
4. 中断相关接口
5. 坏块管理接口
## 驱动功能
驱动组成由以下所示 :
.
├── fnand_bbm.c
├── fnand_bbm.h
├── fnand.c
├── fnand_dma.c
├── fnand_dma.h
├── fnand_ecc.c
├── fnand_ecc.h
├── fnand_g.c
├── fnand.h
├── fnand_hw.c
├── fnand_hw.h
├── fnand_intr.c
├── fnand_option.c
├── fnand_sinit.c
├── fnand_timing.c
├── fnand_timing.h
├── fnand_toggle.c
└── fnand_toggle.h
其中fnand.h 为用户开发者主要使用接口,提供了以下功能:
1. Nand 控制器初始化接口
2. 根据Nand 介质id 初始化介质页/块的大小
3. Nand 控制器相关状态位的回调函数注册
4. Nand 控制器中断处理函数
5. Nand 坏块管理函数
## 数据结构
```c
typedef struct _FNand
{
u32 is_ready; /* Device is ininitialized and ready*/
FNandConfig config;
u32 work_mode; /* NAND controler work mode */
/* nand flash info */
FNandInterMode inter_mode[FNAND_CONNECT_MAX_NUM]; /* NAND controler timing work mode */
FNandTimingMode timing_mode[FNAND_CONNECT_MAX_NUM];
u32 nand_flash_interface[FNAND_CONNECT_MAX_NUM] ; /* Nand Flash Interface , followed by FNAND_ONFI_MODE \ FNAND_TOGGLE_MODE*/
struct FNandDmaBuffer dma_data_buffer; /* DMA data buffer */
struct FNandDmaBuffer descriptor_buffer; /* DMA descriptor */
struct FNandDmaDescriptor descriptor[2]; /* DMA descriptor */
struct FNandSdrTimings sdr_timing; /* SDR NAND chip timings */
/* bbm */
FNandBadBlockManager bbt_manager[FNAND_CONNECT_MAX_NUM]; /* bad block manager handler */
/* nand detect */
FNandNandGeometry nand_geometry[FNAND_CONNECT_MAX_NUM]; /* nand flash infomation */
/* dma 页操作 */
FnandIrqEventHandler irq_event_fun_p; /* Interrupt event response function */
void *irq_args;
FNandOperationWaitIrqCallback wait_irq_fun_p; /* The NAND controller operates the wait function */
void *wait_args;
/* operations */
FNandTransferP write_p ; /* Write page function */
FNandTransferP read_p ; /* Read page function */
FNandTransferP write_oob_p ; /* Write page spare space function */
FNandTransferP read_oob_p ; /* Read page spare space function */
FNandTransferP write_hw_ecc_p ; /* Write page with hardware function */
FNandTransferP read_hw_ecc_p ; /* Read page with hardware function */
FNandEraseP erase_p; /* Erase block function */
} FNand;
```
## 错误码定义
```
FNAND_ERR_OPERATION /* NAND 控制器操作NAND flash 失败 */
FNAND_ERR_INVAILD_PARAMETER /* 当NAND 控制器配置信息不存在 */
FNAND_IS_BUSY /* NAND 控制器操作NAND flash ,控制器正忙 */
FNAND_OP_TIMEOUT /* NAND 控制器操作超时*/
FNAND_VALUE_ERROR /* NAND 控制器在进行BBM 搜索过程时,获取坏块管理信息不匹配 */
FNAND_VALUE_FAILURE /* 获取的数据与预期不相符合 */
FNAND_NOT_FET_TOGGLE_MODE /* toggle 模式 */
FNAND_ERR_READ_ECC /* 读取过程中进行硬件ecc ,错误超过纠错的范围 */
FNAND_ERR_IRQ_OP_FAILED /* 中断进行读/写/擦操作时,回调函数反馈错误 */
FNAND_ERR_IRQ_LACK_OF_CALLBACK /* 中断进行读/写/擦操作时,缺少回调函数 */
FNAND_ERR_IRQ_OP_FAILED /* 等待中断回应失败 */
FNAND_ERR_NOT_MATCH /* 进行flash id 检测时,检测结果与预期不符合 */
```
## 应用例程
- baremetal/example/peripheral/nand/nand_test
## API 介绍
### 1. FNandLookupConfig
```
FNandConfig *FNandLookupConfig(u32 instance_id)
```
#### 介绍
- 获取当前FNand驱动默认配置
#### 参数
- u32 instance_id :当前Nand驱动中对应的ID
#### 返回
FGicConfig * :静态默认配置
### 2. FNandCfgInitialize
```
FError FNandCfgInitialize(FNand *instance_p,FNandConfig *config_p)
```
#### 介绍
- 根据传入配置初始化NAND驱动实例
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- FNandConfig * 需要应用于示例中的配置项
#### 返回
- FError :FT_SUCCESS 为初始成功
### 3. FNandScan
```
FError FNandScan(FNand *instance_p)
```
#### 介绍
- Nand flash 扫描此接口调用之后会自动扫描Nand flash 介质信息
#### 参数
- FNand *instance_p FNand 控制器实例的指针
#### 返回
- FError :FT_SUCCESS 为初始成功
### 4. FNandWritePage
```
FError FNandWritePage(FNand *instance_p,u32 page_addr,u8 *buffer,u32 page_copy_offset ,u32 length,u8 *oob_buffer,u32 oob_copy_offset,u32 oob_length,u32 chip_addr)
```
#### 介绍
- 每次写一个页面的操作,包括写页面数据和空闲数据 默认会进行硬件ecc 编码写入
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- u32 page_addr 页操作地址,单位为页
- u8 *buffer 指向写入内容缓冲区的指针
- u32 page_copy_offset 写入某一页中的具体位置当此参数非0 时,写入的地址为 在page_addr 对应的页面下0 + page_copy_offset 开始的地址未覆盖的地方默认填入0xff
- u32 length 数据写入页面下的长度
- u8 *oob_buffer 指向写入spare space内容 缓冲区的指针
- u32 oob_copy_offset 写入某一页中spare space 的具体位置当此参数非0 时在page_addr 对应的页面下,写入的地址为 页长度 + page_copy_offset 开始的地址未覆盖的地方默认填入0xff
- u32 oob_length spare space数据写入页面下的长度
- u32 chip_addr 芯片地址
#### 返回
- FError :FT_SUCCESS 为写入成功
### 5. FNandWritePageRaw
```
FError FNandWritePageRaw(FNand *instance_p,u32 page_addr,u8 *buffer,u32 page_copy_offset ,u32 length,u8 *oob_buffer,u32 oob_copy_offset,u32 oob_length,u32 chip_addr)
```
#### 介绍
- 每次写一个页面的操作,包括写页面数据和空闲数据 默认不会进行硬件ecc 编码写入
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- u32 page_addr 页操作地址,单位为页
- u8 *buffer 指向写入内容缓冲区的指针
- u32 page_copy_offset 写入某一页中的具体位置当此参数非0 时,写入的地址为 在page_addr 对应的页面下0 + page_copy_offset 开始的地址未覆盖的地方默认填入0xff
- u32 length 数据写入页面下的长度
- u8 *oob_buffer 指向写入spare space内容 缓冲区的指针
- u32 oob_copy_offset 写入某一页中spare space 的具体位置当此参数非0 时在page_addr 对应的页面下,写入的地址为 页长度 + page_copy_offset 开始的地址未覆盖的地方默认填入0xff
- u32 oob_length spare space数据写入页面下的长度
- u32 chip_addr 芯片地址
#### 返回
- FError :FT_SUCCESS 为写入成功
### 6. FNandReadPage
```
FError FNandReadPage(FNand *instance_p,u32 page_addr,u8 *buffer,u32 page_copy_offset,u32 length,u8 *oob_buffer,u32 oob_copy_offset,u32 oob_length,u32 chip_addr)
```
#### 介绍
- 每次读出一个页面的操作,包括读页面数据和空闲数据 默认会进行ecc 纠错
#### 参数
```
FNand *instance_p FNand 控制器实例的指针
u32 page_addr 页操作地址,单位为页
u8 *buffer 指向读出内容缓冲区的指针
u32 page_copy_offset 读出某一页中的具体位置当此参数非0 时,读出的地址为 在page_addr 对应的页面下 0 + page_copy_offset 开始的地址
u32 length 数据读出页面下的长度
u8 *oob_buffer 指向读出spare space内容 缓冲区的指针
u32 oob_copy_offset 读出某一页中spare space 的具体位置当此参数非0 时在page_addr 对应的页面下,读出的地址为 页长度 + page_copy_offset 开始的地址
u32 oob_length spare space数据读出的长度
u32 chip_addr 芯片地址
```
#### 返回
- FError :FT_SUCCESS 为读出成功
### 7. FNandReadPageRaw
```
FError FNandReadPageRaw(FNand *instance_p,u32 page_addr,u8 *buffer,u32 page_copy_offset,u32 length,u8 *oob_buffer,u32 oob_copy_offset,u32 oob_length,u32 chip_addr)
```
#### 介绍
- 每次读出一个页面的操作,包括读页面数据和空闲数据 不会进行ecc 纠错
#### 参数
```
FNand *instance_p FNand 控制器实例的指针
u32 page_addr 页操作地址,单位为页
u8 *buffer 指向读出内容缓冲区的指针
u32 page_copy_offset 读出某一页中的具体位置当此参数非0 时,读出的地址为 在page_addr 对应的页面下 0 + page_copy_offset 开始的地址
u32 length 数据读出页面下的长度
u8 *oob_buffer 指向读出spare space内容 缓冲区的指针
u32 oob_copy_offset 读出某一页中spare space 的具体位置当此参数非0 时在page_addr 对应的页面下,读出的地址为 页长度 + page_copy_offset 开始的地址
u32 oob_length spare space数据读出的长度
u32 chip_addr 芯片地址
```
#### 返回
- FError :FT_SUCCESS 为读出成功
### 8. FNandEraseBlock
```
FError FNandEraseBlock(FNand *instance_p, u32 block, u32 chip_addr)
```
#### 介绍
- 擦除块数据
#### 参数
FNand *instance_p FNand 控制器实例的指针
u32 block 块的位置号
u32 chip_addr 芯片地址
#### 返回
- FError :FT_SUCCESS 为写入成功
### 9. FNandReadPageOOb
```
FError FNandReadPageOOb(FNand *instance_p,u32 page_addr,u8 *oob_buffer,u32 oob_copy_offset,u32 oob_length,u32 chip_addr)
```
#### 介绍
- 读取每一页中的 spare space 内容
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- u32 page_addr 需要读取空闲空间的Row Address
- u8 * oob_buffer 指向读取数据的缓冲区
- u32 oob_copy_offset 读出某一页中spare space 中位置的偏移当此参数非0 时,读出的地址为 在page_addr 对应的页面下 page length + oob_copy_offset 开始的地址
- u32 oob_length 需要读取是页面中spare space 中的长度
- u32 chip_addr 芯片地址
#### 返回
- FError :FT_SUCCESS 为写入成功
### 10. FNandWritePageOOb
```
FError FNandWritePageOOb(FNand *instance_p,u32 page_addr,u8 *oob_buffer,u32 page_copy_offset,u32 oob_length,u32 chip_addr)
```
#### 介绍
- 读取每一页中的 spare space 内容
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- u32 page_addr 需要写入空闲空间的Row Address
- u8 * oob_buffer 指向写入数据的缓冲区
- u32 oob_copy_offset 写入某一页中spare space 中位置的偏移当此参数非0时写入的地址为 在page_addr 对应的页面下 page length + oob_copy_offset 开始的地址
- u32 oob_length 需要写入是页面中spare space 中的长度
- u32 chip_addr 芯片地址
#### 返回
- FError :FT_SUCCESS 为写入成功
### 11. FNandSetIsrHandler
```
void FNandSetIsrHandler(FNand *instance_p, FnandIrqEventHandler event_p, void *irq_args)
```
#### 介绍
- 初始化中断事件回调函数
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- FnandIrqEventHandler event_p 中断事件回调函数
- void *irq_args 回调函数传入参数
#### 返回
### 12. FNandIrqHandler
```
void FNandIrqHandler(s32 vector, void *param)
```
#### 介绍
- Nand 控制器中断响应函数
#### 参数
- s32 vector 中断ID
- void * param 中断传入参数
#### 返回
-
### 13. FNandInitBbtDesc
```
void FNandInitBbtDesc(FNand *instance_p)
```
#### 介绍
- 坏块表初始化
#### 参数
- FNand *instance_p FNand 控制器实例的指针
#### 返回
-
### 10. FNandScanBbt
```
FError FNandScanBbt(FNand *instance_p, u32 target_addr)
```
#### 介绍
- 在Nand flash中扫描具体目标地址的坏块表
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- u32 chip_addr 芯片地址
#### 返回
- FError :FT_SUCCESS 为扫描成功
### 11. FNandIsBlockBad
```
FError FNandIsBlockBad(FNand *instance_p, u32 block, u32 target_addr)
```
#### 介绍
- 检查当前块是否为坏块
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- u32 block 需要检查的块ID号
- u32 chip_addr 芯片地址
#### 返回
- FError :FT_SUCCESS 为当前块为坏块
### 12. FNandOperationWaitIrqRegister
```
void FNandOperationWaitIrqRegister(FNand *instance_p,FNandOperationWaitIrqCallback wait_irq_fun_p ,void *wait_args)
```
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- FNandOperationWaitIrqCallback 用户使用读/写/擦接口过程中,等待中断完成的回调函数接口 用户的回调函数驱动以FT_SUCCESS 作为成功判断,否则为失败
- void *wait_args 用户需要传入至回调函数中的参数
### 返回
### 13. FNandSetOption
- 依据options 选项参数,配置对应参数
```c
FError FNandSetOption(FNand *instance_p,u32 options,u32 value)
```
#### 参数
- FNand *instance_p FNand 控制器实例的指针
- u32 option 具体配置项
- u32 value 配置项中对应的参数