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

Files at this revision

API Documentation at this revision

Comitter:
humlet
Date:
Fri Apr 19 21:33:29 2013 +0000
Parent:
2:514105beb343
Child:
4:eafa7efcd771
Commit message:
refactored, compiles and crashes

Changed in this revision

I2CDriver.cpp Show annotated file Show diff for this revision Revisions of this file
I2CDriver.h Show annotated file Show diff for this revision Revisions of this file
I2CDriverTest01.h Show annotated file Show diff for this revision Revisions of this file
I2CDriverTest02.h Show annotated file Show diff for this revision Revisions of this file
I2CMasterRtos.h Show annotated file Show diff for this revision Revisions of this file
I2CSlaveRtos.h Show annotated file Show diff for this revision Revisions of this file
mbed-NXP.lib Show annotated file Show diff for this revision Revisions of this file
mbed-src.lib Show annotated file Show diff for this revision Revisions of this file
--- a/I2CDriver.cpp	Sun Apr 14 21:42:22 2013 +0000
+++ b/I2CDriver.cpp	Fri Apr 19 21:33:29 2013 +0000
@@ -1,4 +1,5 @@
 #include "I2CDriver.h"
+#include "i2c_api.h"
 #include "error.h"
 
 using namespace mbed;
@@ -31,6 +32,23 @@
 }
 
 
