/** ##########################################################################
**     Filename  :
**     Project   :
**     Module    :
**     Processor :
**     Version   : 1.0
**     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---  --修改--

** #########################################################################*/

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

#include "error.h"
#include "eeprom.h"
#include "eeprom_seq.h"
#include "eeprom_state_machine.h"
#include "system_voltage_manage.h"
#include "wdog.h"

#ifdef NVM_EEPROM_EXT_EN
/*---------------------------------------------------------------------------
- D E F I N E S / M A C R O S
----------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
- T Y P E   D E F I N I T I O N S
----------------------------------------------------------------------------*/



/*---------------------------------------------------------------------------
- S T A T I C   V A R I A B L E S
----------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
* G L O B A L   V A R I A B L E S
----------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
- C O N S T A N T S
----------------------------------------------------------------------------*/


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


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		: 擦除数据
----------------------------------------------------------------------------*/
eeprom_statys_t eeprom_erase_page(u32 page_addr)
{
	eeprom_statys_t  l_flash_status ;

	#ifdef EEPROM_EXT_JUDGE_PAGE_ADDR
	assert_param(page_addr>=EEPROM_FLASH_ADDR_START);
	assert_param(page_addr<EEPROM_FLASH_ADDR_END);
	#endif
	wdog_task();
	#ifdef EEPROM_EXT_DEBUG_IO_EN
	//EEPROM_EXT_ERASE_TEST_ON();
	#endif
	if (FL_FAIL == FL_FLASH_SectorErase(FLASH, page_addr))
	{
		l_flash_status = EFLASH_STATUS_BUSY;
	}
	else
	{
		l_flash_status = EFLASH_STATUS_SUCCESS;
	}
	#ifdef EEPROM_EXT_DEBUG_IO_EN
	//EEPROM_EXT_ERASE_TEST_OFF();
	#endif
	return l_flash_status;
}

/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		: 写一个word
----------------------------------------------------------------------------*/
eeprom_statys_t eeprom_program_u32(u32 addr, u32 data)
{
	eeprom_statys_t  l_flash_status ;
	#ifdef EEPROM_EXT_JUDGE_PAGE_ADDR
	assert_param(addr>=EEPROM_FLASH_ADDR_START);
	assert_param(addr<=EEPROM_AERA_END_ADDR);
	assert_param((addr&FLASH_ADDRS_ALIGN_RES_MASK)==0u);
	#endif
	wdog_task();
	if (FL_FAIL == FL_FLASH_Program_Word(FLASH, addr, data))
	{
		l_flash_status = EFLASH_STATUS_BUSY;
	}
	else
	{
		l_flash_status = EFLASH_STATUS_SUCCESS;
	}
	return l_flash_status;
}

