A hacked library to offer I2C functionality similar to the standard mbed library for I2C1 only. Is seemingly required when using the v29 beta mbed library as of 12.05.2011, as the I2C does not seem to work otherwise. Has been developed and tested with the ADXL345 accelerometer.

Dependents:   SensorsThingSpeak

I2CR.cpp

Committer:
ShockSoc
Date:
2011-05-12
Revision:
0:375ecd0ed73d

File content as of revision 0:375ecd0ed73d:

#include "I2CR.h"

//Constructor
I2CR::I2CR() {

    //set pins to i2c1
    LPC_PINCON->PINSEL0 = LPC_PINCON->PINSEL0 | 0xF;
    //set to no pull up/down resistors
    LPC_PINCON->PINMODE0 = LPC_PINCON->PINMODE0 | 0xA;
    //set to open drain mode
    LPC_PINCON->PINMODE_OD0 = LPC_PINCON->PINMODE_OD0 | 0x3;

    //turn on power
    LPC_SC->PCONP = LPC_SC->PCONP | 0x00080000;

    //set clock to 100kHz
    LPC_I2C1->I2SCLL = 120;
    LPC_I2C1->I2SCLH = 120;

    //enable i2c1 i2en
    LPC_I2C1->I2CONSET = 0x40;
    //clear sta si and aa
    LPC_I2C1->I2CONCLR = 0x2C;


}

//Write function
int I2CR::write(int address, const char* data, int length) {
    //MASTER TRANSMITTER

    //send start condition
    LPC_I2C1->I2CONSET = 0x20;

    //block until interrupt
    while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

    //i2stat should be 0x08. could check
    if (LPC_I2C1->I2STAT != 0x08) {
        printf("START %x\r\n",LPC_I2C1->I2STAT);
        //stop if failed
        LPC_I2C1->I2CONSET = 0x10;
        return -1;
    }

    //clear start condition
    LPC_I2C1->I2CONCLR = 0x20;

    //load i2dat
    LPC_I2C1->I2DAT = address;

    //reset si
    LPC_I2C1->I2CONCLR = 0x08;

    //block until interrupt
    while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

    //i2stat should be ack received
    if (LPC_I2C1->I2STAT != 0x18) {
        printf("ADD %x\r\n",LPC_I2C1->I2STAT);
        //stop
        LPC_I2C1->I2CONSET = 0x10;
        return -1;
    }

    for (int i=0; i<length; i++) {
    
        //load i2dat
        LPC_I2C1->I2DAT = data[i];

        //reset si
        LPC_I2C1->I2CONCLR = 0x08;

        //block until interrupt
        while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

        //i2stat should be ack received
        if (LPC_I2C1->I2STAT != 0x28) {
            printf("DATA%d %x\r\n",i,LPC_I2C1->I2STAT);
            //stop
            LPC_I2C1->I2CONSET = 0x10;
            return -1;
        }
    }

    //stop
    LPC_I2C1->I2CONSET = 0x10;

    //reset si
    LPC_I2C1->I2CONCLR = 0x08;

    return 0;
}


int I2CR::read(int address, char* data, int length) {

    //MASTER RECEIVER

    //send start condition
    LPC_I2C1->I2CONSET = 0x20;

    //block until interrupt
    while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

    //i2stat should be 0x08. could check
    if (LPC_I2C1->I2STAT != 0x08) {
        printf("RSTART %x\r\n",LPC_I2C1->I2STAT);
        //stop if failed
        LPC_I2C1->I2CONSET = 0x10;
        return -1;
    }

    //clear start condition
    LPC_I2C1->I2CONCLR = 0x20;

    //load i2dat with read bit set
    LPC_I2C1->I2DAT = address | 0x1;

    //reset si
    LPC_I2C1->I2CONCLR = 0x08;

    //block until interrupt
    while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

    //i2stat should be 0x40 - ack received
    if (LPC_I2C1->I2STAT != 0x40) {
        printf("RADD %x\r\n",LPC_I2C1->I2STAT);
        //stop
        LPC_I2C1->I2CONSET = 0x10;
        return -1;
    }

    for (int i=0; i<length-1; i++) {

        //ack next byte
        LPC_I2C1->I2CONSET = 0x4;

        //reset si
        LPC_I2C1->I2CONCLR = 0x08;

        //block until interrupt
        while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

        //i2stat should be 0x50, byte received, ack sent
        if (LPC_I2C1->I2STAT != 0x50) {
            printf("rDATA%d %x\r\n",i,LPC_I2C1->I2STAT);
            //stop
            LPC_I2C1->I2CONSET = 0x10;
            return -1;
        }

        data[i] = LPC_I2C1->I2DAT;
    }

    //last byte
    //nack next byte
    LPC_I2C1->I2CONCLR = 0x4;

    //reset si
    LPC_I2C1->I2CONCLR = 0x08;

    //block until interrupt
    while ((LPC_I2C1->I2CONSET & 0x8) != 0x8) {}

    //i2stat should be 0x58, byte received, nack sent
    if (LPC_I2C1->I2STAT != 0x58) {
        printf("lastd %x\r\n",LPC_I2C1->I2STAT);
        //stop
        LPC_I2C1->I2CONSET = 0x10;
        return -1;
    }

    data[length-1] = LPC_I2C1->I2DAT;

    //stop
    LPC_I2C1->I2CONSET = 0x10;

    //reset si
    LPC_I2C1->I2CONCLR = 0x08;

    return 0;

}