/** ##########################################################################
**     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---  --修改--

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

/*---------------------------------------------------------------------------
- I N C L U D E   F I L E S
----------------------------------------------------------------------------*/
#include "common_types.h"
#include "common_memory.h"
#include "eeprom.h"
#include "eeprom_seq.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		: 读取所有到ram,顺序执行
----------------------------------------------------------------------------*/
void eeprom_read_all_data_to_ram_seq(u8 area_id)
{
	u16 i;

	for(i=0u;i<EEPROM_AREAx_ADDR_TOTAL_U32(area_id);i++)
	{
		g_eeprom_ext[area_id].cmd_eeprom_result =eeprom_read_one_element(area_id,i,&g_logic_page_read_data[area_id]);
		{
			if(g_eeprom_ext[area_id].cmd_eeprom_result == EFLASH_READ_OK)
			{
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[12]++;
				#endif
			}
			else
			{
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[13]++;
				#endif
			}
		}
		common_memory_copys((u8*)&g_ram_for_eeprom[area_id][4u*i],(u8*)&g_logic_page_read_data[area_id],EEPROM_READ_U32_NUM);
	}
	g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;

}

/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		: 转移
----------------------------------------------------------------------------*/
uint8_t eeprom_page_transfer_seq(u8 area_id,u16 virt_addr, u32 data)
{
	u16 l_valid_page = EFLASH_PAGE0;
	uint8_t l_status_res = EFLASH_STATUS_BUSY;
	u16 ReadStatus = 0;
	u32 DataVar;
	u8  i;

	if(g_eeprom_ext[area_id].transfer_state == EFLASH_PAGE_TRANSFER_STATE_WRITE_NEW_DATA)
	{
		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 (uint8_t)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  //把另外4字节用起来
		l_status_res = eeprom_program_u32(g_eeprom_ext[area_id].page_addr_new+EFLASH_OPERATION_LEN, EFLASH_RECEIVE_DATA);
		#endif
		if (l_status_res != EFLASH_STATUS_SUCCESS)
		{
			#ifdef EEPROM_EXT_DEBUG_EN
			g_eeprom_ext_test[area_id].test_count[14]++;
			#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[15]++;
			#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[16]++;
		#endif
	}

	if(g_eeprom_ext[area_id].transfer_state == EFLASH_PAGE_TRANSFER_STATE_COPY)
	{
		/* Transfer process: transfer variables from old to the new active page */
		do
		{
			for (i = 0u; i < 4u; i ++)
			{
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[17]++;
				#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[18]++;
					#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[19]++;
						#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[20]++;
							#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[21]++;
						#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[22]++;
				  #endif
				  break;
				}
			}
		}while(g_eeprom_ext[area_id].transfer_state==EFLASH_PAGE_TRANSFER_STATE_COPY);
	}

	if(g_eeprom_ext[area_id].transfer_state == EFLASH_PAGE_TRANSFER_STATE_ERASE)
	{
		do
		{
			l_status_res = eeprom_erase_page((u32)g_eeprom_ext[area_id].page_addr_old + \
						  (u32)g_eeprom_ext[area_id].eflash_page_index * (u32)EFLASH_PAGE_SIEZ);
			if (l_status_res != EFLASH_STATUS_SUCCESS)
			{
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[23]++;
				#endif
				return l_status_res;
			}
			#ifdef EEPROM_EXT_DEBUG_EN
			g_eeprom_ext_test[area_id].test_count[24]++;
			#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[25]++;
				#endif
				break;
			}
			else
			{
				l_status_res = EFLASH_STATUS_BUSY;
				#ifdef EEPROM_EXT_DEBUG_EN
				g_eeprom_ext_test[area_id].test_count[26]++;
				#endif
			}
		}while(1);

	}
	return (l_status_res);
}

#if 0
/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	: virt_addr: Variable virtual address
						data: 16 bit data to be written
