⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 flashload.c

📁 FLASH f39v1601 的底层驱动
💻 C
字号:

#include "..\Include\FlashLoad.h"

extern int FLH_Program1Word(U16 * addr, U16 val);
extern int FLH_Erase1Sector(U16 * addr);
extern int FLH_Erase1Block(U16 * addr);
extern void FLH_ReadSecID(U16 * ptr);
extern void FLH_WriteSecID(U16 value, U16 offset);

extern void FLH_Erase1Block_Load();
extern void FLH_Erase1Sector_Load();
extern void FLH_Program1Word_Load();
extern void FLH_ReadSecID_Load();
extern void FLH_ProgramSecID_Load();

extern void Test_Delay(U16 num);

// This module is to copy itself to RAM,jump to RAM and to do code update.
//void BootLoader()
//{
//}
void FLH_ReadSecurityID(U16 * ptr)
{
	FLH_ReadSecID_Load();
	FLH_ReadSecID(ptr);
}

void FLH_Program_SecID(U16 * data_ptr)
{
	U16 i;
	FLH_ProgramSecID_Load();
	for (i=0; i<8; i++)
	{
		FLH_WriteSecID(data_ptr[i], i+0x10);
	}
}

U16 FLH_Program_Word(U16 * addr, U16 val)
{
/*	U16 i;
	U16 * ptr;
	
	ptr = (U16 *)PROGRAM_WORD_START;
	for (i = 0;i<PROGRAM_WORD_LEN; i++){
		GBuf[i] = ptr[i];
	}
*/
	FLH_Program1Word_Load();
	return (FLH_Program1Word(addr, val));
}

U16 FLH_Erase_Sector(U16 * addr)
{
/*	U16 i;
	U16 * ptr;
	ptr = (U16 *)ERASE_SECTOR_START;
	for (i = 0;i<ERASE_SECTOR_LEN; i++){
		GBuf[i] = ptr[i];
	}
//	 Test_Delay(10);
*/
	FLH_Erase1Sector_Load();
	return (FLH_Erase1Sector(addr));
}

U16 FLH_Erase_Block(U16 * addr)
{
/*	U16 i;
	U16 * ptr;
	ptr = (U16 *)ERASE_BLOCK_START;
	for (i = 0;i<ERASE_BLOCK_LEN; i++){
		GBuf[i] = ptr[i];
	}
*/
	FLH_Erase1Block_Load();
	return (FLH_Erase1Block(addr));
}

U16 FLH_Program_Long(U16 * addr, U32 val)
{
	U16 i;
//	U16 * ptr;
	U32_HL tmp;
/*	
	ptr = (U16 *)PROGRAM_WORD_START;
	for (i = 0;i<PROGRAM_WORD_LEN; i++){
		GBuf[i] = ptr[i];
	}
*/
	FLH_Program1Word_Load();
	
	tmp.DWord = val;
	i = FLH_Program1Word(addr, tmp.HLWord.L);
	i += FLH_Program1Word(addr+1, tmp.HLWord.H);
	return(i);
}

// program from 1 sector to another sector; at sector begining to sector end
U16 FLH_Program_Sector(U16 * src_ptr, U16 * dest_ptr)
{
	U16 i,j;
//	U16 * ptr;
	U32_HL src, dest;
/*
	ptr = (U16 *)PROGRAM_WORD_START;
	for (i = 0;i<PROGRAM_WORD_LEN; i++){
		GBuf[i] = ptr[i];
	}
*/
	FLH_Program1Word_Load();
	
	src.DWord = (U32)src_ptr;
	src.HLWord.L &= 0xF800;
	dest.DWord = (U32)dest_ptr;
	dest.HLWord.L &= 0xF800;
	src_ptr = (U16 *)src.DWord;
	dest_ptr = (U16 *)dest.DWord;
	
	j = 0;
	for (i=0; i<SECTOR_SIZE; i++)
	{
		j += FLH_Program1Word(dest_ptr++, *src_ptr++);
	}
	return(j);
}

U16 FLH_Program_Data(U16 * src_ptr, U16 * dest_ptr, U16 len)
{
	U16 i,j;
//	U16 * ptr;
/*
	ptr = (U16 *)PROGRAM_WORD_START;
	for (i = 0;i<PROGRAM_WORD_LEN; i++){
		GBuf[i] = ptr[i];
	}
*/
	FLH_Program1Word_Load();
	
	j = 0;
	for (i=0; i<len; i++)
	{
		j += FLH_Program1Word(dest_ptr++, *src_ptr++);
	}
	return(j);
}

// 1 sector for flag; 7 sectors for swap area
// swap area is cyclic to backup sectors
// flag sector is cyclic to record update flag items

// find last index in flag sector, return which item is the last.
// 0 to MAX_FLAG_REC -1, if return MAX_FLAG_REC, the pool is full.
U16 Find_Last_Flag()
{
	FLASH_FLAG_REC * ptr;
	U16 i;
	ptr = (FLASH_FLAG_REC *)SWAP_FLAG;
	for (i=0; i<=MAX_FLAG_REC; i++)
	{
		if ((ptr->flag == 0xffff) && (ptr->addr_ptr == (U16 *)0xffffffff) && (ptr->length == 0xffff))
			break;
		ptr++;
	}
	return(i);
}

