--- /dev/null
+;######################################################################
+; i2clib.inc - I2C LIBRARY - IMPLEMENTATION
+;
+; See i2clib.asm for documentation of the interface to this file.
+
+ include /usr/share/gputils/header/p18f458.inc
+ radix dec
+ include ../iwjpictest/insn-aliases.inc
+
+;============================================================
+; COMMON ADMINISTRATIVE ROUTINES
+
+ udata_acs
+t res 1
+
+ code
+
+;--------------------
+i2cs_init
+; W slave number undefined
+ rcall slave2addr2
+ mov_wf SSPADD
+ mov_lw 0x16 ; !SSPEN, CKP(release), I2C 7-bit slave
+ mov_wf SSPCON1
+ mov_lw 0x81 ; GCEN, SEN
+ mov_wf SSPCON2
+ mov_lw 0x8 ; SMP(noslew), !CKE, !BF(empty)
+ mov_wf SSPSTAT
+ bs_f TRISB, 0
+ bs_f TRISB, 1
+ bc_f IPR1, SSPIP
+ bs_f SSPCON1, SSPEN
+ bs_f PIE1, SSPIE
+ return
+
+;--------------------
+i2cs_interrupt
+ bt_f_if0 PIR1, SSPIF
+ return
+; We have an interrupt. What are the possibilities ?
+ mov_ff SSPSTAT, t
+
+chkval macro mask, value, label
+ mov_fw t
+ and_lw mask
+ xor_lw value
+ bra_z label
+ endm
+ ; bits we want to check
+ ; 80 60 20 04 02 01
+ ; SMP CKE D_A R_W UA BF
+ ; set clr data? read? clr full?
+
+ chkval 0xe3, 0x81, got_addr
+ chkval 0xe7, 0xa1, got_data_write
+ chkval 0xe7, 0xa4, sent_data_read
+
+
+
+ mov_fw SSPSTAT
+ and_lw 0xe7 ; all except P and S
+
+ xor_lw 0x80
+ ; bits which might sensibly be set
+
+chkval_last equ 0
+chkval macro value, label
+ xor_lw value ^ chkval_last
+ bra_z label
+chkval_last equ value
+ endm
+ chkval 0x80 ; addr dunno
+
+ mov_lw 0x8
+
+
+ bt_f_if0 DATA_ADDRESS, SSPSTAT
+ bra data
+
+slave2addr
+; computes slave address in form suitable for use in i2c controller
+; actual i2c slave address is (slave number) + 0b0001000
+; W slave number i2c address * 2
+ add_lw 0b0001000
+ rlc_w
+ return
+
+
+
+
+ include i2clib.inc
+ end