I2CSTART   I2CSTOP   I2CSEND   I2CRECV

' -------------------------------------------------------------------------
' Program Description
' -------------------------------------------------------------------------
'
' Writes a pseudo-random value to a 24LC16B EEPROM and then reads the
' value back. Run program in Debug/Poll mode to view address, output and
' input values.

' -------------------------------------------------------------------------
' Device Settings
' -------------------------------------------------------------------------

DEVICE          SX28, OSCXT2, TURBO, STACKX, OPTIONX
FREQ            4_000_000
ID              "I2C"

' -------------------------------------------------------------------------
' IO Pins
' -------------------------------------------------------------------------

SDA             VAR     RA.0
SCL             VAR     RA.1

' -------------------------------------------------------------------------
' Constants
' -------------------------------------------------------------------------

SlaveID         CON     $A0                     ' for 24LC16B

Ack             CON     0
Nak             CON     1

' -------------------------------------------------------------------------
' Variables
' -------------------------------------------------------------------------

addr            VAR     Word                    ' address in 24LC16B
addrLo          VAR     addr_LSB
addrHi          VAR     addr_MSB

outVal          VAR     Byte                    ' to 24LC16B
inVal           VAR     Byte                    ' from 24LC16B

tmpW1           VAR     Word                    ' work vars
tmpB1           VAR     Byte
tmpB2           VAR     Byte
tmpB3           VAR     Byte
tmpB4           VAR     Byte

WATCH addr                                      ' for Debug/Poll mode
WATCH outVal
WATCH inVal

' =========================================================================
  PROGRAM Start
' =========================================================================

' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------

MEM_OUT         SUB     3                       ' write value to memory
MEM_IN          SUB     2                       ' read byte from memory

' -------------------------------------------------------------------------
' Program Code
' -------------------------------------------------------------------------

Start:
  INPUT SDA                                     ' float I2C bus pins
  INPUT SCL

Main:
  DO
    FOR addr = 0 TO $03FF
      RANDOM outVal                             ' recreate new value
      MEM_OUT addr, outVal                      ' send to 24LC16
      PAUSE 500                                 ' delay for Debug/Poll mode
      inVal = MEM_IN addr                       ' get from 24LC16
      BREAK                                     ' allow WATCH window view
    NEXT
  LOOP

' -------------------------------------------------------------------------
' Subroutines Code
' -------------------------------------------------------------------------

' Use: MEM_OUT address, value
' -- writes 'value' to 24LC16B location at 'address'

MEM_OUT:
  tmpW1 = __WPARAM12                            ' copy address
  tmpB1 = __PARAM3                              ' copy value

  I2CSTART SDA
  tmpW1_MSB = tmpW1_MSB & $03                   ' get block value
  tmpW1_MSB = tmpW1_MSB << 1
  tmpW1_MSB = tmpW1_MSB | SlaveID               ' create control byte
  tmpW1_MSB.0 = 0                               ' set RW bit for write
  I2CSEND SDA, tmpW1_MSB                        ' send slave ID
  I2CSEND SDA, tmpW1_LSB                        ' send word address
  I2CSEND SDA, tmpB1                            ' send data byte
  I2CSTOP SDA                                   ' finish
  RETURN

' -------------------------------------------------------------------------

' Use: value = MEM_IN address
' -- reads 'value' from 24LC16B location at 'address'

MEM_IN:
  tmpW1 = __WPARAM12                            ' copy address

  I2CSTART SDA
  tmpW1_MSB = tmpW1_MSB & $03                   ' get block value
  tmpW1_MSB = tmpW1_MSB << 1
  tmpW1_MSB = tmpW1_MSB | SlaveID               ' create control byte
  tmpW1_MSB.0 = 0                               ' set RW bit for write
  I2CSEND SDA, tmpW1_MSB                        ' send slave ID
  I2CSEND SDA, tmpW1_LSB                        ' send word address
  I2CSTART SDA                                  ' restart for read
  tmpW1_MSB.0 = 1                               ' set RW bit for Read
  I2CSEND SDA, tmpW1_MSB                        ' resend slave ID
  I2CRECV SDA, tmpB1, Nak                       ' get one byte
  I2CSTOP SDA
  RETURN tmpB1