;******************************************************************************
;
;	Telescope Battery Monitor System
;
;	The PIC 16F88 pin layout:
;	
;
;	RA0	LCD Data
;	RA1	LCD Data
;	RA2 	LCD Data
;	RA3	LCD Data
;	RA4 	AD for Battery Voltage
;	RA5	
;	RA6	LCD RS
;	RA7	LCD EN	
;
;	RB0 	Switch input for Display Dimming - low when pressed	
;	RB1	
;	RB2	
;	RB3	PWM for Display Backlight
;	RB4	
;	RB5 
;	RB6 	AD for Plug 1 current	
;	RB7 	AD for Plug 2 current
;			
;******************************************************************************
;                                                                     
;    Filename:	    telescope.asm                                        
;    Date: 			1 July 2004                                 
;    File Version:  1.0                                               
;                                                                  
;    Author: 		A.Round                                        
;    Company: 		Round Innovations                           
;                                                              
;                                                              
;******************************************************************************
;                                                                   
;    Files required:	"m_lcd.h"
;                                                                     
;******************************************************************************
;                                                                  
;    Notes:	Version 1.0 - Initial Baseline                           
;                                   
;                                                                    
;                                                                    
;*****************************************************************************

	list      p=16f88           ; list directive to define processor
	#include <p16F88.inc>       ; processor specific variable definitions

	__CONFIG    _CONFIG1, _CP_OFF & _CCP1_RB3 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_OFF & _MCLR_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_IO
	__CONFIG    _CONFIG2, _IESO_OFF & _FCMEN_OFF

; '__CONFIG' directive is used to embed configuration word within .asm file.
; The lables following the directive are located in the respective .inc file.
; See data sheet for additional information on configuration word settings.

;***** LCD HARDWARE DECLARATION *****

LCD_CONTROL			EQU     PORTA
LCD_CONTROL_TRIS	EQU     TRISA

#define R_S	LCD_CONTROL,6  			; LCD Register Select control line RA6
#define EN	LCD_CONTROL,7  			; LCD Enable control line RA7

LCD_DATA		EQU     PORTA		; LCD data byte using PortA
LCD_DATA_TRIS	EQU     TRISA

;***** VARIABLE DECLARATION *****

	CBLOCK	0X20

TEST								; Used in Keyboard debounce routine
TEMP1								; Used in LCD subroutines
TEMP2								; Used in LCD_Hex subroutine
CNTR								; Used in LCD Screen subroutines
DELAY1								; Used in Delay macros
DELAY2								; Used in Delay macros
HALF_SEC_COUNT						; Used for Timer1 ISR routines
PLUG1H								; High byte of Plug 1 current A/D
PLUG1L								; Low byte of Plug 1 current A/D
CALCPLUG1H							; High byte of Plug 1 current in 10's mA
CALCPLUG1L							; Low byte of Plug 1 current in 10's mA
PLUG2H								; High byte of Plug 2 current A/D
PLUG2L								; Low byte of Plug 2 current A/D
CALCPLUG2H							; High byte of Plug 2 current in 10's mA
CALCPLUG2L							; Low byte of Plug 2 current in 10's mA
VOLTH								; High byte of Battery voltage A/D
VOLTL								; Low byte of Battery voltage A/D
AHH									; High byte of Amp seconds count
AHL									; Low byte of Amp seconds count
CALCH								; Working MS byte
CALCL								; Working LS byte
P11									; ASCII Plug 1 amps 1's
P101								; ASCII Plug 1 amps 0.1's
P1001								; ASCII Plug 1 amps 0.01's
P21									; ASCII Plug 2 amps 1's
P201								; ASCII Plug 2 amps 0.1's
P2001								; ASCII Plug 2 amps 0.01's
V10									; ASCII Battery Voltage 10's
V1									; ASCII Battery Voltage 1's
V01									; ASCII Battery Voltage 0.1's
AH10								; ASCII Amp Hours 10's
AH1									; ASCII Amp Hours 1's
AH01								; ASCII Amp Hours 0.1's
AH001								; ASCII Amp Hours 0.01's
SUBH								; Used in 16BIT subtraction routine
SUBL								; Used in 16BIT subtraction routine
DIGIT								; Used in binary to ASCII conversion
DIM									; Used in display dimming routine

	ENDC

	CBLOCK	0X70

