Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
MMA7660.cpp
00001 #include "MMA7660.h" 00002 00003 MMA7660::MMA7660(PinName sda, PinName scl, bool active) : _i2c(sda, scl) 00004 { 00005 setActive(active); 00006 samplerate = 64; 00007 00008 } 00009 00010 //Since the MMA lacks a WHO_AM_I register, we can only check if there is a device that answers to the I2C address 00011 bool MMA7660::testConnection( void ) 00012 { 00013 if (_i2c.write(MMA7660_ADDRESS, NULL, 0) == 0 ) 00014 return true; 00015 else 00016 return false; 00017 } 00018 00019 void MMA7660::setActive(bool state) 00020 { 00021 char modereg = read(MMA7660_MODE_R); 00022 modereg &= ~(1<<0); 00023 00024 //If it somehow was in testmode, disable that 00025 if (modereg && (1<<2)) { 00026 modereg &= ~(1<<2); 00027 write(MMA7660_MODE_R, modereg); 00028 } 00029 00030 modereg += state; 00031 write(MMA7660_MODE_R, modereg); 00032 } 00033 00034 void MMA7660::readData(int *data) 00035 { 00036 if (!active) { 00037 setActive(true); 00038 active = true; 00039 wait(0.012 + 1/samplerate); //Wait until new sample is ready, my experience is that 1/samplerate isnt needed, but datasheet says so 00040 } 00041 00042 char temp[3]; 00043 bool alert; 00044 00045 do { 00046 alert = false; 00047 read(MMA7660_XOUT_R, temp, 3); 00048 for (int i = 0; i<3; i++) { 00049 if (temp[i] > 63) 00050 alert = true; 00051 if (temp[i] > 31) 00052 temp[i] += 128+64; 00053 data[i] = (signed char)temp[i]; 00054 } 00055 } while (alert); 00056 00057 if (!active) 00058 setActive(false); 00059 } 00060 00061 00062 void MMA7660::readData(float *data) 00063 { 00064 int intdata[3]; 00065 readData(intdata); 00066 for (int i = 0; i<3; i++) 00067 data[i] = intdata[i]/MMA7660_SENSITIVITY; 00068 } 00069 00070 float MMA7660::x( void ) 00071 { 00072 return getSingle(0); 00073 } 00074 00075 float MMA7660::y( void ) 00076 { 00077 return getSingle(1); 00078 } 00079 00080 float MMA7660::z( void ) 00081 { 00082 return getSingle(2); 00083 } 00084 00085 00086 void MMA7660::setSampleRate(int samplerate) 00087 { 00088 setActive(false); //Not allowed to be active to change anything 00089 int rates[] = {120, 64, 32, 16, 8, 4, 2, 1}; //Alowed samplerates (and their number in array is also number required for MMA) 00090 int sampleLoc = 0, sampleError = 10000, temp; 00091 for (int i = 0; i<8; i++) { 00092 temp = abs( rates[i] - samplerate ); 00093 if (temp<sampleError) { 00094 sampleLoc = i; 00095 sampleError=temp; 00096 } 00097 } 00098 00099 //Update the samplerate reg 00100 temp = read(MMA7660_SR_R); 00101 temp &= ~0x07; //Awake sample rate are lowest 3 bit 00102 temp |= sampleLoc; 00103 write(MMA7660_SR_R, temp); 00104 this->samplerate = rates[sampleLoc]; 00105 setActive(active); //Restore previous active state 00106 } 00107 00108 00109 MMA7660::Orientation MMA7660::getSide( void ) 00110 { 00111 char tiltreg = read(MMA7660_TILT_R); 00112 00113 //We care about 2 LSBs 00114 tiltreg &= 0x03; 00115 if (tiltreg == 0x01) 00116 return MMA7660::Front; 00117 if (tiltreg == 0x02) 00118 return MMA7660::Back; 00119 return MMA7660::Unknown; 00120 } 00121 00122 MMA7660::Orientation MMA7660::getOrientation( void ) 00123 { 00124 char tiltreg = read(MMA7660_TILT_R); 00125 00126 //We care about bit 2, 3 and 4 (counting from zero) 00127 tiltreg &= 0x07<<2; 00128 tiltreg >>= 2; 00129 if (tiltreg == 0x01) 00130 return MMA7660::Left; 00131 if (tiltreg == 0x02) 00132 return MMA7660::Right; 00133 if (tiltreg == 0x05) 00134 return MMA7660::Down; 00135 if (tiltreg == 0x06) 00136 return MMA7660::Up; 00137 return MMA7660::Unknown; 00138 } 00139 00140 00141 00142 ////////////////////////////////////////////// 00143 ///////////////PRIVATE//////////////////////// 00144 ////////////////////////////////////////////// 00145 00146 00147 void MMA7660::write(char address, char data) 00148 { 00149 char temp[2]; 00150 temp[0]=address; 00151 temp[1]=data; 00152 00153 _i2c.write(MMA7660_ADDRESS, temp, 2); 00154 } 00155 00156 char MMA7660::read(char address) 00157 { 00158 char retval; 00159 _i2c.write(MMA7660_ADDRESS, &address, 1, true); 00160 _i2c.read(MMA7660_ADDRESS, &retval, 1); 00161 return retval; 00162 } 00163 00164 void MMA7660::read(char address, char *data, int length) 00165 { 00166 _i2c.write(MMA7660_ADDRESS, &address, 1, true); 00167 _i2c.read(MMA7660_ADDRESS, data, length); 00168 } 00169 00170 float MMA7660::getSingle( int number ) 00171 { 00172 if (!active) { 00173 setActive(true); 00174 wait(0.012 + 1/samplerate); //Wait until new sample is ready 00175 } 00176 00177 signed char temp; 00178 bool alert; 00179 00180 do { 00181 alert = false; 00182 temp = read(MMA7660_XOUT_R + number); 00183 if (temp > 63) 00184 alert = true; 00185 if (temp > 31) 00186 temp += 128+64; 00187 } while (alert); 00188 00189 if (!active) 00190 setActive(false); 00191 00192 return temp / MMA7660_SENSITIVITY; 00193 }
Generated on Sun Jul 17 2022 08:25:28 by 1.7.2