117 lines
4.1 KiB
C
117 lines
4.1 KiB
C
#ifndef __W25Q64_H
|
||
#define __W25Q64_H
|
||
|
||
#include <stdint.h>
|
||
#include "main.h"
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
/* -------------------------------------------------
|
||
* W25Q64 外部 SPI Flash 驱动接口
|
||
* 硬件连接(软件 SPI,任意 GPIO):
|
||
* CS -> PB4
|
||
* CLK -> PB3
|
||
* DO -> PB5 (Flash 数据输出 / MCU 输入)
|
||
* DI -> PA15 (Flash 数据输入 / MCU 输出)
|
||
* ------------------------------------------------- */
|
||
|
||
#define W25Q64_FLASH_SIZE (8ul * 1024 * 1024) /* 8MB */
|
||
#define W25Q64_SECTOR_SIZE 4096u
|
||
#define W25Q64_BLOCK_SIZE 65536u
|
||
#define W25Q64_PAGE_SIZE 256u
|
||
|
||
#define W25Q64_JEDEC_ID 0xEF4017u /* W25Q64JV */
|
||
|
||
/* 忙等待超时:覆盖页编程/扇区擦除/64KB 块擦除最大耗时;整片擦除单独给足 */
|
||
#define W25Q64_BUSY_TIMEOUT_MS 5000u
|
||
#define W25Q64_CHIP_ERASE_TIMEOUT_MS 60000u
|
||
|
||
/* 命令字 */
|
||
#define W25Q64_CMD_WRITE_ENABLE 0x06u
|
||
#define W25Q64_CMD_WRITE_DISABLE 0x04u
|
||
#define W25Q64_CMD_READ_STATUS1 0x05u
|
||
#define W25Q64_CMD_READ_DATA 0x03u
|
||
#define W25Q64_CMD_PAGE_PROGRAM 0x02u
|
||
#define W25Q64_CMD_SECTOR_ERASE 0x20u
|
||
#define W25Q64_CMD_BLOCK_ERASE 0xD8u
|
||
#define W25Q64_CMD_CHIP_ERASE 0xC7u
|
||
#define W25Q64_CMD_READ_ID 0x9Fu
|
||
|
||
/* 外部 Flash 分区布局(每个区 256KB,足够放下 224KB 的 APP) */
|
||
#define W25Q64_SLOT_SIZE 0x40000u /* 256KB */
|
||
#define W25Q64_SLOT_BACKUP_ADDR 0x000000u /* 槽 A:旧版本 / 回退镜像 */
|
||
#define W25Q64_SLOT_NEW_ADDR 0x040000u /* 槽 B:新下载的固件 */
|
||
|
||
/* 信息区:两个独立的 4KB 扇区,双副本冗余,必须避开固件槽 B 的 0x040000~0x07FFFF */
|
||
#define W25Q64_INFO_SECTOR_A 0x080000u
|
||
#define W25Q64_INFO_SECTOR_B 0x081000u
|
||
#define W25Q64_INFO_MAGIC 0x5741544Fu /* 'WATO' */
|
||
|
||
/* OTA 状态 */
|
||
#define W25Q64_STATE_IDLE 0u
|
||
#define W25Q64_STATE_DOWNLOADED 1u
|
||
#define W25Q64_STATE_COPYING 2u
|
||
#define W25Q64_STATE_INSTALLED 3u
|
||
#define W25Q64_STATE_ROLLBACK 4u
|
||
|
||
#define W25Q64_MAX_TRIALS 3u
|
||
|
||
#pragma pack(push, 1)
|
||
typedef struct {
|
||
uint32_t magic; /* 0x5741544F */
|
||
uint32_t sequence; /* 写入序号,越大越新 */
|
||
uint16_t new_version; /* 新版本号 */
|
||
uint32_t new_size; /* 新固件大小 */
|
||
uint16_t new_crc16; /* 新固件 MODBUS CRC16 */
|
||
uint8_t new_valid; /* 槽 B 固件是否有效 */
|
||
uint8_t update_state; /* 当前 OTA 状态 */
|
||
uint16_t boot_trial_count; /* 已尝试启动次数 */
|
||
uint8_t app_confirmed; /* APP 运行稳定后置 1 */
|
||
uint8_t reserved1;
|
||
uint16_t backup_version; /* 备份固件版本号 */
|
||
uint32_t backup_size; /* 备份固件大小 */
|
||
uint16_t backup_crc16; /* 备份固件 CRC16 */
|
||
uint8_t backup_valid; /* 槽 A 备份是否有效 */
|
||
uint8_t reserved2;
|
||
char ota_id[20]; /* 平台 OTA 任务 id(重启后补发 result.post 用) */
|
||
uint16_t checksum; /* 前面所有字节累加和 */
|
||
} W25Q64_OtaInfo;
|
||
#pragma pack(pop)
|
||
|
||
/* 基础 SPI Flash 操作 */
|
||
uint8_t W25Q64_Init(void);
|
||
void W25Q64_ReadID(uint8_t *id3);
|
||
uint8_t W25Q64_ReadStatus(void);
|
||
uint8_t W25Q64_WaitBusy(uint32_t timeout_ms); /* 返回 0=就绪,1=超时 */
|
||
uint8_t W25Q64_WriteEnable(void); /* 返回 0=成功,1=超时 */
|
||
void W25Q64_SectorErase(uint32_t addr);
|
||
void W25Q64_BlockErase(uint32_t addr);
|
||
void W25Q64_ChipErase(void);
|
||
void W25Q64_PageProgram(uint32_t addr, const uint8_t *data, uint16_t len);
|
||
void W25Q64_Read(uint32_t addr, uint8_t *buf, uint32_t len);
|
||
|
||
void W25Q64_EraseRegion(uint32_t addr, uint32_t size);
|
||
int W25Q64_WriteBuffer(uint32_t addr, const uint8_t *data, uint32_t len);
|
||
int W25Q64_Verify(uint32_t addr, const uint8_t *data, uint32_t len);
|
||
|
||
/* OTA 专用信息区操作 */
|
||
int W25Q64_OTA_ReadInfo(W25Q64_OtaInfo *info);
|
||
int W25Q64_OTA_WriteInfo(const W25Q64_OtaInfo *info);
|
||
int W25Q64_OTA_SetNewInfo(uint16_t version, uint32_t size, uint16_t crc16);
|
||
int W25Q64_OTA_SetBackupInfo(uint32_t size, uint16_t crc16);
|
||
int W25Q64_OTA_ClearNew(void);
|
||
int W25Q64_OTA_SetState(uint8_t state);
|
||
int W25Q64_OTA_IncTrial(void);
|
||
int W25Q64_OTA_SetConfirmed(void);
|
||
int W25Q64_OTA_ClearConfirmed(void);
|
||
|
||
uint16_t W25Q64_CRC16(const uint8_t *data, uint32_t len);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
|
||
#endif /* __W25Q64_H */
|