#ifndef __IAP_H
#define __IAP_H
#include "global.h"
#include <stm32f4xx.h>

#define IAP_FLASH_UP_LEN  0x8080000
#define IAP_FLASH_UP_ADDR 0X8080004

#define IAP_RUN_START_SECTOR 0x8010000
#define IAP_DOWN_BEGIN_ADDR  0x8080000 // iap代码下载起始地址
// #define  IAP_DOWN_END_ADDR         0x80BFFFF //iap代码下载结束地址

// #define  IAP_BACKUP_BEGIN_ADDR     0x80C0000 //iap代码下载起始地址
// #define  IAP_BACKUP_END_ADDR       0x80FFFFF //iap代码下载结束地址
#define IAP_BACKUP_SECTOR1 10
#define IAP_BACKUP_SECTOR2 11

#define IAP_PC_BEGINE_FRAME 0x18CFD0EF
#define IAP_PC_DATA_FRAME   0x18CED0EF

#define IAP_MCU_BIGEN_FRAME 0x18CFEFD0
#define IAP_MCU_DATA_FRAME  0x18CEEFD0

#define IAP_CMD_CHECK        0x01 // 请求校验
#define IAP_CMD_DOWNLOAD     0x02 // 数据下载
#define IAP_CMD_DOWNLOAD_END 0x03 // 下载代码完成
#define IAP_CMD_READ         0x04 // 读取下发帧内容
#define IAP_CMD_DOWNLOAD_SUC 0X05 // 下载成功

#define IAP_BUF_SIZE 0x40
#define MAX_PACK_NUM 0x17

#define MCU_DOWNLOAD_SUCC 0x01
#define MCU_DOWNLOAD_FAIL 0x02

#define IAP_UP_BEGINNING 0x37377373
#define IAP_UP_SUCCESS   0x59599595
#define IAP_UP_FAIL      0x6A6AA6A6

// FLASH 扇区的起始地址
#define ADDR_FLASH_SECTOR_0   ((u32)0x08000000) // 扇区0起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_1   ((u32)0x08004000) // 扇区1起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_2   ((u32)0x08008000) // 扇区2起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_3   ((u32)0x0800C000) // 扇区3起始地址, 16 Kbytes
#define ADDR_FLASH_SECTOR_4   ((u32)0x08010000) // 扇区4起始地址, 64 Kbytes
#define ADDR_FLASH_SECTOR_5   ((u32)0x08020000) // 扇区5起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_6   ((u32)0x08040000) // 扇区6起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_7   ((u32)0x08060000) // 扇区7起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_8   ((u32)0x08080000) // 扇区8起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_9   ((u32)0x080A0000) // 扇区9起始地址, 128 Kbytes
#define ADDR_FLASH_SECTOR_10  ((u32)0x080C0000) // 扇区10起始地址,128 Kbytes
#define ADDR_FLASH_SECTOR_11  ((u32)0x080E0000) // 扇区11起始地址,128 Kbytes
#define ADDR_FLASH_SECTOR_END ((u32)0x080FFFFF)

typedef enum
{
    DISCONNECT = 0,
    HANDSHAKE,
    PROGRAMING,
    PROGRAMFinish,
} workmode;

typedef union
{
    u8  value[4];
    u32 cmd;
} IAP_Union;

void iap_process(CanData_TypeDef *rx_msg);
u8   flash_up_is_ok(void);
void Iap_from_Flash(void);
#endif
