;IIC ROUTINES FOR COMUNICATING TO AN EEPROM
;IIC EQUATES
ACK EQU .1
#DEFINE SDA PORTB,1 ;DATA LINE
#DEFINE SCL PORTB,0 ;CLOCK LINE
#DEFINE SDA_TRIS TRISB,1 ;DATA LINE TRIS
#DEFINE SCL_TRIS TRISB,0 ;CLOCK LINE TRIS
GENERAL EQU 0x21 ;general equate
COUNTER EQU 0X5A
TX_BUFFER EQU 0X5B
RX_BUFFER EQU 0X5C
EEPROMWR EQU B'10100000' ;WRITE INFO TO THE EEPROM
EEPROMRE EQU B'10100001' ;READ FROM THE EEPROM
HADD EQU 0X5D ;HIGH BYTE ADDRESS
LADDRESS EQU 0X58 ;LOW BYTE ADDRESS
DATA_IN EQU 0X5F ;DATA IN
DATA_OUT EQU 0X59 ;DATA OUT
SDAUP:
BSF STATUS,RP0 ;BANK ONE
BSF SDA_TRIS ;UP
BCF STATUS,RP0 ;BANK ZERO
NOP
RETURN
SDADOWN:
BSF STATUS,RP0 ;BANK ONE
BCF SDA_TRIS ;DOWN
BCF STATUS,RP0 ;BANK ZERO
NOP
RETURN
SCLUP:
BSF STATUS,RP0 ;BANK ONE
BSF SCL_TRIS ;UP
BCF STATUS,RP0 ;BANK ZERO
NOP
RETURN
SCLDOWN:
BSF STATUS,RP0 ;BANK ONE
BCF SCL_TRIS ;DOWN
BCF STATUS,RP0 ;BANK ZERO
NOP
RETURN
INIT_IIC:
BSF STATUS,RP0 ;BANK 1
BCF SCL_TRIS ;ALL AS OUTPUT
BCF SDA_TRIS ;ALL AS OUTPUT
BCF STATUS,RP0 ;BANK 0
BCF SDA ;STEADY STATE FOR DATA LINE
BCF SCL ;STEADY STATE FOR CLOCK
CALL SDAUP ;DATA LINE UP
CALL SCLUP ;CLOCK LINE UP
MOVLW .2
CALL MDELAY ;
RETURN
OUTPUT:
MOVLW 01H
MOVWF COUNTER ;SET THE POINTER/COUNTER
LOOP:
BTFSC TX_BUFFER,7 ;CHECK THE DATA
GOTO SET_IT ;GOTO SET THE DATA HIGH
CALL SDADOWN ;DATA LOW
CONT: CALL SCLUP ;CLOCK GOES HIGH
CALL SCLDOWN ;CLOCK GOES LOW AGAIN
BCF STATUS,C ;CLEAR THE CARRY
RLF TX_BUFFER,F ;ROTATE THE DATA
BCF STATUS,C ;CLEAR THE CARRY
RLF COUNTER,F ;ROTATE THE COUNTER
BTFSC STATUS,C ;TEST FOR END
RETURN ;GOTO FINNISH ;
GOTO LOOP ;CARRY ON IF NOT FINNISHED
SET_IT: CALL SDAUP ;DATA HIGH
GOTO CONT ;continue
INPUT: ;GET THE BYTE!
MOVLW 01H
MOVWF COUNTER ;SET THE POINTER/COUNTER
IPLOOP:
CALL SDAUP ;MAKE THE SDA LINE AN INPUT
CALL SCLUP ;CLOCK BACK UP
BTFSC SDA ;TEST SDA
GOTO SET_RXBUF ;SET THE DATA BIT
BCF RX_BUFFER,0 ;CLEAR THE DATA BIT
IPCONT:
CALL SCLDOWN ;RETURN CLOCK DOWN
RLF COUNTER,F ;ROTATE THE COUNTER
BTFSC STATUS,C ;TEST FOR END
RETURN ;END OF ROUTINE ;
BCF STATUS,C ;CLEAR THE CARRY
RLF RX_BUFFER,F ;ROTATE THE DATA
BCF STATUS,C ;CLEAR THE CARRY
GOTO IPLOOP ;CARRY ON IF NOT FINNISHED
SET_RXBUF:
BSF RX_BUFFER,0 ;SET THE INFO
GOTO IPCONT ;CARRY ON
START_BIT:
CALL SDAUP ;MAKE SURE THE SDA LINE IS UP
CALL SCLUP ;SET THE CLOCK UP
CALL SDADOWN ;DATA LINE ADD LOW WHILE CLOCK HIGH
CALL SCLDOWN ;START THE CLOCK TRAIN
RETURN
STOP_BIT:
CALL SDADOWN ;MAKE SURE THE SDA LINE IS DOWN
CALL SCLUP ;MAKE SURE THE SCL LINE IS UP
CALL SDAUP ;SDA LINE GOES HIGH WHEN SCL IS HIGH
RETURN
GET_ACK: ;ACKNOWLEDGE
CALL SDAUP ;MAKE THE SDA LINE AN INPUT
CALL SCLUP ;CLOCK BACK UP
BTFSC SDA ;TEST FOR LOW ACK
GOTO SET_FLAG ;SET THE ACK FLAG
BCF GENERAL,ACK ;CLEAR THE FLAG
FLAG_SET:
CALL SCLDOWN ;RETURN CLOCK ADDLOW
RETURN
SET_FLAG:
BSF GENERAL,ACK ;SET THE FLAG
GOTO FLAG_SET ;CARRY ON
SEND_ACK: ;WHEN READING, THE MASTER HAS TO
;GIVE THE ACKS/NO ACKS.
CALL SDADOWN ;DATA LINE DOWN
CALL SCLUP ;CLOCK GOES HIGH
CALL SCLDOWN ;CLOCK GOES DOWN
RETURN
NO_ACK: ;WHEN READING, THE MASTER HAS TO
;GIVE THE ACKS/NO ACKS.
CALL SDAUP ;DATA HIGH
CALL SCLUP ;CLOCK GOES HIGH
CALL SCLDOWN ;CLOCK GOES DOWN
RETURN
;****************************************************************
; INPUTS TO THIS ROUTINE ARE... HIGH (HIGH BYTE ADDRESS)
; ADDLOW (ADDLOW BYTE ADDRESS) AND DATA_OUT (THE DATA OUT!)
;****************************************************************
EEWRITE_BYTE: ;WRITE A BYTE TO THE EEPROM
CALL START_BIT ;OUTPUT THE START BIT
MOVLW EEPROMWR ;CALL THE EEPROM TO WRITE
MOVWF TX_BUFFER ;TO OUTPUT BUFFER
CALL OUTPUT ;OUTPUT THE DATA ON PORTE
CALL GET_ACK ;GET ACK BIT
MOVFW HADD ;GET THE HIGH BYTE ADDRESS
MOVWF TX_BUFFER ;SEND TO THE BUFFER
CALL OUTPUT ;OUTPUT THE DATA ON PORT
CALL GET_ACK ;GET ACK BIT
MOVFW LADDRESS ;GET THE ADDLOW BYTE ADDRESS
MOVWF TX_BUFFER ;SEND TO THE BUFFER
CALL OUTPUT ;OUTPUT THE DATA ON PORT
CALL GET_ACK ;GET ACK BIT
MOVFW DATA_OUT ;GET THE DATA TO BE SENT
MOVWF TX_BUFFER ;SEND TO THE BUFFER
CALL OUTPUT ;OUTPUT THE DATA ON PORT
CALL GET_ACK ;GET ACK BIT
CALL STOP_BIT ;OUTPUT THE STOP BIT
RETURN ;RETURN TO MAIN PROGRAM
;*********************************************************************
; INPUTS TO THIS ROUTINE ARE... HIGH (HIGH BYTE ADDRESS)
; ADDLOW (ADDLOW BYTE ADDRESS). OUTPUT FROM THIS ROUTINE IS DATA_IN
;*********************************************************************
EEREAD_BYTE: ;WRITE A BYTE TO THE EEPROM
CALL START_BIT ;OUTPUT THE START BIT
MOVLW EEPROMWR ;CALL THE EEPROM TO WRITE
MOVWF TX_BUFFER ;TO OUTPUT BUFFER
CALL OUTPUT ;OUTPUT THE DATA ON PORTE
CALL GET_ACK ;GET ACK BIT
MOVFW HADD ;GET THE HIGH BYTE ADDRESS
MOVWF TX_BUFFER ;SEND TO THE BUFFER
CALL OUTPUT ;OUTPUT THE DATA ON PORT
CALL GET_ACK ;GET ACK BIT
MOVFW LADDRESS ;GET THE ADDLOW BYTE ADDRESS
MOVWF TX_BUFFER ;SEND TO THE BUFFER
CALL OUTPUT ;OUTPUT THE DATA ON PORT
CALL GET_ACK ;GET ACK BIT
CALL START_BIT ;START BIT
MOVLW EEPROMRE ;READ OPERATION
MOVWF TX_BUFFER ;TRANSMIT IT
CALL OUTPUT ;OUTPUT THE CODE
CALL GET_ACK ;GET THE ACK
CALL INPUT ;GET THE DATA BYTE. STORE IN DATA_IN
CALL NO_ACK ;SEND A NOT ACK
CALL STOP_BIT ;OUTPUT THE STOP BIT
MOVFW RX_BUFFER ;GET THE DATA OUT
MOVWF DATA_IN ;AN MOVE IT TO DATA IN
RETURN ;RETURN TO MAIN PROGRAM