//-------------------------------------------------------------------------*
//文件名: Flash.c                                                          *
//说  明: SCI构件函数源文件                                                *
//-------------------------------------------------------------------------*

//头文件
#include "Flash.h"
#include "Includes.h"

#define Page_Erase   ((unsigned char(*)(unsigned int))(PGM))
#define Program_Byte ((unsigned char(*)(unsigned int, unsigned char))(PGM))
 
//擦除或写入函数的操作代码指令对应的机器码
volatile unsigned char PGM[57]  = { 
0x87,0xc6,0x18,0x25,0xa5,0x10,0x27,0x08,0xc6,0x18,
0x25,0xaa,0x10,0xc7,0x18,0x25,0x9e,0xe6,0x01,0xf7,
0xa6,0x40,0xc7,0x18,0x26,0x45,0x18,0x25,0xf6,0xaa,
0x80,0xf7,0x9d,0x9d,0x9d,0x9d,0xc6,0x18,0x25,0xa5,
0x30,0x27,0x04,0xa6,0x01,0x8a,0x81,0xc6,0x18,0x25,
0xa5,0x40,0x27,0xf9,0x4f,0x8a,0x81  
};

//-------------------------------------------------------------------------*
//函数名: FlashInit                                                        *
//功  能: 初始化Flash时钟分频、禁止保护                                    *
//参  数: busclk: 总线频率(单位Khz)                                        *
//返  回: 无                                                               *
//说  明: (1)请注意入口参数busclk(总线频率)的单位是Khz                     *
//        (2)AW60主频取值:20MHz,10MHz,8MHz,4MHz,2MHz,1MHz,200kHz,15kHz     *
//-------------------------------------------------------------------------*
void FlashInit(uint32 busclk)
{
    uint8 div6;
    
    //根据总线频率,设置Flash分频寄存器
    if(busclk>10*1000)
    {
       FeedDog();
       FCDIV |= (1<<6);          //置PRDIV8=1 
       div6 = 12;                //最高主频为20MHz
    }
    else if(busclk>=1000)
    {
        FeedDog();
        FCDIV &= ~(1<<6);        //清PRDIV8=0 
        div6 = (busclk/1000)*5-1;
    }
    else
    {
        FeedDog();
        FCDIV &= ~(1<<6);        //清PRDIV8=0 
        div6 = 0;
    }  
    FCDIV |= div6;               //设置Flash分频寄存器
    FeedDog();
}
   
//-------------------------------------------------------------------------*
//函数名: Flash_PageErase                                                  *
//功  能: Flash页擦除                                                      *
//参  数: pageNo:页号(从5开始)                                             *
//返  回: 0 - 成功,1 - 失败                                                *
//说  明: 无                                                               *
//-------------------------------------------------------------------------*
uint8 Flash_PageErase(uint8 pageNo)
{
    uint16 pageAddr;
    uint8  rtnValue;
    FeedDog();
    pageAddr= pageNo*512;            //根据页号计算页内地址
    PGM[21] = 0x40;                  //设置页擦除指令
    FeedDog();
    rtnValue = Page_Erase(pageAddr); //擦除addr所在的页           
    return rtnValue;
}

//-------------------------------------------------------------------------*
//函数名: Flash_ByteWrite                                                  *
//功  能: Flash字节写入                                                    *
//参  数:       buff: 源数据缓冲区地址                                     *
//            pageNo: 要写入的Flash的页号                                  *
//        startSAddr: 要写入的Flash页内地址                                *
//               len: 写入字节数                                           *
//返  回: 0 - 成功,1 - 失败                                                *
//说  明: (1) Flash 写入时，未将页内其他位置数据进行保护，原因 RAM一共2KB，*
//            若进行了保护，则需要开辟512B的缓冲区 很容易出现内存溢出      *                                                         *
//-------------------------------------------------------------------------*
uint8 Flash_ByteWrite(uint8 *buff,uint16 pageNo,uint16 startAddr,uint16 len)
{
    uint16 i;
    uint16 flashaddr;
    uint8  rtnValue;
    
    //1.计算写入地址
    FeedDog();
    flashaddr = pageNo*512 + startAddr; 
    
    //2.逐个字节写入数据
    for(i=0; i<len; i++) 
    {
        FeedDog();
        PGM[21]  = 0x20;
        FeedDog();                             //字节编程指令 
        rtnValue = Program_Byte(flashaddr+i,buff[i]);//执行写入操作
        FeedDog();
        if(rtnValue)
            return 1; 
    }
    return 0;
    FeedDog();
} 

