#include "boot_macrodriver.h"
#include "pfdl.h"
#include "pfdl_types.h"
#include "pfdl_user.h"

/***********************************************************************************************************************
* Function Name: WriteDataflash
* Description  : 
* Arguments    : buffer: to be writed data; Addr:Target absolute address,must be check for different mcu;lenth:to be writed number,<=1024
* Return Value : PFDL_OK - 
                     Success
                 PFDL_IDLE -
				     Idling statement
			     PFDL_ERR_MARGIN - 
				     Blank check error
				     
				 other//if(Addr>=FLASH_START_ADDRESS&&Addr<FLASH_END_ADDRESS){				      
***********************************************************************************************************************/

/************************************************************************************
// 获取data Flash数据存取索引号														//
// 输入参数 code :  																//			
//			0 : 获取APP重编程请求标志索引号											//
//			1 : 获取2E服务0xF110的索引号                                            //
//			2 : 获取2E服务0xF190的索引号                                            //
//			3 : 获取2E服务0xF197的索引号                                            //
//			4 : 获取2E服务0xF198的索引号                                            //
//			5 : 获取2E服务0xF199的索引号                                            //
//			6 : 获取2E服务0xF19D的索引号                                    		//		
//                      7 : 获取2E服务0xF112的索引号                                                            //
//                      8 : 获取19服务0xF00616的索引号
//                      9 : 获取19服务0xF00617的索引号
//                      10: 获取19服务0x918112的索引号
//                      11: 获取19服务0x918114的索引号
//                      12: 获取19服务0x918171的索引号
//                      13: 获取19服务0x918312的索引号
//                      14: 获取19服务0x918314的索引号
//                      15: 获取19服务0x918371的索引号
//                      16: 获取19服务0x918412的索引号
//                      17: 获取19服务0x918414的索引号
//                      18: 获取19服务0x918471的索引号
//                      19: 获取19服务0x918611的索引号
//                      20: 获取19服务0x918614的索引号
//                      21: 获取19服务0xC07300的索引号
// 返回值：                                                                         //
//          2E 服务数据索引号                         								//
//                                                                                  //
************************************************************************************/

const fdl_index_t DF_INDEX_TAB[]={
	/*
	{0x000F1000,  8 + 1,},	// byte Power lost memory  0
	{0x000F1200,  4 + 1,},
	{0x000F1400,  4 + 1,},	// byte APP REProgrammer Request  1
	{0x000F1405,  8 + 1,},	// byte BLOCK_0xF110,  2
	{0x000F1408, 17 + 1,},	// byte BLOCK_0xF190,Z  3
	{0x000F1420,  8 + 1,},	// byte BLOCK_0xF197,  4
	{0x000F1800, 16 + 1,},	// byte BLOCK_0xF198,Z  5
	{0x000F1810,  4 + 1,},	// byte BLOCK_0xF199,Z  6
	{0x000F1814,  4 + 1,},	// byte BLOCK_0xF19D,Z  7
	{0x000F1444,  8 + 1,},	// byte BLOCK_0xF112, 
	*/
	{0x000F1000,  8 + 1,},	// byte Power lost memory
	
	{0x000F1400,  4 + 1,},	// byte APP REProgrammer Request
	{0x000F1410,  8 + 1,},	// byte BLOCK_0xF110,
	{0x000F1420, 17 + 1,},	// byte BLOCK_0xF190,
	{0x000F1440,  8 + 1,},	// byte BLOCK_0xF197,
	{0x000F1450, 16 + 1,},	// byte BLOCK_0xF198,
	{0x000F1460,  4 + 1,},	// byte BLOCK_0xF199,
	{0x000F1470,  4 + 1,},	// byte BLOCK_0xF19D,
	{0x000F1480,  8 + 1,},	// byte BLOCK_0xF112, 
	
	
	{0x000F1803,  2 + 1,},	// byte 19服务0xF00616
	{0x000F1806,  2 + 1,},	// byte 19服务0xF00617
	{0x000F1809,  2 + 1,},	// byte 19服务0x918112
	{0x000F180C,  2 + 1,},	// byte 19服务0x918114
	{0x000F180F,  2 + 1,},	// byte 19服务0x918171
	{0x000F1812,  2 + 1,},	// byte 19服务0x918312
	{0x000F1815,  2 + 1,},	// byte 19服务0x918314
	{0x000F1818,  2 + 1,},	// byte 19服务0x918371
	{0x000F181B,  2 + 1,},	// byte 19服务0x918412
	{0x000F181E,  2 + 1,},	// byte 19服务0x918414
	{0x000F1821,  2 + 1,},	// byte 19服务0x918471
	{0x000F1824,  2 + 1,},	// byte 19服务0x918611
	{0x000F1827,  2 + 1,},	// byte 19服务0x918614
	{0x000F182A,  2 + 1,},	// byte 19服务0xC07300
};


