
;	Lithium Ion Battery Charger
;	Charges (Raw) unprotected cells
;	12/05 Luhan Monat

	device	pic12f675,intrc_osc,pwrte_on,mclre_on


	org	20h

flag	ds	1
temp	ds	1
data	ds	1
count	ds	1
htime	ds	1		;power on time
ltime	ds	1		;power off time
battv	ds	1		;battery volts
batta	ds	1		;battery amps
hi	ds	1
low	ds	1
timer	ds	2
dfact	ds	3
digit	ds	1
dela	ds	1

BVOLT	=	gp.1		;battery top voltage
BAMP	=	gp.0		;battery current sense
LED	=	gp.4		;LED indicator
PWR	=	gp.5		;power control

SOUT	=	LED
BUG	=	gp.2

	org	0
	
	goto	start
	
	org	4
	
	reti

	
start	bsf	RP0
	movlw	000011b		;set gp io directions
	movwf	gp
	movlw	127
	movwf	OSCCAL
	movlw	00010011b	;clk/8, ad0,1
	movwf	ANSEL
	bcf	RP0
	movlw	7
	movwf	CMCON		;enable digital lines
	bsf	PWR		;power off
 	bsf	LED		;led off
 
	call	getvolt
	call	getvolt
	movlw	70
	call	delay
	call	clamp		;kill stray charge
	call	testb		;test for battery
	movlw	40
	call	delay
	call	charge
	goto	chend	

; loop time = 900ms
; 5 hrs = 20,000 loops

charge	movlw	20000>
	movwf	timer
	movlw	20000<
	movwf	timer+1

:2	call	getamp		;read charge current pulse
	movf	batta,w		;result?
	call	pwidth
	xorlw	0		;check for zero
	btfsc	z
	ret			;done.
	call	setpwr
	call	ppulse
	call	ppulse
	call	ppulse
	call	ppulse
	call	ppulse
	call	chktim		;count down timer
	btfss	z		;done?
	goto	:2		;no.
	goto	toerr		;yes - timed out

; count down timer+1,/timer return Z on done.

chktim	movf	timer
	btfsc	z
	decf	timer+1
	decf	timer
	movf	timer,w
	iorwf	timer+1,w
	ret
	

testb	call	getvolt		;is battery present
	movf	battv,w		;get voltage
	addlw	10		;too high?
	btfsc	c
	goto	hverr
	movf	battv,w
	addlw	240		;battery present?
	btfss	c
	goto	nperr
	movf	battv,w
	addlw	160		;too low?
	btfss	c
	goto	lverr
	ret


; discharge stray voltage at battery clips

clamp	bcf	BVOLT		;line low
	bsf	RP0
	bcf	BVOLT		;line is out
	bcf	ANSEL,1		;line is digital
	bcf	RP0
	movlw	20		;clear any charge
	call	delay
	bsf	RP0
	bsf	BVOLT		;line is input
	bsf	ANSEL,1		;line is analog
	bcf	RP0
	ret
	
	
chend	movlw	1
	goto	hold	
toerr	movlw	2
	goto	hold
nperr	movlw	3
	goto	hold
lverr	movlw	4
	goto	hold
hverr	movlw	5
	goto	hold


; turn off power and flash value in W

hold	bsf	PWR		;power off
	movwf	temp
:2	movf	temp,w
	movwf	count
:4	bcf	LED
	movlw	25
	call	delay
	bsf	LED
	movlw	50
	call	delay
	decfsz	count
	goto	:4
	movlw	70
	call	delay
	goto	:2


sign	movlw	10
	movwf	count
:2	bcf	LED		;led on
	movlw	20
	call	delay
	bsf	LED		;led off
	movlw	20
	call	delay
	decfsz	count
	goto	:2
	ret
		

eval	call	getamp
	call	serout
	movlw	50
	call	delay
	goto	eval
		

test	bsf	LED
	call	ppulse
	bcf	LED
	movlw	20
	call	setpwr
	call	ppulse
	goto	test

; set power pulse delay values via 'w'

setpwr	movwf	htime		;high time
	sublw	0		;residual time
	movwf	ltime
	ret


; generate power pulse

ppulse	movlw	250
	movwf	count		;set main loop count
:blip	movf	htime,w
	movwf	temp
	bcf	PWR		;engage power
	bcf	LED
:b2	decfsz	temp
	goto	:b2
	bsf	PWR		;end power pulse
	bsf	LED
	movf	ltime,w
	movwf	temp
:b4	decfsz	temp		;remaining time
	goto	:b4
	decfsz	count
	goto	:blip
	ret


getvolt	bsf	PWR		;turn off charge
	call	volts
	movwf	battv		;save data
	ret

getamp	bcf	PWR		;turn on charge
	call	amps
	movwf	batta		;save data
	bsf	PWR		;turn off charge
	ret


; read battery voltage and current

amps	movlw	81h		;right just, chan=0, a/d on
	movwf	ADCON0
	nop			; need to settle?
	bsf	ADCON0,1	;start conversion
:wt	btfsc	ADCON0,1	;ready?
	goto	:wt		;no.
	bsf	RP0
	movf	ADRESL,w	;read lower quadrant
	bcf	RP0
	ret

volts	movlw	05h		;left just, chan=1, a/d on
	movwf	ADCON0
	bsf	ADCON0,1	;start conversion
:wt	btfsc	ADCON0,1	;ready?
	goto	:wt		;no.
	movf	ADRESH,w
	ret	
	

delay	movwf	dfact+2
:dz	movwf	dfact+1
:dy	movwf	dfact
:dx	decfsz	dfact
	goto	:dx
	decfsz	dfact+1
	goto	:dy
	decfsz	dfact+2
	goto	:dz
	ret


	
serout	movwf	temp
	clrf	count
	bsf	count,3
	bcf	SOUT		;start bit
	nop
	nop
	nop
	nop
:s2	nop
	call	fbit
	rrf	temp
	btfss	c
	bcf	SOUT
	btfsc	c
	bsf	SOUT
	decfsz	count
	goto	:s2
	call	fbit
	bsf	SOUT		;stop bit
	call	fbit
	call	fbit
	ret

; 9600 baud at 20mhz clock
	
fbit	movlw	136
	goto	fhbit
hbit	movlw	1	
fhbit	movwf	dela
:f2	decfsz	dela
	goto	:f2
	ret

pwidth	clrf	PCLATH
	bsf	PCLATH,0	;100h
	movwf	temp
	rrf	temp
	rrf	temp
	movf	temp,w
	andlw	3fh		;devide by 4
	movwf	PCL

	org	100h

:0	retw	  0,  0,  0,255,255, 250,245,240
:40	retw	235,228,215,200,185, 170,155,140,125,110
:80	retw	107,103, 99, 95, 90   85,  83, 81, 79, 77
:120	retw	 60, 40, 40, 40, 40,  40,  40, 40, 40, 40
	retw	 40, 40, 40, 40, 40,  40,  40, 40, 40, 40
	
	end
		

	