//-------------------------------------------------------------------------*
//函数名: Flash_Secure                                                     *	
//功  能: 加密Flash,同时设置加密密码(后门机制)                             *
//返  回: 0=成功                                                           * 
//        1=擦除失败                                                       *
//        2=写入失败                                                       *
//        3=已设置块保护,无法修改                                          *
//说  明: (1)只有芯片复位后,设置才生效                                     *
//内部调用: Flash_PageErase,Flash_ByteWrite                                *
//-------------------------------------------------------------------------*
uint8 Flash_Secure(uint8 key[]) 
{
   	uint8 vecdata[512];
	  uint8 * addr;
	  uint16 i;
	  uint8 rtnValue=0;
	   FeedDog();
	//1.检查是否已设置块保护
    if((FPROT & 0x01)==0) //已设置块保护
    {
        FeedDog();
        rtnValue = 3;                 //已设置块保护,无法修改
        goto Flash_Secure_Exit;
    }

    //2.复制中断向量表(Flash第127页)至RAM
	addr = (uint8 *)0xFE00;
	for(i=0;i<512;i++)
	{
	    FeedDog();
	    vecdata[i] = addr[i];
	}
	//3. 设置密钥
	for(i=0;i<8;i++)
	{
	    FeedDog();
	    vecdata[432+i] = key[i];  //后门密钥
	}
	//4. 设置保护块
	FPROT = 0xFF;
	FeedDog();
	vecdata[445] = 0b11111111;//设置块保护寄存器
    //               ||||||||__/FPDIS=1:禁止块保护  
    //               |||||||   \FPDIS=0:保护FPS7~FPS1之后的地址 
    //               |||||||___ FPS1
    //               ||||||____ FPS2
    //               |||||_____ FPS3        
    //               ||||______ FPS4
    //               |||_______ FPS5
    //               ||________ FPS6  
    //               |_________ FPS7                 
    //5. 设置寄存器NVOPT/FOPT
    FeedDog();
	vecdata[447] = 0b11000001;
    //               ||    ||__SEC00  (SEC01:SEC00=1:0是为非保密状态，
    //               ||    |___SEC01   其他为保密状态)
    //               ||
    //               ||________/FNORED=1:禁止向量重定向;
    //               |         \FNORED=0:允许向量重定向;
    //               |
    //               |_________/KEYEN=1:允许后门密钥;
    //                         \KEYEN=0:禁止后门密钥
    //6. 擦除
    rtnValue=Flash_PageErase(127);//擦除最后一页
    if(rtnValue!=0)
    {
        rtnValue = 1;              //擦除失败
        goto Flash_Secure_Exit;
    }	
	//7. 写入,将配置好的参数写入Flash
	rtnValue=Flash_ByteWrite(vecdata,127,0,512);
	FeedDog();
	if(rtnValue!=0)
    {
        FeedDog();
        rtnValue = 2;              //写入失败
        goto Flash_Secure_Exit;
    }
FeedDog(); 
Flash_Secure_Exit://函数出口
FeedDog();
	return rtnValue;
	FeedDog();
}