W_TEMP      
STATUS_TEMP
PCLATH_TEMP

	ENDC


;**********************************************************************
		ORG		0x000             	; processor reset vector
		GOTO	MAIN              	; go to beginning of program
	

		ORG		0x004             	; interrupt vector location

GIE_CLEAR
		BANKSEL	INTCON
		BCF		INTCON, GIE			; turn off interupts
		BTFSC	INTCON, GIE			; make sure they are really turned off
		GOTO	GIE_CLEAR
		MOVWF   W_TEMP            	; save off current W register contents
		MOVF	STATUS, W         	; move status register into W register
		MOVWF	STATUS_TEMP       	; save off contents of STATUS register
		MOVF	PCLATH,W	  		; move PCLATH register into W register
		MOVWF	PCLATH_TEMP	       	; save off contents of PCLATH register

		BTFSC	PIR1, TMR1IF		; test to see if Timer1 overflow 
		GOTO	HALF_SEC			; if yes, go to time counting routine 
		GOTO	TEST_SWITCH			; if no, go to TEST_SWITCH

HALF_SEC
		BCF		PIR1, TMR1IF		; clear Timer1 interrupt flag
		INCF	HALF_SEC_COUNT,F	; increment half seconds count
		BTFSC	HALF_SEC_COUNT,0
		GOTO	HEARTBEAT
		GOTO	HEARTBEAT1

HEARTBEAT
		MOVLW   0X87 
      	CALL	LCD_Cmd
		MOVLW	' '
		CALL	LCD_Nbl
		MOVLW	0x7E
		CALL	LCD_Nbl
		GOTO	HEARTBEAT2

HEARTBEAT1
		MOVLW   0X87 
      	CALL	LCD_Cmd
		MOVLW	0x7F
		CALL	LCD_Nbl
		MOVLW	' '
		CALL	LCD_Nbl

HEARTBEAT2
		MOVFW	HALF_SEC_COUNT		; check to see if 60 seconds has elapsed
		SUBLW	b'01111000'
		SKPNZ
		GOTO	HALF_SEC1			; if yes, update amp hour calculation
		GOTO	ISR_OVER			; if no, go to ISR_OVER and wait for next interrupt

HALF_SEC1
		MOVF	CALCPLUG1L,W		
		ADDWF	AHL,F
		MOVF	CALCPLUG1H,W
		BTFSC	STATUS,C
		ADDLW	D'1'
		ADDWF	AHH,F
		MOVF	CALCPLUG2L,W		
		ADDWF	AHL,F
		MOVF	CALCPLUG2H,W
		BTFSC	STATUS,C
		ADDLW	D'1'
		ADDWF	AHH,F
		MOVF	AHH, W
		MOVWF	CALCH
		MOVF	AHL, W
		MOVWF	CALCL
		CALL	AMP_ASCII
		CLRF	HALF_SEC_COUNT		; clear half seconds count
		GOTO	ISR_OVER			; go to ISR_OVER and wait for next interrupt

TEST_SWITCH
		BTFSC	INTCON, INTF		; test to see if switch 1 is pushed
		GOTO	TEST_SWITCH1		; if yes, change dimming
		GOTO	ISR_OVER			; if no, go to ISR_OVER and wait for next interupt

TEST_SWITCH1
		BANKSEL	STATUS
		BCF		STATUS, C			; if no, clear Carry bit of STATUS 	
		RLF		DIM, F				; rotate DIM right one bit
		BTFSS	DIM, 4				; test to see if we need to go back to bit 0
		GOTO	DIM_SEL				; no, go to DIM_SEL
		BCF		DIM, 4				; yes, clear DIM bit 4
		BSF		DIM, 0				; set MODE bit 0
	
DIM_SEL
		BTFSS	DIM, 0				; 100%?
		GOTO	DIM_SEL1			; no, check again
		GOTO	DIM_100				; yes, set PWM to 100%

DIM_SEL1
		BTFSS	DIM, 1				; 5%?
		GOTO	DIM_SEL2			; no, check again
		GOTO	DIM_05				; yes, set PWM to 5%

DIM_SEL2
		BTFSS	DIM, 2				; 01%?
		GOTO	DIM_00				; no, only 00% left
		GOTO	DIM_01				; yes, set PWM to 01%

