Modified version of the official mbed lib providing a RTOS enabled i2c-driver based on the official i2c-C-api.

Dependencies:   mbed-rtos mbed-src

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 
00006 #include "I2C.h"
00007 
00008 #include "Thread.h"
00009 #include "Mutex.h"
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     /// Status returned by the receiveSlave() function
00019     enum SlaveRxStatus {
00020         NoData         = 0,
00021         ReadAddressed  = 1,
00022         WriteGeneral   = 2,
00023         WriteAddressed = 3
00024     };
00025 
00026     /** Create an I2C Master interface, connected to the specified pins.
00027      *
00028      *  @param sda I2C data line pin
00029      *  @param scl I2C clock line pin
00030      *
00031      *  @note Has to be created in a thread context, i.e. within the main or some other function. A global delaration does not work
00032      */
00033     I2CDriver(PinName sda, PinName scl, int hz=100000, int slaveAdr=0);
00034 
00035     /** Set the frequency of the I2C interface
00036     *
00037     *  @param hz The bus frequency in hertz
00038     */
00039     void frequency(int hz) {
00040         m_freq = hz;
00041     }
00042 
00043     /** Read from an I2C slave
00044      *
00045      * Performs a complete read transaction. The bottom bit of
00046      * the address is forced to 1 to indicate a read.
00047      *
00048      *  @param address 8-bit I2C slave address [ addr | 1 ]
00049      *  @param data Pointer to the byte-array to read data in to
00050      *  @param length Number of bytes to read
00051      *  @param repeated Repeated start, true - don't send stop at end
00052      *
00053      *  @returns
00054      *       0 on success (ack),
00055      *   non-0 on failure (nack)
00056      */
00057     int readMaster(int address, char* data, int length, bool repeated = false);
00058 
00059     /** Read from a given I2C slave register
00060      *
00061      * Performs a complete write-register-read-data-transaction. The bottom bit of
00062      * the address is forced to 1 to indicate a read.
00063      *
00064      *  @param address 8-bit I2C slave address [ addr | 1 ]
00065      *  @param _register 8-bit regster address
00066      *  @param data Pointer to the byte-array to read data in to
00067      *  @param length Number of bytes to read
00068      *  @param repeated Repeated start, true - don't send stop at end
00069      *
00070      *  @returns
00071      *       0 on success (ack),
00072      *   non-0 on failure (nack)
00073      */
00074     int readMaster(int address, uint8_t _register, char* data, int length, bool repeated = false);
00075 
00076     /** Read a single byte from the I2C bus
00077      *
00078      *  @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
00079      *
00080      *  @returns
00081      *    the byte read
00082      */
00083     int readMaster(int ack=1);
00084 
00085     /** Write to an I2C slave
00086      *
00087      * Performs a complete write transaction. The bottom bit of
00088      * the address is forced to 0 to indicate a write.
00089      *
00090      *  @param address 8-bit I2C slave address [ addr | 0 ]
00091      *  @param data Pointer to the byte-array data to send
00092      *  @param length Number of bytes to send
00093      *  @param repeated Repeated start, true - do not send stop at end
00094      *
00095      *  @returns
00096      *       0 on success (ack),
00097      *   non-0 on failure (nack)
00098      */
00099     int writeMaster(int address, const char *data, int length, bool repeated = false);
00100 
00101     /** Write single byte out on the I2C bus
00102      *
00103      *  @param data data to write out on bus
00104      *
00105      *  @returns
00106      *    '1' if an ACK was received,
00107      *    '0' otherwise
00108      */
00109     int writeMaster(int data);
00110 
00111     /** Sets the I2C slave address.
00112      *
00113      *  @param address The address to set for the slave (ignoring the least
00114      *  signifcant bit). If set to 0, the slave will only respond to the
00115      *  general call address.
00116      */
00117     void addressSlave(int address) {
00118         m_slaveAdr=address;
00119     }
00120 
00121     /** Checks to see if this I2C Slave has been addressed.
00122      *
00123      *  @returns
00124      *  A status indicating if the device has been addressed, and how
00125      *  - NoData            - the slave has not been addressed
00126      *  - ReadAddressed     - the master has requested a read from this slave
00127      *  - WriteAddressed    - the master is writing to this slave
00128      *  - WriteGeneral      - the master is writing to all slave
00129      */
00130     int receiveSlave(uint32_t timeout_ms=osWaitForever);
00131 
00132     /** Read from an I2C master.
00133      *
00134      *  @param data pointer to the byte array to read data in to
00135      *  @param length maximum number of bytes to read
00136      *
00137      *  @returns
00138      *       0 on success,
00139      *   non-0 otherwise
00140      */
00141     int readSlave(char *data, int length);
00142 
00143     /** Read a single byte from an I2C master.
00144     *
00145     *  @returns
00146     *    the byte read
00147     */
00148     int readSlave(void);
00149 
00150     /** Write to an I2C master.
00151      *
00152      *  @param data pointer to the byte array to be transmitted
00153      *  @param length the number of bytes to transmite
00154      *
00155      *  @returns
00156      *       0 on success,
00157      *   non-0 otherwise
00158      */
00159     int writeSlave(const char *data, int length);
00160 
00161     /** Write a single byte to an I2C master.
00162     *
00163     *  @data the byte to write
00164     *
00165     *  @returns
00166     *    '1' if an ACK was received,
00167     *    '0' otherwise
00168     */
00169     int writeSlave(int data);
00170 
00171 
00172     /// Creates a start condition on the I2C bus
00173     void startMaster(void);
00174 
00175     ///Creates a stop condition on the I2C bus
00176     void stopSlave(void);
00177 
00178     ///Creates a stop condition on the I2C bus
00179     void stopMaster(void);
00180 
00181     /// Wait until the i2c driver becomes available.
00182     ///
00183     /// Useful if you want to run a sequence of command without interrution by another thread.
00184     /// There's no need to call this function for running single request, because all driver functions
00185     /// will lock the device for exclusive access automatically.
00186     void lock();
00187 
00188     /// Unlock the driver that has previously been locked by the same thread.
00189     void unlock();
00190 
00191 protected:
00192     // commands sent from user to drive thread
00193     enum Command {
00194         START,
00195         STOP,
00196         READ_MST,
00197         READ_MST_REG,
00198         READ_SLV,
00199         READ_BYTE,
00200         WRITE_MST,
00201         WRITE_SLV,
00202         WRITE_BYTE,
00203         RECEIVE
00204     };
00205 
00206     // data transfer struct for communication between user and driver thread
00207     struct Transfer {
00208         Command cmd;
00209         int ret;
00210         int freq;
00211         int adr;
00212         char* dta;
00213         const char* wdta;
00214         int len;
00215         int ack;
00216         bool rep;
00217         uint8_t reg;
00218         bool slv;
00219         uint32_t tmout;
00220         osThreadId caller;
00221     };
00222 
00223     // structure that holds handles/locks for accessing the I2C channels
00224     struct Channel {
00225         osThreadId driver;
00226         rtos::Mutex  mutex;
00227         volatile Transfer transfer;
00228     };
00229 
00230     // current frequency setting
00231     int m_freq;
00232     // current slave address setting
00233     int m_slaveAdr;
00234     // prio of current caller thread
00235     osPriority m_callerPrio;
00236     // ID of current caller thread
00237     osThreadId m_callerID;
00238 
00239     // i2c driver prio
00240     static const osPriority c_drvPrio = osPriorityRealtime;
00241     // the pin names fo the i2c channels
00242     static const PinName c_sdas[2];
00243     static const PinName c_scls[2];
00244 
00245     // static storage for the I2C channel access objects
00246     static Channel* s_channels[2];
00247 
00248     // i2c channel object of this driver interface, in fact just pointer
00249     /// to one of the entries in s_channels
00250     Channel* m_channel;
00251 
00252     // ISRs
00253     static void channel_0_ISR();
00254     static void channel_1_ISR();
00255 
00256     // the driver thread function
00257     static void threadFun(void const *args);
00258 
00259     int sendNwait();
00260 };
00261 }
00262 #endif