;***********************************************************************
;*   This file is the firmware to implement a     *
;*   at GPIO 2 Transistor output driver                                *
;***********************************************************************
;*                                                                     *
;*    					                               *
;*                                                                     *
;*    File Version: A.0                                               *
;*                                                                     *
;*    Author:       g michael                                          *
;*                  Principal Applications Engineer                    *
;*    Company:      Michaels Prototype                                 *
;*                                                                     *
;***********************************************************************

	list      p=12F683	; list directive to define processor
	#include <..\macros2b.asm>
	#include <p12f683.inc>	; processor specific variable definitions

 __CONFIG  _CP_OFF & _WDT_ON & _BOD_ON & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _CPD_OFF



;	ERRORLEVEL -302				; Get rid of banking messages...

;******************************************************************************

;******************************************************************************
;General Purpose Registers (GPR's) 
;******************************************************************************

	cblock	0x20
	SystemStatus,case,ALT,VoltMem,TenMore:2,Duty
	AL,AH,BL
	EEcount,LoBndry,MdBndry,HiBndry,LoDuty,MdDuty,HiDuty

	
	endc
#define	STACK	0x7F
#define	IOdir	  b'11111000'

#define ANSELinit B'01111000' 	;ADC Frc clock,
				;and GP1, 3 as analog

;******************************************************************************
;Reset Vector 
;******************************************************************************
	ORG     0x000		; processor reset vector

	nop			; required by in circuit debugger
	goto    Init		; go to beginning of program

;******************************************************************************
;Interrupt Vector     
;******************************************************************************
	ORG     0x004
	return			;IRQ TRAP
;******************************************************************************
;Subroutines
;******************************************************************************


#define	V11.0	b'01000000'
#define	V12.0	b'01100000'
#define V12.6	b'01110101'
#define	V13.7	b'10011110'
#define	V14.7	b'10101011'

vtable		addwf	PCL,F

		 retlw	V11.0
		 retlw  0xFE

		 retlw	V12.0
		 retlw	0xF0

		 retlw	V12.6
		 retlw	0x30

		 retlw  V13.7
		 retlw	0x10

		 retlw  V14.7
		 retlw	0x04
	



;
;movdutyAL	clrf	AH
;		mov	CCPR1L,AL	;load
;		shll	AL,(word)
;		shll	AL,(word)
;		btfsc	CCP1CON,DC1B0
;		 bsf	AL,0
;		btfsc	CCP1CON,DC1B1
;		 bsf	AL,1
;		retlw 0
;
;
movALduty	
		shr	AL		;unload
		bcf	CCP1CON,DC1B0
		skpNC
		 bsf 	CCP1CON,DC1B0
		
		shr	AL
		bcf	CCP1CON,DC1B1
		skpNC
		 bsf 	CCP1CON,DC1B1
		mov	AL, CCPR1L
		retlw	0

subtrisio	
		BANKSEL	Bank1		; 
		movwf	TRISIO		;
		BANKSEL	Bank0
		return
;		

#define		disport	1
#define		DH	STACK-3
displaybits	movlw	(1<<disport)
		BANKSEL	Bank1		; 
		bsf	TRISIO,disport
		;iorwf	TRISIO,F
		BANKSEL	Bank0

		eq	STACK, .10
		call	wak2delay


		eq	DH, .15
firstbit	movf	DH,F
		if_any AH, 7, STATUS, Z
		 goto nextbit-1
		clrC
		rlf	AL,F
		rlf	AH,F
		decf	DH,F
		goto	firstbit

		incf	DH,F
nextbit		clrC				;restore AL
		rlf	AL,F
		rlf	AH,F

		bcf	GPIO,disport		;red LED on
		movlw	1
		skpC
		 goto	wdelay
		movlw	5
		bsf	AL,0			;restore AL
		bsf	GPIO,disport		;green LED on

wdelay		movwf	STACK
	
		movlw	0x0F -(1<<disport)
		BANKSEL	Bank1
		bcf	TRISIO,disport
		;andwf	TRISIO,F	;GPport outout
		BANKSEL	Bank0
		call	wak2delay

		movlw	(1<<disport)
		BANKSEL	Bank1	
		Bsf	TRISIO,disport	; 
;		iorwf	TRISIO,F
		BANKSEL	Bank0

		eq	STACK,.1
		if_	DH,eql,.9,	(byteconst)
		 call	llong
		
		call	wak2delay
		decfsz	DH,F
		 goto nextbit
		retlw	0
		
llong		eq	STACK,.3
		retlw	0
		
;		
wak2delay	eqte	STACK-2,.100*.255,(word)
		clrwdt
		decfsz	STACK-2,F
		 goto	$-2
		decfsz	STACK-1,F
		 goto	$-4
		decfsz	STACK,F
		 goto	wak2delay
		retlw	0


pwmoff	bcf	T2CON,TMR2ON	 ; disable TMR2
	movlw	b'11110011'
	andwf	 CCP1CON, F	 ; disable PWM
	nop
	bcf	GPIO,2		 ; make sure GP2 is down
	retlw	0

pwmon	mov 	Duty,AL
	call	movALduty
	movlw	b'00001100'
	iorwf	 CCP1CON, F	 ; enable PWM
	bsf	T2CON,TMR2ON	 ; enable TMR2	;
	retlw	0

adc3	MOVLW 	B'00001101' 		;left justify,
	MOVWF 	ADCON0 			;Vdd Vref, AN3, On
	goto	$+1	
	goto	$+1
	goto	$+1			;Acquisiton delay
	BSF 	ADCON0,GO 			;Start conversion
	BTFSC 	ADCON0,GO 		;Is conversion done?
	GOTO 	$-1 			;No, test again

	MOVF 	ADRESH,W 		;Read upper 8 bits
	MOVWF 	AL 			;Store in GPR space
	retlw	0

;******************************************************************************
;Initialization
;******************************************************************************

#define	OPTIONinit	b'11011111'
#define	PR2init		.64
Init	init683
aftrinit
	clrf	case
	eq	Duty,.10
	call 	pwmoff
	

moreadc	eq	STACK,.1		 ; 200ms
morad2	call	wak2delay

	call	adc3
	
	mov	AL,Duty
	clrf	AH
	if_bit GPIO,3
	 call displaybits
	mov	Duty,AL

	if_	AL,lss,V11.0,		(byteconst);undervoltage
	 goto	slpy
	if_	AL,lss,.255,		(byteconst); overvoltage
	 goto	ok_V

slpy	call	pwmoff
	sleep
	call	adc3
;	clrf	AH
;	call displaybits
	if_	AL,lss,V12.0,		(byteconst)
	 goto	slpy
	goto	aftrinit
					;emergency stop


ok_V	eq	case,.4	;test
	;if_	AL,lss,(V12.0+V13.7 )/2, (byteconst)
	; clrf	case

;	goto	moreadc		;test

	movfw	case
	addwf	PCL,F
	 goto	case0
	 goto	case1
	 goto	case2
	 goto	case3
	 goto	case4

case0	clrf	Duty
	if_	AL,lss,V14.7,	(byteconst)
	 goto	moreadc
	eq	case,.3
	eqte	TenMore, .5*.120,	word
	eq	Duty,.1
	call	pwmon
	goto	moreadc

case1
	if_	AL,lss,V13.7-.2,	(byteconst)
	 goto	casis2

	if_ 	AL,grtr_eql,VoltMem,	(byte)
	 goto	incDuty
	mov	AL,VoltMem
	eq	BL,.5
	goto	moreadc+2
incDuty	if_	Duty,grtr,.60,		(byteconst)	
         goto	moreadc			; error !
	incf	Duty,F
	mov	Duty,AL
	call	movALduty
	goto	moreadc
casis2	eq	case,.2
	
case2	eq	BL,.5
	if_	AL,grtr,VoltMem	,	(byte)
	 goto	risingV
	if_	Duty,lss,.1,		(byteconst)
	 goto	risingV
	dec_	Duty,			(byte)
		mov	Duty,AL
	call	movALduty
	goto	moreadc

risingV	mov	AL,VoltMem
	if_	AL,lss,V13.7+3,		(byteconst)
	 goto	moreadc	

	decf	case,F		 	; case = 1
	goto	moreadc

case3	if_	AL, lss, b'11000000' , 	(byteconst)
	 goto tenmore
lowerP	if_	Duty,grtr,.40	,	(byteconst)
	 goto	casis1
	inc_	Duty,			(byte)
	mov	Duty,AL
	call	movALduty
	goto	moreadc

casis1	mov	AL,VoltMem
	eq	case,.1
	goto	moreadc

tenmore decfsz	TenMore,F
	 goto	moreadc
	decfsz	TenMore+1,F
	 goto	moreadc
	goto	casis1


case4  		eq	BL,.1

basesearch	if_	BL,grtr,.9,	(byteconst)
		 goto	over147
		 
		incf	BL,F
		movfw	BL
		call	vtable
		movwf	HiBndry

;		incf	BL,F
;		movfw	BL
;		call	vtable
;		movwf	CH
;
		incf	BL,F
		movfw	BL
		call	vtable
		movwf	HiDuty
	
;		incf	BL,F
;		movfw	BL
;		call	vtable
;		movwf	DH
;
		if_ 	AL,grtr,HiBndry,		(byte)
                 goto	basesearch
		
		decl	BL,.3
		movfw	BL
		call	vtable
		movwf	LoBndry

;		incf	BL,F
;		movfw	BL
;		call	vtable
;		movwf	
;
;
		incf	BL,F
		movfw	BL	
		call	vtable
		movwf	LoDuty

	
;		incf	BL,F
;		movfw	BL
;		call	vtable
;		movwf	DLH+1


binsearch	ar_	MdBndry,LoBndry,plus,HiBndry,	(byte)
		rrf	MdBndry,F
		ar_	MdDuty,LoDuty,plus,HiDuty,	(byte)
		rrf	MdDuty,F
		if_	AL,eql,MdBndry	,		(byte)
		 goto	xit
		
		if_	AL,grtr,MdBndry,		(byte)
		 goto	higher

		mov	MdBndry,HiBndry
		mov	MdDuty,HiDuty
		goto	binsearch
higher		mov	MdBndry,LoBndry
		mov	MdDuty,LoDuty
		goto	binsearch
		incf	BL,F
xit		
		mov	MdDuty,Duty

		call	pwmon
		eq	STACK,.5
		goto	morad2

over147		eq	Duty,.3
		goto	xit
	end
