Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 
 

771 rader
17 KiB

#include "Updata.h"
#include "LT768_Lib.h"
#include "string.h"
#include "CRC.h"
#include "eflash_drv.h"
#include "Uart_Vcom.h"
#include "wdt_drv.h"
//extern u8  W25Q256; 	 
extern u8  Flash_type; 
//extern u32 Flash_size;
u32 Flash_ID = 0;
void num_to_char(char *buf,u8 num)
{
	if(num >= 100)
	{
		buf[0] = '1';
		buf[1] = '0';
		buf[2] = '0';
	}
	else if(num >=10)
	{
		buf[0] = ' ';
		buf[1] = (num / 10) + '0';
		buf[2] = (num % 10) + '0';
	}
	else
	{
		buf[0] = ' ';
		buf[1] = ' ';
		buf[2] = num + '0';
	}
	buf[3] = '%';
	buf[4] = '\0';
}
u8 buff[4*1024];
signed char Flash_Updata(const char *buf,char type)  //正确返回1,错误返回0
{
	u64 addr = 0;
	u8 num = 0;
	u32 block_num = 0;
	u32 blockremain = 0;
	u32 file_size = 0;
	u32 BIN_CRC = 0;
	u32 Check_BIN_CRC = 0;
	u32 Check_num = 0;
	
	char run_flag = 0;
	
	
	char showbuff[10];
	
	FATFS fs;
	FIL fsrc;
	FRESULT res;
	UINT br;
	f_mount(&fs,"0:",1);
	res = f_open(&fsrc, buf, FA_READ);
	if(res != FR_OK)
	{
		res = f_open(&fsrc, buf, FA_READ);
	}
	if(res == FR_OK)
	{
		file_size = f_size(&fsrc);
		
		if (Flash_ID == 0xef13)
		{
			if 
				(file_size > 1024*1024*1)
			{
				LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG");
				LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity");
				while(1) WDT_FeedDog();
			}
		}
		else if (Flash_ID == 0xef14)
		{
			if (file_size > 1024*1024*2)
			{
				LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG");
				LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity");
				while(1) WDT_FeedDog();
			}
		}
		else if (Flash_ID == 0xef15)
		{
			if (file_size > 1024*1024*4)
			{
				LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG");
				LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity");
				while(1) WDT_FeedDog();
			}
		}
		else if (Flash_ID == 0xef16)
		{
			if (file_size > 1024*1024*8)
			{
				LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG");
				LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity");
				while(1) WDT_FeedDog();
			}
		}
		else if (Flash_ID == 0xef17 || Flash_ID == 0x5e17)
		{
			if (file_size > 1024*1024*16)
			{
				LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG");
				LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity");
				while(1) WDT_FeedDog();
			}
		}
		else if (Flash_ID == 0xef18)
		{
			if (file_size > 1024*1024*32)
			{
				LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG");
				LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity");
				while(1) WDT_FeedDog();
			}
		}
		else if (Flash_ID == 0xefaa21)
		{
			MUC_SS_flag = 0;
			if (W25N01GV_ReadID() == 0xefaa21)
			{
				if (file_size > (1024*1024*128 - 20*1024) *2)
				{
					LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG");
					LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity");
					while(1) WDT_FeedDog();
				}
			}
			else if (file_size > (1024*1024*128 - 20*1024))
			{
				LT768_Print_Internal_Font_String(370,LINE1,NG_color,White,"NG");
				LT768_Print_Internal_Font_String(10,LINE4,Red,White,"File size exceeds Flash capacity");
				while(1) WDT_FeedDog();
			}
			MUC_SS_flag = 1;
		}
//		printf("size=%d\r\n",file_size);
		for(;;)		//从SD卡读数据写入SPI_FLASH
		{
			WDT_FeedDog();
			//闪动=====================================================================
			{
				if(run_flag == run_time)
				{
					LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* ");
				}
				else if(run_flag == run_time*2)
				{
					LT768_Print_Internal_Font_String(20,LINE5,Black,White," *");
					run_flag = 0;
				}
				run_flag++;
			}
			//========================================================================		
			//进度=====================================================================
			if(MUC_SS_flag == 0 && type != 0)
				num = (addr + 2048*64*(1024-20)) * 100.0 / file_size;
			else 
				num = addr * 100.0 / file_size;
	
			
			//if(num == 100) num = 99;
			num_to_char(showbuff,num);
			
			if(type == 1||type == 2)   			//UartTFT-II_Flash.bin   片选1
			{
				LT768_Print_Internal_Font_String(310,LINE1,Progress_color,White,showbuff);
			}
			else if(type == 0)			//UartTFT-II_Flash.bin   片选0
			{
#if UartTFT_Flash_0
				LT768_Print_Internal_Font_String(275,LINE4,Progress_color,White,showbuff);	
#endif
			}
			//========================================================================
			
			//读文件烧录
			u8 time = 0;
			
			u32 File_CRC = 0;
			u32 Flash_CRC = 0;
			char BBM_flag = 0;
			
			res=f_read(&fsrc,buff,2*1024,&br);
			if(res||(br == 0))
			{
				f_close(&fsrc);
				break;
			}
			if(type!=2)		//type为2,不校验CRC
			{
				if(addr == 0 && ((type == 1 && MUC_SS_flag == 1) || type == 0))	
				{
					BIN_CRC = buff[379]<<24|buff[378]<<16|buff[377]<<8|buff[376];					
					memset(&buff[372], 0xFF, 12);
				}
				File_CRC = GetCrc32(buff,br,0);	
			}			
			for(;;)
			{
				WDT_FeedDog();
				if(Flash_type == 0 )//NorFlash 
				{
					block_num = addr/(64*1024);
					blockremain = addr% (64*1024);
					
					if(blockremain == 0)				//新BLOCK执行擦除
						W25QXX_BlockErase64KB(block_num);
					
					W25QXX_Write_NoCheck(buff,addr,br);//写入数据
//					W25QXX_Read(&buff[2*1024],addr,br);//立刻拿回数据
				}
				else				//NandFlash
				{
					block_num = addr/(128*1024);
					blockremain = addr% (128*1024);
					
					if(blockremain == 0)				//新BLOCK执行擦除
						W25N01GV_Erase_Block(block_num);
					W25N01GV_Write_NoCheck(buff,addr,br);//写入数据
					
				}
				if(type!=2)	//type为2,不校验CRC
				{
					if(Flash_type == 0 )
						W25QXX_Read(&buff[2*1024],addr,br);//立刻拿回数据
					else
						W25N01GV_Read_NoCheck(&buff[2*1024],addr,br);//立刻拿回数据
					Flash_CRC = GetCrc32(&buff[2*1024],br,0);
					if(File_CRC != Flash_CRC)//对比数据是否正确
					{
						time++;
					}
					else
					{
						break;
					}
					if(time == 3) //三次了,退出报错,NG CRC
					{
						if(Flash_type == 0 )//NorFlash
						{
							return -1;
						}
						else			   //NandFlash
						{
							
							if(W25N01GV_BBM(block_num)  == 0) //BBM OK
							{
								BBM_flag = 1;
								break;
							}
							else							 //BBM Fail
							{
								return -2;
							}
						}
					}					
				}
				else
				{
					break;
				}
			}
			addr += br;  //Flash地址增加
			
			if(BBM_flag)
			{
				f_lseek(&fsrc,block_num*128*1024);
				addr = block_num*128*1024;
			}
			if(addr == 2048*64*(1024-20)) 
			{
				MUC_SS_flag = 0;	//更换片选
				addr = 0;
			}
			//========================================================================
		}
		
		if(type == 1 || type == 2)
		{
			MUC_SS_flag = 1;
		}
		//校验整体CRC========================================================================
		if(type!=2)	//type为2,不校验CRC
		{
			LT768_Print_Internal_Font_String(10,LINE4,File_name_color,White,"Checking CRC");
			for(;;)
			{
				WDT_FeedDog();
				//进度=====================================================================
	
				num =  Check_num * 100.0 / file_size;
				num_to_char(showbuff,num);
				LT768_Print_Internal_Font_String(310,LINE4,Progress_color,White,showbuff);
				
			//闪动=====================================================================
				{
					if(run_flag == run_time)
					{
						LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* ");
					}
					else if(run_flag == run_time*2)
					{
						LT768_Print_Internal_Font_String(20,LINE5,Black,White," *");
						run_flag = 0;
					}
					run_flag++;
				}
			//========================================================================	
				
				
				unsigned short Read_size;
				if(file_size - Check_num>= 2048)
					Read_size = 2048;
				else
					Read_size = file_size - Check_num;
				
				if(Flash_type == 0 )//NorFlash 
				{
					W25QXX_Read(buff,Check_num,Read_size);
				}
				else			   //NandFlash
				{
					if(MUC_SS_flag == 0 && type == 1)
					{
						W25N01GV_Read_NoCheck(buff,Check_num - 2048*64*(1024-20),Read_size);
					}
					else 
						W25N01GV_Read_NoCheck(buff,Check_num,Read_size);
				}
				
				Check_BIN_CRC = GetCrc32(buff,Read_size,Check_BIN_CRC);
				
				Check_num += Read_size;
				
				if(Check_num == 2048*64*(1024-20))	
				{
					MUC_SS_flag = 0;	//更换片选
				}
				
				if(Check_num == file_size)
				{
					Check_num = 0;
					
					break;
				}				
			}
			if(Check_BIN_CRC != BIN_CRC)  //NG CRC
			{
				
				LT768_Print_Internal_Font_String(370,LINE4,NG_color,White,"NG");
				//LT768_Print_Internal_Font_String(46 ,LINE5,Black,White,"NG: CRC error");
				LT768_Print_Internal_Font_String(10 ,LINE5,Black,White,"Result:");
				LT768_Print_Internal_Font_String(96,LINE5,Red,White,"Failed");
				while(1) WDT_FeedDog();
				return -3;
			}
			LT768_DrawSquare_Fill(0,LINE4,LCD_XSIZE_TFT-1,LINE5-1,Back_color);
		}
		//========================================================================
		
		return 0;   //能跑到这里的,只能是好的
	}
	else    //打开文件失败,返回文件系统结果代号
	{	
		return res;
	}
	
}
//判断块是不是坏块,参数为块编号;  好块返回0,坏块返回1;
uint8_t  Check_BadBlock(uint16_t block_num) 
{
	
	uint16_t i= 0 ,j= 0;
	uint32_t addr = block_num*128*1024;
	W25N01GV_Erase_Block(block_num);
	
	addr = block_num*128*1024;
	for(i=0;i<64;i++)
	{
		memset(buff,i,sizeof(buff));
		W25N01GV_Write_NoCheck(buff,addr,2048);
		addr+=2048;
	}
	
	addr = block_num*128*1024;
	for(i=0;i<64;i++)
	{
		W25N01GV_Read_NoCheck(buff,addr,2048);
		
		for(j=0;j<2048;j++)
		{
			if(buff[j] != i)
				return 1;
		}
		addr+=2048;
	}
	W25N01GV_Erase_Block(block_num);
	
	addr = block_num*128*1024;
	for(i=0;i<64;i++)
	{
		memset(buff,0xA5,sizeof(buff));
		W25N01GV_Write_NoCheck(buff,addr,2048);
		addr+=2048;
	}
	
	addr = block_num*128*1024;
	for(i=0;i<64;i++)
	{
		W25N01GV_Read_NoCheck(buff,addr,2048);
		
		for(j=0;j<2048;j++)
		{
			if(buff[j] != 0xA5)
				return 1;
		}
		addr+=2048;
	}
	
	W25N01GV_Erase_Block(block_num);
	
	addr = block_num*128*1024;
	for(i=0;i<64;i++)
	{
		memset(buff,0xFF,sizeof(buff));
		W25N01GV_Write_NoCheck(buff,addr,2048);
		addr+=2048;
	}
	
	addr = block_num*128*1024;
	for(i=0;i<64;i++)
	{
		W25N01GV_Read_NoCheck(buff,addr,2048);
		
		for(j=0;j<2048;j++)
		{
			if(buff[j] != 0xFF)
				return 1;
		}
		addr+=2048;
	}
	return 0;
}
u8 uart_nand_BBM_flag = 0;
signed char W25N01GV_BBM(unsigned short Block_num) //OK 0,Fail 1
{
	BBM LUT[20];
	
	if(Check_BadBlock(Block_num) == 0)		//检查是否真的是坏块
		return 1;
	
	if((W25N01GV_ReadSR(0xC0) & 0x40) == 0x40)  // 替换列表已经满了
	{
		return 1;
	}
		
	W25N01GV_Read_BBM_LUT(LUT);				//读回Flash里的坏块管理表数据
//	for(int i=0;i<20;i++)
//	printf("LBA[%d]:%x   PBA[%d]:%x \r\n",i,LUT[i].LBA,i,LUT[i].PBA);
//	printf("\r\n");
	
//	while(1);
	unsigned short Block_replace_num = 1023;
	unsigned char  Find_good_block_result = 0;
	
	char run_flag = 0;
	char time = 0;
	for(;;)
	{
		WDT_FeedDog();
		Find_good_block_result = 0;
		//闪动=====================================================================
			if(!uart_nand_BBM_flag)
			{
				if(run_flag == run_time)
				{
					LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* ");
				}
				else if(run_flag == run_time*2)
				{
					LT768_Print_Internal_Font_String(20,LINE5,Black,White," *");
					run_flag = 0;
				}
				run_flag++;
			}
		//========================================================================	
		
		for(int i=0;i<20;i++)
		{
			if(LUT[i].PBA == Block_replace_num)   //替换列表里有该替换地址
			{
				if((LUT[i].LBA & 0xC000) == 0x8000) //该替换序列使能并有效
				{
					Find_good_block_result = 0;
					break;
				}
				else
				{
					Find_good_block_result = 1;
					break;
				}
			}
			else  //没有该替换地址
			{
				Find_good_block_result = 1;
			}
		}
		if(Find_good_block_result == 1) //该Block没有在替换类表里,再判断该Block是否为好的块
		{
			if(Check_BadBlock(Block_replace_num) == 0) //好块
			{
				break;
			}
			else										//坏块
			{
				time++;
				Block_replace_num--;
				Find_good_block_result = 0;
			}
		}
		else
		{
			time++;
			if(time == 21)
			{
				Find_good_block_result = 0;
				break;
			}
			Block_replace_num--;
		}
	}
	
	uart_nand_BBM_flag = 0;
	
	if(Find_good_block_result == 0)  //无法找到好块
	{
		return 1;
	}
	else							//找到好块
	{
		char Replace_flag = 1;
//		printf("Block_replace_num:%x\r\n",Block_replace_num);
//		while(1);
		if(Block_num>=Block_replace_num) return 1;
		W25N01GV_Bad_Block_Replace(Block_num,Block_replace_num);
		W25N01GV_Read_BBM_LUT(LUT);
		for(int i=0;i<20;i++)
		{
//			printf("LBA[%d]:%x   PBA[%d]:%x \r\n",i,LUT[i].LBA,i,LUT[i].PBA);
			if(((LUT[i].LBA & 0x3FFF) == Block_num) && (LUT[i].PBA == Block_replace_num))
			{
				if((LUT[i].LBA & 0xC000) == 0x8000)  //Enable link
				{
					Replace_flag = 0;
				}
				else
				{
					Replace_flag = 1;
				}
			}
		}
		if(Replace_flag)
			return 1;
		else if(Replace_flag == 0)
			return 0;
	}
}
signed char APP_Updata(const char *buf)  //OK 0; NG crc -1, BBM -2;None 
{
	u8 num = 0;
	u32 addr = 0;
	u32 file_size = 0;
	char showbuff[10];
	u32 BIN_CRC = 0;
	u32 Check_BIN_CRC = 0;
	char run_flag = 0;
	u32 Check_num = 0;
	
	u32	val_flag=0;
	
	FATFS fs;
	FIL fsrc;
	FRESULT res;
	UINT br;
	printf("enter app updata\r\n");
	EFLASH_Init(g_sys_clk/1000);
	EFLASH_SetWritePermission();
	printf("next  f_mount\r\n");
	//f_mount(&fs,"0:",1);
	printf(" next f_open!!\r\n");
	res = f_open(&fsrc, buf, FA_READ);
	if(res == FR_OK)
	{
		printf("open mcu1 OK!!\r\n");
//	printf("res=%d\r\n",res);
	file_size = f_size(&fsrc);
//	printf("size=%d\r\n",file_size);
		
		//读取文件获取文件总体CRC==============================================
		for(;;)
		{
			WDT_FeedDog();
		//闪动=====================================================================
//			{
//				if(run_flag == run_time)
//				{
//					LT768_Print_Internal_Font_String(10,LINE5,Black,White,"* ");
//				}
//				else if(run_flag == run_time*2)
//				{
//					LT768_Print_Internal_Font_String(10,LINE5,Black,White," *");
//					run_flag = 0;
//				}
//				run_flag++;
//			}
		//========================================================================	
			res = f_read(&fsrc,buff,4*1024,&br);
			if(res||(br == 0))
			{
				f_lseek(&fsrc,0);   //不关闭文件,将文件读取指针指向文件开头
				break;
			}
			BIN_CRC = GetCrc32(buff,br,BIN_CRC);
		}
//		printf("CRC:%x\r\n",BIN_CRC);
		
		//=====================================================================
		
		for(;;)
		{
			WDT_FeedDog();
		//闪动=====================================================================
			{
				if(run_flag == run_time)
				{
					LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* ");
				}
				else if(run_flag == run_time*2)
				{
					LT768_Print_Internal_Font_String(20,LINE5,Black,White," *");
					run_flag = 0;
				}
				run_flag++;
			}
		//========================================================================		
		//进度====================================================================
			num = addr * 100 / file_size;
			if(num == 100) num = 99;
			num_to_char(showbuff,num);
			
			LT768_Print_Internal_Font_String(310,LINE2,Progress_color,White,showbuff);
		//========================================================================
			//读文件烧录
			u8 time = 0;
			
			u32 File_CRC = 0;
			u32 Flash_CRC = 0;
			res=f_read(&fsrc,buff,2*1024,&br);
			if(res||(br == 0))
			{
				f_close(&fsrc);
				break;
			}
			File_CRC = GetCrc32(buff,br,0);
			
			for(;;)
			{
				WDT_FeedDog();
				EFLASH_Write(APP_ADDR+addr,buff,br);//写入数据
				for(u16 i = 0;i<br;i++)             //立刻拿回数据
					buff[2*1024 + i] = *(volatile unsigned char*)(APP_ADDR+addr+i);
				Flash_CRC = GetCrc32(&buff[2*1024],br,0);
				
				if(File_CRC != Flash_CRC)//对比数据是否正确
				{
					time++;
					printf("***data right!***\r\n");
				}
				else
				{
					break;
				}
				if(time ==3) //三次了,退出报错,NG CRC
				{
					return -1;
				}
			}
			addr += br;  //增加
			//========================================================================
		}
		//校验整体CRC========================================================================
		for(;;)
		{
			WDT_FeedDog();
		//闪动=====================================================================
			{
				if(run_flag == run_time)
				{
					LT768_Print_Internal_Font_String(20,LINE5,Black,White,"* ");
				}
				else if(run_flag == run_time*2)
				{
					LT768_Print_Internal_Font_String(20,LINE5,Black,White," *");
					run_flag = 0;
				}
				run_flag++;
			}
		//========================================================================	
			
			unsigned short Read_size;
			
			if(file_size - Check_num>= 4000)
				Read_size = 4000;
			else
				Read_size = file_size - Check_num;
			
			for(u16 i = 0;i<Read_size;i++)             //立刻拿回数据
					buff[i] = *(volatile unsigned char*)(APP_ADDR + Check_num + i);
			
			Check_BIN_CRC = GetCrc32(buff,Read_size,Check_BIN_CRC);
			
			Check_num += Read_size;
			if(Check_num == file_size) break;
		}
		if(Check_BIN_CRC != BIN_CRC)  //NG CRC
			return -1;
		//========================================================================
		
		val_flag = 0x21436587;
		EFLASH_PageErase(0x8009E00);//测试:擦除Flash前将标志位清除
		EFLASH_WordsProg(0x8009E00,&val_flag,1);	//测试:校准成功后将标志位写入0x21436587	
		Run_Boot_ID=0x00000000;
		
		return 0;   //能跑到这里的,只能是好的		
	}
	else    //打开文件失败,返回文件系统结果代号
	{	
		return res;
	}
}