/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		:初始化
----------------------------------------------------------------------------*/
u16 eeprom_drv_init(u8 area_id)
{
	u16 i;
	u16 l_page0_status, l_page1_status;
	#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
	#else
	u16 l_page0_auxi, l_page1_auxi;
	#endif
	//u16 l_addr_index = 0u;
	//u16 l_eeprom_status = 0u, l_read_status = EFLASH_READ_FAILED;
	u16  l_flash_status = EFLASH_STATUS_SUCCESS;
	u8 l_flag_out=0u;

	assert_param(area_id<EEPROM_AREA_TOTAL);

	if(area_id>=EEPROM_AREA_TOTAL)
	{
		l_flash_status = EFLASH_STATUS_PPADRER_ERROR;
		//return l_flash_status;
	}
	else
	{
		/* Get Page0 status */
		l_page0_status = (*(__IO eflash_operate_t*)EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id));
		/* Get Page1 status */
		l_page1_status = (*(__IO eflash_operate_t*)EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id));
		#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
		#else
		/* Get Page0 status */
		l_page0_auxi = (*(__IO eflash_operate_t*)(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id)+EFLASH_OPERATION_LEN));
		/* Get Page1 status */
		l_page1_auxi = (*(__IO eflash_operate_t*)(EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id)+EFLASH_OPERATION_LEN));
		#endif
		/* Check for invalid header states and repair if necessary */
		switch (l_page0_status)
		{
			case EFLASH_ERASED:
				if (l_page1_status == EFLASH_VALID_PAGE) /* Page0 erased, Page1 valid */
				{
					//其实不需要每次都擦除，
					#if 1  //其实没必要，每次都删除
					if(g_eeprom_ext[area_id].first_reset_flag != EEPROM_FLAG_NOT_FIRST_RESET)
					{
						for(i = 0; i < EEPROM_AREAx_EFLASH_PAGE_NUM(area_id); i ++)
						{
							l_flash_status = eeprom_erase_page(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) + i * EFLASH_PAGE_SIEZ);
							if(l_flash_status != EFLASH_STATUS_SUCCESS)
							{
								break;
							}
						}
						/* If erase operation was failed, a Flash error code is returned */
						if (l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							//return l_flash_status;
							l_flag_out=1u;
							break;
						}
					}
					#endif
				}
				#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
				else if (l_page1_status == EFLASH_RECEIVE_DATA) /* Page0 erased, Page1 receive */
				{
					//g_eeprom_ext[area_id].first_reset_flag = EEPROM_FLAG_FIRST_RESET_CLEAR;
					/* Erase Page0 */
					for(i = 0; i < EEPROM_AREAx_EFLASH_PAGE_NUM(area_id); i ++)
					{
						l_flash_status = eeprom_erase_page(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) + i * EFLASH_PAGE_SIEZ);
						if(l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							break;
						}
					}
					/* If erase operation was failed, a Flash error code is returned */
					if (l_flash_status != EFLASH_STATUS_SUCCESS)
					{
						l_flag_out=1u;
						break;
					}
					/* Mark Page1 as valid */
					l_flash_status = eeprom_program_u32(EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id), EFLASH_VALID_PAGE);
					/* If program operation was failed, a Flash error code is returned */
					if (l_flash_status != EFLASH_STATUS_SUCCESS)
					{
						l_flag_out=1u;
						break;
					}
					g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
					break;
				}
				#endif
				else /* First EEPROM access (Page0&1 are erased) or invalid state -> format EEPROM */
				{
					#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO

					#else
					if( l_page0_auxi == EFLASH_RECEIVE_DATA )
					{
						//正在转移，不用格式化--并且把FFFFF清成0，
						l_flash_status = eeprom_program_u32(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id), EFLASH_VALID_PAGE);
						if (l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							//return l_flash_status;
							l_flag_out=1u;
							break;
						}
						g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
					}
					else if(l_page1_auxi == EFLASH_RECEIVE_DATA )
					{
						//正在转移，不用格式化--并且把FFFFF清成0，
						l_flash_status = eeprom_program_u32(EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id), EFLASH_VALID_PAGE);
						if (l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							//return l_flash_status;
							l_flag_out=1u;
							break;
						}
						g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
					}
					else
					#endif
					{
						/* Erase both Page0 and Page1 and set Page0 as valid page */
						l_flash_status = eeprom_format(area_id);
						/* If erase/program operation was failed, a Flash error code is returned */
						if (l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							//return l_flash_status;
							l_flag_out=1u;
							break;
						}
						g_eeprom_ext[area_id].first_reset_flag = EEPROM_FLAG_FIRST_RESET_CLEAR;
					}
				}
				break;
			#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
			case EFLASH_RECEIVE_DATA:
				if (l_page1_status == EFLASH_VALID_PAGE) /* Page0 receive, Page1 valid */
				{
					#ifdef EEPROM_EXT_STATE_MACHILE_ENABLE
					//--其实可以考虙删除PAGE0，重新在状态机中搬
					/* Erase Page1 */
					for(i = 0; i < EEPROM_AREAx_EFLASH_PAGE_NUM(area_id); i ++)
					{
						//wdog_task();
						//wdt_disable();
						l_flash_status = eeprom_erase_page(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) + i * EFLASH_PAGE_SIEZ);
						//wdog_init();
						//wdog_task();
						if(l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							break;
						}
					}
					/* If erase operation was failed, a Flash error code is returned */
					if (l_flash_status != EFLASH_STATUS_SUCCESS)
					{
						l_flag_out=1u;
						break;
					}
					//g_eeprom_ext[area_id].first_reset_flag = EEPROM_FLAG_FIRST_RESET_CLEAR;
					g_eeprom_ext[area_id].trans_page_count =0u;
					g_eeprom_ext[area_id].transfer_state = EFLASH_PAGE_TRANSFER_STATE_WRITE_NEW_DATA;
					#else
					/* Transfer data from Page1 to Page0 */ //--其实可以考虙删除PAGE0，重新在状态机中搬
					eeprom_reset_page_transfer_continus(area_id,g_eeprom_ext[area_id].page_cur_id, g_logic_page_write_data[area_id]);
					#endif
				}
				else if(l_page1_status == EFLASH_ERASED) /* Page0 receive, Page1 erased */
				{
					/* Erase Page1 */
					//g_eeprom_ext[area_id].first_reset_flag = EEPROM_FLAG_FIRST_RESET_CLEAR;
					for(i = 0; i < EEPROM_AREAx_EFLASH_PAGE_NUM(area_id); i ++)
					{
						l_flash_status = eeprom_erase_page(EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id) + i * EFLASH_PAGE_SIEZ);
						if(l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							break;
						}
					}
					/* If erase operation was failed, a Flash error code is returned */
					if (l_flash_status != EFLASH_STATUS_SUCCESS)
					{
						l_flag_out=1u;
						break;
					}
					/* Mark Page0 as valid */
					l_flash_status = eeprom_program_u32(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id), EFLASH_VALID_PAGE);
					/* If program operation was failed, a Flash error code is returned */
					if (l_flash_status != EFLASH_STATUS_SUCCESS)
					{
						l_flag_out=1u;
						break;
					}
					g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
				}
				else /* Invalid state -> format eeprom */
				{
					/* Erase both Page0 and Page1 and set Page0 as valid page */
					l_flash_status = eeprom_format(area_id);
					/* If erase/program operation was failed, a Flash error code is returned */
					if (l_flash_status != EFLASH_STATUS_SUCCESS)
					{
						//return l_flash_status;
						l_flag_out=1u;
						break;
					}
					g_eeprom_ext[area_id].first_reset_flag = EEPROM_FLAG_FIRST_RESET_CLEAR;
				}
			break;
			#endif
			case EFLASH_VALID_PAGE:
				if (l_page1_status == EFLASH_VALID_PAGE) /* Invalid state -> format eeprom */
				{
					/* Erase both Page0 and Page1 and set Page0 as valid page */
					l_flash_status = eeprom_format(area_id);
					/* If erase/program operation was failed, a Flash error code is returned */
					if (l_flash_status != EFLASH_STATUS_SUCCESS)
					{
						//return l_flash_status;
						l_flag_out=1u;
						break;
					}
					g_eeprom_ext[area_id].first_reset_flag = EEPROM_FLAG_FIRST_RESET_CLEAR;
				}
				else if (l_page1_status == EFLASH_ERASED) /* Page0 valid, Page1 erased */
				{
					/* Erase Page1 */
					#if 1  //其实没必要，每次都删除
					if(g_eeprom_ext[area_id].first_reset_flag != EEPROM_FLAG_NOT_FIRST_RESET)
					{
						for(i = 0; i < EEPROM_AREAx_EFLASH_PAGE_NUM(area_id); i ++)
						{
							l_flash_status = eeprom_erase_page(EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id) + i * EFLASH_PAGE_SIEZ);
							if(l_flash_status != EFLASH_STATUS_SUCCESS)
							{
								break;
							}
						}
						/* If erase operation was failed, a Flash error code is returned */
						if (l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							//return l_flash_status;
							l_flag_out=1u;
							break;
						}
					}
					#endif
				}
				else /* Page0 valid, Page1 receive */
				{
					#ifdef EEPROM_EXT_STATE_MACHILE_ENABLE
					for(i = 0; i < EEPROM_AREAx_EFLASH_PAGE_NUM(area_id); i ++)
					{
						//wdog_task();
						//wdt_disable();
						l_flash_status = eeprom_erase_page(EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id) + i * EFLASH_PAGE_SIEZ);
						//wdog_init();
						//wdog_task();
						if(l_flash_status != EFLASH_STATUS_SUCCESS)
						{
							break;
						}
					}
					/* If erase operation was failed, a Flash error code is returned */
					if (l_flash_status != EFLASH_STATUS_SUCCESS)
					{
						l_flag_out=1u;
						break;
					}
					g_eeprom_ext[area_id].trans_page_count =0u;
					g_eeprom_ext[area_id].transfer_state = EFLASH_PAGE_TRANSFER_STATE_WRITE_NEW_DATA;
					#else
					/* Transfer data from Page0 to Page1 */  //--其实可以考虙删除PAGE1，重新在状态机中搬
					eeprom_reset_page_transfer_continus(area_id,g_eeprom_ext[area_id].page_cur_id, g_logic_page_write_data[area_id]);
					#endif
				}

				break;

			default:  /* Any other state -> format eeprom */
				/* Erase both Page0 and Page1 and set Page0 as valid page */
				l_flash_status = eeprom_format(area_id);
				/* If erase/program operation was failed, a Flash error code is returned */
				if (l_flash_status != EFLASH_STATUS_SUCCESS)
				{
					//return l_flash_status;
					l_flag_out=1u;
					break;
				}
				g_eeprom_ext[area_id].first_reset_flag = EEPROM_FLAG_FIRST_RESET_CLEAR;
				break;
		}
	}
	if(l_flag_out==0u)
	{
		l_flash_status = EFLASH_STATUS_SUCCESS;
	}
	return l_flash_status;
}


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	: area_id: Var片区；virt_addr: Variable virtual address；data: Global variable contains the read variable value
|Output parameters	:
|Return value		: Success or error status:
	*           - 0: if variable was found
	*           - 1: if the variable was not found
	*           - EFLASH_NO_VALID_PAGE: if no valid page was found.
