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:
humlet
Date:
Fri May 10 20:38:35 2013 +0000
Revision:
13:530968937ccb
Parent:
9:65aae53a34de
Child:
14:352609d395c1
happyhappyjoyjoy

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