unsigned long GetDataFlashAddress(unsigned char code)
{
	return(DF_INDEX_TAB[code].addr);
}

unsigned char DF_Write(unsigned char* write_buf,unsigned char data_num,unsigned char len)
{
	unsigned char DF_Buf[128];
	unsigned char block_num,block_use,buf_addr;
	unsigned char sum,i = 0;
	unsigned long addr;
	
	addr = GetDataFlashAddress(data_num);
	
	block_num = (unsigned char)((addr - 0xF1000)>>10);
	
	if(0==block_num){
		block_use = DF_BLOCK0_USE;
	}
	else if(1==block_num){
		block_use = DF_BLOCK1_USE;
	}
	else if(2==block_num){
		block_use = DF_BLOCK2_USE;
	}
	else{
		block_use = 0xFF;
	}
	
	if(2 >= block_num){
		ReadFlashData(DF_Buf,(0x000F1000 + block_num*0x400),block_use);
				
		buf_addr = (unsigned char)(addr - (0x000F1000 + block_num*0x400));
		
		for(sum=0,i=0;i<len;i++)
		{
			DF_Buf[buf_addr + i] = *(write_buf+i);
			sum += *(write_buf+i);
		}
		
		sum = (sum^0xFF)+1;
		DF_Buf[buf_addr + i] = sum;
		
		if(WriteDataflash(DF_Buf,(0x000F1000 + block_num*0x400),block_use) == 0x11)
		{
			return 0;
		}
		else{
			return 0xFF;
		}
	}
	else{
		return 0xFF;
	}
}

unsigned char DF_Read(unsigned char* read_buf,unsigned char data_num,unsigned char len)
{
	unsigned char DF_Buf[128];
	unsigned char block_num,block_use,buf_addr;
	unsigned char sum,i = 0;
	unsigned long addr;
	
	addr = GetDataFlashAddress(data_num);
	
	block_num = (unsigned char)((addr - 0x000F1000)/0x400);
	
	if(0==block_num){
		block_use = DF_BLOCK0_USE;
	}
	else if(1==block_num){
		block_use = DF_BLOCK1_USE;
	}
	else if(2==block_num){
		block_use = DF_BLOCK2_USE;
	}
	else{
		block_use = 0xFF;
	}
	
	if(2 >= block_num){
		ReadFlashData(DF_Buf,(0x000F1000 + block_num*0x400),block_use);
				
		buf_addr = (unsigned char)(addr - (0x000F1000 + block_num*0x400));
		
		for(sum=0,i=0;i<len;i++)
		{
			sum += DF_Buf[buf_addr + i];
		}
		
		sum = (sum^0xFF)+1;
		
		if(DF_Buf[buf_addr + i] == sum){
			for(i=0;i<len;i++)
			{
				read_buf[i] = DF_Buf[buf_addr + i];
			}
			return 0;
		}		
		else{
			return 0xFF;
		}
	}
	else{
		return 0xFF;
	}
}

unsigned char DF_Write_All_DTC(unsigned char* write_buf,unsigned long addr,unsigned char len)
{
	uint8_t ret;
	
	ret = WriteDataflash(write_buf,addr,len);
	
	if(0x11 == ret){
		return (0);
	}
	else{
		return (ret);
	}
}

unsigned char DF_Read_All_DTC(unsigned char* read_buf,unsigned long addr,unsigned char len)
{
	ReadFlashData(read_buf,addr,len);
	
	return 0;
}

unsigned char GetProgrammingCounter(void)
{
	return *((__far uint8_t *)DID_0200_ADDR);
}

unsigned char GetProgrammingAttempCounter(void)
{
	return *((__far uint8_t *)DID_0201_ADDR);
}

