;***********************************************************************
;*   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=12F629	; list directive to define processor
	#include <..\macros2b.asm>
	config629

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

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

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

	cblock	0x20
	SystemStatus,CasE,MaxTmr:2,VoltMem,TenMore
	PR2				;DutyCase
	FlipCounter,FlipCounterLoader
	AL,AH,DH
	endc
#define STACK 0X5F

#define Tmr0_Bit7	SystemStatus,7




#define	IOdir	 b'11001011'
				; GP5	outp 
				; GP4	inp  ; AN3
				; GP3	inp
				; GP2	outp
				; GP1	inp
				; GP0	outp

#define ANSELinit B'01111010' 	;ADC Frc clock,
				;and GP1, 3 as analog
#define CCPR1Linit	.10	;10us Pulse start with
;******************************************************************************
;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
;******************************************************************************
;
;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	clrC
;		shrr	AL,(word)		;unload
;		bcf	CCP1CON,DC1B0
;		skpNC
;		 bsf 	CCP1CON,DC1B0
;		clrC
;		shrr	AL,(word)
;		bcf	CCP1CON,DC1B1
;		skpNC
;		 bsf 	CCP1CON,DC1B1
;		mov	AL, CCPR1L
;		retlw	0
;

subtrisio	bsf	STATUS,5	;BANKSEL	Bank1		; 
		movwf	TRISIO		;
		BANKSEL	Bank0
		return
;
;
;displaycase	if_	CasE,not_eql,.1	, (byte)
;		 goto	out
;
;		movlw	IOdir |	b'00010000'		;GP4 input
;		call	subtrisio
;
;		retlw	0
;out		movlw	IOdir &	b'11101111'		;GP4 outout
;		call	subtrisio
;		if_	CasE,eql,.3	,(byte)
;	         goto	c3
;		mov_bit	CasE,1, GPIO,4
;		retlw	0
;c3		inv_bit	GPIO,4
;		Retlw	0
;
;displaybits	movlw	IOdir |	b'00100000'		;GP5 input
;		call	subtrisio
;		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,5
;		movlw	1
;		skpC
;		 goto	wdelay
;		movlw	5
;		bsf	AL,0			;restore AL
;		bsf	GPIO,5
;
;wdelay		movwf	STACK
;
;		movlw	IOdir &	b'11011111'			;GP5 outout
;		call	subtrisio
;
;;		movlw	b'00001100'
;;		iorwf	 CCP1CON, F	 ; enable PWM
;;
;		call	wak2delay
;	
;;dis		movlw	b'11110011'
;;		andwf	 CCP1CON, F	 ; disable PWM
;;
;		movlw	IOdir |	b'00100000'		;GP5 input
;	
;		call	subtrisio
;
;		eq	STACK,.1
;		if_	DH,eql,.9,	(byteconst)
;		 call	long
;		
;		call	wak2delay
;		decfsz	DH,F
;		 goto nextbit
;		retlw	0		
;long		eq	STACK,.3
;		retlw	0
;		
wak2delay	clrwdt
		decfsz	STACK-2,F
		 goto	$-2
		decfsz	STACK-1,F
		 goto	$-4
		decfsz	STACK,F
		 goto	$-6
		retlw	0

#define	port 5

flip		decfsz	MaxTmr,F		; overflow 256*16ms 4sec 32 for 512ms
		 incf	MaxTmr+1,F
		decf	MaxTmr+1,F
		decfsz	FlipCounter,F
		 retlw	0

		movlw	IOdir &	b'11011111'			;GP5 outout
		call	subtrisio

		movlw	1<<port
		xorwf	GPIO,F
		comf	FlipCounterLoader,F
		mov	FlipCounterLoader,FlipCounter

		retlw	0

#define	NFET_Gate_Port	GPIO,2
#define DutyCase	.5

dopwm		decf	CasE,W			; case <> 1?
		skpNZ
		 goto	nocycle		 
		movlw	DutyCase		;0..15
		addwf	PCL,F
		 bsf	NFET_Gate_Port
		 bsf	NFET_Gate_Port		; 1
		 bsf	NFET_Gate_Port
		 bsf	NFET_Gate_Port		; 3:  26
		 bsf	NFET_Gate_Port
		 bsf	NFET_Gate_Port		; 5:  1
		 bsf	NFET_Gate_Port	
		 bsf	NFET_Gate_Port		; 7:  8
		 bsf	NFET_Gate_Port		; 8:  7
		 bsf	NFET_Gate_Port		; 9:  6us
		 bsf	NFET_Gate_Port		; 10: 5
		 bsf	NFET_Gate_Port		; 11: 4
		 bsf	NFET_Gate_Port		; 12: 3
		 bsf	NFET_Gate_Port		; 13: 2us
