RTOS enabled i2c-driver based on the official i2c-C-api.

Dependencies:   mbed-rtos

Fork of mbed-RtosI2cDriver by Helmut Schmücker

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers I2CDriver.h Source File

I2CDriver.h

00001 #ifndef I2CDRIVER_H
00002 #define I2CDRIVER_H
00003 
00004 #include "stdint.h"
00005 #include "I2C.h"
00006 #include "Mutex.h"
00007 
00008 #include "DigitalOut.h"
00009 
00010 
00011 namespace mbed
00012 {
00013 /// I2C driver based on mbed RTOS and I2C-C-API.
00014 /// Supports Master and Slave mode
00015 class I2CDriver
00016 {
00017 public:
00018     //static DigitalOut osci2;
00019     /// Status returned by the receiveSlave() function
00020     enum SlaveRxStatus {
00021         NoData         = 0,
00022         ReadAddressed  = 1,
00023         WriteGeneral   = 2,
00024         WriteAddressed = 3
00025     };
00026 
00027     /** Create an I2C Master interface, connected to the specified pins.
00028      *
00029      *  @param sda I2C data line pin
00030      *  @param scl I2C clock line pin
00031      *
00032      *  @note Has to be created in a thread context, i.e. within the main or some other function. A global delaration does not work
00033      */
00034     I2CDriver(PinName sda, PinName scl, int hz=100000, int slaveAdr=0);
00035 
00036     /** Set the frequency of the I2C interface
00037     *
00038     *  @param hz The bus frequency in hertz
00039     */
00040     void frequency(int hz) {
00041         m_freq = hz;
00042     }
00043 
00044     /** Read from an I2C slave
00045      *
00046      * Performs a complete read transaction. The bottom bit of
00047      * the address is forced to 1 to indicate a read.
00048      *
00049      *  @param address 8-bit I2C slave address [ addr | 1 ]
00050      *  @param data Pointer to the byte-array to read data in to
00051      *  @param length Number of bytes to read
00052      *  @param repeated Repeated start, true - don't send stop at end
00053      *
00054      *  @returns
00055      *       0 on success (ack),
00056      *   non-0 on failure (nack)
00057      */
00058     int readMaster(int address, char* data, int length, bool repeated = false);
00059 
00060     /** Read from a given I2C slave register
00061      *
00062      * Performs a complete write-register-read-data-transaction. The bottom bit of
00063      * the address is forced to 1 to indicate a read.
00064      *
00065      *  @param address 8-bit I2C slave address [ addr | 1 ]
00066      *  @param _register 8-bit regster address
00067      *  @param data Pointer to the byte-array to read data in to
00068      *  @param length Number of bytes to read
00069      *  @param repeated Repeated start, true - don't send stop at end
00070      *
00071      *  @returns
00072      *       0 on success (ack),
00073      *   non-0 on failure (nack)
00074      */
00075     int readMaster(int address, uint8_t _register, char* data, int length, bool repeated = false);
00076 
00077     /** Read a single byte from the I2C bus
00078      *
00079      *  @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
00080      *
00081      *  @returns
00082      *    the byte read
00083      */
00084     int readMaster(int ack=1);
00085 
00086     /** Write to an I2C slave
00087      *
00088      * Performs a complete write transaction. The bottom bit of
00089      * the address is forced to 0 to indicate a write.
00090      *
00091      *  @param address 8-bit I2C slave address [ addr | 0 ]
00092      *  @param data Pointer to the byte-array data to send
00093      *  @param length Number of bytes to send
00094      *  @param repeated Repeated start, true - do not send stop at end
00095      *
00096      *  @returns
00097      *       0 on success (ack),
00098      *   non-0 on failure (nack)
00099      */
00100     int writeMaster(int address, const char *data, int length, bool repeated = false);
00101 
00102     /** Write single byte out on the I2C bus
00103      *
00104      *  @param data data to write out on bus
00105      *
00106      *  @returns
00107      *    '1' if an ACK was received,
00108      *    '0' otherwise
00109      */
00110     int writeMaster(int data);
00111 
00112     /** Sets the I2C slave address.
00113      *
00114      *  @param address The address to set for the slave (ignoring the least
00115      *  signifcant bit). If set to 0, the slave will only respond to the
00116      *  general call address.
00117      */
00118     void addressSlave(int address) {
00119         m_slaveAdr=(address & 0xff) | 1;
00120     }
00121 
00122     /** Checks to see if this I2C Slave has been addressed.
00123      *
00124      *  @returns
00125      *  A status indicating if the device has been addressed, and how
00126      *  - NoData            - the slave has not been addressed
00127      *  - ReadAddressed     - the master has requested a read from this slave
00128      *  - WriteAddressed    - the master is writing to this slave
00129      *  - WriteGeneral      - the master is writing to all slave
00130      */
00131     int receiveSlave(uint32_t timeout_ms=osWaitForever);
00132 
00133     /** Read from an I2C master.
00134      *
00135      *  @param data pointer to the byte array to read data in to
00136      *  @param length maximum number of bytes to read
00137      *
00138      *  @returns
00139      *       0 on success,
00140      *   non-0 otherwise
00141      * ... no! instead it returns number of bytes read minus one ... weird, guess its a bug in the official lib
00142      */
00143     int readSlave(char *data, int length);
00144 
00145     /** Read a single byte from an I2C master.
00146     *
00147     *  @returns
00148     *    the byte read
00149     */
00150     int readSlave(void);
00151 
00152     /** Write to an I2C master.
00153      *
00154      *  @param data pointer to the byte array to be transmitted
00155      *  @param length the number of bytes to transmite
00156      *
00157      *  @returns
00158      *       0 on success,
00159      *   non-0 otherwise
00160      */
00161     int writeSlave(const char *data, int length);
00162 
00163     /** Write a single byte to an I2C master.
00164     *
00165     *  @data the byte to write
00166     *
00167     *  @returns
00168     *    '1' if an ACK was received,
00169     *    '0' otherwise
00170     */
00171     int writeSlave(int data);
00172 
00173 
00174     /// Creates a start condition on the I2C bus
00175     void startMaster(void);
00176 
00177     ///Creates a stop condition on the I2C bus
00178     void stopSlave(void);
00179 
00180     /// Creates a stop condition on the I2C bus
00181     /// If unsccessful because someone on the bus holds the scl line down it returns "false" after 23µs
00182     /// In normal operation the stop shouldn't take longer than 12µs @ 100kHz and 3-4µs @ 400kHz.
00183     bool stopMaster(void);
00184 
00185     /// Wait until the i2c driver becomes available.
00186     ///
00187     /// Useful if you want to run a sequence of command without interrution by another thread.
00188     /// There's no need to call this function for running single request, because all driver functions
00189     /// will lock the device for exclusive access automatically.
00190     void lock();
00191 
00192     /// Unlock the driver that has previously been locked by the same thread.
00193     void unlock();
00194 
00195 protected:
00196     void config();
00197     void lockNconfig() {
00198         lock();
00199         config();
00200     }
00201 
00202     // structure that holds I2C channels status
00203     struct Channel {
00204         rtos::Mutex mutex;
00205         i2c_t i2c;
00206         int freq;
00207         int slaveAdr;
00208         bool modeSlave;
00209         bool initialized;
00210         osThreadId callerID;
00211         osPriority callerPrio;
00212     };
00213 
00214     // current i2c configuration of this driver interface
00215     int m_freq;
00216     int m_slaveAdr;
00217     bool m_modeSlave;
00218 
00219     // i2c driver prio
00220     static const osPriority c_drvPrio = osPriorityRealtime;
00221     // the pin names fo the i2c channels
00222     static const PinName c_sdas[2];
00223     static const PinName c_scls[2];
00224 
00225     // static storage for the I2C channel access objects
00226     static Channel* s_channels[2];
00227 
00228     // i2c channel object of this driver interface, in fact just a pointer
00229     /// to one of the entries in s_channels
00230     Channel* m_channel;
00231 };
00232 }
00233 #endif