RTOS enabled i2c-driver based on the official i2c-C-api.
Fork of mbed-RtosI2cDriver by
I2CDriverTest04.h
00001 // A high prio thread reads at a rate of 1kHz from a MPU6050 gyro/acc meter's FIFO 00002 // data packets of different size, whereas the lower prio ain thread the CPU time left. 00003 00004 #include "mbed.h" 00005 #include "rtos.h" 00006 #include "I2CMasterRtos.h" 00007 #include "stdint.h" 00008 00009 //#include "DigitalOut.h" 00010 //DigitalOut osci(p8); 00011 00012 volatile int g_disco=0; 00013 volatile int g_len=0; 00014 volatile int g_freq=100000; 00015 const uint32_t i2cAdr = 0x68<<1; 00016 00017 static void config(I2CMasterRtos& i2c); 00018 00019 I2CMasterRtos i2c(p28, p27); 00020 00021 void highPrioCallBck(void const *args) 00022 { 00023 //I2CDriver::osci2.write(0); 00024 const char reg= 0x74; 00025 static char result[64]; 00026 //I2CDriver::osci2.write(1); 00027 // read from MPU600's fifo 00028 i2c.frequency(g_freq); 00029 uint32_t t1=us_ticker_read(); 00030 //I2CDriver::osci2.write(0); 00031 int stat = i2c.read(i2cAdr, reg, result, g_len); 00032 uint32_t dt=us_ticker_read()-t1; 00033 if(stat!=0) { 00034 printf("\n%x %d %d %d\n",stat,g_freq,g_len,dt); 00035 exit(0); 00036 } 00037 int16_t val=((static_cast<int16_t>(result[0])<<8)|static_cast<int16_t>(result[1])); 00038 00039 if(--g_disco>0)printf("val=%8d dt=%4dus\n",val,dt); 00040 } 00041 00042 int doit() 00043 { 00044 config(i2c); 00045 00046 RtosTimer highPrioTicker(highPrioCallBck, osTimerPeriodic, (void *)0); 00047 00048 Thread::wait(500); 00049 highPrioTicker.start(1); 00050 00051 #if defined(TARGET_LPC1768) 00052 const int nTest=7; 00053 const int freq[nTest]= {1e5, 1e5, 1e5, 4e5, 4e5, 4e5, 4e5}; 00054 const int len[nTest]= {1, 4, 7, 1, 6, 12, 36}; 00055 #elif defined(TARGET_LPC11U24) 00056 const int nTest=5; 00057 const int freq[nTest]= {1e5, 1e5, 4e5, 4e5, 4e5 }; 00058 const int len[nTest]= {1, 6, 1, 6, 32}; 00059 #endif 00060 for(int i=0; i<nTest; ++i) { 00061 g_freq = freq[i]; 00062 g_len = len[i]; 00063 printf("f=%d l=%d\n",g_freq,g_len); 00064 Thread::wait(500); 00065 //highPrioTicker.start(1); 00066 const uint32_t dt=1e6; 00067 uint32_t tStart = us_ticker_read(); 00068 uint32_t tLast = tStart; 00069 uint32_t tAct = tStart; 00070 uint32_t tMe=0; 00071 do { // loop an count consecutive µs ticker edges 00072 //osci.write(!osci.read()); 00073 tAct=us_ticker_read(); 00074 #if defined(TARGET_LPC1768) 00075 if(tAct==tLast+1)++tMe; 00076 #elif defined(TARGET_LPC11U24) 00077 uint32_t delta = tAct-tLast; 00078 if(delta<=2)tMe+=delta; // on the 11U24 this loop takes a bit longer than 1µs (ISR ~3µs, task switch ~8µs) 00079 #endif 00080 tLast=tAct; 00081 } while(tAct-tStart<dt); 00082 //highPrioTicker.stop(); 00083 // and calculate the duty cycle from this measurement 00084 printf("dc=%5.2f \n", 100.0*(float)tMe/dt); 00085 g_disco=5; 00086 while(g_disco>0); 00087 } 00088 return 0; 00089 } 00090 00091 void readModWrite(I2CMasterRtos& i2c, uint8_t reg, uint8_t dta) 00092 { 00093 char rd1; 00094 int rStat1 = i2c.read(i2cAdr, reg, &rd1, 1); 00095 char data[2]; 00096 data[0]=(char)reg; 00097 data[1]=(char)dta; 00098 char rd2; 00099 int wStat = i2c.write(i2cAdr, data, 2); 00100 osDelay(100); 00101 int rStat2 = i2c.read(i2cAdr, reg, &rd2, 1); 00102 printf("(%3x%3x%3x) %2x <- %2x => %2x -> %2x \n", rStat1, wStat, rStat2, reg, dta, rd1, rd2); 00103 } 00104 00105 static void config(I2CMasterRtos& i2c) 00106 { 00107 uint8_t ncfg=32; 00108 uint8_t regs[ncfg]; 00109 uint8_t vals[ncfg]; 00110 int cnt=0; 00111 regs[cnt]=0x6b; 00112 vals[cnt++]=(1<<7); // pwr 1 reg //: device reset 00113 regs[cnt]=0x6b; 00114 vals[cnt++]=1; // pwr 1 reg // clock from x gyro all pwr sav modes off 00115 regs[cnt]=0x19; 00116 vals[cnt++]=0; // sample rate divider reg // sapmle rate = gyro rate / (1+x) 00117 regs[cnt]=0x1a; 00118 vals[cnt++]=0;// conf reg // no ext frame sync / no dig low pass set to 1 => 8kHz Sampling 00119 regs[cnt]=0x1b; 00120 vals[cnt++]=0;// gyro conf reg // no test mode and gyro range 250°/s 00121 regs[cnt]=0x1c; 00122 vals[cnt++]=0;// accl conf reg // no test mode and accl range 2g 00123 regs[cnt]=0x23; 00124 vals[cnt++]=0xf<<3;// fifo conf reg // accl + all gyro -> fifo 00125 regs[cnt]=0x6a; 00126 vals[cnt++]=(1<<2); // pwr 1 reg // fifo reset 00127 regs[cnt]=0x6a; 00128 vals[cnt++]=(1<<6); // pwr 1 reg // fifo on 00129 00130 for(int i=0; i<cnt; i++) 00131 readModWrite(i2c, regs[i], vals[i]); 00132 }
Generated on Wed Jul 13 2022 17:20:05 by 1.7.2