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

📄 main.cpp

📁 coldfire5206芯片平台的升级程序
💻 CPP
字号:

/*	
Create by					date
shiliangcai				2002/10/15
*/

#include "bastype.h"
#include "fpga.h"
#include "flash.h"
#include "mcf5206.h"
#include "mbusman.h"
//#include "uartdrv.h"
//#include "fpgauart.h"
//#include "Update.h"
#include "graph.h"
#include "main.h"

// 注意FPGA文件的FPGA数据必须使用const定义,因为loader.cpp没有初始化全局变量,
#if defined(RESOLVING_800_600)
#include "fpga\8k9k_800_600_fpga.h"
#include "fpga\6k_800_600_fpga.h"
#else
#if defined(RESOLVING_640_480)
#include "fpga\8k9k_640_480_fpga.h"
#endif
#endif

// BIOS_STARTUP_ADDRESS需要手工赋值
#define BIOS_STARTUP_ADDRESS 0x800040

#define BIOS_START_ADDRESS	0x850000
#define FPGA_START_ADDRESS	0x870000

SYSCONFIGFLAG g_stSysFlag;

UCHAR g_acFileBuffer[0x200000];

extern  START;
extern  _START_ADDRESS;             // start address of user's program
extern  _END_ADDRESS;               // end address of user's program
extern  _CHECK_ADDRESS;
extern  __SP_INIT;                  // init SP of user's program
extern _SPEC_START;

#define FPGA_2M_FLASH_ADDR	0xD000
#define FPGA_4M_FLASH_ADDR	0x3C0000
#define LANG_2M_FLASH_ADDR	0x1E0000
#define LANG_4M_FLASH_ADDR	0x260000
#define CONFIG_2M_FLASH_ADDR	0x1F8000
#define CONFIG_4M_FLASH_ADDR	0x3E0000

//********************************************************
//	Function Reference
//********************************************************
VOID		DoJump(VOID);
VOID  HardwareInit( VOID);
VOID  SoftwareInit( VOID);
void TestForBios();
void UpdateBios(void);
void HaltCpu();

UINT32 GetCheckSum( UINT16* p_ram_data, UINT16* p_flash_data, UINT32 nLen );
VOID GetCurBedNo(UCHAR* pucMonitorID);
BOOL WriteFpgaInFlash();
BOOL WriteFlashSystemInfo();
// 随机产生的一个唯一标志ID
UINT32 g_alMonitorId[2];
static UINT32 sBinCode[] =
{
#if defined(RESOLVING_800_600)
	#include "h_boot.txt"
#else
#if defined(RESOLVING_640_480)
	#include "l_boot.txt"
#endif
#endif
};

//VOID	main()
void  main()
{
#ifndef RUN_IN_FLASH
	// BIN模式下(FLASH)这段代码在EPRCRT0.S中运行
	// 首先,根据寄存器取得一个随机值作为机器ID,放入s_lMonitorId
	asm ( " MOVE.L D2, D2");
	asm ( " ADD.L D3, D2");
	asm ( " ADD.L D4, D2");
	asm ( " ADD.L D5, D2");
	asm ( " ADD.L D6, D2");
	asm ( " ADD.L D7, D2");
	asm ( "	MOVE.L #_g_alMonitorId, A1 ");
	asm (" MOVE.L  D2, (A1) ");
//	asm ( " ADD.L A1, D2");
	asm ( " MOVE.L A2, D2");
	asm ( " ADD.L A3, D2");
	asm ( " ADD.L A4, D2");
	asm ( " ADD.L A5, D2");
	asm ( " ADD.L A6, D2");
	asm ( "	MOVE.L #_g_alMonitorId + 4, A1 ");
	asm (" MOVE.L  D2, (A1) ");
#endif

	UCHAR				acTempStr[100];

	// Firstly, mask all interrutp
	asm("  MOVE.W #$2700, SR ");
	HardwareInit();	
	SoftwareInit();
	// Lastly, open all interrutp
	asm("  MOVE.W #$2000, SR ");

	UpdateBios();

//	Sleep(10000);
//	DisableSysInterrupt(MCF5206::IM_ALL);

	while (1);	// waiting for reseting
}


