#ifndef __CHIPFLASH_H
#define __CHIPFLASH_H

#include "stdint.h"
#include "stm32h5xx.h"
#include "stm32h523xx.h"

//一个扇区8*1024bytes
#define CPU_FLASH_SIZE (512 * 1024)    // FLASH总容量（很奇怪，GD32的128KB后64KB可能跟STM32一样没有保障，稳定优先）
#define BOOT_FLASH_SIZE (8 * 1024)    // BOOTLOADER占用容量
#define PAR_FLASH_SIZE (8 * 1024)      // PAR占用容量
#define PROGRAM_FLASH_SIZE (8 * 1024) // APP占用容量
#define SECTOR_SIZE (8 * 1024)         // 扇区大小 8*1024bytes

#define CPU_FLASH_BASE_ADDR (uint32_t)(FLASH_BASE)
#define BOOT_FLASH_END_ADDR (CPU_FLASH_BASE_ADDR + BOOT_FLASH_SIZE)

#define PAR_FLASH_BASE_ADDR (BOOT_FLASH_END_ADDR)
#define PAR_FLASH_END_ADDR (PAR_FLASH_BASE_ADDR + PAR_FLASH_SIZE)

#define PROGRAM_FLASH_BASE_ADDR (PAR_FLASH_END_ADDR + 8 * 1024) // 跳过APP1
#define PROGRAM_FLASH_END_ADDR (PROGRAM_FLASH_BASE_ADDR + PROGRAM_FLASH_SIZE)

#define FLASH_IS_EQU 0    // 无需擦除
#define FLASH_REQ_WRITE 1 // 不需要擦除直接写
#define FLASH_REQ_ERASE 2 // 先擦除再写
#define FLASH_PARAM_ERR 3 // 函数参数错误

#define ChipUniqueID_HIGH 0x1FFFF7F0
#define ChipUniqueID_MEDIUM 0x1FFFF7EC
#define ChipUniqueID_LOW 0x1FFFF7E8
#define CHIPFLASHSIZE 0x1FFFF7E0
#define CHIPMCUID 0xE0042000

#define WS_INFO_ADDR (PAR_FLASH_BASE_ADDR)
#define WS_INFO_FLAG (uint32_t)0xA77A

#pragma pack(push, 1)
typedef struct
{
    uint32_t _app_bin_size;
    uint16_t _compAddr; // 0x66
    uint16_t _hardVer;  // 0x0001
    uint32_t _softVer;
    uint32_t _moduleID; // 预留0x00
    uint32_t _bootFlag; // 0x1234abcd

    uint16_t _crcCheck;
} _WS_INFO;
#pragma pack(pop)

extern _WS_INFO ws_info;

#pragma pack(push, 1)
typedef struct
{
    uint32_t ChipUniqueID[3];
    uint32_t ChipFlashSize;
    uint32_t ChipMCUID;
} _CHIP_INFO;
#pragma pack(pop)

extern _CHIP_INFO chip_info;

typedef struct
{
    uint8_t (*Read_Flash)(uint32_t ulFlashAddr, uint8_t *pdata, uint32_t len);
    uint8_t (*Write_Flash)(uint32_t ulFlashAddr, uint8_t *pdata, uint32_t len);
    uint8_t (*Erase_Flash)(uint32_t ulFlashAddr, uint32_t u2FlashAddr);
} __FLASH_OPS;

extern __FLASH_OPS *flash_ops;

// uint32_t bsp_get_sector(uint32_t Addr);

// uint8_t bsp_read_cpu_flash(uint32_t ulFlashAddr, uint8_t* ucpDst, uint32_t ulSize);

// uint8_t bsp_cmp_cpu_flash(uint32_t ulFlashAddr, uint8_t* ucpBuf, uint32_t ulSize);

// uint8_t bsp_write_cpu_flash(uint32_t ulFlashAddr, uint8_t* ucpSrc, uint32_t ulSize);

// uint8_t bsp_erase_cpu_flash(uint32_t ulFlashAddr, uint32_t u2FlashAddr);

// void get_chip_info(void);

#endif
