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
Diff: I2CDriver.h
- Revision:
- 3:967dde37e712
- Parent:
- 2:514105beb343
- Child:
- 5:8a418c89e515
diff -r 514105beb343 -r 967dde37e712 I2CDriver.h --- a/I2CDriver.h Sun Apr 14 21:42:22 2013 +0000 +++ b/I2CDriver.h Fri Apr 19 21:33:29 2013 +0000 @@ -6,25 +6,36 @@ #include "I2C.h" #include "Thread.h" -#include "Semaphore.h" #include "Mutex.h" namespace mbed { - -class I2CDriver : protected I2C +/// class i2c driver +class I2CDriver { public: - using I2C::RxStatus; - using I2C::Acknowledge; - using I2C::frequency; + + enum SlaveRxStatus { + NoData = 0, + ReadAddressed = 1, + WriteGeneral = 2, + WriteAddressed = 3 + }; /** Create an I2C Master interface, connected to the specified pins * * @param sda I2C data line pin * @param scl I2C clock line pin */ - I2CDriver(PinName sda, PinName scl); + I2CDriver(PinName sda, PinName scl, int hz=100000, int slaveAdr=0); + + /** Set the frequency of the I2C interface + * + * @param hz The bus frequency in hertz + */ + void frequency(int hz) { + m_freq = hz; + } /** Read from an I2C slave * @@ -40,9 +51,24 @@ * 0 on success (ack), * non-0 on failure (nack) */ - int read(int address, char *data, int length, bool repeated = false); + int readMaster(int address, char *data, int length, bool repeated = false); - int read(int address, uint8_t regist, char *data, int length, bool repeated = false); + /** Read from a given I2C slave register + * + * Performs a complete write-register-read-data-transaction. The bottom bit of + * the address is forced to 1 to indicate a read. + * + * @param address 8-bit I2C slave address [ addr | 1 ] + * @param _register 8-bit regster address + * @param data Pointer to the byte-array to read data in to + * @param length Number of bytes to read + * @param repeated Repeated start, true - don't send stop at end + * + * @returns + * 0 on success (ack), + * non-0 on failure (nack) + */ + int readMaster(int address, uint8_t _register, char *data, int length, bool repeated = false); /** Read a single byte from the I2C bus * @@ -51,7 +77,7 @@ * @returns * the byte read */ - int read(int ack); + int readMaster(int ack=1); /** Write to an I2C slave * @@ -67,7 +93,7 @@ * 0 on success (ack), * non-0 on failure (nack) */ - int write(int address, const char *data, int length, bool repeated = false); + int writeMaster(int address, const char *data, int length, bool repeated = false); /** Write single byte out on the I2C bus * @@ -77,60 +103,136 @@ * '1' if an ACK was received, * '0' otherwise */ - int write(int data); + int writeMaster(int data); + + /** Sets the I2C slave address. + * + * @param address The address to set for the slave (ignoring the least + * signifcant bit). If set to 0, the slave will only respond to the + * general call address. + */ + void addressSlave(int address) { + m_slaveAdr=address; + } + + /** Checks to see if this I2C Slave has been addressed. + * + * @returns + * A status indicating if the device has been addressed, and how + * - NoData - the slave has not been addressed + * - ReadAddressed - the master has requested a read from this slave + * - WriteAddressed - the master is writing to this slave + * - WriteGeneral - the master is writing to all slave + */ + int receiveSlave(uint32_t timeout_ms=osWaitForever); + + /** Read from an I2C master. + * + * @param data pointer to the byte array to read data in to + * @param length maximum number of bytes to read + * + * @returns + * 0 on success, + * non-0 otherwise + */ + int readSlave(char *data, int length); + + /** Read a single byte from an I2C master. + * + * @returns + * the byte read + */ + int readSlave(void); + + /** Write to an I2C master. + * + * @param data pointer to the byte array to be transmitted + * @param length the number of bytes to transmite + * + * @returns + * 0 on success, + * non-0 otherwise + */ + int writeSlave(const char *data, int length); + + /** Write a single byte to an I2C master. + * + * @data the byte to write + * + * @returns + * '1' if an ACK was received, + * '0' otherwise + */ + int writeSlave(int data); + /// Creates a start condition on the I2C bus - void start(void); + void startMaster(void); ///Creates a stop condition on the I2C bus - void stop(void); + void stopSlave(void); + + ///Creates a stop condition on the I2C bus + void stopMaster(void); + + /// Wait until the i2c driver becomes available. + /// + /// Useful if you want to run a sequence of command without interrution by another thread. + /// There's no need to call this function for running single request, because all driver functions + /// will lock the device for exclusive access automatically. void lock() { - // if one and the same thread can lock twice, but then it needs also to unlock twice. + // One and the same thread can lock twice, but then it needs also to unlock twice. // exactly what we need here m_channel->mutex.lock(osWaitForever); } - /// Unlock the driver that has previously been locked by the same thread + /// Unlock the driver that has previously been locked by the same thread. void unlock() { m_channel->mutex.unlock(); } - protected: enum Command { START, STOP, - WRITE_BYTE, - WRITE, + READ_MST, + READ_MST_REG, + READ_SLV, READ_BYTE, - READ, - READ_FROM_REGISTER + WRITE_MST, + WRITE_SLV, + WRITE_BYTE, + RECEIVE }; struct Transfer { - osThreadId caller; Command cmd; + int ret; int freq; int adr; - uint8_t reg; char* dta; const char* wdta; int len; int ack; bool rep; - int ret; + uint8_t reg; + bool slv; + uint32_t tmout; + osThreadId caller; }; struct Channel { - volatile osThreadId driver; + volatile osThreadId driver; // evillive: do we really need that volatile rtos::Mutex mutex; volatile Transfer transfer; - volatile int freq; }; + int m_freq; + int m_slaveAdr; + static const PinName c_sdas[2]; static const PinName c_scls[2]; @@ -143,8 +245,7 @@ static void threadFun(void const *args); - void sendNwait(); - + int sendNwait(); }; } #endif