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:
Sun Apr 28 15:08:04 2013 +0000
Parent:
6:5b98c902a659
Child:
8:5be85bd4c5ba
Commit message:
stable before perf measurements

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
I2CDriverTest03.h Show annotated file Show diff for this revision Revisions of this file
I2CDriverTest04.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
mbed-NXP.lib Show annotated file Show diff for this revision Revisions of this file
--- a/I2CDriver.cpp	Sat Apr 20 20:06:44 2013 +0000
+++ b/I2CDriver.cpp	Sun Apr 28 15:08:04 2013 +0000
@@ -2,10 +2,13 @@
 #include "i2c_api.h"
 #include "error.h"
 
+#include "DigitalOut.h"
+
 using namespace mbed;
 using namespace rtos;
 
-//#define I2C_ISR_DRV_SIG (1<<7)
+DigitalOut osci(p12);
+
 #define DRV_USR_SIG (1<<6)
 
 const PinName I2CDriver::c_sdas[] = {p9,p28};
@@ -16,19 +19,23 @@
 #if defined(TARGET_LPC1768)
 void I2CDriver::channel_0_ISR()
 {
+    osci.write(1);
     osSignalSet( s_channels[0]->driver, I2C_ISR_DRV_SIG);
     NVIC_DisableIRQ(I2C1_IRQn);
+    osci.write(0);
 }
 #endif
 
 void I2CDriver::channel_1_ISR()
 {
+    osci.write(1);
     osSignalSet( s_channels[1]->driver, I2C_ISR_DRV_SIG);
 #if defined(TARGET_LPC1768) || defined(TARGET_LPC2368)
     NVIC_DisableIRQ(I2C2_IRQn);
 #elif defined(TARGET_LPC11U24)
     NVIC_DisableIRQ(I2C_IRQn);
 #endif
+    osci.write(0);
 }
 
 
@@ -105,6 +112,7 @@
                 tr.ret = i2c_read(&i2c, tr.adr, tr.dta, tr.len, (tr.rep?0:1));
                 break;
             case READ_MST_REG:
+                //printf("Disco\n");
                 tr.ret = i2c_write(&i2c, tr.adr,(const char*)&(tr.reg), 1, 0);
                 if(tr.ret)break; // error => bail out
                 tr.ret = i2c_read(&i2c, tr.adr, tr.dta, tr.len, (tr.rep?0:1));
--- a/I2CDriver.h	Sat Apr 20 20:06:44 2013 +0000
+++ b/I2CDriver.h	Sun Apr 28 15:08:04 2013 +0000
@@ -54,7 +54,7 @@
      *       0 on success (ack),
      *   non-0 on failure (nack)
      */
-    int readMaster(int address, char *data, int length, bool repeated = false);
+    int readMaster(int address, char* data, int length, bool repeated = false);
 
     /** Read from a given I2C slave register
      *
@@ -71,7 +71,7 @@
      *       0 on success (ack),
      *   non-0 on failure (nack)
      */
