;***** PWM demonstration with RGB LED ****
; Demonstrates how to set the PWM modes of the Timer/Counter1, 1a and 2 of the AT Mega8.
; A  RGB LED @ the PWM output at PORTB.1.2.3 fades on and off.
; Author	: www.avrprojects.net  
; Target	: ATMega8 
; Hardware	: RGB LED at PORTB1:2:3 G:B:R
;*****************************************
.include "M8def.inc"
.def Temp =r16 	; Temporary register
.def pw1 =r20	;
.def pw2 =r21	;
.def pw3 =r22	;

;***** Initialization ********************
INIT_SP:

			ldi   r16,high(RAMEND)   ;Intialize stackpointer 
      		out   SPH,r16 
      		ldi   r16,low(RAMEND) 
      		out   SPL,r16

			ldi temp,0
			out OCR1AL,temp
			out OCR1BL,temp
			out OCR2,temp
		
INIT_PORTB:
			ser	Temp
			out	DDRB,Temp			; Set PORTB to output
			clr temp
			out PORTB,temp			; Set PORTB to 0

INIT_TIMER_1AB:
			ldi	temp, 0b10100001	; Set Timer/Counter1AB, set PWM mode to clear OC1AB at upcounting, set OC1AB at downcounting 
			out	TCCR1A, temp		;
			ldi temp, 0b00000001	; Start Timer/Counter1AB 
			out TCCR1B, temp

INIT_TIMER_2:
			ldi temp, 0b01100001	; Start Timer/Counter2 , set PWM mode to clear OCR2 at upcounting
			out TCCR2, temp

;******* this is the main loop 
 
LOOP:		rcall	UP1				; call UP1 subroutine
			rcall	DN1
			rcall	UP2
			rcall	DN2
			rcall	UP3
			rcall	DN3
			rjmp 	LOOP

;******* subroutines

UP1:		inc pw1					; Increase the pulse width
			out OCR1AL,pw1			; Output to CompareRegister1A which will set the puls width
			rcall delay				; Delay of 0.01s
			cpi pw1,255				; Check if pulse width is max
			brne UP1
			ret

DN1:		dec pw1
			out OCR1AL,pw1
			rcall delay
			cpi pw1,0
			brne DN1
			ret

UP2:		inc pw2					; Increase the pulse width
			out OCR1BL,pw2			; Output to CompareRegister1B which will set the puls width
			rcall delay				; Delay of 0.01s
			cpi pw2,255				; Check if pulse width is max
			brne UP2
			ret

DN2:		dec pw2
			out OCR1BL,pw2
			rcall delay
			cpi pw2,0
			brne DN2
			ret

UP3:		inc	 pw3				; Increase the pulse width
			out OCR2,pw3			; Output to CompareRegister2 which will set the puls width
			rcall delay				; Delay of 0.01s
			cpi pw3,255				; Check if pulse width is max
			brne UP3
			ret
						
DN3:		dec pw3
			out OCR2,pw3
			rcall delay
			cpi pw3,0
			brne DN3
			ret




DELAY:								; delay of 0.01s @ 4Mhz
; ============================= 
;    delay loop generator 
          ldi  R17, $43
WGLOOP0:  ldi  R18, $C6
WGLOOP1:  dec  R18
          brne WGLOOP1
          dec  R17
          brne WGLOOP0
; ----------------------------- 
; delaying 1 cycle:
          nop
; =============================
			ret


