]> git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/tests/peripherals/MMA7660/MMA7660.cpp
Merge commit '4d116a04e94cf0d19317d5b44e4fa9f34a3e5594'
[tmk_keyboard.git] / tmk_core / 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 }
Imprint / Impressum