github.com/aykevl/tinygo@v0.5.0/targets/avr.S (about) 1 ; This file provides common code across AVRs that cannot be implemented directly 2 ; in Go. 3 ; The reset vector is device-specific and is generated by tools/gen-device-avr.py. 4 5 ; Startup code 6 .section .text.__vector_RESET 7 .global __vector_RESET 8 __vector_RESET: 9 clr r1 ; r1 is expected to be 0 by the C calling convention 10 11 ; Set up the stack pointer. 12 ldi xl, lo8(_stack_top) 13 ldi xh, hi8(_stack_top) 14 out 0x3d, xl; SPL 15 out 0x3e, xh; SPH 16 17 ; Subtract one from the stack pointer, so it doesn't point in the .data section. 18 push r0 19 20 ; Initialize .data 21 init_data: 22 ldi xl, lo8(_sdata) 23 ldi xh, hi8(_sdata) 24 ldi yl, lo8(_edata) 25 ldi yh, hi8(_edata) 26 ldi zl, lo8(_sidata) 27 ldi zh, hi8(_sidata) 28 init_data_loop: 29 cp xl, yl ; if x == y 30 cpc xh, yh 31 breq init_data_end ; goto main 32 lpm r0, Z+ ; r0 = *(z++) 33 st X+, r0 ; *(x++) = r0 34 rjmp init_data_loop ; goto init_data_loop 35 init_data_end: 36 37 ; main will be placed right after here by the linker script so there's no 38 ; need to jump. 39 40 41 ; The only thing this WDT handler really does is disable itself, to get out of 42 ; sleep mode. 43 .section .text.__vector_WDT 44 .global __vector_WDT 45 __vector_WDT: 46 push r16 47 48 clr r16 49 wdr ; Reset watchdog 50 out 0x34, r16 ; Clear reset reason (MCUSR) 51 52 ; part 1: set WDCE and WDE to enable editing WDTCSR 53 lds r16, 0x60 ; r16 = WDTCSR 54 ori r16, 0x18 ; r16 |= WDCE | WDE 55 sts 0x60, r16 ; WDTCSR = r16 56 57 ; part 2: within 4 clock cycles, set the new value for WDTCSR 58 clr r16 59 sts 0x60, r16 ; WDTCSR = 0 60 61 pop r16 62 reti