/**
*/
VOID  HardwareInit( VOID )
{
	UINT32 i, j;
	CHAR   result;

	*(unsigned char *)PARRAPORT_PADAT = 0xff;

	MCF5206Init();

	MBusInit( );

	// 在使用定时器喂狗之前,复位一下看门狗
	// 以免硬件初始化时间加上1S的喂狗时间叠加导致复位 
	ResetWatchdog();

	// 自升级程序中,不需要网络和串口初始化
//	ConfigUart();
	
	return;
}

/**
*  global variables, objects. all initialization about software
*  coding here
*/
VOID  SoftwareInit( VOID )
{
	int vector;
	VOID   **vector_table;                      /* Pointer to vector table   */

	 // 定义在int_sbc.s中,装载中断向量表
	extern void* exception_handler1;
	extern void* irq_handler1;
	extern void* exception_handler;
	extern void* irq_handler;
	extern  VOID  *INT_FpgaExtInt2ISR;
	extern  VOID  *INT_FpgaExtInt3ISR;
	extern void* INT_Timer1_Interrupt;
	extern void* INT_Timer2_Interrupt;
	extern void* INT_UART2_Interrupt;
	extern void* INT_UART1_Interrupt;
	extern void* INT_Net_Interrupt;

     /* Calculate the starting address of the actual vector table.  */
    vector_table =  (VOID **) 0x0;
	for (vector = 2; vector <= 24; vector ++)
	{
		vector_table[vector] = &exception_handler1;
	}
	for (vector = 25; vector <= 31; vector ++)
	{
		vector_table[vector] = &irq_handler1;
	}
	for (vector = 32; vector <= 63; vector ++)
	{
		vector_table[vector] = &exception_handler;
	}
	for (vector = 64; vector <= 255; vector ++)
	{
		vector_table[vector] = &irq_handler;
	}
	vector = MCF5206::IV_TIMER1;
	vector_table[vector] = &INT_Timer1_Interrupt;
	vector = MCF5206::IV_TIMER2;
	vector_table[vector] = &INT_Timer2_Interrupt;
	vector = MCF5206::IV_UART1;
	vector_table[vector] = &INT_UART1_Interrupt;
	vector = MCF5206::IV_UART2;
	vector_table[vector] = &INT_UART2_Interrupt;
	vector = MCF5206::IV_EINT2;
	vector_table[vector] = &INT_FpgaExtInt2ISR;
	vector = MCF5206::IV_EINT3;
	vector_table[vector] = &INT_FpgaExtInt3ISR;
	vector = MCF5206::IV_EINT4;
	vector_table[vector] = &INT_Net_Interrupt;

	// enable timer for resetting watchdog
	EnableSysInterrupt(MCF5206::IM_TIMER1);		

	// read system flag from eeprom
	CAT24C021ReadSeqByte(EEPROM_SYSTEM_FLAG_POS, sizeof(EEPROMSYSFLAG), (UINT8*)(&g_stSysFlag.stESysFlag));

	// read system flag from flash
	memcpy((UINT8*)(&g_stSysFlag.stFSysFlag), (UINT8*)FLASH_SYSTEM_FLAG_POS, sizeof(FLASHSYSFLAG));

	if (g_stSysFlag.stESysFlag.ucMainSysIsValid != 1)	// 第一次会是0xff,所以不能用非0来判断
	{
		g_stSysFlag.stESysFlag.ucUpdateMachineID = g_stSysFlag.stFSysFlag.ucSelfMachineID;
		g_stSysFlag.stESysFlag.ucUpdatePortID = g_stSysFlag.stFSysFlag.ucSelfPortID;
	}	

	return;
}



