PIC JAL IO Routine

I2C with SSP

by Josef [snail at iol.cz]

Enter with bank 0 selected. Underscored are bit names, here mostly from SSPCON2.

SELRP0 = BCF STATUS,RP0
SELRP1 = BSF STATUS,RP0
LDB REG,DATA = MOVLW DATA, MOVWF REG

; ------------------------------
; I2C INIT SEQUENCE
; ------------------------------
	LDB	SSPCON,B'00101000'	;I2C MASTER
	SELRP1
	LDB	SSPSTAT,B'10000000'	;NO SLEW RATE CONTROL
	LDB	SSPCON2,B'01100000'
	LDB	SSPADD,D'10'		;ADJUST ACCORDING TO CLOCK & I2C SPEED
	SELRP0
	RETURN

; ------------------------------
; ISSUE I2C START CONDITION
; ------------------------------
I2CST:	SELRP1
	BSF	_SEN
	BTFSC	_SEN
	GOTO	$-1
	SELRP0
	RETURN

; --------------------------------
; ISSUE I2C REPEAT START CONDITION
; --------------------------------
I2CRST:	SELRP1
	BSF	_RSEN
	BTFSC	_RSEN
	GOTO	$-1
	SELRP0
	RETURN

; ------------------------------
; ISSUE I2C STOP CONDITION
; ------------------------------
I2CSP:	SELRP1
	BSF	_PEN
	BTFSC	_PEN
	GOTO	$-1
	SELRP0
	RETURN

; ------------------------------
; I2C TRANSMIT DATA
; INPUT W - DATA
; OUTPUT CARRY - ACKNOWLEDGE
; ------------------------------
I2CTX:	MOVWF	SSPBUF
	SELRP1
	BTFSC	_R_W
	GOTO	$-1
	BCF	_C
	BTFSC	_ACKSTAT
	BSF	_C
	SELRP0
	RETURN

; ------------------------------
; I2C RECEIVE DATA
; INPUT CARRY - ACKNOWLEDGE
; OUTPUT W - DATA
; ------------------------------
I2CRX:	SELRP1
	BCF	_ACKDT
	BTFSC	_C
	BSF	_ACKDT
	BSF	_RCEN
	BTFSS	_BF
	GOTO	$-1
	BSF	_ACKEN
	BTFSC	_ACKEN
	GOTO	$-1
	SELRP0
	MOVF	SSPBUF,W
	RETURN

...the I2C protocol always consists of start, restart, byte read, byte write and stop. Eeproms have several modes of operation - byte write, page write, current address read, random read, continuous read. At this point you have to reffer to the datasheet for applicable modes of operation. Example 24C02 byte write (untested):

; -------------------------------------
; input _24c02addr - address in eeprom
; input _24c02data - data to be written
; -------------------------------------
_24c02wr:
	call	i2cst		;issue start
	movlw	0xA0		;transmit device address
	call	i2ctx		;(all address pins low)
	btfsc	status,carry
	goto	_24c02wr0	;error - no acknowledge
	movf	_24c02addr,w	;transmit byte address
	call	i2ctx
	movf	_24c02data,w	;transmit data
	call	i2ctx
_24c02wr0:
	call	i2csp		;issue stop
	return

After this, the eeprom will not acknowledge its address until the internal write has finished. It can be used for testing end of write:

_24c02wait:
	call	i2cst
	movlw	0xA0		;try to address the eeprom
	call	i2ctx
	call	i2csp		;i2csp preserves carry bit
	btfsc	status,carry
	goto	_24c02wait	;no acknowledge, try again
	return


Questions: