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

📄 flash.c

📁 dm270 source code
💻 C
字号:

#include <prkernel.h>
#include <system/uart270.h>
#include <system/osd270.h>
#include "api/app_msg.h"
#include "api/file_mng.h"
#include "api/ui_msg.h"
#include "system_ver.h"
#include "api/file_cache.h"


#define	ADDR555	0x0555 
#define	ADDR2AA	0x02aa
#define	FILE_HEADER_SIZE	50
#define SEC_HEADER_SIZE		48
#define	SYM_TABLE_SIZE		18
#define	REL_ENTRY_SIZE		12
#define	FLASH_CE	0x00100000
#define	SZFLASH		0x00400000

typedef struct _COFF_HEADER
{
	USHORT	COFFVer;
	USHORT	nSection;
	LONG	Time;
	LONG 	pSymbolTable;
	LONG	nSymbolTable;
	LONG	pStringTable;
	LONG	nStringTable;
	USHORT	nOpHeader;
	USHORT	HeaderFlag;
	USHORT	ID;

/* option header */
	SHORT	nMagic;
	SHORT	VerStamp;
	LONG	sExcutable;
	LONG	sInitial;
	LONG	sBSS;
	LONG	pEntry;
	LONG	StAddrEx;
	LONG	StAddrIni;
} COFF_HEADER;

typedef struct _SECTION_HEADER
{
	CHAR	SecName[64];
	LONG	SecPhyAddr;
	LONG	SecVirAddr;
	LONG	SecSize;
	LONG	pRawData;
	LONG	pRelEntry;
	LONG	pLineEntry;
	ULONG	nRelEntry;
	ULONG	nLineEntry;
	ULONG	SecFlag;
	INT		valid;
} SECTION_HEADER;

void CF_in(void);
void flash_write(USHORT *ce);
void SD_disable(void);
void printu(CHAR *pString, int nstr);
void disp_comp(int err);

COFF_HEADER fheader;
INT COFFCOPY = 0x01275000;


void fl_reset(USHORT *ce){
	*ce = 0x00f0;
}
	
int erace_all(USHORT *ce){

	int i;
	USHORT dat;

	fl_reset(ce);
	for(i = 0; i < 1000; i++); 

	*(ce + ADDR555) = 0x00aa;
	*(ce + ADDR2AA) = 0x0055;
	*(ce + ADDR555) = 0x0080;
	*(ce + ADDR555) = 0x00aa;
	*(ce + ADDR2AA) = 0x0055;
	*(ce + ADDR555) = 0x0010;

	while(1){
		dat = *ce;

		if(dat == 0xffff){
			for(i = 0; i < 5000; i++); 
			return 0;
		}
					
		if(dat & 0x20)
			return -1;
	}
}

#define		RETRY	100

int fl_write(USHORT *src, USHORT *dst, int size)
{

	USHORT *ce, dat1, dat2;
	int i, j, k;

	ce = (USHORT*)((INT)dst & 0xfff00000);
	
	for(i = 0; i < size/2; i++){
		*(ce + ADDR555) = 0x00aa;
		*(ce + ADDR2AA) = 0x0055;
		*(ce + ADDR555) = 0x00a0;
		*dst = *src;

		for(j = 0; j < RETRY; j++){
			for(k= 0; k< 50; k++);
				
			dat1 = *dst;
			dat2 = *dst;

			if((dat1 == *src) & (dat2 == *src))
				break;
		 	if((dat1 & 0x20) & (dat2 & 0x20))
		 		return -1;
		}
	
		if(j < RETRY){
			*src++;
			*dst++;
		}
		else
			i--;
	}

	return 0;
}

int fl_verify(USHORT *src, USHORT *dst, int size){
	int i;
	USHORT *ce;

	ce = (USHORT*)((INT)dst & 0xfff00000);

	for(i = 0; i < size/2; i++){
		if(*src++ != *dst++)
			return -1;
	}

	fl_reset(ce);
	for(i = 0; i < 1000; i++); 

	return 0;
}
	
