网络通,测试flash
This commit is contained in:
67
AGENTS.md
Normal file
67
AGENTS.md
Normal file
@@ -0,0 +1,67 @@
|
||||
# STM32F4-Base
|
||||
|
||||
## 项目概述
|
||||
|
||||
STM32F407ZGTx (Cortex-M4 FPU) 基础固件项目,集成 CH395F 以太网控制器 SPI 驱动(CH395F 自带 MAC+PHY 及 TCP/IP 协议栈固件)。
|
||||
|
||||
## 关键文件
|
||||
|
||||
| 路径 | 说明 |
|
||||
|---|---|
|
||||
| `Src/main.c` | 程序入口,初始化序列及主循环 |
|
||||
| `Src/ch395f.c` / `Inc/ch395f.h` | CH395F 以太网芯片 SPI 驱动(核心自定义代码) |
|
||||
| `MDK-ARM/STM32F407-Demo.uvprojx` | Keil MDK 项目文件 |
|
||||
| `STM32F407-Demo.ioc` | STM32CubeMX 项目源文件 |
|
||||
|
||||
## 构建
|
||||
|
||||
仅支持 Keil MDK-ARM v5 (ARMCC)。打开 `MDK-ARM/STM32F407-Demo.uvprojx` 编译。
|
||||
|
||||
- 编译器:ARMCC V5.06 update 7
|
||||
- 优化等级:`-O4` (项目级),`spi.c`/`usart.c` / HAL 源文件使用 `-O0`
|
||||
- C 标准:C99
|
||||
- 全局宏定义:`USE_HAL_DRIVER, STM32F407xx`
|
||||
|
||||
## 硬件配置
|
||||
|
||||
- **主频:** HSE 25MHz → PLL 168MHz (4/168/2)
|
||||
- **6 个 LED:** PC4, PC5, PB1, PB2, PF11, PF12(低电平点亮)
|
||||
- **CH395F:** SPI2 (PB12 CS, PB13 SCK, PB14 SDO, PB15 SDI)
|
||||
- **USART1:** PA9 TX, PA10 RX (115200bps)
|
||||
|
||||
## 启动顺序
|
||||
|
||||
```
|
||||
HAL_Init() → SystemClock_Config() → MX_GPIO_Init() → MX_USART1_UART_Init() → MX_SPI2_Init() → ch395f_reset() → ch395f_init()
|
||||
```
|
||||
|
||||
## 代码规范
|
||||
|
||||
参考 `嵌入式C语言代码规范(V1.0).md`,关键要点:
|
||||
|
||||
- 缩进:4 空格,禁止 Tab
|
||||
- 命名:小写字母+下划线;全局变量 `g_` 前缀,静态 `s_`,指针 `p_`,数组 `a_`
|
||||
- 函数注释块需包含:函数功能、入口参数、返回值、限定条件、函数说明
|
||||
- 大括号:K&R 风格(左大括号不换行)
|
||||
|
||||
## 注意
|
||||
|
||||
- `Inc/` 和 `Src/` 中 CubeMX 生成的文件(gpio, spi, usart, stm32f4xx_it, main 的骨架)带有 `USER CODE BEGIN`/`END` 标记,自定义代码应写在这些区域之间以免被 CubeMX 重新生成时覆盖
|
||||
- `ch395f.c`/`ch395f.h` 为纯手工代码,不受 CubeMX 保护
|
||||
- 每次 SPI 事务需调用 `ch395f_spi_begin()` / `ch395f_spi_end()` 包裹
|
||||
- CH395F 命令执行时序参考 `ch395f.h` 中命令码注释及 `CH395F.md`
|
||||
|
||||
## 已知问题
|
||||
|
||||
### CH395F 与 RTL8305NBI 自动协商不兼容
|
||||
|
||||
CH395F 与 RTL8305NBI-CG 直连(经网络变压器)时,自动协商始终失败(返回 `PHY_DISCONN`),但强制 100M 全双工工作正常。强制 10M 全双工同样失败。
|
||||
|
||||
**诊断结果:**
|
||||
- Auto-Neg: `0x01 (DISCONNECTED)`
|
||||
- Force 100M-FULL: `0x08 (LINK OK)`
|
||||
- Force 10M-FULL: `0x01 (DISCONNECTED)`
|
||||
|
||||
**解决方案:** 初始化协议栈后调用 `ch395f_set_phy(CH395F_PHY_100M_FULL)` 跳过自动协商。
|
||||
|
||||
**推测根因:** 不同厂家 PHY 直连时的自动协商实现差异(CH395F WCH 固件 vs RTL8305NBI Realtek 硬件),物理层正常。
|
||||
@@ -915,4 +915,4 @@ uint8_t ch395f_get_sock_int_status(uint8_t sock)
|
||||
ch395f_spi_end();
|
||||
|
||||
return status;
|
||||
}
|
||||
}
|
||||
@@ -492,4 +492,4 @@ uint8_t ch395f_get_sock_int_status(uint8_t sock);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __CH395F_H */
|
||||
#endif /* __CH395F_H */
|
||||
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 */
|
||||
1843
GD5F2GQ5UExxG.md
Normal file
1843
GD5F2GQ5UExxG.md
Normal file
File diff suppressed because one or more lines are too long
12
Inc/main.h
12
Inc/main.h
@@ -81,6 +81,18 @@ void Error_Handler(void);
|
||||
#define ST_TX0_GPIO_Port GPIOA
|
||||
#define ST_RX0_Pin GPIO_PIN_10
|
||||
#define ST_RX0_GPIO_Port GPIOA
|
||||
#define GD_SCLK_Pin GPIO_PIN_3
|
||||
#define GD_SCLK_GPIO_Port GPIOB
|
||||
#define GD_SO_Pin GPIO_PIN_4
|
||||
#define GD_SO_GPIO_Port GPIOB
|
||||
#define GD_SI_Pin GPIO_PIN_5
|
||||
#define GD_SI_GPIO_Port GPIOB
|
||||
#define GD_WP_Pin GPIO_PIN_8
|
||||
#define GD_WP_GPIO_Port GPIOB
|
||||
#define GD_CS_Pin GPIO_PIN_0
|
||||
#define GD_CS_GPIO_Port GPIOE
|
||||
#define GD_HOLD_Pin GPIO_PIN_1
|
||||
#define GD_HOLD_GPIO_Port GPIOE
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
|
||||
@@ -32,12 +32,15 @@ extern "C" {
|
||||
|
||||
/* USER CODE END Includes */
|
||||
|
||||
extern SPI_HandleTypeDef hspi1;
|
||||
|
||||
extern SPI_HandleTypeDef hspi2;
|
||||
|
||||
/* USER CODE BEGIN Private defines */
|
||||
|
||||
/* USER CODE END Private defines */
|
||||
|
||||
void MX_SPI1_Init(void);
|
||||
void MX_SPI2_Init(void);
|
||||
|
||||
/* USER CODE BEGIN Prototypes */
|
||||
|
||||
1
Lib/FlashDB
Submodule
1
Lib/FlashDB
Submodule
Submodule Lib/FlashDB added at 8236571f6e
1
Lib/fal
Submodule
1
Lib/fal
Submodule
Submodule Lib/fal added at aa02112186
@@ -340,7 +340,7 @@
|
||||
<MiscControls></MiscControls>
|
||||
<Define>USE_HAL_DRIVER,STM32F407xx</Define>
|
||||
<Undefine></Undefine>
|
||||
<IncludePath>../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include</IncludePath>
|
||||
<IncludePath>../Inc;../Drivers/STM32F4xx_HAL_Driver/Inc;../Drivers/STM32F4xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32F4xx/Include;../Drivers/CMSIS/Include;../Drivers/BSP/CH395F;../Drivers/BSP/GD5F2GQ5UE;../Lib/FlashDB/port/fal/inc;../Lib/FlashDB/inc</IncludePath>
|
||||
</VariousControls>
|
||||
</Cads>
|
||||
<Aads>
|
||||
@@ -516,11 +516,6 @@
|
||||
</FileArmAds>
|
||||
</FileOption>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>ch395f.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>../Src/ch395f.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>stm32f4xx_it.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
@@ -725,6 +720,66 @@
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>Drivers/BSP</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>ch395f.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Drivers\BSP\CH395F\ch395f.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>fal_flash_gd5f2gq5ue.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Drivers\BSP\GD5F2GQ5UE\fal_flash_gd5f2gq5ue.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>gd5f2gq5ue.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Drivers\BSP\GD5F2GQ5UE\gd5f2gq5ue.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>lib/FlashDB</GroupName>
|
||||
<Files>
|
||||
<File>
|
||||
<FileName>fdb.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Lib\FlashDB\src\fdb.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>fdb_kvdb.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Lib\FlashDB\src\fdb_kvdb.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>fdb_tsdb.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Lib\FlashDB\src\fdb_tsdb.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>fdb_utils.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Lib\FlashDB\src\fdb_utils.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>fal.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Lib\FlashDB\port\fal\src\fal.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>fal_flash.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Lib\FlashDB\port\fal\src\fal_flash.c</FilePath>
|
||||
</File>
|
||||
<File>
|
||||
<FileName>fal_partition.c</FileName>
|
||||
<FileType>1</FileType>
|
||||
<FilePath>..\Lib\FlashDB\port\fal\src\fal_partition.c</FilePath>
|
||||
</File>
|
||||
</Files>
|
||||
</Group>
|
||||
<Group>
|
||||
<GroupName>::CMSIS</GroupName>
|
||||
</Group>
|
||||
@@ -745,4 +800,13 @@
|
||||
<files/>
|
||||
</RTE>
|
||||
|
||||
<LayerInfo>
|
||||
<Layers>
|
||||
<Layer>
|
||||
<LayName>STM32F407-Demo</LayName>
|
||||
<LayPrjMark>1</LayPrjMark>
|
||||
</Layer>
|
||||
</Layers>
|
||||
</LayerInfo>
|
||||
|
||||
</Project>
|
||||
|
||||
1549
RTL8305NBI-CG.md
Normal file
1549
RTL8305NBI-CG.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,11 @@ Mcu.CPN=STM32F407ZGT6
|
||||
Mcu.Family=STM32F4
|
||||
Mcu.IP0=NVIC
|
||||
Mcu.IP1=RCC
|
||||
Mcu.IP2=SPI2
|
||||
Mcu.IP3=SYS
|
||||
Mcu.IP4=USART1
|
||||
Mcu.IPNb=5
|
||||
Mcu.IP2=SPI1
|
||||
Mcu.IP3=SPI2
|
||||
Mcu.IP4=SYS
|
||||
Mcu.IP5=USART1
|
||||
Mcu.IPNb=6
|
||||
Mcu.Name=STM32F407Z(E-G)Tx
|
||||
Mcu.Package=LQFP144
|
||||
Mcu.Pin0=PH0-OSC_IN
|
||||
@@ -23,8 +24,14 @@ Mcu.Pin12=PA9
|
||||
Mcu.Pin13=PA10
|
||||
Mcu.Pin14=PA13
|
||||
Mcu.Pin15=PA14
|
||||
Mcu.Pin16=VP_SYS_VS_Systick
|
||||
Mcu.Pin16=PB3
|
||||
Mcu.Pin17=PB4
|
||||
Mcu.Pin18=PB5
|
||||
Mcu.Pin19=PB8
|
||||
Mcu.Pin2=PC4
|
||||
Mcu.Pin20=PE0
|
||||
Mcu.Pin21=PE1
|
||||
Mcu.Pin22=VP_SYS_VS_Systick
|
||||
Mcu.Pin3=PC5
|
||||
Mcu.Pin4=PB1
|
||||
Mcu.Pin5=PB2
|
||||
@@ -32,7 +39,7 @@ Mcu.Pin6=PF11
|
||||
Mcu.Pin7=PF12
|
||||
Mcu.Pin8=PB12
|
||||
Mcu.Pin9=PB13
|
||||
Mcu.PinsNb=17
|
||||
Mcu.PinsNb=23
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F407ZGTx
|
||||
@@ -99,6 +106,31 @@ PB2.GPIO_Speed=GPIO_SPEED_FREQ_HIGH
|
||||
PB2.Locked=true
|
||||
PB2.PinState=GPIO_PIN_SET
|
||||
PB2.Signal=GPIO_Output
|
||||
PB3.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||
PB3.GPIO_Label=GD_SCLK
|
||||
PB3.GPIO_PuPd=GPIO_PULLUP
|
||||
PB3.Locked=true
|
||||
PB3.Mode=Full_Duplex_Master
|
||||
PB3.Signal=SPI1_SCK
|
||||
PB4.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||
PB4.GPIO_Label=GD_SO
|
||||
PB4.GPIO_PuPd=GPIO_PULLUP
|
||||
PB4.Locked=true
|
||||
PB4.Mode=Full_Duplex_Master
|
||||
PB4.Signal=SPI1_MISO
|
||||
PB5.GPIOParameters=GPIO_PuPd,GPIO_Label
|
||||
PB5.GPIO_Label=GD_SI
|
||||
PB5.GPIO_PuPd=GPIO_PULLUP
|
||||
PB5.Locked=true
|
||||
PB5.Mode=Full_Duplex_Master
|
||||
PB5.Signal=SPI1_MOSI
|
||||
PB8.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PB8.GPIO_Label=GD_WP
|
||||
PB8.GPIO_PuPd=GPIO_PULLUP
|
||||
PB8.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PB8.Locked=true
|
||||
PB8.PinState=GPIO_PIN_SET
|
||||
PB8.Signal=GPIO_Output
|
||||
PC4.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PC4.GPIO_Label=LED1
|
||||
PC4.GPIO_PuPd=GPIO_PULLUP
|
||||
@@ -121,6 +153,20 @@ PCC.PartNumber=STM32F407ZGTx
|
||||
PCC.Series=STM32F4
|
||||
PCC.Temperature=25
|
||||
PCC.Vdd=3.3
|
||||
PE0.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PE0.GPIO_Label=GD_CS
|
||||
PE0.GPIO_PuPd=GPIO_PULLUP
|
||||
PE0.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PE0.Locked=true
|
||||
PE0.PinState=GPIO_PIN_SET
|
||||
PE0.Signal=GPIO_Output
|
||||
PE1.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PE1.GPIO_Label=GD_HOLD
|
||||
PE1.GPIO_PuPd=GPIO_PULLUP
|
||||
PE1.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||
PE1.Locked=true
|
||||
PE1.PinState=GPIO_PIN_SET
|
||||
PE1.Signal=GPIO_Output
|
||||
PF11.GPIOParameters=GPIO_Speed,PinState,GPIO_PuPd,GPIO_Label
|
||||
PF11.GPIO_Label=LED5
|
||||
PF11.GPIO_PuPd=GPIO_PULLUP
|
||||
@@ -172,7 +218,7 @@ ProjectManager.ToolChainLocation=
|
||||
ProjectManager.UAScriptAfterPath=
|
||||
ProjectManager.UAScriptBeforePath=
|
||||
ProjectManager.UnderRoot=false
|
||||
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_SPI2_Init-SPI2-false-HAL-true
|
||||
ProjectManager.functionlistsort=1-SystemClock_Config-RCC-false-HAL-false,2-MX_GPIO_Init-GPIO-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_SPI2_Init-SPI2-false-HAL-true,5-MX_SPI1_Init-SPI1-false-HAL-true
|
||||
RCC.48MHZClocksFreq_Value=84000000
|
||||
RCC.AHBFreq_Value=168000000
|
||||
RCC.APB1CLKDivider=RCC_HCLK_DIV4
|
||||
@@ -206,6 +252,11 @@ RCC.VCOI2SOutputFreq_Value=384000000
|
||||
RCC.VCOInputFreq_Value=2000000
|
||||
RCC.VCOOutputFreq_Value=336000000
|
||||
RCC.VcooutputI2S=192000000
|
||||
SPI1.CalculateBaudRate=42.0 MBits/s
|
||||
SPI1.Direction=SPI_DIRECTION_2LINES
|
||||
SPI1.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
|
||||
SPI1.Mode=SPI_MODE_MASTER
|
||||
SPI1.VirtualType=VM_MASTER
|
||||
SPI2.CalculateBaudRate=21.0 MBits/s
|
||||
SPI2.Direction=SPI_DIRECTION_2LINES
|
||||
SPI2.IPParameters=VirtualType,Mode,Direction,CalculateBaudRate
|
||||
|
||||
20
Src/gpio.c
20
Src/gpio.c
@@ -50,16 +50,20 @@ void MX_GPIO_Init(void)
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOF_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOC, LED1_Pin|LED2_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOB, LED3_Pin|LED4_Pin|CH395_SCS_Pin, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOB, LED3_Pin|LED4_Pin|CH395_SCS_Pin|GD_WP_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOF, LED5_Pin|LED6_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pin Output Level */
|
||||
HAL_GPIO_WritePin(GPIOE, GD_CS_Pin|GD_HOLD_Pin, GPIO_PIN_SET);
|
||||
|
||||
/*Configure GPIO pins : LED1_Pin LED2_Pin */
|
||||
GPIO_InitStruct.Pin = LED1_Pin|LED2_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
@@ -88,6 +92,20 @@ void MX_GPIO_Init(void)
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(CH395_SCS_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pin : GD_WP_Pin */
|
||||
GPIO_InitStruct.Pin = GD_WP_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
HAL_GPIO_Init(GD_WP_GPIO_Port, &GPIO_InitStruct);
|
||||
|
||||
/*Configure GPIO pins : GD_CS_Pin GD_HOLD_Pin */
|
||||
GPIO_InitStruct.Pin = GD_CS_Pin|GD_HOLD_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 2 */
|
||||
|
||||
95
Src/main.c
95
Src/main.c
@@ -27,6 +27,8 @@
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "ch395f.h"
|
||||
#include "gd5f2gq5ue.h"
|
||||
#include "flashdb.h"
|
||||
/* USER CODE END Includes */
|
||||
|
||||
/* Private typedef -----------------------------------------------------------*/
|
||||
@@ -92,10 +94,93 @@ int main(void)
|
||||
MX_GPIO_Init();
|
||||
MX_USART1_UART_Init();
|
||||
MX_SPI2_Init();
|
||||
MX_SPI1_Init();
|
||||
/* USER CODE BEGIN 2 */
|
||||
/* CH395F 初始化 */
|
||||
ch395f_reset();
|
||||
ch395f_init();
|
||||
char dbg[64];
|
||||
uint8_t mac[6];
|
||||
|
||||
ch395f_reset();
|
||||
|
||||
/* [1/5] SPI 通信检测 */
|
||||
sprintf(dbg, "[1/5] CH395F %s\r\n",
|
||||
(ch395f_check_exist() == CH395F_STATUS_OK) ? "detected" : "ERROR: not detected");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* [2/5] 芯片版本 */
|
||||
sprintf(dbg, "[2/5] CH395F version: 0x%02X\r\n", ch395f_get_version());
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* 配置 IP/网关/掩码 */
|
||||
{
|
||||
uint8_t ip[4] = {192, 168, 1, 100};
|
||||
uint8_t gw[4] = {192, 168, 1, 1};
|
||||
uint8_t mask[4] = {255, 255, 255, 0};
|
||||
ch395f_set_ip_addr(ip);
|
||||
ch395f_set_gwip_addr(gw);
|
||||
ch395f_set_mask_addr(mask);
|
||||
}
|
||||
|
||||
/* [3/5] 协议栈初始化 */
|
||||
sprintf(dbg, "[3/5] Protocol stack init %s\r\n",
|
||||
(ch395f_init() == CH395F_STATUS_OK) ? "OK" : "ERROR");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* [4/5] MAC 地址 */
|
||||
ch395f_get_mac_addr(mac);
|
||||
sprintf(dbg, "[4/5] MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* [5/5] 强制 100M 全双工后检测 PHY */
|
||||
ch395f_set_phy(CH395F_PHY_100M_FULL);
|
||||
HAL_Delay(3000);
|
||||
{
|
||||
uint8_t s = ch395f_get_phy_status();
|
||||
const char *desc = (s == CH395F_PHY_DISCONN) ? "DISCONNECTED" :
|
||||
(s == CH395F_PHY_100M_FULL) ? "100M FULL" :
|
||||
(s == CH395F_PHY_100M_HALF) ? "100M HALF" :
|
||||
(s == CH395F_PHY_10M_FULL) ? "10M FULL" :
|
||||
(s == CH395F_PHY_10M_HALF) ? "10M HALF" : "RESERVED";
|
||||
sprintf(dbg, "[5/5] PHY: 0x%02X (%s)\r\n", s, desc);
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
}
|
||||
|
||||
/* ===================== FlashDB KVDB 测试 ===================== */
|
||||
{
|
||||
uint8_t gd_mid, gd_did;
|
||||
int ret;
|
||||
|
||||
/* 检测 GD5F2GQ5UE */
|
||||
ret = gd5f2gq5ue_read_id(&gd_mid, &gd_did);
|
||||
sprintf(dbg, "[GD5F] ID: MID=0x%02X DID=0x%02X %s\r\n",
|
||||
gd_mid, gd_did,
|
||||
(ret == GD5F_OK && gd_mid == 0xC8 && gd_did == 0x52) ? "OK" : "FAIL");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
/* 初始化 FlashDB KVDB */
|
||||
{
|
||||
static struct fdb_kvdb kvdb;
|
||||
ret = fdb_kvdb_init(&kvdb, "db", "fdb_kvdb1", NULL, NULL);
|
||||
sprintf(dbg, "[FlashDB] KVDB init: %s\r\n",
|
||||
(ret == FDB_NO_ERR) ? "OK" : "FAIL");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
|
||||
if (ret == FDB_NO_ERR) {
|
||||
/* 写入测试 KV */
|
||||
fdb_kv_set(&kvdb, "test_key", "hello_flashdb");
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)"[FlashDB] KV set OK\r\n", 21, 1000);
|
||||
|
||||
/* 读取测试 KV */
|
||||
char *val = fdb_kv_get(&kvdb, "test_key");
|
||||
if (val) {
|
||||
sprintf(dbg, "[FlashDB] KV get: %s\r\n", val);
|
||||
} else {
|
||||
sprintf(dbg, "[FlashDB] KV get: NULL\r\n");
|
||||
}
|
||||
HAL_UART_Transmit(&huart1, (uint8_t*)dbg, strlen(dbg), 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* USER CODE END 2 */
|
||||
|
||||
/* Infinite loop */
|
||||
@@ -111,7 +196,7 @@ int main(void)
|
||||
HAL_GPIO_TogglePin(LED4_GPIO_Port, LED4_Pin);
|
||||
HAL_GPIO_TogglePin(LED5_GPIO_Port, LED5_Pin);
|
||||
HAL_GPIO_TogglePin(LED6_GPIO_Port, LED6_Pin);
|
||||
HAL_UART_Transmit(&huart1, str, strlen((char*)str), 1000);
|
||||
//HAL_UART_Transmit(&huart1, str, strlen((char*)str), 1000);
|
||||
HAL_Delay(500);
|
||||
}
|
||||
/* USER CODE END 3 */
|
||||
@@ -195,4 +280,4 @@ void assert_failed(uint8_t *file, uint32_t line)
|
||||
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
|
||||
/* USER CODE END 6 */
|
||||
}
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
#endif /* USE_FULL_ASSERT */
|
||||
|
||||
87
Src/spi.c
87
Src/spi.c
@@ -24,8 +24,41 @@
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
SPI_HandleTypeDef hspi1;
|
||||
SPI_HandleTypeDef hspi2;
|
||||
|
||||
/* SPI1 init function */
|
||||
void MX_SPI1_Init(void)
|
||||
{
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 0 */
|
||||
|
||||
/* USER CODE END SPI1_Init 0 */
|
||||
|
||||
/* USER CODE BEGIN SPI1_Init 1 */
|
||||
|
||||
/* USER CODE END SPI1_Init 1 */
|
||||
hspi1.Instance = SPI1;
|
||||
hspi1.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi1.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi1.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi1.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
hspi1.Init.CRCPolynomial = 10;
|
||||
if (HAL_SPI_Init(&hspi1) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
/* USER CODE BEGIN SPI1_Init 2 */
|
||||
|
||||
/* USER CODE END SPI1_Init 2 */
|
||||
|
||||
}
|
||||
/* SPI2 init function */
|
||||
void MX_SPI2_Init(void)
|
||||
{
|
||||
@@ -41,10 +74,10 @@ void MX_SPI2_Init(void)
|
||||
hspi2.Init.Mode = SPI_MODE_MASTER;
|
||||
hspi2.Init.Direction = SPI_DIRECTION_2LINES;
|
||||
hspi2.Init.DataSize = SPI_DATASIZE_8BIT;
|
||||
hspi2.Init.CLKPolarity = SPI_POLARITY_HIGH;
|
||||
hspi2.Init.CLKPhase = SPI_PHASE_2EDGE;
|
||||
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
|
||||
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
|
||||
hspi2.Init.NSS = SPI_NSS_SOFT;
|
||||
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256;
|
||||
hspi2.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
|
||||
hspi2.Init.FirstBit = SPI_FIRSTBIT_MSB;
|
||||
hspi2.Init.TIMode = SPI_TIMODE_DISABLE;
|
||||
hspi2.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
|
||||
@@ -63,7 +96,32 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
|
||||
{
|
||||
|
||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
if(spiHandle->Instance==SPI2)
|
||||
if(spiHandle->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 0 */
|
||||
/* SPI1 clock enable */
|
||||
__HAL_RCC_SPI1_CLK_ENABLE();
|
||||
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
/**SPI1 GPIO Configuration
|
||||
PB3 ------> SPI1_SCK
|
||||
PB4 ------> SPI1_MISO
|
||||
PB5 ------> SPI1_MOSI
|
||||
*/
|
||||
GPIO_InitStruct.Pin = GD_SCLK_Pin|GD_SO_Pin|GD_SI_Pin;
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||
GPIO_InitStruct.Pull = GPIO_PULLUP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
||||
GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
|
||||
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspInit 1 */
|
||||
}
|
||||
else if(spiHandle->Instance==SPI2)
|
||||
{
|
||||
/* USER CODE BEGIN SPI2_MspInit 0 */
|
||||
|
||||
@@ -100,7 +158,26 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)
|
||||
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)
|
||||
{
|
||||
|
||||
if(spiHandle->Instance==SPI2)
|
||||
if(spiHandle->Instance==SPI1)
|
||||
{
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 0 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 0 */
|
||||
/* Peripheral clock disable */
|
||||
__HAL_RCC_SPI1_CLK_DISABLE();
|
||||
|
||||
/**SPI1 GPIO Configuration
|
||||
PB3 ------> SPI1_SCK
|
||||
PB4 ------> SPI1_MISO
|
||||
PB5 ------> SPI1_MOSI
|
||||
*/
|
||||
HAL_GPIO_DeInit(GPIOB, GD_SCLK_Pin|GD_SO_Pin|GD_SI_Pin);
|
||||
|
||||
/* USER CODE BEGIN SPI1_MspDeInit 1 */
|
||||
|
||||
/* USER CODE END SPI1_MspDeInit 1 */
|
||||
}
|
||||
else if(spiHandle->Instance==SPI2)
|
||||
{
|
||||
/* USER CODE BEGIN SPI2_MspDeInit 0 */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user