⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cstartup_boot_sam9.s

📁 AT91BootSAM9261.zip,atmelsam9261微处理器启动初始化源代码
💻 S
字号:
;------------------------------------------------------------------------------
;-         ATMEL Microcontroller Software Support  -  ROUSSET  -
;------------------------------------------------------------------------------
; The software is delivered "AS IS" without warranty or condition of any
; kind, either express, implied or statutory. This includes without
; limitation any warranty or condition with respect to merchantability or
; fitness for any particular purpose, or against the infringements of
; intellectual property rights of others.
;-----------------------------------------------------------------------------
;- File source          : cstartup_boot.arm
;- Object               : Generic CStartup
;- Compilation flag     : None
;-
;- 1.0 01/22/04 	FBr : Creation ARM ADS
;------------------------------------------------------------------------------

;------------------------------------------------------------------------------
;- Area Definition
;-----------------
;- Must be defined as function to put first in the code as it must be mapped
;- at offset 0 of the flash EBI_CSR0, ie. at address 0 before remap.
;------------------------------------------------------------------------------
                AREA        reset, CODE, READONLY

	IF :DEF:AT91SAM9XE512
		INCLUDE		AT91SAM9XE512.inc
	ENDIF

	IF :DEF:AT91SAM9260
		INCLUDE		AT91SAM9260.inc
	ENDIF

	IF :DEF:AT91SAM9261
		INCLUDE		AT91SAM9261.inc
	ENDIF

	IF :DEF:AT91SAM9262
		INCLUDE		AT91SAM9262.inc
	ENDIF

	IF :DEF:AT91C340
		INCLUDE		AT91C340.inc
	ENDIF


ARM_MODE_FIQ	EQU	0x11
I_BIT			EQU	0x80
F_BIT			EQU	0x40


;------------------------------------------------------------------------------
;- Define the entry point
;------------------------

	EXPORT	__ENTRY
__ENTRY

;------------------------------------------------------------------------------
;- Exception vectors ( before Remap )
;------------------------------------
;- These vectors are read at address 0.
;- They absolutely requires to be in relative addresssing mode in order to 
;- guarantee a valid jump. For the moment, all are just looping (what may be 
;- dangerous in a final system). If an exception occurs before remap, this 
;- would result in an infinite loop. 
;------------------------------------------------------------------------------
	IF :DEF:AT91SAM9XE512
		IMPORT AT91F_EFC_Perform_Command
	ENDIF

                B           InitReset       	; reset
undefvec
                B           undefvec        	; Undefined Instruction
swivec
	IF :DEF:AT91SAM9XE512
		DCD AT91F_EFC_Perform_Command
	ELSE
                B           _main          	; Software Interrupt
	ENDIF                
pabtvec
                B           pabtvec         	; Prefetch Abort
dabtvec 
                B           dabtvec         	; Data Abort
rsvdvec
                B           rsvdvec         	; reserved
irqvec
                B         	irqvec    			; IRQ : read the AIC
				
	IF :DEF:AT91SAM9260 :LOR: :DEF:AT91SAM9XE512
fiqvec
;------------------------------------------------------------------------------
;- FIQ Handler
;------------------------------------------------------------------------------
;- r8:  counter value
;- r9:  TC0 Base Address
;- r10: PIO Base Address
;- r11: AIC Base Address
;- r12: Address of the application structure AT91S_FIQ_PROCESS
;------------------------------------------------------------------------------	

; Clear AIC source
	mov     r13, #(1:SHL:AT91C_ID_PIOB)
	str     r13, [r11, #AIC_ICCR]	
	
; Acknowledge the IT with PIO_ISR
	ldr     r13, [r10, #PIO_ISR]

; Check the semaphore
	ldr     r13, [r12, #4]
	ands    r13, r13, #1

; If the semaphore is not ready return
	subnes  pc,lr,#4
		
; Test the PIO state PIO_PDSR
	ldr     r13, [r10, #PIO_PDSR]
	ands    r13,  r13, #AT91C_PB14_DRXD	

; Negedge:  TC0 SWTRG
	ldreq	r13, =AT91C_TC_SWTRG
	streq	r13, [r9, #TC_CCR]
	
; Posedge:
; Capture the TC0 value in the TC_CV register
; Store the end event
	ldrne   r8, [ r9, #TC_CV]
	strneh  r8, [r12, #2]

; Set the semaphore
	movne   r13, #1
	strne	r13, [r12, #4]

; Return 
	subs    pc,lr,#4

;-------------------
;- The reset handler
;-------------------
	EXPORT	InitReset

InitReset

;------------------------------------------------------------------------------
;FIQ Init
;------------------------------------------------------------------------------
;- Switch to Fast Interrupt Mode
	mrs     r0, CPSR
	msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT
	
;- Init banked registers
	add     r2, pc,#-(8+.-FiqInitData)  ; @ where to read values (relative)
	ldmia   r2, {r9, r10, r11, r12}
	
;- Back to current Mode F_BIT cleared
	bic     r0, r0, #F_BIT
	msr     CPSR_c, r0
	b       EndInitFiq
                
FiqInitData
	IMPORT Fiq_Process
	DCD   AT91C_BASE_TC0     ;TC0 Base Address 
	DCD   AT91C_BASE_PIOB    ;PIO Base Address 
	DCD   AT91C_BASE_AIC     ;AIC Base Address 
	DCD   Fiq_Process        ;mailbox @ between FIQ hdlr & application 
EndInitFiq

	ELSE		; END AT91SAM9260

fiqvec
				B			fiqvec				; FIQ

;-------------------
;- The reset handler
;-------------------
InitReset

	ENDIF

;-------------------------------------
;- Setup the stack for supervisor mode
;-------------------------------------
	ldr     sp, = TOP_OF_MEMORY	; Init stack SVC


;------------------------------------------------------------------------------
;PMC Init
;------------------------------------------------------------------------------
;- Main Oscillator Bypass
;------------------------------------------------------------------------------
	IF :DEF:AT91SAM9262 :LOR: :DEF:AT91SAM9260 :LOR: :DEF:AT91SAM9XE512
	
	ldr     r1, = AT91C_BASE_PMC	; Get the PMC Base Address
;-Main oscillator Bypass 	PMC_MOR
	ldr 	r0, = AT91C_CKGR_OSCBYPASS
	str     r0, [r1, #PMC_MOR]

;- Reading the PMC Main Clock Frequency Register to detect when MAINF value is available
    	mov     r4, #AT91C_CKGR_MAINRDY
    	mov 	r0, #32		; Timeout
    	
MAINRDY_Loop
    	ldr     r3, [r1, #PMC_MCFR]
    	and     r3, r4, r3
    	cmp     r3, #AT91C_CKGR_MAINRDY
    	beq     MAINF_Read
	subs	r0, r0, #1
    	bne     MAINRDY_Loop

MAINF_Read    
    	ldr     r4, =AT91C_CKGR_MAINF
    	ldr     r3, [r1, #PMC_MCFR]
    	and     r3, r4, r3
    	cmp     r3, #16
	bgt	Init_MCKR	; MAINF > 16 so External Clock on XIN

	mov 	r0, #0		; Clear AT91C_CKGR_OSCBYPASS
	str     r0, [r1, #PMC_MOR]
    
	ENDIF

;------------------------------------------------------------------------------
;PMC Init Step 1.
;------------------------------------------------------------------------------
;- Enable the Main Oscillator
;------------------------------------------------------------------------------

AT91C_CKGR_OSCOUNT_18432        EQU (0x40:SHL:8) ;- (CKGR) MO Start-up Time Max 15ms

	ldr     r1, = AT91C_BASE_PMC	; Get the PMC Base Address
;-Main oscillator Enable register	PMC_MOR : Enable main oscillator , OSCOUNT = 0xFF
	ldr 	r0, = AT91C_CKGR_MOSCEN:OR:AT91C_CKGR_OSCOUNT_18432
	str     r0, [r1, #PMC_MOR]

;- Reading the PMC Status register to detect when the Main Oscillator is enabled
    mov     r4, #AT91C_PMC_MOSCS
MOSCS_Loop
    ldr     r3, [r1, #PMC_SR]
    and     r3, r4, r3
    cmp     r3, #AT91C_PMC_MOSCS
    bne     MOSCS_Loop
    
;------------------------------------------------------------------------------
;PMC Init Step 2.
;------------------------------------------------------------------------------
;- Switch on the Main Oscillator 18.432 MHz
;------------------------------------------------------------------------------
Init_MCKR

;-Master Clock Controller register PMC_MCKR
	ldr 	r0, = AT91C_PMC_CSS_MAIN_CLK:OR:AT91C_PMC_PRES_CLK
	str     r0, [r1, #PMC_MCKR]

;- Reading the PMC Status register to detect when the Main Oscillator is enabled
    mov     r4, #AT91C_PMC_MCKRDY
MCKRDY_Loop
    ldr     r3, [r1, #PMC_SR]
    and     r3, r4, r3
    cmp     r3, #AT91C_PMC_MCKRDY
    bne     MCKRDY_Loop 

;------------------------------------------------------------------------------
;- Initialise C variables
;------------------------------------------------------------------------------
;- Following labels are automatically generated by the linker. 
;- RO: Read-only = the code
;- RW: Read Write = the data pre-initialized and zero-initialized.
;- ZI: Zero-Initialized.
;- Pre-initialization values are located after the code area in the image.
;- Zero-initialized datas are mapped after the pre-initialized.
;- Note on the Data position : 
;------------------------------------------------------------------------------

	add     r2, pc,#-(8+.-CInitData)  ; @ where to read values (relative)
	ldmia   r2, {r0, r1, r3, r4}
	
	cmp         r0, r1                  ; Check that they are different
	beq         EndRW
LoopRW	
	cmp         r1, r3                  ; Copy init data
	ldrcc       r2, [r0], #4
	strcc       r2, [r1], #4
	bcc         LoopRW
EndRW

	mov         r2, #0
LoopZI	
	cmp         r3, r4                  ; Zero init
	strcc       r2, [r3], #4
	bcc         LoopZI
 
	b           EndInitC
                
CInitData
 	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|      ; Top of zero init segment
	
	DCD     |Image$$RO$$Limit|      ; End of ROM code (=start of ROM data)
 	DCD     |Image$$RW$$Base|       ; Base of RAM to initialise
 	DCD     |Image$$ZI$$Base|       ; Base and limit of area
 	DCD     |Image$$ZI$$Limit|      ; Top of zero init segment
EndInitC

;------------------------------------------------------------------------------
;- Low level Init is performed in a C function: AT91F_LowLevelInit
;------------------------------------------------------------------------------

	IMPORT     AT91F_LowLevelInit

	ldr       r0, = AT91F_LowLevelInit
	mov       lr, pc
	bx        r0

;------------------------------------------------------------------------------
;- Specific Download by DataFlash on internal SRAM
;------------------------------------------------------------------------------
	IF :DEF:AT91SAM9XE512
	
	ELSE

; Chip Select 0 : NPCS0 %1110
AT91C_SPI_PCS0_DATAFLASH	EQU 	0xE

; Chip Select 1 : NPCS1 %1101
AT91C_SPI_PCS1_DATAFLASH	EQU		0xD

	IMPORT     AT91F_DataFlashBoot

	ldr       r1, = AT91F_DataFlashBoot
	ldr 	  r0, = AT91C_SPI_PCS0_DATAFLASH
	mov       lr, pc
	bx        r1

	IF :DEF: AT91SAM9260

	ldr       r1, = AT91F_DataFlashBoot
	ldr 	  r0, = AT91C_SPI_PCS1_DATAFLASH
	mov       lr, pc
	bx        r1
	
	ENDIF

;------------------------------------------------------------------------------
;- Specific Download by NandFlash on internal SRAM
;------------------------------------------------------------------------------
	IF :DEF: AT91SAM9262 :LOR: :DEF: AT91SAM9260

	IMPORT     AT91F_NandFlashBoot

	ldr       r0, = AT91F_NandFlashBoot
	mov       lr, pc
	bx        r0
	
	ENDIF
	
;--------------------------------------------
;- Read/modify/write CP15 control register 1
;- Enable I-Cache
;--------------------------------------------
; DO NOT USE I-CACHE FOR AUTOBAUDRATE !!!
;--------------------------------------------
	IF :DEF: AT91SAM9260

	ELSE

AT91C_ENABLE_ICACHE		EQU (1:SHL:12)

    	mrc     p15, 0, r5, c1, c0,0	; read cp15 reg1
	ldr 	r6, = AT91C_ENABLE_ICACHE 
    	orr     r5, r5, r6             
	mcr 	p15, 0, r5, c1, c0, 0	; write cp15 reg1

	ENDIF

	ENDIF	; END !AT91SAM9XE512
;------------------------------------------------------------------------------
;- Branch on C code Main function (with interworking)
;----------------------------------------------------
;- Branch must be performed by an interworking call as either an ARM or Thumb 
;- main C function must be supported. This makes the code not position-
;- independant. A Branch with link would generate errors 
;------------------------------------------------------------------------------
	IMPORT      main
_main
__main
	EXPORT    _main
	EXPORT    __main
	ldr       r0, =main
	mov       lr, pc
	bx        r0

End
	b           End
	
;------------------------------------------------------------------------------
;- Jump for SAMBA-Boot
;- Write CP15 control register 7 : Invalidate I-Cache
;------------------------------------------------------------------------------

	EXPORT  Jump
Jump	
	ldr 	r7, = 0
	mcr 	p15, 0, r7, c7, c5, 0

	ldr		lr, =_main
	bx		r0				
	
End2
	b           End2
	
;------------------------------------------------------------------------------
;- Remap for DataFlash-Boot
;------------------------------------------------------------------------------

	EXPORT  Remap
Remap
	ldr		r2, = 0
	ldr     r1, = AT91C_BASE_MATRIX	; Get the MATRIX Base Address

	IF :DEF:AT91SAM9261
		ldr	r0, = AT91C_MATRIX_RCB0 | AT91C_MATRIX_RCB1
		str     r0, [r1,#MATRIX_MCFG]
	ELSE
		ldr	r0, = AT91C_MATRIX_RCA926I | AT91C_MATRIX_RCA926D
		str     r0, [r1,#MATRIX_MRCR]	
	ENDIF

	mov 	pc, r2				

End3
	b           End3
	
            END

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -