LPC4088 QuickStart Board - How to Expand - I2C

Overview

There are two I2C interfaces on the LPC4088 QuickStart Board. The I2C interface is perfect for expanding to peripherals that do not need very fast updates/sampling. Many different peripherals can easily be connected to the I2C bus.

  1. I2C0 is available on p31/p32.
  2. I2C1 is available on p9/p10.

The advantages of the I2C bus are:

  • Only two pins are needed.
  • It has a bus-oriented structure and support 127 different devices
  • It supports many masters and many slaves on the bus, although one master and many slaves is the most common structure.
  • Built-in acknowledge-handling at the lowest level of the protocol.

The disadvantages are:

  • The low communication speed (0.1/0.4 Kbps). The 3.4 Mbps rate is currently not supported although the LPC4088 supports it.
  • The limited bus length (typically less than 1 meter, the higher bit rate the shorter communication distance)

For more information about I2C, see http://en.wikipedia.org/wiki/I%C2%B2C

The two I2C busses can be used simultaneously. One I2C bus can be shared by different parts of the application program, for example when running several processes/tasks in an RTOS (Real-Time Operating System). Some kind of mutual-exclusive protection or driver abstraction must then be created so that the use of the bus is serialized in time, i.e., two or more users do not try to use the bus simultaneously.
On the other hand, using separate I2C busses can make the program control simpler. Separate parts of the program can control separate I2C busses.

Example Schematic

One page covers example I2C expansion in the example interface design schematic. A temperature sensor (LM75), e2prom (24LC256) and port expansion (PCA9532) are used as examples.

Note:

  • The I2C0 interface is also available on the display expansion connector.
  • The I2C0 interface has on-board 1.5 Kohm pull-up resistors.
  • The I2C1 interface has on-board 5 Kohm pull-up resistors.
  • Make sure there is no address conflicts when connecting multiple peripherals on the bus.

Example Code

The example below is using the on-board 24AA02E48 EEPROM as the I2C device to communication with. It is illustrated how the MAC address is retrieved as well as how to write data to the EEPROM.

I2C example using the 24AA02E48 EEPROM

#include "mbed.h"

// 24AA02E48 datasheet:
// http://ww1.microchip.com/downloads/en/DeviceDoc/20002124E.pdf

// the address of the EEPROM I2C device
#define EEPROM_24AA02E48_ADDR (0xA0)

static I2C i2c(P0_27, P0_28);

int main(void) {

    int i = 0;
    char offset = 0;
    bool verifiedOk = true;
    char buf[7];

    printf("Reading MAC address\n");

    do {

        // the MAC address is stored at offset 0xFA in the EEPROM
        // start by telling the EEPROM that we want to access this offset
        offset = 0xFA;

        // write returns non-0 on failure
        if (i2c.write(EEPROM_24AA02E48_ADDR, &offset, 1) != 0) {
            printf("Failed to write to I2C device (%x) at offset 0xFA\n",
                    EEPROM_24AA02E48_ADDR);
            break;
        }

        // read the MAC address (48 bits = 6 bytes). The read function
        // returns non-0 in case of failure
        if (i2c.read(EEPROM_24AA02E48_ADDR, buf, 6) != 0) {
            printf("Failed to read from I2C device (%x) at offset 0xFA\n",
                    EEPROM_24AA02E48_ADDR);
        }

        printf(" - the MAC address is %02X:%02X:%02X:%02X:%02X:%02X\n",
                buf[0],buf[1],buf[2],buf[3],buf[4],buf[5]);

    } while (0);

    printf("Writing data to EEPROM\n");

    do {

        // initializing the buffer with values that will be
        // written to the EEPROM. Note that index 0 is used as
        // the offset and data are put in the remaining 6 bytes
        // see "write data" section below
        for (i = 0; i < 6; i++) {
            buf[i+1] = i+3;
        }

        // We write to the beginning of the EEPROM (offset = 0) in this
        // example.
        //
        // Please note that there are limitations to how to write to the EEPROM
        // - At most one page (8 bytes for this EEPROM) can be written at a time
        // - A write request will wrap around if writing passed a page boundary
        //   - Example: If writing 4 bytes starting at offset 6, positions 6,7
        //              0, and 1 will actually be written since page boundaries
        //              are at even page sizes (0, 8, 16, ...) and a write
        //              request will wrap around if passing a page boundary.
        // - the upper part (0x80-0xFF) are always write protected for this
        //   particular EEPROM
        offset = 0;


        // write data
        // All data is written in one request (page write). The first byte must
        // therefore contain the offset to where the data should be written.
        // It is also possible to write one byte at a time.
        buf[0] = offset;
        if (i2c.write(EEPROM_24AA02E48_ADDR, buf, 7) != 0) {
            printf("Failed to write to I2C device (%x) 2\n",
                    EEPROM_24AA02E48_ADDR);
            break;
        }


    } while (0);

    printf("Reading back written data\n");

    do {
        // resetting the buffer
        memset(buf, 0, 6);


        // tell the EEPROM which offset to use
        if (i2c.write(EEPROM_24AA02E48_ADDR, &offset, 1) != 0) {
            printf("Failed to write to I2C device (%x) 3\n",
                    EEPROM_24AA02E48_ADDR);
            break;
        }

        // read data
        if (i2c.read(EEPROM_24AA02E48_ADDR, buf, 6) != 0) {
            printf("Failed to read from I2C device (%x) 3\n",
                    EEPROM_24AA02E48_ADDR);
        }

        // verifying read data
        for (i = 0; i < 6; i++) {
            if (buf[i] != (i+3)) {
                verifiedOk = false;
                printf(" - Read data not equal to written buf[%d]=%d != %d\n",
                        i, buf[i], (i+3));
                break;
            }
        }

        if (verifiedOk) {
            printf(" - Read data is equal to written data\n");
        }

    } while (0);

    return 0;
}

Other I2C Examples


Please log in to post comments.