RTOS enabled i2c-driver based on the official i2c-C-api.
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