-    int readMaster(int address, uint8_t _register, char *data, int length, bool repeated = false);
+    int readMaster(int address, uint8_t _register, char* data, int length, bool repeated = false);
 
     /** Read a single byte from the I2C bus
      *
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CDriverTest03.h	Sun Apr 28 15:08:04 2013 +0000
@@ -0,0 +1,173 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "I2CMasterRtos.h"
+#include "stdint.h"
+
+const int dataReadySig = 1<<5;
+osThreadId mainThreadID = 0;
+char data[64];
+int16_t fifo[16];
+const int i2cAdr = 0x68<<1;
+int fifoAdr = 0x72;
+
+//Serial pc(USBTX, USBRX);
+
+void configMPU6050(I2CMasterRtos& i2c);
+void config(I2CMasterRtos& i2c);
+
+
+void dataReadyIsr()
+{
+    osSignalSet(mainThreadID, dataReadySig);
+}
+
+void readModWrite(I2CMasterRtos& i2c, uint8_t reg, uint8_t dta)
+{
+    
+    char rd1;
+    int rStat1 = i2c.read(i2cAdr, reg, &rd1, 1);
+    char data[2];
+    data[0]=(char)reg;
+    data[1]=(char)dta;
+    char rd2;
+    int wStat = i2c.write(i2cAdr, data, 2);
+    osDelay(500);
+    int rStat2 = i2c.read(i2cAdr, reg, &rd2, 1);
+    printf("%2d%2d%2d  %2x <- %2x  => %2x -> %2x \n", rStat1, wStat, rStat2, reg, dta, rd1, rd2);
+}
+
+
+int doit()
+{
+    //pc.baud(115200);
+    mainThreadID = osThreadGetId();
+
+    I2CMasterRtos i2c(p28, p27,400000);
+    osDelay(500);
+
+    printf("Initialize ... \n");
+    config(i2c);
+
+    printf("Action!\n");
+
+    InterruptIn dataReadyIrq(p8);
+    dataReadyIrq.mode(PullNone);
+    dataReadyIrq.rise(&dataReadyIsr);
+
+    /*
+    data[0]=0x6a;   // pwr 1 reg
+    data[1]=(1<<6)|(1<<2); // fifo on
+    i2c.write(i2cAdr,data,2,1);
+
+    data[0]=0x38;   // irq conf  reg
+    data[1]=1;      // irq on data ready
+    i2c.write(i2cAdr,data,2,1);
+    */
+    //fifoAdr = 0x3b;
+    char devNull;
+    while(1) {
+        osSignalWait(dataReadySig, 1000); // osWaitForever
+        i2c.read(i2cAdr,fifoAdr,data,2);
+        i2c.read(i2cAdr,fifoAdr+2,data+2,12);
+        i2c.read(i2cAdr,0x3a,&devNull,1);
+        for(int i=0; i<7; i++) {
+            fifo[i] = (data[2*i]<<8) | data[2*i+1];
+            printf("%8d",fifo[i]);
+        }
+        printf("     %x\n",devNull);
+
+    }
+    return 0;
+}
+
+static void config(I2CMasterRtos& i2c)
+{
+    uint8_t ncfg=32;
+    uint8_t regs[ncfg];
+    uint8_t vals[ncfg];
+    int cnt=0;
+    regs[cnt]=0x6b;
+    vals[cnt++]=(1<<7); // pwr 1 reg //: device reset
+    regs[cnt]=0x6b;
+    vals[cnt++]=1; // pwr 1 reg // clock from x gyro all pwr sav modes off
+    regs[cnt]=0x19;
+    vals[cnt++]=199;  // sample rate divider reg  // sapmle rate = gyro rate / (1+x)
+    regs[cnt]=0x1a;
+    vals[cnt++]=1;// conf  reg // no ext frame sync / dig low pass set to 1 => 1kHz Sampling with ~200Hz bandwidth DLPF
+    regs[cnt]=0x1b;
+    vals[cnt++]=0;// gyro conf  reg // no test mode and gyro range 250°/s
+    regs[cnt]=0x1c;
+    vals[cnt++]=0;// accl conf  reg // no test mode and accl range 2g
+    regs[cnt]=0x23;
+    vals[cnt++]=0xf<<3;// fifo conf  reg // accl + all gyro -> fifo
+    regs[cnt]=0x37;
+    vals[cnt++]=(0<<7)|(0<<6)|(0<<5)|(0<<4); // irq conf  reg // act high | 0:pupu 1:opnDrn| pulse | clear on any read
+    regs[cnt]=0x38;
+    vals[cnt++]=1|(1<<4); // irq conf  reg // irq on data ready
+    regs[cnt]=0x6a;
+    vals[cnt++]=(1<<2); // pwr 1 reg // fifo reset
+    regs[cnt]=0x6a;
+    vals[cnt++]=(1<<6); // pwr 1 reg // fifo on
+
+    /*
+    readModWrite(i2c, regs[0], vals[0]);
+    char reset=0xff;
+    while(reset&(1<<7)) {
+        osDelay(100);
+        i2c.read(i2cAdr,0x6b,&reset,1,1);
+    }
+    */
+    for(int i=0; i<cnt; i++)
+        readModWrite(i2c, regs[i], vals[i]);
+}
+
+static void configMPU6050(I2CMasterRtos& i2c)
+{
+
+    data[0]=0x6b;   // pwr 1 reg
+    data[1]=1<<7;   // device reset
+    i2c.write(i2cAdr,data,2,1);
+    char reset=0xff;
+    while(reset&(1<<7)) {
+        osDelay(100);
+        i2c.read(i2cAdr,0x6b,&reset,1,1);
+    }
+
+    data[0]=0x19;   // sample rate divider reg
+    data[1]=99;    // sapmle rate = gyro rate / (1+x)
+    i2c.write(i2cAdr,data,2,1);
+
+    data[0]=0x1a;   // conf  reg
+    data[1]=1;      // no ext frame sync / dig low pass set to 1 => 1kHz Sampling with ~200Hz bandwidth DLPF
+    i2c.write(i2cAdr,data,2,1);
+
+    data[0]=0x1b;   // gyro conf  reg
+    data[1]=0;      // no test mode and gyro range 250°/s
+    i2c.write(i2cAdr,data,2,1);
+
+    data[0]=0x1c;   // accl conf  reg
+    data[1]=0;      // no test mode and accl range 2g
+    i2c.write(i2cAdr,data,2,1);
+
+    data[0]=0x23;   // fifo conf  reg
+    data[1]=0xf<<3; // accl + all gyro -> fifo
+    i2c.write(i2cAdr,data,2,1);
+
+    data[0]=0x37;   // irq conf  reg
+    data[1]=(1<<7)|(0<<6)|(0<<5)|(1<<4); // act high | pupu | pulse | clear on any read
+    i2c.write(i2cAdr,data,2,1);
+
+    /*
+    data[0]=0x38;   // irq conf  reg
+    data[1]=1;      // irq on data ready
+    i2c.write(i2cAdr,data,2,1);
+
+    data[0]=0x6a;   // pwr 1 reg
+    data[1]=(1<<6); // fifo on
+    i2c.write(i2cAdr,data,2,1);
+    */
+    data[0]=0x6b;   // pwr 1 reg
+    data[1]=1;      // clock from x gyro all pwr sav modes off
+    i2c.write(i2cAdr,data,2,1);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/I2CDriverTest04.h	Sun Apr 28 15:08:04 2013 +0000
@@ -0,0 +1,123 @@
+#include "mbed.h"
+#include "rtos.h"
+#include "I2CMasterRtos.h"
+#include "stdint.h"
+
+volatile int g_disco=0;
+volatile int g_len=0;
+volatile int g_freq=100000;
+const uint32_t i2cAdr = 0x68<<1;
+volatile osThreadId i2cDrvThrdID;
+
+static void config(I2CMasterRtos& i2c);
+
+void highPrioCallBck(void const *args)
+{
+    osSignalSet(i2cDrvThrdID, 1<<5);
+}
+
+void highPrioThreadFun(void const *args)
+{
+    i2cDrvThrdID = Thread::gettid();
+    I2CMasterRtos i2c(p28, p27);
+    
+    config(i2c);
+
+    while(true) {
+        i2c.frequency(g_freq);
+        Thread::signal_wait(1<<5,osWaitForever);
+        // read back srf08 echo times (1+16 words)
+        const char reg= 0x3a;
+        char result[64];
+        uint32_t t1=us_ticker_read();
+        i2c.read(i2cAdr, reg, result, g_len);
+        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=%8d dt=%4dus\n",tm,dt);
+    }
+}
+
+int doit()
+{
+    Thread highPrioThread(highPrioThreadFun,0,osPriorityAboveNormal);
+    RtosTimer highPrioTicker(highPrioCallBck, osTimerPeriodic, (void *)0);
+
+    Thread::wait(100);
+    highPrioTicker.start(1);
+    
+#if defined(TARGET_LPC1768)
+    const int nTest=7;
+    const int freq[nTest]=  {1e5,   1e5,    1e5,   4e5,    4e5,    4e5,    4e5};
+    const int len[nTest]=   {1,     4,      6,      1,     6,     12,      29};
+#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);
+        Thread::wait(500);
+        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);
+        g_disco=10;
+        while(g_disco>0);
+    }
+    return 0;
+}
+
+void readModWrite(I2CMasterRtos& i2c, uint8_t reg, uint8_t dta)
+{   
+    char rd1;
+    int rStat1 = i2c.read(i2cAdr, reg, &rd1, 1);
+    char data[2];
+    data[0]=(char)reg;
+    data[1]=(char)dta;
+    char rd2;
+    int wStat = i2c.write(i2cAdr, data, 2);
+    osDelay(100);
+    int rStat2 = i2c.read(i2cAdr, reg, &rd2, 1);
+    printf("%2d%2d%2d  %2x <- %2x  => %2x -> %2x \n", rStat1, wStat, rStat2, reg, dta, rd1, rd2);
+}
+
+static void config(I2CMasterRtos& i2c)
+{
+    uint8_t ncfg=32;
+    uint8_t regs[ncfg];
+    uint8_t vals[ncfg];
+    int cnt=0;
+    regs[cnt]=0x6b;
+    vals[cnt++]=(1<<7); // pwr 1 reg //: device reset
+    regs[cnt]=0x6b;
+    vals[cnt++]=1; // pwr 1 reg // clock from x gyro all pwr sav modes off
+    regs[cnt]=0x19;
+    vals[cnt++]=0;  // sample rate divider reg  // sapmle rate = gyro rate / (1+x)
+    regs[cnt]=0x1a;
+    vals[cnt++]=0;// conf  reg // no ext frame sync / no dig low pass set to 1 => 8kHz Sampling 
+    regs[cnt]=0x1b;
+    vals[cnt++]=0;// gyro conf  reg // no test mode and gyro range 250°/s
+    regs[cnt]=0x1c;
+    vals[cnt++]=0;// accl conf  reg // no test mode and accl range 2g
+    regs[cnt]=0x23;
+    vals[cnt++]=0xf<<3;// fifo conf  reg // accl + all gyro -> fifo
+    regs[cnt]=0x6a;
+    vals[cnt++]=(1<<2); // pwr 1 reg // fifo reset
+    regs[cnt]=0x6a;
+    vals[cnt++]=(1<<6); // pwr 1 reg // fifo on
+
+    for(int i=0; i<cnt; i++)
+        readModWrite(i2c, regs[i], vals[i]);
+}
\ No newline at end of file
--- a/I2CMasterRtos.h	Sat Apr 20 20:06:44 2013 +0000
+++ b/I2CMasterRtos.h	Sun Apr 28 15:08:04 2013 +0000
@@ -64,7 +64,7 @@
     *       0 on success (ack),
     *   non-0 on failure (nack)
     */
-    int read(int address, uint8_t _register, char *data, int length, bool repeated = false) {
+    int read(int address, uint8_t _register, char* data, int length, bool repeated = false) {
         return m_drv.readMaster( address, _register, data, length, repeated);
     }
 
--- a/mbed-NXP.lib	Sat Apr 20 20:06:44 2013 +0000
+++ b/mbed-NXP.lib	Sun Apr 28 15:08:04 2013 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/humlet/code/mbed-NXP/#9b3db7ced428
+http://mbed.org/users/humlet/code/mbed-NXP/#5e7f2f37d75b