;Jeff Mucha
;pic microcontroler code for exercising multi color LEDs
;Porta bits 0 1 2 3 are inputs where active low switches are attached.
;proper debouncing is required.
;portb is pulse width modulated to provide n levels of output drive to the LEDs
;external clock is devided by 4 to provide internal clock most all instructions take 1 internal cycle

	list	p=16c54
	radix	hex
#define	width 	0x0d ;define the depth of PWM

;--------------------------------------------------;
;equates
;--------------------------------------------------;
pc	equ	0x02
f	equ	0x01
porta	equ	0x05
portb	equ	0x06
count	equ	0x0c	;general purpose counter
status	equ	0x03
countr	equ	0x0d	;counter red
countg  equ	0x0e	;counter green
countb	equ	0x0f	;counter blue

countt	equ	0x1f	;table counter step


pwm1	equ	0x10
pwm2	equ	0x11
pwm3	equ	0x12
pwm4	equ	0x13
pwm5	equ	0x14
pwm6	equ	0x15
pwm7	equ	0x16
pwm8	equ	0x17
pwm9	equ	0x18
pwm10	equ	0x19
pwm11	equ	0x1a
pwm12	equ	0x1b
pwm13	equ	0x1c


;--------------------------------------------------;
;main program
;--------------------------------------------------;
	org	0x000
start	movlw	0x00
	tris	portb
	movlw	0xff
	tris	porta

	movlw	b'00000000'   ;initial values for pwm table
	movwf	pwm1
	movwf	pwm2
	movwf	pwm3
	movwf	pwm4
	movwf	pwm5
	movwf	pwm6
	movwf	pwm7
	movwf	pwm8
	movwf	pwm9
	movwf	pwm10
	movwf	pwm11
	movwf	pwm12

	movlw	width  ; 0x09
	movwf	count
	movwf	countr
	movwf	countg
	movwf	countb
	movlw	0x0c	;color table depth
	movwf	countt
;--------------------------------------------------;
;PWM loop	modulates all three colors
;--------------------------------------------------;
	
loopa	movlw	b'00001111'			;port a bits 0,1,2,3 set high means no buttons pushed	
	subwf	porta,w			;compare w to port a using the subtract and then z flag check
	btfss	status,2
	goto	select


	movf	pwm12,w			
	movwf	portb
	movf	pwm11,w
	movwf	portb
	movf	pwm10,w
	movwf	portb
	movf	pwm9,w
	movwf	portb

	movf	pwm8,w
	movwf	portb	
	movf	pwm7,w
	movwf	portb
	movf	pwm6,w
	movwf	portb
	movf	pwm5,w
	movwf	portb
	movf	pwm4,w
	movwf	portb
	movf	pwm3,w
	movwf	portb
	movf	pwm2,w
	movwf	portb
	movf	pwm1,w
	movwf	portb

	goto	loopa	

;--------------------------------------------------;
;determines which button is pressed
;--------------------------------------------------;

select	btfss	porta,0	
	call	setr
	btfss	porta,1	
	call	setg
	btfss	porta,2	
	call	setb
	btfss	porta,3
	call	seti		;calls the color incriment routine
;	btfss	porta,4
	goto	loopa
;	movlw	b'00000111'
;	movwf	portb
;	goto	select


;--------------------------------------------------;
;indirectly addressed red routine
;--------------------------------------------------;

setr	decfsz	countr
	goto	setr2
	goto	resetr
	
;	movwf	countr

setr2	movlw	0x0F		;this sets the bit for the value of the counter
	addwf	countr,w
	movwf	0x04
	bsf	0x00,0		;sets the red bit

testrl	btfss	porta,0		
	goto	testrl
	return

resetr	movlw	width	;0x09
	movwf	count

rloopr	movlw	0x0F		
	addwf	count,w
	movwf	0x04
	bcf	0x00,0		;clears red bit

	decfsz	count
	goto	rloopr
	movlw	width    ; 0x09
	movwf	countr
	goto	testrl



;--------------------------------------------------;
;indirectly addressed green routine
;--------------------------------------------------;


setg	decfsz	countg
	goto	setg2
	goto	resetg
	

setg2	movlw	0x0F		
	addwf	countg,w
	movwf	0x04
	bsf	0x00,1		;set the green bit