void UpdateBios(void)
{
	if (JudgeLayOut() == FALSE)
	{
//		TextOut( 100, 160, BLINKRED, 0, "FLASH is error");
		////HaltCpu();
		while(1);
	}

#ifdef RUN_IN_FLASH
	// 通过网络下载升级引导程序时,会使用伪装的ID值,
	// 也就是假的系统软件信息中的固定的lComLen和随机的ver组成
	UINT32 lCfgPos; 
	if (g_nFlashSizeType == FLASH_SIZE_4M)
	{
		lCfgPos =  CONFIG_4M_FLASH_ADDR + FLASH_BASE_ADDRESS;
	}
	else
	{
		lCfgPos =  CONFIG_2M_FLASH_ADDR + FLASH_BASE_ADDRESS;
	}
	memcpy(g_alMonitorId, (UINT8*)(lCfgPos + 902), 8);
#endif

	// 先将FPGA写入FLASH,然后再初始化FPGA	
	UINT32 fpga_data_addr;
	UINT32 fpga_data_len;
#if defined(RESOLVING_800_600)
	if (g_nFlashCircuitType == FLASH_CIRCUIT_VER_6000)
	{
		fpga_data_len = sizeof(fpga_6k_800_600);
		fpga_data_addr = 	(UINT32)fpga_6k_800_600;
	}
	else
	{
		fpga_data_len = sizeof(fpga_8k9k_800_600);
		fpga_data_addr = 	(UINT32)fpga_8k9k_800_600;
	}
#else
#if defined(RESOLVING_640_480)
	// 640× 480没有用于6000产品
	if (g_nFlashCircuitType == FLASH_CIRCUIT_VER_6000)
	{
		TextOut( 100, 160, BLINKRED, 0, "640*480 is not supported by PM6000");
		//HaltCpu();
		while(1);
	}
	else
	{
		fpga_data_len = sizeof(fpga_8k9k_640_480);
		fpga_data_addr = 	(UINT32)fpga_8k9k_640_480;
	}
#endif
#endif
	ScreenInit(fpga_data_addr, fpga_data_len);  	

	TextOut( 100, 100, YELLOW,  0, "Update Bios......");
	// Write FPGA data
	TextOut( 100, 160, GREEN, 0, "Write fpga in flash......");
	if (WriteFpgaInFlash() == FALSE )
	{
		TextOut( 400, 160, BLINKRED, 0, "Fail");
		//HaltCpu();
		while(1);
	}
	else
	{
		TextOut( 400, 160, GREEN, 0, "Succeed");
	}
	TextOut( 100, 200, GREEN, 0, "Write machine info in flash......");
	if (WriteFlashSystemInfo() == FALSE )
	{
		TextOut( 400, 200, BLINKRED, 0, "Fail");
		//HaltCpu();
		while(1);
	}
	else
	{
		TextOut( 400, 200, GREEN, 0, "Succeed");
	}
	
	// 写引导程序
	TextOut( 100, 240, GREEN, 0, "Write bios in flash......");
	UINT32 nAddr = BIOS_STARTUP_ADDRESS - FLASH_BASE_ADDRESS;
	if (WriteFlash(nAddr, (UCHAR*)sBinCode, sizeof(sBinCode)) == FALSE)
	{
		TextOut( 400, 240, BLINKRED, 0, "Fail");
//		//HaltCpu();
		while(1);
	}
	else
	{
		TextOut( 400, 240, GREEN, 0, "Succeed");
	}

	unsigned char flag[10];
	EEPROMSYSFLAG stEFlag;
	memset(&stEFlag, 0x00000000, sizeof(EEPROMSYSFLAG));
	if (FALSE == WriteEeprom(EEPROM_SYSTEM_FLAG_POS, sizeof(EEPROMSYSFLAG), (UCHAR*)(&stEFlag)))
	{
		TextOut( 100, 280, BLINKRED, 0, "EEPROM maybe have some problems!");
		//HaltCpu();
		while(1);
	}
	
	TextOut( 100, 280, GREEN, 0, "Clear config info in flash......");
	// 擦除FLASH中的配置
	UINT32 lTempValue = 0;
	UINT8 acTempCfg[2000];
	memset(acTempCfg, 0x00, 2000);
	if (g_nFlashSizeType == FLASH_SIZE_4M)
	{
		lTempValue +=  !WriteFlash(LANG_4M_FLASH_ADDR, acTempCfg, 2000);
		lTempValue +=  !WriteFlash(CONFIG_4M_FLASH_ADDR, acTempCfg, 1500);
	}
	else
	{
		lTempValue +=  !WriteFlash(LANG_2M_FLASH_ADDR, acTempCfg, 2000);
		lTempValue +=  !WriteFlash(CONFIG_2M_FLASH_ADDR, acTempCfg, 1500);
	}
	if (lTempValue != 0)
	{
		TextOut( 400, 280, BLINKRED, 0, "FAIL");
		//HaltCpu();
		while(1);
	}
	else
	{
		TextOut( 400, 280, GREEN, 0, "Succeed");
	}

	TextOut( 100, 320, GREEN, 0, "Identify by checksum......");
	//check sum
	UINT32 check_sum = GetCheckSum((UINT16*)sBinCode, (UINT16*)(BIOS_STARTUP_ADDRESS), sizeof(sBinCode));
	if (0 == check_sum)
	{
		TextOut( 400, 320, BLINKRED, 0, "FAIL");
		//HaltCpu();
		while(1);
	}
	else
	{
		TextOut( 400, 320, GREEN, 0, "Succeed");
	}


	char  flashbuf[100];
	strcpy(flashbuf, "Checksum is  ");
//		strcat(flashbuf, BIOS_CHECKSUM);
//		sprintf(flashbuf + strlen(flashbuf), "%02d", BIOS_VER);
	char acTempStr222[20];
	sprintf(acTempStr222, "0x%08X", check_sum);
	strcat(flashbuf, acTempStr222);
//	strcat(flashbuf, "  ");
//	strcat(flashbuf, __TIME__);
	strcat(flashbuf, "  ");
	strcat(flashbuf, __DATE__);
	TextOut( 100, 360, GREEN, 0, flashbuf );

	TextOut( 400, 100, YELLOW,  0, "DONE");
	TextOut( 100, 400, YELLOW,  0, "Update success, please download main system program");
	
#ifndef RUN_IN_FLASH
	// 在SDS下,利用HALT指令来告知UPDATE完毕,这样可以不用显示支持,就知道下载成功
	HaltCpu();
#endif
}


