Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed-rtos mbed-src
Diff: I2CDriver.cpp
- Revision:
- 1:90455d5bdd8c
- Parent:
- 0:13c962fecb13
- Child:
- 2:514105beb343
--- a/I2CDriver.cpp	Sat Apr 13 13:37:29 2013 +0000
+++ b/I2CDriver.cpp	Sun Apr 14 06:39:04 2013 +0000
@@ -1,102 +1,197 @@
 #include "I2CDriver.h"
 #include "error.h"
 
-#define ISR2DRV_SIG (1<<0);
-#define DRV_USR_SIG (1<<1);
+using namespace mbed;
+using namespace rtos;
 
-Channel I2CDriver::channels[2]= {0,0};
+#define ISR2DRV_SIG (1<<7)
+#define DRV_USR_SIG (1<<6)
+
+const PinName I2CDriver::c_sdas[] = {p9,p28};
+const PinName I2CDriver::c_scls[] = {p10,p27};
+
+I2CDriver::Channel* I2CDriver::s_channels[2] = {0,0};
 
 
 void I2CDriver::channel_0_ISR()
 {
-    osSignalSet( channels[0].driver, ISR2DRV_SIG);
-    NVIC_DisableIRQ(I2C1_IRQn); //I2C_IRQn
+    osSignalSet( s_channels[0]->driver, ISR2DRV_SIG);
+    NVIC_DisableIRQ(I2C1_IRQn);
 }
 
 
 void I2CDriver::channel_1_ISR()
 {
-    osSignalSet( channels[1].driver, ISR2DRV_SIG);
-    NVIC_DisableIRQ(I2C2_IRQn); //I2C_IRQn
+    osSignalSet( s_channels[1]->driver, ISR2DRV_SIG);
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
+    NVIC_DisableIRQ(I2C2_IRQn);
+#elif defined(TARGET_LPC11U24)
+    NVIC_DisableIRQ(I2C_IRQn);
+#endif
 }
 
 
-void I2CDriver::threadFun(void* const args)
+void I2CDriver::threadFun(void const *args)
 {
     int channelIdx = (int)args;
     Channel channel;
     s_channels[channelIdx] = &channel;
 
     channel.driver = Thread::gettid();
-
+#if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
     if(channelIdx==0)NVIC_SetVector(I2C1_IRQn, (uint32_t)I2CDriver::channel_0_ISR);
     if(channelIdx==1)NVIC_SetVector(I2C2_IRQn, (uint32_t)I2CDriver::channel_1_ISR);
-
-    I2C i2c(c_sda[channelIdx], c_scl[channelIdx]);
-
+#elif defined(TARGET_LPC11U24)
+    NVIC_SetVector(I2C_IRQn, (uint32_t)I2CDriver::channel_1_ISR);
+#endif
+    I2C i2c(c_sdas[channelIdx], c_scls[channelIdx]);
+    volatile Transfer& tr = channel.transfer;
     while(1) {
-        osSignalWait(DRV_USR_SIG,0);
-        switch(channels[channel].transfer.cmd) {
+        // 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);
+        }
+        // just doit
+        switch(tr.cmd) {
             case START:
-                if(channel.freq!=channel.transfer.freq) i2c.frequency
                 i2c.start();
                 break;
             case STOP:
                 i2c.stop();
                 break;
+            case READ:
+                tr.ret = i2c.read(tr.adr, tr.dta, tr.len, tr.rep);
+                break;
+            case READ_FROM_REGISTER:
+                tr.ret = i2c.write(tr.adr,(const char*)&(tr.reg), 1, true);
+                if(tr.ret)break; // error => bail out
+                tr.ret = i2c.read(tr.adr, tr.dta, tr.len, tr.rep);
+                break;
+            case READ_BYTE:
+                tr.ret = i2c.read(tr.ack);
+                break;
+            case WRITE:
+                tr.ret = i2c.write(tr.adr, tr.wdta, tr.len, tr.rep);
+                break;
+            case WRITE_BYTE:
+                tr.ret = i2c.write(tr.ack);
+                break;
+            default:
+                error("call 911");
         }
-        s_threads[2]
+        // inform the caller
+        osSignalSet( channel.transfer.caller, DRV_USR_SIG);
     }
 }
 
 
-I2CDriver::I2CDriver(PinName sda, PinName scl)
+I2CDriver::I2CDriver(PinName sda, PinName scl):I2C(sda,scl)
 {
     // check pins and determine i2c channel
     int channel=0;
-    if(sda==sdas[0] && scl==scls[0]) channel=0; // I2C_1
-    else if (sda==sdas[1] && scl==scls[1]) channel=1; //I2C_2
-    else error("I2CDriver: Invalid I2C pinns selected");
-
+#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_channel[channel]);
+    m_channel = s_channels[channel];
 }
 
-void I2CDriver::sendNwait(){
-    osSignalSet( m_channel.driver, DRV_USR_SIG);
+
+void I2CDriver::sendNwait()
+{
+    m_channel->transfer.freq = _hz;
+    m_channel->transfer.caller = Thread::gettid();
+    osSignalSet( m_channel->driver, DRV_USR_SIG);
     osSignalWait(DRV_USR_SIG,osWaitForever);
 }
 
-void I2CDriver::frequency(int hz);
 
-
-int I2CDriver::read(int address, char *data, int length, bool repeated = false);
-
-
-int I2CDriver::read(int ack);
-
-
-int I2CDriver::write(int address, const char *data, int length, bool repeated = false);
-
-
-int I2CDriver::write(int data);
-
-
-void I2CDriver::start(void){
+int I2CDriver::read(int address, char *data, int length, bool repeated)
+{
     lock();
-    m_channel.transfer.freq = _hz;
-    m_channel.transfer.cmd = START;
+    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();
-    unlock();   
+    int ret = m_channel->transfer.ret;
+    unlock();
+    return ret;
 }
 
 
-void I2CDriver::stop(void){
+int I2CDriver::read(int address, uint8_t regist, char *data, int length, bool repeated)
+{
+    lock();
+    m_channel->transfer.cmd = READ_FROM_REGISTER;
+    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;
+}
+
+int I2CDriver::read(int ack)
+{
+    lock();
+    m_channel->transfer.cmd = READ_BYTE;
+    m_channel->transfer.ack = ack;
+    sendNwait();
+    int ret = m_channel->transfer.ret;
+    unlock();
+    return ret;
+}
+
+int I2CDriver::write(int address, const char *data, int length, bool repeated)
+{
     lock();
-    m_channel.transfer.freq = _hz;
-    m_channel.transfer.cmd = STOP;
+    m_channel->transfer.cmd = WRITE;
+    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;
+}
+
+int I2CDriver::write(int data)
+{
+    lock();
+    m_channel->transfer.cmd = WRITE_BYTE;
+    m_channel->transfer.ack = data;
     sendNwait();
-    unlock();   
+    int ret = m_channel->transfer.ret;
+    unlock();
+    return ret;
 }
+
+void I2CDriver::start(void)
+{
+    lock();
+    m_channel->transfer.cmd = START;
+    sendNwait();
+    unlock();
+}
+
+
+void I2CDriver::stop(void)
+{
+    lock();
+    m_channel->transfer.cmd = STOP;
+    sendNwait();
+    unlock();
+}