;-------------------------------------------------------------------
;	PROGRAM NAME & REVISION INFORMATION
;
;-------------------------------------------------------------------
;	WHEELCHAIR SPEED CONTROLLER
;
;	VERSION 5.0
;
;	DESIGNED BY E BROUWER
;
;	DATE: NOVEMBER 2016

;-------------------------------------------------------------------
;	DESCRIPTION
;
;	PREVENTS INCORRECT SELECTION OF FORWARD/REVERSE 
;	WILL BLOCK H-BRIDGE IF INPUTS ARE INVALID
;
;	TEMPERATURE MEASURED USING LM35
;	COOLING FAN CONTROLLED BY TEMPERATURE
;	H-BRIDGE WILL SWITCH OFF IF TEMPERATURE EXCEED LIMIT 
;
;-------------------------------------------------------------------
;	PIN ASSIGNMENTS
;
;-------------------------------------------------------------------
;	PIN	INPUT/OUTPUT	USED FOR
;	GP0	OUTPUT		FWD_OUT
;	GP1	OUTPUT		REV_OUT
;	GP2	OUTPUT		FAN_OUT
;	GP3	INPUT		REV_IN
;	GP4	INPUT		TEMP_IN
;	GP5	INPUT		FWD_IN
;
;-------------------------------------------------------------------
;	COMPILER SETTINGS
;
;-------------------------------------------------------------------
 	LIST    F=INHX8M, P=12F675, R=HEX
 	#include <p12F675.inc>  

	;CONFIGRATION BITS
	;-----------------
	__CONFIG _CPD_OFF & _CP_ON & _BODEN_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_ON & _INTRC_OSC_NOCLKOUT

;-------------------------------------------------------------------
;	VARIABLES/LABELS DECLARATIONS
;
;-------------------------------------------------------------------
	CBLOCK H'20'		;DEFINE RAM LOCATION
		LM35L		;LM35 TEMPERATURE LOW BYTE
		LM35H		;LM35 TEMPERATURE HIGH BYYR
		FLAGS		;FLAGS
		DLY		;DELAY COUNTER
		TEMP		;TEMP 
	ENDC
;DEFINE TEMPERATURE SETTINGS
;---------------------------
#DEFINE	FAN_OFF	.80		;40 DEGREES C
#DEFINE	FAN_ON	.102		;50 DEGREES C
#DEFINE	TEMP_RST	.81		;40 DEGREES C
#DEFINE 	TEMP_TRIP	.163		;80 DEGREES C


;DEFINE I/O PINS
;---------------
#DEFINE	FWD_IN	GPIO,5		;
#DEFINE	REV_IN	GPIO,3		;
#DEFINE	TEMP_IN	GPIO,4		;
#DEFINE	FWD_OUT	GPIO,0		;
#DEFINE	REV_OUT	GPIO,1		;
#DEFINE	FAN_OUT	GPIO,2		;

;DEFIEN FLAGS
;------------
#DEFINE	IN_FWD	FLAGS,0		;COPY OF FWD INPUT	
#DEFINE	IN_REV	FLAGS,1		;COPY OF REV INPUT
#DEFINE	FWD_FLAG	FLAGS,2		;FORWARD COMMAND
#DEFINE	REV_FLAG	FLAGS,3		;REVERSE COMMAND
#DEFINE	FWD_OLD	FLAGS,4		;PREVIOUS FORWARD COMMAND
#DEFINE	REV_OLD	FLAGS,5		;PREVIOUS REVERSE COMMAND
#DEFINE	ESC_OFF	FLAGS,6		;ESC OVER-TEMPERATURE FLAG


;-------------------------------------------------------------------
;	START-UP OF PIC
;
;-------------------------------------------------------------------
	ORG	0 		;RESET VECTOR
	GOTO	START		;	/
	ORG	4		;INTERRUPT VECTOR
	GOTO	ISR		;	/
	
