/**************************** (C) COPYRIGHT 2017 Fortiortech shenzhen *****************************
* File Name          : FlashWrite.c
* Author             : 
* Version            : 
* Date               : 
* Description        : 
***************************************************************************************************
* All Rights Reserved
**************************************************************************************************/
#include <FU68xx_2.h>
#include <Myproject.h>

/*Private variables------------------------------------------------------------------------------*/
MCUFlash xdata FlashTest;

/*-------------------------------------------------------------------------------------------------
	Function Name :	uint16 GetLastDataFromFlash(uint8 xdata *BlockStartAddr)
	Description   :	从目标FLASH扇区读取2字节最新写入的数据
	Input         :	uint8 xdata *BlockStartAddr：目标FLASH扇区
	Output        :	读出的数据
-------------------------------------------------------------------------------------------------*/
uint16 Get2ByteFromFlash(uint8 xdata *BlockStartAddr)
{
	uint8 xdata *FlashStartAddr = BlockStartAddr;
	uint8 i;
	uint16 tempofFlashData;
	
	for(i=0;i<64;i++)
	{
		tempofFlashData = *(uint16 code *)(FlashStartAddr+2*i);
		if(tempofFlashData==0)
		{
			if(i!=0)
			{
				tempofFlashData = *(uint16 code *)(FlashStartAddr+2*(i-1));
				return tempofFlashData;
			}
			else
			{
				return 0;
			}
		}
		else
		{
			if(i==63)
			{
				return tempofFlashData;
			}
		}	
	}
	return 0;
}

/*-------------------------------------------------------------------------------------------------
	Function Name :	void WriteData2Flash(uint8 xdata *BlockStartAddr,uint16 NewData2Flash)
	Description   :	写入2个字节到FLASH
	Input         :	uint8 xdata *BlockStartAddr：目标FLASH地址  NewData2Flash：被写入数据
    Output		  :	1:扇区未满,写入完成  0:扇区已满,写入失败
-------------------------------------------------------------------------------------------------*/
uint8 Write2Byte2Flash(uint8 xdata *BlockStartAddr,uint16 NewData2Flash)
{
	uint8 xdata *FlashStartAddr = BlockStartAddr;
	uint16 tempofFlashData=0;
	uint16 tempofNewFlashData=0;
	uint8 i;
	
	tempofNewFlashData = NewData2Flash;
	
	for(i=0;i<64;i++)
	{
		tempofFlashData = *(uint16 code *)(FlashStartAddr+2*i);
		if(tempofFlashData==0)
		{
			tempofFlashData = tempofNewFlashData>>8;                            //待写入数据首字节
			Flash_Sector_Write((FlashStartAddr+2*i),(uint8)tempofFlashData);
			_nop_();
			tempofFlashData = tempofNewFlashData&0x00ff;                        //待写入数据末字节
			Flash_Sector_Write((FlashStartAddr+2*i+1),(uint8)tempofFlashData);
			_nop_();		

			return 1;
		}
		else
		{
			if(i==63)
			{
				return 0;
			}
		}
	}
	return 0;
}
/*-------------------------------------------------------------------------------------------------
    Function Name :	uint8 Get4ByteFromFlash(uint8 xdata *BlockStartAddr)
	Description   :	从目标FLASH扇区读取4字节最新写入的数据
	Input         :	uint8 xdata *BlockStartAddr：目标FLASH扇区
    Output		  :	读出的数据
-------------------------------------------------------------------------------------------------*/
uint32 Get4ByteFromFlash(uint8 xdata *BlockStartAddr)
{
	uint8 xdata *FlashStartAddr = BlockStartAddr;
	uint8 i;
	uint32 tempofFlashData;
	
	for(i=0;i<32;i++)
	{
		tempofFlashData = *(uint32 code *)(FlashStartAddr + 4*i);
		if(tempofFlashData==0)
		{
			if(i!=0)
			{
				tempofFlashData = *(uint32 code *)(FlashStartAddr + 4*(i-1));
				return tempofFlashData;
			}
			else
			{
				return 0;
			}
		}
		else
		{
			if(i==31)
			{
				return tempofFlashData;
			}
		}	
	}
	return 0;
}