+I2CDriver::I2CDriver(PinName sda, PinName scl, int hz, int slaveAdr):m_freq(hz),m_slaveAdr(slaveAdr)
+{
+    // check pins and determine i2c channel
+    int channel=0;
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+    if(sda==c_sdas[0] && scl==c_scls[0]) channel=0; // I2C_1
+    else
+#endif
+        if (sda==c_sdas[1] && scl==c_scls[1]) channel=1; //I2C_2 or I2C
+        else error("I2CDriver: Invalid I2C pinns selected");
+
+    if(s_channels[channel]==0)
+        new Thread(threadFun,(void *)channel,osPriorityRealtime,512);
+    m_channel = s_channels[channel];
+}
+
+
 void I2CDriver::threadFun(void const *args)
 {
     int channelIdx = (int)args;
@@ -45,42 +63,69 @@
     NVIC_SetVector(I2C_IRQn, (uint32_t)I2CDriver::channel_1_ISR);
 #endif
 
-    I2C i2c(c_sdas[channelIdx], c_scls[channelIdx]);
+    int freq = 0;
+    int adrSlave = 0;
+    int modeSlave = 0;
+    i2c_t i2c;
+    i2c_init(&i2c, c_sdas[channelIdx], c_scls[channelIdx]);
 
     volatile Transfer& tr = channel.transfer;
     while(1) {
         // wait for requests
         osSignalWait(DRV_USR_SIG,osWaitForever);
+
         // check and adapt frequency
-        if(channel.freq != tr.freq) {
-            channel.freq = tr.freq;
-            i2c.frequency(tr.freq);
+        if(freq != tr.freq) {
+            freq = tr.freq;
+            i2c_frequency(&i2c, tr.freq);
         }
+
+        // check and adapt slave/master mode
+        if(modeSlave != tr.slv) {
+            modeSlave = tr.slv;
+            i2c_slave_mode(&i2c, tr.slv);
+        }
+
+        // check and adapt slave address
+        int adr = (tr.adr & 0xFF) | 1;
+        if(tr.slv && adrSlave != adr) {
+            adrSlave = adr;
+            i2c_slave_address(&i2c, 0, adr, 0);
+        }
+
         // just doit
         switch(tr.cmd) {
             case START:
-                i2c.start();
+                i2c_start(&i2c);
                 break;
             case STOP:
-                i2c.stop();
+                i2c_stop(&i2c);
                 break;
-            case READ:
-                tr.ret = i2c.read(tr.adr, tr.dta, tr.len, tr.rep);
+            case READ_MST:
+                tr.ret = i2c_read(&i2c, tr.adr, tr.dta, tr.len, (tr.rep?0:1));
                 break;
-            case READ_FROM_REGISTER:
-                tr.ret = i2c.write(tr.adr,(const char*)&(tr.reg), 1, true);
+            case READ_MST_REG:
+                tr.ret = i2c_write(&i2c, tr.adr,(const char*)&(tr.reg), 1, 0);
                 if(tr.ret)break; // error => bail out
-                tr.ret = i2c.read(tr.adr, tr.dta, tr.len, tr.rep);
+                tr.ret = i2c_read(&i2c, tr.adr, tr.dta, tr.len, (tr.rep?0:1));
+                break;
+            case READ_SLV:
+                tr.ret = i2c_slave_read(&i2c, tr.dta, tr.len);
                 break;
             case READ_BYTE:
-                tr.ret = i2c.read(tr.ack);
+                tr.ret = i2c_byte_read(&i2c, (tr.ack?0:1));
                 break;
-            case WRITE:
-                tr.ret = i2c.write(tr.adr, tr.wdta, tr.len, tr.rep);
+            case WRITE_MST:
+                tr.ret = i2c_write(&i2c, tr.adr, tr.wdta, tr.len, (tr.rep?0:1));
+                break;
+            case WRITE_SLV:
+                tr.ret = i2c_slave_write(&i2c, tr.wdta, tr.len);
                 break;
             case WRITE_BYTE:
-                tr.ret = i2c.write(tr.ack);
+                tr.ret = i2c_byte_write(&i2c, tr.ack);
                 break;
+            case RECEIVE:
+                tr.ret = i2c_slave_receive_rtos(&i2c, tr.tmout);
             default:
                 error("call 911");
         }
@@ -89,112 +134,149 @@
     }
 }
 
-
-I2CDriver::I2CDriver(PinName sda, PinName scl):I2C(sda,scl)
+int I2CDriver::sendNwait()
 {
-    // check pins and determine i2c channel
-    int channel=0;
-#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
-    if(sda==c_sdas[0] && scl==c_scls[0]) channel=0; // I2C_1
-    else
-#endif
-        if (sda==c_sdas[1] && scl==c_scls[1]) channel=1; //I2C_2 or I2C
-        else error("I2CDriver: Invalid I2C pinns selected");
- 
-    if(s_channels[channel]==0)
-        new Thread(threadFun,(void *)channel,osPriorityRealtime);
-    m_channel = s_channels[channel];
-}
-
-
-void I2CDriver::sendNwait()
-{
-    m_channel->transfer.freq = _hz;
+    m_channel->transfer.freq = m_freq;
     m_channel->transfer.caller = Thread::gettid();
     osSignalSet( m_channel->driver, DRV_USR_SIG);
     osSignalWait(DRV_USR_SIG,osWaitForever);
-}
-
-
-int I2CDriver::read(int address, char *data, int length, bool repeated)
-{
-    lock();
-    m_channel->transfer.cmd = READ;
-    m_channel->transfer.adr = address;
-    m_channel->transfer.dta = data;
-    m_channel->transfer.len = length;
-    m_channel->transfer.rep = repeated;
-    sendNwait();
     int ret = m_channel->transfer.ret;
     unlock();
     return ret;
 }
 
-
-int I2CDriver::read(int address, uint8_t regist, char *data, int length, bool repeated)
+int I2CDriver::readMaster(int address, char *data, int length, bool repeated)
 {
     lock();
-    m_channel->transfer.cmd = READ_FROM_REGISTER;
+    m_channel->transfer.cmd = READ_MST;
+    m_channel->transfer.slv = false;
     m_channel->transfer.adr = address;
-    m_channel->transfer.reg = regist;
     m_channel->transfer.dta = data;
     m_channel->transfer.len = length;
     m_channel->transfer.rep = repeated;
-    sendNwait();
-    int ret = m_channel->transfer.ret;
-    unlock();
-    return ret;
+    return sendNwait();
 }
 
-int I2CDriver::read(int ack)
+int I2CDriver::readMaster(int address, uint8_t _register, char *data, int length, bool repeated)
+{
+    lock();
+    m_channel->transfer.cmd = READ_MST_REG;
+    m_channel->transfer.slv = false;
+    m_channel->transfer.adr = address;
+    m_channel->transfer.reg = _register;
+    m_channel->transfer.dta = data;
+    m_channel->transfer.len = length;
+    m_channel->transfer.rep = repeated;
+    return sendNwait();
+}
+
+int I2CDriver::readMaster(int ack)
 {
     lock();
     m_channel->transfer.cmd = READ_BYTE;
+    m_channel->transfer.slv = false;
     m_channel->transfer.ack = ack;
-    sendNwait();
-    int ret = m_channel->transfer.ret;
-    unlock();
-    return ret;
+    return sendNwait();
 }
 
-int I2CDriver::write(int address, const char *data, int length, bool repeated)
+int I2CDriver::writeMaster(int address, const char *data, int length, bool repeated)
 {
     lock();
-    m_channel->transfer.cmd = WRITE;
+    m_channel->transfer.cmd = WRITE_MST;
+    m_channel->transfer.slv = false;
     m_channel->transfer.adr = address;
     m_channel->transfer.wdta = data;
     m_channel->transfer.len = length;
     m_channel->transfer.rep = repeated;
-    sendNwait();
-    int ret = m_channel->transfer.ret;
-    unlock();
-    return ret;
+    return sendNwait();
 }
 
-int I2CDriver::write(int data)
+int I2CDriver::writeMaster(int data)
 {
     lock();
     m_channel->transfer.cmd = WRITE_BYTE;
+    m_channel->transfer.slv = false;
     m_channel->transfer.ack = data;
-    sendNwait();
-    int ret = m_channel->transfer.ret;
-    unlock();
-    return ret;
+    return sendNwait();
 }
 
-void I2CDriver::start(void)
+void I2CDriver::startMaster(void)
 {
     lock();
     m_channel->transfer.cmd = START;
+    m_channel->transfer.slv = false;
     sendNwait();
-    unlock();
+}
+
+void I2CDriver::stopMaster(void)
+{
+    lock();
+    m_channel->transfer.cmd = STOP;
+    m_channel->transfer.slv = false;
+    sendNwait();
+}
+
+void I2CDriver::stopSlave(void)
+{
+    lock();
+    m_channel->transfer.cmd = STOP;
+    m_channel->transfer.slv = true;
+    m_channel->transfer.adr = m_slaveAdr;
+    sendNwait();
+}
+
+int I2CDriver::receiveSlave(uint32_t timeout_ms)
+{
+    lock();
+    m_channel->transfer.cmd = RECEIVE;
+    m_channel->transfer.slv = true;
+    m_channel->transfer.adr = m_slaveAdr;
+    m_channel->transfer.tmout = timeout_ms;
+    return sendNwait();
+}
+
+int I2CDriver::readSlave(char* data, int length)
+{
+    lock();
+    m_channel->transfer.cmd = READ_SLV;
+    m_channel->transfer.slv = true;
+    m_channel->transfer.adr = m_slaveAdr;
+    m_channel->transfer.dta = data;
+    m_channel->transfer.len = length;
+    return sendNwait();
+}
+
+int I2CDriver::readSlave(void)
+{
+    lock();
+    m_channel->transfer.cmd = READ_BYTE;
+    m_channel->transfer.slv = true;
+    m_channel->transfer.adr = m_slaveAdr;
+    m_channel->transfer.ack = 1;
+    return sendNwait();
+}
+
+int I2CDriver::writeSlave(const char *data, int length)
+{
+    lock();
+    m_channel->transfer.cmd = WRITE_SLV;
+    m_channel->transfer.slv = true;
+    m_channel->transfer.adr = m_slaveAdr;
+    m_channel->transfer.wdta = data;
+    m_channel->transfer.len = length;
+    return sendNwait();
+}
+
+int I2CDriver::writeSlave(int data)
+{
+    lock();
+    m_channel->transfer.cmd = WRITE_BYTE;
+    m_channel->transfer.slv = true;
+    m_channel->transfer.adr = m_slaveAdr;
+    m_channel->transfer.ack = data;
+    return sendNwait();
 }
 
 
-void I2CDriver::stop(void)
-{
-    lock();
-    m_channel->transfer.cmd = STOP;
-    sendNwait();
-    unlock();
-}
+
+
--- 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CDriverTest01.h	Fri Apr 19 21:33:29 2013 +0000
@@ -0,0 +1,68 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "I2CMasterRtos.h"
+#include "stdint.h"
+
+volatile int disco=0;
+volatile osThreadId i2cDrvThrdID;
+
+void highPrioCallBck(void const *args)
+{
+    osSignalSet(i2cDrvThrdID, 1<<5);
+}
+
+void highPrioThreadFun(void const *args)
+{
+    i2cDrvThrdID = Thread::gettid();
+    I2CMasterRtos i2c(p28, p27);
+    i2c.frequency(400000);
+    const uint32_t adr = 0x70<<1;
+
+    // trigger on srf08 ranging
+    const char regNcmd[2]= {0x00,0x51};
+    i2c.write(adr, regNcmd, 2);
+
+    while(true) {
+        Thread::signal_wait(1<<5,osWaitForever);
+        // read back srf08 echo times (1+16 words)
+        const char reg= 0x02;
+        char result[64];
+        uint32_t t1=us_ticker_read();
+        i2c.read(adr, reg, result, 25, 1);
+
+        uint32_t dt=us_ticker_read()-t1;
+        uint16_t tm=((static_cast<uint16_t>(result[0])<<8)|static_cast<uint16_t>(result[1]));
+        
+        if(--disco>0) printf("tm=%4dus dt=%4dus\n",tm,dt);
+    }
+}
+
+int doit()
+{
+    Thread highPrioThread(highPrioThreadFun,0,osPriorityAboveNormal);
+    RtosTimer highPrioTicker(highPrioCallBck, osTimerPeriodic, (void *)0);
+
+    Thread::wait(100);
+    highPrioTicker.start(1);
+
+    uint32_t cnt=0;
+    while (++cnt<5) {
+        const uint32_t dt=1e6;
+        uint32_t tStart = us_ticker_read();
+        uint32_t tLast = tStart;
+        uint32_t tAct = tStart;
+        uint32_t tMe=0;
+        do {
+            tAct=us_ticker_read();
+            if(tAct>tLast) {
+                if(tAct==tLast+1)++tMe;
+            }
+            tLast=tAct;
+        } while(tAct-tStart<dt);
+        printf("dc=%5.2f \n", 100.0*(float)tMe/dt);
+        disco=10;
+        while(disco>0);
+        Thread::wait(1000);
+    }
+    return 0;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CDriverTest02.h	Fri Apr 19 21:33:29 2013 +0000
@@ -0,0 +1,75 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "I2CMasterRtos.h"
+#include "I2CSlaveRtos.h"
+
+const int freq = 100000;
+const int adr = 42;
+const int len=42;
+const char* cMsg="We are mbed, resistance is futile";
+
+static void rxMsg(I2CSlaveRtos& slv)
+{
+    char rMsg[len];
+    memset(rMsg,0,len);
+    if ( slv.receive() == I2CSlave::WriteAddressed) {
+        slv.read(rMsg, len); // have to add 1 byte for the address (bug report!)
+        printf("thread %d received message '%s'\n",Thread::gettid(),rxMsg);
+    } else
+        printf("god damned nation");
+}
+
+static void txMsg(I2CMasterRtos& mst)
+{
+    mst.write(adr,cMsg,len);
+    printf("thread %d has sent the message\n",Thread::gettid());
+}
+
+static void channel1(void const *args)
+{
+    I2CMasterRtos mst(p9,p10,freq);
+    I2CSlaveRtos slv(p9,p10,freq,adr);
+    while(1) {
+        rxMsg(slv);
+        Thread::wait(100);
+        txMsg(mst);
+        Thread::wait(100);
+    }
+}
+
+void channel2(void const *args)
+{
+    I2CMasterRtos mst(p28,p27,freq);
+    I2CSlaveRtos slv(p28,p27,freq,adr);
+    while(1) {
+        txMsg(mst);
+        Thread::wait(100);
+        rxMsg(slv);
+        Thread::wait(100);
+    }
+}
+
+int doit()
+{
+    Thread selftalk01(channel1,0,osPriorityAboveNormal);
+    Thread selftalk02(channel2,0,osPriorityAboveNormal);
+
+    uint32_t cnt=0;
+    while (++cnt<5) {
+        const uint32_t dt=1e6;
+        uint32_t tStart = us_ticker_read();
+        uint32_t tLast = tStart;
+        uint32_t tAct = tStart;
+        uint32_t tMe=0;
+        do {
+            tAct=us_ticker_read();
+            if(tAct>tLast) {
+                if(tAct==tLast+1)++tMe;
+            }
+            tLast=tAct;
+        } while(tAct-tStart<dt);
+        printf("dc=%5.2f \n", 100.0*(float)tMe/dt);
+    }
+    return 0;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CMasterRtos.h	Fri Apr 19 21:33:29 2013 +0000
@@ -0,0 +1,127 @@
+#ifndef I2CMASTERRTOS_H
+#define I2CMASTERRTOS_H
+
+#include "I2CDriver.h"
+
+namespace mbed
+{
+
+/// I2C master interface to the RTOS-I2CDriver.
+/// The interface is compatible to the original mbed I2C class.
+/// Provides an additonal read from register function.
+class I2CMasterRtos
+{
+    I2CDriver m_drv;
+
+public:
+    /** Create an I2C Master interface, connected to the specified pins
+    *
+    *  @param sda I2C data line pin
+    *  @param scl I2C clock line pin
+    */
+    I2CMasterRtos(PinName sda, PinName scl, int freq=100000):m_drv(sda,scl,freq) {}
+
+    /** Set the frequency of the I2C interface
+     *
+     *  @param hz The bus frequency in hertz
+     */
+    void frequency(int hz) {
+        m_drv.frequency(hz);
+    }
+
+    /** Read from an I2C slave
+     *
+     * Performs a complete read 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 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 read(int address, char *data, int length, bool repeated = false) {
+        return m_drv.readMaster( address, data, length, repeated);
+    }
+
+    /** 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 read(int address, uint8_t _register, char *data, int length, bool repeated = false) {
+        return m_drv.readMaster( address, _register, data, length, repeated);
+    }
+
+    /** Read a single byte from the I2C bus
+     *
+     *  @param ack indicates if the byte is to be acknowledged (1 = acknowledge)
+     *
+     *  @returns
+     *    the byte read
+     */
+    int read(int ack) {
+        return m_drv.readMaster(ack);
+    }
+
+    /** Write to an I2C slave
+     *
+     * Performs a complete write transaction. The bottom bit of
+     * the address is forced to 0 to indicate a write.
+     *
+     *  @param address 8-bit I2C slave address [ addr | 0 ]
+     *  @param data Pointer to the byte-array data to send
+     *  @param length Number of bytes to send
+     *  @param repeated Repeated start, true - do not send stop at end
+     *
+     *  @returns
+     *       0 on success (ack),
+     *   non-0 on failure (nack)
+     */
+    int write(int address, const char *data, int length, bool repeated = false) {
+        return m_drv.writeMaster(address, data, length, repeated);
+    }
+
+    /** Write single byte out on the I2C bus
+     *
+     *  @param data data to write out on bus
+     *
+     *  @returns
+     *    '1' if an ACK was received,
+     *    '0' otherwise
+     */
+    int write(int data) {
+        return m_drv.writeMaster(data);
+    }
+
+    /** Creates a start condition on the I2C bus
+     */
+
+    void startMaster(void) {
+        m_drv.startMaster();
+    }
+
+    /** Creates a stop condition on the I2C bus
+     */
+    void stop(void) {
+        m_drv.stopMaster();
+    }
+
+};
+}
+
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CSlaveRtos.h	Fri Apr 19 21:33:29 2013 +0000
@@ -0,0 +1,119 @@
+#ifndef I2CSLAVERTOS_H
+#define I2CSLAVERTOS_H
+
+#include "I2CDriver.h"
+
+namespace mbed
+{
+
+/// I2C master interface to the RTOS-I2CDriver.
+/// The interface is compatible to the original mbed I2C class.
+class I2CSlaveRtos
+{
+    I2CDriver m_drv;
+
+public:
+
+    enum RxStatus {
+        NoData         = 0,
+        ReadAddressed  = 1,
+        WriteGeneral   = 2,
+        WriteAddressed = 3
+    };
+
+    /** Create an I2C Slave interface, connected to the specified pins.
+     *
+     *  @param sda I2C data line pin
+     *  @param scl I2C clock line pin
+     */
+    I2CSlaveRtos(PinName sda, PinName scl, int freq=100000, int address=42)
+        :m_drv(sda,scl,100000,address) {}
+
+    /** Set the frequency of the I2C interface
+     *
+     *  @param hz The bus frequency in hertz
+     */
+    void frequency(int hz) {
+        m_drv.frequency(hz);
+    }
+
+    /** 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 receive(void) {
+        return m_drv.receiveSlave();
+    }
+
+    /** 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 read(char *data, int length) {
+        return m_drv.readSlave(data, length);
+    }
+
+    /** Read a single byte from an I2C master.
+     *
+     *  @returns
+     *    the byte read
+     */
+    int read(void) {
+        return m_drv.readSlave();
+    }
+
+    /** 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 write(const char *data, int length) {
+        return m_drv.writeSlave(data, length);
+    }
+
+    /** Write a single byte to an I2C master.
+     *
+     *  @data the byte to write
+     *
+     *  @returns
+     *    '1' if an ACK was received,
+     *    '0' otherwise
+     */
+    int write(int data) {
+        return m_drv.writeSlave(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 address(int address) {
+        m_drv.addressSlave(address);
+    }
+
+
+    /** Reset the I2C slave back into the known ready receiving state.
+     */
+    void stop(void){
+        m_drv.stopSlave();
+    }
+};
+}
+
+#endif
\ No newline at end of file
--- a/mbed-NXP.lib	Sun Apr 14 21:42:22 2013 +0000
+++ b/mbed-NXP.lib	Fri Apr 19 21:33:29 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed-NXP/#09117a22982e
+http://mbed.org/users/mbed_official/code/mbed-NXP/#b7a4ba1b2dab
--- a/mbed-src.lib	Sun Apr 14 21:42:22 2013 +0000
+++ b/mbed-src.lib	Fri Apr 19 21:33:29 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed-src/#6dfdb79ccc45
+http://mbed.org/users/mbed_official/code/mbed-src/#6e50904b84e2