;-------------------------------------------------------------------
;	SET-UP OF REGISTERS AND INTERRUPTS
;
;-------------------------------------------------------------------
START	CALL	H'3FF'		;LOAD CALIBRATION DATA
	BSF	STATUS,RP0	;SET BANK 1
	MOVWF	OSCCAL		;SET CALIRATION
	BCF	STATUS,RP0	;SET BANK 0

;REMOVE BELOW - USED FOR CODE TESTING
;------------------------------------
		
;------------------------------------
;REMOVE ABOVE - USED FOR CODE TESTING
;------------------------------------

	;SETUP OF REGISTERS
	;------------------
	CLRF	GPIO		;CLEAR PORTS
	CLRF	FLAGS		;CLEAR FLAGS
	MOVLW	B'111'		;SET COMPARATOR TO OFF
	MOVWF	CMCON		;	/
	BSF	STATUS,RP0	;SET BANK 1
	MOVLW	B'01101000' 	;SETUP A/D PINS
	MOVWF	ANSEL		
	MOVLW	B'000000'		;ENABLE WEAK PULL-UPS
	MOVWF	WPU		;	/
	MOVLW	B'111000'		;SETUP IO DIRECTION
	MOVWF	TRISIO		;	/
	MOVLW	B'10001111'	;B'00101010'LOAD OPTION REGISTER
				;BIT 7 - 0 = WEAK PULL-UPS ENABLED
				;BIT 6 - 0 = INTERRUPT ON RISING EDGE OF GP2
				;BIT 5 - 1 = TMR0 CLOCK SET TO GP2 PIN
				;BIT 4 - 1 = TMR0 INC ON HIGH TO LOW 
				;BIT 3 - 1 = PRESCALER ASSIGNED TO WDT
				;BIT 2..1  = PRESCALER SET TO 1:256
	MOVWF	OPTION_REG	;	/
	BCF	STATUS,RP0	;SET BANK 0
	;READ A/D CONVERTER
	;------------------
	CALL	READ_A2D
	;POWER ON DELAY
	;--------------
;	BSF	FAN_OUT
	CALL	DLY_500		;WAIT FOR SIGNALS TO STABALISE
	CALL	DLY_500		;WAIT FOR SIGNALS TO STABALISE
;	BCF	FAN_OUT

