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
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 }
Generated on Sat Jul 16 2022 11:45:43 by 1.7.2