|Description		:读取一个U32
----------------------------------------------------------------------------*/
u16 eeprom_read_one_element(u8 area_id,u16 virt_addr, u32* data)
{
	u16 l_valid_page = EFLASH_PAGE0;
	u16 l_addr_value = 0x5555, l_read_status = EFLASH_READ_FAILED;
	u32 l_addr, l_page_start_addr;

	assert_param(area_id<EEPROM_AREA_TOTAL);

	/* Get active Page for read operation */
	l_valid_page = eeprom_find_valid_page(area_id,EFLASH_READ_FROM_VALID_PAGE);

	/* Check if there is no valid page */
	if (l_valid_page == EFLASH_NO_VALID_PAGE)
	{
		return  EFLASH_NO_VALID_PAGE;
	}

	/* Get the valid Page start l_addr */
	l_page_start_addr = (u32)(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) + (u32)(l_valid_page * EFLASH_AREAx_MASS_PAGE_SIZE(area_id)));
	#ifdef EEPROM_OPTIMIZE_SEARCH_FAST
	if(eeprom_get_cur_page_id(area_id) == l_valid_page)
	{
		l_addr = eeprom_get_cur_end_addr(area_id);
	}
	else
	{
		l_addr = (u32)((EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id)  - EFLASH_OPERATION_LEN ) + (u32)((1 + l_valid_page) * EFLASH_AREAx_MASS_PAGE_SIZE(area_id) ));
	}
	#else
	/* Get the valid Page end l_addr */
	l_addr = (u32)((EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id)  - EFLASH_OPERATION_LEN ) + (u32)((1 + l_valid_page) * EFLASH_AREAx_MASS_PAGE_SIZE(area_id) ));
	#endif
	/* Check each active page address starting from end */
	while (l_addr > (l_page_start_addr + EFLASH_OPERATION_LEN))
	{
		/* Get the current location content to be compared with virtual address */
		l_addr_value = (*(__IO eflash_operate_t*)l_addr);

		/* Compare the read address with the virtual address */
		if (l_addr_value == (virt_addr + EEPROM_VIRT_ADDRESS_OFFSET))
		{
			/* Get content of l_addr-EFLASH_OPERATION_LEN which is variable value */
			*data = (*(__IO eflash_operate_t*)(l_addr - EFLASH_OPERATION_LEN));

			/* In case variable value is read, reset l_read_status flag */
			l_read_status = EFLASH_READ_OK;

			break;
		}
		else
		{
			/* Next address location */
			l_addr = l_addr - EFLASH_ELEMENT_LEN;
		}
	}

	//如果讀取，沒有該數據，返回一個默認值
	if(l_read_status!=EFLASH_READ_OK)
	{
		*data= EEPROM_EXT_UN_WRITE_INIT;
	}

	/* Return l_read_status value: (0: variable exist, 1: variable doesn't exist) */
	return l_read_status;

}


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	: area_id: Var片区；virt_addr: 16 bit virtual address of the variable
						data: 16 bit data to be written as variable value
|Output parameters	:
|Return value		: Success or error status:
	*           - EFLASH_STATUS_SUCCESS: on success
	*           - EFLASH_PAGE_FULL: if valid page is full
	*           - EFLASH_NO_VALID_PAGE: if no valid page was found
	*           - Flash error code: on write Flash error