//-------------------------------------------------------------------------*
//函数名: Flash_SetBlockProtect                                            *	
//功  能: 设置块保护                                                       *
//参  数: pageNo:页号(4~127)                                               *
//        protectFlag:0=设置块保护;1=禁止块保护                            *                  
//返  回: 0=成功                                                           * 
//        1=擦除失败                                                       *
//        2=写入失败                                                       *
//说  明: (1)只有芯片在加密状态下,才可以进行块保护                         *
//        (2)若上一次操作已经使得芯片块保护,则此次只能将FPROT的地址改小,   *
//           而且不能修改NVPROT的内容                                      *   
//        (3)若FPROT的最后1位为1(即块保护未生效),则可以任意修改块保护的地址*
//内部调用: Page_Erase,Flash_Page_Write                                    *
//-------------------------------------------------------------------------*
uint8 Flash_SetBlockProtect(uint8 pageNo,uint8 protectFlag)
{ 
  uint8 vecdata[512];
	uint8 * addr;
	uint16 i;
	uint8 rtnValue=0;
    FeedDog();
    //1. 复制中断向量表(Flash第127页)至RAM中
	addr = (uint8 *)0xFE00;
	for(i=0;i<512;i++)
	{
	    FeedDog();
      vecdata[i] = addr[i];
	}
	//2. 若芯片未加密,则需要先加密以后再设置块保护   
	if((FOPT & 0x03)==0x02)//芯片未加密
	{
	    FeedDog();
    	vecdata[447] = 0b11000001;//设置寄存器NVOPT/FOPT
        //               ||    ||__SEC00  (SEC01:SEC00=1:0是为非保密状态，
        //               ||    |___SEC01   其他为保密状态)
        //               ||
        //               ||________/FNORED=1:禁止向量重定向;
        //               |         \FNORED=0:允许向量重定向;
        //               |
        //               |_________/KEYEN=1:允许后门密钥;
        //                         \KEYEN=0:禁止后门密钥
	}
	//3. 设置保护块
    //   根据页号计算详细地址
    //   例如:要保护第9页及其以后的页
    //   第9页的地址范围:0x1200-0x13FF,0x1200的前一个地址为0x11FF,
    //   所以FPS7~FPS1是除去0x11FF低9位后剩余的值,即0001 000
    FeedDog();	
	vecdata[445] = (pageNo<<1)-1;//根据页号计算详细地址
	FeedDog();
    if(0 == protectFlag)
    {
        FeedDog();
        vecdata[445] &= 0xFE;    
    }
    //FOPT = vecdata[445];//该设置无效, FOPT需要将MCU重新复位后,方可改变
    
    //4. 若芯片已经设置块保护，则只能临时修改保护区域
    FeedDog();
	if((FPROT & 0x01)==0)
    {
        FeedDog();
        FPROT = vecdata[445];           //设置块保护寄存器
        goto Flash_SetBlockProtect_Exit;
    }
    //5. 擦除
    FeedDog();
    rtnValue=Flash_PageErase(127);
    FeedDog();
    if(rtnValue!=0)
    {    
        FeedDog();
        rtnValue = 1;                   //擦除失败
        goto Flash_SetBlockProtect_Exit;
    }	
	//6. 写入
	FeedDog();
	rtnValue=Flash_ByteWrite(vecdata,127,0,512);
	FeedDog();
	if(rtnValue!=0)
    {
        FeedDog();
        rtnValue = 2;                   //写入失败
        goto Flash_SetBlockProtect_Exit;
    }
FeedDog(); 
Flash_SetBlockProtect_Exit:             //函数出口
    return rtnValue;
    FeedDog();
}

//-------------------------------------------------------------------------*
//函数名: Flash_KEY_Match                                                  *	
//功  能: 后门密钥匹配                                                     *
//参  数: key[]:8个字节密钥                                                *		
//返  回: 0=成功                                                           * 
//        1=未使能后门机制                                                 *
//        2=密钥错误                                                       *
//内部调用:                                                                *
//-------------------------------------------------------------------------*
uint8 Flash_KEY_Match(uint8 key[])
{
	uint8 * addr;
	uint16 i;
	uint8  rtnValue=0;
    
    //1. 判断是否使能后门机制
    //寄存器NVOPT/FOPT的KEYEN位为0时，后门机制无效，
    //但是如果KEYEN位为1时，用户按照如下的方法取消MCU的保密状态
    if((FOPT & (1<<7)) == 0)
    {
        FeedDog();
        rtnValue = 1;        //未使能后门机制
        goto Flash_KEY_Match_Exit;
    }
    //2. 置FCNFG的KEYACC位为1
    FCNFG |= (1<<KEYACC); //BSET(KEYACC,FCNFG);
      
    //3. 修改密钥
    //向NVBACKKEY~NVBACKKEY+7的位置(即$FFB0~$FFB7)依次写入8个字节
    addr = (uint8 *)0xFFB0;//密钥首地址
	for(i=0;i<8;i++)
	{
	    FeedDog();
	    addr[i] = key[i];    //写入密钥
	}
    //4. 将FCNFG的KEYACC位清0  
    FCNFG &= ~(1<<KEYACC);  //BCLR(KEYACC,FCNFG);   
    //延时
    FeedDog();
    for(i=0;i<10;i++);
    FeedDog();
    for(i=0;i<10;i++);
    //5.检查密钥是否正确
    //  若用户写入的8字节密钥和NVBACKKEY~NVBACKKEY+7本身的8字节密钥一致,
    //  则MCU会将SEC01:SEC00改写成1:0,从而取消MCU的保密性。
    FeedDog();
 
    if((FOPT & 0x03)!=0x02)
        rtnValue = 2;       //密钥错误
 FeedDog();       
Flash_KEY_Match_Exit:       //函数出口
	return rtnValue;
	FeedDog();
}

