Interrupt based I2C functionality for the LPC1768. (If you want the other one, send a PM and I might make it). Also adds buffer functionality to the I2C bus.

Dependents:   Algoritmo_Fuzzy FlyBed1 FlyBedLight

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MODI2C.cpp Source File

MODI2C.cpp

00001 #include "MODI2C.h"
00002 
00003 MODI2C::I2CBuffer MODI2C::Buffer1 = {0,0};        //Sets the initial buffer empty and count on zero
00004 MODI2C::I2CBuffer MODI2C::Buffer2 = {0,0};        //Sets the initial buffer empty
00005 //int MODI2C::status=0;
00006 int MODI2C::defaultStatus=0;
00007 
00008 
00009 
00010 
00011 MODI2C::MODI2C(PinName sda, PinName scl) : led(LED3) {
00012     //Check which connection we are using, if not correct, go to error status
00013     if ((sda==p9) && (scl==p10))
00014         I2CMODULE = LPC_I2C1;
00015     else if ((sda==p28) && (scl==p27))
00016         I2CMODULE = LPC_I2C2;
00017     else
00018         error("MODI2C pins not valid");
00019 
00020     //Default settings:
00021     frequency(100000);
00022 
00023     writePinState();
00024 }
00025 
00026 int MODI2C::write(int address, char *data, int length, bool repeated, int *status) {
00027 
00028     I2CData Data;
00029     //Store relevant information
00030     address &= 0xFE;
00031     Data.caller = this;
00032     Data.address = address;
00033     Data.repeated = repeated;
00034     Data.data = data;
00035     Data.length = length;
00036     Data.status = status;
00037 
00038     while(!addBuffer(Data, I2CMODULE));
00039 
00040     return 0;
00041 }
00042 
00043 int MODI2C::write(int address, char *data, int length, int *status) {
00044     return write(address, data, length, false, status);
00045     }
00046 
00047 int MODI2C::read_nb(int address, char *data, int length, bool repeated, int *status) {
00048     //Store relevant information
00049     address |= 0x01;
00050 
00051     //isIdle check here
00052     I2CData Data;
00053 
00054 
00055     Data.caller = this;
00056     Data.address = address;
00057     Data.repeated = repeated;
00058     Data.data = data;
00059     Data.length = length;
00060     Data.status = status;
00061 
00062     while(!addBuffer(Data, I2CMODULE));
00063 
00064     return 0;
00065 }
00066 
00067 int MODI2C::read_nb(int address, char *data, int length, int *status) {
00068     return read_nb(address, data, length, false, status);
00069     }
00070 
00071 int MODI2C::read(int address, char *data, int length, bool repeated) {
00072     int stat;
00073     //Store relevant information
00074     address |= 0x01;
00075 
00076     //isIdle check here
00077     I2CData Data;
00078 
00079 
00080     Data.caller = this;
00081     Data.address = address;
00082     Data.repeated = repeated;
00083     Data.data = data;
00084     Data.length = length;
00085     Data.status = &stat;
00086 
00087     while(!addBuffer(Data, I2CMODULE));
00088     
00089     I2CBuffer *Buffer;
00090     if (I2CMODULE == LPC_I2C1) {
00091         Buffer = &Buffer1;
00092     } else {
00093         Buffer = &Buffer2;
00094     }
00095     
00096     while(Buffer->queue!=0)
00097         wait_us(1);
00098     
00099     if (stat==0x58)         //Return zero if ended correctly, otherwise return return code.
00100         return 0;
00101     else
00102         return stat;
00103 }
00104 
00105 
00106 void MODI2C::start( void ) {
00107     _start(I2CMODULE);
00108 }
00109 
00110 void MODI2C::stop( void ) {
00111     _stop(I2CMODULE);
00112 }
00113 
00114 void MODI2C::frequency(int hz) {
00115     //The I2C clock by default runs on quarter of system clock, which is 96MHz
00116     //So to calculate high/low count times, we do 96MHz/4/2/frequency
00117     duty = 96000000/8/hz;
00118     if (duty>65535)
00119         duty=65535;
00120     if (duty<4)
00121         duty=4;
00122 }
00123 
00124 int MODI2C::getQueue( void ) {
00125     I2CBuffer *Buffer;
00126     if (I2CMODULE == LPC_I2C1) {
00127         Buffer = &Buffer1;
00128     } else {
00129         Buffer = &Buffer2;
00130     }
00131     return Buffer->queue;
00132     }
00133 
00134 
00135 
00136 //*******************************************
00137 //***********Internal functions**************
00138 //*******************************************
00139 
00140 
00141 void MODI2C::writeSettings( void ) {
00142     I2CMODULE->I2CONSET = 1<<I2C_ENABLE;     //Enable I2C
00143     I2CMODULE->I2CONCLR = I2C_STOP;
00144     I2CMODULE->MMCTRL = 0;                   //Disable monitor mode
00145     I2CMODULE->I2SCLH = duty;
00146     I2CMODULE->I2SCLL = duty;
00147 
00148 }
00149 
00150 void MODI2C::writePinState( void ) {
00151     if (I2CMODULE == LPC_I2C1) {
00152         LPC_PINCON->PINSEL0 |= 0x0000000F;       //Sets pins as I2C
00153         LPC_PINCON->PINMODE0 |= 0x0000000A;      //Neither pull up nor pull down
00154         LPC_PINCON->PINMODE_OD0 |= 0x00000003;   //Open drain mode enabled
00155     } else if (I2CMODULE == LPC_I2C2) {
00156         LPC_PINCON->PINSEL0 |= (1<<21)|(1<<23); //Same story, different register settings
00157         LPC_PINCON->PINMODE0 |= (1<<21)|(1<<23);
00158         LPC_PINCON->PINMODE_OD0 |= (1<<10)|(1<<11);
00159     }
00160 }
00161 
00162 
00163 
00164 void MODI2C::attach( void (*function)(void), int operation) {
00165     IRQOp = operation;
00166     callback.attach(function);
00167 }
00168 
00169 template<typename T>
00170 void MODI2C::attach(T *object, void (T::*member)(void), int operation) {
00171     IRQOp = operation;
00172     callback.attach(object, member);
00173 }
00174 
00175 void MODI2C::detach( void ) {
00176     callback.attach(NULL);
00177 }
00178 
00179 void MODI2C::_start(LPC_I2C_TypeDef *I2CMODULE) {
00180     if (!(I2CMODULE->I2CONSET & 1<<I2C_START))  //If already sent, skip
00181         I2CMODULE->I2CONSET = 1<<I2C_START;     //Send start condition
00182 }
00183 
00184 void MODI2C::_stop(LPC_I2C_TypeDef *I2CMODULE) {
00185     I2CMODULE->I2CONSET = 1<<I2C_STOP;      //Send stop condition
00186     I2CMODULE->I2CONCLR = 1<<I2C_FLAG;
00187 }
00188 
00189 //Set interrupt vector
00190 void MODI2C::setISR(void) {
00191     _setISR(I2CMODULE);
00192 }
00193 
00194 void MODI2C::_setISR(LPC_I2C_TypeDef *I2CMODULE) {
00195     if (I2CMODULE == LPC_I2C1) {
00196         NVIC_SetVector(I2C1_IRQn, (uint32_t)&IRQ1Handler);
00197         NVIC_EnableIRQ(I2C1_IRQn);
00198     } else if (I2CMODULE == LPC_I2C2) {
00199         NVIC_SetVector(I2C2_IRQn, (uint32_t)&IRQ2Handler);
00200         NVIC_EnableIRQ(I2C2_IRQn);
00201     }
00202 }
00203 
00204 void MODI2C::clearISR( void ) {
00205     _clearISR(I2CMODULE);
00206 }
00207 
00208 void MODI2C::_clearISR( LPC_I2C_TypeDef *I2CMODULE ) {
00209     if (I2CMODULE == LPC_I2C1) {
00210         NVIC_DisableIRQ(I2C1_IRQn);
00211     } else if (I2CMODULE == LPC_I2C2) {
00212         NVIC_DisableIRQ(I2C2_IRQn);
00213     }
00214 }