|Description		:快速定位地址；
----------------------------------------------------------------------------*/
void eeprom_get_current_page_addr(u8 area_id,u16 *p_valid_page,u32 *p_addr)
{
	u16 l_valid_page = EFLASH_PAGE0;
	//eeprom_statys_t l_status_res = EFLASH_STATUS_SUCCESS;
	u32 l_current_addr = 0u;
	u32 l_addr, l_page_end_addr;

	/* Get active Page for read operation */
	l_valid_page = eeprom_find_valid_page(area_id,EFLASH_READ_FROM_VALID_PAGE);

	/* Check if there is no valid page */
	if (l_valid_page == EFLASH_NO_VALID_PAGE)
	{
		*p_valid_page = EFLASH_NO_VALID_PAGE;
		*p_addr = EFLASH_READ_NOT_VALID_ADDR_CUR;  //表示没有 有效的页
		return  ;
	}
	*p_valid_page = l_valid_page;
	/* Get the valid Page start l_addr */
	l_addr = (u32)(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) + (u32)(l_valid_page * EFLASH_AREAx_MASS_PAGE_SIZE(area_id)) + EFLASH_PAGE_FIRST_VARIABLE_ADDRESS);

	/* Get the valid Page end l_addr */
	l_page_end_addr = (u32)((EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) - EFLASH_OPERATION_LEN) + (u32)((1 + l_valid_page) * EFLASH_AREAx_MASS_PAGE_SIZE(area_id)));
	/* Check each active page address starting from begining */
	while (l_addr <= l_page_end_addr)
	{
		/* Verify if l_addr and l_addr+EFLASH_OPERATION_LEN contents are all 0xF */
		#if (EFLASH_OPERATION_LEN == 2)
		if ((*(__IO eflash_operate_t*)l_addr) == 0xFFFFFFFF)
		#elif (EFLASH_OPERATION_LEN == 4)
		if (((*(__IO eflash_operate_t*)l_addr) == 0xFFFFFFFF) &&
				((*(__IO eflash_operate_t*)(l_addr - EFLASH_OPERATION_LEN)) == 0xFFFFFFFF))  //我认为目前-4是合理的 因为数据在地址前面
		#endif
		{
			/* Set variable data */
			//向前找，如果先找到FFFF，则认为是空的，当前可以填的。
			l_current_addr = l_addr;
			*p_addr = l_current_addr;
			/* Return program operation status */
			return ;//l_current_addr;
		}
		else
		{
			/* Next address location */
			l_addr = l_addr + EFLASH_ELEMENT_LEN;
		}
	}

	l_current_addr = l_page_end_addr;
	*p_addr = l_current_addr;  //对齐到实际地址
	/* Return EFLASH_PAGE_FULL in case the valid page is full */
	return ;//l_current_addr;

}

/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	: Erases EFLASH_PAGE0 and EFLASH_PAGE1 and writes EFLASH_VALID_PAGE header to EFLASH_PAGE0
|Output parameters	:
|Return value		: Status of the last operation (Flash write or erase) done during
	*         EEPROM formating
|Description		:
----------------------------------------------------------------------------*/
eeprom_statys_t eeprom_format(u8 area_id)
{
	eeprom_statys_t l_status_res = EFLASH_STATUS_SUCCESS;
	u8 i;

	assert_param(area_id<EEPROM_AREA_TOTAL);

	/* Erase Page0 */
	for(i = 0; i < EEPROM_AREAx_EFLASH_PAGE_NUM(area_id); i ++)
	{
		l_status_res = eeprom_erase_page(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) + i * EFLASH_PAGE_SIEZ);
		if (l_status_res != EFLASH_STATUS_SUCCESS)
		{
			break;
		}
	}

	/* If erase operation was failed, a Flash error code is returned */
	if (l_status_res != EFLASH_STATUS_SUCCESS)
	{
		return l_status_res;
	}

	/* Set Page0 as valid page: Write EFLASH_VALID_PAGE at Page0 base address */
	l_status_res = eeprom_program_u32(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id), EFLASH_VALID_PAGE);

	/* If program operation was failed, a Flash error code is returned */
	if (l_status_res != EFLASH_STATUS_SUCCESS)
	{
		return l_status_res;
	}

	/* Erase Page1 */
	for(i = 0; i < EEPROM_AREAx_EFLASH_PAGE_NUM(area_id); i ++)
	{
		l_status_res = eeprom_erase_page(EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id) + i * EFLASH_PAGE_SIEZ);
		if (l_status_res != EFLASH_STATUS_SUCCESS)
		{
			break;
		}
	}

	/* Return Page1 erase operation status */
	return l_status_res;

}


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	: area_id: Var片区 ； operation: operation to achieve on the valid page.
	*   This parameter can be one of the following values:
	*     @arg EFLASH_READ_FROM_VALID_PAGE: read operation from valid page
	*     @arg EFLASH_WRITE_IN_VALID_PAGE: write operation from valid page
|Output parameters	:
|Return value		:Valid page number (EFLASH_PAGE0 or EFLASH_PAGE1) or EFLASH_NO_VALID_PAGE in case
	*   of no valid page was found
