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.h
00001 #ifndef I2CDRIVER_H 00002 #define I2CDRIVER_H 00003 00004 #include "stdint.h" 00005 00006 #include "I2C.h" 00007 00008 #include "Thread.h" 00009 #include "Mutex.h" 00010 00011 namespace mbed 00012 { 00013 /// I2C driver based on mbed RTOS and I2C-C-API. 00014 /// Supports Master and Slave mode 00015 class I2CDriver 00016 { 00017 public: 00018 /// Status returned by the receiveSlave() function 00019 enum SlaveRxStatus { 00020 NoData = 0, 00021 ReadAddressed = 1, 00022 WriteGeneral = 2, 00023 WriteAddressed = 3 00024 }; 00025 00026 /** Create an I2C Master interface, connected to the specified pins. 00027 * 00028 * @param sda I2C data line pin 00029 * @param scl I2C clock line pin 00030 * 00031 * @note Has to be created in a thread context, i.e. within the main or some other function. A global delaration does not work 00032 */ 00033 I2CDriver(PinName sda, PinName scl, int hz=100000, int slaveAdr=0); 00034 00035 /** Set the frequency of the I2C interface 00036 * 00037 * @param hz The bus frequency in hertz 00038 */ 00039 void frequency(int hz) { 00040 m_freq = hz; 00041 } 00042 00043 /** Read from an I2C slave 00044 * 00045 * Performs a complete read transaction. The bottom bit of 00046 * the address is forced to 1 to indicate a read. 00047 * 00048 * @param address 8-bit I2C slave address [ addr | 1 ] 00049 * @param data Pointer to the byte-array to read data in to 00050 * @param length Number of bytes to read 00051 * @param repeated Repeated start, true - don't send stop at end 00052 * 00053 * @returns 00054 * 0 on success (ack), 00055 * non-0 on failure (nack) 00056 */ 00057 int readMaster(int address, char* data, int length, bool repeated = false); 00058 00059 /** Read from a given I2C slave register 00060 * 00061 * Performs a complete write-register-read-data-transaction. The bottom bit of 00062 * the address is forced to 1 to indicate a read. 00063 * 00064 * @param address 8-bit I2C slave address [ addr | 1 ] 00065 * @param _register 8-bit regster address 00066 * @param data Pointer to the byte-array to read data in to 00067 * @param length Number of bytes to read 00068 * @param repeated Repeated start, true - don't send stop at end 00069 * 00070 * @returns 00071 * 0 on success (ack), 00072 * non-0 on failure (nack) 00073 */ 00074 int readMaster(int address, uint8_t _register, char* data, int length, bool repeated = false); 00075 00076 /** Read a single byte from the I2C bus 00077 * 00078 * @param ack indicates if the byte is to be acknowledged (1 = acknowledge) 00079 * 00080 * @returns 00081 * the byte read 00082 */ 00083 int readMaster(int ack=1); 00084 00085 /** Write to an I2C slave 00086 * 00087 * Performs a complete write transaction. The bottom bit of 00088 * the address is forced to 0 to indicate a write. 00089 * 00090 * @param address 8-bit I2C slave address [ addr | 0 ] 00091 * @param data Pointer to the byte-array data to send 00092 * @param length Number of bytes to send 00093 * @param repeated Repeated start, true - do not send stop at end 00094 * 00095 * @returns 00096 * 0 on success (ack), 00097 * non-0 on failure (nack) 00098 */ 00099 int writeMaster(int address, const char *data, int length, bool repeated = false); 00100 00101 /** Write single byte out on the I2C bus 00102 * 00103 * @param data data to write out on bus 00104 * 00105 * @returns 00106 * '1' if an ACK was received, 00107 * '0' otherwise 00108 */ 00109 int writeMaster(int data); 00110 00111 /** Sets the I2C slave address. 00112 * 00113 * @param address The address to set for the slave (ignoring the least 00114 * signifcant bit). If set to 0, the slave will only respond to the 00115 * general call address. 00116 */ 00117 void addressSlave(int address) { 00118 m_slaveAdr=address; 00119 } 00120 00121 /** Checks to see if this I2C Slave has been addressed. 00122 * 00123 * @returns 00124 * A status indicating if the device has been addressed, and how 00125 * - NoData - the slave has not been addressed 00126 * - ReadAddressed - the master has requested a read from this slave 00127 * - WriteAddressed - the master is writing to this slave 00128 * - WriteGeneral - the master is writing to all slave 00129 */ 00130 int receiveSlave(uint32_t timeout_ms=osWaitForever); 00131 00132 /** Read from an I2C master. 00133 * 00134 * @param data pointer to the byte array to read data in to 00135 * @param length maximum number of bytes to read 00136 * 00137 * @returns 00138 * 0 on success, 00139 * non-0 otherwise 00140 */ 00141 int readSlave(char *data, int length); 00142 00143 /** Read a single byte from an I2C master. 00144 * 00145 * @returns 00146 * the byte read 00147 */ 00148 int readSlave(void); 00149 00150 /** Write to an I2C master. 00151 * 00152 * @param data pointer to the byte array to be transmitted 00153 * @param length the number of bytes to transmite 00154 * 00155 * @returns 00156 * 0 on success, 00157 * non-0 otherwise 00158 */ 00159 int writeSlave(const char *data, int length); 00160 00161 /** Write a single byte to an I2C master. 00162 * 00163 * @data the byte to write 00164 * 00165 * @returns 00166 * '1' if an ACK was received, 00167 * '0' otherwise 00168 */ 00169 int writeSlave(int data); 00170 00171 00172 /// Creates a start condition on the I2C bus 00173 void startMaster(void); 00174 00175 ///Creates a stop condition on the I2C bus 00176 void stopSlave(void); 00177 00178 ///Creates a stop condition on the I2C bus 00179 void stopMaster(void); 00180 00181 /// Wait until the i2c driver becomes available. 00182 /// 00183 /// Useful if you want to run a sequence of command without interrution by another thread. 00184 /// There's no need to call this function for running single request, because all driver functions 00185 /// will lock the device for exclusive access automatically. 00186 void lock(); 00187 00188 /// Unlock the driver that has previously been locked by the same thread. 00189 void unlock(); 00190 00191 protected: 00192 // commands sent from user to drive thread 00193 enum Command { 00194 START, 00195 STOP, 00196 READ_MST, 00197 READ_MST_REG, 00198 READ_SLV, 00199 READ_BYTE, 00200 WRITE_MST, 00201 WRITE_SLV, 00202 WRITE_BYTE, 00203 RECEIVE 00204 }; 00205 00206 // data transfer struct for communication between user and driver thread 00207 struct Transfer { 00208 Command cmd; 00209 int ret; 00210 int freq; 00211 int adr; 00212 char* dta; 00213 const char* wdta; 00214 int len; 00215 int ack; 00216 bool rep; 00217 uint8_t reg; 00218 bool slv; 00219 uint32_t tmout; 00220 osThreadId caller; 00221 }; 00222 00223 // structure that holds handles/locks for accessing the I2C channels 00224 struct Channel { 00225 osThreadId driver; 00226 rtos::Mutex mutex; 00227 volatile Transfer transfer; 00228 }; 00229 00230 // current frequency setting 00231 int m_freq; 00232 // current slave address setting 00233 int m_slaveAdr; 00234 // prio of current caller thread 00235 osPriority m_callerPrio; 00236 // ID of current caller thread 00237 osThreadId m_callerID; 00238 00239 // i2c driver prio 00240 static const osPriority c_drvPrio = osPriorityRealtime; 00241 // the pin names fo the i2c channels 00242 static const PinName c_sdas[2]; 00243 static const PinName c_scls[2]; 00244 00245 // static storage for the I2C channel access objects 00246 static Channel* s_channels[2]; 00247 00248 // i2c channel object of this driver interface, in fact just pointer 00249 /// to one of the entries in s_channels 00250 Channel* m_channel; 00251 00252 // ISRs 00253 static void channel_0_ISR(); 00254 static void channel_1_ISR(); 00255 00256 // the driver thread function 00257 static void threadFun(void const *args); 00258 00259 int sendNwait(); 00260 }; 00261 } 00262 #endif
Generated on Sun Jul 17 2022 01:45:03 by 1.7.2