|
@@ -0,0 +1,222 @@
|
|
1
|
+/*
|
|
2
|
+ * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
|
|
3
|
+ * Copyright (c) 2014 Intel Corporation.
|
|
4
|
+ *
|
|
5
|
+ * Permission is hereby granted, free of charge, to any person obtaining
|
|
6
|
+ * a copy of this software and associated documentation files (the
|
|
7
|
+ * "Software"), to deal in the Software without restriction, including
|
|
8
|
+ * without limitation the rights to use, copy, modify, merge, publish,
|
|
9
|
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
|
10
|
+ * permit persons to whom the Software is furnished to do so, subject to
|
|
11
|
+ * the following conditions:
|
|
12
|
+ *
|
|
13
|
+ * The above copyright notice and this permission notice shall be
|
|
14
|
+ * included in all copies or substantial portions of the Software.
|
|
15
|
+ *
|
|
16
|
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
19
|
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
20
|
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
21
|
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
22
|
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+ */
|
|
24
|
+
|
|
25
|
+#include <iostream>
|
|
26
|
+#include <unistd.h>
|
|
27
|
+#include <stdlib.h>
|
|
28
|
+
|
|
29
|
+#include "gy65.h"
|
|
30
|
+
|
|
31
|
+using namespace upm;
|
|
32
|
+
|
|
33
|
+GY65::GY65 (int bus, int devAddr, uint8_t mode) {
|
|
34
|
+ m_name = "GY65";
|
|
35
|
+
|
|
36
|
+ m_controlAddr = devAddr;
|
|
37
|
+ m_bus = bus;
|
|
38
|
+
|
|
39
|
+ m_i2ControlCtx = maa_i2c_init(m_bus);
|
|
40
|
+
|
|
41
|
+ maa_result_t ret = maa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
|
42
|
+ if (ret != MAA_SUCCESS) {
|
|
43
|
+ fprintf(stderr, "Messed up i2c bus\n");
|
|
44
|
+ }
|
|
45
|
+
|
|
46
|
+ if (i2cReadReg_8 (0xD0) != 0x55) {
|
|
47
|
+ std::cout << "Error :: Cannot continue" << std::endl;
|
|
48
|
+ return;
|
|
49
|
+ }
|
|
50
|
+
|
|
51
|
+ if (mode > BMP085_ULTRAHIGHRES) {
|
|
52
|
+ mode = BMP085_ULTRAHIGHRES;
|
|
53
|
+ }
|
|
54
|
+ oversampling = mode;
|
|
55
|
+
|
|
56
|
+ /* read calibration data */
|
|
57
|
+ ac1 = i2cReadReg_16 (BMP085_CAL_AC1);
|
|
58
|
+ ac2 = i2cReadReg_16 (BMP085_CAL_AC2);
|
|
59
|
+ ac3 = i2cReadReg_16 (BMP085_CAL_AC3);
|
|
60
|
+ ac4 = i2cReadReg_16 (BMP085_CAL_AC4);
|
|
61
|
+ ac5 = i2cReadReg_16 (BMP085_CAL_AC5);
|
|
62
|
+ ac6 = i2cReadReg_16 (BMP085_CAL_AC6);
|
|
63
|
+
|
|
64
|
+ b1 = i2cReadReg_16 (BMP085_CAL_B1);
|
|
65
|
+ b2 = i2cReadReg_16 (BMP085_CAL_B2);
|
|
66
|
+
|
|
67
|
+ mb = i2cReadReg_16 (BMP085_CAL_MB);
|
|
68
|
+ mc = i2cReadReg_16 (BMP085_CAL_MC);
|
|
69
|
+ md = i2cReadReg_16 (BMP085_CAL_MD);
|
|
70
|
+}
|
|
71
|
+
|
|
72
|
+GY65::~GY65() {
|
|
73
|
+ maa_i2c_stop(m_i2ControlCtx);
|
|
74
|
+}
|
|
75
|
+
|
|
76
|
+int32_t
|
|
77
|
+GY65::getPressure () {
|
|
78
|
+ int32_t UT, UP, B3, B5, B6, X1, X2, X3, p;
|
|
79
|
+ uint32_t B4, B7;
|
|
80
|
+
|
|
81
|
+ UT = getTemperatureRaw();
|
|
82
|
+ UP = getPressureRaw();
|
|
83
|
+ B5 = computeB5(UT);
|
|
84
|
+
|
|
85
|
+ // do pressure calcs
|
|
86
|
+ B6 = B5 - 4000;
|
|
87
|
+ X1 = ((int32_t)b2 * ( (B6 * B6)>>12 )) >> 11;
|
|
88
|
+ X2 = ((int32_t)ac2 * B6) >> 11;
|
|
89
|
+ X3 = X1 + X2;
|
|
90
|
+ B3 = ((((int32_t)ac1*4 + X3) << oversampling) + 2) / 4;
|
|
91
|
+
|
|
92
|
+ X1 = ((int32_t)ac3 * B6) >> 13;
|
|
93
|
+ X2 = ((int32_t)b1 * ((B6 * B6) >> 12)) >> 16;
|
|
94
|
+ X3 = ((X1 + X2) + 2) >> 2;
|
|
95
|
+ B4 = ((uint32_t)ac4 * (uint32_t)(X3 + 32768)) >> 15;
|
|
96
|
+ B7 = ((uint32_t)UP - B3) * (uint32_t)( 50000UL >> oversampling );
|
|
97
|
+
|
|
98
|
+ if (B7 < 0x80000000) {
|
|
99
|
+ p = (B7 * 2) / B4;
|
|
100
|
+ } else {
|
|
101
|
+ p = (B7 / B4) * 2;
|
|
102
|
+ }
|
|
103
|
+ X1 = (p >> 8) * (p >> 8);
|
|
104
|
+ X1 = (X1 * 3038) >> 16;
|
|
105
|
+ X2 = (-7357 * p) >> 16;
|
|
106
|
+
|
|
107
|
+ p = p + ((X1 + X2 + (int32_t)3791)>>4);
|
|
108
|
+
|
|
109
|
+ return p;
|
|
110
|
+}
|
|
111
|
+
|
|
112
|
+int32_t
|
|
113
|
+GY65::getPressureRaw () {
|
|
114
|
+ uint32_t raw;
|
|
115
|
+
|
|
116
|
+ i2cWriteReg (BMP085_CONTROL, BMP085_READPRESSURECMD + (oversampling << 6));
|
|
117
|
+
|
|
118
|
+ if (oversampling == BMP085_ULTRALOWPOWER) {
|
|
119
|
+ usleep(5000);
|
|
120
|
+ } else if (oversampling == BMP085_STANDARD) {
|
|
121
|
+ usleep(8000);
|
|
122
|
+ } else if (oversampling == BMP085_HIGHRES) {
|
|
123
|
+ usleep(14000);
|
|
124
|
+ } else {
|
|
125
|
+ usleep(26000);
|
|
126
|
+ }
|
|
127
|
+
|
|
128
|
+ raw = i2cReadReg_16 (BMP085_PRESSUREDATA);
|
|
129
|
+
|
|
130
|
+ raw <<= 8;
|
|
131
|
+ raw |= i2cReadReg_8 (BMP085_PRESSUREDATA + 2);
|
|
132
|
+ raw >>= (8 - oversampling);
|
|
133
|
+
|
|
134
|
+ return raw;
|
|
135
|
+}
|
|
136
|
+
|
|
137
|
+int16_t
|
|
138
|
+GY65::getTemperatureRaw () {
|
|
139
|
+ i2cWriteReg (BMP085_CONTROL, BMP085_READTEMPCMD);
|
|
140
|
+ usleep(5000);
|
|
141
|
+ return i2cReadReg_16 (BMP085_TEMPDATA);
|
|
142
|
+}
|
|
143
|
+
|
|
144
|
+float
|
|
145
|
+GY65::getTemperature () {
|
|
146
|
+ int32_t UT, B5; // following ds convention
|
|
147
|
+ float temp;
|
|
148
|
+
|
|
149
|
+ UT = getTemperatureRaw ();
|
|
150
|
+
|
|
151
|
+ B5 = computeB5 (UT);
|
|
152
|
+ temp = (B5 + 8) >> 4;
|
|
153
|
+ temp /= 10;
|
|
154
|
+
|
|
155
|
+ return temp;
|
|
156
|
+}
|
|
157
|
+
|
|
158
|
+int32_t
|
|
159
|
+GY65::getSealevelPressure(float altitudeMeters) {
|
|
160
|
+ float pressure = getPressure ();
|
|
161
|
+ return (int32_t)(pressure / pow(1.0-altitudeMeters/44330, 5.255));
|
|
162
|
+}
|
|
163
|
+
|
|
164
|
+float
|
|
165
|
+GY65::getAltitude (float sealevelPressure) {
|
|
166
|
+ float altitude;
|
|
167
|
+
|
|
168
|
+ float pressure = getPressure ();
|
|
169
|
+
|
|
170
|
+ altitude = 44330 * (1.0 - pow(pressure /sealevelPressure,0.1903));
|
|
171
|
+
|
|
172
|
+ return altitude;
|
|
173
|
+}
|
|
174
|
+
|
|
175
|
+int32_t
|
|
176
|
+GY65::computeB5(int32_t UT) {
|
|
177
|
+ int32_t X1 = (UT - (int32_t)ac6) * ((int32_t)ac5) >> 15;
|
|
178
|
+ int32_t X2 = ((int32_t)mc << 11) / (X1+(int32_t)md);
|
|
179
|
+
|
|
180
|
+ return X1 + X2;
|
|
181
|
+}
|
|
182
|
+
|
|
183
|
+maa_result_t
|
|
184
|
+GY65::i2cWriteReg (uint8_t reg, uint8_t value) {
|
|
185
|
+ maa_result_t error = MAA_SUCCESS;
|
|
186
|
+
|
|
187
|
+ uint8_t data[2] = { reg, value };
|
|
188
|
+ error = maa_i2c_address (m_i2ControlCtx, m_controlAddr);
|
|
189
|
+ error = maa_i2c_write (m_i2ControlCtx, data, 2);
|
|
190
|
+
|
|
191
|
+ return error;
|
|
192
|
+}
|
|
193
|
+
|
|
194
|
+uint16_t
|
|
195
|
+GY65::i2cReadReg_16 (int reg) {
|
|
196
|
+ uint16_t data;
|
|
197
|
+
|
|
198
|
+ maa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
|
199
|
+ maa_i2c_write_byte(m_i2ControlCtx, reg);
|
|
200
|
+
|
|
201
|
+ maa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
|
202
|
+ maa_i2c_read(m_i2ControlCtx, (uint8_t *)&data, 0x2);
|
|
203
|
+
|
|
204
|
+ uint8_t high = (data & 0xFF00) >> 8;
|
|
205
|
+ data = (data << 8) & 0xFF00;
|
|
206
|
+ data |= high;
|
|
207
|
+
|
|
208
|
+ return data;
|
|
209
|
+}
|
|
210
|
+
|
|
211
|
+uint8_t
|
|
212
|
+GY65::i2cReadReg_8 (int reg) {
|
|
213
|
+ uint8_t data;
|
|
214
|
+
|
|
215
|
+ maa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
|
216
|
+ maa_i2c_write_byte(m_i2ControlCtx, reg);
|
|
217
|
+
|
|
218
|
+ maa_i2c_address(m_i2ControlCtx, m_controlAddr);
|
|
219
|
+ maa_i2c_read(m_i2ControlCtx, &data, 0x1);
|
|
220
|
+
|
|
221
|
+ return data;
|
|
222
|
+}
|