;------------------------------------------------------------------------
;`	MAIN PROGRAAM LOOP
;
;------------------------------------------------------------------------
WAIT	CLRWDT			;RESET WATCHDOG TIMER

	;READ A/D CONVERTER
	;------------------
	CALL	READ_A2D

	;READ FORWARD/REVERSE INPUTS
	;---------------------------
	BTFSS	FWD_IN		;IS FWD_IN LOW?
	BCF	IN_FWD		;YES, CLEAR IN_FWD
;	BCF	FWD_OUT		;YES, CLEAR IN_FWD
	BTFSC	FWD_IN		;IS FWD_IN HIGH?
	BSF	IN_FWD		;YES, SET IN_FWD
;	BSF	FWD_OUT		;YES, SET IN_FWD

	BTFSS	REV_IN		;IS REV_IN LOW?
	BCF	IN_REV		;YES, CLEAR IN_REV
;	BCF	REV_OUT		;YES, CLEAR IN_REV
	BTFSC	REV_IN		;IS REV_IN HIGH?
	BSF	IN_REV		;YES, SET IN_REV
;	BSF	REV_OUT		;YES, SET IN_REV

;	GOTO	WAIT

	;PREVENT SWITCHING BETWEEN FORWARD/REVERSE WITHOUT FIRST STOP
	;------------------------------------------------------------
	

	;CHECK IF FWD = 0 AND REV = 0
	;----------------------------
	BTFSC	IN_FWD		;IS FWD LOW?
	GOTO	CHK01		;NO
	BTFSC	IN_REV		;IS REV LOW?
	GOTO	CHK01		;NO
	;HERE, FWD = 0 AND REV = 0
	;-------------------------
	BCF	FWD_FLAG		;SET STATUS FLAG
	BCF	REV_FLAG		;SET STATUS FLAG
	BCF	FWD_OLD
	BCF	REV_OLD

	;CHECK IF FWD = 1 AND REV = 0
	;----------------------------
CHK01	BTFSS	IN_FWD		;IS FWD HIGH?
	GOTO	CHK02		;NO
	BTFSC	IN_REV		;IS REV LOW?	/
	GOTO	CHK02		;NO
	;HERE, FWD = 1 AND REV = 0
	;WAS PREVIOUS STATE REVERSE?
	;---------------------------
	BTFSC	REV_OLD		;PREVIOUS STATE REVERSE?
	GOTO	CHK02		;YES
	;SAFE TO SELECT FORWARD
	;----------------------
	BSF	FWD_FLAG		;SET STATUS FLAG
	BCF	REV_FLAG		;SET STATUS FLAG

	;CHECK IF FWD = 0 AND REV = 1
	;----------------------------
CHK02	BTFSC	IN_FWD		;IS FWD LOW?
	GOTO	CHK03		;NO
	BTFSS	IN_REV		;IS REV HIGH?
	GOTO	CHK03		;NO
	;HERE, FWD = 0 AND REV = 1
	;-------------------------
	;WAS PREVIOUS STATE FORWARD?
	;---------------------------
	BTFSC	FWD_OLD		;PREVIOUS STATE FORWARD?
	GOTO	CHK03		;YES
	;SAFE TO SELECT REVERSE
	;----------------------
	BCF	FWD_FLAG		;SET STATUS FLAG
	BSF	REV_FLAG		;SET STATUS FLAG
	BSF	FWD_OLD
	BSF	REV_OLD


	;CHECK IF FWD = 1 AND REV = 1
	;----------------------------
CHK03	BTFSS	IN_FWD		;IS FWD HIGH?
	GOTO	CHK04		;NO
	BTFSS	IN_REV		;IS REV HIGH?
	GOTO	CHK04		;NO
	;HERE, FWD = 1 AND REV = 1
	;-------------------------
	BCF	FWD_FLAG		;SET STATUS FLAG
	BCF	REV_FLAG		;SET STATUS FLAG


	;CHECK TEMERATURE
	;IF < 40C, FAN OFF		
	;---------------------------------
CHK04	MOVLW	FAN_OFF
	SUBWF	LM35L,0	
	BTFSC	STATUS,C
	GOTO	CHK05
	BCF	FAN_OUT		;TURN OFF FAN

	;CHECK TEMERATURE
	;IF > 50C, FAN ON		
	;---------------------------------
CHK05	MOVF	LM35L,0
	SUBLW	FAN_ON	
	BTFSC	STATUS,C
	GOTO	CHK06
	BSF	FAN_OUT		;TURN ON FAN

	;CHECK TEMERATURE
	;IF < 50C, ESC ON		
	;---------------------------------
CHK06	MOVLW	TEMP_RST
	SUBWF	LM35L,0	
	BTFSC	STATUS,C
	GOTO	CHK07
	BCF	ESC_OFF		;ENABLE ECS

	;CHECK TEMERATURE
	;IF > 80C, ESC OFF		
	;---------------------------------
CHK07	MOVF	LM35L,0
	SUBLW	TEMP_TRIP	
	BTFSC	STATUS,C
	GOTO	CHK08
	BSF	ESC_OFF		;TURN OFF ESC
	BSF	FWD_OLD
	BSF	REV_OLD

	;SET FORWARD/REVERSE OUTPUTS
	;---------------------------

	;DISABLE FORWARD/REVERSE OUTPUTS IF TEMPERATURE > 80C  (ESC_OFF FLAG SET)
	;------------------------------------------------------------------------
CHK08	BTFSS	ESC_OFF		;IS TEMP > 80C?
	GOTO	CHK09		;NO
	;OVER TEMPERATURE CONDITION. DISABLE H-BRIDGE BY TURNING OFF
	;FWD AND REV OUTPUTS
	;------------------------------------------------------------
	BCF	FWD_FLAG		;DISABLE FORWARD
	BCF	REV_FLAG		;DISWABLE REVERSE
	BCF	FWD_OUT		;FWD_OUT OFF
	BCF	REV_OUT		;REV_OUT OFF
	GOTO	DONE		;DONE

	;IF TEMPERATURE OK, SWITCH FORWARD/REVERSE SIGNALS AS PER INPUTS
	;---------------------------------------------------------------
CHK09	BTFSS	FWD_FLAG		;FORWARD SELECTED?
	GOTO	CHK10		;NO
	BTFSC	REV_FLAG		;REVERSE NOT SELECTED?
	GOTO	CHK10		;NO
	;TURN ON FORWARD OUTPUT
	;----------------------
	BCF	REV_OUT		;YES, ENABLE FORWARD
	BSF	FWD_OUT		;	/
	BSF	FWD_OLD		;	/
	GOTO	DONE		;DONE

CHK10	BTFSS	REV_FLAG		;REVERSE SELECTED?
	GOTO	CHK11		;NO
	BTFSC	FWD_FLAG		;FORWARD NOT SELECTED?
	GOTO	CHK11		;NO
	;TURN ON REVERSE OUTPUT
	;-----------------------
	BCF	FWD_OUT		;YES, ENABLE REVERSE
	BSF	REV_OUT		;	/
	BSF	REV_OLD		;	/
	GOTO	DONE		;DONE

	;INVALID SELECTION, TURN OFF OUTPUTS
	;-----------------------------------
CHK11	BCF	FWD_OUT		;DISABLE FORWARD/REVERSE
	BCF	REV_OUT		;	/

	;END OF MAIN LOOP - REPEAT
	;-------------------------
DONE	CALL	DELAY		;SMALL DELAY
	


	GOTO	WAIT



;------------------------------------------------------------------------
;`	READ A/D CONVERTER
;	USE BITS 7..0
;------------------------------------------------------------------------
READ_A2D	MOVLW	B'10001101'
	MOVWF	ADCON0		;SET CHANNEL 1
	CLRF	TMR0
	BTFSS	TMR0,5		;WAIT REQUIRED ACQUISITION TIME
	GOTO	$-1	;	/
	BSF	ADCON0,GO		;START CONVERSION
	BTFSC	ADCON0,GO		;WAIT FOR A/D CONVERSION
	GOTO	$-1
	MOVF	ADRESH,0		;READ A/D HI RESULT
	MOVWF	LM35H		;SAVE IN FILE
	BSF	STATUS,RP0	;BANK1
	MOVF	ADRESL,0		;READ A/D LO RESULT
	MOVWF	LM35L		;SAVE IN FILE
	BCF	STATUS,RP0	;BANK0
	;IF LM35H <> 0, SET LM35L TO 255
	;-------------------------------
	MOVF	LM35H,0
	BTFSC	STATUS,Z
	RETURN
	MOVLW	.255
	MOVWF	LM35L
	RETURN


;------------------------------------------------------------------------
;	INTERRUPT SERVICE ROUTINE
;	
;------------------------------------------------------------------------
ISR	RETFIE			;RETURN & RESET INTERRUPTS

;------------------------------------------------------------------------
;	750us DELAY
;	
;------------------------------------------------------------------------
DELAY	MOVLW	D'106'		;LOAD DELAY VARIABLE
	MOVWF	DLY		;	/
DLY_1	NOP
	NOP
	NOP
	NOP
	DECFSZ	DLY,1		;DECREASE DLY, SKIP IF ZERO
	GOTO	DLY_1		;NOT ZERO,WAIT
	NOP
	NOP
	NOP
	NOP
	RETURN			;RETURN

;------------------------------------------------------------------------
;	0.5s DELAY
;	
;------------------------------------------------------------------------
DLY_500	MOVLW	D'65'		;REPEAT TEMP TIMES
	MOVWF	TEMP		;	/
DLY_51	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	CALL	DELAY		;750us DELAY
	DECFSZ	TEMP,1		;	/
	GOTO	DLY_51
	RETURN

;------------------------------------------------------------------------
;	END OF PROGRAM
;	
;------------------------------------------------------------------------
	END
