📄 main.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 + -