//if checking ok ,return checksum , else return 0
UINT32 GetCheckSum( UINT16* p_ram_data, UINT16* p_flash_data, UINT32 nLen )
{
	UINT32   nChecksum;

	nLen = nLen/2;
	nChecksum = 0;
	//checking if program writing ok,if not, break ;
	while( (*p_ram_data == *p_flash_data) && (nLen > 0))
	{
		nChecksum += *p_ram_data;
		p_flash_data ++;
		p_ram_data ++;
		nLen --;
	}
	
	if (nLen != 0)
	{
		return 0;
	}
	else
	{
		return nChecksum;
	}
}
///////////////////////////////////////////////////////////////////////
//		BOOL WriteFpgaInFlash()
// 写FPGA文件到FLASH,因为8000和9000的FPGA相同,而6000的则不同,
// 所以根据FLASH走线类型来判断是否是6000
// return: TRUE, success, FALSE, failure
BOOL WriteFpgaInFlash()
{
	UINT32 fpga_data_len;
	UCHAR* p_fpga_data;
	SOFTCOMINFO comInfo;
	memset(&comInfo, 0x00, sizeof(SOFTCOMINFO));
#if defined(RESOLVING_800_600)
	if (g_nFlashCircuitType == FLASH_CIRCUIT_VER_6000)
	{
		fpga_data_len = sizeof(fpga_6k_800_600);
		p_fpga_data = 	(UCHAR*)fpga_6k_800_600;
		comInfo.ucType = 0x01;
	}
	else
	{
		fpga_data_len = sizeof(fpga_8k9k_800_600);
		p_fpga_data = 	(UCHAR*)fpga_8k9k_800_600;
		comInfo.ucType = 0x00;
	}
#else
#if defined(RESOLVING_640_480)
	// 640× 480没有用于6000产品
	if (g_nFlashCircuitType == FLASH_CIRCUIT_VER_6000)
	{
		TextOut( 100, 160, BLINKRED, 0, "640*480 is not supported by PM6000");
//		//HaltCpu();
		while(1);
	}
	else
	{
		fpga_data_len = sizeof(fpga_8k9k_640_480);
		p_fpga_data = 	(UCHAR*)fpga_8k9k_640_480;
		comInfo.ucType = 0x00;
	}
#endif
#endif

	// data in flash rom
	comInfo.lComLen = fpga_data_len;
	comInfo.acVer[0] = 0x01;
	UINT32 lChecksum = 0x00;
	int i;
	for (i = 0; i < fpga_data_len / 2; i ++)
	{
		lChecksum += *((UINT16*)p_fpga_data + i);
	}
	comInfo.lComChecksum = lChecksum;
	lChecksum = 0x00;
	for (i = 0; i < (sizeof(SOFTCOMINFO) - 4) / 2; i ++)
	{
		lChecksum += *((UINT16*)(&comInfo) + i);
	}
	comInfo.lChecksum = lChecksum;

	UINT32 lTempValue = 0;
	if (g_nFlashSizeType == FLASH_SIZE_2M)
	{
		lTempValue +=  !WriteFlash(FPGA_2M_FLASH_ADDR, (UCHAR*)&comInfo, sizeof(SOFTCOMINFO));
		lTempValue +=  !WriteFlash(FPGA_2M_FLASH_ADDR + sizeof(SOFTCOMINFO), p_fpga_data, fpga_data_len);
	}
	else
	{
		lTempValue +=  !WriteFlash(FPGA_4M_FLASH_ADDR, (UCHAR*)&comInfo, sizeof(SOFTCOMINFO));
		lTempValue +=  !WriteFlash(FPGA_4M_FLASH_ADDR + sizeof(SOFTCOMINFO), p_fpga_data, fpga_data_len);
	}

	return !lTempValue;
}

