1 /*
2 * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3 *
4 *
5 */
6
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "aos/kernel.h"
11 #include "sensor_drv_api.h"
12 #include "sensor_hal.h"
13
14 /* ST BARO SENSOR REGISTER MAP */
15 #define LPS35HB_BIT(x) ((uint8_t)x)
16 #define LPS35HB_ADDRESS (uint8_t)0xB8
17 #define LPS35HB_DriverVersion_Major (uint8_t)1
18 #define LPS35HB_DriverVersion_Minor (uint8_t)0
19 #define LPS35HB_DriverVersion_Point (uint8_t)0
20 #define LPS35HB_WHO_AM_I_REG (uint8_t)0x0F
21 #define LPS35HB_WHO_AM_I_VAL (uint8_t)0xB1
22 #define LPS35HB_REF_P_XL_REG (uint8_t)0x15
23 #define LPS35HB_REF_P_L_REG (uint8_t)0x16
24 #define LPS35HB_REF_P_H_REG (uint8_t)0x17
25 #define LPS35HB_RES_CONF_REG (uint8_t)0x1A
26 #define LPS35HB_RES_CONF_REG (uint8_t)0x1A
27 #define LPS35HB_RES_CONF_REG (uint8_t)0x1A
28 #define LPS35HB_LCEN_MASK (uint8_t)0x01
29 #define LPS35HB_LCEN_POWERON (uint8_t)0x00
30 #define LPS35HB_LCEN_LOWPOWER (uint8_t)0x01
31 #define LPS35HB_CTRL_REG1 (uint8_t)0x10
32 #define LPS35HB_ODR_MASK (uint8_t)0x70
33 #define LPS35HB_LPFP_MASK (uint8_t)0x08
34 #define LPS35HB_LPFP_CUTOFF_MASK (uint8_t)0x04
35 #define LPS35HB_BDU_MASK (uint8_t)0x02
36 #define LPS35HB_SIM_MASK (uint8_t)0x01
37 #define LPS35HB_LPFP_BIT LPS35HB_BIT(3)
38 #define LPS35HB_CTRL_REG2 (uint8_t)0x11
39 #define LPS35HB_BOOT_BIT LPS35HB_BIT(7)
40 #define LPS35HB_FIFO_EN_BIT LPS35HB_BIT(6)
41 #define LPS35HB_WTM_EN_BIT LPS35HB_BIT(5)
42 #define LPS35HB_ADD_INC_BIT LPS35HB_BIT(4)
43 #define LPS35HB_I2C_BIT LPS35HB_BIT(3)
44 #define LPS35HB_SW_RESET_BIT LPS35HB_BIT(2)
45 #define LPS35HB_FIFO_EN_MASK (uint8_t)0x40
46 #define LPS35HB_WTM_EN_MASK (uint8_t)0x20
47 #define LPS35HB_ADD_INC_MASK (uint8_t)0x10
48 #define LPS35HB_I2C_MASK (uint8_t)0x08
49 #define LPS35HB_ONE_SHOT_MASK (uint8_t)0x01
50 #define LPS35HB_CTRL_REG3 (uint8_t)0x12
51 #define LPS35HB_PP_OD_BIT LPS35HB_BIT(6)
52 #define LPS35HB_FIFO_FULL_BIT LPS35HB_BIT(5)
53 #define LPS35HB_FIFO_FTH_BIT LPS35HB_BIT(4)
54 #define LPS35HB_FIFO_OVR_BIT LPS35HB_BIT(3)
55 #define LPS35HB_DRDY_BIT LPS35HB_BIT(2)
56 #define LPS35HB_INT_H_L_MASK (uint8_t)0x80
57 #define LPS35HB_PP_OD_MASK (uint8_t)0x40
58 #define LPS35HB_FIFO_FULL_MASK (uint8_t)0x20
59 #define LPS35HB_FIFO_FTH_MASK (uint8_t)0x10
60 #define LPS35HB_FIFO_OVR_MASK (uint8_t)0x08
61 #define LPS35HB_DRDY_MASK (uint8_t)0x04
62 #define LPS35HB_INT_S12_MASK (uint8_t)0x03
63 #define LPS35HB_INTERRUPT_CFG_REG (uint8_t)0x0B
64 #define LPS35HB_DIFF_EN_BIT LPS35HB_BIT(3)
65 #define LPS35HB_LIR_BIT LPS35HB_BIT(2)
66 #define LPS35HB_PLE_BIT LPS35HB_BIT(1)
67 #define LPS35HB_PHE_BIT LPS35HB_BIT(0)
68 #define LPS35HB_AUTORIFP_MASK (uint8_t)0x80
69 #define LPS35HB_RESET_ARP_MASK (uint8_t)0x40
70 #define LPS35HB_AUTOZERO_MASK (uint8_t)0x20
71 #define LPS35HB_RESET_AZ_MASK (uint8_t)0x10
72 #define LPS35HB_DIFF_EN_MASK (uint8_t)0x08
73 #define LPS35HB_LIR_MASK (uint8_t)0x04
74 #define LPS35HB_PLE_MASK (uint8_t)0x02
75 #define LPS35HB_PHE_MASK (uint8_t)0x01
76 #define LPS35HB_INTERRUPT_SOURCE_REG (uint8_t)0x25
77 #define LPS35HB_BOOT_STATUS_BIT LPS35HB_BIT(7)
78 #define LPS35HB_IA_BIT LPS35HB_BIT(2)
79 #define LPS35HB_PL_BIT LPS35HB_BIT(1)
80 #define LPS35HB_PH_BIT LPS35HB_BIT(0)
81 #define LPS35HB_BOOT_STATUS_MASK (uint8_t)0x80
82 #define LPS35HB_IA_MASK (uint8_t)0x04
83 #define LPS35HB_PL_MASK (uint8_t)0x02
84 #define LPS35HB_PH_MASK (uint8_t)0x01
85 #define LPS35HB_STATUS_REG (uint8_t)0x27
86 #define LPS35HB_TOR_BIT LPS35HB_BIT(5)
87 #define LPS35HB_POR_BIT LPS35HB_BIT(4)
88 #define LPS35HB_TDA_BIT LPS35HB_BIT(1)
89 #define LPS35HB_PDA_BIT LPS35HB_BIT(0)
90 #define LPS35HB_TOR_MASK (uint8_t)0x20
91 #define LPS35HB_POR_MASK (uint8_t)0x10
92 #define LPS35HB_TDA_MASK (uint8_t)0x02
93 #define LPS35HB_PDA_MASK (uint8_t)0x01
94 #define LPS35HB_PRESS_OUT_XL_REG (uint8_t)0x28
95 #define LPS35HB_PRESS_OUT_L_REG (uint8_t)0x29
96 #define LPS35HB_PRESS_OUT_H_REG (uint8_t)0x2A
97 #define LPS35HB_TEMP_OUT_L_REG (uint8_t)0x2B
98 #define LPS35HBH_TEMP_OUT_H_REG (uint8_t)0x2C
99 #define LPS35HB_THS_P_LOW_REG (uint8_t)0x0C
100 #define LPS35HB_THS_P_HIGH_REG (uint8_t)0x0D
101 #define LPS35HB_CTRL_FIFO_REG (uint8_t)0x14
102 #define LPS35HB_FIFO_MODE_MASK (uint8_t)0xE0
103 #define LPS35HB_WTM_POINT_MASK (uint8_t)0x1F
104 #define LPS35HB_STATUS_FIFO_REG (uint8_t)0x26
105 #define LPS35HB_FTH_FIFO_BIT LPS35HB_BIT(7)
106 #define LPS35HB_OVR_FIFO_BIT LPS35HB_BIT(6)
107 #define LPS35HB_FTH_FIFO_MASK (uint8_t)0x80
108 #define LPS35HB_OVR_FIFO_MASK (uint8_t)0x40
109 #define LPS35HB_LEVEL_FIFO_MASK (uint8_t)0x3F
110 #define LPS35HB_FIFO_EMPTY (uint8_t)0x00
111 #define LPS35HB_FIFO_FULL (uint8_t)0x18
112 #define LPS35HB_RPDS_H_REG (uint8_t)0x19
113 #define LPS35HB_CLOCK_TREE_CONFIG (uint8_t)0x43
114 #define LPS35HB_CTE_MASK (uint8_t)0x20
115
116 #define LPS35HB_I2C_ADDR1_R (uint8_t)0xB9
117 #define LPS35HB_I2C_ADDR1_W (uint8_t)0xB8
118 #define LPS35HB_I2C_ADDR2_R (uint8_t)0xBB
119 #define LPS35HB_I2C_ADDR2_W (uint8_t)0xBZ
120
121 #define LPS35HB_I2C_ADDR1 (0x5C)
122 #define LPS35HB_I2C_ADDR2 (0x5D)
123 #define LPS35HB_I2C_ADDR_TRANS(n) ((n)<<1)
124 #define LPS35HB_I2C_ADDR LPS35HB_I2C_ADDR_TRANS(LPS35HB_I2C_ADDR2)
125
126
127 typedef enum {
128 LPS35HB_ODR_ONE_SHOT = (uint8_t)0x00, /*!< Output Data Rate: one shot */
129 LPS35HB_ODR_1HZ = (uint8_t)0x10, /*!< Output Data Rate: 1Hz */
130 LPS35HB_ODR_10HZ = (uint8_t)0x20, /*!< Output Data Rate: 10Hz */
131 LPS35HB_ODR_25HZ = (uint8_t)0x30, /*!< Output Data Rate: 25Hz */
132 LPS35HB_ODR_50HZ = (uint8_t)0x40, /*!< Output Data Rate: 50Hz */
133 LPS35HB_ODR_75HZ = (uint8_t)0x50 /*!< Output Data Rate: 75Hz */
134 } lps35hb_odr_e;
135
136 typedef enum {
137 LPS35HB_BDU_CONTINUOUS_UPDATE = (uint8_t)0x00, /*!< Data updated continuously */
138 LPS35HB_BDU_NO_UPDATE = (uint8_t)0x02 /*!< Data updated after a read operation */
139 } lps35hb_bdu_e;
140
141 i2c_dev_t lps35hb_ctx = {
142 .port = 3,
143 .config.address_width = 8,
144 .config.freq = 400000,
145 .config.dev_addr = LPS35HB_I2C_ADDR,
146 };
147
drv_baro_st_lps35hb_hz2odr(int hz)148 static lps35hb_odr_e drv_baro_st_lps35hb_hz2odr(int hz)
149 {
150 if(hz > 50)
151 return LPS35HB_ODR_75HZ;
152 else if(hz > 25)
153 return LPS35HB_ODR_50HZ;
154 else if(hz > 10)
155 return LPS35HB_ODR_25HZ;
156 else if(hz > 1)
157 return LPS35HB_ODR_10HZ;
158 else
159 return LPS35HB_ODR_1HZ;
160 }
161
drv_baro_st_lps35hb_validate_id(i2c_dev_t * drv,uint8_t id_value)162 static int drv_baro_st_lps35hb_validate_id(i2c_dev_t* drv, uint8_t id_value)
163 {
164 uint8_t value = 0x00;
165 int ret = 0;
166
167 if(drv == NULL){
168 return -1;
169 }
170
171 ret = sensor_i2c_read(drv, LPS35HB_WHO_AM_I_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
172 if(unlikely(ret)){
173 return ret;
174 }
175
176 if (id_value != value){
177 return -1;
178 }
179 return 0;
180 }
181
drv_baro_st_lps35hb_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)182 static int drv_baro_st_lps35hb_set_power_mode(i2c_dev_t* drv, dev_power_mode_e mode)
183 {
184 uint8_t value = 0x00;
185 int ret = 0;
186
187 ret = sensor_i2c_read(drv, LPS35HB_RES_CONF_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
188 if(unlikely(ret)){
189 return ret;
190 }
191
192 switch(mode){
193 case DEV_POWER_ON:{
194 value &= ~LPS35HB_LCEN_MASK;
195 value |= LPS35HB_LCEN_POWERON;
196 ret = sensor_i2c_write(drv, LPS35HB_RES_CONF_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
197 if(unlikely(ret)){
198 return ret;
199 }
200 }break;
201
202 case DEV_POWER_OFF:{
203 value |= LPS35HB_LCEN_LOWPOWER;
204 ret = sensor_i2c_write(drv, LPS35HB_RES_CONF_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
205 if(unlikely(ret)){
206 return ret;
207 }
208 }break;
209
210 default:break;
211 }
212 return 0;
213 }
214
drv_baro_st_lps35hb_set_odr(i2c_dev_t * drv,lps35hb_odr_e odr)215 static int drv_baro_st_lps35hb_set_odr(i2c_dev_t* drv, lps35hb_odr_e odr)
216 {
217 uint8_t value = 0x00;
218 int ret = 0;
219
220 ret = sensor_i2c_read(drv, LPS35HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
221 if(unlikely(ret)){
222 return ret;
223 }
224 value &= ~LPS35HB_ODR_MASK;
225 value |= (uint8_t)odr;
226
227 ret = sensor_i2c_write(drv, LPS35HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
228 if(unlikely(ret)){
229 return ret;
230 }
231 return 0;
232 }
233
234
drv_baro_st_lps35hb_enable_lpf(i2c_dev_t * drv)235 static int drv_baro_st_lps35hb_enable_lpf(i2c_dev_t* drv)
236 {
237 uint8_t value = 0x00;
238 int ret = 0;
239
240 ret = sensor_i2c_read(drv, LPS35HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
241 if(unlikely(ret)){
242 return ret;
243 }
244 value |= LPS35HB_LPFP_MASK | LPS35HB_LPFP_CUTOFF_MASK;
245
246 ret = sensor_i2c_write(drv, LPS35HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
247 if(unlikely(ret)){
248 return ret;
249 }
250 return 0;
251 }
252
drv_baro_st_lps35hb_set_bdu(i2c_dev_t * drv,lps35hb_bdu_e bdu)253 static int drv_baro_st_lps35hb_set_bdu(i2c_dev_t* drv, lps35hb_bdu_e bdu)
254 {
255 uint8_t value = 0x00;
256 int ret = 0;
257
258 ret = sensor_i2c_read(drv, LPS35HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
259 if(unlikely(ret)){
260 return ret;
261 }
262 value &= ~LPS35HB_BDU_MASK;
263 value |= (uint8_t)bdu;
264
265 ret = sensor_i2c_write(drv, LPS35HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES);
266 if(unlikely(ret)){
267 return ret;
268 }
269 return 0;
270 }
271
drv_baro_st_lps35hb_set_default_config(i2c_dev_t * drv)272 static int drv_baro_st_lps35hb_set_default_config(i2c_dev_t* drv)
273 {
274 int ret = 0;
275 ret = drv_baro_st_lps35hb_set_power_mode(drv, DEV_POWER_OFF);
276 if(unlikely(ret)){
277 return ret;
278 }
279 ret = drv_baro_st_lps35hb_set_odr(drv, LPS35HB_ODR_25HZ);
280 if(unlikely(ret)){
281 return ret;
282 }
283 ret = drv_baro_st_lps35hb_enable_lpf(drv);
284 if(unlikely(ret)){
285 return ret;
286 }
287
288 ret = drv_baro_st_lps35hb_set_bdu(drv, LPS35HB_BDU_NO_UPDATE);
289 if(unlikely(ret)){
290 return ret;
291 }
292 /* you also can set the low-pass filter and cut off config here */
293 return 0;
294 }
295
296
drv_baro_st_lps35hb_irq_handle(void)297 static void drv_baro_st_lps35hb_irq_handle(void)
298 {
299 /* no handle so far */
300 }
301
drv_baro_st_lps35hb_open(void)302 static int drv_baro_st_lps35hb_open(void)
303 {
304 int ret = 0;
305 ret = drv_baro_st_lps35hb_set_power_mode(&lps35hb_ctx, DEV_POWER_ON);
306 if(unlikely(ret)){
307 return -1;
308 }
309 LOG("%s %s successfully \n", SENSOR_STR, __func__);
310 return 0;
311
312 }
313
drv_baro_st_lps35hb_close(void)314 static int drv_baro_st_lps35hb_close(void)
315 {
316 int ret = 0;
317 ret = drv_baro_st_lps35hb_set_power_mode(&lps35hb_ctx, DEV_POWER_OFF);
318 if(unlikely(ret)){
319 return -1;
320 }
321 LOG("%s %s successfully \n", SENSOR_STR, __func__);
322 return 0;
323 }
324
325
drv_baro_st_lps35hb_read(void * buf,size_t len)326 static int drv_baro_st_lps35hb_read(void *buf, size_t len)
327 {
328 int ret = 0;
329 size_t size;
330 uint8_t data[3];
331 barometer_data_t* pdata = (barometer_data_t*)buf;
332 if(buf == NULL){
333 return -1;
334 }
335
336 size = sizeof(barometer_data_t);
337 if(len < size){
338 return -1;
339 }
340
341 ret = sensor_i2c_read(&lps35hb_ctx, LPS35HB_PRESS_OUT_XL_REG, &data[0], I2C_DATA_LEN, I2C_OP_RETRIES);
342 ret |= sensor_i2c_read(&lps35hb_ctx, LPS35HB_PRESS_OUT_L_REG, &data[1], I2C_DATA_LEN, I2C_OP_RETRIES);
343 ret |= sensor_i2c_read(&lps35hb_ctx, LPS35HB_PRESS_OUT_H_REG, &data[2], I2C_DATA_LEN, I2C_OP_RETRIES);
344 if(unlikely(ret)){
345 return -1;
346 }
347
348 /* hatch the baro data here*/
349 for(int i=0; i<3; i++){
350 pdata->p |= (((uint32_t)data[i]) << (8*i));
351 }
352
353 /* convert the 2's complement 24 bit to 2's complement 32 bit */
354 if((pdata->p & 0x00800000) != 0){
355 pdata->p |= 0xFF000000;
356 }
357 pdata->p = ((pdata->p)*100)/4096;
358 //pdata->p = pdata->p/100;
359 pdata->timestamp = aos_now_ms();
360
361 return (int)size;
362 }
363
drv_baro_st_lps35hb_write(const void * buf,size_t len)364 static int drv_baro_st_lps35hb_write(const void *buf, size_t len)
365 {
366 return 0;
367 }
368
drv_baro_st_lps35hb_ioctl(int cmd,unsigned long arg)369 static int drv_baro_st_lps35hb_ioctl(int cmd, unsigned long arg)
370 {
371 int ret = 0;
372
373 switch(cmd){
374 case SENSOR_IOCTL_ODR_SET:{
375 lps35hb_odr_e odr = drv_baro_st_lps35hb_hz2odr(arg);
376 ret = drv_baro_st_lps35hb_set_odr(&lps35hb_ctx, odr);
377 if(unlikely(ret)){
378 return -1;
379 }
380 }break;
381 case SENSOR_IOCTL_SET_POWER:{
382 ret = drv_baro_st_lps35hb_set_power_mode(&lps35hb_ctx, arg);
383 if(unlikely(ret)){
384 return -1;
385 }
386 }break;
387 case SENSOR_IOCTL_GET_INFO:{
388 /* fill the dev info here */
389 dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
390 info->model = "LPS35HB";
391 info->range_max = 1260;
392 info->range_min = 260;
393 info->unit = pa;
394
395 }break;
396
397 default:break;
398 }
399
400 LOG("%s %s successfully \n", SENSOR_STR, __func__);
401 return 0;
402 }
403
drv_baro_st_lps35hb_init(void)404 int drv_baro_st_lps35hb_init(void){
405 int ret = 0;
406 sensor_obj_t sensor;
407 memset(&sensor, 0, sizeof(sensor));
408
409 /* fill the sensor obj parameters here */
410 sensor.tag = TAG_DEV_BARO;
411 sensor.path = dev_baro_path;
412 sensor.io_port = I2C_PORT;
413 sensor.open = drv_baro_st_lps35hb_open;
414 sensor.close = drv_baro_st_lps35hb_close;
415 sensor.read = drv_baro_st_lps35hb_read;
416 sensor.write = drv_baro_st_lps35hb_write;
417 sensor.ioctl = drv_baro_st_lps35hb_ioctl;
418 sensor.irq_handle = drv_baro_st_lps35hb_irq_handle;
419
420
421 ret = sensor_create_obj(&sensor);
422 if(unlikely(ret)){
423 return -1;
424 }
425
426 ret = drv_baro_st_lps35hb_validate_id(&lps35hb_ctx, LPS35HB_WHO_AM_I_VAL);
427 if(unlikely(ret)){
428 return -1;
429 }
430 /* set the default config for the sensor here */
431 ret = drv_baro_st_lps35hb_set_default_config(&lps35hb_ctx);
432 if(unlikely(ret)){
433 return -1;
434 }
435
436 LOG("%s %s successfully \n", SENSOR_STR, __func__);
437 return 0;
438 }
439
440 SENSOR_DRV_ADD(drv_baro_st_lps35hb_init);
441
442