onecycle	 bsf	NFET_Gate_Port		; 14: 1us+15
nocycle		 bcf	NFET_Gate_Port		; 15: NFET or Transistor off

		mov	PR2, STACK		;simulate PR2...
		shr	STACK
		shr	STACK
		movlw	.6			; 24us overhead
		subwf	STACK,F
		clrwdt
		decfsz	STACK,F
		 goto	$-2

		if__	TMR0,7 ,not_but, Tmr0_Bit7
		 call flip			; overflow 8ms
		mov_bit	TMR0,7,  Tmr0_Bit7		
		retlw 0
	
;******************************************************************************
;Initialization
;******************************************************************************

#define	OPTIONinit	B'11010001'; 4ms
Init	init629


#define	tc	.1024
	clrf	CasE
	eq	PR2,.250
	eqte	MaxTmr, (.1*tc)+0x0100,	(word)

mainloo	bcf	GPIO,port
	decfsz	CasE,W
	 bsf	GPIO,port
	eq	STACK,.1		 ; 200ms
	call	wak2delay
	bcf	GPIO,port


	ADCON629 0




	mov STACK-1,AL
	mov STACK,AH

;	call	displaycase

;	call	displaybits
;	goto	mainloo


;	BANKSEL ADRESL 			;
;	MOVF 	STACK,W 		;Read lower 8 bits
;	BANKSEL AL	
;	MOVWF 	AL 			;Store in GPR space

;
;	shrr	AL,	(word)			;max 9 bit
;	shrr	AL,	(word)			;max 8 bit
;	call	movALduty		;leaves AL = AL div 4
	
;	clrf	AH
;	call 	displaybits
;	goto	moreadc
#define	v14.8t	b'00100100'
#define	v14.6t	b'00100111'
#define	v13.6t	b'00111100'
#define v13.5t	b'01000010'
#define	v12.7t	b'10000011'

	if_	AL,lss,v12.7t	,(wordconst)
	 goto notlow
	clrf	CasE
	eq	FlipCounterLoader,.128	 
	goto	notmaxV

notlow	if_	AL,grtr,v14.8t	,(byteconst)
	 goto	ok_V
	eq	CasE,.1
	eq	PR2,.250		;emergency stop
	goto	mainloo


	

ok_V	movlw	v14.8t		;ALT = AL - Vmaxt 
	subwf	AL,W
	movwf	FlipCounterLoader
;	skpnZ				;no Zeros
;	 decf	FlipCounterLoader,F
;	comf	FlipCounterLoader,F

	movfw	CasE
	addwf	PCL,F
	 goto	case0
	 goto	case1
	 goto	case2
	 goto	case3

case0	if_	AL,grtr,v14.6t,		(byteconst)
	 goto	notmaxV
	eq	CasE,.3
	clrf	TenMore
	goto	case3
notmaxV	if_	PR2,lss,.41,		(byteconst)
	 goto	is25kHz
	dec_	PR2,			(byte)
	eqte	MaxTmr, (.1 * tc)+0x0100,(word)
	goto	moreadc

is25kHz	eqte	MaxTmr, (.25 * tc)+0x0100,(word) ;25 seconds
	goto	moreadc
	

case1	eqte	MaxTmr ,(.1 * tc)+0x0100,(word)
	if_	AL,lss,v13.5t,	(byteconst)
	 goto	moreadc

	incf	CasE,F			;CasE = 2
	mov	AL,VoltMem
	goto	moreadc	


case2	eqte	MaxTmr ,(tc /2)+0x0100	,(word)
	if_	AL,lss,VoltMem	,	(byte)
	 goto	risingV
	if_	PR2,lss,.41,		(byteconst)
	 goto	risingV
	dec_	PR2,			(byte)

risingV	mov	AL,VoltMem
	if_	AL,grtr,v13.6t,		(byteconst)
	 goto	moreadc	

	decf	CasE,F		 	; CasE = 1
	goto	moreadc

case3	eqte	MaxTmr ,(.1 * tc)+0x0100	,	(word)
	if_	AL, grtr,v14.6t  , 	(byteconst)
	 goto tenmore

lowerP	inc_	PR2,			(byte)
	if_	PR2, lss, .250	   , 	(byteconst)
	 goto	moreadc
	eq	CasE,.1
	goto	moreadc

tenmore decfsz	TenMore,F
	 goto	moreadc
	incf	TenMore,F
	goto	lowerP


moreadc 
blinky	call	dopwm	
	movfw	MaxTmr
	iorwf	MaxTmr+1,W		; maxTmr = 0?
	skpZ
	 goto	blinky
	
	goto	mainloo
	

	end
