;Slave address of I2C device to whom we are talking #DEFINE SLAVEID 0x90 ; Set this for your device ; ********************************************************************* ; MACRO DEFINITIONS ; Generic PIC Assembly macro definitions ; Copywrite (c) 2004 Randy Gamage ; ifpos macro arg1 btfss arg1,7 ;Test if argument is positive (high bit clear) endm ifneg macro arg1 btfsc arg1,7 ;Test if argument is negative (high bit set) endm bank0 macro bcf STATUS,RP1 bcf STATUS,RP0 endm bank1 macro bcf STATUS,RP1 bsf STATUS,RP0 endm bank2 macro bsf STATUS,RP1 bcf STATUS,RP0 endm bank3 macro bsf STATUS,RP1 bsf STATUS,RP0 endm ; ;============================================== ; I2C Routines (using H/W I2C Peripheral ;============================================== I2CInit: ;NOTE: I2C Pins must already be set to be INPUTS movlw 0x28 ; Set mode to I2C Master, enable I2C movwf SSPCON bank1 clrf SSPCON2^0x80 ; Clear status flags movlw 49 ; Set speed to 100kHz w/20MHz clock movwf SSPADD^0x80 bsf SSPSTAT^0x80,SMP ; Disable slew rate control, set for 100kHz bcf SSPSTAT^0x80,CKE ; Set levels to I2C (set if you want SMBus levels) bank0 bcf PIR1,SSPIF ; Clear SSPIF interrupt flag bcf PIR2,BCLIF ; Clear bus collision flag return I2CWaitForIdle: bank1 I2C_WFI: movf SSPCON2^0x80,W ; Check all busy bits andlw 0x1F skipz goto I2C_WFI ifset SSPSTAT^0x80,R_W goto $ - 1 bank0 return I2CStart: call I2CWaitForIdle bank1 bsf SSPCON2^0x80,SEN ; Initiate Start bank0 return I2CRepStart: call I2CWaitForIdle bank1 bsf SSPCON2^0x80,RSEN ; Initiate Repeated Start bank0 return I2CStop: call I2CWaitForIdle bank1 bsf SSPCON2^0x80,PEN ; Initiate stop bank0 return I2CRead: call I2CWaitForIdle bank1 bsf SSPCON2^0x80,RCEN ; Initiate receive bank0 call I2CWaitForIdle movf SSPBUF,W movwf I2CData call I2CWaitForIdle bank1 bsf SSPCON2^0x80,ACKDT ; Don't send an ACK (EEPROM doesn't require it) bsf SSPCON2^0x80,ACKEN ; Initiate ACK sequence bank0 return I2CReadwAck: ; Same as I2CRead, but we send an ACK this time call I2CWaitForIdle bank1 bsf SSPCON2^0x80,RCEN ; Initiate receive bank0 call I2CWaitForIdle movf SSPBUF,W movwf I2CData call I2CWaitForIdle bank1 bcf SSPCON2^0x80,ACKDT ; Send an ACK this time bsf SSPCON2^0x80,ACKEN ; Initiate ACK sequence bank0 return I2CWrite: movwf I2CData ; Save input value call I2CWaitForIdle movf I2CData,W movwf SSPBUF call I2CWaitForIdle ; Can capture ACK return value here (in SSPCON2, ACKSTAT) if desired return