/*-------------------------------------------------------------------------------------------------
	Function Name :	void Write4Byte2Flash(uint8 xdata *BlockStartAddr,uint32 NewData2Flash)
	Description   :	写入4个字节到FLASH
	Input         :	uint8 xdata *BlockStartAddr：目标FLASH地址  NewData2Flash：被写入数据
    Output		  :	无
-------------------------------------------------------------------------------------------------*/
void Write4Byte2Flash(uint8 xdata *BlockStartAddr,uint32 NewData2Flash)
{
	uint8 i;
    uint8 xdata *FlashStartAddr = BlockStartAddr;
	uint32 tempofFlashData=0;
	uint32 tempofNewFlashData=0;	
		
	tempofNewFlashData = NewData2Flash;
	
	for(i=0;i<32;i++)
	{
		tempofFlashData = *(uint32 code *)(FlashStartAddr+4*i);
		if(tempofFlashData==0)
		{
			tempofFlashData = (tempofNewFlashData>>24)&0x000000ff;
			Flash_Sector_Write((FlashStartAddr+4*i),(uint8)tempofFlashData);
			_nop_();
			tempofFlashData = (tempofNewFlashData>>16)&0x000000ff;
			Flash_Sector_Write((FlashStartAddr+4*i+1),(uint8)tempofFlashData);
			_nop_();
			tempofFlashData = (tempofNewFlashData>>8)&0x000000ff;
			Flash_Sector_Write((FlashStartAddr+4*i+2),(uint8)tempofFlashData);
			_nop_();
			tempofFlashData = tempofNewFlashData&0x000000ff;
			Flash_Sector_Write((FlashStartAddr+4*i+3),(uint8)tempofFlashData);
			_nop_();			
			break;
		}
		else
		{
			/*若扇区已写满,擦除后重新写入数据*/
            if(i==31)
			{
				Flash_Sector_Erase(FlashStartAddr);
				_nop_();
				tempofFlashData = (tempofNewFlashData>>24)&0x000000ff;
				Flash_Sector_Write((FlashStartAddr),(uint8)tempofFlashData);
				_nop_();
				tempofFlashData = (tempofNewFlashData>>16)&0x000000ff;
				Flash_Sector_Write((FlashStartAddr+1),(uint8)tempofFlashData);
				_nop_();
				tempofFlashData = (tempofNewFlashData>>8)&0x000000ff;
				Flash_Sector_Write((FlashStartAddr+2),(uint8)tempofFlashData);
				_nop_();
				tempofFlashData = tempofNewFlashData&0x000000ff;
				Flash_Sector_Write((FlashStartAddr+3),(uint8)tempofFlashData);
				_nop_();				
			}
		}
	}	
}

/*-------------------------------------------------------------------------------------------------
	Function Name :	void WriteOrReadFlashTest(uint8 xdata *BlockStartAddr,uint16 NewData2Flash)
	Description   :	FLASH读写数据测试,先把NewData2Flash写入到目标FLASH地址BlockStartAddr后,再将其
                    FLASH值读出来
	Input         :	uint8 xdata *BlockStartAddr：目标FLASH地址  NewData2Flash：被写入数据
    Output		  :	无
-------------------------------------------------------------------------------------------------*/
void WriteOrReadFlashTest(uint8 xdata *BlockStartAddr,uint16 NewData2Flash)
{
	uint8 FlashWriteStatus=0;

	if(FlashTest.FlashWrite)
	{
        FlashWriteStatus = Write2Byte2Flash(BlockStartAddr,NewData2Flash);
        if(!FlashWriteStatus)
        {
            //扇区写满时擦除扇区再写入
            Flash_Sector_Erase(BlockStartAddr);	
            FlashWriteStatus = Write2Byte2Flash(BlockStartAddr,NewData2Flash);				
        }			
		    FlashTest.FlashWrite = 0;
        FlashTest.FlashRead  = 1;
	}
    
   if(FlashTest.FlashRead)
	{	
		FlashTest.FlashRead2Byte = Get2ByteFromFlash(BlockStartAddr);
		FlashTest.FlashRead = 0;
	}
}
