📄 main.c
字号:
/****************************************************************
NAME: main.c
DESC: u2440mon entry point,menu,download
HISTORY:
2008/12/27 xm_boot
****************************************************************/
#define GLOBAL_CLK 1//hzh
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "bootpara.h"
#include "nand.h"
#include "usbmain.h"
#include "usbout.h"
#include "usblib.h"
#include "2440usb.h"
#include "lcdinit.h"
#include "rtc.h"
#include "app_cfg.h"
#include "includes.h"
void Isr_Init(void);
void HaltUndef(void);
void HaltSwi(void);
void HaltPabort(void);
void HaltDabort(void);
//#define DOWNLOAD_ADDRESS _RAM_STARTADDRESS
volatile U32 downloadAddress;
volatile unsigned char *downPt;
volatile U32 downloadFileSize;
volatile U16 checkSum;
volatile unsigned int err=0;
volatile U32 totalDmaCount;
volatile int isUsbdSetConfiguration;
int download_run=0;
U32 tempDownloadAddress;
int menuUsed=0;
static U32 autorun_10ms;
static U16 autorun_ds;
static U16 autorun_trig;
U8 consoleNum;
#define RGB(r,g,b) (unsigned int)( (r << 16) + (g << 8) + b )
OS_STK MainTaskStk[MainTaskStkLengh];
OS_STK Task0Stk [Task0StkLengh]; // Define the Task0 stack
OS_STK Task1Stk [Task1StkLengh]; // Define the Task1 stack
OS_STK Task2Stk [Task2StkLengh]; // Define the Task1 stack
int rYear, rMonth,rDay,rDayOfWeek,rHour,rMinute,rSecond;
//**************************[配置CPU时钟]**************************
static U32 cpu_freq;
static U32 UPLL;
static void cal_cpu_bus_clk(void)
{
U32 val;
U8 m, p, s;
ChangeMPllValue(MDIV_mpll,PDIV_mpll,SDIV_mpll); //配置FCLK
//配置UCLK
#if FIN==12000000
ChangeUPllValue(56,2,2);
#endif
#if FIN==16934400
ChangeUPllValue(60,4,1);
#endif
val = rMPLLCON;
m = (val>>12)&0xff;
p = (val>>4)&0x3f;
s = val&3;
//(m+8)*FIN*2 不要超出32位数!
cpu_freq = ((m+8)*(FIN/100)*2)/((p+2)*(1<<s))*100;
val = rCLKDIVN;
m = (val>>1)&3;
p = val&1;
val = rCAMDIVN;
s = val>>8;
switch (m) {
case 0:
HCLK = FCLK;
break;
case 1:
HCLK = FCLK>>1;
break;
case 2:
if(s&2)
HCLK = FCLK>>3;
else
HCLK = FCLK>>2;
break;
case 3:
if(s&1)
HCLK = FCLK/6;
else
HCLK = FCLK/3;
break;
}
if(p)
PCLK = HCLK>>1;
else
PCLK = HCLK;
if(s&0x10)
cpu_freq = HCLK;
val = rUPLLCON;
m = (val>>12)&0xff;
p = (val>>4)&0x3f;
s = val&3;
UPLL = ((m+8)*FIN)/((p+2)*(1<<s));
//if(UPLL==96*MEGA) //当FIN==1693400时UPLL=95960000,起不了作用 xm
if(UPLL>=95961600) //xm
rCLKDIVN |= 8; //UCLK=UPLL/2,UCLK must be 48M for USB
UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;
}
/*
static void init_autorun_timer(int sec)
{
U32 val = (PCLK>>4)/100-1;
autorun_10ms = sec*100;
pISR_TIMER4 = (U32)autorun_proc;
rTCFG0 &= ~(0xff<<8);
rTCFG0 |= 3<<8; //prescaler = 3+1
rTCFG1 &= ~(0xf<<16);
rTCFG1 |= 1<<16; //mux = 1/4
rTCNTB4 = val;
rTCON &= ~(0xf<<20);
rTCON |= 7<<20; //interval, inv-off, update TCNTB4&TCMPB4, start timer 4
rTCON &= ~(2<<20); //clear manual update bit
EnableIrq(BIT_TIMER4);
}*/
//******************[BootLoader菜单显示函数]*********************
void Menu(void)
{
int i;
U8 key;
menuUsed=1;
while(1)
{
Uart_Printf("\n###### Select Menu ######\n");
Uart_Printf(" [0] Download & Run\n");
Uart_Printf(" [1] Download Only\n");
// Uart_Printf(" [2] Test SDRAM \n");
// Uart_Printf(" [3] Change The Console UART Ch.\n");
// Uart_Printf(" [4] Clear unused area in SDRAM \n");
Uart_Printf(" [2] Download From UART\n");
Uart_Printf(" [3] Write File to SST39VF160\n");
// Uart_Printf(" [5] Write File to TE28F128\n");
Uart_Printf(" [4] Write File to NAND Flash\n");
Uart_Printf(" [5] Boot OS\n");
Uart_Printf(" [6] Erase NAND Flash Partition\n");
Uart_Printf(" [7] Config parameters\n");
Uart_Printf(" [8] Relocate NK.bin\n");
Uart_Printf(" [9] run\n");
key=Uart_Getch();
switch(key)
{
case '0':
Uart_Printf("\nDownload&Run is selected.\n\n");
download_run=1;
return;
case '1':
Uart_Printf("\nDownload Only is selected.\n");
Uart_Printf("Enter a new temporary download address(0x3...):");
tempDownloadAddress=Uart_GetIntNum();
download_run=0;
Uart_Printf("The temporary download address is 0x%x.\n\n",tempDownloadAddress);
return;
//case '2':
// Uart_Printf("\nMemory Test is selected.\n");
//MemoryTest();
//Menu();
//return;
// break;
/* case '3':
Uart_Printf("\nWhich UART channel do you want to use for the console?[0/1]\n");
if(Uart_Getch()!='1')
{
*pMagicNum=0x0;
Uart_Printf("UART ch.0 will be used for console at next boot.\n");
}
else
{
*pMagicNum=0x12345678;
Uart_Printf("UART ch.1 will be used for console at next boot.\n");
Uart_Printf("UART ch.0 will be used after long power-off.\n");
}
Uart_Printf("System is waiting for a reset. Please, Reboot!!!\n");
while(1);
break;
case '4':
Uart_Printf("\nMemory clear is selected.\n");
ClearMemory();
break;
*/ case '2':
comdownload();
break;
case '3':
if(downloadFileSize)
// SectorProg(0, (U16 *)downloadAddress, downloadFileSize); //modify by xm
break;
/*case '5':
{
int c;
Uart_Printf("Where to program?\n1 : 0x00000000\n2 : 0x00020000\n3 : 0x00200000\nEsc to abort\n");
while(1) {
c = Uart_Getch();
if(c==0x1b||c=='1'||c=='2'||c=='3')
break;
}
if(c>='1'&&c<='3') {
U32 addr = 0;
if(c=='2')
addr = 0x00020000;
if(c=='3')
addr = 0x00200000;
ProgNorFlash(addr, downloadAddress, downloadFileSize);
}
break;
}*/
case '4':
if(downloadFileSize)
NandWrite();
break;
case '5':
NandLoadRun();
break;
case '6':
NandErase();
break;
case '7':
set_params();
break;
case '8':
//case 'A':
{
U32 launch;
if(!RelocateNKBIN(downloadAddress, (U32 *)&downloadAddress, (U32 *)&downloadFileSize, &launch)) {
boot_params.run_addr.val = launch;
boot_params.initrd_addr.val = downloadAddress;
boot_params.initrd_len.val = downloadFileSize;
save_params(); //save initrd_len.val
}
}
break;
case '9': //xm
call_linux();
break;
/* case 'c':
case 'C':
{
int i;
U32 *p1 = (U32 *)downloadAddress;
U32 *p2 = (void *)0x32000000;
for(i=0; i<(boot_params.initrd_len.val/4); i++)
if(p1[i]!=p2[i])
printf("0x%08x, p1 0x%08x, p2 0x%08x\n", i*4, p1[i], p2[i]);
}
break;
*/ default:
break;
}
}
}
//**********************[等待下载的主逻辑函数]*******************
void WaitDownload(void)
{
U32 i;
U32 j;
U16 cs;
U32 temp;
U16 dnCS;
int first=1;
float time;
U8 tempMem[16];
U8 key;
checkSum=0;
downloadAddress=(U32)tempMem; //_RAM_STARTADDRESS;
downPt=(unsigned char *)downloadAddress;
//This address is used for receiving first 8 byte.
downloadFileSize=0;
#if 0
MMU_DisableICache();
//For multi-ICE.
//If ICache is not turned-off, debugging is started with ICache-on.
#endif
/*******************************/
/* Test program download */
/*******************************/
j=0;
if(isUsbdSetConfiguration==0)
{
Uart_Printf("USB host is not connected yet.\n");
}
while(downloadFileSize==0)
{
if(first==1 && isUsbdSetConfiguration!=0)
{
Uart_Printf("USB host is connected. Waiting a download.\n");
first=0;
}
if(j%0x50000==0)Led_Display(0x6);
if(j%0x50000==0x28000)Led_Display(0x9);
j++;
key=Uart_GetKey();
if(autorun_trig)
NandLoadRun(); //run it in svc mode
if(key!=0)
{
autorun_ds = 1;
//printf("disable autorun\n");
Menu();
first=1; //To display the message,"USB host ...."
//在串口下载返回后downloadFileSize不为0,因此不能再执行USB下载! hzh
}
}
autorun_ds = 1;
//printf("disable autorun\n");
Timer_InitEx();
Timer_StartEx();
#if USBDMA
rINTMSK&=~(BIT_DMA2);
ClearEp3OutPktReady();
// indicate the first packit is processed.
// has been delayed for DMA2 cofiguration.
if(downloadFileSize>EP3_PKT_SIZE)
{
if(downloadFileSize<=(0x80000))
{
ConfigEp3DmaMode(downloadAddress+EP3_PKT_SIZE-8,downloadFileSize-EP3_PKT_SIZE);
//will not be used.
/* rDIDST2=(downloadAddress+downloadFileSize-EP3_PKT_SIZE);
rDIDSTC2=(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(0);
*/
}
else
{
ConfigEp3DmaMode(downloadAddress+EP3_PKT_SIZE-8,0x80000-EP3_PKT_SIZE);
//2440比2410的DIDSTCx寄存器多了中断产生条件的控制位,USB的DMA传输为字节计数
//防止高频开cache运行时下载大于0x80000字节文件时IsrDma2出错!!! hzh
//while((rDSTAT2&0xfffff)==(0x80000-EP3_PKT_SIZE));
while(!(rDSTAT2&(1<<20))); //防止DMA传输尚未开始就写入下一次重装值!!! hzh
if(downloadFileSize>(0x80000*2))//for 1st autoreload
{
rDIDST2=(downloadAddress+0x80000-8); //for 1st autoreload.
rDIDSTC2=(1<<2)|(0<<1)|(0<<0);
rDCON2=rDCON2&~(0xfffff)|(0x80000);
while(rEP3_DMA_TTC<0xfffff)
{
rEP3_DMA_TTC_L=0xff;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -