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 I2cRtosDriver by
I2CDriver.h@13:530968937ccb, 2013-05-10 (annotated)
- 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?
| User | Revision | Line number | New 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 |
