网络通,测试flash
This commit is contained in:
35
Drivers/BSP/GD5F2GQ5UE/fal_cfg.h
Normal file
35
Drivers/BSP/GD5F2GQ5UE/fal_cfg.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file fal_cfg.h
|
||||
* @brief FAL 配置:Flash 设备表 + 分区表
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _FAL_CFG_H_
|
||||
#define _FAL_CFG_H_
|
||||
|
||||
#define FAL_DEBUG 0
|
||||
|
||||
#define FAL_PART_HAS_TABLE_CFG
|
||||
|
||||
/* ===================== Flash 设备表 ===================== */
|
||||
extern const struct fal_flash_dev gd5f2gq5ue_flash;
|
||||
|
||||
#define FAL_FLASH_DEV_TABLE \
|
||||
{ \
|
||||
&gd5f2gq5ue_flash, \
|
||||
}
|
||||
|
||||
/* ===================== 分区表 ===================== */
|
||||
/* 分区名称 设备名称 偏移 大小 */
|
||||
/* KVDB: 64MB @ 0 */
|
||||
/* TSDB: 64MB @ 64MB */
|
||||
#ifdef FAL_PART_HAS_TABLE_CFG
|
||||
#define FAL_PART_TABLE \
|
||||
{ \
|
||||
{FAL_PART_MAGIC_WORD, "fdb_kvdb1", "gd5f2gq5ue", 0, 64*1024*1024, 0}, \
|
||||
{FAL_PART_MAGIC_WORD, "fdb_tsdb1", "gd5f2gq5ue", 64*1024*1024, 64*1024*1024, 0}, \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _FAL_CFG_H_ */
|
||||
47
Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c
Normal file
47
Drivers/BSP/GD5F2GQ5UE/fal_flash_gd5f2gq5ue.c
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file fal_flash_gd5f2gq5ue.c
|
||||
* @brief FAL 端口:GD5F2GQ5UE SPI NAND Flash 适配层
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "fal_def.h"
|
||||
#include "gd5f2gq5ue.h"
|
||||
|
||||
/* ===================== FAL Flash 设备操作函数 ===================== */
|
||||
|
||||
static int gd5f_fal_init(void)
|
||||
{
|
||||
return gd5f2gq5ue_init();
|
||||
}
|
||||
|
||||
static int gd5f_fal_read(long offset, uint8_t *buf, size_t size)
|
||||
{
|
||||
return gd5f2gq5ue_read(offset, buf, size);
|
||||
}
|
||||
|
||||
static int gd5f_fal_write(long offset, const uint8_t *buf, size_t size)
|
||||
{
|
||||
return gd5f2gq5ue_write(offset, buf, size);
|
||||
}
|
||||
|
||||
static int gd5f_fal_erase(long offset, size_t size)
|
||||
{
|
||||
return gd5f2gq5ue_erase(offset, size);
|
||||
}
|
||||
|
||||
/* ===================== FAL Flash 设备定义 ===================== */
|
||||
|
||||
const struct fal_flash_dev gd5f2gq5ue_flash = {
|
||||
.name = "gd5f2gq5ue",
|
||||
.addr = 0,
|
||||
.len = GD5F_TOTAL_SIZE, /* 256MB */
|
||||
.blk_size = GD5F_BLOCK_SIZE, /* 128KB */
|
||||
.ops = {
|
||||
.init = gd5f_fal_init,
|
||||
.read = gd5f_fal_read,
|
||||
.write = gd5f_fal_write,
|
||||
.erase = gd5f_fal_erase,
|
||||
},
|
||||
.write_gran = 8,
|
||||
};
|
||||
32
Drivers/BSP/GD5F2GQ5UE/fdb_cfg.h
Normal file
32
Drivers/BSP/GD5F2GQ5UE/fdb_cfg.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file fdb_cfg.h
|
||||
* @brief FlashDB 配置文件
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _FDB_CFG_H_
|
||||
#define _FDB_CFG_H_
|
||||
|
||||
/* 启用 KVDB(键值数据库) */
|
||||
#define FDB_USING_KVDB
|
||||
|
||||
#ifdef FDB_USING_KVDB
|
||||
/* 当 KVDB 版本号变化时自动更新到最新默认值 */
|
||||
/* #define FDB_KV_AUTO_UPDATE */
|
||||
#endif
|
||||
|
||||
/* 启用 TSDB(时序数据库) */
|
||||
#define FDB_USING_TSDB
|
||||
|
||||
/* 使用 FAL 存储模式(非文件模式) */
|
||||
#define FDB_USING_FAL_MODE
|
||||
|
||||
/* Flash 写入粒度(单位:bit)
|
||||
* STM32F4 = 8(字节可编程) */
|
||||
#define FDB_WRITE_GRAN 8
|
||||
|
||||
/* 调试输出 */
|
||||
#define FDB_DEBUG_ENABLE
|
||||
|
||||
#endif /* _FDB_CFG_H_ */
|
||||
367
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c
Normal file
367
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.c
Normal file
@@ -0,0 +1,367 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file gd5f2gq5ue.c
|
||||
* @brief GD5F2GQ5UE SPI NAND Flash 驱动实现
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "gd5f2gq5ue.h"
|
||||
#include <string.h>
|
||||
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
|
||||
/* ===================== 内部辅助函数 ===================== */
|
||||
|
||||
/**
|
||||
* @brief SPI 发送/接收单字节
|
||||
*/
|
||||
static uint8_t gd5f_spi_xfer(uint8_t tx)
|
||||
{
|
||||
uint8_t rx;
|
||||
HAL_SPI_TransmitReceive(&hspi1, &tx, &rx, 1, 100);
|
||||
return rx;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI 发送缓冲区
|
||||
*/
|
||||
static void gd5f_spi_tx(const uint8_t *buf, size_t len)
|
||||
{
|
||||
HAL_SPI_Transmit(&hspi1, (uint8_t *)buf, len, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SPI 接收缓冲区
|
||||
*/
|
||||
static void gd5f_spi_rx(uint8_t *buf, size_t len)
|
||||
{
|
||||
HAL_SPI_Receive(&hspi1, buf, len, 100);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 等待操作完成(OIP 位清零)
|
||||
* @param timeout_ms: 超时时间(毫秒)
|
||||
* @retval GD5F_OK 成功, GD5F_BUSY_TIMEOUT 超时
|
||||
*/
|
||||
static int gd5f_wait_busy(uint32_t timeout_ms)
|
||||
{
|
||||
uint8_t cmd = GD5F_CMD_GET_FEATURE;
|
||||
uint8_t addr = GD5F_REG_STATUS;
|
||||
uint8_t status;
|
||||
uint32_t tickstart = HAL_GetTick();
|
||||
|
||||
while (1) {
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(&cmd, 1);
|
||||
gd5f_spi_tx(&addr, 1);
|
||||
gd5f_spi_rx(&status, 1);
|
||||
GD5F_CS_HIGH();
|
||||
|
||||
if ((status & GD5F_STATUS_OIP) == 0) {
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
if ((HAL_GetTick() - tickstart) >= timeout_ms) {
|
||||
return GD5F_BUSY_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 写使能
|
||||
*/
|
||||
static int gd5f_write_enable(void)
|
||||
{
|
||||
uint8_t cmd = GD5F_CMD_WRITE_ENABLE;
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(&cmd, 1);
|
||||
GD5F_CS_HIGH();
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取状态寄存器
|
||||
*/
|
||||
static int gd5f_read_status(uint8_t *status)
|
||||
{
|
||||
uint8_t cmd = GD5F_CMD_GET_FEATURE;
|
||||
uint8_t addr = GD5F_REG_STATUS;
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(&cmd, 1);
|
||||
gd5f_spi_tx(&addr, 1);
|
||||
gd5f_spi_rx(status, 1);
|
||||
GD5F_CS_HIGH();
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 页读取到缓存(Page Read to Cache)
|
||||
* @param page_addr: 页地址(行地址,包含 block + page)
|
||||
*/
|
||||
static int gd5f_page_read(uint32_t page_addr)
|
||||
{
|
||||
uint8_t cmd[4];
|
||||
cmd[0] = GD5F_CMD_PAGE_READ;
|
||||
cmd[1] = (page_addr >> 16) & 0xFF;
|
||||
cmd[2] = (page_addr >> 8) & 0xFF;
|
||||
cmd[3] = page_addr & 0xFF;
|
||||
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(cmd, 4);
|
||||
GD5F_CS_HIGH();
|
||||
|
||||
return gd5f_wait_busy(100);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 从缓存读取数据(Read from Cache)
|
||||
* @param column: 列地址(页内偏移)
|
||||
* @param buf: 数据缓冲区
|
||||
* @param size: 读取字节数
|
||||
*/
|
||||
static int gd5f_read_from_cache(uint16_t column, uint8_t *buf, size_t size)
|
||||
{
|
||||
uint8_t cmd[5];
|
||||
cmd[0] = GD5F_CMD_READ_FROM_CACHE;
|
||||
cmd[1] = (column >> 8) & 0xFF;
|
||||
cmd[2] = column & 0xFF;
|
||||
cmd[3] = 0x00; /* dummy byte */
|
||||
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(cmd, 4);
|
||||
gd5f_spi_rx(buf, size);
|
||||
GD5F_CS_HIGH();
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 页编程(从缓存写入阵列)
|
||||
* @param page_addr: 页地址
|
||||
* @param column: 列地址
|
||||
* @param buf: 数据缓冲区
|
||||
* @param size: 写入字节数
|
||||
*/
|
||||
static int gd5f_page_program(uint32_t page_addr, uint16_t column, const uint8_t *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
uint8_t cmd[4];
|
||||
|
||||
/* 1. 写使能 */
|
||||
gd5f_write_enable();
|
||||
|
||||
/* 2. 数据加载到缓存 (Program Load) */
|
||||
cmd[0] = GD5F_CMD_PROGRAM_LOAD;
|
||||
cmd[1] = (column >> 8) & 0xFF;
|
||||
cmd[2] = column & 0xFF;
|
||||
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(cmd, 3);
|
||||
gd5f_spi_tx(buf, size);
|
||||
GD5F_CS_HIGH();
|
||||
|
||||
/* 3. 编程执行 (Program Execute) */
|
||||
cmd[0] = GD5F_CMD_PROGRAM_EXEC;
|
||||
cmd[1] = (page_addr >> 16) & 0xFF;
|
||||
cmd[2] = (page_addr >> 8) & 0xFF;
|
||||
cmd[3] = page_addr & 0xFF;
|
||||
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(cmd, 4);
|
||||
GD5F_CS_HIGH();
|
||||
|
||||
/* 4. 等待完成 */
|
||||
ret = gd5f_wait_busy(1000);
|
||||
if (ret != GD5F_OK) return ret;
|
||||
|
||||
/* 5. 检查编程结果 */
|
||||
uint8_t status;
|
||||
gd5f_read_status(&status);
|
||||
if (status & GD5F_STATUS_P_FAIL) {
|
||||
/* 清除 P_FAIL:写使能 + 读状态 */
|
||||
gd5f_write_enable();
|
||||
return GD5F_PROGRAM_FAIL;
|
||||
}
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 块擦除
|
||||
* @param block_addr: 块地址 (0 ~ 2047)
|
||||
*/
|
||||
static int gd5f_block_erase(uint32_t block_addr)
|
||||
{
|
||||
int ret;
|
||||
uint8_t cmd[4];
|
||||
|
||||
/* 1. 写使能 */
|
||||
gd5f_write_enable();
|
||||
|
||||
/* 2. 块擦除命令 */
|
||||
cmd[0] = GD5F_CMD_BLOCK_ERASE;
|
||||
cmd[1] = (block_addr >> 8) & 0xFF;
|
||||
cmd[2] = block_addr & 0xFF;
|
||||
cmd[3] = 0x00;
|
||||
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(cmd, 4);
|
||||
GD5F_CS_HIGH();
|
||||
|
||||
/* 3. 等待完成(擦除较慢) */
|
||||
ret = gd5f_wait_busy(5000);
|
||||
if (ret != GD5F_OK) return ret;
|
||||
|
||||
/* 4. 检查擦除结果 */
|
||||
uint8_t status;
|
||||
gd5f_read_status(&status);
|
||||
if (status & GD5F_STATUS_E_FAIL) {
|
||||
gd5f_write_enable();
|
||||
return GD5F_ERASE_FAIL;
|
||||
}
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
/* ===================== 公共接口实现 ===================== */
|
||||
|
||||
int gd5f2gq5ue_init(void)
|
||||
{
|
||||
int ret;
|
||||
uint8_t mid, did;
|
||||
|
||||
/* 确保控制引脚处于非激活状态 */
|
||||
GD5F_CS_HIGH();
|
||||
GD5F_WP_HIGH();
|
||||
GD5F_HOLD_HIGH();
|
||||
|
||||
/* 小延时等待上电稳定 */
|
||||
HAL_Delay(10);
|
||||
|
||||
/* 复位芯片 */
|
||||
ret = gd5f2gq5ue_reset();
|
||||
if (ret != GD5F_OK) return ret;
|
||||
|
||||
HAL_Delay(5);
|
||||
|
||||
/* 读取 ID 验证通信 */
|
||||
ret = gd5f2gq5ue_read_id(&mid, &did);
|
||||
if (ret != GD5F_OK) return ret;
|
||||
|
||||
if (mid != GD5F_MANUFACTURER_ID || did != GD5F_DEVICE_ID) {
|
||||
return GD5F_ID_MISMATCH;
|
||||
}
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
int gd5f2gq5ue_read_id(uint8_t *mid, uint8_t *did)
|
||||
{
|
||||
uint8_t cmd = GD5F_CMD_READ_ID;
|
||||
uint8_t id_buf[3];
|
||||
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(&cmd, 1);
|
||||
gd5f_spi_rx(id_buf, 3); /* dummy + MID + DID */
|
||||
GD5F_CS_HIGH();
|
||||
|
||||
*mid = id_buf[1]; /* id_buf[0] = dummy */
|
||||
*did = id_buf[2];
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
int gd5f2gq5ue_read(long offset, uint8_t *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while (size > 0) {
|
||||
/* 计算页地址和列偏移 */
|
||||
uint32_t page_addr = offset / GD5F_PAGE_SIZE;
|
||||
uint16_t column = offset % GD5F_PAGE_SIZE;
|
||||
|
||||
/* 本次读取字节数(不超过当前页剩余空间) */
|
||||
size_t bytes = GD5F_PAGE_SIZE - column;
|
||||
if (bytes > size) bytes = size;
|
||||
|
||||
/* Page Read to Cache */
|
||||
ret = gd5f_page_read(page_addr);
|
||||
if (ret != GD5F_OK) return ret;
|
||||
|
||||
/* Read from Cache */
|
||||
ret = gd5f_read_from_cache(column, buf, bytes);
|
||||
if (ret != GD5F_OK) return ret;
|
||||
|
||||
offset += bytes;
|
||||
buf += bytes;
|
||||
size -= bytes;
|
||||
}
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
int gd5f2gq5ue_write(long offset, const uint8_t *buf, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
while (size > 0) {
|
||||
/* 计算页地址和列偏移 */
|
||||
uint32_t page_addr = offset / GD5F_PAGE_SIZE;
|
||||
uint16_t column = offset % GD5F_PAGE_SIZE;
|
||||
|
||||
/* 本次写入字节数(不超过当前页剩余空间) */
|
||||
size_t bytes = GD5F_PAGE_SIZE - column;
|
||||
if (bytes > size) bytes = size;
|
||||
|
||||
/* 页编程 */
|
||||
ret = gd5f_page_program(page_addr, column, buf, bytes);
|
||||
if (ret != GD5F_OK) return ret;
|
||||
|
||||
offset += bytes;
|
||||
buf += bytes;
|
||||
size -= bytes;
|
||||
}
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
int gd5f2gq5ue_erase(long offset, size_t size)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* 擦除起始地址必须块对齐 */
|
||||
if (offset % GD5F_BLOCK_SIZE != 0) {
|
||||
return GD5F_ERROR;
|
||||
}
|
||||
|
||||
/* 擦除大小必须为块大小的整数倍 */
|
||||
if (size % GD5F_BLOCK_SIZE != 0) {
|
||||
return GD5F_ERROR;
|
||||
}
|
||||
|
||||
/* 逐块擦除 */
|
||||
while (size > 0) {
|
||||
uint32_t block_addr = offset / GD5F_BLOCK_SIZE;
|
||||
|
||||
ret = gd5f_block_erase(block_addr);
|
||||
if (ret != GD5F_OK) return ret;
|
||||
|
||||
offset += GD5F_BLOCK_SIZE;
|
||||
size -= GD5F_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
|
||||
int gd5f2gq5ue_reset(void)
|
||||
{
|
||||
uint8_t cmd = GD5F_CMD_RESET;
|
||||
|
||||
GD5F_CS_LOW();
|
||||
gd5f_spi_tx(&cmd, 1);
|
||||
GD5F_CS_HIGH();
|
||||
|
||||
HAL_Delay(5);
|
||||
|
||||
return GD5F_OK;
|
||||
}
|
||||
133
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h
Normal file
133
Drivers/BSP/GD5F2GQ5UE/gd5f2gq5ue.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file gd5f2gq5ue.h
|
||||
* @brief GD5F2GQ5UE SPI NAND Flash 驱动头文件
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __GD5F2GQ5UE_H
|
||||
#define __GD5F2GQ5UE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "main.h"
|
||||
#include "spi.h"
|
||||
|
||||
/* ===================== 硬件引脚定义 ===================== */
|
||||
#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)
|
||||
|
||||
/* ===================== 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 /* Fast Read, 1 dummy byte */
|
||||
#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_STATUS 0xC0
|
||||
#define GD5F_REG_PROTECT 0xA0
|
||||
#define GD5F_REG_FEATURE 0xB0
|
||||
#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_BIT4 (1 << 4)
|
||||
#define GD5F_STATUS_ECCS0 (1 << 5)
|
||||
#define GD5F_STATUS_ECCS1 (1 << 6)
|
||||
#define GD5F_STATUS_ECCSE0 (1 << 4) /* ECC 单 bit 错误低位 */
|
||||
#define GD5F_STATUS_ECCSE1 (1 << 5) /* ECC 单 bit 错误高位 */
|
||||
#define GD5F_STATUS_ECCSE2 (1 << 6) /* ECC 单 bit 错误高位 */
|
||||
|
||||
/* ===================== Feature 位定义 ===================== */
|
||||
#define GD5F_FEATURE_ECC_EN (1 << 4)
|
||||
#define GD5F_FEATURE_QE (1 << 0) /* Quad Enable, B0[0] */
|
||||
|
||||
/* ===================== 芯片参数 ===================== */
|
||||
#define GD5F_PAGE_SIZE 2048 /* 主数据区字节数 */
|
||||
#define GD5F_SPARE_SIZE 64 /* ECC 启用时 spare 区 */
|
||||
#define GD5F_TOTAL_PAGE_SIZE 2112 /* 2048 + 64 */
|
||||
#define GD5F_PAGES_PER_BLOCK 64
|
||||
#define GD5F_BLOCK_SIZE (GD5F_PAGES_PER_BLOCK * GD5F_PAGE_SIZE) /* 128KB */
|
||||
#define GD5F_TOTAL_BLOCKS 2048
|
||||
#define GD5F_TOTAL_SIZE (GD5F_TOTAL_BLOCKS * GD5F_BLOCK_SIZE) /* 256MB */
|
||||
|
||||
/* 制造商 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
|
||||
|
||||
/* ===================== 公共接口函数 ===================== */
|
||||
|
||||
/**
|
||||
* @brief 初始化 GD5F2GQ5UE(SPI + GPIO + 读 ID 验证)
|
||||
* @retval GD5F_OK 成功, 其他为错误码
|
||||
*/
|
||||
int gd5f2gq5ue_init(void);
|
||||
|
||||
/**
|
||||
* @brief 读取芯片 ID(MID + DID)
|
||||
* @param mid: 制造商 ID 输出指针
|
||||
* @param did: 设备 ID 输出指针
|
||||
* @retval GD5F_OK 成功
|
||||
*/
|
||||
int gd5f2gq5ue_read_id(uint8_t *mid, uint8_t *did);
|
||||
|
||||
/**
|
||||
* @brief 从 NAND 读取数据(支持跨页)
|
||||
* @param offset: 起始字节偏移(相对于 Flash 起始地址)
|
||||
* @param buf: 数据缓冲区
|
||||
* @param size: 读取字节数
|
||||
* @retval GD5F_OK 成功
|
||||
*/
|
||||
int gd5f2gq5ue_read(long offset, uint8_t *buf, size_t size);
|
||||
|
||||
/**
|
||||
* @brief 向 NAND 写入数据(支持跨页)
|
||||
* @param offset: 起始字节偏移
|
||||
* @param buf: 数据缓冲区
|
||||
* @param size: 写入字节数
|
||||
* @retval GD5F_OK 成功
|
||||
*/
|
||||
int gd5f2gq5ue_write(long offset, const uint8_t *buf, size_t size);
|
||||
|
||||
/**
|
||||
* @brief 擦除块(按块擦除,最小单位 128KB)
|
||||
* @param offset: 起始字节偏移(必须块对齐)
|
||||
* @param size: 擦除字节数(必须为块大小的整数倍)
|
||||
* @retval GD5F_OK 成功
|
||||
*/
|
||||
int gd5f2gq5ue_erase(long offset, size_t size);
|
||||
|
||||
/**
|
||||
* @brief 复位芯片
|
||||
* @retval GD5F_OK 成功
|
||||
*/
|
||||
int gd5f2gq5ue_reset(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GD5F2GQ5UE_H */
|
||||
Reference in New Issue
Block a user