Modified version of the official mbed lib providing a RTOS enabled i2c-driver based on the official i2c-C-api.
Dependencies: mbed-rtos mbed-src
I2CDriver.cpp
00001 #include "I2CDriver.h" 00002 #include "i2c_api.h" 00003 #include "error.h" 00004 00005 using namespace mbed; 00006 using namespace rtos; 00007 00008 extern "C"{ 00009 osSemaphoreId i2cIsrDrvSem_1; 00010 osSemaphoreDef(i2cIsrDrvSem_1); 00011 osSemaphoreId i2cIsrDrvSem_2; 00012 osSemaphoreDef(i2cIsrDrvSem_2); 00013 } 00014 00015 #define DRV_USR_SIG (1<<6) 00016 00017 const PinName I2CDriver::c_sdas[] = {p9,p28}; 00018 const PinName I2CDriver::c_scls[] = {p10,p27}; 00019 00020 I2CDriver::Channel* I2CDriver::s_channels[2] = {0,0}; 00021 00022 #if defined(TARGET_LPC1768) 00023 void I2CDriver::channel_0_ISR() 00024 { 00025 osSemaphoreRelease(i2cIsrDrvSem_1); 00026 NVIC_DisableIRQ(I2C1_IRQn); 00027 } 00028 #endif 00029 00030 void I2CDriver::channel_1_ISR() 00031 { 00032 osSemaphoreRelease(i2cIsrDrvSem_2); 00033 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) 00034 NVIC_DisableIRQ(I2C2_IRQn); 00035 #elif defined(TARGET_LPC11U24) 00036 NVIC_DisableIRQ(I2C_IRQn); 00037 #endif 00038 } 00039 00040 00041 I2CDriver::I2CDriver(PinName sda, PinName scl, int hz, int slaveAdr):m_freq(hz),m_slaveAdr(slaveAdr) 00042 { 00043 // check pins and determine i2c channel 00044 int channel=0; 00045 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) 00046 if(sda==c_sdas[0] && scl==c_scls[0]) channel=0; // I2C_1 00047 else 00048 #endif 00049 if (sda==c_sdas[1] && scl==c_scls[1]) channel=1; //I2C_2 or I2C 00050 else error("I2CDriver: Invalid I2C pinns selected"); 00051 00052 if(s_channels[channel]==0){ 00053 new Thread(threadFun,(void *)channel,osPriorityRealtime,256); 00054 if(channel==0){ 00055 i2cIsrDrvSem_1 = osSemaphoreCreate(osSemaphore(i2cIsrDrvSem_1), 1); 00056 osSemaphoreWait(i2cIsrDrvSem_1,osWaitForever); 00057 }else{ 00058 i2cIsrDrvSem_2 = osSemaphoreCreate(osSemaphore(i2cIsrDrvSem_2), 1); 00059 osSemaphoreWait(i2cIsrDrvSem_2,osWaitForever); 00060 } 00061 } 00062 m_channel = s_channels[channel]; 00063 } 00064 00065 00066 void I2CDriver::threadFun(void const *args) 00067 { 00068 int channelIdx = (int)args; 00069 Channel channel; 00070 s_channels[channelIdx] = &channel; 00071 channel.driver = Thread::gettid(); 00072 00073 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) 00074 if(channelIdx==0)NVIC_SetVector(I2C1_IRQn, (uint32_t)I2CDriver::channel_0_ISR); 00075 if(channelIdx==1)NVIC_SetVector(I2C2_IRQn, (uint32_t)I2CDriver::channel_1_ISR); 00076 #elif defined(TARGET_LPC11U24) 00077 NVIC_SetVector(I2C_IRQn, (uint32_t)I2CDriver::channel_1_ISR); 00078 #endif 00079 00080 int freq = 0; 00081 int adrSlave = 0; 00082 int modeSlave = 0; 00083 i2c_t i2c; 00084 i2c_init(&i2c, c_sdas[channelIdx], c_scls[channelIdx]); 00085 00086 volatile Transfer& tr = channel.transfer; 00087 while(1) { 00088 // wait for requests 00089 osSignalWait(DRV_USR_SIG,osWaitForever); 00090 00091 // check and adapt frequency 00092 if(freq != tr.freq) { 00093 freq = tr.freq; 00094 i2c_frequency(&i2c, tr.freq); 00095 } 00096 00097 // check and adapt slave/master mode 00098 if(modeSlave != tr.slv) { 00099 modeSlave = tr.slv; 00100 i2c_slave_mode(&i2c, tr.slv); 00101 } 00102 00103 // check and adapt slave address 00104 int adr = (tr.adr & 0xFF) | 1; 00105 if(tr.slv && adrSlave != adr) { 00106 adrSlave = adr; 00107 i2c_slave_address(&i2c, 0, adr, 0); 00108 } 00109 00110 // just doit 00111 switch(tr.cmd) { 00112 case START: 00113 i2c_start(&i2c); 00114 break; 00115 case STOP: 00116 i2c_stop(&i2c); 00117 break; 00118 case READ_MST: 00119 tr.ret = i2c_read(&i2c, tr.adr, tr.dta, tr.len, (tr.rep?0:1)); 00120 break; 00121 case READ_MST_REG: 00122 //printf("Disco\n"); 00123 tr.ret = i2c_write(&i2c, tr.adr,(const char*)&(tr.reg), 1, 0); 00124 if(tr.ret)break; // error => bail out 00125 tr.ret = i2c_read(&i2c, tr.adr, tr.dta, tr.len, (tr.rep?0:1)); 00126 break; 00127 case READ_SLV: 00128 tr.ret = i2c_slave_read(&i2c, tr.dta, tr.len); 00129 break; 00130 case READ_BYTE: 00131 tr.ret = i2c_byte_read(&i2c, (tr.ack?0:1)); 00132 break; 00133 case WRITE_MST: 00134 tr.ret = i2c_write(&i2c, tr.adr, tr.wdta, tr.len, (tr.rep?0:1)); 00135 break; 00136 case WRITE_SLV: 00137 tr.ret = i2c_slave_write(&i2c, tr.wdta, tr.len); 00138 break; 00139 case WRITE_BYTE: 00140 tr.ret = i2c_byte_write(&i2c, tr.ack); 00141 break; 00142 case RECEIVE: 00143 tr.ret = i2c_slave_receive_rtos(&i2c, tr.tmout); 00144 break; 00145 default: 00146 error("call 911\n"); 00147 } 00148 // inform the caller 00149 osSignalSet( channel.transfer.caller, DRV_USR_SIG); 00150 } 00151 } 00152 00153 void I2CDriver::lock() 00154 { 00155 // One and the same thread can lock twice, but then it needs also to unlock twice. 00156 // exactly what we need here 00157 m_callerID = osThreadGetId(); 00158 m_callerPrio = osThreadGetPriority(m_callerID); 00159 m_channel->mutex.lock(osWaitForever); 00160 osThreadSetPriority(m_callerID, c_drvPrio); // hopefully not interrupted since the lock 00161 } 00162 00163 void I2CDriver::unlock() 00164 { 00165 // free the mtex and restore original prio 00166 m_channel->mutex.unlock(); 00167 osThreadSetPriority(m_callerID, m_callerPrio); 00168 } 00169 00170 int I2CDriver::sendNwait() 00171 { 00172 m_channel->transfer.freq = m_freq; 00173 m_channel->transfer.caller = Thread::gettid(); 00174 osSignalSet( m_channel->driver, DRV_USR_SIG); 00175 osSignalWait(DRV_USR_SIG,osWaitForever); 00176 int ret = m_channel->transfer.ret; 00177 unlock(); 00178 return ret; 00179 } 00180 00181 int I2CDriver::readMaster(int address, char *data, int length, bool repeated) 00182 { 00183 lock(); 00184 m_channel->transfer.cmd = READ_MST; 00185 m_channel->transfer.slv = false; 00186 m_channel->transfer.adr = address; 00187 m_channel->transfer.dta = data; 00188 m_channel->transfer.len = length; 00189 m_channel->transfer.rep = repeated; 00190 return sendNwait(); 00191 } 00192 00193 int I2CDriver::readMaster(int address, uint8_t _register, char *data, int length, bool repeated) 00194 { 00195 lock(); 00196 m_channel->transfer.cmd = READ_MST_REG; 00197 m_channel->transfer.slv = false; 00198 m_channel->transfer.adr = address; 00199 m_channel->transfer.reg = _register; 00200 m_channel->transfer.dta = data; 00201 m_channel->transfer.len = length; 00202 m_channel->transfer.rep = repeated; 00203 return sendNwait(); 00204 } 00205 00206 int I2CDriver::readMaster(int ack) 00207 { 00208 lock(); 00209 m_channel->transfer.cmd = READ_BYTE; 00210 m_channel->transfer.slv = false; 00211 m_channel->transfer.ack = ack; 00212 return sendNwait(); 00213 } 00214 00215 int I2CDriver::writeMaster(int address, const char *data, int length, bool repeated) 00216 { 00217 lock(); 00218 m_channel->transfer.cmd = WRITE_MST; 00219 m_channel->transfer.slv = false; 00220 m_channel->transfer.adr = address; 00221 m_channel->transfer.wdta = data; 00222 m_channel->transfer.len = length; 00223 m_channel->transfer.rep = repeated; 00224 return sendNwait(); 00225 } 00226 00227 int I2CDriver::writeMaster(int data) 00228 { 00229 lock(); 00230 m_channel->transfer.cmd = WRITE_BYTE; 00231 m_channel->transfer.slv = false; 00232 m_channel->transfer.ack = data; 00233 return sendNwait(); 00234 } 00235 00236 void I2CDriver::startMaster(void) 00237 { 00238 lock(); 00239 m_channel->transfer.cmd = START; 00240 m_channel->transfer.slv = false; 00241 sendNwait(); 00242 } 00243 00244 void I2CDriver::stopMaster(void) 00245 { 00246 lock(); 00247 m_channel->transfer.cmd = STOP; 00248 m_channel->transfer.slv = false; 00249 sendNwait(); 00250 } 00251 00252 void I2CDriver::stopSlave(void) 00253 { 00254 lock(); 00255 m_channel->transfer.cmd = STOP; 00256 m_channel->transfer.slv = true; 00257 m_channel->transfer.adr = m_slaveAdr; 00258 sendNwait(); 00259 } 00260 00261 int I2CDriver::receiveSlave(uint32_t timeout_ms) 00262 { 00263 lock(); 00264 m_channel->transfer.cmd = RECEIVE; 00265 m_channel->transfer.slv = true; 00266 m_channel->transfer.adr = m_slaveAdr; 00267 m_channel->transfer.tmout = timeout_ms; 00268 return sendNwait(); 00269 } 00270 00271 int I2CDriver::readSlave(char* data, int length) 00272 { 00273 lock(); 00274 m_channel->transfer.cmd = READ_SLV; 00275 m_channel->transfer.slv = true; 00276 m_channel->transfer.adr = m_slaveAdr; 00277 m_channel->transfer.dta = data; 00278 m_channel->transfer.len = length; 00279 return sendNwait(); 00280 } 00281 00282 int I2CDriver::readSlave(void) 00283 { 00284 lock(); 00285 m_channel->transfer.cmd = READ_BYTE; 00286 m_channel->transfer.slv = true; 00287 m_channel->transfer.adr = m_slaveAdr; 00288 m_channel->transfer.ack = 1; 00289 return sendNwait(); 00290 } 00291 00292 int I2CDriver::writeSlave(const char *data, int length) 00293 { 00294 lock(); 00295 m_channel->transfer.cmd = WRITE_SLV; 00296 m_channel->transfer.slv = true; 00297 m_channel->transfer.adr = m_slaveAdr; 00298 m_channel->transfer.wdta = data; 00299 m_channel->transfer.len = length; 00300 return sendNwait(); 00301 } 00302 00303 int I2CDriver::writeSlave(int data) 00304 { 00305 lock(); 00306 m_channel->transfer.cmd = WRITE_BYTE; 00307 m_channel->transfer.slv = true; 00308 m_channel->transfer.adr = m_slaveAdr; 00309 m_channel->transfer.ack = data; 00310 return sendNwait(); 00311 } 00312 00313 00314 00315
Generated on Sun Jul 17 2022 01:45:03 by 1.7.2