BOOL WriteFlashSystemInfo()
{
	// FLASH开始的64个字节
	// 前面8个字节的STACK和START POS和后面56字节的系统标志
	UINT8	acFlashCfgInfo[64];
	UCHAR ucMonitorID[8];
	UINT32 lPos, lTempValue;

	// 先取得标志信息
	memset(acFlashCfgInfo, 0x00, 64);
	// sp
	lPos = 0;
	lTempValue = (UINT32)&__SP_INIT;
	memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
	lPos += 4;
	//start
	lTempValue = BIOS_STARTUP_ADDRESS;
	memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
	lPos += 4;
	// machine self type, self update port, bios ver, reserved 1
	acFlashCfgInfo[lPos] = MT_PM_NET_COMMON;
	lPos ++;
	acFlashCfgInfo[lPos] = UT_SELF_VALUE;
	lPos ++;
	acFlashCfgInfo[lPos] = BIOS_VER;
	lPos ++;
	acFlashCfgInfo[lPos] = 0x00;
	lPos ++;
	// machine ID
	memcpy(acFlashCfgInfo + lPos, (UINT8*)(&g_alMonitorId), 8);
	lPos += 8;
	// flash size flag, flash circuit flag, reserved 2
	acFlashCfgInfo[lPos] = g_nFlashSizeType;
	lPos ++;
	acFlashCfgInfo[lPos] = g_nFlashCircuitType;
	lPos ++;
//	lTempValue = ( (g_nFlashSizeType << 24) & 0xff000000 )
//		+ ( (g_nFlashCircuitType << 16) & 0x00ff0000 );
//	memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
	if (g_nFlashSizeType == FLASH_SIZE_2M)
	{
		lTempValue = FPGA_2M_FLASH_ADDR + FLASH_BASE_ADDRESS;
		memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
		lPos += 4;
		lTempValue = LANG_2M_FLASH_ADDR + FLASH_BASE_ADDRESS;
		memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
		lPos += 4;
		lTempValue = CONFIG_2M_FLASH_ADDR + FLASH_BASE_ADDRESS;
		memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
		lPos += 4;

	}
	else
	{
		lTempValue = FPGA_4M_FLASH_ADDR + FLASH_BASE_ADDRESS;
		memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
		lPos += 4;
		lTempValue = LANG_4M_FLASH_ADDR + FLASH_BASE_ADDRESS;
		memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
		lPos += 4;
		lTempValue = CONFIG_4M_FLASH_ADDR + FLASH_BASE_ADDRESS;
		memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
		lPos += 4;
	}
	// checksum
	lPos = 60;
	lTempValue = 0;
	for (int i = 8; i < 64; i += 2)
		lTempValue += *((UINT16*)(acFlashCfgInfo + i));
	memcpy(acFlashCfgInfo + lPos, &lTempValue, 4);
	lPos += 4;

	// 写FLASH
	lTempValue = 0;
	lTempValue +=  !WriteFlash(0x00, acFlashCfgInfo, 64);

	return !lTempValue;
}

void HaltCpu()
{
	asm("		MOVE 	SR,D0		");	//get SR
	asm("		ORI.L	#$2000,D0	");
	asm("		MOVE	D0,SR		");	//set CPU to no user mode
	asm("		HALT				");	//send halt instrument same as BKPT
}

⌨️ 快捷键说明

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