//-------------------------------------------------------------------------*
//函数名: Flash_Key_Delete                                                 *	
//功  能: 加密Flash,同时设置加密密码(后门机制)                             *
//返  回: 0=成功                                                           * 
//        1=擦除失败                                                       *
//        2=写入失败                                                       *
//        3=已设置块保护,无法删除                                          *
//说  明: (1)只有芯片复位后,设置才生效                                     *
//内部调用: Flash_PageErase,Flash_ByteWrite                                *
//-------------------------------------------------------------------------*
uint8 Flash_Key_Delete() 
{
  uint8 vecdata[512];
	uint8 * addr;
	uint16 i;
	uint8 rtnValue=0;

    //1.检查是否已设置块保护
    FeedDog();
    if((FPROT & 0x01)==0) //已设置块保护
    {
        FeedDog();
        rtnValue = 3;                  //已设置块保护,无法删除密钥
        goto Flash_Key_Delete_Exit;
    }
    
    //2.复制中断向量表(Flash第127页)至RAM
    FeedDog();
	addr = (uint8 *)0xFE00;
	FeedDog();
	for(i=0;i<512;i++)
	{
	    FeedDog();
	    vecdata[i] = addr[i];
	}
	//3. 设置密钥
	for(i=0;i<8;i++)
	{
	    FeedDog();
	    vecdata[432+i] = 0xFF;  //后门密钥
	}               
    //4. 设置寄存器NVOPT/FOPT
    FeedDog();
	vecdata[447] = 0b11000001;
    //             ||    ||__SEC00  (SEC01:SEC00=1:0是为非保密状态，
    //             ||    |___SEC01   其他为保密状态)
    //             ||
    //             ||________/FNORED=1:禁止向量重定向;
    //             |         \FNORED=0:允许向量重定向;
    //             |
    //             |_________/KEYEN=1:允许后门密钥;
    //                       \KEYEN=0:禁止后门密钥
    //5. 擦除
    FeedDog();
    rtnValue=Flash_PageErase(127); //擦除最后一页
    FeedDog();
    if(rtnValue!=0)
    {
        FeedDog();
        rtnValue = 1;              //擦除失败
        goto Flash_Key_Delete_Exit;
    }	
	//6. 写入,将配置好的参数写入Flash
	FeedDog();
	rtnValue=Flash_ByteWrite(vecdata,127,0,512);
	FeedDog();
	if(rtnValue!=0)
    {
        FeedDog();
        rtnValue = 2;              //写入失败
        goto Flash_Key_Delete_Exit;
    }
FeedDog(); 
Flash_Key_Delete_Exit://函数出口
FeedDog();
	return rtnValue;
	FeedDog();
}

