Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-RtosI2cDriver by
I2CDriver.cpp
00001 #include "I2CDriver.h" 00002 #include "i2cRtos_api.h" 00003 //#include "rt_System.h" 00004 #include "error.h" 00005 00006 using namespace mbed; 00007 using namespace rtos; 00008 00009 //DigitalOut I2CDriver::osci2(p7); 00010 00011 #define PREFIX i2cRtos 00012 //#define PREFIX i2c // fallback to offical busy wait i2c c-api for performance testing 00013 #define PASTER(x,y) x ## _ ## y 00014 #define EVALUATOR(x,y) PASTER(x,y) 00015 #define FUNCTION(fun) EVALUATOR(PREFIX, fun) 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 I2CDriver::I2CDriver(PinName sda, PinName scl, int hz, int slaveAdr):m_freq(hz),m_slaveAdr(slaveAdr) 00023 { 00024 // ensure exclusive access for initialization 00025 static Mutex mtx; 00026 bool locked = false; 00027 if(osKernelRunning()) { // but don't try to lock if rtos kernel is not running yet. (global/static definition) 00028 mtx.lock(); 00029 locked = true; 00030 } 00031 00032 // check pins and determine i2c channel 00033 int channel=0; 00034 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368) 00035 if(sda==c_sdas[0] && scl==c_scls[0]) channel=0; // I2C_1 00036 else 00037 #endif 00038 if (sda==c_sdas[1] && scl==c_scls[1]) channel=1; //I2C_2 or I2C 00039 else error("I2CDriver: Invalid I2C pins selected\n"); 00040 00041 // initialize the selected i2c channel 00042 if(s_channels[channel]==0) { 00043 s_channels[channel] = new I2CDriver::Channel; 00044 m_channel = s_channels[channel]; 00045 m_channel->freq = 0; 00046 m_channel->slaveAdr = 0; 00047 m_channel->modeSlave = 0; 00048 m_channel->initialized=false; // defer i2c initialization util we are sure the rtos kernel is running (config() function) 00049 } 00050 m_channel = s_channels[channel]; 00051 if(locked) mtx.unlock(); 00052 } 00053 00054 void I2CDriver::lock() 00055 { 00056 //osci2.write(1); 00057 // One and the same thread can lock twice, but then it needs also to unlock twice. 00058 // exactly what we need here 00059 m_channel->mutex.lock(osWaitForever); 00060 m_channel->callerID = osThreadGetId(); 00061 m_channel->callerPrio = osThreadGetPriority(m_channel->callerID); 00062 // maximize thread prio 00063 osThreadSetPriority(m_channel->callerID, c_drvPrio); // hopefully not interrupted since the lock in the line above 00064 // mutex code looks like that waiting threads are priority ordered 00065 // also priority inheritance seems to be provided 00066 //osci2.write(0); 00067 } 00068 00069 void I2CDriver::unlock() 00070 { 00071 //osci2.write(1); 00072 // free the mutex and restore original prio 00073 //rt_tsk_lock(); // just prevent beeing preempted after restoring prio before freeing the mutex 00074 osThreadSetPriority(m_channel->callerID, m_channel->callerPrio); 00075 m_channel->mutex.unlock(); 00076 //rt_tsk_unlock(); 00077 //osci2.write(0); 00078 } 00079 00080 void I2CDriver::config() 00081 { 00082 //osci2.write(1); 00083 // check and initialize driver 00084 if(!m_channel->initialized) { 00085 int channel = m_channel==s_channels[0] ? 0 : 1; // ...ugly 00086 FUNCTION(init)(&m_channel->i2c, c_sdas[channel], c_scls[channel]); 00087 m_channel->initialized=true; 00088 } 00089 // check and update frequency 00090 if(m_freq != m_channel->freq) { 00091 m_channel->freq = m_freq; 00092 i2c_frequency(&m_channel->i2c, m_freq); 00093 } 00094 // check and update slave/master mode 00095 if(m_modeSlave != m_channel->modeSlave) { 00096 m_channel->modeSlave = m_modeSlave; 00097 i2c_slave_mode(&m_channel->i2c, m_modeSlave); 00098 } 00099 // check and update slave address 00100 if(m_modeSlave && m_slaveAdr != m_channel->slaveAdr) { 00101 m_channel->slaveAdr = m_slaveAdr; 00102 i2c_slave_address(&m_channel->i2c, 0, m_slaveAdr, 0); 00103 } 00104 //osci2.write(0); 00105 } 00106 00107 int I2CDriver::readMaster(int address, char *data, int length, bool repeated) 00108 { 00109 m_modeSlave = false; 00110 lockNconfig(); 00111 int ret = FUNCTION(read)(&m_channel->i2c, address, data, length, (repeated?0:1)); 00112 unlock(); 00113 return ret; 00114 } 00115 int I2CDriver::readMaster(int address, uint8_t _register, char *data, int length, bool repeated) 00116 { 00117 m_modeSlave = false; 00118 lockNconfig(); 00119 int ret = FUNCTION(write)(&m_channel->i2c, address,(const char*)&_register, 1, 0); 00120 if(!ret) ret = FUNCTION(read)(&m_channel->i2c, address, data, length, (repeated?0:1)); 00121 unlock(); 00122 return ret; 00123 } 00124 int I2CDriver::readMaster(int ack) 00125 { 00126 m_modeSlave = false; 00127 lockNconfig(); 00128 int ret = i2cRtos_byte_read(&m_channel->i2c, (ack?0:1)); 00129 unlock(); 00130 return ret; 00131 } 00132 int I2CDriver::writeMaster(int address, const char *data, int length, bool repeated) 00133 { 00134 m_modeSlave = false; 00135 lockNconfig(); 00136 int ret = FUNCTION(write)(&m_channel->i2c, address, data, length, (repeated?0:1)); 00137 unlock(); 00138 return ret; 00139 } 00140 int I2CDriver::writeMaster(int data) 00141 { 00142 m_modeSlave = false; 00143 lockNconfig(); 00144 int ret = i2cRtos_byte_write(&m_channel->i2c, data); 00145 unlock(); 00146 return ret; 00147 } 00148 void I2CDriver::startMaster(void) 00149 { 00150 m_modeSlave = false; 00151 lockNconfig(); 00152 i2c_start(&m_channel->i2c); 00153 unlock(); 00154 } 00155 bool I2CDriver::stopMaster(void) 00156 { 00157 m_modeSlave = false; 00158 lockNconfig(); 00159 bool ret=i2cRtos_stop(&m_channel->i2c); 00160 unlock(); 00161 return ret; 00162 } 00163 void I2CDriver::stopSlave(void) 00164 { 00165 m_modeSlave = true; 00166 lockNconfig(); 00167 i2c_stop(&m_channel->i2c); 00168 unlock(); 00169 } 00170 int I2CDriver::receiveSlave(uint32_t timeout_ms) 00171 { 00172 m_modeSlave = true; 00173 lockNconfig(); 00174 int ret = i2cRtos_slave_receive(&m_channel->i2c, timeout_ms); 00175 unlock(); 00176 return ret; 00177 } 00178 int I2CDriver::readSlave(char* data, int length) 00179 { 00180 m_modeSlave = true; 00181 lockNconfig(); 00182 int ret = i2cRtos_slave_read(&m_channel->i2c, data, length); 00183 unlock(); 00184 return ret; 00185 } 00186 int I2CDriver::readSlave(void) 00187 { 00188 m_modeSlave = true; 00189 lockNconfig(); 00190 int ret = i2cRtos_byte_read(&m_channel->i2c, 0); 00191 unlock(); 00192 return ret; 00193 } 00194 int I2CDriver::writeSlave(const char *data, int length) 00195 { 00196 m_modeSlave = true; 00197 lockNconfig(); 00198 int ret = i2cRtos_slave_write(&m_channel->i2c, data, length); 00199 unlock(); 00200 return ret; 00201 } 00202 int I2CDriver::writeSlave(int data) 00203 { 00204 m_modeSlave = true; 00205 lockNconfig(); 00206 int ret = i2cRtos_byte_write(&m_channel->i2c, data); 00207 unlock(); 00208 return ret; 00209 } 00210 00211 00212 00213
Generated on Wed Jul 13 2022 17:20:05 by
1.7.2
