Helmut Schmücker / mbed-RtosI2cDriver

Dependencies:   mbed-rtos mbed-src

Files at this revision

API Documentation at this revision

Comitter:
humlet
Date:
Sat Apr 20 20:06:44 2013 +0000
Parent:
5:8a418c89e515
Child:
7:04824382eafb
Commit message:
alpha

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
mbed-NXP.lib Show annotated file Show diff for this revision Revisions of this file
--- a/I2CDriver.cpp	Sat Apr 20 11:56:35 2013 +0000
+++ b/I2CDriver.cpp	Sat Apr 20 20:06:44 2013 +0000
@@ -13,13 +13,13 @@
 
 I2CDriver::Channel* I2CDriver::s_channels[2] = {0,0};
 
-
+#if defined(TARGET_LPC1768)
 void I2CDriver::channel_0_ISR()
 {
     osSignalSet( s_channels[0]->driver, I2C_ISR_DRV_SIG);
     NVIC_DisableIRQ(I2C1_IRQn);
 }
-
+#endif
 
 void I2CDriver::channel_1_ISR()
 {
@@ -44,7 +44,7 @@
         else error("I2CDriver: Invalid I2C pinns selected");
 
     if(s_channels[channel]==0)
-        new Thread(threadFun,(void *)channel,osPriorityRealtime,512);
+        new Thread(threadFun,(void *)channel,osPriorityRealtime,256);
     m_channel = s_channels[channel];
 }
 
@@ -135,6 +135,23 @@
     }
 }
 
+void I2CDriver::lock()
+{
+    // One and the same thread can lock twice, but then it needs also to unlock twice.
+    // exactly what we need here
+    m_callerID = osThreadGetId();
+    m_callerPrio = osThreadGetPriority(m_callerID);
+    m_channel->mutex.lock(osWaitForever);
+    osThreadSetPriority(m_callerID, c_drvPrio); // hopefully not interrupted since the lock
+}
+
+void I2CDriver::unlock()
+{
+    // free the mtex and restore original prio
+    m_channel->mutex.unlock();
+    osThreadSetPriority(m_callerID, m_callerPrio);
+}
+
 int I2CDriver::sendNwait()
 {
     m_channel->transfer.freq = m_freq;
--- a/I2CDriver.h	Sat Apr 20 11:56:35 2013 +0000
+++ b/I2CDriver.h	Sat Apr 20 20:06:44 2013 +0000
@@ -178,26 +178,18 @@
     ///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()  {
-        // 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);
-    }
+    void lock();
 
     /// Unlock the driver that has previously been locked by the same thread.
-    void unlock() {
-        m_channel->mutex.unlock();
-    }
+    void unlock();
 
 protected:
-    // commands sent from user to drive thread 
+    // commands sent from user to drive thread
     enum Command {
         START,
         STOP,
@@ -210,7 +202,7 @@
         WRITE_BYTE,
         RECEIVE
     };
-    
+
     // data transfer struct for communication between user and driver thread
     struct Transfer {
         Command cmd;
@@ -228,36 +220,42 @@
         osThreadId caller;
     };
 
-    // structure that holds handles/locks for accessing the I2C channels 
+    // structure that holds handles/locks for accessing the I2C channels
     struct Channel {
-        osThreadId driver; 
+        osThreadId driver;
         rtos::Mutex  mutex;
         volatile Transfer transfer;
     };
-    
+
     // current frequency setting
     int m_freq;
     // current slave address setting
     int m_slaveAdr;
-    
+    // prio of current caller thread
+    osPriority m_callerPrio;
+    // ID of current caller thread
+    osThreadId m_callerID;
+
+    // i2c driver prio
+    static const osPriority c_drvPrio = osPriorityRealtime;
     // the pin names fo the i2c channels
     static const PinName c_sdas[2];
     static const PinName c_scls[2];
 
-    // static storage for the I2C channel access objects  
+    // static storage for the I2C channel access objects
     static Channel* s_channels[2];
-    
+
     // i2c channel object of this driver interface, in fact just pointer
     /// to one of the entries in s_channels
     Channel* m_channel;
-    
-    // ISRs  
+
+    // ISRs
     static void channel_0_ISR();
     static void channel_1_ISR();
-    
+
     // the driver thread function
     static void threadFun(void const *args);
-    
+
     int sendNwait();
 };
 }
--- a/I2CDriverTest01.h	Sat Apr 20 11:56:35 2013 +0000
+++ b/I2CDriverTest01.h	Sat Apr 20 20:06:44 2013 +0000
@@ -33,7 +33,7 @@
         i2c.read(adr, reg, result, g_len, 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(--g_disco>0) printf("tm=%4dus dt=%4dus\n",tm,dt);
     }
 }
@@ -46,11 +46,16 @@
     Thread::wait(100);
     highPrioTicker.start(1);
 
+#if defined(TARGET_LPC1768)
     const int nTest=7;
-    const int freq[nTest]=  {4e5,   4e5,    4e5,    4e5,    4e5,    1e5,    1e5};
-    const int len[nTest]=   {1,     4,      9,      16,     25,     1,      6};
-    
-    for(int i=0; i<nTest; ++i){
+    const int freq[nTest]=  {1e5,   1e5,    1e5,   4e5,    4e5,    4e5,    4e5};
+    const int len[nTest]=   {1,     4,      6,      1,     6,     12,      25};
+#elif defined(TARGET_LPC11U24)
+    const int nTest=5;
+    const int freq[nTest]=  {1e5,   1e5,    4e5,   4e5,    4e5    };
+    const int len[nTest]=   {1,     4,      1,      6,     12};
+#endif
+    for(int i=0; i<nTest; ++i) {
         g_freq = freq[i];
         g_len = len[i];
         printf("f=%d l=%d\n",g_freq,g_len);
--- a/I2CDriverTest02.h	Sat Apr 20 11:56:35 2013 +0000
+++ b/I2CDriverTest02.h	Sat Apr 20 20:06:44 2013 +0000
@@ -15,7 +15,6 @@
     memset(rxMsg,0,len);
     if ( slv.receive() == I2CSlave::WriteAddressed) {
         slv.read(rxMsg, len);
-        //rMsg[len-1]=0;
         printf("thread %X received message as i2c slave: '%s'\n",Thread::gettid(),rxMsg);
     } else
         printf("Ouch slv rx failure\n");
@@ -32,7 +31,6 @@
 static void mstTxMsg(I2CMasterRtos& mst)
 {
     mst.write(adr,mstMsg,len);
-    //printf("thread %X has sent the message\n",Thread::gettid());
 }
 
 static void mstRxMsg(I2CMasterRtos& mst)
@@ -76,22 +74,8 @@
     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);
-    }
+    Thread::wait(10000);
+
     return 0;
 }
 
--- a/mbed-NXP.lib	Sat Apr 20 11:56:35 2013 +0000
+++ b/mbed-NXP.lib	Sat Apr 20 20:06:44 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/humlet/code/mbed-NXP/#50c599e18714
+http://mbed.org/users/humlet/code/mbed-NXP/#9b3db7ced428