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:
Sat May 04 16:47:56 2013 +0000
Revision:
9:65aae53a34de
Parent:
7:04824382eafb
Child:
13:530968937ccb
at least it compiles

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 "Thread.h"
humlet 0:13c962fecb13 9 #include "Mutex.h"
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 5:8a418c89e515 18 /// Status returned by the receiveSlave() function
humlet 3:967dde37e712 19 enum SlaveRxStatus {
humlet 3:967dde37e712 20 NoData = 0,
humlet 3:967dde37e712 21 ReadAddressed = 1,
humlet 3:967dde37e712 22 WriteGeneral = 2,
humlet 3:967dde37e712 23 WriteAddressed = 3
humlet 3:967dde37e712 24 };
humlet 0:13c962fecb13 25
humlet 5:8a418c89e515 26 /** Create an I2C Master interface, connected to the specified pins.
humlet 0:13c962fecb13 27 *
humlet 0:13c962fecb13 28 * @param sda I2C data line pin
humlet 0:13c962fecb13 29 * @param scl I2C clock line pin
humlet 5:8a418c89e515 30 *
humlet 5:8a418c89e515 31 * @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 32 */
humlet 3:967dde37e712 33 I2CDriver(PinName sda, PinName scl, int hz=100000, int slaveAdr=0);
humlet 3:967dde37e712 34
humlet 3:967dde37e712 35 /** Set the frequency of the I2C interface
humlet 3:967dde37e712 36 *
humlet 3:967dde37e712 37 * @param hz The bus frequency in hertz
humlet 3:967dde37e712 38 */
humlet 3:967dde37e712 39 void frequency(int hz) {
humlet 3:967dde37e712 40 m_freq = hz;
humlet 3:967dde37e712 41 }
humlet 0:13c962fecb13 42
humlet 0:13c962fecb13 43 /** Read from an I2C slave
humlet 0:13c962fecb13 44 *
humlet 0:13c962fecb13 45 * Performs a complete read transaction. The bottom bit of
humlet 0:13c962fecb13 46 * the address is forced to 1 to indicate a read.
humlet 0:13c962fecb13 47 *
humlet 0:13c962fecb13 48 * @param address 8-bit I2C slave address [ addr | 1 ]
humlet 0:13c962fecb13 49 * @param data Pointer to the byte-array to read data in to
humlet 0:13c962fecb13 50 * @param length Number of bytes to read
humlet 0:13c962fecb13 51 * @param repeated Repeated start, true - don't send stop at end
humlet 0:13c962fecb13 52 *
humlet 0:13c962fecb13 53 * @returns
humlet 0:13c962fecb13 54 * 0 on success (ack),
humlet 0:13c962fecb13 55 * non-0 on failure (nack)
humlet 0:13c962fecb13 56 */
humlet 7:04824382eafb 57 int readMaster(int address, char* data, int length, bool repeated = false);
humlet 0:13c962fecb13 58
humlet 3:967dde37e712 59 /** Read from a given I2C slave register
humlet 3:967dde37e712 60 *
humlet 3:967dde37e712 61 * Performs a complete write-register-read-data-transaction. The bottom bit of
humlet 3:967dde37e712 62 * the address is forced to 1 to indicate a read.
humlet 3:967dde37e712 63 *
humlet 3:967dde37e712 64 * @param address 8-bit I2C slave address [ addr | 1 ]
humlet 3:967dde37e712 65 * @param _register 8-bit regster address
humlet 3:967dde37e712 66 * @param data Pointer to the byte-array to read data in to
humlet 3:967dde37e712 67 * @param length Number of bytes to read
humlet 3:967dde37e712 68 * @param repeated Repeated start, true - don't send stop at end
humlet 3:967dde37e712 69 *
humlet 3:967dde37e712 70 * @returns
humlet 3:967dde37e712 71 * 0 on success (ack),
humlet 3:967dde37e712 72 * non-0 on failure (nack)
humlet 3:967dde37e712 73 */
humlet 7:04824382eafb 74 int readMaster(int address, uint8_t _register, char* data, int length, bool repeated = false);
humlet 1:90455d5bdd8c 75
humlet 0:13c962fecb13 76 /** Read a single byte from the I2C bus
humlet 0:13c962fecb13 77 *
humlet 0:13c962fecb13 78 * @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
humlet 0:13c962fecb13 79 *
humlet 0:13c962fecb13 80 * @returns
humlet 0:13c962fecb13 81 * the byte read
humlet 0:13c962fecb13 82 */
humlet 3:967dde37e712 83 int readMaster(int ack=1);
humlet 0:13c962fecb13 84
humlet 0:13c962fecb13 85 /** Write to an I2C slave
humlet 0:13c962fecb13 86 *
humlet 0:13c962fecb13 87 * Performs a complete write transaction. The bottom bit of
humlet 0:13c962fecb13 88 * the address is forced to 0 to indicate a write.
humlet 0:13c962fecb13 89 *
humlet 0:13c962fecb13 90 * @param address 8-bit I2C slave address [ addr | 0 ]
humlet 0:13c962fecb13 91 * @param data Pointer to the byte-array data to send
humlet 0:13c962fecb13 92 * @param length Number of bytes to send
humlet 0:13c962fecb13 93 * @param repeated Repeated start, true - do not send stop at end
humlet 0:13c962fecb13 94 *
humlet 0:13c962fecb13 95 * @returns
humlet 0:13c962fecb13 96 * 0 on success (ack),
humlet 0:13c962fecb13 97 * non-0 on failure (nack)
humlet 0:13c962fecb13 98 */
humlet 3:967dde37e712 99 int writeMaster(int address, const char *data, int length, bool repeated = false);
humlet 0:13c962fecb13 100
humlet 0:13c962fecb13 101 /** Write single byte out on the I2C bus
humlet 0:13c962fecb13 102 *
humlet 0:13c962fecb13 103 * @param data data to write out on bus
humlet 0:13c962fecb13 104 *
humlet 0:13c962fecb13 105 * @returns
humlet 0:13c962fecb13 106 * '1' if an ACK was received,
humlet 0:13c962fecb13 107 * '0' otherwise
humlet 0:13c962fecb13 108 */
humlet 3:967dde37e712 109 int writeMaster(int data);
humlet 3:967dde37e712 110
humlet 3:967dde37e712 111 /** Sets the I2C slave address.
humlet 3:967dde37e712 112 *
humlet 3:967dde37e712 113 * @param address The address to set for the slave (ignoring the least
humlet 3:967dde37e712 114 * signifcant bit). If set to 0, the slave will only respond to the
humlet 3:967dde37e712 115 * general call address.
humlet 3:967dde37e712 116 */
humlet 3:967dde37e712 117 void addressSlave(int address) {
humlet 3:967dde37e712 118 m_slaveAdr=address;
humlet 3:967dde37e712 119 }
humlet 3:967dde37e712 120
humlet 3:967dde37e712 121 /** Checks to see if this I2C Slave has been addressed.
humlet 3:967dde37e712 122 *
humlet 3:967dde37e712 123 * @returns
humlet 3:967dde37e712 124 * A status indicating if the device has been addressed, and how
humlet 3:967dde37e712 125 * - NoData - the slave has not been addressed
humlet 3:967dde37e712 126 * - ReadAddressed - the master has requested a read from this slave
humlet 3:967dde37e712 127 * - WriteAddressed - the master is writing to this slave
humlet 3:967dde37e712 128 * - WriteGeneral - the master is writing to all slave
humlet 3:967dde37e712 129 */
humlet 3:967dde37e712 130 int receiveSlave(uint32_t timeout_ms=osWaitForever);
humlet 3:967dde37e712 131
humlet 3:967dde37e712 132 /** Read from an I2C master.
humlet 3:967dde37e712 133 *
humlet 3:967dde37e712 134 * @param data pointer to the byte array to read data in to
humlet 3:967dde37e712 135 * @param length maximum number of bytes to read
humlet 3:967dde37e712 136 *
humlet 3:967dde37e712 137 * @returns
humlet 3:967dde37e712 138 * 0 on success,
humlet 3:967dde37e712 139 * non-0 otherwise
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 3:967dde37e712 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 3:967dde37e712 178 ///Creates a stop condition on the I2C bus
humlet 3:967dde37e712 179 void stopMaster(void);
humlet 3:967dde37e712 180
humlet 0:13c962fecb13 181 /// Wait until the i2c driver becomes available.
humlet 3:967dde37e712 182 ///
humlet 3:967dde37e712 183 /// Useful if you want to run a sequence of command without interrution by another thread.
humlet 3:967dde37e712 184 /// There's no need to call this function for running single request, because all driver functions
humlet 3:967dde37e712 185 /// will lock the device for exclusive access automatically.
humlet 6:5b98c902a659 186 void lock();
humlet 0:13c962fecb13 187
humlet 3:967dde37e712 188 /// Unlock the driver that has previously been locked by the same thread.
humlet 6:5b98c902a659 189 void unlock();
humlet 0:13c962fecb13 190
humlet 0:13c962fecb13 191 protected:
humlet 6:5b98c902a659 192 // commands sent from user to drive thread
humlet 0:13c962fecb13 193 enum Command {
humlet 0:13c962fecb13 194 START,
humlet 0:13c962fecb13 195 STOP,
humlet 3:967dde37e712 196 READ_MST,
humlet 3:967dde37e712 197 READ_MST_REG,
humlet 3:967dde37e712 198 READ_SLV,
humlet 0:13c962fecb13 199 READ_BYTE,
humlet 3:967dde37e712 200 WRITE_MST,
humlet 3:967dde37e712 201 WRITE_SLV,
humlet 3:967dde37e712 202 WRITE_BYTE,
humlet 3:967dde37e712 203 RECEIVE
humlet 1:90455d5bdd8c 204 };
humlet 6:5b98c902a659 205
humlet 5:8a418c89e515 206 // data transfer struct for communication between user and driver thread
humlet 0:13c962fecb13 207 struct Transfer {
humlet 0:13c962fecb13 208 Command cmd;
humlet 3:967dde37e712 209 int ret;
humlet 0:13c962fecb13 210 int freq;
humlet 0:13c962fecb13 211 int adr;
humlet 0:13c962fecb13 212 char* dta;
humlet 1:90455d5bdd8c 213 const char* wdta;
humlet 0:13c962fecb13 214 int len;
humlet 1:90455d5bdd8c 215 int ack;
humlet 0:13c962fecb13 216 bool rep;
humlet 3:967dde37e712 217 uint8_t reg;
humlet 3:967dde37e712 218 bool slv;
humlet 3:967dde37e712 219 uint32_t tmout;
humlet 3:967dde37e712 220 osThreadId caller;
humlet 1:90455d5bdd8c 221 };
humlet 0:13c962fecb13 222
humlet 6:5b98c902a659 223 // structure that holds handles/locks for accessing the I2C channels
humlet 0:13c962fecb13 224 struct Channel {
humlet 6:5b98c902a659 225 osThreadId driver;
humlet 1:90455d5bdd8c 226 rtos::Mutex mutex;
humlet 1:90455d5bdd8c 227 volatile Transfer transfer;
humlet 1:90455d5bdd8c 228 };
humlet 6:5b98c902a659 229
humlet 5:8a418c89e515 230 // current frequency setting
humlet 3:967dde37e712 231 int m_freq;
humlet 5:8a418c89e515 232 // current slave address setting
humlet 3:967dde37e712 233 int m_slaveAdr;
humlet 6:5b98c902a659 234 // prio of current caller thread
humlet 6:5b98c902a659 235 osPriority m_callerPrio;
humlet 6:5b98c902a659 236 // ID of current caller thread
humlet 6:5b98c902a659 237 osThreadId m_callerID;
humlet 6:5b98c902a659 238
humlet 6:5b98c902a659 239 // i2c driver prio
humlet 6:5b98c902a659 240 static const osPriority c_drvPrio = osPriorityRealtime;
humlet 5:8a418c89e515 241 // the pin names fo the i2c channels
humlet 1:90455d5bdd8c 242 static const PinName c_sdas[2];
humlet 1:90455d5bdd8c 243 static const PinName c_scls[2];
humlet 0:13c962fecb13 244
humlet 6:5b98c902a659 245 // static storage for the I2C channel access objects
humlet 2:514105beb343 246 static Channel* s_channels[2];
humlet 6:5b98c902a659 247
humlet 5:8a418c89e515 248 // i2c channel object of this driver interface, in fact just pointer
humlet 5:8a418c89e515 249 /// to one of the entries in s_channels
humlet 2:514105beb343 250 Channel* m_channel;
humlet 6:5b98c902a659 251
humlet 5:8a418c89e515 252 // the driver thread function
humlet 1:90455d5bdd8c 253 static void threadFun(void const *args);
humlet 6:5b98c902a659 254
humlet 3:967dde37e712 255 int sendNwait();
humlet 1:90455d5bdd8c 256 };
humlet 0:13c962fecb13 257 }
humlet 0:13c962fecb13 258 #endif