
;*******************************
;;LED FX.asm
;  11-3-2010 
;*******************************


	list	p=12F629
	radix	dec
	include	"p12f629.inc"
	
		errorlevel	-302	; Dont complain about BANK 1 Registers during assembly

	__CONFIG	_MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  ;Internal osc.

;_MCLRE_OFF  - master clear must be off for gp3 to work as input pin 

;****************************************************************
; variables - names and files
;****************************************************************


temp1		equ 20h	;
temp2		equ 21h	;
temp3		equ 22h	;
temp4		equ	23h	; 
jump		equ	24h	;jump value for table1
fadeUp		equ	25h
fadeDwn		equ	26h
sequences	equ	27h
sw_duration	equ 28h
testing		equ 29h




;****************************************************************
;Equates
;****************************************************************
status		equ	0x03
rp1			equ	0x06
rp0			equ	0x05
GPIO 		equ 0x05
			

status		equ	03h
option_reg	equ 81h


		; bits on GPIO
				
pin7		equ	0	;GP0  LED C
pin6	 	equ	1	;GP1  LED B
pin5		equ	2	;GP2  LED A
pin4		equ	3	;GP3  Sw A  
pin3		equ	4	;GP4  Sw B
pin2		equ	5	;GP5  Sw C   
 

		;bits
				
rp0			equ	5			;bit 5 of the status register



;****************************************************************
;Beginning of program
;****************************************************************
		org		0x00
		nop
		nop
		nop
		nop
		nop			
SetUp	bsf		status, rp0 	;Bank 1			
       	movlw	b'11111000'		;Set TRIS  GP0,1,2 out   GP3,4,5 input
		movwf	TRISIO	   	    ;		
		bcf		status, rp0		;bank 0
		movlw   07h         	;turn off Comparator ports
        movwf   CMCON       	;must be placed in bank 0  
		clrf 	GPIO       		;Clear GPIO of junk	
		call	_memory
		btfss	gpio,5			;SwA to: "record new sequence"		
		goto	record			
		btfsc	gpio,3		;SwC removes attract sequence
		goto	$+.10		
		movlw	0FFh
		bsf		status,rp0	;select bank1	
		movwf	EEDATA						
		bcf		status,rp0	;select bank0	
		movlw	.101
		bsf		status,rp0	;select bank1	
		movwf	EEADR			 
		bcf		status,rp0	;select bank0
		call 	write			
		movlw	.101
		bsf		status,rp0			
		movwf	EEADR									
		bsf		EECON1,0	;starts EEPROM read operation storing result in EEDATA						
		movf	EEDATA,w	;move read data into w
		bcf		status,rp0				
		xorlw	.8			;look for 8 - for Attract mode
		btfsc	03,2
		goto	Attract_Seq	;selected sequence will appear first	
		goto 	Main	
		
		
				

;****************************************************************
;* Tables 			*
;****************************************************************

table1	addwf   PCL,F           ;02h,1  add W to program counter
		retlw   .10     ;
		retlw   .50 
        retlw   .30     ;
		retlw   .50       
		retlw   .100     ;
		retlw   .40		;	program starts at bottom of table
		retlw   .10     ;
		retlw   .50 
        retlw   .30     ;
		retlw   .50       
		retlw   .60     ;
		retlw   .10     ;
		retlw   .50 
        retlw   .10     ;
		retlw   .50       
		retlw   .100     ;
		retlw   .20     ;
		retlw   .50 
        retlw   .30     ;
		retlw   .50       
		retlw   .70 
		retlw   .60     ;
		retlw   .100     ;
		retlw   .50 
        retlw   .100     ;
		retlw   .50       
		retlw   .100     ;
		retlw   .70     ;
		retlw   .50 
        retlw   .30     ;
		retlw   .50       
		retlw   .70     ;
		
table2	addwf   PCL,F           ;02h,1  add W to program counter
		goto	seq1   
		goto	seq2   
		goto	seq3   
		goto	seq4   
		goto	seq5   
		goto	seq6   
		goto	seq7   
		goto	seq8   
		goto	seq9   
		goto	seq10 
		goto	seq11     
		goto	seq12		

;****************************************************************
;* Delays 			*
;****************************************************************


_xuS	movwf	temp2
_uS		movlw	.10
		movwf	temp1
		decfsz	temp1,f
		goto	$-1				
		decfsz 	temp2,f
		goto 	_uS		
		retlw 	00
		
