;*********************************************************************** ; compact I2C eeprom access code V1.0 ; (C) Mike Harrison 1998 ; example code for PIC12C508 ;------------------------------------------------------- workspace cnt equ 08 ; byte count register flags equ 09 ; flags and bit count : read equ 0 ; 1 to read bytes, 0 to write addr equ 1 ; 0 to send eeprom address byte rden equ 2 ; 1 to enable read next cycle ; b5-7 used as bit counter temp equ 0a ; read/write data byte eeadr equ 0b ; eeprom address iiport equ gpio ; port address sclbit equ 4 ; SCL port pin (no pullup required) sdabit equ 5 ; SDA port pin (10K pullup to Vdd required) lotris equ b'00101' ; TRIS setting with SCL and SDA outputs, other bits as required by application hitris equ lotris+(1<, movlw address-3 ; FSR offset due to unconditional increment movwf fsr movlw 0ef - bytes ; 2 writes (control, address) + n+1 reads (control,data) call do_iic endm writeee macro bytes,address ; usage : writeee , movlw address-1 movwf fsr movlw 0e0 - (bytes <<4) ; n+2 writes (control,address,data), no reads call do_iic endm ;-----------------------------------------------------------do_iic do_iic ; read/write byte(s) to I2C EEPROM ; W & FSR to be setup as follows : ; read : EF - nbytes FSR = RAM address-1 ; write : E0 - (nbytes<<4) FSR = RAM address-3 ; eeadr holds eeprom address (preserved on exit) ; on exit, FSR points to the byte after the last one read/written ; nbytes can be up to 14, but eeprom write cache may limit this movwf cnt retry_iic clrf flags ; initialise flags and bit count phaseloop movlw hitris tris iiport ; ensure SDA high bsf iiport,sclbit ; SCL high bcf iiport,sdabit ; ensure SDA o/p reg low movlw lotris goto $+1 ; ensure Tsu:sta - can be omitted in fast mode tris iiport ; sda low - start condition movlw iiadr ; IIC control byte (write) btfsc flags,rden movlw iiadr+1 ; .. or read control byte if read pending movwf temp ; IIC control byte bcf iiport,sclbit ; scl low - code above ensures Thd:sta byteloop ; ; start of byte read/write section movlw lotris btfss flags,read ; set SDA high (tri-state) if reading btfsc temp,7 ; set SDA low only if writing and data bit = 0 movlw hitris ; (sda o/p register bit will be low) tris iiport goto $+1 ; wait set-up time bsf iiport,sclbit ; clock high (may set SDA o/p reg bit high) clc ; used later - done here for timing movlw 0ff^(1<