DIM_00
		MOVLW	b'00000000'			; PWM duty cycle of 00%
		MOVWF	CCPR1L
		GOTO	DIM_OVER

DIM_01
		MOVLW	b'00000001'			; PWM duty cycle of 01%
		MOVWF	CCPR1L
		GOTO	DIM_OVER

DIM_05
		MOVLW	b'00000011'			; PWM duty cycle of 05%
		MOVWF	CCPR1L
		GOTO	DIM_OVER

DIM_100
		MOVLW	b'00111111'			; PWM duty cycle of 100%
		MOVWF	CCPR1L
	
DIM_OVER
		BANKSEL	PORTB
		MOVF	PORTB, W			; read PORTB
		MOVWF	TEST				; store PORTB in TEST
		BTFSS	TEST, 0				; has display key been released?
		GOTO	DIM_OVER			; if no, go to DIM_OVER
		CALL	DELAY_KB			; if yes, 10 ms Keyboard debounce
		MOVF	PORTB, W			; read PORTB
		MOVWF	TEST				; store PORTB in TEST
		BTFSS	TEST, 0				; has display key been released?
		GOTO	DIM_OVER			; if no, go to DIM_OVER
		BCF		INTCON, INTF		; if yes, clear RB0 interupt flag

ISR_OVER
		CALL	DISPLAY_UPDATE		; Update display
		BANKSEL	PCLATH_TEMP
		MOVF	PCLATH_TEMP,W		; retrieve copy of PCLATH register
		MOVWF	PCLATH            	; restore pre-isr PCLATH register contents
		MOVF	STATUS_TEMP,W     	; retrieve copy of STATUS register
		MOVWF	STATUS            	; restore pre-isr STATUS register contents
		SWAPF	W_TEMP,F
		SWAPF	W_TEMP,W          	; restore pre-isr W register contents
		RETFIE                    	; return from interrupt

;***** INCLUDE FILES *****

	#include "m_lcd.h"

;*************************************** TABLES *************************************

;***** SCREEN TABLES *****

SCREEN1
		MOVWF	PCL
		DT	"V=  . V    .  AH",0x00		

SCREEN2
		MOVWF	PCL
		DT	"I1= . A  I2= . A",0x00	

;*************************************** DELAY MACROS *************************************

;***** SHORT DELAY MACRO *****

D10USEC	MACRO	TCNST				; provides a delay equal to TCNST * 10 usecs
		MOVLW	TCNST
		MOVWF	DELAY1
		CALL	D10USEC1
		ENDM

D10USEC1
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		DECFSZ	DELAY1, F
		GOTO	D10USEC1
		RETURN


;***** LONG DELAY MACRO *****

DLONG	MACRO	TCNST				; provided a delay of TCNST * msec
		MOVLW	TCNST
		MOVWF	DELAY1
		CALL	OUTER
		ENDM	

OUTER
		MOVLW	D'110'				; close to 1.0 msec delay when set to 110
		MOVWF	DELAY2
INNER
		NOP
		NOP
		NOP
		NOP
		NOP
		NOP
		DECFSZ	DELAY2, F		
		GOTO	INNER
		DECFSZ	DELAY1, F
		GOTO	OUTER
		RETURN

;*************************************** DELAY SUBROUTINES *************************************

DELAY_KB
		DLONG	D'10'
		RETURN

;*************************************** LCD MODULE SUBROUTINES *************************************
; For HD44780 controller chips
; Note that lower bits of Port are being used

;***** LCD MODULE INITALIZATION SUBROUTINE *****

LCD_Init
		BANKSEL	LCD_DATA
		CLRF	LCD_DATA
		BCF		R_S					;write to the HD44780's IR. 
		MOVLW	b'00000011'			;Command for 8-bit interface
        MOVWF   LCD_DATA        
        BSF     EN      
        NOP
        BCF     EN
		DLONG	D'5'				;have to wait 4.1 ms here
        BSF     EN	           	
        NOP                    
       	BCF     EN     
        D10USEC	D'10'				;have to wait 100us here
        BSF     EN	           	
        NOP                    
        BCF     EN
        D10USEC	D'10'  				;have to wait 100us here
        BCF		R_S 
        MOVLW   b'00000010'			;Command for 4-bit interface
        MOVWF   LCD_DATA        
        BSF     EN     
        NOP
        BCF     EN
		MOVLW	FUNC_SET			;Function Set
		CALL	LCD_Cmd
		MOVLW   DISP_OFF			;Display Off        
		CALL	LCD_Cmd                
		MOVLW   CLR_DISP			;Clear the Display
        CALL	LCD_Cmd
        MOVLW   ENTRY_INC			;Entry Cursor Increment 
        CALL	LCD_Cmd        
		MOVLW   DISP_ON				;Display On, No Cursor
        CALL	LCD_Cmd
    
		RETURN                                                 
        
