I2C

i2cstest() i2cread
i2cwrite
i2copen
i2close

The I2C (I squared C) interface has just two associated commands for reading and writing which should cover most of the I2C devices on the market. For a discussion of the hardware and connection details see the Hardware Guide. This section deals only with the BASIC software interface.

For the BV513 only channel 1 is used as channel 2 is used by the SPI interface.

i2ctest
i2ctest(adr)
a=i2ctest(0x42)

The I2C test command will return 1 if the device is present otherwise it returns 0. The I2C channel must be opened first otherwise the command will return 0 regardless of the device presence or not.

function i2_test
dim j%
    i2copen 100000
    for j%=0x02 to 0xf0 step 2
        if i2ctest(j%) <> 0 then
            print "device at ";j%
        endif
    next
endf

The above code will scan through all I2C even addresses from 2 to 0xf0 and report if any devices are found at that address. Run this routine if you have an I2C device but not sure of its address.

This is the output from the above code when there is a BV4237 connected that has a RTC, temperature device and I/O device:
device at 0x62
device at 0x90
device at 0xd0

i2cread 
i2cread <adr>[cmd>..],ary[start];number
i2cread rtc, a[1];4
i2cread 0x42 0x55, a[1];3

It is recognised that some I2C devices require one or more commands prior to obtaining input. The serial EEPROM for example may have the memory address following the input. This statement can take care of that as an optional command or commands can be sent prior to reading from the i2c

Example 1:

dim a&2[2]
i2cread 0x90, a&[1];2

This is an example of reading a temperature device with an address of 0x90. Two bytes are returned by the device. An address always follows the statement, this should be the write address (an even number). The comma tells the statement that an integer or character array follows, this is where the data will go. The number of bytes to read comes after the semicolon. This statement will therefore address the I2C device at address 0x90 and read into a&[1] and a&[2] two bytes.

The index used in the array will be the first ‘slot’ to write the data to. In I2C speak this would be s 90 r g-2 p where s is the start condition, 90 is a byte sent in hex r is a restart condition using 0x91, g-2 gets 2 bytes from the device and p is the stop condition. In this example a character array ‘&’ has been used, an integer array could also be used.

Example 2:

dim a[3]
i2cread 0x62 0x55, a[1];3

A more complex example is used to check that a I2C BV device is working or connected. These device have a test command whereby if 0x55 is sent, subsequent reads returns an incrementing number. Here the command 0x55 is sent before reading 3 bytes.

The rules for this statement are as follows:

  1. An address must always follow the statement
  2.  None or up to 10 commands can be sent after the address
  3. A comma indicates the start of the read section, i.e. it must go after the address or last command.
  4. A single dimension integer or character array must always be used to gather the data from the I2C device. The index given will be the first byte, the next byte will be +1.
  5. The number of bytes to be read is specified after the semicolon.
i2write
i2write <adr> <cmd> <cmd>...
i2cwrite 0x40 0xff
i2cwrite l% 2,“Hello”

Writing to the I2C device simply amounts to sending data. To make life easier there are a few options. The basic statement is:

i2cwrite <address> <data>,<data>,..

Data can consist of an integer number, any integer, character, variable or a string or string variable. The latter is useful for writing a ‘buffer’ of information or for writing to displays.

Example:

The BV4218 is an LCD controller, to send text to this device requires a command (2) followed by the text to display. In I2C speak to send “Hello” to the display would require the following: s 0x42 2 0x48 0x65 0x6c 0x6c 0x6f s Where s and p are the stop and start conditions, 0x42 is the address of the LCD device and the other bytes are the ASCII for “Hello”. To send this using the i2cwrite statement:

dim l%=0x42
i2cwrite l% 2,“Hello”

This would also work:

dim l%, a$=”hello”
i2cwrite l% 2,a$
i2copen
i2copen <speed>
i2copen 100000

This sets the appropriate registers and serial rate to enable I2C communications. This must be actioned first before any other I2C command. The speed is in HZ, in the above example it has been opened for a slow speed device of 100k

i2close
i2close

The purpose of this keyword is to free up the ports used for the I2C communications so that they may be used for other purposes.