_ZuS	movwf	temp2
		goto	$+2
		goto	$+2		
		decfsz 	temp2,f
		goto 	$-3		
		retlw 	00		


_xmS	movwf	temp2
_x		nop
		decfsz 	temp1,f
		goto 	_x
		decfsz 	temp2,f
		goto 	_x	
		retlw 	00
		
		;5mS delay for increments in timing for "New Sequence" 
		
_5mS	movlw	05h
		movwf	temp2
_5		nop
		decfsz 	temp1,f
		goto 	_5
		decfsz 	temp2,f
		goto 	_5	
		retlw 	00	
		
		
_10mS	movlw	0Ah
		movwf	temp2
_10		nop
		decfsz 	temp1,f
		goto 	_10
		decfsz 	temp2,f
		goto 	_10	
		retlw 	00		
		

_50mS	movlw	.50
		movwf	temp2
_50		nop
		decfsz 	temp1,f
		goto 	_50
		decfsz 	temp2,f
		goto 	_50	
		retlw 	00
		
_100mS	movlw	.100
		movwf	temp2
_100	nop
		decfsz 	temp1,f
		goto 	_100
		decfsz 	temp2,f
		goto 	_100	
		retlw 	00	
		
		
_150mS	movlw	.150
		movwf	temp2
_150	nop
		decfsz 	temp1,f
		goto 	_150
		decfsz 	temp2,f
		goto 	_150	
		retlw 	00			
				


;****************************************************************
;* Sub Routines 			*
;****************************************************************
			
_memory			
			
		movlw	.48
		movwf	temp1
		movlw	2Fh
		movwf	fsr
		incf	fsr,f
		movlw	0FFh
		movwf	indf
		decfsz	temp1,f
		goto	$-4
		retlw	00
		
		   ;SwB puts current sequence into EEPROM for turn on. 
		   ;and puts "marker" in location 101
		   
Attract	
		movf	sequences,w	;put sequence number into w	
		bsf		status,rp0	;select bank1	
		movwf	EEDATA						
		bcf		status,rp0	;select bank0	
		movlw	.100
		bsf		status,rp0	;select bank1	
		movwf	EEADR			 
		bcf		status,rp0	;select bank0
		call 	write
		movlw	.8	
		bsf		status,rp0	;select bank1	
		movwf	EEDATA				
		incf	EEADR,1			 
		bcf		status,rp0	;select bank0
		call 	write		
		nop
		goto	$-1   ;Project must be turned off
		
		
		;Seq selected as Attract will be displayed when project turned on			
		
Attract_Seq	
		movlw	.100
		bsf		status,rp0			
		movwf	EEADR									
		bsf		EECON1,0	;starts EEPROM read operation. Result in EEDATA						
		movf	EEDATA,w	;move read data into w
		bcf		status,rp0
		movwf	temp4
		movf	temp4,w				
		call	table2		
		goto	$-2		


		;record new sequence - looks for "no switch pressed" for 1.25 seconds to exit
		;uses files 30h to 5Fh  (48 files)
		;three files per "step"   1st file = LEDs,  2nd = Off time, 3rd = on time
		;15 steps allowed - look for 5Dh 
		
record	btfss	gpio,5		;wait for release of button A
		goto	$-1
		movlw	30h
		movwf	fsr			;start storage at file 30h
		
			;look at keys being pressed - identifies 2 or 3 keys pressed together
			
_r1		clrf	sw_duration
_r1a	call	_5mS
		incfsz	sw_duration,1		;5mS x 256 = 1.25seconds
		goto	$+2
		goto	Store		;time out! store files 30h to 5Fh in EEPROM		
		btfss	gpio,5		;see if one or more Sw is pressed
		goto	$+5
		btfss	gpio,4
		goto	$+3
		btfsc	gpio,3
		goto	_r1a		;no sw pressed create 2.5 sec timing
							;1,2,or 3 sw pressed
		
		call	_10mS		;delay to detect 2 or 3 switches
		incfsz	sw_duration,1
		goto	$+2
		goto	Main		
		btfsc	gpio,5		;SwA
		goto	$+2
		bsf		gpio,0		;turn on LED A		
		btfsc	gpio,4		;SwB
		goto	$+2
		bsf		gpio,1		;turn on LED B		
		btfsc	gpio,3		;SwC
		goto	$+2			;
		bsf		gpio,2		;turn on LED C
							;LEDs have been illuminated							
		movf	gpio,w		
		movwf	indf			;w moved to fsr's file (30h+)					
		incf	fsr,f			
		movf	sw_duration,w	;off time!!
		movwf	indf			;w moved to fsr's file (30h+)				
		incf	fsr,f		
		clrf	sw_duration							