;***** LCD_Nbl SUBROUTINE *****

LCD_Nbl	
		BANKSEL	TEMP1	
		MOVWF   TEMP1				; Character to be sent is in
									; W so put in Temp1
		DLONG	D'2'				; Wait 2ms instead of Busy Check				
		SWAPF	TEMP1, W       	
		ANDLW   0x0F				; Get upper nibble into lower half port
		MOVWF   LCD_DATA	        ; Send data to LCD
		BSF     R_S					; Set LCD to data mode
		CALL	LCDtglclk	        ; Toggle EN
		MOVF	TEMP1, W
		ANDLW   0x0F            	; Get lower nibble into upper half port
		MOVWF   LCD_DATA	        ; Send data to LCD
		BSF     R_S		        	; Set LCD to data mode
		CALL	LCDtglclk			; Toggle EN
		RETURN

LCDtglclk
		BSF     EN					; Toggle EN for LCD
		NOP 
		NOP
		BCF     EN
		RETURN

;***** LCD_Cmd SUBROUTINE *****

LCD_Cmd
		BANKSEL	TEMP1	
		MOVWF   TEMP1				; Command to be sent is in
									; W so put in Temp1
		DLONG	D'2'	
		SWAPF	TEMP1, W
		ANDLW   0x0F				; Get upper nibble into lower half port
		MOVWF   LCD_DATA	        ; Send data to LCD
		BCF     R_S					; Set LCD to command mode
		CALL	LCDtglclk			; Toggle EN
		MOVF	TEMP1, W
		ANDLW	0x0F				; Get lower nibble into lower half port
 		MOVWF   LCD_DATA	        ; Send data to LCD
		BCF     R_S					; Set LCD to command mode
		CALL    LCDtglclk			; Toggle EN
		RETURN        

;***** LCD_Hex SUBROUTINE *****

LCD_Hex	
		BANKSEL	TEMP2
		MOVWF	TEMP2				; Character to be sent is in
									; W so put in Temp2
		SWAPF	TEMP2, W
		ANDLW   0x0F				; Get upper nibble into lower half port
		CALL	LCD_Hex1			; Convert upper nybble to ASCII 
		CALL	LCD_Nbl				; Output ASCII on LCD display 
     	MOVF	TEMP2, W
		ANDLW	0x0F
									; Get lower nibble into lower half port
 		CALL	LCD_Hex1			; Convert lower nybble to ASCII 
		CALL	LCD_Nbl				; Output ASCII on LCD display 
		RETURN
 
LCD_Hex1
		ADDLW	0xF6				; This routine converts a number in w to an  
		BTFSC	STATUS, C			; ASCII hex number.  Result in W 
		ADDLW	0x07 
		ADDLW	0x3A 
        RETURN

;***** LCD_Clear SUBROUTINE *****

LCD_Clear
       	MOVLW   CLR_DISP
      	CALL	LCD_Cmd 
      	RETURN

;***************************************LCD MODULE MACROS *************************************

;***** LCD_Move Macro *****

LCD_Move	MACRO   Address 
       	MOVLW   Address ;(Address|0x80) 
       	CALL	LCD_Cmd 
       	ENDM

;***************************************LCD SCREEN SUBROUTINES *************************************

;***** START SCREEN *****

START_SCREEN
		CALL	LCD_Clear
		CLRF	CNTR

START_SCREEN1
		MOVLW	HIGH SCREEN1
		MOVWF	PCLATH
		MOVLW	LOW	SCREEN1 + 1
		ADDWF	CNTR,W
		BTFSC	STATUS,C
		INCF	PCLATH,F
		CALL	SCREEN1
		ANDLW	0xFF
		BTFSC	STATUS, Z
		GOTO	START_SCREEN2	
		CALL	LCD_Nbl
		INCF	CNTR,F
		GOTO	START_SCREEN1

