/** ##########################################################################
**     Filename  :
**     Project   :
**     Module    :
**     Processor :
**     Version   :
**     Compiler  :
**     Date/Time :
**     Abstract  :
**     Contents  :
**     Note      :
**     (c) Copyright dmdz Co.,Ltd
**  --------------------------------------------------------------------------
**               R E V I S I O N   H I S T O R Y
**  --------------------------------------------------------------------------
**  Date       Ver   Author             Description

**  -20230602-  --V1.0--  --mingyea---  --修改--

** #########################################################################*/
#ifndef EEPROM_H__
#define EEPROM_H__

/*---------------------------------------------------------------------------
- I N C L U D E   F I L E S
----------------------------------------------------------------------------*/

#include "common_types.h"
#include "common_cfg.h"
#include "fm33lg0xx_fl.h"
#include "mf_config.h"
#include "eeprom_cfg.h"

#ifdef NVM_EEPROM_EXT_EN

/*---------------------------------------------------------------------------
- D E F I N E S / M A C R O S
----------------------------------------------------------------------------*/
#define EFLASH_STATE_READ               0u
#define EFLASH_STATE_IDLE               1u
#define EFLASH_STATE_UPDATE             2u
#define EFLASH_STATE_PAGE_TRANSFER      3u

#define EFLASH_PAGE_ERASE_STATE_WAIT_LAST_OPERATION 0u
#define EFLASH_PAGE_ERASE_STATE_TRIGGER_TO_START    1u
#define EFLASH_PAGE_ERASE_STATE_WAIT_ERASE_FINISH   2u
#define EFLASH_PAGE_ERASE_STATE_WAIT_EOP            3u

#define EFLASH_PAGE_TRANSFER_STATE_WRITE_NEW_DATA   0u
#define EFLASH_PAGE_TRANSFER_STATE_COPY             1U
#define EFLASH_PAGE_TRANSFER_STATE_ERASE            2U

#define EFLASH_RESULT_INIT            0U
#define EFLASH_RESULT_ONCE_OK            1U   //循环一次

/* Used Flash pages for EEPROM emulation */
#define EFLASH_PAGE0                   ((u16)0x0000)
#define EFLASH_PAGE1                   ((u16)0x0001)

/* No valid page define */
#define EFLASH_NO_VALID_PAGE           ((u16)0x00AB)

/* Page status definitions */
#define EFLASH_ERASED                  ((u16)0xFFFF)     /* PAGE is empty */
#define EFLASH_RECEIVE_DATA            ((u16)0xEEEE)     /* PAGE is marked to receive data */
#define EFLASH_VALID_PAGE              ((u16)0x0000)     /* PAGE containing valid data */

/* Valid pages in read and write defines */
#define EFLASH_READ_FROM_VALID_PAGE    ((u8)0x00)
#define EFLASH_WRITE_IN_VALID_PAGE     ((u8)0x01)

/* Page full define */
#define EFLASH_PAGE_FULL               ((u8)0x80)


#define EFLASH_OPERATION_LEN             4u   //flash operation lenth, 4 bytes
#define EFLASH_PAGE_START_INFO_LEN             8u   //page start information, 4 bytes for page status, 4 bytes reserved
#define EFLASH_PAGE_FIRST_VARIABLE_ADDRESS     (EFLASH_PAGE_START_INFO_LEN + EFLASH_OPERATION_LEN) //(EFLASH_PAGE_START_INFO_LEN + EFLASH_OPERATION_LEN)
#define EFLASH_ELEMENT_LEN                     8u   //page element lenth, 8 bytes{4 for data + 4 for virtual address}

#define EFLASH_ADDRS_ALIGN            4u

#define EFLASH_STATUS_SUCCESS 4U
#define EFLASH_STATUS_BUSY 1U
#define EFLASH_STATUS_CMD_INVALID 3U
#define EFLASH_STATUS_PPADRER_ERROR 2U



#define EFLASH_READ_OK 0u
#define EFLASH_READ_FAILED 1u


#define FLASH_Lock()
#define FLASH_Unlock()

//#define EEPROM_FLAG_CHANGE 0x000000u

/*---------------------------------------------------------------------------
- T Y P E   D E F I N I T I O N S
----------------------------------------------------------------------------*/
typedef u32 eflash_operate_t;  //flash operation occupy

typedef enum
{
	FLASH_BUSY = 1u,
	FLASH_ERROR_PG,
	FLASH_ERROR_WRP,
	FLASH_COMPLETE,
	FLASH_TIMEOUT
}FLASH_Status;