_r2		call	_5mS
		incfsz	sw_duration,1					
		goto	$+2
		goto	record		;time out! keys pressed too long. Start again	
		btfss	gpio,5
		goto	_r2			;sw pressed
		btfss	gpio,4
		goto	_r2			;sw pressed
		btfss	gpio,3
		goto	_r2			;sw pressed			
							;file empty. Put duration into file
		movf	sw_duration,w	;on time				
		movwf	indf			;w moved to fsr's file (30h+)					
		incf	fsr,f			
		movlw	5Dh
		xorwf	fsr,w
		btfss	03,2				
		goto	$+2
		goto	Store		;stop at 15 steps. store files 30h to 5Fh in EEPROM				
		clrf	gpio		
		goto	_r1				
			
			;sequences:
			
			;seq1 Self-Programmed sequence 
			;1St file:LEDs  2nd file:OFF time  3rd file:On time
			
seq1	bsf		status,rp0			
		clrf	EEADR		
		bcf		status,rp0		
		bsf		status,rp0					
		bsf		EECON1,0	;starts EEPROM read operation. Result in EEDATA						
		movf	EEDATA,w	;move read data into w
		bcf		status,rp0				
		movwf	gpio
		bsf		status,rp0
		incf	EEADR,1						
		bsf		EECON1,0	;						
		movf	EEDATA,w	;move read data into w
		bcf		status,rp0		
		movwf	temp4	;this is OFF time. Store it
		bsf		status,rp0
		incf	EEADR,1						
		bsf		EECON1,0	;						
		movf	EEDATA,w	;move read data into w
		bcf		status,rp0		
		movwf	sw_duration ;this is ON time
		call	_5mS
		decfsz	sw_duration,1
		goto	$-2
		clrf	gpio
		call	_5mS
		decfsz	temp4,f	;create OFF duration
		goto	$-2		
		bsf		status,rp0
		incf	EEADR,1						
		bsf		EECON1,0	;						
		movf	EEDATA,w	;move read data into w
		bcf		status,rp0			
		xorlw	0FFh	;look for 0FFh - end of routine
		btfss	03,2
		goto	$-31
		retlw	00
			
			
			;seq2  chase right - very fast

				
seq2	bsf		gpio,0
		call	_100mS
		bcf		gpio,0
		bsf		gpio,1
		call	_100mS
		bcf		gpio,1
		bsf		gpio,2
		call	_100mS
		bcf		gpio,2
		call	_100mS
		clrf	gpio
		retlw	00
		
		;seq3  chase right 
		
		
seq3	bsf		gpio,0
		call	_150mS
		bcf		gpio,0
		bsf		gpio,1
		call	_150mS
		bcf		gpio,1
		bsf		gpio,2
		call	_150mS
		bcf		gpio,2
		call	_150mS
		clrf	gpio
		retlw	00	
		
		;seq4  chase right with off-delay at end	
		
		
seq4	bsf		gpio,0
		call	_150mS
		bcf		gpio,0
		bsf		gpio,1
		call	_150mS
		bcf		gpio,1
		bsf		gpio,2
		call	_150mS
		bcf		gpio,2
		call	_150mS		
		retlw	00	
		
		;seq5  left right left right 
		
seq5	bsf		gpio,0
		call	_150mS
		bcf		gpio,0		
		bsf		gpio,2
		call	_150mS
		bcf		gpio,2				
		retlw	00
		
		
		;seq6  middle on   middle off
		
seq6	bsf		gpio,1
		call	_150mS
		bcf		gpio,1	
		call	_150mS			
		clrf	gpio			
		retlw	00
				
		
		;seq7  All on   all off
		
seq7	clrf	gpio
		call	_150mS
		decf	gpio,f
		call	_150mS
		clrf	gpio					
		retlw	00	
		
		
seq8	;seq8  middle on then sides on 	
		
		bsf		gpio,1
		call	_150mS
		bcf		gpio,1
		bsf		gpio,0
		bsf		gpio,2
		call	_150mS
		clrf	gpio					
		retlw	00
		
		;seq9  police flasher  3 times left 3 times right 
		