START_SCREEN2
		LCD_Move	0xC0
		CLRF	CNTR

START_SCREEN3
		MOVLW	HIGH SCREEN2
		MOVWF	PCLATH
		MOVLW	LOW	SCREEN2 + 1
		ADDWF	CNTR,W
		BTFSC	STATUS,C
		INCF	PCLATH,F
		CALL	SCREEN2
		ANDLW	0xFF
		BTFSC	STATUS, Z
		GOTO	START_SCREEN4	
		CALL	LCD_Nbl
		INCF	CNTR,F
		GOTO	START_SCREEN3

START_SCREEN4
		RETURN

;***** DISPLAY UPDATE *****

DISPLAY_UPDATE
	
		LCD_Move	0x82
		MOVF	V10,W
		CALL	LCD_Nbl
		MOVF	V1,W
		CALL	LCD_Nbl
		LCD_Move	0x85
		MOVF	V01,W
		CALL	LCD_Nbl
		LCD_Move	0x89
		MOVF	AH10,W
		CALL	LCD_Nbl
		MOVF	AH1,W
		CALL	LCD_Nbl
		LCD_Move	0X8C
		MOVF	AH01,W
		CALL	LCD_Nbl
		MOVF	AH001,W
		CALL	LCD_Nbl
		LCD_Move	0xC3
		MOVF	P11,W
		CALL	LCD_Nbl
		LCD_Move	0xC5
		MOVF	P101,W
		CALL	LCD_Nbl
		LCD_Move	0xCC
		MOVF	P21,W
		CALL	LCD_Nbl
		LCD_Move	0xCE
		MOVF	P201,W
		CALL	LCD_Nbl

		RETURN

;***************************************MATH SUBROUTINES *************************************

;***** 16 BIT SUBTRACTION *****
; 	Input: CALCH, CALCL , SUBH, SUBL
;	Output: CALCH=CALCH-SUBH, CALCL=CALCL-SUBL

SUB16
		BCF		STATUS,C
		MOVF	SUBL,W
		SUBWF	CALCL,F
		MOVF	SUBH,W
		BTFSS	STATUS,C
		ADDLW	D'1'
		SUBWF	CALCH,F

		RETURN

;***** 16 BIT ADDITION *****
; 	Input: CALCH, CALCL , SUBH, SUBL
;	Output: CALCH=CALCH+SUBH, CALCL=CALCL+SUBL

ADD16
		MOVF	SUBL,W		
		ADDWF	CALCL,F
		MOVF	SUBH,W
		BTFSC	STATUS,C
		ADDLW	D'1'
		ADDWF	CALCH,F
		RETURN

;***** 16 BIT MACRO *****
; Loads SUBH, SUBL with ARGL

LOADS	MACRO	ARGL
		MOVLW	HIGH(ARGL)
		MOVWF	SUBH
		MOVLW	LOW(ARGL)
		MOVWF	SUBL
		ENDM

;***** BINARY TO ASCII CONVERSION MACRO*****
; 	Input: CALCH, CALCL, ARGL
;	Output: ASCII value in DIGIT based on CALCH,CALCL divided by ARGL 

DODIGIT	MACRO	ARGL
		LOADS	ARGL
		CALL	DOSUB
		ENDM

DOSUB
		MOVLW	'0'-1		
		MOVWF	DIGIT				; tracks ASCII value of count

DOSUB1	
		INCF	DIGIT,F				; increment ASCII character
		CALL	SUB16		
		BTFSC	STATUS,C			; any carry?
		GOTO	DOSUB1				; no, keep subtracting
		CALL	ADD16				; yes, reverse the last subtraction
		MOVF	DIGIT,W				; place ASCII value of count in W
		BCF		STATUS,C
		RETURN

;***** PLUG 1 CURRENT DATA TO ASCII CONVERSION *****
;		Input:	Current data is in CALCH, CALCL
;		Output: ASCII characters in P11, P101, P1001

PLUG1_ASCII

		DODIGIT	D'100'				; count 1's of amps
		MOVWF	P11					; store result in P11
		DODIGIT	D'10'				; count 0.1's of amps
		MOVWF	P101				; store result in P101
		DODIGIT	D'1'				; count 0.01's of amps
		MOVWF	P1001				; store result in P1001

		RETURN							

