龙人的BIOS启动程序写的很好,研究之后,真是获益良多啊。当然期间比较系统看了ADS的GUIDE。说起GUIDE:
下面这几本对程序开发非常重要,最好仔细研读啊。
1. ADS Development Guide.pdf
2. ADS Compiler and Library Guide.pdf
3. ADS linker and utilities Guide.pdf
4. ADS Assembler Guide.pdf
是啊,都是E文,但看过之后,定会获准良多。当然有很多书就是翻译的芯片手册和上面的部分手册的部分内容,但翻译确实不怎么样,很多关键性的东西都没说清楚,甚至有些谬误,更是差之毫厘,谬以行里。有时会严重误导读者,正所为尽信书不如无书啊。古人早以预知。呵呵...不过,有些书写的或译的就还是不错的,如邵贝贝的《UCOSII...》,韦东山大哥的《嵌入式LINUX应用开发》...买书时要慎重、细心。买一本书就要消灭它,不是用来接灰尘的。
言归正传,我对龙人的代码进行一些简化与调整,以随项目需要添加代码,而且支持库函数了,省去写很多重实现代码,而这些代码编译器可以为我们配置。当然若仅做BOOT,直接进入LINUX或WINCE就没有必要留那些库了。但若用UCOSII的话,留着那些库,省不少心。另外保留了不用库的代码,只是被注释了而已。
下面就贴代码了。由于页面较窄,格式乱了些,COPY到UE中应该可能解决
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% start.s %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
;===================================================================================================
; NAME: START.S
; DESC: M-BOOT for uCOSII
; Configure Exception,ISR and stacks etc.
; Copy 'RO' and 'RW' from nand flash to sdram, and init 'ZI'.
; Jump to '__rt_entry' in sdram,later jump to main();
; Initialize C-variables
;===================================================================================================
; NAME: START.S
; DESC: M-BOOT for uCOSII
; Configure Exception,ISR and stacks etc.
; Copy 'RO' and 'RW' from nand flash to sdram, and init 'ZI'.
; Jump to '__rt_entry' in sdram,later jump to main();
; Initialize C-variables
;===================================================================================================
GET option.inc
GET S3C2410.inc
GET S3C2410.inc
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; macrodefinition table 宏定义表
;---------------------------------------------------------------------------------------------------
; macrodefinition table 宏定义表
;---------------------------------------------------------------------------------------------------
;Pre-defined constants
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
USERMODE EQU 0x10
FIQMODE EQU 0x11
IRQMODE EQU 0x12
SVCMODE EQU 0x13
ABORTMODE EQU 0x17
UNDEFMODE EQU 0x1b
MODEMASK EQU 0x1f
NOINT EQU 0xc0
;The location of stacks
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
UserStack EQU (_STACK_BASEADDRESS-0x3800) ;0x33ff4800 ~
SVCStack EQU (_STACK_BASEADDRESS-0x2800) ;0x33ff5800 ~
UndefStack EQU (_STACK_BASEADDRESS-0x2400) ;0x33ff5c00 ~
AbortStack EQU (_STACK_BASEADDRESS-0x2000) ;0x33ff6000 ~
IRQStack EQU (_STACK_BASEADDRESS-0x1000) ;0x33ff7000 ~
FIQStack EQU (_STACK_BASEADDRESS-0x0) ;0x33ff8000 ~
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;IMPOORT AND EXPORT DECLARATION
;---------------------------------------------------------------------------------------------------
IMPORT ClockInit
IMPORT MemSetup
IMPORT |Image$$RO$$Base| ; Base of ROM code
IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
IMPORT |Image$$ZI$$Base| ; Base and limit of area
IMPORT |Image$$ZI$$Limit| ; to zero initialise
IMPORT __use_no_semihosting_swi
;IMPOORT AND EXPORT DECLARATION
;---------------------------------------------------------------------------------------------------
IMPORT ClockInit
IMPORT MemSetup
IMPORT |Image$$RO$$Base| ; Base of ROM code
IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
IMPORT |Image$$ZI$$Base| ; Base and limit of area
IMPORT |Image$$ZI$$Limit| ; to zero initialise
IMPORT __use_no_semihosting_swi
EXPORT __user_initial_stackheap
EXPORT _sys_exit
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;中断处理宏代码 Note: HERE,they are not simply push and pop.
;---------------------------------------------------------------------------------------------------
EXPORT _sys_exit
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;中断处理宏代码 Note: HERE,they are not simply push and pop.
;---------------------------------------------------------------------------------------------------
MACRO
$HandlerLabel HANDLER $HandleLabel
;这段代码仅仅是跳进中断处理函数,关于现场保护、中断服务、现场恢复,没有实现。
$HandlerLabel ;需在代码中实现,以及实现中断嵌套,均需自己实现。
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it return to original address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
$HandlerLabel HANDLER $HandleLabel
;这段代码仅仅是跳进中断处理函数,关于现场保护、中断服务、现场恢复,没有实现。
$HandlerLabel ;需在代码中实现,以及实现中断嵌套,均需自己实现。
sub sp,sp,#4 ;decrement sp(to store jump address)
stmfd sp!,{r0} ;PUSH the work register to stack(lr does't push because it return to original address)
ldr r0,=$HandleLabel ;load the address of HandleXXX to r0
ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
MEND
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; INIT ENTRY 初始化函数入口函数
;---------------------------------------------------------------------------------------------------
CODE32
AREA mBoot, CODE, READONLY
ENTRY
EXPORT __ENTRY
__ENTRY
ResetEntry
; INIT ENTRY 初始化函数入口函数
;---------------------------------------------------------------------------------------------------
CODE32
AREA mBoot, CODE, READONLY
ENTRY
EXPORT __ENTRY
__ENTRY
ResetEntry
b ResetHandler
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
ResetHandler
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]
b HandlerUndef ;handler for Undefined mode
b HandlerSWI ;handler for SWI interrupt
b HandlerPabort ;handler for PAbort
b HandlerDabort ;handler for DAbort
b . ;reserved
b HandlerIRQ ;handler for IRQ interrupt
b HandlerFIQ ;handler for FIQ interrupt
HandlerFIQ HANDLER HandleFIQ
HandlerIRQ HANDLER HandleIRQ
HandlerUndef HANDLER HandleUndef
HandlerSWI HANDLER HandleSWI
HandlerDabort HANDLER HandleDabort
HandlerPabort HANDLER HandlePabort
ResetHandler
ldr r0,=WTCON ;watch dog disable
ldr r1,=0x0
str r1,[r0]
ldr r0,=INTMSK
ldr r1,=0xffffffff ;all interrupt disable
str r1,[r0]
ldr r1,=0xffffffff ;all interrupt disable
str r1,[r0]
ldr r0,=INTSUBMSK
ldr r1,=0x3ff ;all sub interrupt disable
str r1,[r0]
bl ClockInit
bl MemSetup
bl InitStacks
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;retarget RO,RW,ZI.
;---------------------------------------------------------------------------------------------------
;judge the boot mode. nor flash,nand flash or debug?
ldr r0, =BWSCON
ldr r0, [r0]
ands r0, r0, #6 ;OM[1:0] != 0, NOR FLash boot
bne copy_proc_beg ;don't read nand flash
adr r0, ResetEntry ;OM[1:0] == 0, NAND FLash boot
cmp r0, #0 ;if use Multi-ice,
bne copy_proc_beg ;don't read nand flash for boot
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;nand flash boot beg. copy 256 pages context to 'ResetEntry' in sdram.
;---------------------------------------------------------------------------------------------------
nand_boot_beg
mov r5, #NFCONF
ldr r0, =(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7)
str r0, [r5] ;Set nand flash control register
bl ReadNandID
mov r6, #0
ldr r0, =0xec73 ;ID=0xec73 nand flash.
cmp r5, r0
beq %F1
ldr r0, =0xec75 ;ID=0xec75 nand flash.
cmp r5, r0
beq %F1
mov r6, #1 ;by judge. return 1 in r6, if nand flash is K9F1208U0M
1
bl ReadNandStatus
;now ID in 'r5' and sratus in 'r1','r6'=1
mov r8, #0 ;it's the page Number. note: the using of 'ldr'
ldr r9, =ResetEntry ;what type addr it is on earth?(it's expected address == |Image$$RO$$Base|)
2
ands r0, r8, #0x1f ;get the low five bits into r0. ==00000b?
bne %F3 ;if(!=0) jump.just check each block (has 32 page).
mov r0, r8 ;r8->r0
bl CheckBadBlk ;check bad region of nand flash
cmp r0, #0 ;if data is 0xff.here rsl is eq.
addne r8, r8, #32 ;100000b if it's bad, jump to next block.
bne %F4 ;and jump to 4 . compare 'r8' with #256.
3 ;if the block is well, it begin to read the 32 pages from the block.
mov r0, r8
mov r1, r9
bl ReadNandPage ;## NOTE: the block bad check happen at the head of block.
add r9, r9, #512
add r8, r8, #1
4
cmp r8, #16 ;100000000b
bcc %B2
;Now the copy job is finished.
mov r5, #NFCONF ;DsNandFlash
ldr r0, [r5]
and r0, r0, #~0x8000
str r0, [r5]
ldr pc, =copy_proc_beg ;//### NOTE: Here it's very important.after this work cycle, the application will run in SDRAM.
;ldr绝对地址,跳到SDRAM中刚刚搬迁好的拷贝代码中去执行.why? look up the differences between 'ldr' and 'adr'.
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;nor flash copy proc code begin. but it maybe not necessary.
;---------------------------------------------------------------------------------------------------
copy_proc_beg
adr r0, ResetEntry ;now run in stepingstone, the r0 is 0.
ldr r2, BaseOfROM ;
cmp r0, r2 ;cmp r0, r2.
ldreq r0, TopOfROM ;如果相等的话,说明已经在SDRAM中了两中可能:1:debuging2:nand flash copy has
beq InitRam ;been done.TopOfROM->r0.但需要复制code区中的rw段
ldr r3, TopOfROM ;
0
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0
ldr r1,=0x3ff ;all sub interrupt disable
str r1,[r0]
bl ClockInit
bl MemSetup
bl InitStacks
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;retarget RO,RW,ZI.
;---------------------------------------------------------------------------------------------------
;judge the boot mode. nor flash,nand flash or debug?
ldr r0, =BWSCON
ldr r0, [r0]
ands r0, r0, #6 ;OM[1:0] != 0, NOR FLash boot
bne copy_proc_beg ;don't read nand flash
adr r0, ResetEntry ;OM[1:0] == 0, NAND FLash boot
cmp r0, #0 ;if use Multi-ice,
bne copy_proc_beg ;don't read nand flash for boot
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;nand flash boot beg. copy 256 pages context to 'ResetEntry' in sdram.
;---------------------------------------------------------------------------------------------------
nand_boot_beg
mov r5, #NFCONF
ldr r0, =(1<<15)|(1<<12)|(1<<11)|(7<<8)|(7<<4)|(7)
str r0, [r5] ;Set nand flash control register
bl ReadNandID
mov r6, #0
ldr r0, =0xec73 ;ID=0xec73 nand flash.
cmp r5, r0
beq %F1
ldr r0, =0xec75 ;ID=0xec75 nand flash.
cmp r5, r0
beq %F1
mov r6, #1 ;by judge. return 1 in r6, if nand flash is K9F1208U0M
1
bl ReadNandStatus
;now ID in 'r5' and sratus in 'r1','r6'=1
mov r8, #0 ;it's the page Number. note: the using of 'ldr'
ldr r9, =ResetEntry ;what type addr it is on earth?(it's expected address == |Image$$RO$$Base|)
2
ands r0, r8, #0x1f ;get the low five bits into r0. ==00000b?
bne %F3 ;if(!=0) jump.just check each block (has 32 page).
mov r0, r8 ;r8->r0
bl CheckBadBlk ;check bad region of nand flash
cmp r0, #0 ;if data is 0xff.here rsl is eq.
addne r8, r8, #32 ;100000b if it's bad, jump to next block.
bne %F4 ;and jump to 4 . compare 'r8' with #256.
3 ;if the block is well, it begin to read the 32 pages from the block.
mov r0, r8
mov r1, r9
bl ReadNandPage ;## NOTE: the block bad check happen at the head of block.
add r9, r9, #512
add r8, r8, #1
4
cmp r8, #16 ;100000000b
bcc %B2
;Now the copy job is finished.
mov r5, #NFCONF ;DsNandFlash
ldr r0, [r5]
and r0, r0, #~0x8000
str r0, [r5]
ldr pc, =copy_proc_beg ;//### NOTE: Here it's very important.after this work cycle, the application will run in SDRAM.
;ldr绝对地址,跳到SDRAM中刚刚搬迁好的拷贝代码中去执行.why? look up the differences between 'ldr' and 'adr'.
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;nor flash copy proc code begin. but it maybe not necessary.
;---------------------------------------------------------------------------------------------------
copy_proc_beg
adr r0, ResetEntry ;now run in stepingstone, the r0 is 0.
ldr r2, BaseOfROM ;
cmp r0, r2 ;cmp r0, r2.
ldreq r0, TopOfROM ;如果相等的话,说明已经在SDRAM中了两中可能:1:debuging2:nand flash copy has
beq InitRam ;been done.TopOfROM->r0.但需要复制code区中的rw段
ldr r3, TopOfROM ;
0
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0
adrl r0, ResetEntry ;don't use adr, 'cause out of range error occures
ldr r2, BaseOfROM
ldr r2, BaseOfROM
sub r2, r2, r3
sub r0, r0, r2
InitRam
ldr r2, BaseOfBSS
ldr r3, BaseOfZero
0 ;copy to 'RW'
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
sub r0, r0, r2
InitRam
ldr r2, BaseOfBSS
ldr r3, BaseOfZero
0 ;copy to 'RW'
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
mov r0, #0 ;init 'ZI' with 0.
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ldr pc, GotoMain ;bl Main Don't use main() because ......without library
; b .
ldr r3, EndOfBSS
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; ldr pc, GotoMain ;bl Main Don't use main() because ......without library
; b .
IMPORT __rt_entry ;using library
EXPORT __main
__main
b __rt_entry
EXPORT __main
__main
b __rt_entry
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;nand Flash base operating function.
;---------------------------------------------------------------------------------------------------
ReadNandID
mov r7,#NFCONF
ldr r0,[r7,#0] ;NFChipEn();
bic r0,r0,#0x800
str r0,[r7,#0]
mov r0,#0x90 ;WrNFCmd(RdIDCMD);
strb r0,[r7,#4]
mov r4,#0 ;WrNFAddr(0);
strb r4,[r7,#8]
1 ;while(NFIsBusy());
ldr r0,[r7,#0x10]
tst r0,#1
beq %B1
ldrb r0,[r7,#0xc] ;id = RdNFDat()<<8;
mov r0,r0,lsl #8
ldrb r1,[r7,#0xc] ;id |= RdNFDat();
orr r5,r1,r0
ldr r0,[r7,#0] ;NFChipDs();
orr r0,r0,#0x800
str r0,[r7,#0]
mov pc,lr ;get nand flash ID in 'r5' and return.
ReadNandStatus
mov r7,#NFCONF
ldr r0,[r7,#0] ;NFChipEn();
bic r0,r0,#0x800
str r0,[r7,#0]
mov r0,#0x70 ;WrNFCmd(QUERYCMD);
strb r0,[r7,#4]
ldrb r1,[r7,#0xc] ;r1 = RdNFDat();
ldr r0,[r7,#0] ;NFChipDs();
orr r0,r0,#0x800
str r0,[r7,#0]
mov pc,lr ;get the nand flash status value in 'r1' and return.
;nand Flash base operating function.
;---------------------------------------------------------------------------------------------------
ReadNandID
mov r7,#NFCONF
ldr r0,[r7,#0] ;NFChipEn();
bic r0,r0,#0x800
str r0,[r7,#0]
mov r0,#0x90 ;WrNFCmd(RdIDCMD);
strb r0,[r7,#4]
mov r4,#0 ;WrNFAddr(0);
strb r4,[r7,#8]
1 ;while(NFIsBusy());
ldr r0,[r7,#0x10]
tst r0,#1
beq %B1
ldrb r0,[r7,#0xc] ;id = RdNFDat()<<8;
mov r0,r0,lsl #8
ldrb r1,[r7,#0xc] ;id |= RdNFDat();
orr r5,r1,r0
ldr r0,[r7,#0] ;NFChipDs();
orr r0,r0,#0x800
str r0,[r7,#0]
mov pc,lr ;get nand flash ID in 'r5' and return.
ReadNandStatus
mov r7,#NFCONF
ldr r0,[r7,#0] ;NFChipEn();
bic r0,r0,#0x800
str r0,[r7,#0]
mov r0,#0x70 ;WrNFCmd(QUERYCMD);
strb r0,[r7,#4]
ldrb r1,[r7,#0xc] ;r1 = RdNFDat();
ldr r0,[r7,#0] ;NFChipDs();
orr r0,r0,#0x800
str r0,[r7,#0]
mov pc,lr ;get the nand flash status value in 'r1' and return.
WaitNandBusy
mov r0,#0x70 ;WrNFCmd(QUERYCMD);
mov r1,#NFCONF
strb r0,[r1,#4]
1 ;while(!(RdNFDat()&0x40));
ldrb r0,[r1,#0xc]
tst r0,#0x40
beq %B1
mov r0,#0 ;WrNFCmd(READCMD0);
strb r0,[r1,#4]
mov pc,lr
mov r0,#0x70 ;WrNFCmd(QUERYCMD);
mov r1,#NFCONF
strb r0,[r1,#4]
1 ;while(!(RdNFDat()&0x40));
ldrb r0,[r1,#0xc]
tst r0,#0x40
beq %B1
mov r0,#0 ;WrNFCmd(READCMD0);
strb r0,[r1,#4]
mov pc,lr
CheckBadBlk ;if the subfunc will invoke other subfunc, the 'lr' must be preserved.
mov r7, lr
mov r5, #NFCONF
bic r0, r0, #0x1f ;addr &= ~0x1f; clear low 5 bits.
ldr r1,[r5,#0] ;NFChipEn()
bic r1,r1,#0x800
str r1,[r5,#0]
mov r7, lr
mov r5, #NFCONF
bic r0, r0, #0x1f ;addr &= ~0x1f; clear low 5 bits.
ldr r1,[r5,#0] ;NFChipEn()
bic r1,r1,#0x800
str r1,[r5,#0]
mov r1,#0x50 ;WrNFCmd(READCMD2)
strb r1,[r5,#4]
mov r1, #6
strb r1,[r5,#8] ;WrNFAddr(6)
strb r0,[r5,#8] ;WrNFAddr(addr)
mov r1,r0,lsr #8 ;WrNFAddr(addr>>8)
strb r1,[r5,#8]
cmp r6,#0 ;if(NandAddr) |'r6' is 1 stand for is 64mb nand flash.
movne r0,r0,lsr #16 ;WrNFAddr(addr>>16) |it need four time addr sends.
strneb r0,[r5,#8]
bl WaitNandBusy ;WaitNFBusy()
strb r1,[r5,#4]
mov r1, #6
strb r1,[r5,#8] ;WrNFAddr(6)
strb r0,[r5,#8] ;WrNFAddr(addr)
mov r1,r0,lsr #8 ;WrNFAddr(addr>>8)
strb r1,[r5,#8]
cmp r6,#0 ;if(NandAddr) |'r6' is 1 stand for is 64mb nand flash.
movne r0,r0,lsr #16 ;WrNFAddr(addr>>16) |it need four time addr sends.
strneb r0,[r5,#8]
bl WaitNandBusy ;WaitNFBusy()
ldrb r0, [r5,#0xc] ;RdNFDat()
sub r0, r0, #0xff ;judge the data. if normal the result is 0, or is not 0.
mov r1,#0 ;WrNFCmd(READCMD0) write READCMD0 to CMD register.
strb r1,[r5,#4]
ldr r1,[r5,#0] ;NFChipDs()
orr r1,r1,#0x800
str r1,[r5,#0]
mov pc, r7 ;save the judgement result to r0 and return.
ReadNandPage
mov r7,lr
mov r4,r1 ;the 'RO' Adrr is in r1.
mov r5,#NFCONF
sub r0, r0, #0xff ;judge the data. if normal the result is 0, or is not 0.
mov r1,#0 ;WrNFCmd(READCMD0) write READCMD0 to CMD register.
strb r1,[r5,#4]
ldr r1,[r5,#0] ;NFChipDs()
orr r1,r1,#0x800
str r1,[r5,#0]
mov pc, r7 ;save the judgement result to r0 and return.
ReadNandPage
mov r7,lr
mov r4,r1 ;the 'RO' Adrr is in r1.
mov r5,#NFCONF
ldr r1,[r5,#0] ;NFChipEn()
bic r1,r1,#0x800
str r1,[r5,#0]
bic r1,r1,#0x800
str r1,[r5,#0]
mov r1,#0 ;WrNFCmd(READCMD0)
strb r1,[r5,#4]
strb r1,[r5,#8] ;WrNFAddr(0)
strb r0,[r5,#8] ;WrNFAddr(addr)
mov r1,r0,lsr #8 ;WrNFAddr(addr>>8)
strb r1,[r5,#8]
cmp r6,#0 ;if(NandAddr)
movne r0,r0,lsr #16 ;WrNFAddr(addr>>16)
strneb r0,[r5,#8]
ldr r0,[r5,#0] ;InitEcc()
orr r0,r0,#0x1000
str r0,[r5,#0]
bl WaitNandBusy ;WaitNFBusy()
mov r0,#0 ;for(i=0; i<512; i++)
1
ldrb r1,[r5,#0xc] ;buf[i] = RdNFDat()
strb r1,[r4,r0]
add r0,r0,#1
bic r0,r0,#0x10000 ;??
cmp r0,#0x200
bcc %B1
ldr r0,[r5,#0] ;NFChipDs()
orr r0,r0,#0x800
str r0,[r5,#0]
mov pc,r7
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;function initializing stacks "初始化栈指针"
;---------------------------------------------------------------------------------------------------
InitStacks
mov r0,lr
msr cpsr_cxsf,#0xdb ;UndefMode
ldr sp,=UndefStack
msr cpsr_cxsf,#0xd7 ;AbortMode
ldr sp,=AbortStack
strb r1,[r5,#4]
strb r1,[r5,#8] ;WrNFAddr(0)
strb r0,[r5,#8] ;WrNFAddr(addr)
mov r1,r0,lsr #8 ;WrNFAddr(addr>>8)
strb r1,[r5,#8]
cmp r6,#0 ;if(NandAddr)
movne r0,r0,lsr #16 ;WrNFAddr(addr>>16)
strneb r0,[r5,#8]
ldr r0,[r5,#0] ;InitEcc()
orr r0,r0,#0x1000
str r0,[r5,#0]
bl WaitNandBusy ;WaitNFBusy()
mov r0,#0 ;for(i=0; i<512; i++)
1
ldrb r1,[r5,#0xc] ;buf[i] = RdNFDat()
strb r1,[r4,r0]
add r0,r0,#1
bic r0,r0,#0x10000 ;??
cmp r0,#0x200
bcc %B1
ldr r0,[r5,#0] ;NFChipDs()
orr r0,r0,#0x800
str r0,[r5,#0]
mov pc,r7
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;function initializing stacks "初始化栈指针"
;---------------------------------------------------------------------------------------------------
InitStacks
mov r0,lr
msr cpsr_cxsf,#0xdb ;UndefMode
ldr sp,=UndefStack
msr cpsr_cxsf,#0xd7 ;AbortMode
ldr sp,=AbortStack
msr cpsr_cxsf,#0xd2 ;IRQMode
ldr sp,=IRQStack
msr cpsr_cxsf,#0xd1 ;FIQMode
ldr sp,=FIQStack
ldr sp,=IRQStack
msr cpsr_cxsf,#0xd1 ;FIQMode
ldr sp,=FIQStack
msr cpsr_cxsf,#0xdf ;SYSMode
ldr sp,=UserStack
msr cpsr_cxsf,#0xd3 ;SVCMode
ldr sp,=SVCStack
ldr sp,=UserStack
msr cpsr_cxsf,#0xd3 ;SVCMode
ldr sp,=SVCStack
mov pc,r0
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;remplement ADS system library functions that must't be requeited in nosemihosting application
;---------------------------------------------------------------------------------------------------
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;remplement ADS system library functions that must't be requeited in nosemihosting application
;---------------------------------------------------------------------------------------------------
__user_initial_stackheap
ldr r0,=EndOfBSS
ldr r1,=UserStack
mov pc,lr
_sys_exit
mov pc,lr
ldr r0,=EndOfBSS
ldr r1,=UserStack
mov pc,lr
_sys_exit
mov pc,lr
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;init functions
;---------------------------------------------------------------------------------------------------
;init functions
;---------------------------------------------------------------------------------------------------
;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ - KEY CODE FINISHED - $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;该处存放该段,即AREA声明的一个段里可能产生的LTORG文本池。
;---------------------------------------------------------------------------------------------------
LTORG ;在这里使用LTORG会使编译器产生的所有文本池填充在这里。
;该处存放该段,即AREA声明的一个段里可能产生的LTORG文本池。
;---------------------------------------------------------------------------------------------------
LTORG ;在这里使用LTORG会使编译器产生的所有文本池填充在这里。
BaseOfROM DCD |Image$$RO$$Base|
TopOfROM DCD |Image$$RO$$Limit|
BaseOfBSS DCD |Image$$RW$$Base|
BaseOfZero DCD |Image$$ZI$$Base|
EndOfBSS DCD |Image$$ZI$$Limit|
TopOfROM DCD |Image$$RO$$Limit|
BaseOfBSS DCD |Image$$RW$$Base|
BaseOfZero DCD |Image$$ZI$$Base|
EndOfBSS DCD |Image$$ZI$$Limit|
;------------------------------声明Main()函数宏变量并设置保存Main()入口地址-------------------------
; GBLS main_entry
;main_entry SETS "Main"
; IMPORT $main_entry
;GotoMain DCD $main_entry ;the first instruction from Main is place here.
; GBLS main_entry
;main_entry SETS "Main"
; IMPORT $main_entry
;GotoMain DCD $main_entry ;the first instruction from Main is place here.
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
; 内存表段 ;
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;为所有中断建立一个结构化的内存表。采用了命令'^'和'#',即MAP与FILED
ALIGN
; 内存表段 ;
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;为所有中断建立一个结构化的内存表。采用了命令'^'和'#',即MAP与FILED
ALIGN
AREA RamData, DATA, READWRITE
^ _ISR_STARTADDRESS ;MAP与"^"相同, MAP用于定义一个结构化的内存表(StorageMAP)的首地址。
HandleReset # 4
HandleUndef # 4 ;FIELD 与"#"相同, 伪指令用于定义一个结构化内存表中的数据域。
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
HandleReset # 4
HandleUndef # 4 ;FIELD 与"#"相同, 伪指令用于定义一个结构化内存表中的数据域。
HandleSWI # 4
HandlePabort # 4
HandleDabort # 4
HandleReserved # 4
HandleIRQ # 4
HandleFIQ # 4
;Don't use the label 'IntVectorTable',
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleRSV6 # 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleRSV24 # 4
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
;The value of IntVectorTable is different with the address you think it may be.
;IntVectorTable
HandleEINT0 # 4
HandleEINT1 # 4
HandleEINT2 # 4
HandleEINT3 # 4
HandleEINT4_7 # 4
HandleEINT8_23 # 4
HandleRSV6 # 4
HandleBATFLT # 4
HandleTICK # 4
HandleWDT # 4
HandleTIMER0 # 4
HandleTIMER1 # 4
HandleTIMER2 # 4
HandleTIMER3 # 4
HandleTIMER4 # 4
HandleUART2 # 4
HandleLCD # 4
HandleDMA0 # 4
HandleDMA1 # 4
HandleDMA2 # 4
HandleDMA3 # 4
HandleMMC # 4
HandleSPI0 # 4
HandleUART1 # 4
HandleRSV24 # 4
HandleUSBD # 4
HandleUSBH # 4
HandleIIC # 4
HandleUART0 # 4
HandleSPI1 # 4
HandleRTC # 4
HandleADC # 4
END
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% init.c %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//the functions in the file are invoked by code in start.s
/***********************************************Copyleft***********************************************
**
** Enjoying-Spring's Blog
** http://enjoyspring.cublog.cn
**
**
**---------------------------------------------File Info----------------------------------------------
** File name: init.c
** Created by: Kevin Liu
** Created date: 2009-07-12
** Last modified Date:
** Last Version: 1.0
** Descriptions: The start up codes for S3C2410, including the initializing codes for the entry
** point of exceptions and the stacks of user tasks.Every project should have a
** independent copy of this file for related modifications.
**----------------------------------------------------------------------------------------------------
**
** You can use this file freely. if you change this file, modify some faults or advanced this file,
** please send this file to my E_Mail for share with more developers.
**
******************************************************************************************************/
**
** Enjoying-Spring's Blog
** http://enjoyspring.cublog.cn
**
**
**---------------------------------------------File Info----------------------------------------------
** File name: init.c
** Created by: Kevin Liu
** Created date: 2009-07-12
** Last modified Date:
** Last Version: 1.0
** Descriptions: The start up codes for S3C2410, including the initializing codes for the entry
** point of exceptions and the stacks of user tasks.Every project should have a
** independent copy of this file for related modifications.
**----------------------------------------------------------------------------------------------------
**
** You can use this file freely. if you change this file, modify some faults or advanced this file,
** please send this file to my E_Mail for share with more developers.
**
******************************************************************************************************/
#include "s3c2410.h"
#define S3C2410_MPLL_200MHZ ((0x5c<<12)|(0x04<<4)|(0x00))
//-------------------------------------declaration functions------------------------------------------
void ClockInit(void);
void MemSetup(void);
void MemSetup(void);
//-------------------------------------implement base functions---------------------------------------
void ClockInit(void)
{
// LOCKTIME = 0x00ffffff; // 使用默认值即可
rCLKDIVN = 0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
{
// LOCKTIME = 0x00ffffff; // 使用默认值即可
rCLKDIVN = 0x03; // FCLK:HCLK:PCLK=1:2:4, HDIVN=1,PDIVN=1
// 如果HDIVN非0,CPU的总线模式应该从“fast bus mode”变为“asynchronous bus mode”
__asm
{
mrc p15, 0, r1, c1, c0, 0 // 读出控制寄存器
orr r1, r1, #0xc0000000 // 设置为“asynchronous bus mode”
mcr p15, 0, r1, c1, c0, 0 // 写入控制寄存器
}
__asm
{
mrc p15, 0, r1, c1, c0, 0 // 读出控制寄存器
orr r1, r1, #0xc0000000 // 设置为“asynchronous bus mode”
mcr p15, 0, r1, c1, c0, 0 // 写入控制寄存器
}
rMPLLCON = S3C2410_MPLL_200MHZ; // 现在,FCLK=200MHz,HCLK=100MHz,PCLK=50MHz
return;
}
return;
}
void MemSetup(void)
{
// 存储控制器13个寄存器的值
rBWSCON = 0x22011110; //BWSCON
rBANKCON0 = 0x00000700; //BANKCON0
rBANKCON1 = 0x00000700; //BANKCON1
rBANKCON2 = 0x00000700; //BANKCON2
rBANKCON3 = 0x00000700; //BANKCON3
rBANKCON4 = 0x00000700; //BANKCON4
rBANKCON5 = 0x00000700; //BANKCON5
rBANKCON6 = 0x00018005; //BANKCON6
rBANKCON7 = 0x00018005; //BANKCON7
rREFRESH = 0x008C04F4;
rBANKSIZE = 0x000000B1; //BANKSIZE
rMRSRB6 = 0x00000030; //MRSRB6
rMRSRB7 = 0x00000030; //MRSRB7
return;
}
{
// 存储控制器13个寄存器的值
rBWSCON = 0x22011110; //BWSCON
rBANKCON0 = 0x00000700; //BANKCON0
rBANKCON1 = 0x00000700; //BANKCON1
rBANKCON2 = 0x00000700; //BANKCON2
rBANKCON3 = 0x00000700; //BANKCON3
rBANKCON4 = 0x00000700; //BANKCON4
rBANKCON5 = 0x00000700; //BANKCON5
rBANKCON6 = 0x00018005; //BANKCON6
rBANKCON7 = 0x00018005; //BANKCON7
rREFRESH = 0x008C04F4;
rBANKSIZE = 0x000000B1; //BANKSIZE
rMRSRB6 = 0x00000030; //MRSRB6
rMRSRB7 = 0x00000030; //MRSRB7
return;
}
/******************************************************************************************************/
/** THE END **/
/******************************************************************************************************/
/** THE END **/
/******************************************************************************************************/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Main.c %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/***********************************************Copyleft***********************************************
**
** Enjoying-Spring's Blog
** http://enjoyspring.cublog.cn
**
**
**---------------------------------------------File Info----------------------------------------------
** File name: init.c
** Created by: Kevin Liu
** Created date: 2009-07-12
** Last modified Date:
** Last Version: 1.0
** Descriptions: The start up codes for S3C2410, including the initializing codes for the entry
** point of exceptions and the stacks of user tasks.Every project should have a
** independent copy of this file for related modifications.
**----------------------------------------------------------------------------------------------------
**
** You can use this file freely. if you change this file, modify some faults or advanced this file,
** please send this file to my E_Mail for share with more developers.
**
******************************************************************************************************/
**
** Enjoying-Spring's Blog
** http://enjoyspring.cublog.cn
**
**
**---------------------------------------------File Info----------------------------------------------
** File name: init.c
** Created by: Kevin Liu
** Created date: 2009-07-12
** Last modified Date:
** Last Version: 1.0
** Descriptions: The start up codes for S3C2410, including the initializing codes for the entry
** point of exceptions and the stacks of user tasks.Every project should have a
** independent copy of this file for related modifications.
**----------------------------------------------------------------------------------------------------
**
** You can use this file freely. if you change this file, modify some faults or advanced this file,
** please send this file to my E_Mail for share with more developers.
**
******************************************************************************************************/
#include "s3c2410.h"
#define GPF6_out (1<<(6*2))
#define GPF7_out (1<<(7*2))
#define GPF6_out (1<<(6*2))
#define GPF7_out (1<<(7*2))
void wait(unsigned long dly)
{
for(; dly > 0; dly--);
}
//int Main(void) //without library.
int main(void) //using library
{
rGPFCON = GPF6_out|GPF7_out; // 将LED1-2对应的GPB6/7两个引脚设为输出
rGPFDAT=0xFF;
{
for(; dly > 0; dly--);
}
//int Main(void) //without library.
int main(void) //using library
{
rGPFCON = GPF6_out|GPF7_out; // 将LED1-2对应的GPB6/7两个引脚设为输出
rGPFDAT=0xFF;
while(1){
wait(480000);
rGPFDAT=rGPFDAT&0xBF; //开LED1
rGPFDAT=rGPFDAT|0x80; //关LED2
wait(480000);
rGPFDAT=rGPFDAT&0x7F; //开LED2
rGPFDAT=rGPFDAT|0x40; //关LED1
}
return 0;
}
wait(480000);
rGPFDAT=rGPFDAT&0xBF; //开LED1
rGPFDAT=rGPFDAT|0x80; //关LED2
wait(480000);
rGPFDAT=rGPFDAT&0x7F; //开LED2
rGPFDAT=rGPFDAT|0x40; //关LED1
}
return 0;
}
/******************************************************************************************************/
/** THE END **/
/******************************************************************************************************/
/** THE END **/
/******************************************************************************************************/