#ifndef __FLASH_H_
#define	__FLASH_H_

#include "stm32l4xx_hal.h"
/* ========================
 * STM32L431CCT6 256KB Flash 自定义三段式 IAP升级系统
 * 结构：Bootloader + APP1 + APP2
 * 通信方式：UART1 (RS485)
 * 校验方式：MD5（含 tiny_md5）
 * ========================
 */

/* ========== Flash 分区方案 ==========
 * Flash: 256KB (0x08000000 - 0x0803FFFF) 0x40000字节
 *   Bootloader  : 0x08000000 - 0x080067FF (26KB) 0x6800
 *   App1        : 0x08006800 - 0x0801E7FF (96KB) 0x18000
 *   App2        : 0x0801E800 - 0x080367FF (96KB) 0x18000
 *   Param(MD5)  : 0x08036800 - 0x08036FFF (2KB)	0x800
 *   APP应用参数 : 0x08037000 - 0x0803FFFF (36KB)
 * 	   
 */
 
 
//------------------------宏定义-----------------------------// 
#define FLASH_ADDR_MAX 0x08040000			////写入数据地址小于STM32L431CC的flash地址最大值

#define FLASH_PARAMS_MAGIC    0xA5A5
#define FLASH_PARAM_ADDR  0x0803F800  // STM32L431CCT6 最后一页起始地址 (256KB Flash, 每页2KB)
#define SUCCESS               0
#define ERROR                 1

#define BOOTLOADER_ADDR   0x08000000
#define APP1_ADDR         0x08006800
#define APP2_ADDR         0x0801E800
#define PARAM_ADDR        0x08036800 

/**************************************************************/

typedef struct {
    uint32_t app1_version;
    uint8_t  app1_md5[16];
    uint8_t  app1_valid;     // 0xA5 表示有效，其它为无效

    uint32_t app2_version;
    uint8_t  app2_md5[16];
    uint8_t  app2_valid;

    uint32_t upgrade_flag;   // 固件升级标志
    uint32_t rollback_flag;  // 回退标志
} BootParams;

extern BootParams params;

typedef struct {
    uint32_t Firmware_Version;   		// 固件版本号 [备用][年][月][日][序号]
		uint16_t Running_time;      		// 运行时长
		uint16_t SlaveDevice_addr;      // 从机地址
    uint16_t Serial_baud_rate;      // 波特率
    uint16_t Device_SN[3];      		// 设备编号   
    uint16_t magic;                 // 魔术字
} DeviceParams_t;

extern DeviceParams_t g_deviceParams;


/**************************************************************/

/**************         FLASH操作接口         *****************/
uint32_t Flash_ReadOneWord(uint32_t faddr);
void Flash_ErasePages(uint32_t faddr,uint32_t fdataNum);
uint8_t Flash_WriteOneWord(uint32_t faddr,uint32_t fdata32);
uint8_t Flash_WriteDoubleWord(uint32_t faddr,uint64_t fdata64);
void Flash_Write32(uint32_t faddr,uint32_t *fdata32, uint32_t fdata32Num);
void Flash_Write64(uint32_t faddr,uint64_t *fdata64, uint32_t fdata64Num);
void Flash_Read32(uint32_t faddr,uint32_t *fdata32,uint32_t fdata32Num);
void Flash_ReadBytes(uint32_t faddr,uint8_t *fdata8,uint32_t fdata8Num);
uint8_t Flash_WriteRead(uint32_t fAdress, uint8_t *wData, uint32_t wDataLen, uint8_t *rData);

void save_params_to_flash(void);
void load_params_from_flash(void);
void SaveBootloaderParams(void) ;
#endif

/**************************END OF FILE*************************/

