3-D snake game for the mbed application board.

Dependencies:   C12832 MMA7660 mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers MMA7660.cpp Source File

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 }