Files
STM32F4-Base/Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h
2026-07-21 00:30:59 +08:00

182 lines
6.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#ifndef __GD5F2GQ5UE_H
#define __GD5F2GQ5UE_H
/*
* 模块名称GD5F2GQ5UE SPI NAND Flash 驱动
* 模块功能:提供 GD5F2GQ5UE SPI NAND Flash 的初始化、读、写、擦除接口
* 适用平台STM32F407ZGT6 + SPI1 硬件 SPI
* 作者:王建锋
* 创建日期2026-07-16
* 修改记录:
* 2026-07-16 王建锋 创建初始版本
* 2026-07-17 王建锋 切换为硬件 SPI修正擦除地址参考 NuttX 驱动
*/
#ifdef __cplusplus
extern "C" {
#endif
#include "main.h"
/* ======================== 宏定义 ======================== */
/* SPI 命令码 */
#define GD5F_CMD_WRITE_ENABLE 0x06
#define GD5F_CMD_WRITE_DISABLE 0x04
#define GD5F_CMD_GET_FEATURE 0x0F
#define GD5F_CMD_SET_FEATURE 0x1F
#define GD5F_CMD_READ_ID 0x9F
#define GD5F_CMD_PAGE_READ 0x13
#define GD5F_CMD_READ_FROM_CACHE 0x0B
#define GD5F_CMD_PROGRAM_LOAD 0x02
#define GD5F_CMD_PROGRAM_EXEC 0x10
#define GD5F_CMD_BLOCK_ERASE 0xD8
#define GD5F_CMD_RESET 0xFF
/* 寄存器地址 */
#define GD5F_REG_PROTECT 0xA0
#define GD5F_REG_FEATURE 0xB0
#define GD5F_REG_STATUS 0xC0
#define GD5F_REG_DRIVER 0xD0
/* 状态位定义 */
#define GD5F_STATUS_OIP (1 << 0)
#define GD5F_STATUS_WEL (1 << 1)
#define GD5F_STATUS_E_FAIL (1 << 2)
#define GD5F_STATUS_P_FAIL (1 << 3)
#define GD5F_STATUS_ECCS0 (1 << 4)
#define GD5F_STATUS_ECCS1 (1 << 5)
/* Feature 位定义 */
#define GD5F_FEATURE_ECC_EN (1 << 4)
#define GD5F_FEATURE_QE (1 << 0)
/* 芯片参数 */
#define GD5F_PAGE_SIZE 2048
#define GD5F_SPARE_SIZE 64
#define GD5F_TOTAL_PAGE_SIZE 2112
#define GD5F_PAGES_PER_BLOCK 64
#define GD5F_BLOCK_SIZE (GD5F_PAGES_PER_BLOCK * GD5F_PAGE_SIZE)
#define GD5F_TOTAL_BLOCKS 2048
#define GD5F_TOTAL_SIZE (GD5F_TOTAL_BLOCKS * GD5F_BLOCK_SIZE)
/* 制造商 ID 和设备 ID */
#define GD5F_MANUFACTURER_ID 0xC8
#define GD5F_DEVICE_ID 0x52
/* 返回值定义 */
#define GD5F_OK 0
#define GD5F_ERROR -1
#define GD5F_BUSY_TIMEOUT -2
#define GD5F_ECC_ERROR -3
#define GD5F_PROGRAM_FAIL -4
#define GD5F_ERASE_FAIL -5
#define GD5F_ID_MISMATCH -6
/* 控制引脚宏 */
#define GD5F_CS_LOW() HAL_GPIO_WritePin(GD_CS_GPIO_Port, GD_CS_Pin, GPIO_PIN_RESET)
#define GD5F_CS_HIGH() HAL_GPIO_WritePin(GD_CS_GPIO_Port, GD_CS_Pin, GPIO_PIN_SET)
#define GD5F_WP_HIGH() HAL_GPIO_WritePin(GD_WP_GPIO_Port, GD_WP_Pin, GPIO_PIN_SET)
#define GD5F_HOLD_HIGH() HAL_GPIO_WritePin(GD_HOLD_GPIO_Port, GD_HOLD_Pin, GPIO_PIN_SET)
/* ======================== 函数声明 ======================== */
/*
* 函数功能:初始化 GD5F2GQ5UE读 ID + 使能 ECC + 解除块保护)
* 入口参数:无
* 返回值0 - 成功,其他 - 错误码
* 限定条件SPI1 和相关 GPIO 已由 CubeMX 初始化完成
* 函数说明1. 发送复位命令并等待完成
* 2. 读取芯片 ID 并校验
* 3. 使能内部 ECC (B0h bit4)
* 4. 解除所有块保护 (A0h = 0x00)
*/
int gd5f2gq5ue_init(void);
/*
* 函数功能:读取芯片 IDMID + DID
* 入口参数mid - 制造商 ID 输出指针 uint8_t* 不为 NULL
* did - 设备 ID 输出指针 uint8_t* 不为 NULL
* 返回值0 - 成功
* 限定条件SPI 已初始化
* 函数说明:发送 9Fh 命令后接收1个 dummy + MID + DID
*/
int gd5f2gq5ue_read_id(uint8_t *p_mid, uint8_t *p_did);
/*
* 函数功能:从 NAND 读取数据(支持跨页)
* 入口参数offset - 起始字节偏移 long 0 - GD5F_TOTAL_SIZE-1
* buf - 数据缓冲区 uint8_t* 不为 NULL
* size - 读取字节数 size_t > 0
* 返回值0 - 成功,其他 - 错误码
* 限定条件gd5f2gq5ue_init() 已成功调用
* 函数说明:自动处理跨页读取,每次读取不超过当前页剩余空间
*/
int gd5f2gq5ue_read(long offset, uint8_t *buf, size_t size);
/*
* 函数功能:向 NAND 写入数据(支持跨页)
* 入口参数offset - 起始字节偏移 long 0 - GD5F_TOTAL_SIZE-1
* buf - 数据缓冲区 uint8_t* 不为 NULL
* size - 写入字节数 size_t > 0
* 返回值0 - 成功,其他 - 错误码
* 限定条件gd5f2gq5ue_init() 已成功调用,目标区域已擦除
* 函数说明:自动处理跨页写入,每次写入不超过当前页剩余空间
*/
int gd5f2gq5ue_write(long offset, const uint8_t *buf, size_t size);
/*
* 函数功能:擦除块(按块擦除,最小单位 128KB
* 入口参数offset - 起始字节偏移 long 必须 GD5F_BLOCK_SIZE 对齐
* size - 擦除字节数 size_t 必须 GD5F_BLOCK_SIZE 整数倍
* 返回值0 - 成功,其他 - 错误码
* 限定条件gd5f2gq5ue_init() 已成功调用
* 函数说明擦除操作以块为单位offset 和 size 必须块对齐
*/
int gd5f2gq5ue_erase(long offset, size_t size);
/*
* 函数功能:复位芯片
* 入口参数:无
* 返回值0 - 成功
* 限定条件SPI 已初始化
* 函数说明:发送 FFh 复位命令后等待 5ms
*/
int gd5f2gq5ue_reset(void);
/*
* 函数功能:查询块是否坏块
* 入口参数block - 块编号 uint32_t 0 ~ GD5F_TOTAL_BLOCKS-1
* 返回值0 - 好块1 - 坏块
* 限定条件gd5f2gq5ue_init() 已成功调用
* 函数说明:通过 BBTBad Block Table查询BBT 在 init 阶段 ECC 使能前扫描构建
*/
int gd5f2gq5ue_is_block_bad(uint32_t block);
/*
* 函数功能:标记块为坏块
* 入口参数block - 块编号 uint32_t 0 ~ GD5F_TOTAL_BLOCKS-1
* 返回值:无
* 限定条件gd5f2gq5ue_init() 已成功调用
* 函数说明:更新 BBT并尝试物理标记该块最后一页 spare byte 0 为 0x00
*/
void gd5f2gq5ue_mark_block_bad(uint32_t block);
/* ==================== SPI 原语FTL 共享) ==================== */
int gd5f_wait_busy(uint32_t timeout_ms);
int gd5f_write_enable(void);
int gd5f_read_status(uint8_t *p_status);
int gd5f_page_read(uint32_t page_addr);
int gd5f_read_from_cache(uint16_t column, uint8_t *p_buf, size_t size);
int gd5f_program_load(uint16_t column, const uint8_t *p_buf, size_t size);
int gd5f_program_exec(uint32_t page_addr);
int gd5f_block_erase(uint32_t block_addr);
int gd5f_check_ecc(void);
#ifdef __cplusplus
}
#endif
#endif /* __GD5F2GQ5UE_H */