//-------------------------------------------------------------------------*
//函数名: Flash_UnSecure                                                   *	
//功  能: 加密Flash,同时设置加密密码(后门机制)                             *
//返  回: 0=成功                                                           * 
//        1=擦除失败                                                       *
//        2=写入失败                                                       *
//        3=已设置块保护,无法修改                                          *
//说  明: (1)只有芯片复位后,设置才生效                                     *
//内部调用: Flash_PageErase,Flash_ByteWrite                                *
//-------------------------------------------------------------------------*
uint8 Flash_UnSecure() 
{
   	uint8 vecdata[512];
	uint8 * addr;
	uint16 i;
	uint8 rtnValue=0;
	
	//1.检查是否已设置块保护
	FeedDog();
    if((FPROT & 0x01)==0) //已设置块保护
    {
        FeedDog();
        rtnValue = 3;                  //已设置块保护,无法修改
        goto Flash_UnSecure_Exit;
    }
    FeedDog();
    //2.复制中断向量表(Flash第127页)至RAM
	addr = (uint8 *)0xFE00;
	for(i=0;i<512;i++)
	{
	    FeedDog();
	    vecdata[i] = addr[i];
	}   
	FeedDog();            
    //3. 设置寄存器NVOPT/FOPT
	vecdata[447] = 0b01000010;
    //               ||    ||__SEC00  (SEC01:SEC00=1:0是为非保密状态，
    //               ||    |___SEC01   其他为保密状态)
    //               ||
    //               ||________/FNORED=1:禁止向量重定向;
    //               |         \FNORED=0:允许向量重定向;
    //               |
    //               |_________/KEYEN=1:允许后门密钥;
    //                         \KEYEN=0:禁止后门密钥
    //4. 擦除
    rtnValue=Flash_PageErase(127);//擦除最后一页
    FeedDog();
    if(rtnValue!=0)
    {
        FeedDog();
        rtnValue = 1;              //擦除失败
        goto Flash_UnSecure_Exit;
    }	
	//5. 写入,将配置好的参数写入Flash
	FeedDog();
	rtnValue=Flash_ByteWrite(vecdata,127,0,512);
	FeedDog();
	if(rtnValue!=0)
  {
       FeedDog();
       rtnValue = 2;              //写入失败
       goto Flash_UnSecure_Exit;
  }
  FeedDog(); 
  Flash_UnSecure_Exit://函数出口
	return rtnValue;
	FeedDog();
}
void Display_Flash_Help() 
{
    SCISendString(1," Erase E:8\r\n");
    SCISendString(1," read R:8:0:8\r\n");
    SCISendString(1," write W:8:0:4:1,2,3,4\r\n");
    SCISendString(1," setting key B:8,7,6,");
    SCISendString(1,"5,4,3,2,1\r\n");
    SCISendString(1," key verification M:8,7,6,5,4,3,2,1\r\n");
    SCISendString(1," Key delete D\r\n");
    SCISendString(1," Encryption lifted U\r\n");
    SCISendString(1," block protection P:8\r\n");
}
void Display_Flash_E(uint16 len,uint8 FBuff[])            //Flash擦除功能
{
    uint8 i;
    uint16 count,state,cmd,page;
    uint8  rev[512];
    uint16 pstartadd;
    uint32 addr;
    i=0;
    count=0;
    page = 0;
    pstartadd = 0;
    FeedDog();
    //接收串口数据 
    for(i=2;i<=len;i++)
    {
        FeedDog();
        rev[count++] = FBuff[i];
    }
    //计算地址
    i=0;
    while(i<(count-1))
    {
        FeedDog();
        page = page*10 +rev[i++]-'0';
    }
    //擦除flash
    FeedDog();
    state = Flash_PageErase(page);
    FeedDog();
    if(state == 0) 
    {
        FeedDog();
        SCISendString(1," Erase Succeed\r\n");
    }
    else
    {
        SCISendString(1," Erase Failed\r\n");
    }
          
}
void Display_Flash_W(uint16 len,uint8 FBuff[])            //Flash写入功能
{
    uint8 i;
    uint16 j,count,state,cmd,page;
    uint8  rev[512],writebuf[512];
    uint16 pstartadd;
    uint32 addr;
    count=0;
    i=0;
    pstartadd = 0;
    FeedDog();
    page=0;
    //接收串口数据     
    for(i=2;i<=len;i++)
    {
        FeedDog();
    		rev[count++] = FBuff[i];
    }
    FeedDog();	
    i = 0;
    //计算页号
    while(rev[i] != ':')
    {
    		FeedDog();
    		page = page *10 +rev[i++]-'0';
    }
    i++;
    //计算页内开始写的偏移地址
    while(rev[i] != ':')
    {
    		FeedDog();
    		pstartadd = pstartadd *10 +rev[i++]-'0';
    }
    i++;
    FeedDog();
    			           //计算要写的字节个数
    len=0;
    while(rev[i] != ':')
    {
    		FeedDog();
    		len = len *10 +rev[i++]-'0';  
    }
    i++;
    //取得要写入的数据
    j = 0;
    FeedDog();
    while(i<(count-1))
    {
    		FeedDog();
    		if(rev[i] == ',')
    		{
    		    i++; 
    		}    			        
    		else
    		{
    			  FeedDog();
    			  writebuf[j] = rev[i];
    			  j++; i++;
    		}
    }
    //写入Flash	
    FeedDog();
		state = Flash_ByteWrite((uint8*)&writebuf[0],page,pstartadd,len);
		SCISendN(1,len,writebuf);
		FeedDog();
		if(0 == state) 
		{

		    SCISendString(1," Write Succeed\r\n");
		}      
		else 
		{
				SCISendString(1," Write Failed\r\n");
		}
}
void Display_Flash_R(uint16 len,uint8 FBuff[])            //Flash读出功能
{
    uint8 i;
    uint16 count,state,cmd,page;
    uint8  rev[512],writebuf[512];
    uint16 pstartadd;
    uint32 addr;
    count=0;
    i=0;
    pstartadd = 0;
    FeedDog();
    page=0;
    //接收串口数据
    for(i=2;i<=len;i++)
    {
        FeedDog();
        rev[count++] = FBuff[i];
    }
    //计算页号
    i = 0;
    while(rev[i] != ':')
    {
    		FeedDog();
    		page = page*10 +rev[i++]-'0';
    }
    i++;
    //计算开始地址
    while(rev[i] != ':')
    {
    		FeedDog();
    		pstartadd = pstartadd*10 +rev[i++]-'0';
    }
    i++;
    //计算读的字节个数
    len=0;
    while((rev[i] >= '0')&&(rev[i] <= '9')&&(i<count))
    {
    		FeedDog();
    		len = len*10 +rev[i++]-'0';  
    }
    SCISendString(1," R:");
    SCISendN(1,len-4,(uint8*)(page*512+pstartadd));
    SCISendString(1,"\r\n");
}
void Display_Flash_B(uint16 len,uint8 FBuff[])            //Flash设置后门密钥功能
{
    uint8 i;
    uint16 j,count,state,cmd,page;
    uint8  rev[512],writebuf[512];
    uint16 pstartadd;
    uint32 addr;
    count=0;
    i=0;
    pstartadd = 0;
    FeedDog();
    page=0;
    //接收串口数据   
    for(i=2;i<=len;i++)
    {
        FeedDog();
    		rev[count++] = FBuff[i];
    }
    FeedDog();	
    //取得要写入的数据
    i = 0;
    j = 0;
    while(i<(count-1))
    {
    		FeedDog();
    		if(rev[i] == ',')
    		{
    		    i++;
    			  continue;
    		}    			        
    		else
    		{
    		    writebuf[j++] = rev[i++];
    		}
    }
    //设置后门密钥
    state = Flash_Secure((uint8*)&writebuf);    
    if(state == 0)
    {
        SCISendString(1,"Set Backdoor Key Succeed\r\n");
    }
    else if(1 == state)
    {
        SCISendString(1,"Set Backdoor Key Failed--Erase-Error\r\n");
    }
    else if(2 == state) 
    {
        SCISendString(1,"Set Backdoor Key Failed--Write-Error\r\n");
    }
    else if(3 == state) 
    {
        SCISendString(1,"Set Backdoor Key Failed--Block Protect-Error\r\n");
    }
    else 
    {
        SCISendString(1,"Set Backdoor Key Failed--Else-Error\r\n");
    }
}
void Display_Flash_M(uint16 len,uint8 FBuff[])            //Flash验证后门密钥功能
{
    uint8 i;
    uint16 j,count,state,cmd,page;
    uint8  rev[512],writebuf[512];
    uint16 pstartadd;
    uint32 addr;
    count=0;
    i=0;
    pstartadd = 0;
    FeedDog();
    page=0;
    //接收串口数据        
    for(i=2;i<=len;i++)
    {
        rev[count++] = FBuff[i];
    }	
    //取得要写入的数据
    i = 0;
    j = 0;
    while(i<(count-1))
    {
    		FeedDog();
    		if(rev[i] == ',')
    		{
    		    FeedDog();
    			  i++;
    			  continue;
    		}    			        
    		else
    		{
    			  FeedDog();
    			  writebuf[j++] = rev[i++];
    		}
    }
    FeedDog();
    state = Flash_KEY_Match(writebuf); //密钥匹配
    if(0 == state) 
    {
            SCISendString(1," KEY Match Succeed\r\n");
    }
    else if(1 == state) 
    {
            SCISendString(1," KEY Match Failed--Error-BackDoor Disable\r\n");
    }
    else if(2 == state) 
    {
            SCISendString(1," KEY Match Failed--Error-BackDoor Wrong\r\n");
    }
    else 
    {
            SCISendString(1," KEY Match Failed--Error-Else\r\n"); 
    }
}
void Display_Flash_D()            //Flash密钥删除功能
{
    uint16 state;
    state = Flash_Key_Delete();
    if(0 == state) 
    {
        SCISendString(1,"Delete key Succeed\r\n");
    }
    else if(1 == state) 
    {
        SCISendString(1,"Delete key Failed--Erase-Error\r\n");
    }
    else if(2 == state) 
    {
        SCISendString(1,"Delete key Failed--Write-Error\r\n");
    }
    else if(3 == state)
    {
        SCISendString(1,"Delete key Failed--Block Protect-Error\r\n");
    }
    else 
    {
        SCISendString(1,"Delete key Failed--Else-Error\r\n");
    }  
}
void Display_Flash_U()            //Flash加密解除功能
{
    uint16 state;
    state = Flash_UnSecure();
    if(0 == state) 
    {
        SCISendString(1,"UnSecure Succeed\r\n");
    }
    else if(1 == state) 
    {
        SCISendString(1,"UnSecure Failed--Erase-Error\r\n");
    }
    else if(2 == state) 
    {
        SCISendString(1,"UnSecure Failed--Write-Error\r\n");
    }
    else if(3 == state) 
    {
        SCISendString(1,"UnSecure Failed--Block Protect-Error\r\n");
    }
    else 
    {
        SCISendString(1,"UnSecure Failed--Else-Error\r\n");
    }
         
}   
void Display_Flash_P(uint16 len,uint8 FBuff[])            //Flash块保护功能
{
    uint8 i;
    uint16 tmp,j,count,state,cmd,page;
    uint8  rev[512];
    uint16 pstartadd;
    uint32 addr;
    count=0;
    i=0;
    pstartadd = 0;
    FeedDog();
    page=0;
    //接收串口数据      
    for(i=2;i<=len;i++)
    {
        rev[count++] = FlashBuff[i];
    }	
    i=0;
    //计算地址
    while(i<(count-1))
    {
    		FeedDog();
    		page = page*10 +rev[i++]-'0';
    }
    //块保护
    state = Flash_SetBlockProtect(page,0);
    FeedDog();
    if(0 == state) 
    {
        SCISendString(1,"Succeed to Set Block Protect\r\n");
    }
    else if(1 == state) 
    {
        SCISendString(1,"Failed to Set Block Protect--Erase-Error\r\n");
    }
    else if(2 == state) 
    {
        SCISendString(1,"Failed to Set Block Protect--Write-Error\r\n");
    }
    else 
    {
        SCISendString(1,"Failed to Set Block Protect--Else-Error\r\n");
    }     
}
void Display_Flash_K()            //Flash查看密钥功能 
{
    SCISendN(1,8,(uint8 *)0xFFB0);
}
void Display_Flash_S()            //Flash查看块保护地址和保密字节功能 
{
 
    SCISend1(1,FPROT );//FPROT  -保护页  *(uint8 *)0x1824
    SCISend1(1,NVPROT);//NVPROT *(uint8 *)0xFFBD
    SCISend1(1,FOPT);//FOPT keyen sec01 sec00  *(uint8 *)0x1821
    SCISend1(1,NVOPT);//NVOPT  *(uint8 *)0xFFBF
}



                         