;Hearbeat LED
;(C) 2004 Markus Vohburger
;Gewerbliche Nutzung untersagt.
;


;Registerdefinitionen für Tiny12 ladan
.include "tn12def.inc"

.def temp1 = r16
.def temp2 = r17
.def output = r18

;Software-Zähler
.def swcount = r19
.def  output = r20

;Zähler für PWM
.def pwmcount = r21

;Richtung heller oder dunkler
.def direction = r25

;Wert für PWM
.def pwmvalue = r27

;Kalibrierbyte für internen Oszillator ist in EEPROM $3f gespeichert
.equ EE_OSCCAL= $3f;



;reset-Vektor
.org $0000
rjmp main


;Timer 0 Overflow Interrupt Vektor
;timer overflow interrut handler
.org OVF0Addr
rjmp OVF0Handler



;Hauptprogramm beginnt hier
.org $0010
main:

;set internal osc cal
ldi temp1,EE_OSCCAL
rcall readeeprom
out osccal,temp1


;Ports Setup
ldi temp1,$1f
out ddrb,temp1

ldi temp1,$1f
out portb,temp1

clr pwmcount
clr pwmvalue
clr direction

;Timer zurücksetzen
clr temp1
out tcnt0,temp1


;Timer interrupts an
ldi temp1,(1<<toie0)
out timsk,temp1


;Timer starten
ldi temp1,$02
out tccr0,temp1

ldi swcount,0

sei



;hauptschleife, implementiert die PWM

loop:

;leds aus
ldi output,$1f


check_value:
cp pwmvalue,pwmcount
brsh writeoutput
;leds an (PB0 bis PB2)
andi output,$18


writeoutput:
out portb,output
inc pwmcount
rjmp loop





;subroutine zum Lesen aus EEprom
readeeprom:
sbic eecr,eewe
rjmp readeeprom
out eear,temp1
in temp1,eedr
ret


;Timer 0 Interrupthandler

OVF0Handler:
;statusregister sichern
in r1,sreg

;Softwarezähler erhöhen
inc swcount
cpi swcount,$04
brlo exit_ovf0handler
clr swcount


cpi direction,$00
breq dodec


;pwmwert erhöhen
doinc:
inc pwmvalue

cpi pwmvalue,$80
brlo exit_ovf0handler
clr direction
ldi pwmvalue,$80
rjmp exit_ovf0handler



;pwmwert verringern
;das Verringern geschieht doppelt so schnell wie das Erhöhen, um den Effekt zu verbessern
dodec:
dec pwmvalue
dec pwmvalue

cpi pwmvalue,$01
brsh exit_ovf0handler

ldi pwmvalue,$01
ldi direction,$01



;ende der Timer 0 Interrupt Routine
exit_ovf0Handler:
out sreg,r1
reti