typedef struct
{
	u32 first_reset_flag;  //是否第一次操作

	//转移相关
	u32 page_addr_new;
	u32 page_addr_old;
	u16 valid_page_new;
	u16 eflash_page_index;
	u16 trans_page_count;

	//总状态相关
	u8 state;  //状态 --
	u8 erase_state;  //状态  --擦除数据
	u8 transfer_state;  //状态  --转移数据
	u8 result;  //
	u16 cmd_eeprom_result;  //每一條指令，的返回
	//u16 cmd_ram_result;  //每一條指令，的返回
	u16 page_count;
	u16 page_cur_id;
	u16 page_addr_cur_total;

	#ifdef EEPROM_OPTIMIZE_SEARCH_FAST  //快速定位相关
	u16 current_page;
	u32 current_end_addr;  //存了多少个数据，指的是，flash扇区上，包括重复
	#endif
	//u32 data;  //
	//u8 data_u8[4];

}eeprom_ext_s;

typedef struct
{
	u8 test;
	#ifdef EEPROM_EXT_DEBUG_EN
	//做為接口的eeprom 邏輯地址
	u16 test_count[70];
	#endif
}eeprom_ext_test_s;

typedef struct
{
	u8 sector_num; //有几个扇区，不包含备份域，
	u16 mass_page_size_byte;  //总容量，不包含备份域
	u16 mass_page_addr_total_u32;
	u16 mass_page_addr_total_u8;
	u32 ram_start_addr;
	u32 ram_end_addr;
	u32 eflash_page0_start_addr;
	u32 eflash_page0_end_addr;
	u32 eflash_page1_start_addr;
	u32 eflash_page1_end_addr;
}eeprom_user_info_s;

typedef struct
{
	u8 flag;
	u8 count;
}eeprom_input_test_s;
/*---------------------------------------------------------------------------
- G L O B A L   V A R I A B L E S
- only configuration table allowed here,variables are not allowed!
----------------------------------------------------------------------------*/
#ifdef EEPROM_EXT_DEBUG_EN
extern eeprom_input_test_s g_eeprom_input_test[EEPROM_AREA_TOTAL_FOR_RAM];
#endif
extern MEMORY_MAP_RAM_FLAG_NOINIT eeprom_ext_s g_eeprom_ext[EEPROM_AREA_TOTAL_FOR_RAM];
extern eeprom_ext_test_s g_eeprom_ext_test[EEPROM_AREA_TOTAL_FOR_RAM] ;
extern u8 *g_ram_for_eeprom[EEPROM_AREA_TOTAL_FOR_RAM] ;
extern u32 g_logic_page_read_data[EEPROM_AREA_TOTAL_FOR_RAM] MEMORY_MAP_RAM_WDOG  ;
extern u32 g_logic_page_write_data[EEPROM_AREA_TOTAL_FOR_RAM] MEMORY_MAP_RAM_WDOG ;
extern u8 g_logic_page_read_u8data[EEPROM_AREA_TOTAL_FOR_RAM][4]  MEMORY_MAP_RAM_WDOG ;

/*---------------------------------------------------------------------------
- C O N S T A N T S
----------------------------------------------------------------------------*/
extern const eeprom_user_info_s g_eeprom_user_info[EEPROM_AREA_TOTAL_FOR_RAM] ;

/*---------------------------------------------------------------------------
- F U N C T I O N   P R O T O T Y P E
----------------------------------------------------------------------------*/


//////以下是内部接口，给eeprom_ext
u16 eeprom_read_one_element(u8 area_id,u16 virt_addr, u32* data);
uint8_t eeprom_verify_page_ful_write_one_ele(u8 area_id,u16 valid_page, u16 virt_addr, u32 data);
uint8_t eeprom_program_u32(u32 addr, u32 data);
u16 eeprom_find_valid_page(u8 area_id,u8 operation);
uint8_t eeprom_erase_page(u32 page_addr);
uint8_t eeprom_format(u8 area_id);
void eeprom_get_current_page_addr(u8 area_id,u16 *p_valid_page,u32 *p_addr);
u16 eeprom_drv_init(u8 area_id);
uint8_t eeprom_page_transfer(u8 area_id,u16 virt_addr, u32 data);
u16 eeprom_get_cur_page_id(u8 area_id);
u32 eeprom_get_cur_end_addr(u8 area_id);

///以下是外部接口
void eeprom_init(void);
void eeprom_task(void);
u8 eeprom_ext_get_state(u8 area_id);
void eeprom_ext_clear_flag(void);


u8 eeprom_write_u8_ext1(u32 w_addr, u8 *p_data, u16 b_number);

#endif

u8 eeprom_read_u8_ext(u32 w_addr, u8 *p_data, u16 b_number);
u8 eeprom_write_u8_ext(u32 w_addr, u8 *p_data, u16 b_number);


#endif /* __EEPROM_H */

