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 LPS22HB_BIT(x) ((uint8_t)x)
16 #define LPS22HB_ADDRESS (uint8_t)0xB8
17 #define LPS22HB_DriverVersion_Major (uint8_t)1
18 #define LPS22HB_DriverVersion_Minor (uint8_t)0
19 #define LPS22HB_DriverVersion_Point (uint8_t)0
20 #define LPS22HB_WHO_AM_I_REG (uint8_t)0x0F
21 #define LPS22HB_WHO_AM_I_VAL (uint8_t)0xB1
22 #define LPS22HB_REF_P_XL_REG (uint8_t)0x15
23 #define LPS22HB_REF_P_L_REG (uint8_t)0x16
24 #define LPS22HB_REF_P_H_REG (uint8_t)0x17
25 #define LPS22HB_RES_CONF_REG (uint8_t)0x1A
26 #define LPS22HB_RES_CONF_REG (uint8_t)0x1A
27 #define LPS22HB_RES_CONF_REG (uint8_t)0x1A
28 #define LPS22HB_LCEN_MASK (uint8_t)0x01
29 #define LPS22HB_LCEN_POWERON (uint8_t)0x00
30 #define LPS22HB_LCEN_LOWPOWER (uint8_t)0x01
31 #define LPS22HB_CTRL_REG1 (uint8_t)0x10
32 #define LPS22HB_ODR_MASK (uint8_t)0x70
33 #define LPS22HB_LPFP_MASK (uint8_t)0x08
34 #define LPS22HB_LPFP_CUTOFF_MASK (uint8_t)0x04
35 #define LPS22HB_BDU_MASK (uint8_t)0x02
36 #define LPS22HB_SIM_MASK (uint8_t)0x01
37 #define LPS22HB_LPFP_BIT LPS22HB_BIT(3)
38 #define LPS22HB_CTRL_REG2 (uint8_t)0x11
39 #define LPS22HB_BOOT_BIT LPS22HB_BIT(7)
40 #define LPS22HB_FIFO_EN_BIT LPS22HB_BIT(6)
41 #define LPS22HB_WTM_EN_BIT LPS22HB_BIT(5)
42 #define LPS22HB_ADD_INC_BIT LPS22HB_BIT(4)
43 #define LPS22HB_I2C_BIT LPS22HB_BIT(3)
44 #define LPS22HB_SW_RESET_BIT LPS22HB_BIT(2)
45 #define LPS22HB_FIFO_EN_MASK (uint8_t)0x40
46 #define LPS22HB_WTM_EN_MASK (uint8_t)0x20
47 #define LPS22HB_ADD_INC_MASK (uint8_t)0x10
48 #define LPS22HB_I2C_MASK (uint8_t)0x08
49 #define LPS22HB_ONE_SHOT_MASK (uint8_t)0x01
50 #define LPS22HB_CTRL_REG3 (uint8_t)0x12
51 #define LPS22HB_PP_OD_BIT LPS22HB_BIT(6)
52 #define LPS22HB_FIFO_FULL_BIT LPS22HB_BIT(5)
53 #define LPS22HB_FIFO_FTH_BIT LPS22HB_BIT(4)
54 #define LPS22HB_FIFO_OVR_BIT LPS22HB_BIT(3)
55 #define LPS22HB_DRDY_BIT LPS22HB_BIT(2)
56 #define LPS22HB_INT_H_L_MASK (uint8_t)0x80
57 #define LPS22HB_PP_OD_MASK (uint8_t)0x40
58 #define LPS22HB_FIFO_FULL_MASK (uint8_t)0x20
59 #define LPS22HB_FIFO_FTH_MASK (uint8_t)0x10
60 #define LPS22HB_FIFO_OVR_MASK (uint8_t)0x08
61 #define LPS22HB_DRDY_MASK (uint8_t)0x04
62 #define LPS22HB_INT_S12_MASK (uint8_t)0x03
63 #define LPS22HB_INTERRUPT_CFG_REG (uint8_t)0x0B
64 #define LPS22HB_DIFF_EN_BIT LPS22HB_BIT(3)
65 #define LPS22HB_LIR_BIT LPS22HB_BIT(2)
66 #define LPS22HB_PLE_BIT LPS22HB_BIT(1)
67 #define LPS22HB_PHE_BIT LPS22HB_BIT(0)
68 #define LPS22HB_AUTORIFP_MASK (uint8_t)0x80
69 #define LPS22HB_RESET_ARP_MASK (uint8_t)0x40
70 #define LPS22HB_AUTOZERO_MASK (uint8_t)0x20
71 #define LPS22HB_RESET_AZ_MASK (uint8_t)0x10
72 #define LPS22HB_DIFF_EN_MASK (uint8_t)0x08
73 #define LPS22HB_LIR_MASK (uint8_t)0x04
74 #define LPS22HB_PLE_MASK (uint8_t)0x02
75 #define LPS22HB_PHE_MASK (uint8_t)0x01
76 #define LPS22HB_INTERRUPT_SOURCE_REG (uint8_t)0x25
77 #define LPS22HB_BOOT_STATUS_BIT LPS22HB_BIT(7)
78 #define LPS22HB_IA_BIT LPS22HB_BIT(2)
79 #define LPS22HB_PL_BIT LPS22HB_BIT(1)
80 #define LPS22HB_PH_BIT LPS22HB_BIT(0)
81 #define LPS22HB_BOOT_STATUS_MASK (uint8_t)0x80
82 #define LPS22HB_IA_MASK (uint8_t)0x04
83 #define LPS22HB_PL_MASK (uint8_t)0x02
84 #define LPS22HB_PH_MASK (uint8_t)0x01
85 #define LPS22HB_STATUS_REG (uint8_t)0x27
86 #define LPS22HB_TOR_BIT LPS22HB_BIT(5)
87 #define LPS22HB_POR_BIT LPS22HB_BIT(4)
88 #define LPS22HB_TDA_BIT LPS22HB_BIT(1)
89 #define LPS22HB_PDA_BIT LPS22HB_BIT(0)
90 #define LPS22HB_TOR_MASK (uint8_t)0x20
91 #define LPS22HB_POR_MASK (uint8_t)0x10
92 #define LPS22HB_TDA_MASK (uint8_t)0x02
93 #define LPS22HB_PDA_MASK (uint8_t)0x01
94 #define LPS22HB_PRESS_OUT_XL_REG (uint8_t)0x28
95 #define LPS22HB_PRESS_OUT_L_REG (uint8_t)0x29
96 #define LPS22HB_PRESS_OUT_H_REG (uint8_t)0x2A
97 #define LPS22HB_TEMP_OUT_L_REG (uint8_t)0x2B
98 #define LPS22HBH_TEMP_OUT_H_REG (uint8_t)0x2C
99 #define LPS22HB_THS_P_LOW_REG (uint8_t)0x0C
100 #define LPS22HB_THS_P_HIGH_REG (uint8_t)0x0D
101 #define LPS22HB_CTRL_FIFO_REG (uint8_t)0x14
102 #define LPS22HB_FIFO_MODE_MASK (uint8_t)0xE0
103 #define LPS22HB_WTM_POINT_MASK (uint8_t)0x1F
104 #define LPS22HB_STATUS_FIFO_REG (uint8_t)0x26
105 #define LPS22HB_FTH_FIFO_BIT LPS22HB_BIT(7)
106 #define LPS22HB_OVR_FIFO_BIT LPS22HB_BIT(6)
107 #define LPS22HB_FTH_FIFO_MASK (uint8_t)0x80
108 #define LPS22HB_OVR_FIFO_MASK (uint8_t)0x40
109 #define LPS22HB_LEVEL_FIFO_MASK (uint8_t)0x3F
110 #define LPS22HB_FIFO_EMPTY (uint8_t)0x00
111 #define LPS22HB_FIFO_FULL (uint8_t)0x18
112 #define LPS22HB_RPDS_H_REG (uint8_t)0x19
113 #define LPS22HB_CLOCK_TREE_CONFIG (uint8_t)0x43
114 #define LPS22HB_CTE_MASK (uint8_t)0x20
115
116 #define LPS22HB_I2C_ADDR1_R (uint8_t)0xB9
117 #define LPS22HB_I2C_ADDR1_W (uint8_t)0xB8
118 #define LPS22HB_I2C_ADDR2_R (uint8_t)0xBB
119 #define LPS22HB_I2C_ADDR2_W (uint8_t)0xBZ
120
121 #define LPS22HB_I2C_ADDR1 (0x5C)
122 #define LPS22HB_I2C_ADDR2 (0x5D)
123 #define LPS22HB_I2C_ADDR_TRANS(n) ((n) << 1)
124 #define LPS22HB_I2C_ADDR LPS22HB_I2C_ADDR_TRANS(LPS22HB_I2C_ADDR2)
125
126
127 typedef enum
128 {
129 LPS22HB_ODR_ONE_SHOT = (uint8_t)0x00, /*!< Output Data Rate: one shot */
130 LPS22HB_ODR_1HZ = (uint8_t)0x10, /*!< Output Data Rate: 1Hz */
131 LPS22HB_ODR_10HZ = (uint8_t)0x20, /*!< Output Data Rate: 10Hz */
132 LPS22HB_ODR_25HZ = (uint8_t)0x30, /*!< Output Data Rate: 25Hz */
133 LPS22HB_ODR_50HZ = (uint8_t)0x40, /*!< Output Data Rate: 50Hz */
134 LPS22HB_ODR_75HZ = (uint8_t)0x50 /*!< Output Data Rate: 75Hz */
135 } lps22hb_odr_e;
136
137 typedef enum
138 {
139 LPS22HB_BDU_CONTINUOUS_UPDATE =
140 (uint8_t)0x00, /*!< Data updated continuously */
141 LPS22HB_BDU_NO_UPDATE =
142 (uint8_t)0x02 /*!< Data updated after a read operation */
143 } lps22hb_bdu_e;
144
145 i2c_dev_t lps22hb_ctx = {
146 .port = 1,
147 .config.address_width = 8,
148 .config.freq = 400000,
149 .config.dev_addr = LPS22HB_I2C_ADDR,
150 };
151
drv_baro_st_lps22hb_hz2odr(int hz)152 static lps22hb_odr_e drv_baro_st_lps22hb_hz2odr(int hz)
153 {
154 if (hz > 50)
155 return LPS22HB_ODR_75HZ;
156 else if (hz > 25)
157 return LPS22HB_ODR_50HZ;
158 else if (hz > 10)
159 return LPS22HB_ODR_25HZ;
160 else if (hz > 1)
161 return LPS22HB_ODR_10HZ;
162 else
163 return LPS22HB_ODR_1HZ;
164 }
165
drv_baro_st_lps22hb_validate_id(i2c_dev_t * drv,uint8_t id_value)166 static int drv_baro_st_lps22hb_validate_id(i2c_dev_t *drv, uint8_t id_value)
167 {
168 uint8_t value = 0x00;
169 int ret = 0;
170
171 if (drv == NULL) {
172 return -1;
173 }
174
175 ret = sensor_i2c_read(drv, LPS22HB_WHO_AM_I_REG, &value, I2C_DATA_LEN,
176 I2C_OP_RETRIES);
177 if (unlikely(ret)) {
178 return ret;
179 }
180
181 if (id_value != value) {
182 return -1;
183 }
184 return 0;
185 }
186
drv_baro_st_lps22hb_set_power_mode(i2c_dev_t * drv,dev_power_mode_e mode)187 static int drv_baro_st_lps22hb_set_power_mode(i2c_dev_t * drv,
188 dev_power_mode_e mode)
189 {
190 uint8_t value = 0x00;
191 int ret = 0;
192
193 ret = sensor_i2c_read(drv, LPS22HB_RES_CONF_REG, &value, I2C_DATA_LEN,
194 I2C_OP_RETRIES);
195 if (unlikely(ret)) {
196 return ret;
197 }
198
199 switch (mode) {
200 case DEV_POWER_ON: {
201 value &= ~LPS22HB_LCEN_MASK;
202 value |= LPS22HB_LCEN_POWERON;
203 ret = sensor_i2c_write(drv, LPS22HB_RES_CONF_REG, &value,
204 I2C_DATA_LEN, I2C_OP_RETRIES);
205 if (unlikely(ret)) {
206 return ret;
207 }
208 } break;
209
210 case DEV_POWER_OFF: {
211 value |= LPS22HB_LCEN_LOWPOWER;
212 ret = sensor_i2c_write(drv, LPS22HB_RES_CONF_REG, &value,
213 I2C_DATA_LEN, I2C_OP_RETRIES);
214 if (unlikely(ret)) {
215 return ret;
216 }
217 } break;
218
219 default:
220 break;
221 }
222 return 0;
223 }
224
drv_baro_st_lps22hb_set_odr(i2c_dev_t * drv,lps22hb_odr_e odr)225 static int drv_baro_st_lps22hb_set_odr(i2c_dev_t *drv, lps22hb_odr_e odr)
226 {
227 uint8_t value = 0x00;
228 int ret = 0;
229
230 ret = sensor_i2c_read(drv, LPS22HB_CTRL_REG1, &value, I2C_DATA_LEN,
231 I2C_OP_RETRIES);
232 if (unlikely(ret)) {
233 return ret;
234 }
235 value &= ~LPS22HB_ODR_MASK;
236 value |= (uint8_t)odr;
237
238 ret = sensor_i2c_write(drv, LPS22HB_CTRL_REG1, &value, I2C_DATA_LEN,
239 I2C_OP_RETRIES);
240 if (unlikely(ret)) {
241 return ret;
242 }
243 return 0;
244 }
245
drv_baro_st_lps22hb_set_bdu(i2c_dev_t * drv,lps22hb_bdu_e bdu)246 static int drv_baro_st_lps22hb_set_bdu(i2c_dev_t *drv, lps22hb_bdu_e bdu)
247 {
248 uint8_t value = 0x00;
249 int ret = 0;
250
251 ret = sensor_i2c_read(drv, LPS22HB_CTRL_REG1, &value, I2C_DATA_LEN,
252 I2C_OP_RETRIES);
253 if (unlikely(ret)) {
254 return ret;
255 }
256 value &= ~LPS22HB_BDU_MASK;
257 value |= (uint8_t)bdu;
258
259 ret = sensor_i2c_write(drv, LPS22HB_CTRL_REG1, &value, I2C_DATA_LEN,
260 I2C_OP_RETRIES);
261 if (unlikely(ret)) {
262 return ret;
263 }
264 return 0;
265 }
266
drv_baro_st_lps22hb_set_default_config(i2c_dev_t * drv)267 static int drv_baro_st_lps22hb_set_default_config(i2c_dev_t *drv)
268 {
269 int ret = 0;
270 ret = drv_baro_st_lps22hb_set_power_mode(drv, DEV_POWER_OFF);
271 if (unlikely(ret)) {
272 return ret;
273 }
274 ret = drv_baro_st_lps22hb_set_odr(drv, LPS22HB_ODR_25HZ);
275 if (unlikely(ret)) {
276 return ret;
277 }
278 ret = drv_baro_st_lps22hb_set_bdu(drv, LPS22HB_BDU_NO_UPDATE);
279 if (unlikely(ret)) {
280 return ret;
281 }
282 /* you also can set the low-pass filter and cut off config here */
283 return 0;
284 }
285
286
drv_baro_st_lps22hb_irq_handle(void)287 static void drv_baro_st_lps22hb_irq_handle(void)
288 {
289 /* no handle so far */
290 }
291
drv_baro_st_lps22hb_open(void)292 static int drv_baro_st_lps22hb_open(void)
293 {
294 int ret = 0;
295 ret = drv_baro_st_lps22hb_set_power_mode(&lps22hb_ctx, DEV_POWER_ON);
296 if (unlikely(ret)) {
297 return -1;
298 }
299 LOG("%s %s successfully \n", SENSOR_STR, __func__);
300 return 0;
301 }
302
drv_baro_st_lps22hb_close(void)303 static int drv_baro_st_lps22hb_close(void)
304 {
305 int ret = 0;
306 ret = drv_baro_st_lps22hb_set_power_mode(&lps22hb_ctx, DEV_POWER_OFF);
307 if (unlikely(ret)) {
308 return -1;
309 }
310 LOG("%s %s successfully \n", SENSOR_STR, __func__);
311 return 0;
312 }
313
314
drv_baro_st_lps22hb_read(void * buf,size_t len)315 static int drv_baro_st_lps22hb_read(void *buf, size_t len)
316 {
317 int ret = 0;
318 size_t size;
319 uint8_t data[3];
320 barometer_data_t *pdata = (barometer_data_t *)buf;
321 if (buf == NULL) {
322 return -1;
323 }
324
325 size = sizeof(barometer_data_t);
326 if (len < size) {
327 return -1;
328 }
329
330 ret = sensor_i2c_read(&lps22hb_ctx, LPS22HB_PRESS_OUT_XL_REG, &data[0],
331 I2C_DATA_LEN, I2C_OP_RETRIES);
332 ret |= sensor_i2c_read(&lps22hb_ctx, LPS22HB_PRESS_OUT_L_REG, &data[1],
333 I2C_DATA_LEN, I2C_OP_RETRIES);
334 ret |= sensor_i2c_read(&lps22hb_ctx, LPS22HB_PRESS_OUT_H_REG, &data[2],
335 I2C_DATA_LEN, I2C_OP_RETRIES);
336 if (unlikely(ret)) {
337 return -1;
338 }
339
340 /* hatch the baro data here*/
341 for (int i = 0; i < 3; i++) {
342 pdata->p |= (((uint32_t)data[i]) << (8 * i));
343 }
344
345 /* convert the 2's complement 24 bit to 2's complement 32 bit */
346 if ((pdata->p & 0x00800000) != 0) {
347 pdata->p |= 0xFF000000;
348 }
349 pdata->p = ((pdata->p) * 100) / 4096;
350 // pdata->p = pdata->p/100;
351 pdata->timestamp = aos_now_ms();
352
353 return (int)size;
354 }
355
drv_baro_st_lps22hb_write(const void * buf,size_t len)356 static int drv_baro_st_lps22hb_write(const void *buf, size_t len)
357 {
358 return 0;
359 }
360
drv_baro_st_lps22hb_ioctl(int cmd,unsigned long arg)361 static int drv_baro_st_lps22hb_ioctl(int cmd, unsigned long arg)
362 {
363 int ret = 0;
364
365 switch (cmd) {
366 case SENSOR_IOCTL_ODR_SET: {
367 lps22hb_odr_e odr = drv_baro_st_lps22hb_hz2odr(arg);
368 ret = drv_baro_st_lps22hb_set_odr(&lps22hb_ctx, odr);
369 if (unlikely(ret)) {
370 return -1;
371 }
372 } break;
373 case SENSOR_IOCTL_SET_POWER: {
374 ret = drv_baro_st_lps22hb_set_power_mode(&lps22hb_ctx, arg);
375 if (unlikely(ret)) {
376 return -1;
377 }
378 } break;
379 case SENSOR_IOCTL_GET_INFO: {
380 /* fill the dev info here */
381 dev_sensor_info_t *info = (dev_sensor_info_t *)arg;
382 info->model = "LPS22HB";
383 info->range_max = 1260;
384 info->range_min = 260;
385 info->unit = pa;
386
387 } break;
388
389 default:
390 break;
391 }
392
393 LOG("%s %s successfully \n", SENSOR_STR, __func__);
394 return 0;
395 }
396
drv_baro_st_lps22hb_init(void)397 int drv_baro_st_lps22hb_init(void)
398 {
399 int ret = 0;
400 sensor_obj_t sensor;
401
402 memset(&sensor, 0, sizeof(sensor));
403
404 /* fill the sensor obj parameters here */
405 sensor.tag = TAG_DEV_BARO;
406 sensor.path = dev_baro_path;
407 sensor.io_port = I2C_PORT;
408 sensor.open = drv_baro_st_lps22hb_open;
409 sensor.close = drv_baro_st_lps22hb_close;
410 sensor.read = drv_baro_st_lps22hb_read;
411 sensor.write = drv_baro_st_lps22hb_write;
412 sensor.ioctl = drv_baro_st_lps22hb_ioctl;
413 sensor.irq_handle = drv_baro_st_lps22hb_irq_handle;
414
415
416 ret = sensor_create_obj(&sensor);
417 if (unlikely(ret)) {
418 return -1;
419 }
420
421 ret = drv_baro_st_lps22hb_validate_id(&lps22hb_ctx, LPS22HB_WHO_AM_I_VAL);
422 if (unlikely(ret)) {
423 return -1;
424 }
425 /* set the default config for the sensor here */
426 ret = drv_baro_st_lps22hb_set_default_config(&lps22hb_ctx);
427 if (unlikely(ret)) {
428 return -1;
429 }
430
431 LOG("%s %s successfully \n", SENSOR_STR, __func__);
432 return 0;
433 }
434
435 SENSOR_DRV_ADD(drv_baro_st_lps22hb_init);
436
437