
;		Filename	ARC1
;********************************************************************
;	Program for PIC based block cutout and reversing module
;	Uses PIC 12C509A. Internal oscillator 
;	Hardware detect of overload. PIC handles the turn on / off
;	of the DCC power via two N channel MOSFETs. Reversing by a
;	relay. Minimal cutoff delay to beat the booster. Power is
;	cut off while the relay reverses, then restored. If there is
;	still an overload, system goes into a 0.5 second retry sequence
;	Relay cycling only re-enabled after there is no longer an overload.
;	Tested and working 23/01/02


	Processor 12C509A

	include		"P12c509a.inc"
	
	__CONFIG	h'000E' ; CP off, WDT on, internal clock

;Definitions




DCCon	equ	0
Ovl_in	equ	1	
Relay	equ	2
Ovl_out	equ	4

;	registers used

	 

	CBLOCK	0x0007

		state		;state sequence
		time0		;counter0
		time1		;counter1
		time2		;counter2
		

	ENDC




	org 	0

;start of program

	movwf	OSCCAL		;set cal

;set ports etc.
	bcf	STATUS,PA0
	movlw	B'10001111'
	option
		
				
				;GP0 DCC ON/OFF (hi is ON)
				;GP1 is overload input (active lo)
				;GP2 Reverse output
				;GP4 overload output (HI is overload)
				
	movlw	B'00000010'
	tris	GPIO
	
				
	movlw	B'00000001'	;set ports
	movwf	GPIO

	clrf 	state

;main loop starts here. Scans for hi on overload. 

test	clrwdt
	btfss	GPIO,Ovl_in	;look for overload
	goto	set1
	
test1	btfsc	state,0		;check state
	goto	caltim		;reset delay

	goto	test		;look again


;here if true overload 

set1	bcf	GPIO,DCCon	;turn off
	btfsc	state,0		;0 if first time after reset
	goto	state1
	bsf	state,0		;set to state 1

	movf	GPIO,W		;get port setting
	xorlw	B'00000100'	;reverse relay
	movwf	GPIO

	call	dely25		;delay 25 millisecs for relay
	bsf	GPIO,DCCon	;turn back on
	goto	test		;look for overload

state1	bsf	GPIO,Ovl_out	;set alarm
	call	del500
	bsf	state,7		;set timeout
	bcf	GPIO,Ovl_out	;alarm off
	bsf	GPIO,DCCon	;output on
	goto	test	

caltim	call	timout		;reset timer
	goto	test
	




;	delays

delay	movlw	0xFF		;short delay
	movwf	time0
delay1	clrwdt
	nop
	nop
	decfsz	time0,F
	goto	delay1
	retlw	0

dely25	clrwdt
	movlw	.30		;25 millisecs
	movwf	time1
del25a	movlw	0xFF
	movwf	time2
del25b	decfsz	time2,F
	goto	del25b
	decfsz	time1,F
	goto	del25a
	retlw	0

del500	movlw	0xFF		;500 millisecs
	movwf	time1
del500a	movlw	0xFF
	movwf	time2
del500b	clrwdt
	nop
	nop
	nop
	nop
	decfsz	time2,F
	goto	del500b
	decfsz	time1,F
	goto	del500a
	retlw	0

timout	btfss	state,7		;continue countdown
	goto	countdn
	movlw	0xFF		;set counters
	movwf	time1
timo2	movlw	0xFF
	movwf	time2 
	bcf	state,7
countdn	decfsz	time2,F
	retlw	0
	decfsz	time1,F
	goto	timo3
	clrf	state		;reset
	retlw	0

timo3	movlw	0xFF
	movwf	time2
	retlw	0

	

	end




