📄 main.c
字号:
//*----------------------------------------------------------------------------
extern void FindNandBoot(void);
void InitSDRAM(void)
{
volatile int *pSDRAM = (int *)DRAM_BASE;
//puts("1\n");
/* Configure PIOC as peripheral (D16/D31) */
AT91F_PIO_CfgPeriph( AT91C_BASE_PIOC, 0xFFFF0000, 0);
/*Setup MEMC to support all connected memories (CS0 = FLASH; CS1=SDRAM)*/
AT91C_BASE_EBI->EBI_CSA = AT91C_EBI_CS1A;
/*Init SDRAM*/
AT91C_BASE_SDRC->SDRC_CR = 0x2188c154;
AT91C_BASE_SDRC->SDRC_MR = 0x02;
//puts("2\n");
*pSDRAM = 0;
AT91C_BASE_SDRC->SDRC_MR = 0x04;
//puts("3\n");
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
*pSDRAM = 0;
//puts("4\n");
AT91C_BASE_SDRC->SDRC_MR = 0x03;
*(pSDRAM + 0x80) = 0;
//puts("5\n");
AT91C_BASE_SDRC->SDRC_TR= 0x2e0;
*pSDRAM = 0;
AT91C_BASE_SDRC->SDRC_MR = 0;
*pSDRAM = 0;
//puts("6\n");
}
#define _DATA_OFF_SET 0x00000020
void TestSDRAM()
{
volatile U32 *pSDRAM = (U32*)DRAM_BASE;
U32 i;
U32 j;
for (i=0;i<DRAM_SIZE/sizeof(U32);i++){
*(pSDRAM+i) = i+1/*0+_DATA_OFF_SET*/;
}
for (i=0;i<DRAM_SIZE/sizeof(U32);i++){
j = *(pSDRAM+i);
if(j!=(i+1/*0+_DATA_OFF_SET*/)){
printf("Bad address:0x%x wr = 0x%08X rd = 0x%08X\n",DRAM_BASE+i*sizeof(U32) ,i+1/*0+_DATA_OFF_SET*/,j);
//delay(500);
//puts("aaaaaaaaaaaaaaaa\n");
}
}
return;
}
int main(void)
{
U8 c;
int timeout=3000;
int bootflag=1;
AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
AT91F_RTC_InterruptDisable(AT91C_BASE_RTC, 0x1f);
AT91F_ST_DisableIt(AT91C_BASE_ST, 0xf);
AT91C_BASE_ST->ST_PIMR = 328; // 328/32768 S
// *AT91C_PMC_IDR = 0xf0f; //disabled in InitSDRAM(init.c)
// printf("\nST_PIMR = 0x%08x\n", AT91C_BASE_ST->ST_PIMR);
// AT91F_ST_EnableIt(AT91C_BASE_ST, AT91C_ST_PITS);
//设置网口MAC地址,先使能EMAC时钟,启动linux前要设置好MAC地址.
AT91F_EMAC_CfgPMC();
pEmac->EMAC_SA1L = ((int)OurEmacAddr[2] << 24) | ((int)OurEmacAddr[3] << 16) | ((int)OurEmacAddr[4] << 8) | OurEmacAddr[5];
pEmac->EMAC_SA1H = ((int)OurEmacAddr[0] << 8) | OurEmacAddr[1];
//when set an irq handler, the irq will be disabled in AT91F_AIC_ConfigureIt,
//so enable it after AT91F_AIC_ConfigureIt!!!
AT91F_AIC_ConfigureIt (
AT91C_BASE_AIC, // AIC base address
AT91C_ID_SYS, // System peripheral ID
AT91C_AIC_PRIOR_HIGHEST, // Max priority
AT91C_AIC_SRCTYPE_INT_LEVEL_SENSITIVE, // Level sensitive
SysIrqHandler ); // 将设置处理函数地址填入AIC_SVC[AT91C_ID_SYS]
//使能系统中断(包括ST,DBGU等)
AT91F_AIC_EnableIt(AT91C_BASE_AIC, AT91C_ID_SYS);
MMU_EnableICache();
downloadAddress = LINUX_KERNEL_ADDR;
/* while(1) { //读NAND FLASH 的BUSY脚状态
if(AT91F_PIO_GetInput(AT91C_BASE_PIOC)&AT91C_PIO_PC14)
putch('1');
else
putch('0');
delay(100);
}*/
/* while(1) {
delay(300);
putch('a');
}*/
puts("\n*********************************************\n");
//puts("* *\n");
puts("* BIOS For AT91RM9200 *\n");
//puts("* *\n");
puts("*********************************************\n");
//get counter from CKGR_MCFR
//printf("Set Processor Clock = %dHz \nMaster Clock = %dHz\n",
// AT91F_PMC_GetProcessorClock(AT91C_BASE_PMC, AT91C_BASE_CKGR, 32768),
// AT91F_PMC_GetMasterClock(AT91C_BASE_PMC, AT91C_BASE_CKGR, 32768));
InitPio();
InitTwi();
InitNorFlash();
// InitNandFlash();
InitSDRAM();
puts("1\n");
TestSDRAM();
puts("2\n");
while(timeout--)
{
int key_status;
key_status=GetKeyStatus();
if((key_status==1)||(key_status==2)||(key_status==3)||(key_status==4))
{
bootflag=2;
break;
}
}
// if(bootflag==1)
{
// FindNandBoot();
}
while(1) {
U16 i;
U8 c;
puts("Select\n");
for(i=0; Functions[i].FuncAddr; i++)
printf("%d : %s\n", i, Functions[i].str);
putch('\n');
c = getch();
if((c>='0')&&(c<('0'+i)))
(*Functions[c-'0'].FuncAddr)(downloadAddress, downloadFileSize);
}
}
static volatile U8 *RxTmp;
void DBGU_Rx_Isr(void)
{
//读完状态寄存器后才清掉中断源
unsigned int csr = (((AT91PS_USART)AT91C_BASE_DBGU)->US_CSR & ((AT91PS_USART)AT91C_BASE_DBGU)->US_IMR);
if (csr & AT91C_US_RXRDY) {
*RxTmp = AT91F_US_GetChar((AT91PS_USART) AT91C_BASE_DBGU);
// putch(*RxTmp);
RxTmp++;
}
}
U32 WaitComDownload(void);
void ComDownload(U32 a1, U32 a2)
{
if(WaitComDownload())
return;
start_kernel(downloadAddress, 0);
/* U8 sel;
puts("Select\n1: Kernel\n2: initrd\n3: boot\nEsc: exit\n");
while(1) {
sel = getch();
if(sel=='1') {
downloadAddress = LINUX_KERNEL_ADDR;
break;
}
if(sel=='2') {
downloadAddress = INITRD_START;
break;
}
if(sel=='3') {
downloadAddress = BOOT_PORG_ADDR;
break;
}
if(sel==0x1b)
return;
}
if(WaitComDownload())
return;
if(sel=='2')
return;
if(sel=='3')
start_kernel(downloadAddress, 0);
puts("Do you want to run it ?\n1: boot without initrd\n2: boot wiht initrd\nEsc: exit\n");
while(1) {
char c = getch();
if(c==0x1b)
break;
if((c=='1')||(c=='2'))
start_kernel(downloadAddress, (c=='1')?0:INITRD_START);
}
*/
}
/*
void RunProg(U32 addr, U32 size)
{
start_kernel(downloadAddress, 0);
}*/
void Program_eep(U32 addr, U32 size)
{
#ifdef IIC_SUPPORT
char *pdata;
U32 eep_addr;
int bytes, len;
U32 loop;
char data[EEP_RW_CHK_CNT];
eep_addr = 0;
pdata = (char *)addr;
len = size;
while(len>0) {
putchar('.');
bytes = (len>EEP_RW_CHK_CNT)?EEP_RW_CHK_CNT:len;
AT91F_TWI_Write(AT91C_BASE_TWI, eep_addr, pdata, bytes);
eep_addr += bytes;
pdata += bytes;
len -= bytes;
//for (loop=0; loop<30000; loop++);
delay(5);
}
puts("end\n");
eep_addr = 0;
pdata = (char *)addr;
len = size;
while(len) {
bytes = (len>EEP_RW_CHK_CNT)?EEP_RW_CHK_CNT:len;
AT91F_TWI_Read(AT91C_BASE_TWI, eep_addr, data, bytes);
for(loop=0; loop<bytes; loop++)
if(data[loop]!=pdata[loop]) {
puts("Program EEPROM fail!\n");
printf("%x,%x\n", loop, data[loop]);
return;
}
eep_addr += bytes;
pdata += bytes;
len -= bytes;
}
puts("Program EEPROM Success!\n");
#endif
}
U32 WaitComDownload(void)
{
U32 size;
U16 dnCS, CheckSum;
U8 *buf;
puts("Now download file from uart0...\n");
buf = (U8 *)downloadAddress;
RxTmp = buf-4;
//设置调试串口中断处理程序入口,使能属于调试串口的子中断
DbguIrqHandler = DBGU_Rx_Isr;
AT91F_US_EnableIt((AT91PS_USART) AT91C_BASE_DBGU, (AT91C_US_RXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE));
while((U32)RxTmp<(U32)buf) {
ShowLed(0);
delay(80);
ShowLed(15);
delay(80);
} //接收文件长度,4 bytes
size = *(U32 *)(buf-4);
downloadFileSize = size-6;
printf("Download File Size = %d\n", size);
while(((U32)RxTmp-(U32)buf)<(size-4)) {
ShowLed(0);
delay(80);
ShowLed(15);
delay(80);
}
AT91F_US_DisableIt((AT91PS_USART) AT91C_BASE_DBGU, (AT91C_US_RXRDY | AT91C_US_OVRE | AT91C_US_FRAME | AT91C_US_PARE));
DbguIrqHandler = NULL;
dnCS = (buf[downloadFileSize+1]<<8)|buf[downloadFileSize];
CheckSum = 0;
for(size=0; size<downloadFileSize; size++)
CheckSum += buf[size];
if(dnCS!=CheckSum) {
puts("\nCheckSum error!\n");
return 1;
}
puts("\nDwonload success\n");
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -