; 2010 (c) Bartosz Chodorowski <chomzee@ethernet.pl>
;                              <166142@student.pwr.wroc.pl>
;
; Lista 3, Zadanie 3
; 27 kwietnia 2010

#include<usb1287def.inc>

.cseg
.org 0x0000
rjmp Start


; timer 1 interrupt
.org 0x0022
rjmp IntCmp1

; timer 0 interrupts
.org 0x002a
rjmp IntCmpA
.org 0x002c
rjmp IntCmpB



; global variables
.def diodes=R16
.def lighten=R17
.def freq=R18
.def tmp=R19
.def tmp2=R20
.def ratio=R21
.def const1=R22
.def const2=R23

Start:
ldi R16, low(RAMEND)
ldi R17, high(RAMEND)
out SPH, R17
out SPL, R16

ldi R16, 0b11100000	;PORTB linie 5 do 7 w trybie wejściowym
in R17, PORTB
or R17, R16
out PORTB, R17

ldi R16, 0b00110000	;PORTE linie 4 i 5 w trybie wejściowym
in R17, PORTE
or R17, R16
out PORTE, R17

ldi R16, 0b11110000	;linie 4-7 portu D w trybie wyjściowym, 
in R17, DDRD
or R17, R16			;zasilanie diod LED
out DDRD, R17

; ------------ set timer 1 ------------
ldi R16, low(0)
ldi R17, high(0)
sts TCNT1H, R17
sts TCNT1L, R16 



ldi R16, 0b00000010
sts TIMSK1, R16 ; interrupt mask


ldi R16, 0b00000000
sts TCCR1A, R16

; set prescaler x64 (start timer)
ldi R16, 0b00001011
sts TCCR1B, R16

ldi R16, low(7812)
ldi R17, high(7812)
sts OCR1AH, R17
sts OCR1AL, R16

; ------------ set timer 0 ------------
ldi R16, 0
out TCNT0, R16

ldi R16, 0b00000110 ; interrupt mask
sts TIMSK0, R16

; set CTC mode
ldi R16, 0b00000010
out TCCR0A, R16

ldi R16, 100 ; compare A value
out OCR0A, R16

; set prescaler (start timer)
ldi R16, 0b00000010
out TCCR0B, R16


; enable interrupts
sei

; load constants
ldi ratio, 50
out OCR0B, ratio
ldi const1, 21
ldi const2, 197


; ------------ end of setting timer ------------

ldi lighten, 0
ldi freq, 1

; ------------ MainLopp begins here ------------
MainLoop:
sbis PINB, 7
call Up
sbis PINE, 5
call Down
call Wait
rjmp MainLoop

; ------------ MainLopp ends here ------------


; ------------ Up/Down begins here ------------
Down:
; jesli przycisk dalej wcisniety, powtarzaj
call Wait
sbis PINE, 5
rjmp Down

dec freq

; freq++ if freq==0
cpi freq, 0
brne Down_1
inc freq
Down_1:

call Update

rjmp MainLoop




Up:
; jesli przycisk dalej wcisniety, powtarzaj
call Wait
sbis PINB, 7
rjmp Up

inc freq

; freq-- if freq==11
cpi freq, 11
brne Up_1
dec freq
Up_1:

call Update

rjmp MainLoop


; ---------------- Update
Update:
clr tmp
inc tmp

cp freq, tmp
breq a1
inc tmp

cp freq, tmp
breq a2
inc tmp

cp freq, tmp
breq a3
inc tmp

cp freq, tmp
breq a4
inc tmp

cp freq, tmp
breq a5
inc tmp

cp freq, tmp
breq a6
inc tmp

cp freq, tmp
breq a7
inc tmp

cp freq, tmp
breq a8
inc tmp

cp freq, tmp
breq a9

rjmp a10


a1:
ldi tmp, high(7813)
ldi tmp2, low(7813)
rjmp ok
a2:
ldi tmp, high(3906)
ldi tmp2, low(3906)
rjmp ok
a3:
ldi tmp, high(2604)
ldi tmp2, low(2604)
rjmp ok
a4:
ldi tmp, high(1953)
ldi tmp2, low(1953)
rjmp ok
a5:
ldi tmp, high(1563)
ldi tmp2, low(1563)
rjmp ok
a6:
ldi tmp, high(1302)
ldi tmp2, low(1302)
rjmp ok
a7:
ldi tmp, high(1116)
ldi tmp2, low(1116)
rjmp ok
a8:
ldi tmp, high(977)
ldi tmp2, low(977)
rjmp ok
a9:
ldi tmp, high(868)
ldi tmp2, low(868)
rjmp ok
a10:
ldi tmp, high(781)
ldi tmp2, low(781)
rjmp ok

ok:

sts OCR1AH, tmp
sts OCR1AL, tmp2

clr tmp
clr tmp2

sts TCNT1H, tmp
sts TCNT1L, tmp2
ret

; ------------ Up/Down ends here ------------


; ------------ None begins here ------------
None:
push R16
in R16, PORTD
andi R16, 0x0F
out PORTD, R16
pop R16
ret
; ------------ None ends here ------------
; ------------ Green begins here ------------
Green:
push R16
in R16, PORTD
andi R16, 0x0F
ori R16, 0x40			;0b0100 0000(górna zielona)
out PORTD, R16
pop R16
ret
; ------------ Green ends here ------------

; ------------ Red begins here ------------
Red:
push R16
in R16, PORTD
andi R16, 0x0F
ori R16, 0x80			;0b1000 0000(górna czerwona)
out PORTD, R16
pop R16
ret

; ------------ Red ends here ------------
; ------------ Wait begins here ------------
Wait:
push R16
ldi R16, 0
WaitLoop:
nop
nop
nop
nop
nop
inc R16
cpi R16, 0
brne WaitLoop
pop R16
ret
; ------------ Wait ends here ------------




; ----------------- Interrupts


IntCmp1:
push R16
in R16, SREG
push R16

com lighten ; swap diode state

; draw new ratio
mul ratio, const1
mov ratio, R0
LoopMod2:
cpi ratio, 100
brlo LoopMod2End
subi ratio, 100
rjmp LoopMod2
LoopMod2End:

add ratio, const2
LoopMod:
cpi ratio, 100
brlo LoopModEnd
subi ratio, 100
rjmp LoopMod

LoopModEnd:

out OCR0B, ratio
; end of drawing a new ratio


pop R16
out SREG, R16
pop R16
reti





IntCmpB:
push R16
in R16, SREG
push R16


sbrs lighten, 0
call Green
sbrc lighten, 0
call None

pop R16
out SREG, R16
pop R16
reti


IntCmpA:
push R16
in R16, SREG
push R16

sbrs lighten, 0
call Red
sbrc lighten, 0
call None

pop R16
out SREG, R16
pop R16
reti