seq9	bsf		gpio,0
		call	_50mS
		bcf		gpio,0
		call	_50mS
		bsf		gpio,0
		call	_50mS
		bcf		gpio,0
		call	_50mS
		bsf		gpio,0
		call	_50mS
		bcf		gpio,0
		call	_50mS		
		bsf		gpio,2
		call	_50mS
		bcf		gpio,2
		call	_50mS
		bsf		gpio,2
		call	_50mS
		bcf		gpio,2
		call	_50mS
		bsf		gpio,2
		call	_50mS
		bcf		gpio,2
		clrf	gpio
		call	_50mS				
		retlw	00	
		
		;seq10  random flicker
		
seq10	movlw	.32		;start at bottom of table
		movwf	jump
		bsf		gpio,1
		movf	jump,w	;put table jump value into w
		call 	table1
		call	_xmS	
		bcf		gpio,1
		decfsz	jump,f
		goto	$+2
		retlw	00		;top of table found
		movf	jump,w	;put table jump value into w
		call 	table1
		call	_xmS				
		goto	$-11
		
		
		;seq11  slow fade up down
		
seq11	clrf	fadeUp		;
		clrf	fadeDwn
		incf	fadeUp,f	;to create 1 (delay routine does not like 00)	
		bsf		gpio,1
		movf	fadeUp,w
		call	_xuS
		bcf		gpio,1
		movf	fadeDwn,w
		call	_xuS							
		decfsz	fadeDwn,f	;
		goto	$-8
		incf	fadeDwn,f ;to produce 1
		bsf		gpio,1
		movf	fadeUp,w
		call	_xuS
		bcf		gpio,1
		movf	fadeDwn,w
		call	_xuS
		decf	fadeUp,f			
		incfsz	fadeDwn,f		
		goto	$-8			
		clrf	gpio
		retlw	00
		
		
		;seq12  fast fade up down
		
seq12	clrf	fadeUp		;
		clrf	fadeDwn
		incf	fadeUp,f	;to create 1 (delay routine does not like 00)	
		bsf		gpio,1
		movf	fadeUp,w
		call	_ZuS
		bcf		gpio,1
		movf	fadeDwn,w
		call	_ZuS							
		decfsz	fadeDwn,f	;
		goto	$-8
		incf	fadeDwn,f ;to produce 1
		bsf		gpio,1
		movf	fadeUp,w
		call	_ZuS
		bcf		gpio,1
		movf	fadeDwn,w
		call	_ZuS
		decf	fadeUp,f			
		incfsz	fadeDwn,f		
		goto	$-8			
		clrf	gpio
		retlw	00		
		
		
		;Store   Store the 15 steps in EEPROM		
		
Store	bsf		status,rp0	;select bank1	
		clrf	eeadr						
		bcf		status,rp0	;select bank0		
		movlw	.48
		movwf	temp1
		movlw	2Fh
		movwf	fsr
		incf	fsr,f	;fsr starts at file 30h
		movf	indf,w	;retreive data in file 30h
		bsf		status,rp0	;select bank1	
		movwf	eedata		; 
		bcf		status,rp0	;select bank0
		call 	write
		bsf		status,rp0	;select bank1	
		incf	eeadr,1						
		bcf		status,rp0	;select bank0
		decfsz	temp1,f
		goto	$-10
		goto	Main
		
		
		
write	bsf		status,rp0	;select bank1	
		bsf		eecon1,wren	;enable write		
		movlw	55h 		;unlock codes
		movwf	eecon2
		movlw	0aah
		movwf	eecon2
		bsf		eecon1,wr	;write begins
		bcf		status,rp0	;select bank0		
writeA	btfss	pir1,eeif	;wait for write to complete
		goto	writeA
		bcf		pir1,eeif
		bsf		status,rp0	;select bank1
		bcf		eecon1,wren	;disable other writes
		bcf		status,rp0	;select bank0					
		retlw	00			
		
						
;****************************************************************
;* Main 							*
;****************************************************************

Main	clrf	sequences	
		movf	sequences,w
		call	table2
		btfss	gpio,5		;Is swA still pressed?
		goto	$-3			;SwA still pressed		
		movf	sequences,w	;SwA released
		call	table2
		btfss	gpio,4		;SwB puts current sequence at turn-on	
		goto	Attract
		btfsc	gpio,5
		goto	$-5			;SwA not pressed
		incf	sequences,f
		movlw	.12
		xorwf	sequences,w
		btfss	03,2
		goto	$-12
		goto	Main		
	
				
;****************************************************************
;*EEPROM     						*
;****************************************************************
								
		org		2100h			
					
							
		END
		
		