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