I2CRTOS Driver by Helmut Schmücker. Removed included mbed-rtos library to prevent multiple definition. Make sure to include mbed-rtos library in your program!

Fork of I2cRtosDriver by Helmut Schmücker

Committer:
pHysiX
Date:
Sat May 17 11:56:46 2014 +0000
Revision:
16:2c6432b37cce
Parent:
14:352609d395c1
Modified to make 400kHz default

Who changed what in which revision?

UserRevisionLine numberNew contents of line
humlet 0:13c962fecb13 1 #ifndef I2CDRIVER_H
humlet 0:13c962fecb13 2 #define I2CDRIVER_H
humlet 0:13c962fecb13 3
humlet 0:13c962fecb13 4 #include "stdint.h"
humlet 14:352609d395c1 5 #include "I2C.h"
humlet 14:352609d395c1 6 #include "Mutex.h"
humlet 0:13c962fecb13 7
humlet 14:352609d395c1 8 #include "DigitalOut.h"
humlet 0:13c962fecb13 9
humlet 0:13c962fecb13 10
humlet 0:13c962fecb13 11 namespace mbed
humlet 0:13c962fecb13 12 {
humlet 5:8a418c89e515 13 /// I2C driver based on mbed RTOS and I2C-C-API.
humlet 5:8a418c89e515 14 /// Supports Master and Slave mode
humlet 3:967dde37e712 15 class I2CDriver
humlet 0:13c962fecb13 16 {
humlet 0:13c962fecb13 17 public:
humlet 14:352609d395c1 18 //static DigitalOut osci2;
humlet 5:8a418c89e515 19 /// Status returned by the receiveSlave() function
humlet 3:967dde37e712 20 enum SlaveRxStatus {
humlet 3:967dde37e712 21 NoData = 0,
humlet 3:967dde37e712 22 ReadAddressed = 1,
humlet 3:967dde37e712 23 WriteGeneral = 2,
humlet 3:967dde37e712 24 WriteAddressed = 3
humlet 3:967dde37e712 25 };
humlet 0:13c962fecb13 26
humlet 5:8a418c89e515 27 /** Create an I2C Master interface, connected to the specified pins.
humlet 0:13c962fecb13 28 *
humlet 0:13c962fecb13 29 * @param sda I2C data line pin
humlet 0:13c962fecb13 30 * @param scl I2C clock line pin
humlet 5:8a418c89e515 31 *
humlet 5:8a418c89e515 32 * @note Has to be created in a thread context, i.e. within the main or some other function. A global delaration does not work
humlet 0:13c962fecb13 33 */
humlet 3:967dde37e712 34 I2CDriver(PinName sda, PinName scl, int hz=100000, int slaveAdr=0);
humlet 3:967dde37e712 35
humlet 3:967dde37e712 36 /** Set the frequency of the I2C interface
humlet 3:967dde37e712 37 *
humlet 3:967dde37e712 38 * @param hz The bus frequency in hertz
humlet 3:967dde37e712 39 */
humlet 3:967dde37e712 40 void frequency(int hz) {
humlet 3:967dde37e712 41 m_freq = hz;
humlet 3:967dde37e712 42 }
humlet 0:13c962fecb13 43
humlet 0:13c962fecb13 44 /** Read from an I2C slave
humlet 0:13c962fecb13 45 *
humlet 0:13c962fecb13 46 * Performs a complete read transaction. The bottom bit of
humlet 0:13c962fecb13 47 * the address is forced to 1 to indicate a read.
humlet 0:13c962fecb13 48 *
humlet 0:13c962fecb13 49 * @param address 8-bit I2C slave address [ addr | 1 ]
humlet 0:13c962fecb13 50 * @param data Pointer to the byte-array to read data in to
humlet 0:13c962fecb13 51 * @param length Number of bytes to read
humlet 0:13c962fecb13 52 * @param repeated Repeated start, true - don't send stop at end
humlet 0:13c962fecb13 53 *
humlet 0:13c962fecb13 54 * @returns
humlet 0:13c962fecb13 55 * 0 on success (ack),
humlet 0:13c962fecb13 56 * non-0 on failure (nack)
humlet 0:13c962fecb13 57 */
humlet 7:04824382eafb 58 int readMaster(int address, char* data, int length, bool repeated = false);
humlet 0:13c962fecb13 59
humlet 3:967dde37e712 60 /** Read from a given I2C slave register
humlet 3:967dde37e712 61 *
humlet 3:967dde37e712 62 * Performs a complete write-register-read-data-transaction. The bottom bit of
humlet 3:967dde37e712 63 * the address is forced to 1 to indicate a read.
humlet 3:967dde37e712 64 *
humlet 3:967dde37e712 65 * @param address 8-bit I2C slave address [ addr | 1 ]
humlet 3:967dde37e712 66 * @param _register 8-bit regster address
humlet 3:967dde37e712 67 * @param data Pointer to the byte-array to read data in to
humlet 3:967dde37e712 68 * @param length Number of bytes to read
humlet 3:967dde37e712 69 * @param repeated Repeated start, true - don't send stop at end
humlet 3:967dde37e712 70 *
humlet 3:967dde37e712 71 * @returns
humlet 3:967dde37e712 72 * 0 on success (ack),
humlet 3:967dde37e712 73 * non-0 on failure (nack)
humlet 3:967dde37e712 74 */
humlet 7:04824382eafb 75 int readMaster(int address, uint8_t _register, char* data, int length, bool repeated = false);
humlet 1:90455d5bdd8c 76
humlet 0:13c962fecb13 77 /** Read a single byte from the I2C bus
humlet 0:13c962fecb13 78 *
humlet 0:13c962fecb13 79 * @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
humlet 0:13c962fecb13 80 *
humlet 0:13c962fecb13 81 * @returns
humlet 0:13c962fecb13 82 * the byte read
humlet 0:13c962fecb13 83 */
humlet 3:967dde37e712 84 int readMaster(int ack=1);
humlet 0:13c962fecb13 85
humlet 0:13c962fecb13 86 /** Write to an I2C slave
humlet 0:13c962fecb13 87 *
humlet 0:13c962fecb13 88 * Performs a complete write transaction. The bottom bit of
humlet 0:13c962fecb13 89 * the address is forced to 0 to indicate a write.
humlet 0:13c962fecb13 90 *
humlet 0:13c962fecb13 91 * @param address 8-bit I2C slave address [ addr | 0 ]
humlet 0:13c962fecb13 92 * @param data Pointer to the byte-array data to send
humlet 0:13c962fecb13 93 * @param length Number of bytes to send
humlet 0:13c962fecb13 94 * @param repeated Repeated start, true - do not send stop at end
humlet 0:13c962fecb13 95 *
humlet 0:13c962fecb13 96 * @returns
humlet 0:13c962fecb13 97 * 0 on success (ack),
humlet 0:13c962fecb13 98 * non-0 on failure (nack)
humlet 0:13c962fecb13 99 */
humlet 3:967dde37e712 100 int writeMaster(int address, const char *data, int length, bool repeated = false);
humlet 0:13c962fecb13 101
humlet 0:13c962fecb13 102 /** Write single byte out on the I2C bus
humlet 0:13c962fecb13 103 *
humlet 0:13c962fecb13 104 * @param data data to write out on bus
humlet 0:13c962fecb13 105 *
humlet 0:13c962fecb13 106 * @returns
humlet 0:13c962fecb13 107 * '1' if an ACK was received,
humlet 0:13c962fecb13 108 * '0' otherwise
humlet 0:13c962fecb13 109 */
humlet 3:967dde37e712 110 int writeMaster(int data);
humlet 3:967dde37e712 111
humlet 3:967dde37e712 112 /** Sets the I2C slave address.
humlet 3:967dde37e712 113 *
humlet 3:967dde37e712 114 * @param address The address to set for the slave (ignoring the least
humlet 3:967dde37e712 115 * signifcant bit). If set to 0, the slave will only respond to the
humlet 3:967dde37e712 116 * general call address.
humlet 3:967dde37e712 117 */
humlet 3:967dde37e712 118 void addressSlave(int address) {
humlet 13:530968937ccb 119 m_slaveAdr=(address & 0xff) | 1;
humlet 3:967dde37e712 120 }
humlet 3:967dde37e712 121
humlet 3:967dde37e712 122 /** Checks to see if this I2C Slave has been addressed.
humlet 3:967dde37e712 123 *
humlet 3:967dde37e712 124 * @returns
humlet 3:967dde37e712 125 * A status indicating if the device has been addressed, and how
humlet 3:967dde37e712 126 * - NoData - the slave has not been addressed
humlet 3:967dde37e712 127 * - ReadAddressed - the master has requested a read from this slave
humlet 3:967dde37e712 128 * - WriteAddressed - the master is writing to this slave
humlet 3:967dde37e712 129 * - WriteGeneral - the master is writing to all slave
humlet 3:967dde37e712 130 */
humlet 3:967dde37e712 131 int receiveSlave(uint32_t timeout_ms=osWaitForever);
humlet 3:967dde37e712 132
humlet 3:967dde37e712 133 /** Read from an I2C master.
humlet 3:967dde37e712 134 *
humlet 3:967dde37e712 135 * @param data pointer to the byte array to read data in to
humlet 3:967dde37e712 136 * @param length maximum number of bytes to read
humlet 3:967dde37e712 137 *
humlet 3:967dde37e712 138 * @returns
humlet 3:967dde37e712 139 * 0 on success,
humlet 3:967dde37e712 140 * non-0 otherwise
humlet 13:530968937ccb 141 * ... no! instead it returns number of bytes read minus one ... weird, guess its a bug in the official lib
humlet 3:967dde37e712 142 */
humlet 3:967dde37e712 143 int readSlave(char *data, int length);
humlet 3:967dde37e712 144
humlet 3:967dde37e712 145 /** Read a single byte from an I2C master.
humlet 3:967dde37e712 146 *
humlet 3:967dde37e712 147 * @returns
humlet 3:967dde37e712 148 * the byte read
humlet 3:967dde37e712 149 */
humlet 3:967dde37e712 150 int readSlave(void);
humlet 3:967dde37e712 151
humlet 3:967dde37e712 152 /** Write to an I2C master.
humlet 3:967dde37e712 153 *
humlet 3:967dde37e712 154 * @param data pointer to the byte array to be transmitted
humlet 3:967dde37e712 155 * @param length the number of bytes to transmite
humlet 3:967dde37e712 156 *
humlet 3:967dde37e712 157 * @returns
humlet 3:967dde37e712 158 * 0 on success,
humlet 14:352609d395c1 159 * non-0 otherwise
humlet 3:967dde37e712 160 */
humlet 3:967dde37e712 161 int writeSlave(const char *data, int length);
humlet 3:967dde37e712 162
humlet 3:967dde37e712 163 /** Write a single byte to an I2C master.
humlet 3:967dde37e712 164 *
humlet 3:967dde37e712 165 * @data the byte to write
humlet 3:967dde37e712 166 *
humlet 3:967dde37e712 167 * @returns
humlet 3:967dde37e712 168 * '1' if an ACK was received,
humlet 3:967dde37e712 169 * '0' otherwise
humlet 3:967dde37e712 170 */
humlet 3:967dde37e712 171 int writeSlave(int data);
humlet 3:967dde37e712 172
humlet 0:13c962fecb13 173
humlet 0:13c962fecb13 174 /// Creates a start condition on the I2C bus
humlet 3:967dde37e712 175 void startMaster(void);
humlet 0:13c962fecb13 176
humlet 0:13c962fecb13 177 ///Creates a stop condition on the I2C bus
humlet 3:967dde37e712 178 void stopSlave(void);
humlet 3:967dde37e712 179
humlet 13:530968937ccb 180 /// Creates a stop condition on the I2C bus
humlet 14:352609d395c1 181 /// If unsccessful because someone on the bus holds the scl line down it returns "false" after 23µs
humlet 14:352609d395c1 182 /// In normal operation the stop shouldn't take longer than 12µs @ 100kHz and 3-4µs @ 400kHz.
humlet 13:530968937ccb 183 bool stopMaster(void);
humlet 3:967dde37e712 184
humlet 0:13c962fecb13 185 /// Wait until the i2c driver becomes available.
humlet 3:967dde37e712 186 ///
humlet 3:967dde37e712 187 /// Useful if you want to run a sequence of command without interrution by another thread.
humlet 3:967dde37e712 188 /// There's no need to call this function for running single request, because all driver functions
humlet 3:967dde37e712 189 /// will lock the device for exclusive access automatically.
humlet 6:5b98c902a659 190 void lock();
humlet 0:13c962fecb13 191
humlet 3:967dde37e712 192 /// Unlock the driver that has previously been locked by the same thread.
humlet 6:5b98c902a659 193 void unlock();
humlet 0:13c962fecb13 194
humlet 0:13c962fecb13 195 protected:
humlet 13:530968937ccb 196 void config();
humlet 13:530968937ccb 197 void lockNconfig() {
humlet 13:530968937ccb 198 lock();
humlet 13:530968937ccb 199 config();
humlet 13:530968937ccb 200 }
humlet 13:530968937ccb 201
humlet 13:530968937ccb 202 // structure that holds I2C channels status
humlet 13:530968937ccb 203 struct Channel {
humlet 13:530968937ccb 204 rtos::Mutex mutex;
humlet 13:530968937ccb 205 i2c_t i2c;
humlet 13:530968937ccb 206 int freq;
humlet 13:530968937ccb 207 int slaveAdr;
humlet 13:530968937ccb 208 bool modeSlave;
humlet 14:352609d395c1 209 bool initialized;
humlet 14:352609d395c1 210 osThreadId callerID;
humlet 14:352609d395c1 211 osPriority callerPrio;
humlet 1:90455d5bdd8c 212 };
humlet 6:5b98c902a659 213
humlet 14:352609d395c1 214 // current i2c configuration of this driver interface
humlet 13:530968937ccb 215 int m_freq;
humlet 13:530968937ccb 216 int m_slaveAdr;
humlet 13:530968937ccb 217 bool m_modeSlave;
humlet 0:13c962fecb13 218
humlet 6:5b98c902a659 219 // i2c driver prio
humlet 6:5b98c902a659 220 static const osPriority c_drvPrio = osPriorityRealtime;
humlet 5:8a418c89e515 221 // the pin names fo the i2c channels
humlet 1:90455d5bdd8c 222 static const PinName c_sdas[2];
humlet 1:90455d5bdd8c 223 static const PinName c_scls[2];
humlet 0:13c962fecb13 224
humlet 6:5b98c902a659 225 // static storage for the I2C channel access objects
humlet 2:514105beb343 226 static Channel* s_channels[2];
humlet 6:5b98c902a659 227
humlet 13:530968937ccb 228 // i2c channel object of this driver interface, in fact just a pointer
humlet 5:8a418c89e515 229 /// to one of the entries in s_channels
humlet 2:514105beb343 230 Channel* m_channel;
humlet 1:90455d5bdd8c 231 };
humlet 0:13c962fecb13 232 }
humlet 0:13c962fecb13 233 #endif