;***** PLUG 2 CURRENT DATA TO ASCII CONVERSION *****
;		Input:	Current data is in CALCH, CALCL
;		Output: ASCII characters in P21, P201, P2001

PLUG2_ASCII

		DODIGIT	D'100'				; count 1's of amps
		MOVWF	P21					; store result in P21
		DODIGIT	D'10'				; count 0.1's of amps
		MOVWF	P201				; store result in P201
		DODIGIT	D'1'				; count 0.01's of amps
		MOVWF	P2001				; store result in P2001

		RETURN	

;***** VOLTAGE DATA TO ASCII CONVERSION *****
;		Input:	Current data is in CALCH, CALCL
;		Output: ASCII characters in V10, V1, V01

VOLT_ASCII

		DODIGIT	D'100'				; count 10's of volts
		MOVWF	V10					; store result in V10
		DODIGIT	D'10'				; count 1's of volts
		MOVWF	V1					; store result in V1
		DODIGIT	D'1'				; count 0.1's of volts
		MOVWF	V01					; store result in V01

		RETURN	

;***** AMP HOUR TO ASCII CONVERSION *****
;		Input:	Current data is in CALCH, CALCL
;		Output: ASCII characters in AH10, AH1, AH01, AH001

AMP_ASCII

		DODIGIT	D'60000'			; count 10's of amp hours
		MOVWF	AH10				; store result in AH10
		DODIGIT	D'6000'				; count 1's of amp hours
		MOVWF	AH1					; store result in AH1
		DODIGIT	D'600'				; count 0.1's of amp hours
		MOVWF	AH01				; store result in AH01
		DODIGIT	D'60'				; count 0.01's of amp hours
		MOVWF	AH001				; store result in AH001
		RETURN	

;************** MAIN **************

MAIN

;***** INITALIZE *****

		BANKSEL	TRISA
		MOVLW	b'00010000'	
		MOVWF	TRISA
		BANKSEL	PORTA
		CLRF	PORTA
		BANKSEL	TRISB
		MOVLW	b'11000001'	
		MOVWF	TRISB
		BANKSEL	PORTB
		CLRF	PORTB
		CLRF	HALF_SEC_COUNT
		CLRF	AHH
		CLRF	AHL
		CLRF	CALCPLUG1H
		CLRF	CALCPLUG1L
		CLRF	CALCPLUG2H
		CLRF	CALCPLUG2L
		MOVLW	b'00000001'
		MOVWF	DIM
		MOVLW	'0'	
		MOVWF	P11
		MOVWF	P101
		MOVWF	P1001
		MOVWF	P21
		MOVWF	P201
		MOVWF	P2001
		MOVWF	V10
		MOVWF	V1
		MOVWF	V01
		MOVWF	AH10
		MOVWF	AH1
		MOVWF	AH01
		MOVWF	AH001


		BANKSEL	OPTION_REG
		MOVLW	b'00000000'			; Port B pullups, int falling edge RB0
		MOVWF	OPTION_REG	
		BANKSEL	INTCON
		MOVLW	b'11010000'			; GIE, PIE enabled 
		MOVWF	INTCON
		BANKSEL	PIE1
		MOVLW	b'00000001'			; TMR1I enabled
		MOVWF	PIE1
		BANKSEL	OSCCON
		MOVLW	b'01100010'			; 4MHZ clock
		MOVWF	OSCCON
		BANKSEL	T1CON
		MOVLW	b'00110000'			; 1:8 pre-scale, Internal Clock, Timer1 disabled
		MOVWF	T1CON
		BANKSEL	ANSEL
		MOVLW	b'01110000'
		MOVWF	ANSEL
		BANKSEL	ADCON1
		MOVLW	b'10000000'			; Right justified, VDD/VSS as refs
		MOVWF	ADCON1
		BANKSEL	PR2
		MOVLW	b'00111110'			; PWM frequency of 1kHz
		MOVWF	PR2
		BANKSEL	CCPR1L
		MOVLW	b'00111111'			; PWM duty cycle of 100%
		MOVWF	CCPR1L
		BANKSEL	T2CON
		MOVLW	b'00000111'			; TMR2 prescale value 16, TMR2 on
		MOVWF	T2CON
		BANKSEL	CCP1CON
		MOVLW	b'00001111'			; set PWM in CCP1CON
		MOVWF	CCP1CON
	
		BANKSEL	PORTA

		DLONG	D'200'				; LCD power up delay

		CALL	LCD_Init			; Initialize LCD Module

		CALL	START_SCREEN		; display start screen

		CALL	DISPLAY_UPDATE

		BANKSEL	T1CON
		BSF		T1CON, TMR1ON		; Turn Timer1 on