testgl	btfss	porta,1		
	goto	testgl
	return


resetg	movlw	width	;0x09
	movwf	count

rloopg	movlw	0x0F		
	addwf	count,w
	movwf	0x04
	bcf	0x00,1		;clear the green bit

	decfsz	count
	goto	rloopg
	movlw	width    ; 0x09
	movwf	countg
	goto	testgl



;--------------------------------------------------;
;indirectly addressed blue routine
;--------------------------------------------------;

setb	decfsz	countb
	goto	setb2
	goto	resetb
	


setb2	movlw	0x0F		
	addwf	countb,w
	movwf	0x04
	bsf	0x00,2		;set the blue bit

testbl	btfss	porta,2		
	goto	testbl
	return


resetb	movlw	width	;0x09
	movwf	count

rloopb	movlw	0x0F		
	addwf	count,w
	movwf	0x04
	bcf	0x00,2		;clear the blue bit

	decfsz	count
	goto	rloopb
	movlw	width    ; 0x09
	movwf	countb
	goto	testbl


;--------------------------------------------------;
;indirectly addressed color routine
;--------------------------------------------------;
; this part sets the counter to the width of the 
; pwm table and clears all the bits for all colors

seti   	movlw	width	
	movwf	count

rloopi	movlw	0x0F		
	addwf	count,w
	movwf	0x04

	bcf	0x00,0		;clears red bit
	bcf	0x00,1		;clears green bit
	bcf	0x00,2		;clears blue bit

	decfsz	count
	goto	rloopi
	
;	
	movfw	countt		;start counter at 0x07
	call	redtbl		;will return the value for the countt loop the number of times to decrement the red counter and call the red routine
	movwf	countr
looptr	decfsz	countr		
	goto	jumpir
	goto	nextr
	
jumpir	call	setr2
	goto	looptr

;
nextr	movfw	countt	
	call	grntbl		
	movwf	countg

looptg	decfsz	countg		;will decrement setr counter
	goto	jumpig
	goto	nextg

jumpig	call	setg2
	goto	looptg


;
nextg	movfw	countt	
	call	bluetbl		
	movwf	countb

looptb	decfsz	countb		;will decrement setr counter
	goto	jumpib
	goto	finish

jumpib	call	setb2
	goto	looptb

finish	movlw	0x01		;set these counters to 1 so that
	movwf	countr		;when a color button is pressed
	movwf	countg		;it does not reset countx to 255
	movwf	countb

	decfsz	countt		;look at inc counter
	goto	testil		;if it is 0 reset inc counter and go back
	
	movlw	0x08		;resets the increment counter
	movwf	countt

testil	btfss	porta,3
	goto	restl
	return

restl	movlw	b'00000000'
	movwf	portb	
	goto	testil

	
redtbl	addwf	pc,f  	;red lookup table
	nop
	retlw	0x0d	;orange
	retlw	0x06	;white
	retlw	0x0d	;red
	retlw	0x04	;purple
	retlw	0x01	;green2
	retlw	0x01	;green
	retlw	0x03	;pink2
	retlw	0x0d	;pink
	retlw	0x01	;blue2
	retlw	0x01	;blue
	retlw	0x02	;yellow2
	retlw	0x0a	;yellow

grntbl	addwf	pc,f	;green lookup table
	nop
	retlw	0x05	;orange
	retlw	0x0d	;white
	retlw	0x01	;red
	retlw	0x01	;purple
	retlw	0x04	;green2
	retlw	0x0d	;green
	retlw	0x03	;pink2
	retlw	0x02	;pink
	retlw	0x02	;blue2
	retlw	0x08	;blue
	retlw	0x03	;yellow2
	retlw	0x0d	;yellow
		

bluetbl	addwf	pc,f	;blue lookup table
	nop
	retlw	0x01	;orange
	retlw	0x0a	;white
	retlw	0x01	;red
	retlw	0x0d	;purple
	retlw	0x01	;green2	
	retlw	0x01	;green
	retlw	0x02	;pink2
	retlw	0x0b	;pink
	retlw	0x04	;blue2
	retlw	0x0d	;blue
	retlw	0x01	;yellow2		
	retlw	0x01	;yellow	

	end
