]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/tests/peripherals/MMA7660/MMA7660.cpp
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / tests / peripherals / MMA7660 / MMA7660.cpp
1 #include "MMA7660.h"
2
3 MMA7660::MMA7660(PinName sda, PinName scl, bool active) : _i2c(sda, scl)
4 {
5     setActive(active);
6     samplerate = 64;
7
8 }
9
10 //Since the MMA lacks a WHO_AM_I register, we can only check if there is a device that answers to the I2C address
11 bool MMA7660::testConnection( void )
12 {
13     if (_i2c.write(MMA7660_ADDRESS, NULL, 0) == 0 )
14         return true;
15     else
16         return false;
17 }
18
19 void MMA7660::setActive(bool state)
20 {
21     char modereg = read(MMA7660_MODE_R);
22     modereg &= ~(1<<0);
23
24     //If it somehow was in testmode, disable that
25     if (modereg && (1<<2)) {
26         modereg &= ~(1<<2);
27         write(MMA7660_MODE_R, modereg);
28     }
29
30     modereg += state;
31     write(MMA7660_MODE_R, modereg);
32 }
33
34 void MMA7660::readData(int *data)
35 {
36     if (!active) {
37         setActive(true);
38         active = true;
39         wait(0.012 + 1/samplerate); //Wait until new sample is ready, my experience is that 1/samplerate isnt needed, but datasheet says so
40     }
41
42     char temp[3];
43     bool alert;
44
45     do {
46         alert = false;
47         read(MMA7660_XOUT_R, temp, 3);
48         for (int i = 0; i<3; i++) {
49             if (temp[i] > 63)
50                 alert = true;
51             if (temp[i] > 31)
52                 temp[i] += 128+64;
53             data[i] = (signed char)temp[i];
54         }
55     } while (alert);
56
57     if (!active)
58         setActive(false);
59 }
60
61
62 void MMA7660::readData(float *data)
63 {
64     int intdata[3];
65     readData(intdata);
66     for (int i = 0; i<3; i++)
67         data[i] = intdata[i]/MMA7660_SENSITIVITY;
68 }
69
70 float MMA7660::x( void )
71 {
72     return getSingle(0);
73 }
74
75 float MMA7660::y( void )
76 {
77     return getSingle(1);
78 }
79
80 float MMA7660::z( void )
81 {
82     return getSingle(2);
83 }
84
85
86 void MMA7660::setSampleRate(int samplerate)
87 {
88     setActive(false);                               //Not allowed to be active to change anything
89     int rates[] = {120, 64, 32, 16, 8, 4, 2, 1};    //Alowed samplerates (and their number in array is also number required for MMA)
90     int sampleLoc = 0, sampleError = 10000, temp;
91     for (int i = 0; i<8; i++) {
92         temp = abs( rates[i] - samplerate );
93         if (temp<sampleError) {
94             sampleLoc = i;
95             sampleError=temp;
96         }
97     }
98
99     //Update the samplerate reg
100     temp = read(MMA7660_SR_R);
101     temp &= ~0x07;                                  //Awake sample rate are lowest 3 bit
102     temp |= sampleLoc;
103     write(MMA7660_SR_R, temp);
104     this->samplerate = rates[sampleLoc];
105     setActive(active);                              //Restore previous active state
106 }
107
108
109 MMA7660::Orientation MMA7660::getSide( void )
110 {
111     char tiltreg = read(MMA7660_TILT_R);
112
113     //We care about 2 LSBs
114     tiltreg &= 0x03;
115     if (tiltreg == 0x01)
116         return MMA7660::Front;
117     if (tiltreg == 0x02)
118         return MMA7660::Back;
119     return MMA7660::Unknown;
120 }
121
122 MMA7660::Orientation MMA7660::getOrientation( void )
123 {
124     char tiltreg = read(MMA7660_TILT_R);
125
126     //We care about bit 2, 3 and 4 (counting from zero)
127     tiltreg &= 0x07<<2;
128     tiltreg >>= 2;
129     if (tiltreg == 0x01)
130         return MMA7660::Left;
131     if (tiltreg == 0x02)
132         return MMA7660::Right;
133     if (tiltreg == 0x05)
134         return MMA7660::Down;
135     if (tiltreg == 0x06)
136         return MMA7660::Up;
137     return MMA7660::Unknown;
138 }
139
140
141
142 //////////////////////////////////////////////
143 ///////////////PRIVATE////////////////////////
144 //////////////////////////////////////////////
145
146
147 void MMA7660::write(char address, char data)
148 {
149     char temp[2];
150     temp[0]=address;
151     temp[1]=data;
152
153     _i2c.write(MMA7660_ADDRESS, temp, 2);
154 }
155
156 char MMA7660::read(char address)
157 {
158     char retval;
159     _i2c.write(MMA7660_ADDRESS, &address, 1, true);
160     _i2c.read(MMA7660_ADDRESS, &retval, 1);
161     return retval;
162 }
163
164 void MMA7660::read(char address, char *data, int length)
165 {
166     _i2c.write(MMA7660_ADDRESS, &address, 1, true);
167     _i2c.read(MMA7660_ADDRESS, data, length);
168 }
169
170 float MMA7660::getSingle( int number )
171 {
172     if (!active) {
173         setActive(true);
174         wait(0.012 + 1/samplerate); //Wait until new sample is ready
175     }
176
177     signed char temp;
178     bool alert;
179
180     do {
181         alert = false;
182         temp = read(MMA7660_XOUT_R + number);
183         if (temp > 63)
184             alert = true;
185         if (temp > 31)
186             temp += 128+64;
187     } while (alert);
188
189     if (!active)
190         setActive(false);
191
192     return temp / MMA7660_SENSITIVITY;
193 }