CONVERT
		
		BANKSEL	ADCON0				; Convert Plug 1 current
		MOVLW	b'10101001'			; TAD = 32TOSC, convert AN5, AD on
		MOVWF	ADCON0
		BANKSEL	DELAY1
		D10USEC	D'2'				; have to wait 20us here
		BANKSEL	ADCON0	
		BSF		ADCON0, GO
CONVERT1
		BTFSC	ADCON0, GO
		GOTO	CONVERT1
		BANKSEL	ADRESH
		MOVF	ADRESH, W
		BANKSEL	PLUG1H
		MOVWF	PLUG1H
		BANKSEL	ADRESL
		MOVF	ADRESL, W
		BANKSEL	PLUG1L
		MOVWF	PLUG1L
		RRF		PLUG1H, F			; divide by 4 to get value in #s of 10mA
		RRF		PLUG1L, F
		BCF		STATUS, C
		RRF		PLUG1H, F
		RRF		PLUG1L, F
		BCF		STATUS, C
		MOVF	PLUG1H, W
		MOVWF	CALCPLUG1H
		MOVWF	CALCH
		MOVF	PLUG1L, W
		MOVWF	CALCPLUG1L
		MOVWF	CALCL
		CALL	PLUG1_ASCII
		
		BANKSEL	ADCON0				; Convert Plug 2 current
		MOVLW	b'10110001'			; TAD = 32TOSC, convert AN6, AD on
		MOVWF	ADCON0
		BANKSEL	DELAY1
		D10USEC	D'2'				; have to wait 20us here
		BANKSEL	ADCON0
		BSF		ADCON0, GO
CONVERT2
		BTFSC	ADCON0, GO
		GOTO	CONVERT2
		BANKSEL	ADRESH
		MOVF	ADRESH, W
		BANKSEL	PLUG2H
		MOVWF	PLUG2H
		BANKSEL	ADRESL
		MOVF	ADRESL, W
		BANKSEL	PLUG2L
		MOVWF	PLUG2L
		RRF		PLUG2H, F			; divide by 4 to get value in #s of 10mA
		RRF		PLUG2L, F
		BCF		STATUS, C
		RRF		PLUG2H, F
		RRF		PLUG2L, F
		BCF		STATUS, C
		MOVF	PLUG2H, W
		MOVWF	CALCPLUG2H
		MOVWF	CALCH
		MOVF	PLUG2L, W
		MOVWF	CALCPLUG2L
		MOVWF	CALCL
		CALL	PLUG2_ASCII

		BANKSEL	ADCON0				; Convert Battery voltage
		MOVLW	b'10100001'			; TAD = 32TOSC, convert AN4, AD on
		MOVWF	ADCON0
		BANKSEL	DELAY1
		D10USEC	D'2'				; have to wait 20us here
		BANKSEL	ADCON0
		BSF		ADCON0, GO
CONVERT3
		BTFSC	ADCON0, GO
		GOTO	CONVERT3
		BANKSEL	ADRESH
		MOVF	ADRESH, W
		BANKSEL	VOLTH
		MOVWF	VOLTH
		BANKSEL	ADRESL
		MOVF	ADRESL, W
		BANKSEL	VOLTL
		MOVWF	VOLTL		
		RRF		VOLTH, F			; divide by 4 to get value in #s of 100mV
		RRF		VOLTL, F
		BCF		STATUS, C
		RRF		VOLTH, F
		RRF		VOLTL, F
		BCF		STATUS, C
		MOVF	VOLTH, W
		MOVWF	CALCH
		MOVF	VOLTL, W
		MOVWF	CALCL
		CALL	VOLT_ASCII

		GOTO	CONVERT				; Wait for interrupts
	
		END
