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