|Description		: Find valid Page for write or read operation
----------------------------------------------------------------------------*/
u16 eeprom_find_valid_page(u8 area_id,u8 operation)
{
	u16 l_page0_status, l_page1_status;
	#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
	#else
	u16 l_page0_auxi, l_page1_auxi;
	#endif
	u16 l_result =0u;
	assert_param(area_id<EEPROM_AREA_TOTAL);

	/* Get Page0 actual status */
	l_page0_status = (*(__IO eflash_operate_t*)EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id));

	/* Get Page1 actual status */
	l_page1_status = (*(__IO eflash_operate_t*)EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id));
	#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
	#else
	/* Get Page0 status */
	l_page0_auxi = (*(__IO eflash_operate_t*)(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id)+EFLASH_OPERATION_LEN));
	/* Get Page1 status */
	l_page1_auxi = (*(__IO eflash_operate_t*)(EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id)+EFLASH_OPERATION_LEN));
	#endif
	/* Write or read operation */
	switch (operation)
	{
		case EFLASH_WRITE_IN_VALID_PAGE:   /* ---- Write operation ---- */
			#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
			if(l_page1_status == EFLASH_VALID_PAGE)
			{
				if(l_page0_status == EFLASH_RECEIVE_DATA)
				{
					l_result = EFLASH_PAGE0;           /* Page0 valid */
				}
				else
				{
					l_result = EFLASH_PAGE1;           /* Page1 valid */
				}
			}
			else if(l_page0_status == EFLASH_VALID_PAGE)
			{
				if(l_page1_status == EFLASH_RECEIVE_DATA)
				{
					l_result = EFLASH_PAGE1;           /* Page1 valid */
				}
				else
				{
					l_result = EFLASH_PAGE0;           /* Page0 valid */
				}
			}
			else
			{
				l_result = EFLASH_NO_VALID_PAGE ;  /* No valid Page */
			}
			#else
			if ((l_page0_status == EFLASH_VALID_PAGE) && (l_page1_status == EFLASH_ERASED) )
			{
				l_result =  EFLASH_PAGE0;           /* Page0 valid */
			}
			else if ( (l_page1_status == EFLASH_VALID_PAGE) && (l_page0_status == EFLASH_ERASED) )
			{
				l_result =  EFLASH_PAGE1;           /* Page1 valid */
			}
			else if ( (l_page1_status == EFLASH_ERASED) && (l_page0_status == EFLASH_ERASED) )
			{
				#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
				#else
				if(l_page0_auxi == EFLASH_RECEIVE_DATA)
				{
					l_result = EFLASH_PAGE0;           /* Page0 valid */
				}
				else if(l_page1_auxi == EFLASH_RECEIVE_DATA)
				{
					l_result = EFLASH_PAGE1;           /* Page0 valid */
				}
				else
				#endif
				{
					l_result =  EFLASH_NO_VALID_PAGE ;  /* No valid Page */
				}
			}
			else
			{
				l_result =  EFLASH_NO_VALID_PAGE ;  /* No valid Page */
			}
			#endif
		break;
		case EFLASH_READ_FROM_VALID_PAGE:  /* ---- Read operation ---- */
			if ( (l_page0_status == EFLASH_VALID_PAGE) && (l_page1_status != EFLASH_VALID_PAGE))
			{
				l_result = EFLASH_PAGE0;           /* Page0 valid */
			}
			else if ((l_page1_status == EFLASH_VALID_PAGE) && (l_page0_status != EFLASH_VALID_PAGE))
			{
				l_result = EFLASH_PAGE1;           /* Page1 valid */
			}
			else if ( (l_page1_status == EFLASH_ERASED) && (l_page0_status == EFLASH_ERASED) )
			{
				#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
				#else
				if(l_page0_auxi == EFLASH_RECEIVE_DATA)
				{
					l_result = EFLASH_PAGE0;           /* Page0 valid */
				}
				else if(l_page1_auxi == EFLASH_RECEIVE_DATA)
				{
					l_result = EFLASH_PAGE1;           /* Page0 valid */
				}
				else
				#endif
				{
					l_result =  EFLASH_NO_VALID_PAGE ;  /* No valid Page */
				}
			}
			else
			{
				l_result =  EFLASH_NO_VALID_PAGE ;  /* No valid Page */
			}
		break;
		default:
			l_result = EFLASH_PAGE0;             /* Page0 valid */
		break;
	}
	return l_result;
}


/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	: area_id: Var片区；
						virt_addr: 16 bit virtual address of the variable
						data: 16 bit data to be written as variable value
|Output parameters	:
|Return value		: Success or error status:
	*           - EFLASH_STATUS_SUCCESS: on success
	*           - EFLASH_PAGE_FULL: if valid page is full
	*           - EFLASH_NO_VALID_PAGE: if no valid page was found
	*           - Flash error code: on write Flash error
|Description		:  Verify if active page is full and Writes variable in EEPROM.
----------------------------------------------------------------------------*/
eeprom_statys_t eeprom_verify_page_ful_write_one_ele(u8 area_id,u16 valid_page, u16 virt_addr, u32 data)
{

	eeprom_statys_t l_status_res = EFLASH_STATUS_SUCCESS;

	u32 l_addr, l_page_end_addr;

	#ifdef EEPROM_OPTIMIZE_SEARCH_FAST
	if(eeprom_get_cur_page_id(area_id) == valid_page)
	{
		l_addr = eeprom_get_cur_end_addr(area_id) - EFLASH_OPERATION_LEN;
	}
	else
	{
		l_addr = (u32)(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) + (u32)(valid_page * EFLASH_AREAx_MASS_PAGE_SIZE(area_id)) + EFLASH_PAGE_FIRST_VARIABLE_ADDRESS - EFLASH_OPERATION_LEN);
	}
	#else
	/* Get the valid Page start l_addr */
	l_addr = (u32)(EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) + (u32)(valid_page * EFLASH_AREAx_MASS_PAGE_SIZE(area_id)) + EFLASH_PAGE_FIRST_VARIABLE_ADDRESS - EFLASH_OPERATION_LEN);
	#endif
	/* Get the valid Page end l_addr */
	l_page_end_addr = (u32)((EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id) - EFLASH_OPERATION_LEN) + (u32)((1u + valid_page) * EFLASH_AREAx_MASS_PAGE_SIZE(area_id)));

	/* Check each active page address starting from begining */
	while (l_addr < l_page_end_addr)
	{
		/* Verify if l_addr and l_addr+EFLASH_OPERATION_LEN contents are all 0xF */
		#if (EFLASH_OPERATION_LEN == 2)
		if ((*(__IO eflash_operate_t*)l_addr) == 0xFFFFFFFF)
		#elif (EFLASH_OPERATION_LEN == 4)
		if (((*(__IO eflash_operate_t*)l_addr) == 0xFFFFFFFF) &&
				((*(__IO eflash_operate_t*)(l_addr + EFLASH_OPERATION_LEN)) == 0xFFFFFFFF))
		#endif
		{
			#ifdef EEPROM_EXT_DEBUG_IO_EN
			EEPROM_EXT_TEST1_ON(area_id);
			#endif
			/* Set variable data */
			l_status_res = eeprom_program_u32(l_addr, data);
			#ifdef EEPROM_EXT_DEBUG_IO_EN
			EEPROM_EXT_TEST1_OFF(area_id);
			#endif
			/* If program operation was failed, a Flash error code is returned */
			if (l_status_res != EFLASH_STATUS_SUCCESS)
			{
				return l_status_res;
			}
			#ifdef EEPROM_EXT_DEBUG_IO_EN
			EEPROM_EXT_TEST1_ON(area_id);
			#endif
			/* Set variable virtual address */
			l_status_res = eeprom_program_u32(l_addr + EFLASH_OPERATION_LEN, (virt_addr + EEPROM_VIRT_ADDRESS_OFFSET));
			#ifdef EEPROM_EXT_DEBUG_IO_EN
			EEPROM_EXT_TEST1_OFF(area_id);
			#endif
			/* Return program operation status */
			return l_status_res;
		}
		else
		{
			/* Next address location */
			l_addr = l_addr + EFLASH_ELEMENT_LEN;
		}
	}

	/* Return EFLASH_PAGE_FULL in case the valid page is full */
	return EFLASH_PAGE_FULL;

}


