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.
Revision 0:375ecd0ed73d, committed 2011-05-12
- Comitter:
- ShockSoc
- Date:
- Thu May 12 09:24:27 2011 +0000
- Commit message:
Changed in this revision
I2CR.cpp | Show annotated file Show diff for this revision Revisions of this file |
I2CR.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/I2CR.cpp Thu May 12 09:24:27 2011 +0000 @@ -0,0 +1,184 @@ +#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; + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/I2CR.h Thu May 12 09:24:27 2011 +0000 @@ -0,0 +1,34 @@ +/** +* Author: Rob Hyams +* Date: 12.05.2011 +* This is a beta library for use with I2C1. The standard mbed I2C +* is not currently functioning when using the v29 beta library. +* Therefore, this has been developed as a drop in replacement. +* Code is not particularly robust, but will handle incorrect +* communication by checking states. +* +* Has been developed and tested with ADXL345 accelerometer +*/ + + + +#ifndef I2CR_H +#define I2CR_H + +#include "mbed.h" + +class I2CR { + +public: + //Constructor + I2CR(); + + //Write function + int write(int address, const char* data, int length); + + //Read function + int read(int address, char* data, int length); + +}; + +#endif \ No newline at end of file