mirror of https://github.com/tinygo-org/tinygo.git
wasmstm32webassemblymicrocontrollerarmavrspiwasiadafruitarduinocircuitplayground-expressgpioi2cllvmmicrobitnrf51nrf52nrf52840samd21tinygo
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
84 lines
2.2 KiB
84 lines
2.2 KiB
; 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.
|
|
|
|
; These definitions are necessary because LLVM does not yet know these register
|
|
; aliases. See: https://reviews.llvm.org/D96492
|
|
#define xl r26
|
|
#define xh r27
|
|
#define yl r28
|
|
#define yh r29
|
|
#define zl r30
|
|
#define zh r31
|
|
|
|
; Ugly hack until https://reviews.llvm.org/D137572 is merged.
|
|
#if !defined(__AVR_HAVE_ELPM__) && defined(__flash1)
|
|
#define __AVR_HAVE_ELPM__
|
|
#endif
|
|
|
|
; 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)
|
|
#ifdef __AVR_HAVE_ELPM__
|
|
ldi r16, hh8(_sidata) ; RAMPZ = hh8(_sidata)
|
|
out 0x3b, r16
|
|
#endif
|
|
init_data_loop:
|
|
cp xl, yl ; if x == y
|
|
cpc xh, yh
|
|
breq init_data_end ; goto main
|
|
#ifdef __AVR_HAVE_ELPM__
|
|
elpm r0, Z+ ; r0 = *(z++)
|
|
#else
|
|
lpm r0, Z+ ; r0 = *(z++)
|
|
#endif
|
|
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.
|
|
|
|
|
|
; 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
|
|
|