/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   : area_id: Var片区 
|Output parameters  : None
|Return value       : None
|Description        : 转移
----------------------------------------------------------------------------*/
eeprom_statys_t eeprom_page_transfer(u8 area_id,u16 virt_addr, u32 data)
{
	u16 l_valid_page = EFLASH_PAGE0;
	eeprom_statys_t l_status_res = EFLASH_STATUS_BUSY;
	u16 ReadStatus = 0;
	u32 DataVar;
	u8  i;
	switch (g_eeprom_ext[area_id].transfer_state)
	{
		case EFLASH_PAGE_TRANSFER_STATE_WRITE_NEW_DATA:
			/* Get active Page for read operation */
			l_valid_page = eeprom_find_valid_page(area_id,EFLASH_READ_FROM_VALID_PAGE);

			if (l_valid_page == EFLASH_PAGE1)       /* Page1 valid */
			{
				/* New page address where variable will be moved to */
				g_eeprom_ext[area_id].page_addr_new = EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id);
				g_eeprom_ext[area_id].valid_page_new = EFLASH_PAGE0;

				/* Old page address where variable will be taken from */
				g_eeprom_ext[area_id].page_addr_old = EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id);
			}
			else if (l_valid_page == EFLASH_PAGE0)  /* Page0 valid */
			{
				/* New page address where variable will be moved to */
				g_eeprom_ext[area_id].page_addr_new = EFLASH_AREAx_PAGE1_BASE_ADDRESS(area_id);
				g_eeprom_ext[area_id].valid_page_new = EFLASH_PAGE1;

				/* Old page address where variable will be taken from */
				g_eeprom_ext[area_id].page_addr_old = EFLASH_AREAx_PAGE0_BASE_ADDRESS(area_id);
			}
			else
			{
				return EFLASH_NO_VALID_PAGE;       /* No valid Page */
			}
			#ifdef EEPROM_FLASH_CAN_REWRITE_TO_BIT_ZERO
			l_status_res = eeprom_program_u32(g_eeprom_ext[area_id].page_addr_new, EFLASH_RECEIVE_DATA);
			#else
			l_status_res = eeprom_program_u32(g_eeprom_ext[area_id].page_addr_new+EFLASH_OPERATION_LEN, EFLASH_RECEIVE_DATA);
			#endif
			/* If program operation was failed, a Flash error code is returned */
			if (l_status_res != EFLASH_STATUS_SUCCESS)
			{
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[0]++;
				#endif
				return l_status_res;   //这里要不要返回
			}
			#ifdef EEPROM_EXT_DEBUG_IO_EN
			EEPROM_EXT_TEST1_ON(area_id);
			#endif
			/* Write the variable passed as parameter in the new active page */
			l_status_res = eeprom_verify_page_ful_write_one_ele(area_id,g_eeprom_ext[area_id].valid_page_new,virt_addr, data);
			#ifdef EEPROM_EXT_DEBUG_IO_EN
			EEPROM_EXT_TEST1_OFF(area_id);
			#endif
			/* If program operation was failed, a Flash error code is returned */
			if (l_status_res != EFLASH_STATUS_SUCCESS)
			{
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[1]++;
				#endif
				return l_status_res;  //这里要不要返回？
			}
			g_eeprom_ext[area_id].trans_page_count = 0;
			l_status_res = EFLASH_STATUS_BUSY;
			g_eeprom_ext[area_id].transfer_state = EFLASH_PAGE_TRANSFER_STATE_COPY;
			g_eeprom_ext[area_id].page_addr_cur_total =1u;  //从1开始，因为这个数据，就是存进去的
			#ifdef EEPROM_EXT_DEBUG_EN
			g_eeprom_ext_test[area_id].test_count[2]++;
			#endif
		break;
		case EFLASH_PAGE_TRANSFER_STATE_COPY:
			/* Transfer process: transfer vari[area_id]ables from old to the new active page */
			for (i = 0u; i < 4u; i ++)
			{
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[3]++;
				#endif
				if (g_eeprom_ext[area_id].trans_page_count != (virt_addr))  /* Check each variable except the one passed as parameter */
				{
					#ifdef EEPROM_EXT_DEBUG_EN
					g_eeprom_ext_test[area_id].test_count[4]++;
					#endif
					/* Read the other last variable updates */
					ReadStatus = eeprom_read_one_element(area_id,g_eeprom_ext[area_id].trans_page_count, &DataVar);
					/* In case variable corresponding to the virtual address was found */
					if (ReadStatus == EFLASH_READ_OK)
					{
						/* Transfer the variable to the new active page */
						#ifdef EEPROM_EXT_DEBUG_IO_EN
						EEPROM_EXT_TEST_ON(area_id);
						#endif
						l_status_res = eeprom_verify_page_ful_write_one_ele(area_id,g_eeprom_ext[area_id].valid_page_new,g_eeprom_ext[area_id].trans_page_count, DataVar);
						#ifdef EEPROM_EXT_DEBUG_IO_EN
						EEPROM_EXT_TEST_OFF(area_id);
						#endif
						#ifdef EEPROM_EXT_DEBUG_EN
						g_eeprom_ext_test[area_id].test_count[5]++;
						#endif
						/* If program operation was failed, a Flash error code is returned */
						if (l_status_res != EFLASH_STATUS_SUCCESS)
						{
							#ifdef EEPROM_EXT_DEBUG_EN
							g_eeprom_ext_test[area_id].test_count[6]++;
							#endif
							return l_status_res;
						}
						g_eeprom_ext[area_id].page_addr_cur_total++;
					}
					else
					{
						#ifdef EEPROM_EXT_DEBUG_EN
						g_eeprom_ext_test[area_id].test_count[7]++;
						#endif
					}
				}
				g_eeprom_ext[area_id].trans_page_count ++;
				if(g_eeprom_ext[area_id].trans_page_count >= EEPROM_AREAx_ADDR_TOTAL_U32(area_id))
				{
				  g_eeprom_ext[area_id].trans_page_count = 0;
				  l_status_res = EFLASH_STATUS_BUSY;
				  g_eeprom_ext[area_id].eflash_page_index = 0;
				  g_eeprom_ext[area_id].transfer_state = EFLASH_PAGE_TRANSFER_STATE_ERASE;
				  g_eeprom_ext[area_id].erase_state = EFLASH_PAGE_ERASE_STATE_WAIT_LAST_OPERATION;
				  #ifdef EEPROM_EXT_DEBUG_EN
					g_eeprom_ext_test[area_id].test_count[8]++;
				  #endif
				  break;
				}
			}
			l_status_res = EFLASH_STATUS_BUSY;
			break;
		case EFLASH_PAGE_TRANSFER_STATE_ERASE:

			l_status_res = eeprom_erase_page(g_eeprom_ext[area_id].page_addr_old + g_eeprom_ext[area_id].eflash_page_index * EFLASH_PAGE_SIEZ);
			if (l_status_res != EFLASH_STATUS_SUCCESS)
			{
				return l_status_res;
			}
			#ifdef EEPROM_EXT_DEBUG_EN
			g_eeprom_ext_test[area_id].test_count[9]++;
			#endif
			g_eeprom_ext[area_id].eflash_page_index ++;
			if(g_eeprom_ext[area_id].eflash_page_index >= EEPROM_AREAx_EFLASH_PAGE_NUM(area_id))
			{
				#ifdef EEPROM_EXT_DEBUG_IO_EN
				EEPROM_EXT_TEST_ON(area_id);
				#endif
				l_status_res = eeprom_program_u32(g_eeprom_ext[area_id].page_addr_new, EFLASH_VALID_PAGE);
				#ifdef EEPROM_EXT_DEBUG_IO_EN
				EEPROM_EXT_TEST_OFF(area_id);
				#endif
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[10]++;
				#endif
			}
			else
			{
				l_status_res = EFLASH_STATUS_BUSY;
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[11]++;
				#endif
			}
			break;
		default:
			l_status_res = EFLASH_STATUS_CMD_INVALID;
			break;
	}
	return (l_status_res);
}