|Output parameters	:
|Return value		:
|Description		: 顺序执行
----------------------------------------------------------------------------*/
u16 eeprom_write_one_element_seq(u8 area_id,u16 virt_addr, u32 data)
{
	u16 l_status = 0;
	u16 l_valid_page = EFLASH_PAGE0;

	l_valid_page = eeprom_find_valid_page(area_id,EFLASH_WRITE_IN_VALID_PAGE);

	if (l_valid_page == EFLASH_NO_VALID_PAGE)
	{
		#ifdef EEPROM_EXT_DEBUG_IO_EN
		EEPROM_EXT_TEST1_ON(area_id);
		#endif
		eeprom_format(area_id);
		#ifdef EEPROM_EXT_DEBUG_IO_EN
		EEPROM_EXT_TEST1_OFF(area_id);
		#endif
		g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
		#ifdef EEPROM_OPTIMIZE_SEARCH_FAST
		eeprom_get_current_page_addr(area_id,&g_eeprom_ext[area_id].current_page,&g_eeprom_ext[area_id].current_end_addr);
		#endif
		#ifdef EEPROM_EXT_DEBUG_EN
		g_eeprom_ext_test[area_id].test_count[27]++;
		#endif
	}
	#ifdef EEPROM_EXT_DEBUG_IO_EN
	EEPROM_EXT_TEST1_ON(area_id);
	#endif
	l_status =  eeprom_verify_page_ful_write_one_ele(area_id,l_valid_page, virt_addr, data);
	#ifdef EEPROM_EXT_DEBUG_IO_EN
	EEPROM_EXT_TEST1_OFF(area_id);
	#endif
	if(l_status == EFLASH_STATUS_PPADRER_ERROR)
	{
		#ifdef EEPROM_EXT_DEBUG_IO_EN
		EEPROM_EXT_TEST1_ON(area_id);
		#endif
		eeprom_format(area_id);
		#ifdef EEPROM_EXT_DEBUG_IO_EN
		EEPROM_EXT_TEST1_OFF(area_id);
		#endif
		//EFLASH_SetCtrlReg1(0x0);
		//EFLASH_LockCtrl();  //TEMP_CLOSE 这些不知道怎么修改
		g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
		#ifdef EEPROM_OPTIMIZE_SEARCH_FAST
		eeprom_get_current_page_addr(area_id,&g_eeprom_ext[area_id].current_page,&g_eeprom_ext[area_id].current_end_addr);
		#endif
		#ifdef EEPROM_EXT_DEBUG_EN
		g_eeprom_ext_test[area_id].test_count[28]++;
		#endif
		//break;
	}
	if(l_status == EFLASH_PAGE_FULL)
	{
		//l_timeout = 0;
		#ifdef EEPROM_EXT_NOT_TRANS_MORE_WHEN_FULL
		if( g_eeprom_ext[area_id].page_addr_cur_total >= (g_eeprom_user_info[area_id].mass_page_addr_total_u32) )
		{
			#ifdef EEPROM_EXT_DEBUG_EN
			g_eeprom_ext_test[area_id].test_count[29]++;
			#endif
			g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
			#ifdef EEPROM_OPTIMIZE_SEARCH_FAST
			eeprom_get_current_page_addr(area_id,&g_eeprom_ext[area_id].current_page,&g_eeprom_ext[area_id].current_end_addr);
			#endif
		}
		else
		#endif
		{
			g_eeprom_ext[area_id].state = EFLASH_STATE_PAGE_TRANSFER;
			g_eeprom_ext[area_id].transfer_state = EFLASH_PAGE_TRANSFER_STATE_WRITE_NEW_DATA;
		}
		#ifdef EEPROM_EXT_DEBUG_EN
		g_eeprom_ext_test[area_id].test_count[30]++;
		#endif
	}
	else
	{
		#ifdef EEPROM_OPTIMIZE_SEARCH_FAST
		eeprom_get_current_page_addr(area_id,&g_eeprom_ext[area_id].current_page,&g_eeprom_ext[area_id].current_end_addr);
		#endif
		g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
		#ifdef EEPROM_EXT_DEBUG_EN
		g_eeprom_ext_test[area_id].test_count[31]++;
		#endif
	}
	if(g_eeprom_ext[area_id].state == EFLASH_STATE_PAGE_TRANSFER)
	{
		//virt_addr =virt_addr;// g_eeprom_ext[area_id].page_cur_id;
		//data = g_logic_page_write_data[area_id];
		l_status = eeprom_page_transfer_seq(area_id,virt_addr, data);
		if(l_status == EFLASH_STATUS_SUCCESS)
		{
			g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
			#ifdef EEPROM_EXT_DEBUG_EN
			g_eeprom_ext_test[area_id].test_count[32]++;
			#endif
		}
		if(l_status == EFLASH_STATUS_PPADRER_ERROR)
		{
			#ifdef EEPROM_EXT_DEBUG_IO_EN
			EEPROM_EXT_TEST1_ON(area_id);
			#endif
			eeprom_format(area_id);
			#ifdef EEPROM_EXT_DEBUG_IO_EN
			EEPROM_EXT_TEST1_OFF(area_id);
			#endif
			//EFLASH_SetCtrlReg1(0x0);
			//EFLASH_LockCtrl(); //TEMP_CLOSE 这些不知道怎么修改
			g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
			#ifdef EEPROM_EXT_DEBUG_EN
			g_eeprom_ext_test[area_id].test_count[33]++;
			#endif
		}
		//l_timeout ++;
		if( (l_status != EFLASH_STATUS_BUSY && l_status != EFLASH_STATUS_SUCCESS))
		{
			//EFLASH_SetCtrlReg1(0x0);
			//EFLASH_LockCtrl(); //TEMP_CLOSE 这些不知道怎么修改
			g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
			#ifdef EEPROM_EXT_DEBUG_EN
			g_eeprom_ext_test[area_id].test_count[34]++;
			#endif
		}
		#ifdef EEPROM_EXT_DEBUG_EN
		g_eeprom_ext_test[area_id].test_count[35]++;
		#endif
		#ifdef EEPROM_OPTIMIZE_SEARCH_FAST
		if(g_eeprom_ext[area_id].state==EFLASH_STATE_IDLE)
		{
			eeprom_get_current_page_addr(area_id,&g_eeprom_ext[area_id].current_page,&g_eeprom_ext[area_id].current_end_addr);
		}
		#endif
	}
	//
	/* Return last operation status */
	return l_status;
}
#endif

#if 1
/*---------------------------------------------------------------------------
|Prototype			:
|Called by			:
|Preconditions		:
|Input parameters	:
|Output parameters	:
|Return value		:
|Description		: 转移--上电继续
----------------------------------------------------------------------------*/
uint8_t eeprom_reset_page_transfer_continus(u8 area_id,u16 virt_addr, u32 data)
{
	uint8_t l_status_res = eeprom_page_transfer_seq(area_id,virt_addr,data);
	if (l_status_res != EFLASH_STATUS_SUCCESS)
	{
		//全部擦除
	}
	g_eeprom_ext[area_id].state = EFLASH_STATE_IDLE;
	return l_status_res;
}
#endif
//#endif


#endif


