AvrAsmLib/src/avr_asm_lib/avr_asm_lib.S

112 lines
2.0 KiB
ArmAsm
Raw Normal View History

2021-01-19 12:28:33 +03:00
#define __SFR_OFFSET 0
#define LED_PORT 7
#include "avr/io.h" // ~ #include "avr/iom328p.h"
.global init
.global blink
.global read_temp
.global float_test
init:
sbi DDRD, LED_PORT
ret
float_test:
ldi r25, 0b00111110
ldi r24, 0b00100000
ldi r23, 0b01000000
ldi r22, 0b00000000
clr r1
ret
blink:
ldi r20, 250
call delay_n_ms
ldi r20, 250
call delay_n_ms
sbi PORTD, LED_PORT ; high
ldi r20, 250
call delay_n_ms
cbi PORTD, LED_PORT ; low
ret
read_temp:
; args: r24 to r20, where r24 is the lowest
; return: r24 to r19, where r24 is the lowest
cli ; forbids interruptions
push r29
ldi r30, 0b00000000
sts PRR, r30
subi r24, 14 ; because A0 is D14
; convert pin number to bitmask (r31 is resulting mask)
ldi r31, 1 ; means port 0
cpi r24, 0
breq end_convert
ldi r29, 2
mov r30, r24
convert:
mul r31, r29
mov 31, r0
dec r30
cpi r30, 0
brne convert
end_convert:
com r31 ; inverting mask
; setting correct DDRC using mask
in r30, DDRC
and r30, r31
out DDRC, r30
; first two bits are for the ref voltage
; 01 means AVcc with ext capacitor at aref
; last three bits are for the analog port number
ldi r30, 0b11000000
or r30, r24
sts ADMUX, r30
ldi r30, 0b11000111
sts ADCSRA, r30
wait_adc:
lds r30, ADCSRA
ldi r31, 0b01000000
and r31, r30
cpi r31, 0
brne wait_adc
lds r24, ADCL
lds r25, ADCH
; clearing unused bits ot be sure they're zero
ldi r31, 0b00000011
and r25, r31
sei ; allow interruptions
clr r1 ; c requirement
pop r29 ; c requirement to preserve this register
ret
delay_n_ms:
; delay for ~r20 * 1ms. r20, r30, and r31 are modified.
; 1 ms ~ 16000 cycles at 16MHz.
; The basic loop takes about 5 cycles, so we need about 3000 loops.
ldi r31, 3000 >> 8 ; high byte of the 3000
ldi r30, 3000 & 255 ; low byte of the 3000
delaylp:
sbiw r30, 1 ; sub word r30 1
brne delaylp ; jne delaylp
subi r20, 1
brne delay_n_ms
ret