/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   :
|Output parameters  : None
|Return value       : None
|Description        : 
----------------------------------------------------------------------------*/
err_flag_e ram_read_bytes_for_eeprom(u32 addr,u8 *p_data,u16 len)
{
	err_flag_e l_result;
	u8 *p_src;
	u16 i;

	if( (addr<EEPROM_RAM_ADDR_START) || (addr>EEPROM_RAM_ADDR_END) || ((addr+len)>(EEPROM_RAM_ADDR_END+1u)) )
	{
		l_result = ERR_FAILED;
	}
	else
	{
		p_src = (u8 *)(addr);

		for (i = 0; i < len; i++)
		{
			p_data[i] = p_src[i]; /*lint !e511*/
		}

		l_result = ERR_OK;
	}

	return l_result;
}

/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   :
|Output parameters  : None
|Return value       : None
|Description
----------------------------------------------------------------------------*/
err_flag_e ram_write_bytes_for_eeprom(u32 addr,u8 *p_data,u16 len)
{
	err_flag_e l_result;
	u8 *p_addr;
	u16 i;

	if( (addr<EEPROM_RAM_ADDR_START) || (addr>EEPROM_RAM_ADDR_END) || ((addr+len)>(EEPROM_RAM_ADDR_END+1u)) )
	{
		l_result = ERR_FAILED;
	}
	else
	{
		p_addr = (u8 *)(addr);

		for (i = 0; i < len; i++)
		{
			p_addr[i] = p_data[i] ;  /*lint !e511*/
		}

		l_result = ERR_OK;
	}

	return l_result;
}

/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   :
|Output parameters  : None
|Return value       : None
|Description
----------------------------------------------------------------------------*/
u8 eeprom_read_u8_ext(u32 w_addr, u8 *p_data, u16 b_number)
{
	u8 l_result ;
	l_result = ram_read_bytes_for_eeprom(w_addr+EEPROM_RAM_ADDR_START,p_data,b_number);
	return l_result;
}

/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   :
|Output parameters  : None
|Return value       : None
|Description
----------------------------------------------------------------------------*/
u8 eeprom_write_u8_ext(u32 w_addr, u8 *p_data, u16 b_number)
{
	u8 l_result ;
    #ifdef EEPROM_EXT_STATE_MACHILE_ENABLE
	#else
	u16 l_start_addr;
	u16 l_offset;
	u16 l_len;
	u16 i;
	u32 *p_u32;
	u32 l_data;
    #endif
	l_result =  ram_write_bytes_for_eeprom(w_addr+EEPROM_RAM_ADDR_START,p_data,b_number);
	#ifdef EEPROM_EXT_STATE_MACHILE_ENABLE
	#else
	l_offset = w_addr&(u32)0x03u;
	l_start_addr = (w_addr-l_offset)/4u;
	l_len = ((b_number+l_offset)/0x04u+1u);
	for(i = 0; i < l_len; i++)
	{
		if( ((w_addr+EEPROM_RAM_ADDR_START)>=EEPROM_AREAx_RAM_ADDR_START(EEPROM_AREA_ID_0) )
				&& ((w_addr+EEPROM_RAM_ADDR_START+b_number)<=EEPROM_AREAx_RAM_ADDR_END(EEPROM_AREA_ID_0) ) )
		{
			p_u32 = (u32*)(l_start_addr*4u+EEPROM_RAM_ADDR_START);
			l_data = *p_u32;
			eeprom_write_one_element_seq(EEPROM_AREA_ID_0,l_start_addr,l_data);
		}
		else if( ((w_addr+EEPROM_RAM_ADDR_START)>=EEPROM_AREAx_RAM_ADDR_START(EEPROM_AREA_ID_1) )
				&& ((w_addr+EEPROM_RAM_ADDR_START+b_number)<=EEPROM_AREAx_RAM_ADDR_END(EEPROM_AREA_ID_1) ) )
		{
			p_u32 = (u32*)(l_start_addr*4u+EEPROM_RAM_ADDR_START);
			l_data = *p_u32;
			l_offset = (EEPROM_AREAx_RAM_ADDR_START(EEPROM_AREA_ID_1)-EEPROM_AREAx_RAM_ADDR_START(EEPROM_AREA_ID_0))/4;
			eeprom_write_one_element_seq(EEPROM_AREA_ID_1,l_start_addr-l_offset,l_data);
		}
		else
		{

		}
		p_u32++;
	}
	#endif
	return l_result;
}

/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   :
|Output parameters  : None
|Return value       : None
|Description
----------------------------------------------------------------------------*/
u8 eeprom_ext_get_state(u8 area_id)
{
	assert_param(area_id<EEPROM_AREA_TOTAL);
	return g_eeprom_ext[area_id].state;
}


/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   :
|Output parameters  : None
|Return value       : None
|Description 初始化
----------------------------------------------------------------------------*/
void eeprom_init(void)
{
	eeprom_area_init(EEPROM_AREA_ID_0);
	#if EEPROM_AREA_TOTAL >1u
	eeprom_area_init(EEPROM_AREA_ID_1);
	#endif
}



/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   :
|Output parameters  : None
|Return value       : None
|Description 任务
----------------------------------------------------------------------------*/
void eeprom_task(void)
{
	eeprom_test_task();
	#if 0
	//if(g_eeprom_input_test.flag==0x1)
	{
		//g_eeprom_input_test.flag=2u;
		//g_eeprom_input_test.count++;
		//eeprom_ext_input_test();
		//eeprom_ext_restart();
		if(SVD_ISR_SVDR_Msk != FL_SVD_GetLatchedPowerStatus(SVD))
		{
			return ;  //l_result;
		}
		#ifdef EEPROM_EXT_STATE_MACHILE_ENABLE
		{
			eeprom_state_machine_task(EEPROM_AREA_ID_0);
			#if EEPROM_AREA_TOTAL >1u
			eeprom_state_machine_task(EEPROM_AREA_ID_1);
			#endif
		}
		#endif
	}
	#else
		#ifdef EEPROM_EXT_STATE_MACHILE_ENABLE
		u8 l_power_grade;
		l_power_grade = system_voltage_manage_mode_get(FUNC_SYSTEM_VOLTAGE_MANAGE_ID);
		if(  ( (l_power_grade == SYSTEM_VOLTAGE_MODE_NORMAL) || (l_power_grade == SYSTEM_VOLTAGE_MODE_HIGH) )  //电压不能低于9v
				&& (SVD_ISR_SVDR_Msk == FL_SVD_GetLatchedPowerStatus(SVD)) )
		{
			#ifdef EEPROM_EXT_DEBUG_EN
			//g_eeprom_ext_test.test_count[37]++;
			#endif
			#ifdef EEPROM_EXT_STATE_MACHILE_ENABLE
			eeprom_state_machine_task(EEPROM_AREA_ID_0);
			#if EEPROM_AREA_TOTAL >1u
			eeprom_state_machine_task(EEPROM_AREA_ID_1);
			#endif
			#endif
		}
		else
		{
			#ifdef EEPROM_EXT_DEBUG_EN
			//g_eeprom_ext_test.test_count[38]++;
			#endif
		}
		#endif
	#endif
}


#if 0
//
/*---------------------------------------------------------------------------
|Prototype          :
|Called by          : None
|Preconditions      : None
|Input parameters   :
|Output parameters  : None
|Return value       : None
|Description 测试用
----------------------------------------------------------------------------*/
u8 eeprom_write_u8_ext1(u32 w_addr, u8 *p_data, u16 b_number)
{
	u8 l_result ;
	u16 l_start_addr;
	u16 l_offset;
	u16 l_len;
	u16 i;
	u32 *p_u32;
	u32 l_data;
	l_result =  ram_write_bytes_for_eeprom(w_addr+EEPROM_RAM_ADDR_START,p_data,b_number);
	#if 0 //def EEPROM_EXT_STATE_MACHILE_ENABLE
	#else
	l_offset = w_addr&(u32)0x03u;
	l_start_addr = (w_addr-l_offset)/4u;
	l_len = ((b_number+l_offset)/0x04u+1u);
	for(i = 0; i < l_len; i++)
	{
		if( ((w_addr+EEPROM_RAM_ADDR_START)>=EEPROM_AREAx_RAM_ADDR_START(EEPROM_AREA_ID_0) )
				&& ((w_addr+EEPROM_RAM_ADDR_START+b_number)<=EEPROM_AREAx_RAM_ADDR_END(EEPROM_AREA_ID_0) ) )
		{
			p_u32 = (u32*)(l_start_addr*4u+EEPROM_RAM_ADDR_START);
			l_data = *p_u32;
			eeprom_write_one_element_seq(EEPROM_AREA_ID_0,l_start_addr,l_data);
		}
		else if( ((w_addr+EEPROM_RAM_ADDR_START)>=EEPROM_AREAx_RAM_ADDR_START(EEPROM_AREA_ID_1) )
				&& ((w_addr+EEPROM_RAM_ADDR_START+b_number)<=EEPROM_AREAx_RAM_ADDR_END(EEPROM_AREA_ID_1) ) )
		{
			p_u32 = (u32*)(l_start_addr*4u+EEPROM_RAM_ADDR_START);
			l_data = *p_u32;
			l_offset = (EEPROM_AREAx_RAM_ADDR_START(EEPROM_AREA_ID_1)-EEPROM_AREAx_RAM_ADDR_START(EEPROM_AREA_ID_0))/4;
			eeprom_write_one_element_seq(EEPROM_AREA_ID_1,l_start_addr-l_offset,l_data);
		}
		else
		{

		}
		p_u32++;
	}
	#endif
	return l_result;
}
#endif


#endif

