1 /*
2 * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3 */
4
5 #include "drv_baro_goertek_spl06.h"
6 #include "aos/hal/i2c.h"
7 #include "ulog/ulog.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10
11 #define SPL06_I2C_PORT 1
12
13 uint8_t EEPROM_CHIP_ADDRESS = 0x77;
14
15 static void
i2c_eeprom_write_uint8_t(uint8_t deviceaddress,uint8_t eeaddress,uint8_t data)16 i2c_eeprom_write_uint8_t(uint8_t deviceaddress, uint8_t eeaddress, uint8_t data)
17 {
18 uint8_t write_buffer[2] = {eeaddress, data};
19 sensor_i2c_master_send(SPL06_I2C_PORT, EEPROM_CHIP_ADDRESS, write_buffer, 2, 1000);
20 }
21
i2c_eeprom_read_uint8_t(uint8_t deviceaddress,uint8_t eeaddress)22 static uint8_t i2c_eeprom_read_uint8_t(uint8_t deviceaddress, uint8_t eeaddress)
23 {
24 uint8_t data;
25
26 sensor_i2c_master_send(SPL06_I2C_PORT, EEPROM_CHIP_ADDRESS, &eeaddress, 1, 1000);
27 aos_msleep(2);
28 sensor_i2c_master_recv(SPL06_I2C_PORT, EEPROM_CHIP_ADDRESS, &data, 1, 1000);
29
30 return data;
31 }
32
get_altitude(double pressure,double seaLevelhPa)33 static double get_altitude(double pressure, double seaLevelhPa)
34 {
35 if (seaLevelhPa == 0) {
36 return -1;
37 }
38
39 double altitude;
40
41 pressure /= 100;
42 altitude = 44330 * (1.0 - pow(pressure / seaLevelhPa, 0.1903));
43
44 return altitude;
45 }
46
get_temperature_scale_factor()47 static double get_temperature_scale_factor()
48 {
49 double k;
50
51 uint8_t tmp_Byte;
52 tmp_Byte = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X07); // MSB
53
54 tmp_Byte = tmp_Byte & 0B00000111;
55 // printf("tmp_Byte: %d\n", tmp_Byte);
56
57 switch (tmp_Byte) {
58 case 0B000:
59 k = 524288.0;
60 break;
61
62 case 0B001:
63 k = 1572864.0;
64 break;
65
66 case 0B010:
67 k = 3670016.0;
68 break;
69
70 case 0B011:
71 k = 7864320.0;
72 break;
73
74 case 0B100:
75 k = 253952.0;
76 break;
77
78 case 0B101:
79 k = 516096.0;
80 break;
81
82 case 0B110:
83 k = 1040384.0;
84 break;
85
86 case 0B111:
87 k = 2088960.0;
88 break;
89 default:
90 break;
91 }
92 return k;
93 }
94
get_pressure_scale_factor()95 static double get_pressure_scale_factor()
96 {
97 double k;
98
99 uint8_t tmp_Byte;
100 tmp_Byte = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X06); // MSB
101 // tmp_Byte = tmp_Byte >> 4; //Focus on bits 6-4 - measurement rate
102 tmp_Byte = tmp_Byte & 0B00000111; // Focus on 2-0 oversampling rate
103 // tmp_Byte = 0B011;
104
105 // oversampling rate
106 switch (tmp_Byte) {
107 case 0B000:
108 k = 524288.0;
109 break;
110
111 case 0B001:
112 k = 1572864.0;
113 break;
114
115 case 0B010:
116 k = 3670016.0;
117 break;
118
119 case 0B011:
120 k = 7864320.0;
121 break;
122
123 case 0B100:
124 k = 253952.0;
125 break;
126
127 case 0B101:
128 k = 516096.0;
129 break;
130
131 case 0B110:
132 k = 1040384.0;
133 break;
134
135 case 0B111:
136 k = 2088960.0;
137 break;
138
139 default:
140 break;
141 }
142 return k;
143 }
144
get_traw()145 static int32_t get_traw()
146 {
147 int32_t tmp;
148 uint8_t tmp_MSB, tmp_LSB, tmp_XLSB;
149 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X03); // MSB
150 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X04); // LSB
151 tmp_XLSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X05); // XLSB
152
153 tmp = (tmp_MSB << 8) | tmp_LSB;
154 tmp = (tmp << 8) | tmp_XLSB;
155
156 if (tmp & (1 << 23))
157 tmp = tmp | 0XFF000000; // Set left bits to one for 2's complement
158 // conversion of negitive number
159 return tmp;
160 }
161
get_praw()162 static int32_t get_praw()
163 {
164 int32_t tmp;
165 uint8_t tmp_MSB, tmp_LSB, tmp_XLSB;
166 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X00); // MSB
167 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X01); // LSB
168 tmp_XLSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X02); // XLSB
169
170 tmp = (tmp_MSB << 8) | tmp_LSB;
171 tmp = (tmp << 8) | tmp_XLSB;
172
173 if (tmp & (1 << 23))
174 tmp = tmp | 0XFF000000; // Set left bits to one for 2's complement
175 // conversion of negitive number
176 return tmp;
177 }
178
get_c0()179 static int16_t get_c0()
180 {
181 int16_t tmp;
182 uint8_t tmp_MSB, tmp_LSB;
183
184 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X10);
185 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X11);
186
187 tmp_LSB = tmp_LSB >> 4;
188
189 tmp = (tmp_MSB << 4) | tmp_LSB;
190
191 if (tmp & (1 << 11))
192 // Check for 2's complement negative number
193 tmp = tmp | 0XF000; // Set left bits to one for 2's complement
194 // conversion of negitive number
195
196 return tmp;
197 }
198
get_c1()199 static int16_t get_c1()
200 {
201 int16_t tmp;
202 uint8_t tmp_MSB, tmp_LSB;
203
204 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X11);
205 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X12);
206
207 tmp_MSB = tmp_MSB & 0XF;
208 tmp = (tmp_MSB << 8) | tmp_LSB;
209
210 if (tmp & (1 << 11))
211 // Check for 2's complement negative number
212 tmp = tmp | 0XF000; // Set left bits to one for 2's complement
213 // conversion of negitive number
214
215 return tmp;
216 }
217
get_c00()218 static int32_t get_c00()
219 {
220 int32_t tmp;
221 uint8_t tmp_MSB, tmp_LSB, tmp_XLSB;
222
223 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X13);
224 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X14);
225 tmp_XLSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X15);
226
227 tmp_XLSB = tmp_XLSB >> 4;
228
229 tmp = (tmp_MSB << 8) | tmp_LSB;
230 tmp = (tmp << 4) | tmp_XLSB;
231
232 tmp = (uint32_t)tmp_MSB << 12 | (uint32_t)tmp_LSB << 4 |
233 (uint32_t)tmp_XLSB >> 4;
234
235 if (tmp & (1 << 19))
236 tmp = tmp | 0XFFF00000; // Set left bits to one for 2's complement
237 // conversion of negitive number
238
239 return tmp;
240 }
241
get_c10()242 static int32_t get_c10()
243 {
244 int32_t tmp;
245 uint8_t tmp_MSB, tmp_LSB, tmp_XLSB;
246
247 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X15); // 4 bits
248 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X16); // 8 bits
249 tmp_XLSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X17); // 8 bits
250
251 tmp_MSB = tmp_MSB & 0b00001111;
252
253 tmp = (tmp_MSB << 4) | tmp_LSB;
254 tmp = (tmp << 8) | tmp_XLSB;
255
256 tmp = (uint32_t)tmp_MSB << 16 | (uint32_t)tmp_LSB << 8 | (uint32_t)tmp_XLSB;
257
258 if (tmp & (1 << 19))
259 tmp = tmp | 0XFFF00000; // Set left bits to one for 2's complement
260 // conversion of negitive number
261
262 return tmp;
263 }
264
get_c01()265 static int16_t get_c01()
266 {
267 int16_t tmp;
268 uint8_t tmp_MSB, tmp_LSB;
269
270 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X18);
271 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X19);
272
273 tmp = (tmp_MSB << 8) | tmp_LSB;
274 return tmp;
275 }
276
get_c11()277 static int16_t get_c11()
278 {
279 int16_t tmp;
280 uint8_t tmp_MSB, tmp_LSB;
281
282 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X1A);
283 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X1B);
284
285 tmp = (tmp_MSB << 8) | tmp_LSB;
286 return tmp;
287 }
288
get_c20()289 static int16_t get_c20()
290 {
291 int16_t tmp;
292 uint8_t tmp_MSB, tmp_LSB;
293
294 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X1C);
295 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X1D);
296
297 tmp = (tmp_MSB << 8) | tmp_LSB;
298 return tmp;
299 }
300
get_c21()301 static int16_t get_c21()
302 {
303 int16_t tmp;
304 uint8_t tmp_MSB, tmp_LSB;
305
306 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X1E);
307 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X1F);
308
309 tmp = (tmp_MSB << 8) | tmp_LSB;
310 return tmp;
311 }
312
get_c30()313 static int16_t get_c30()
314 {
315 int16_t tmp;
316 uint8_t tmp_MSB, tmp_LSB;
317
318 tmp_MSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X20);
319 tmp_LSB = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0X21);
320
321 tmp = (tmp_MSB << 8) | tmp_LSB;
322 return tmp;
323 // printf("tmp: %d\n", tmp);
324 }
325
spl06_init(void)326 void spl06_init(void)
327 {
328 uint8_t tmp, data;
329 int32_t ret = sensor_i2c_open(SPL06_I2C_PORT, EEPROM_CHIP_ADDRESS, I2C_BUS_BIT_RATES_100K, 0);
330 if (ret) {
331 LOGE("SENSOR", "sensor i2c open failed, ret:%d\n", ret);
332 return;
333 }
334 aos_msleep(500);
335
336 // printf("\nDevice Reset\n");
337 // i2c_eeprom_write_uint8_t(EEPROM_CHIP_ADDRESS, 0X0C, 0b1001);
338 // aos_msleep(1000);
339
340 tmp = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0x0D);
341 // printf("ID: %d\n", tmp);
342 i2c_eeprom_write_uint8_t(EEPROM_CHIP_ADDRESS, 0X06,
343 0x03); // Pressure 8x oversampling
344 i2c_eeprom_write_uint8_t(EEPROM_CHIP_ADDRESS, 0X07,
345 0X83); // Temperature 8x oversampling
346 i2c_eeprom_write_uint8_t(
347 EEPROM_CHIP_ADDRESS, 0X08,
348 0B0111); // continuous temp and pressure measurement
349 // i2c_eeprom_write_uint8_t(EEPROM_CHIP_ADDRESS, 0X08, 0B0001); // standby
350 // pressure measurement
351 i2c_eeprom_write_uint8_t(EEPROM_CHIP_ADDRESS, 0X09,
352 0X00); // FIFO Pressure measurement
353 }
354
spl06_getdata(spl06_data_t * sp)355 void spl06_getdata(spl06_data_t *sp)
356 {
357 uint8_t tmp;
358 int32_t c00, c10;
359 int16_t c0, c1, c01, c11, c20, c21, c30;
360
361 // Serial.println("\nDevice Reset\n");
362 // i2c_eeprom_write_uint8_t(EEPROM_CHIP_ADDRESS, 0x0C, 0b1001);
363 // delay(1000);
364
365 tmp = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0x0D);
366 sp->id = tmp;
367 tmp = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0x06);
368 tmp = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0x07);
369 tmp = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0x08);
370 tmp = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0x09);
371 tmp = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0x0A);
372 tmp = i2c_eeprom_read_uint8_t(EEPROM_CHIP_ADDRESS, 0x0B);
373
374 c0 = get_c0();
375 c1 = get_c1();
376 c00 = get_c00();
377 c10 = get_c10();
378 c01 = get_c01();
379 c11 = get_c11();
380 c20 = get_c20();
381 c21 = get_c21();
382 c30 = get_c30();
383 int32_t traw = get_traw();
384 double traw_sc = (double)traw / get_temperature_scale_factor();
385 // printf("traw_sc: %0.2f\n", traw_sc);
386
387 sp->Ctemp = (double)c0 * 0.5f + (double)c1 * traw_sc;
388 sp->Ftemp = (sp->Ctemp * 9 / 5) + 32;
389
390 int32_t praw = get_praw();
391
392 double praw_sc = (double)(praw) / get_pressure_scale_factor();
393
394 double pcomp =
395 (double)(c00) +
396 praw_sc * ((double)(c10) +
397 praw_sc * ((double)(c20) + praw_sc * (double)(c30))) +
398 traw_sc * (double)(c01) +
399 traw_sc * praw_sc * ((double)(c11) + praw_sc * (double)(c21));
400
401 sp->pressure = pcomp / 100; // convert to mb
402
403 // double local_pressure = 1010.5; // Look up local sea level pressure on
404 // google
405 double local_pressure =
406 1011.1; // Look up local sea level pressure on google // Local pressure
407 // from airport website 8/22
408 // printf("Local Airport Sea Level Pressure: %0.2f mb\n", local_pressure);
409 sp->altitude = get_altitude(pcomp, local_pressure);
410 }
411
spl06_deinit(void)412 void spl06_deinit(void)
413 {
414 int32_t ret = sensor_i2c_close(SPL06_I2C_PORT);
415 if (ret) {
416 LOGE("SENSOR", "sensor i2c close failed, ret:%d\n", ret);
417 return;
418 }
419 }
420