void GetCOFFHeader(UCHAR *coff,  COFF_HEADER *header)
{
	UCHAR *org;
	org = coff;
	
	header->COFFVer = *coff++ | *coff++ << 8;
	header->nSection = *coff++ | *coff++ << 8;
	header->Time = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	header->pSymbolTable = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	header->nSymbolTable = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	header->nOpHeader = *coff++ | *coff++ << 8;
	header->HeaderFlag = *coff++ | *coff++ << 8;
	header->ID = *coff++ | *coff++ << 8;

	if(header->nOpHeader == 0x1c){
		header->nMagic = *coff++ | *coff++ << 8;
		header->VerStamp = *coff++ | *coff++ << 8;
		header->sExcutable = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
		header->sInitial = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
		header->sBSS = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
		header->pEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
		header->StAddrEx = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
		header->StAddrIni = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	}

	header->pStringTable =	header->pSymbolTable + header->nSymbolTable * SYM_TABLE_SIZE;
	coff = org + header->pStringTable;

	header->nStringTable = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
}

void GetSecHeader(UCHAR *coff, int secID, SECTION_HEADER *sheader)
{

	int	i;
	ULONG pString;
	UCHAR *org;
	
	org = coff;
	coff = org + (secID * SEC_HEADER_SIZE + FILE_HEADER_SIZE);

	for(i = 0; i < 8; i++)
		sheader->SecName[i] = *coff++;
	sheader->SecName[i] = '0';

	sheader->SecPhyAddr = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	sheader->SecVirAddr = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	sheader->SecSize = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	sheader->pRawData = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	sheader->pRelEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	sheader->pLineEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	sheader->nRelEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	sheader->nLineEntry = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;
	sheader->SecFlag = *coff++ | *coff++ << 8 | *coff++ << 16 | *coff++ << 24;

	if((LONG)sheader->SecName[0] == 0){
		i = 0;
		pString =	(UCHAR)sheader->SecName[4] |
					(UCHAR)sheader->SecName[5] << 8 |
					(UCHAR)sheader->SecName[6] << 16 |
					(UCHAR)sheader->SecName[7] << 24;

		coff = org + (fheader.pStringTable + pString); 
		do{
			sheader->SecName[i] = *coff++;
		}while(sheader->SecName[i++] != 0);	
	}

	sheader->valid = ((sheader->SecFlag & 0x0003) == 0) &
					((sheader->SecFlag & 0x0060) != 0) &
					((sheader->SecFlag & 0x0010) == 0) &
					(sheader->SecSize != 0); 

}

void ROM_Util(){


	*(unsigned short*) VIDEOWIN_MODE = 0;
	*(unsigned short*) SYNCEN = 0;
	*(unsigned short*) PVEN = 0;	

	CF_in();
	flash_write((USHORT*)FLASH_CE);
	printu("Done", -1);
	
}


#define ROMCODE "B:\\system.out"

void CF_in(){

	FILE *fp;

	fp = fopen(ROMCODE, "r");

	if(fp)
		//DEV_UART_sendString(UART0,"Loading File OK\r\n");
		printu("Loading File OK\r\n", -1);
	else{
		fclose(fp);
		//DEV_UART_sendString(UART0,"File cannot open\r\n");
		printu("File cannot open\r\n", -1);
		while(1){};
	}		
		
	fread((void*)COFFCOPY, 1, 0xffffffff, fp);
	fclose(fp);
}

