72 строки
		
	
	
	
		
			1,9 КиБ
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			72 строки
		
	
	
	
		
			1,9 КиБ
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
; This file provides common code across AVRs that cannot be implemented directly
 | 
						|
; in Go.
 | 
						|
; The reset vector is device-specific and is generated by tools/gen-device-avr.py.
 | 
						|
 | 
						|
; Startup code
 | 
						|
.section .text.__vector_RESET
 | 
						|
.global  __vector_RESET
 | 
						|
__vector_RESET:
 | 
						|
    clr  r1          ; r1 is expected to be 0 by the C calling convention
 | 
						|
 | 
						|
    ; Set up the stack pointer.
 | 
						|
    ldi  xl, lo8(_stack_top)
 | 
						|
    ldi  xh, hi8(_stack_top)
 | 
						|
    out  0x3d, xl; SPL
 | 
						|
    out  0x3e, xh; SPH
 | 
						|
 | 
						|
    ; Subtract one from the stack pointer, so it doesn't point in the .data section.
 | 
						|
    push r0
 | 
						|
 | 
						|
    ; Initialize .data
 | 
						|
init_data:
 | 
						|
    ldi  xl, lo8(_sdata)
 | 
						|
    ldi  xh, hi8(_sdata)
 | 
						|
    ldi  yl, lo8(_edata)
 | 
						|
    ldi  yh, hi8(_edata)
 | 
						|
    ldi  zl, lo8(_sidata)
 | 
						|
    ldi  zh, hi8(_sidata)
 | 
						|
init_data_loop:
 | 
						|
    cp   xl, yl         ; if x == y
 | 
						|
    cpc  xh, yh
 | 
						|
    breq init_data_end  ; goto main
 | 
						|
    lpm  r0, Z+         ; r0 = *(z++)
 | 
						|
    st   X+, r0         ; *(x++) = r0
 | 
						|
    rjmp init_data_loop ; goto init_data_loop
 | 
						|
init_data_end:
 | 
						|
 | 
						|
    ; main will be placed right after here by the linker script so there's no
 | 
						|
    ; need to jump.
 | 
						|
 | 
						|
 | 
						|
; This is the default handler for interrupts, if triggered but not defined.
 | 
						|
; Sleep inside so that an accidentally triggered interrupt won't drain the
 | 
						|
; battery of a battery-powered device.
 | 
						|
.section .text.__vector_default
 | 
						|
.global  __vector_default
 | 
						|
__vector_default:
 | 
						|
    sleep
 | 
						|
    rjmp __vector_default
 | 
						|
 | 
						|
 | 
						|
; The only thing this WDT handler really does is disable itself, to get out of
 | 
						|
; sleep mode.
 | 
						|
.section .text.__vector_WDT
 | 
						|
.global  __vector_WDT
 | 
						|
__vector_WDT:
 | 
						|
    push r16
 | 
						|
 | 
						|
    clr  r16
 | 
						|
    wdr            ; Reset watchdog
 | 
						|
    out  0x34, r16 ; Clear reset reason (MCUSR)
 | 
						|
 | 
						|
    ; part 1: set WDCE and WDE to enable editing WDTCSR
 | 
						|
    lds  r16, 0x60 ; r16 = WDTCSR
 | 
						|
    ori  r16, 0x18 ; r16 |= WDCE | WDE
 | 
						|
    sts  0x60, r16 ; WDTCSR = r16
 | 
						|
 | 
						|
    ; part 2: within 4 clock cycles, set the new value for WDTCSR
 | 
						|
    clr  r16
 | 
						|
    sts  0x60, r16 ; WDTCSR = 0
 | 
						|
 | 
						|
    pop  r16
 | 
						|
    reti
 |