            TITLE   I2C MEMORY ACCESS ROUTINES

            INCLUDE 68HC11F1.DEF

* The I2C memory is connected to PORTG
* PG0 - SCL 
* PG1 - SDA - with external pull-up resistor !!
* PG2 - WR 


SCL         EQU     $01
SDA         EQU     $02
WR          EQU     $04
CMDR        EQU     $A1         ;control words for Read/Write operations
CMDW        EQU     $A0
        
            DATA

I2CADR      DS      2           ;current address
I2CWD       DS      1           ;data byte for write operations
I2CRD       DS      1           ;storage for data read from device

            CODE
            ORG     $8000       ;remove this line if used with INCLUDE!!!

* INITIALIZATION ROUTINE

I2CINIT     LDAA    #$07
            STAA    PORTG
            STAA    DDRG
            CLR     I2CADR
            CLR     I2CADR+1
            CLR     I2CWD
            RTS

****************************************************************
* I2START - generate the START sequence
****************************************************************
I2START     BSET    PORTG,SCL   ;clock high
            JSR     DELAY
            BCLR    PORTG,SDA   ;falling edge on SDA 
            JSR     DELAY
            RTS

****************************************************************
* I2STOP - generates the STOP condition
* SDA goes from LOW to HIGH when SCL is HIGH
****************************************************************
I2STOP      BSET    PORTG,SCL
            JSR     DELAY
            BSET    PORTG,SDA
            JSR     DELAY
            RTS


****************************************************************
* WRB - write the byte in A on the I2C bus MSB first
* Data changes while SCL is LOW and are stable when SCL is HIGH
****************************************************************

WRB         LDAB        #$08
WRB05       JSR         WRBIT
            DECB
            BNE         WRB05
            JSR         ACKW
            RTS

****************************************************************
* WBYTE - write the byte from I2CWD at the address I2CADR
* generates the START sequence then sends the control byte
* two bytes of the address one byte of data then STOP
****************************************************************
WBYTE       BCLR        PORTG,WR    ;eNable write operations
            JSR         I2START
            LDAA        #CMDW
            JSR         WRB         ;write the control word
            LDAA        I2CADR
            JSR         WRB
            LDAA        I2CADR+1
            JSR         WRB
            LDAA        I2CWD
            JSR         WRB
            JSR         I2STOP
            BSET        PORTG,WR    ;inhibit write
            RTS

****************************************************************
* RDB - read byte. similar to WRB, Reads 8 data bits in I2CRD
****************************************************************
RDB         CLR         I2CRD
            BCLR        DDRG,SDA    ;pull up resIstor on SDA
            LDAB        #$08        ;bit counter
* generate one clock pulse
RDB05       BCLR        PORTG,SCL
            JSR         DELAY       ;short delay
            BSET        PORTG,SCL
            JSR         DELAY
* now data is valid
            LDAA        PORTG
            ANDA        #SDA        ;isoLate the data bit
            BNE         SHIFT1

SHIFT0      CLC
            ROL         I2CRD
            BRA         RDBX

SHIFT1      SEC
            ROL         I2CRD

* check bit counter

RDBX        DECB
            BNE         RDB05

* all bits of the character are received
* It's time to generate an ACK 

            JSR         ACKR
            RTS

****************************************************************
* RBYTE - read the byte from the adress I2CADR and store it to I2CRD 
****************************************************************
RBYTE       JSR         I2START
            LDAA        #CMDW
            JSR         WRB         ;control word for write operations
            LDAA        I2CADR
            JSR         WRB
            LDAA        I2CADR+1
            JSR         WRB
            JSR         I2STOP
            JSR         I2START     ;a new START
            LDAA        #CMDR
            JSR         WRB
            JSR         RDB
            JSR         I2STOP
            RTS

**********************************************************************
* DELAY - short delay
**********************************************************************
DELAY       PSHX
            PULX
            RTS
**********************************************************************
* ACKW - wiat for ACK in write operations
**********************************************************************
ACKW        BCLR    PORTG,SCL
            BCLR    DDRG,SDA
            JSR     DELAY
            BSET    PORTG,SCL
            JSR     DELAY
            BSET    DDRG,SDA
            RTS

**********************************************************************
* ACKR - generate ACK in read operations
**********************************************************************
ACKR        BCLR    PORTG,SCL
            JSR     DELAY
            BSET    DDRG,SDA
            BCLR    PORTG,SDA

            BSET    PORTG,SCL       ;raise clock to HIGH
            JSR     DELAY
            BSET    PORTG,SDA       ;leave the line in output mode
            RTS

**********************************************************************
* WRBIT - write bit 7 of A on SDA and generate the clock
**********************************************************************
WRBIT       ASLA
            BCS     W1
W0          BCLR    PORTG,SCL       ;clock low
            BCLR    PORTG,SDA
            JSR     DELAY
            BSET    PORTG,SCL
            JSR     DELAY
            RTS

W1          BCLR    PORTG,SCL       ;clock low
            BSET    PORTG,SDA
            JSR     DELAY
            BSET    PORTG,SCL
            JSR     DELAY
            RTS

**********************************************************************


            END