void flash_write(USHORT *ce){

	INT err = 0;
	SECTION_HEADER secheader;
	int i;
	USHORT *src, *dst;
	
	WRITE_REGISTER_USHORT(ICA_MODE, 0);
	GetCOFFHeader((UCHAR*)COFFCOPY, &fheader);

	if(fheader.COFFVer != 0xc2){
		//DEV_UART_sendString(UART0, "Invalid COFF File\r\n");
		printu("Invalid COFF File\r\n", -1);
		return;
	}
	
	if(fheader.ID != 0x97){
		//DEV_UART_sendString(UART0, "This is not ARM COFF File\r\n");
		printu("This is not ARM COFF File\r\n", -1);
		return;
	}

	SD_disable();

	// emif initialization
	*(unsigned short*)CS0CTRL1 = 0x668a;
	*(unsigned short*)CS3CTRL1 = 0x668a;
	*(unsigned short*)CS4CTRL1 = 0x668a;
	
	*(unsigned short*)CS0CTRL2 = 0x2442;
	*(unsigned short*)CS3CTRL2 = 0x6442;	// CS3 16-bit
	*(unsigned short*)CS4CTRL2 = 0x6442;	// CS4 16-bit


	GetCOFFHeader((UCHAR*)COFFCOPY, &fheader);


//		GUI_slideShowPanelClear();
//		GUI_slideShowPanelReset();
//		GUI_controlPanelMediaNameSet(" Erace....... ");
		//DEV_UART_sendString(UART0,"Erace...Start\r\n");
		printu("Erace...Start\r\n", -1);
		err = erace_all(ce);
		//DEV_UART_sendString(UART0,"Erace...End\r\n");
		printu("Erace...End\r\n", -1);
		disp_comp(err);
//		GUI_slideShowPanelClear();
//		GUI_slideShowPanelReset();
//		GUI_controlPanelMediaNameSet(" Write....... ");
		// LOOP # of SECTIONs
		//DEV_UART_sendString(UART0,"Write...Start\r\n");
		//DEV_UART_sendString(UART0,"Write.");
		printu("Write...Start\r\n", -1);
		printu("Write.", -1);
		
		for(i = 0; i < fheader.nSection; i++){
			GetSecHeader((UCHAR*)COFFCOPY, i, &secheader);
			if(secheader.valid){
				src = (USHORT*)(COFFCOPY + (ULONG)secheader.pRawData);
				dst = (USHORT*)((ULONG)ce + (ULONG)secheader.SecVirAddr - FLASH_CE);
				err |= fl_write(src, dst, secheader.SecSize);
			}
			//DEV_UART_sendString(UART0,".");
			printu(".", -1);
		}
		//DEV_UART_sendString(UART0,"\r\n");
		//DEV_UART_sendString(UART0,"Write...End\r\n");
		printu("\r\n", -1);
		printu("Write...End\r\n", -1);
		
		disp_comp(err);
//		GUI_slideShowPanelClear();
//		GUI_slideShowPanelReset();
//		GUI_controlPanelMediaNameSet(" Verify....... ");
		//DEV_UART_sendString(UART0,"Verify...Start\r\n");
		//DEV_UART_sendString(UART0,"Verify.");
		printu("Verify...Start\r\n", -1);
		printu("Verify.", -1);
		
		for(i = 0; i < fheader.nSection; i++){
			GetSecHeader((UCHAR*)COFFCOPY, i, &secheader);
			if(secheader.valid){
				src = (USHORT*)(COFFCOPY + (ULONG)secheader.pRawData);
				dst = (USHORT*)((ULONG)ce + (ULONG)secheader.SecVirAddr - FLASH_CE);
				err |= fl_verify(src, dst, secheader.SecSize);
			}
			//DEV_UART_sendString(UART0,".");
			printu(".", -1);
		}
		//DEV_UART_sendString(UART0,"\r\n");
		//DEV_UART_sendString(UART0,"Verify...End\r\n");
		
		printu("\r\n", -1);
		printu("Verify...End\r\n", -1);
		
		disp_comp(err);
//		GUI_slideShowPanelClear();
//		GUI_slideShowPanelReset();
//		GUI_controlPanelMediaNameSet(" Done ");
		//DEV_UART_sendString(UART0,"Done...\r\n");	
		printu("Done...\r\n", -1);
		while(1);
}

void printu(CHAR *pString, int nstr)
{
	int i;
	USHORT buf;

	if(nstr == -1){
		// until end of string
		while (*pString) {
			buf = (*(unsigned short*) SR0) & 0x1;
			if(buf != 0)
				*(unsigned short*) DTRR0 = *pString++;	
		}
	}

	else{
		i = 0;
		while(i < nstr){
			buf = (*(unsigned short*) SR0) & 0x1;
			if(buf != 0){
				if(*pString)
					*(unsigned short*) DTRR0 = *pString++;
				else
					*(unsigned short*) DTRR0 = ' ';
				i++;
			}
		}		
	}
}

void SD_disable(void){

	xdisable();
	*(unsigned short*) EINT0 = 0x0000;
	*(unsigned short*) EINT1 = 0x0000;
	*(unsigned short*) EINT1 = 0x0000;
	*(unsigned short*) VIDEOWIN_MODE = 0;
	*(unsigned short*) SYNCEN = 0;
	*(unsigned short*) PVEN = 0;
}	

void disp_comp(int err){

	if(!err){
//		GUI_slideShowPanelClear();
//		GUI_slideShowPanelReset();
//		GUI_controlPanelMediaNameSet(" Complete... !!");
		printu("Complete\r\n", -1);
		//DEV_UART_sendString(UART0,"Complete...\r\n");		
		}
	else{
//		GUI_slideShowPanelClear();
//		GUI_slideShowPanelReset();
//		GUI_controlPanelMediaNameSet(" Error..shit !!");
		//DEV_UART_sendString(UART0,"Error..shit\r\n");
		printu("Error\r\n", -1);
		while(1);
	}
}


	
	

⌨️ 快捷键说明

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