;**************************************************************************
;
; last change 30.06.2007
;
; uses:
; IICOUNT, IITEMP as 8-Bit variable
;
;**************************************************************************

;**************************************************************************
;
; II2 Bus
; SDA and SCL have open-collector functions
; use external pull-up resistors
;
;**************************************************************************

;********************************************
; Subroutines for setting SDA & SCL
; high-level = pin is input
; low-level  = pin is output and low
;********************************************

SCLHigh
	banksel trisa   ; bank 1
	bsf scl         ; input
	banksel porta
SCLHigh2
	btfss scl       ; wait until SCL is high
	goto SCLHigh2
	goto iidelay

SCLLow
	banksel porta
	bcf scl
	banksel trisa
	bcf scl         ; output
	goto iidelay

SDAHigh
	banksel trisa
	bsf sda         ; input
	goto iidelay

SDALow
	banksel porta
	bcf sda
	banksel trisa
	bcf sda         ; output
		
;********************************
;********** II2 Delay ***********
;********************************

IIDelay
	clrwdt
	return

;********************************
;********* II2 Start ************
;********************************

IISTART
	call SDAHigh    ; SDA & SCL high
	call SCLHigh
	call SDALow     ; SDA Low = start
	call SCLLow     ; SCL Low
	return

;********************************
;******* II2 Stop ***************
;********************************

IISTOP
	call SDALow     ; SDA low
	call SCLHigh    ; SCL high
	call SDAHigh    ; SDA high = stop
	return

;********************************
;******* II2 NAK ****************
;********************************

; send NAK
IINAK
	call SDAHigh    ; SDA high = input
	goto IIACK2

;********************************
;******* II2 ACK ****************
;********************************

; send ACK
IIACK
	call SDALow     ; SDA Low
IIACK2
	call SCLHigh    ; SCL high
	call SCLLow     ; SCL low
	return


;********************************
; IISend
; sends 1 byte in W-register over the bus and checks ACK
; Input  = W-Register
; Output = Carry, 0 = ACK, 1 = NAK
;********************************

IISend
	banksel IITEMP    ; store w
	movwf IITEMP

	movlw 8         ; set loop counter
	banksel IICOUNT
	movwf IICOUNT

iis1
	banksel IITEMP
	rlf IITEMP,f      ; next bit

	btfss status,carry
	call SDALow
	btfsc status,carry
	call SDAHigh

	call SCLHigh    ; Clock High
	call SCLLow     ; Clock Low
	banksel IICOUNT
	decfsz IICOUNT,f    ; -1
	goto iis1

; read ACK
	call SDAHigh    ; High = input

	call SCLHigh    ; Clock High

	bcf status,carry ; ACK

	banksel porta
	btfsc sda        ; if not low 
	bsf status,carry ; NAK

	call SCLLow      ; Clock Low

	return

;********************************
; IIRec
; reads 1 byte from bus into iidat
; Input  = none
; Output = W-Register and IITEMP
;********************************

IIRec
	movlw 8          ; loop counter
	banksel IICOUNT
	movwf IICOUNT

	call SDAHigh     ; input
	
iir1
	call SCLHigh     ; SCL high

	bcf status,carry
	banksel porta
	btfsc sda
	bsf status,carry

	banksel IITEMP    ; shift into iidata
	rlf IITEMP,f
iir2
	call SCLLow      ; SCL low
	banksel IICOUNT
	decfsz IICOUNT,f
	goto iir1

	banksel IITEMP   ; load data
	movfw IITEMP

	return
