📄 main.c
字号:
/****************************************************************
NAME: u2440mon.c
DESC: u2440mon entry point,menu,download
HISTORY:
Mar.25.2002:purnnamu: S3C2400X profile.c is ported for S3C2410X.
Mar.27.2002:purnnamu: DMA is enabled.
Apr.01.2002:purnnamu: isDownloadReady flag is added.
Apr.10.2002:purnnamu: - Selecting menu is available in the waiting loop.
So, isDownloadReady flag gets not needed
- UART ch.1 can be selected for the console.
Aug.20.2002:purnnamu: revision number change 0.2 -> R1.1
Sep.03.2002:purnnamu: To remove the power noise in the USB signal, the unused CLKOUT0,1 is disabled.
****************************************************************/
#define GLOBAL_CLK 1
#include <stdlib.h>
#include <string.h>
#include "def.h"
#include "option.h"
#include "2440addr.h"
#include "2440lib.h"
#include "2440slib.h"
#include "mmu.h"
#include "profile.h"
#include "memtest.h"
#include "usbmain.h"
#include "usbout.h"
#include "usblib.h"
#include "2440usb.h"
void Isr_Init(void);
void HaltUndef(void);
void HaltSwi(void);
void HaltPabort(void);
void HaltDabort(void);
void Lcd_Off(void);
void WaitDownload(void);
void Menu(void);
void ClearMemory(void);
void Clk0_Enable(int clock_sel);
void Clk1_Enable(int clock_sel);
void Clk0_Disable(void);
void Clk1_Disable(void);
//#define DOWNLOAD_ADDRESS _RAM_STARTADDRESS
volatile U32 downloadAddress;
void (*restart)(void)=(void (*)(void))0x0;
//void (*run)(void); //don't use gloable variable, hzh!!!
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;
extern char Image$$RW$$Limit[];
U32 *pMagicNum=(U32 *)Image$$RW$$Limit;
int consoleNum;
/*************************************************************/
#include "bootpara.h"
void LcdDisplay(void);
int write_24c02(U8 *pBuf);
int read_24c02(U8 *pBuf);
int find_camera(void);
void Led_Test(void);
void comdownload(void);
int SectorProg(U32 begin, U16 *data, U32 size);
int RelocateNKBIN(U32 img_src, U32 *pStart, U32 *pLength, U32 *pLaunch);
void LoadRunEboot(void);
void NandErase(void);
int NandWrite(void);
void NandLoadRun(void);
extern void Lcd_Tft_NEC35_Init(void);
extern void Lcd_Tft_NEC35_Test( void ) ;
extern void Test_Lcd_TFT_640_480(void) ;
extern void Test_Touchpanel(void) ;
extern void Test_Adc(void) ; //adc test
extern void KeyScan_Test(void) ;
extern void RTC_Display(void) ;
extern void Test_IrDA_Tx(void) ;
extern void PlayMusicTest(void) ;
extern void RecordTest( void ) ;
extern void Test_Iic(void) ;
extern void Test_SDI(void) ;
#define printf Uart_Printf
#define DM9000_BASE 0x20000300
#define DM9000_DATA_OFFSET 4
#define AMD_FLASH_START 0
void mdelay(int ms)
{
U32 val = (PCLK>>3)/1000-1;
rTCFG0 &= ~(0xff<<8);
rTCFG0 |= 3<<8; //prescaler = 3+1
rTCFG1 &= ~(0xf<<12);
rTCFG1 |= 0<<12; //mux = 1/2
/* while(ms--) {
rTCNTB3 = val;
rTCMPB3 = val>>1; // 50%
rTCON &= ~(0xf<<16);
rTCON |= 3<<16; //one shot, inv-off, update TCNTB3&TCMPB3, start timer 3
rTCON &= ~(2<<16); //clear manual update bit
while(rTCNTO3);
}*/
rTCNTB3 = val;
rTCMPB3 = val>>1; // 50%
rTCON &= ~(0xf<<16);
rTCON |= 0xb<<16; //interval, inv-off, update TCNTB3&TCMPB3, start timer 3
rTCON &= ~(2<<16); //clear manual update bit
while(ms--) {
while(rTCNTO3>=val>>1);
while(rTCNTO3<val>>1);
};
}
static U8 dm9000_ior(int reg)
{
*(volatile U8 *)DM9000_BASE = reg;
return *(volatile U8 *)(DM9000_BASE+DM9000_DATA_OFFSET);
}
static void rd_dm9000_id(void)
{
U16 id;
id = dm9000_ior(0x28) | (dm9000_ior(0x29)<<8);
printf("read dm9000 vid = 0x%x\n", id);
id = dm9000_ior(0x2a) | (dm9000_ior(0x2b)<<8);
printf("read dm9000 pid = 0x%x\n", id);
id = dm9000_ior(0x8) | (dm9000_ior(0x9)<<8);
printf("read dm9000 reg(0x09,0x08) = 0x%x\n", id);
printf("dm9000 isr = 0x%x\n", dm9000_ior(0xfe));
}
static void buzzer(int freq, int ms)
{
rGPBCON &= ~3; //set GPB0 as tout0, pwm output
rGPBCON |= 2;
rTCFG0 &= ~0xff;
rTCFG0 |= 15; //prescaler = 15+1
rTCFG1 &= ~0xf;
rTCFG1 |= 2; //mux = 1/8
rTCNTB0 = (PCLK>>7)/freq;
rTCMPB0 = rTCNTB0>>1; // 50%
rTCON &= ~0x1f;
rTCON |= 0xb; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 0
rTCON &= ~2; //clear manual update bit
mdelay(ms);
rGPBCON &= ~3; //set GPB0 as output
rGPBCON |= 1;
rGPBDAT &= ~1;
}
static U32 autorun_10ms;
static U16 autorun_ds;
static U16 autorun_trig;
static __irq void autorun_proc(void)
{
ClearPending(BIT_TIMER4);
if(autorun_ds)
DisableIrq(BIT_TIMER4);
autorun_10ms--;
if(!autorun_10ms) {
DisableIrq(BIT_TIMER4);
//CLR_IF(); //in irq service routine, irq is disabled
autorun_trig = 1;
//NandLoadRun();
}
}
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);
}
static U32 cpu_freq;
static U32 UPLL;
static void cal_cpu_bus_clk(void)
{
U32 val;
U8 m, p, s;
val = rMPLLCON;
m = (val>>12)&0xff;
p = (val>>4)&0x3f;
s = val&3;
//(m+8)*FIN*2 2?òa3?3?32??êy!
FCLK = ((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;
else
cpu_freq = FCLK;
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)
rCLKDIVN |= 8; //UCLK=UPLL/2
UCLK = (rCLKDIVN&8)?(UPLL>>1):UPLL;
}
void IIC_test(void);
int search_vend_params(void)
{
U8 dat[256];
VenderParams *pVP = (VenderParams *)dat;
//IIC_test();
if(!read_24c02(dat)) {
int i;
//for(i=0; i<256; i++)
// Uart_Printf("%c0x%02x", (i%16)?' ':'\n', dat[i]);
i = 0;
if(strncmp(vend_params.vid.flags, pVP->vid.flags, sizeof(vend_params.vid.flags))==0)
vend_params.vid.val = pVP->vid.val;
else
i = -1;
if(strncmp(vend_params.pid.flags, pVP->pid.flags, sizeof(vend_params.pid.flags))==0)
vend_params.pid.val = pVP->pid.val;
else
i = -1;
if(strncmp(vend_params.ser_l.flags, pVP->ser_l.flags, sizeof(vend_params.ser_l.flags))==0)
vend_params.ser_l.val = pVP->ser_l.val;
else
i = -1;
if(strncmp(vend_params.ser_h.flags, pVP->ser_h.flags, sizeof(vend_params.ser_h.flags))==0)
vend_params.ser_h.val = pVP->ser_h.val;
else
i = -1;
if(strncmp(vend_params.user_params.flags, pVP->user_params.flags, sizeof(vend_params.user_params.flags))==0) {
vend_params.user_params.val = pVP->user_params.val;
memcpy(vend_params.string, pVP->string, sizeof(vend_params.string));
} else
i = -1;
//if it's string, make sure the last char is 0
if(vend_params.user_params.val)
vend_params.string[sizeof(vend_params.string)-1] = 0;
return i;
}
return -2;
}
int save_vend_params(void)
{
return write_24c02((U8 *)&vend_params);
}
void Main(void)
{
char mode[]= {'D','M','A'};
int i;
U8 key;
U32 mpll_val = 0 ;
U32 divn_upll = 0 ;
#if ADS10
__rt_lib_init(); //for ADS 1.0
#endif
Port_Init();
rGPACON &= ~(1<<11);
rGPADAT |= 1<<11;
Isr_Init();
i = search_params(); //hzh, don't use 100M!
switch (boot_params.cpu_clk.val) {
// switch(1) {
case 0: //240
key = 14;
mpll_val = (112<<12)|(4<<4)|(1);
break;
case 1: //320
key = 14;
mpll_val = (72<<12)|(1<<4)|(1);
break;
case 2: //400
key = 14;
mpll_val = (92<<12)|(1<<4)|(1);
break;
case 3: //440!!!
key = 14;
mpll_val = (102<<12)|(1<<4)|(1);
break;
default:
key = 14;
mpll_val = (92<<12)|(1<<4)|(1);
break;
}
#if 1
//init FCLK=400M, so change MPLL first
ChangeMPllValue((mpll_val>>12)&0xff, (mpll_val>>4)&0x3f, mpll_val&3);
ChangeClockDivider(key, 12);
cal_cpu_bus_clk();
if(PCLK<(40*MEGA)) {
ChangeClockDivider(key, 11);
cal_cpu_bus_clk();
}
#else
cal_cpu_bus_clk();
#endif
consoleNum=boot_params.serial_sel.val&0; // Uart 1 select for debug.
Uart_Init(0,boot_params.serial_baud.val);
Uart_Select(consoleNum);
//Uart_Select(0);
LcdDisplay();
//buzzer(2100, 200);
while(0) {
Uart_SendByte('a');
// rGPFDAT |= 1<<6;
// mdelay(500);
// rGPFDAT &= ~(1<<6);
// mdelay(500);
}
Uart_SendByte('\n');
Uart_Printf("<*************************************************************>\n");
Uart_Printf(" S3C2440 Bootloader V2006\n");
/* switch (search_vend_params()) {
case 0:
Uart_Printf("Found vender params.\n");
break;
case -1:
Uart_Printf("Can't found vender params!\n");
save_vend_params();
break;
case -2:
Uart_Printf("Can't found EEPROM device!\n");
break;
default:
break;
}
if(vend_params.user_params.val)
Uart_Printf(" %s\n", vend_params.string);
Uart_Printf("VID is 0x%08x, PID is 0x%08x\n", vend_params.vid.val, vend_params.pid.val);
Uart_Printf("Serial NO. is %08x%08x\n", vend_params.ser_h.val, vend_params.ser_l.val);
*/
//Uart_Printf(" www.ucdragon.com\n");
//Uart_Printf("BWSCON = 0x%08x\n", rBWSCON);
Uart_Printf("CPU ID is 0x%08x\n", rGSTATUS1);
if(!i)
Uart_Printf("Found boot params\n");
else if(i==-1) {
Uart_Printf("Fail to found boot params!\n");
save_params();
} else if(i==-2)
Uart_Printf("Fail to read EEPROM!\n");
Uart_Printf("FCLK=%dMHz, HCLK=%dMHz, PCLK=%dMHz, CPU is running at %dMHz\n",
FCLK/MEGA, HCLK/MEGA, PCLK/MEGA, cpu_freq/MEGA);
Uart_Printf("UPLL=%dMHz, UCLK=%dMHz\n", UPLL/MEGA, UCLK/MEGA);
Uart_Printf("Serial port %d, Baud rate is %d.\n", boot_params.serial_sel.val, boot_params.serial_baud.val);
Uart_Printf("OS image stored in %s Flash.\n", boot_params.osstor.val?"NOR":"NAND");
Uart_Printf("Autoboot delay is %d seconds.\n", boot_params.boot_delay.val);
if(boot_params.boot_delay.val)
init_autorun_timer(boot_params.boot_delay.val);
Uart_Printf("<*************************************************************>\n");
rMISCCR=rMISCCR&~(1<<3); // USBD is selected instead of USBH1
rMISCCR=rMISCCR&~(1<<13); // USB port 1 is enabled.
//
// USBD should be initialized first of all.
//
isUsbdSetConfiguration=0;
rDSC0 = 0x2aa;
rDSC1 = 0x2aaaaaaa;
if(0) {
int i;
volatile U16 *p = (volatile U16 *)0x08000000;
p[3] = 0xbf;
p[2] = 0;
p[3] = 0;
p[2] = 1;
printf("dr2=0x%04x\n", p[2]);
for(i=0; i<8; i++)
printf("0x%08x\n", p[i]);
}
#if 0
#define CS8900A_BASE 0x19000300
//0xa = address port, 0xc=data port
//Chip ID
*(volatile U16 *)(CS8900A_BASE+0xa) = 0;
i = *(volatile U16 *)(CS8900A_BASE+0xc);
printf("0x%04x\n", i);
//Product ID
*(volatile U16 *)(CS8900A_BASE+0xa) = 2;
i = *(volatile U16 *)(CS8900A_BASE+0xc);
printf("0x%04x\n", i);
*(volatile U16 *)(CS8900A_BASE+0xa) = 0x136;
i = *(volatile U16 *)(CS8900A_BASE+0xc);
//if(i&0x80) //SelfST. INITD bit
// break;
#endif
#if 0
UsbdMain();
MMU_Init(); //MMU should be reconfigured or turned off for the debugger,
//After downloading, MMU should be turned off for the MMU based program,such as WinCE.
#else
//MMU_EnableICache();
MMU_Init(); //hzh
Delay(0); //calibrate Delay() first, hzh
#ifdef DEBUG_VERSION
comdownload(); //hzh
// SectorProg(0, (U16 *)downloadAddress, downloadFileSize);
NandWrite();
#endif
UsbdMain();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -