;		RUTINAS DE COMUNICACIÓN CON DISPOSITIVO I2C
;
;			ABRIL 10 DEL 2000
;
;PORTX ES EL PUERTO DONDE SE ENCUENTRAN LOS BITS SCL Y SDA DEL DISPOSITIVO
;TRISX	ES EL REGISTRO DE DIRECCIÓN DEL PUERTO PORTX
;
#DEFINE _c STATUS,C
;
;****************************************************************************
;ENVIA CONDICIÓN DE START AL DISPOSITIVO I2C
;**************************************************************************
START
	BSF	PORTX,SDA
	BANK1
	BCF	TRISX,SDA
	BCF	TRISX,SCL
	BANK0
	BCF	PORTX,SCL
	NOP
	BSF     PORTX,SCL
	NOP
	NOP
	NOP
	NOP
	NOP
	BCF     PORTX,SDA
	NOP
	NOP
	NOP
	NOP
	NOP
	BCF     PORTX,SCL
	NOP
	NOP
	RETURN
;**************************************************************************
;ENVIA CONDICIÓN DE STOP AL DISPOSITIVO I2C
;**************************************************************************
STOP
	BANK1
	BCF	TRISX,SDA
	BCF	TRISX,SCL
	BANK0
	BCF     PORTX,SDA
	NOP
	NOP
	NOP
	BSF     PORTX,SCL
	NOP
	NOP
	NOP
	BSF     PORTX,SDA
	NOP
	NOP
	BCF     PORTX,SCL
	NOP
	NOP
	NOP
	RETURN
;**************************************************************************
;RUTINA QUE COLOCA 8 BITS EN EL DISPOSITIVO I2C, AFECTA F0
;**************************************************************************
WRIBYTE
	BANK1
	BCF	TRISX,SCL
	BCF	TRISX,SDA
	BANK0
	MOVLW   .8
	MOVWF   F0
	BCF     _c
ROTA
	RLF    	F4,F
	BTFSS   _c
	GOTO    ESCERO
ESUNO
	BSF     PORTX,SDA
	GOTO    PULSO
ESCERO
	BCF     PORTX,SDA
PULSO
	nop
	nop
	BSF     PORTX,SCL
	nop
	nop
	nop
	BCF     PORTX,SCL
	nop
	DECFSZ  F0,F
	GOTO    ROTA
	RETLW   TRUE
;****************************************************************************
;RUTINA QUE TOMA 8 BITS DEL DISPOSITIVO I2C, ALMACENA EL RESULTADO EN F4
;****************************************************************************
REBYTE
	MOVLW   .8              ;
	MOVWF   F0              ;CONTADOR
	BANK1
	BSF	TRISX,SDA	;SDA de Entrada
	BANK0
	CLRF    F4
RBIT
	BSF     PORTX,SCL             ;
	nop
	BTFSS   PORTX,SDA
	GOTO    ESTACERO
ESTAUNO
	BSF     _c      	;CARRY=1
	GOTO    PULSDOWN
ESTACERO
	BCF     _c		;CARRY=0
PULSDOWN
	RLF    	F4,F
	BCF     PORTX,SCL	;SCL=0
	nop
	DECFSZ  F0,F		;DEC F0
	GOTO    RBIT
	BANK1
	BCF	TRISX,SDA	;SDA DE SALIDA
	BANK0
	RETLW   TRUE            ;
;***************************************************************************
;RUTINA QUE LEE EL ACK DEL DISPOSITIVO I2C, AFECTA F0
;entrega en el reg W un TRUE si fue OK ó un FALSE si hubo error.
;***************************************************************************
ACKMEM
	BANK1
	BSF	TRISX,SDA	;SDA=IN
	BANK0
	MOVLW   .255
	MOVWF   F0
LOOPACKM
	BSF     PORTX,SCL
	nop
	nop
	nop
	nop
RSDA
	BTFSS   PORTX,SDA
	GOTO    SIACK
NOACK
	nop
	BCF     PORTX,SCL
	DECFSZ  F0,F
	GOTO    LOOPACKM
	RETLW   FALSE           ;EL DISP. I2C NO ENTREGÓ ACK
SIACK
	nop
	BCF     PORTX,SCL
	RETLW   TRUE            ;ACK = CORRECTO
;***************************************************************************
;ENVIA UN ACK AL DISPOSITIVO I2C
;***************************************************************************
ACKMICRO
	BANK1
	BCF	TRISX,SDA
	BCF	TRISX,SCL
	BANK0
	BCF     PORTX,SDA
	BSF     PORTX,SCL
	nop
	NOP
	NOP
	BCF     PORTX,SCL
	nop
	RETLW   TRUE
;***************************************************************************
;RUTINA LA CUAL ESCRIBE UN BYTE EN EL DISPOSITIVO I2C PARÁMETROS:
; DIREE y DATO (A ESCRIBIR)
;***************************************************************************
WR_EE
	CALL	START
	MOVLW	0xA0		; W=10100000 B
	MOVWF	F4
	CALL	WRIBYTE
	CALL	ACKMEM
	MOVF	DIREE,W		;ACOMODO DE WORD ADDRESS
	MOVWF	F4
	CALL	WRIBYTE
	CALL	ACKMEM
	MOVF	DATO,W		;ACOMODO DEL DATO A ESCRIBIR
	MOVWF	F4
	CALL	WRIBYTE
	CALL	ACKMEM
	CALL	STOP
	CALL	DEL5MS
	CALL	DEL5MS		;TIEMPO DE ESPERA twc
	CALL	DEL5MS
	RETLW	TRUE
;***************************************************************************
;ESTA RUTINA LEE DEL DISPOSITIVO I2C UN BYTE , PARÁMETROS:
; DIREE y DATO (LEÍDO)
;***************************************************************************
RD_EE
	CALL	START
	MOVLW	0xA0		; W=10100000 B
	MOVWF	F4
	CALL	WRIBYTE
	CALL	ACKMEM
	MOVF	DIREE,W		;ACOMODO DE WORD ADDRESS
	MOVWF	F4
	CALL	WRIBYTE
	CALL	ACKMEM
	CALL	START
	MOVLW	0xA1
	MOVWF	F4
	CALL	WRIBYTE
	CALL	ACKMEM
	CALL	REBYTE
	MOVF	F4,W
	MOVWF	DATO
	CALL	STOP
	RETLW	TRUE
;***************************************************************************

    Source: geocities.com/micros_uan