// to judge if the data block is cross the sector border or not.
// 0: not cross sector border, 1: cross the sector border
U16 Cross_Sector(U16 * addr, U16 len)
{
	U32 i;
	U16 j,k;
	i = (U32)addr;
	j = i/SECTOR_SIZE;
	k = (i+len)/SECTOR_SIZE;
	if (j==k)
		return(0);
	else
		return(1);
}

void FLH_Restore_Update()
{
	U16 * buf_ptr1;
	U16 * buf_ptr2;
	FLASH_FLAG_REC * rec_ptr;
	U16 i;
	U16 * tmp_ptr;
	
	// find index in flag sector
	i = Find_Last_Flag();
	if (i==0)				// nothing to restore
		return;
	i = i-1;
	rec_ptr = (FLASH_FLAG_REC *)((U32)SWAP_FLAG + i*sizeof(FLASH_FLAG_REC));
	if (rec_ptr->flag == 0)				// nothing to restore
		return;
	if ((rec_ptr->flag == FLAG_1S) || (rec_ptr->flag == FLAG_2S))
	{
		// restore sector 1
		buf_ptr1 = (U16 *)SWAP_ADDR + (i%SWAP_REC_MAX)*SECTOR_SIZE;
		FLH_Erase_Sector(rec_ptr->addr_ptr);
		FLH_Program_Sector(buf_ptr1, rec_ptr->addr_ptr);
		if (rec_ptr->flag == FLAG_2S)	// restore sector 2
		{
			buf_ptr2 = (U16 *)SWAP_ADDR + ((i+1)%SWAP_REC_MAX)*SECTOR_SIZE;
			tmp_ptr = rec_ptr->addr_ptr+SECTOR_SIZE;	// pointer to 2nd sector
			FLH_Erase_Sector(tmp_ptr);
			FLH_Program_Sector(buf_ptr2, tmp_ptr);
		}
		FLH_Program_Word((U16 *)rec_ptr, 0);		// update flag to be finished
	}
}

U16 FLH_Update_Data(U16 * src_ptr, U16 * dest_ptr, U16 len)
{
	U16 * buf_ptr1;
	U16 * buf_ptr2;
	U16 * flag_item_ptr;
	U16 i,j,flag_cross;
	U32 tmplong;
	
	// find index in flag sector
	i = Find_Last_Flag();
	if (i==MAX_FLAG_REC)		// if no available flag item, erase whole sector.
	{
		FLH_Erase_Sector((U16 *)SWAP_FLAG);
		i = 0;
	}
	// to judge if 1 sector or 2 sector to be stored
	flag_cross = Cross_Sector(dest_ptr, len);
	
	// backup sector 1
	buf_ptr1 = (U16 *)SWAP_ADDR + (i%SWAP_REC_MAX)*SECTOR_SIZE;
	FLH_Erase_Sector(buf_ptr1);
	FLH_Program_Sector(dest_ptr, buf_ptr1);
	if (flag_cross)	// backup sector 2
	{
		buf_ptr2 = (U16 *)SWAP_ADDR + ((i+1)%SWAP_REC_MAX)*SECTOR_SIZE;
		FLH_Erase_Sector(buf_ptr2);
		FLH_Program_Sector(dest_ptr+len, buf_ptr2);
	}

	// update flag item
	flag_item_ptr = (U16 *)SWAP_FLAG + i*sizeof(FLASH_FLAG_REC);	//
	FLH_Program_Long(flag_item_ptr+1, (U32)dest_ptr);
	FLH_Program_Word(flag_item_ptr+3, len);
	if (flag_cross)
		FLH_Program_Word(flag_item_ptr, FLAG_2S);
	else
		FLH_Program_Word(flag_item_ptr, FLAG_1S);
		
	// update destination value, erase first, program remainder data + target data;
	// update remainder data
	tmplong = (U32)dest_ptr;
	i = tmplong%SECTOR_SIZE;			// if start from sector begining
	FLH_Erase_Sector(dest_ptr);			// erase first sector
	if (i != 0)							// not from sector begining
	{
		FLH_Program_Data(buf_ptr1, dest_ptr-i, i);
	}
	j = SECTOR_SIZE - (tmplong+len)%SECTOR_SIZE;
	if (flag_cross==0)		// just 1 sector to be updated
	{
		FLH_Program_Data(src_ptr, dest_ptr, len);		// update target data
		if (j != 0)
			FLH_Program_Data(buf_ptr1+i+len, dest_ptr+len, j);
	}
	else					// 2 sectors to be updated, cross border
	{
		FLH_Erase_Sector(dest_ptr+len);			// erase 2nd sector
		FLH_Program_Data(src_ptr, dest_ptr, len);	// program can cross the border
		// if cross border, j should not equal to 0
		// buf_ptr2 do not necessary to be next to buf_ptr1, it might turn to swap area's beginning
		FLH_Program_Data(buf_ptr2+SECTOR_SIZE-j, dest_ptr+len, j);
	}
	i = FLH_Program_Word(flag_item_ptr, 0);		// update flag to be finished
	return(i);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -