/* * Copyright (C) 2015-2017 Alibaba Group Holding Limited * * */ #include #include #include #include "aos/kernel.h" #include "sensor_drv_api.h" #include "sensor_hal.h" /* ST BARO SENSOR REGISTER MAP */ #define LPS22HB_BIT(x) ((uint8_t)x) #define LPS22HB_ADDRESS (uint8_t)0xB8 #define LPS22HB_DriverVersion_Major (uint8_t)1 #define LPS22HB_DriverVersion_Minor (uint8_t)0 #define LPS22HB_DriverVersion_Point (uint8_t)0 #define LPS22HB_WHO_AM_I_REG (uint8_t)0x0F #define LPS22HB_WHO_AM_I_VAL (uint8_t)0xB1 #define LPS22HB_REF_P_XL_REG (uint8_t)0x15 #define LPS22HB_REF_P_L_REG (uint8_t)0x16 #define LPS22HB_REF_P_H_REG (uint8_t)0x17 #define LPS22HB_RES_CONF_REG (uint8_t)0x1A #define LPS22HB_RES_CONF_REG (uint8_t)0x1A #define LPS22HB_RES_CONF_REG (uint8_t)0x1A #define LPS22HB_LCEN_MASK (uint8_t)0x01 #define LPS22HB_LCEN_POWERON (uint8_t)0x00 #define LPS22HB_LCEN_LOWPOWER (uint8_t)0x01 #define LPS22HB_CTRL_REG1 (uint8_t)0x10 #define LPS22HB_ODR_MASK (uint8_t)0x70 #define LPS22HB_LPFP_MASK (uint8_t)0x08 #define LPS22HB_LPFP_CUTOFF_MASK (uint8_t)0x04 #define LPS22HB_BDU_MASK (uint8_t)0x02 #define LPS22HB_SIM_MASK (uint8_t)0x01 #define LPS22HB_LPFP_BIT LPS22HB_BIT(3) #define LPS22HB_CTRL_REG2 (uint8_t)0x11 #define LPS22HB_BOOT_BIT LPS22HB_BIT(7) #define LPS22HB_FIFO_EN_BIT LPS22HB_BIT(6) #define LPS22HB_WTM_EN_BIT LPS22HB_BIT(5) #define LPS22HB_ADD_INC_BIT LPS22HB_BIT(4) #define LPS22HB_I2C_BIT LPS22HB_BIT(3) #define LPS22HB_SW_RESET_BIT LPS22HB_BIT(2) #define LPS22HB_FIFO_EN_MASK (uint8_t)0x40 #define LPS22HB_WTM_EN_MASK (uint8_t)0x20 #define LPS22HB_ADD_INC_MASK (uint8_t)0x10 #define LPS22HB_I2C_MASK (uint8_t)0x08 #define LPS22HB_ONE_SHOT_MASK (uint8_t)0x01 #define LPS22HB_CTRL_REG3 (uint8_t)0x12 #define LPS22HB_PP_OD_BIT LPS22HB_BIT(6) #define LPS22HB_FIFO_FULL_BIT LPS22HB_BIT(5) #define LPS22HB_FIFO_FTH_BIT LPS22HB_BIT(4) #define LPS22HB_FIFO_OVR_BIT LPS22HB_BIT(3) #define LPS22HB_DRDY_BIT LPS22HB_BIT(2) #define LPS22HB_INT_H_L_MASK (uint8_t)0x80 #define LPS22HB_PP_OD_MASK (uint8_t)0x40 #define LPS22HB_FIFO_FULL_MASK (uint8_t)0x20 #define LPS22HB_FIFO_FTH_MASK (uint8_t)0x10 #define LPS22HB_FIFO_OVR_MASK (uint8_t)0x08 #define LPS22HB_DRDY_MASK (uint8_t)0x04 #define LPS22HB_INT_S12_MASK (uint8_t)0x03 #define LPS22HB_INTERRUPT_CFG_REG (uint8_t)0x0B #define LPS22HB_DIFF_EN_BIT LPS22HB_BIT(3) #define LPS22HB_LIR_BIT LPS22HB_BIT(2) #define LPS22HB_PLE_BIT LPS22HB_BIT(1) #define LPS22HB_PHE_BIT LPS22HB_BIT(0) #define LPS22HB_AUTORIFP_MASK (uint8_t)0x80 #define LPS22HB_RESET_ARP_MASK (uint8_t)0x40 #define LPS22HB_AUTOZERO_MASK (uint8_t)0x20 #define LPS22HB_RESET_AZ_MASK (uint8_t)0x10 #define LPS22HB_DIFF_EN_MASK (uint8_t)0x08 #define LPS22HB_LIR_MASK (uint8_t)0x04 #define LPS22HB_PLE_MASK (uint8_t)0x02 #define LPS22HB_PHE_MASK (uint8_t)0x01 #define LPS22HB_INTERRUPT_SOURCE_REG (uint8_t)0x25 #define LPS22HB_BOOT_STATUS_BIT LPS22HB_BIT(7) #define LPS22HB_IA_BIT LPS22HB_BIT(2) #define LPS22HB_PL_BIT LPS22HB_BIT(1) #define LPS22HB_PH_BIT LPS22HB_BIT(0) #define LPS22HB_BOOT_STATUS_MASK (uint8_t)0x80 #define LPS22HB_IA_MASK (uint8_t)0x04 #define LPS22HB_PL_MASK (uint8_t)0x02 #define LPS22HB_PH_MASK (uint8_t)0x01 #define LPS22HB_STATUS_REG (uint8_t)0x27 #define LPS22HB_TOR_BIT LPS22HB_BIT(5) #define LPS22HB_POR_BIT LPS22HB_BIT(4) #define LPS22HB_TDA_BIT LPS22HB_BIT(1) #define LPS22HB_PDA_BIT LPS22HB_BIT(0) #define LPS22HB_TOR_MASK (uint8_t)0x20 #define LPS22HB_POR_MASK (uint8_t)0x10 #define LPS22HB_TDA_MASK (uint8_t)0x02 #define LPS22HB_PDA_MASK (uint8_t)0x01 #define LPS22HB_PRESS_OUT_XL_REG (uint8_t)0x28 #define LPS22HB_PRESS_OUT_L_REG (uint8_t)0x29 #define LPS22HB_PRESS_OUT_H_REG (uint8_t)0x2A #define LPS22HB_TEMP_OUT_L_REG (uint8_t)0x2B #define LPS22HBH_TEMP_OUT_H_REG (uint8_t)0x2C #define LPS22HB_THS_P_LOW_REG (uint8_t)0x0C #define LPS22HB_THS_P_HIGH_REG (uint8_t)0x0D #define LPS22HB_CTRL_FIFO_REG (uint8_t)0x14 #define LPS22HB_FIFO_MODE_MASK (uint8_t)0xE0 #define LPS22HB_WTM_POINT_MASK (uint8_t)0x1F #define LPS22HB_STATUS_FIFO_REG (uint8_t)0x26 #define LPS22HB_FTH_FIFO_BIT LPS22HB_BIT(7) #define LPS22HB_OVR_FIFO_BIT LPS22HB_BIT(6) #define LPS22HB_FTH_FIFO_MASK (uint8_t)0x80 #define LPS22HB_OVR_FIFO_MASK (uint8_t)0x40 #define LPS22HB_LEVEL_FIFO_MASK (uint8_t)0x3F #define LPS22HB_FIFO_EMPTY (uint8_t)0x00 #define LPS22HB_FIFO_FULL (uint8_t)0x18 #define LPS22HB_RPDS_H_REG (uint8_t)0x19 #define LPS22HB_CLOCK_TREE_CONFIG (uint8_t)0x43 #define LPS22HB_CTE_MASK (uint8_t)0x20 #define LPS22HB_I2C_ADDR1_R (uint8_t)0xB9 #define LPS22HB_I2C_ADDR1_W (uint8_t)0xB8 #define LPS22HB_I2C_ADDR2_R (uint8_t)0xBB #define LPS22HB_I2C_ADDR2_W (uint8_t)0xBZ #define LPS22HB_I2C_ADDR1 (0x5C) #define LPS22HB_I2C_ADDR2 (0x5D) #define LPS22HB_I2C_ADDR_TRANS(n) ((n) << 1) #define LPS22HB_I2C_ADDR LPS22HB_I2C_ADDR_TRANS(LPS22HB_I2C_ADDR2) typedef enum { LPS22HB_ODR_ONE_SHOT = (uint8_t)0x00, /*!< Output Data Rate: one shot */ LPS22HB_ODR_1HZ = (uint8_t)0x10, /*!< Output Data Rate: 1Hz */ LPS22HB_ODR_10HZ = (uint8_t)0x20, /*!< Output Data Rate: 10Hz */ LPS22HB_ODR_25HZ = (uint8_t)0x30, /*!< Output Data Rate: 25Hz */ LPS22HB_ODR_50HZ = (uint8_t)0x40, /*!< Output Data Rate: 50Hz */ LPS22HB_ODR_75HZ = (uint8_t)0x50 /*!< Output Data Rate: 75Hz */ } lps22hb_odr_e; typedef enum { LPS22HB_BDU_CONTINUOUS_UPDATE = (uint8_t)0x00, /*!< Data updated continuously */ LPS22HB_BDU_NO_UPDATE = (uint8_t)0x02 /*!< Data updated after a read operation */ } lps22hb_bdu_e; i2c_dev_t lps22hb_ctx = { .port = 1, .config.address_width = 8, .config.freq = 400000, .config.dev_addr = LPS22HB_I2C_ADDR, }; static lps22hb_odr_e drv_baro_st_lps22hb_hz2odr(int hz) { if (hz > 50) return LPS22HB_ODR_75HZ; else if (hz > 25) return LPS22HB_ODR_50HZ; else if (hz > 10) return LPS22HB_ODR_25HZ; else if (hz > 1) return LPS22HB_ODR_10HZ; else return LPS22HB_ODR_1HZ; } static int drv_baro_st_lps22hb_validate_id(i2c_dev_t *drv, uint8_t id_value) { uint8_t value = 0x00; int ret = 0; if (drv == NULL) { return -1; } ret = sensor_i2c_read(drv, LPS22HB_WHO_AM_I_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return ret; } if (id_value != value) { return -1; } return 0; } static int drv_baro_st_lps22hb_set_power_mode(i2c_dev_t * drv, dev_power_mode_e mode) { uint8_t value = 0x00; int ret = 0; ret = sensor_i2c_read(drv, LPS22HB_RES_CONF_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return ret; } switch (mode) { case DEV_POWER_ON: { value &= ~LPS22HB_LCEN_MASK; value |= LPS22HB_LCEN_POWERON; ret = sensor_i2c_write(drv, LPS22HB_RES_CONF_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return ret; } } break; case DEV_POWER_OFF: { value |= LPS22HB_LCEN_LOWPOWER; ret = sensor_i2c_write(drv, LPS22HB_RES_CONF_REG, &value, I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return ret; } } break; default: break; } return 0; } static int drv_baro_st_lps22hb_set_odr(i2c_dev_t *drv, lps22hb_odr_e odr) { uint8_t value = 0x00; int ret = 0; ret = sensor_i2c_read(drv, LPS22HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return ret; } value &= ~LPS22HB_ODR_MASK; value |= (uint8_t)odr; ret = sensor_i2c_write(drv, LPS22HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return ret; } return 0; } static int drv_baro_st_lps22hb_set_bdu(i2c_dev_t *drv, lps22hb_bdu_e bdu) { uint8_t value = 0x00; int ret = 0; ret = sensor_i2c_read(drv, LPS22HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return ret; } value &= ~LPS22HB_BDU_MASK; value |= (uint8_t)bdu; ret = sensor_i2c_write(drv, LPS22HB_CTRL_REG1, &value, I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return ret; } return 0; } static int drv_baro_st_lps22hb_set_default_config(i2c_dev_t *drv) { int ret = 0; ret = drv_baro_st_lps22hb_set_power_mode(drv, DEV_POWER_OFF); if (unlikely(ret)) { return ret; } ret = drv_baro_st_lps22hb_set_odr(drv, LPS22HB_ODR_25HZ); if (unlikely(ret)) { return ret; } ret = drv_baro_st_lps22hb_set_bdu(drv, LPS22HB_BDU_NO_UPDATE); if (unlikely(ret)) { return ret; } /* you also can set the low-pass filter and cut off config here */ return 0; } static void drv_baro_st_lps22hb_irq_handle(void) { /* no handle so far */ } static int drv_baro_st_lps22hb_open(void) { int ret = 0; ret = drv_baro_st_lps22hb_set_power_mode(&lps22hb_ctx, DEV_POWER_ON); if (unlikely(ret)) { return -1; } LOG("%s %s successfully \n", SENSOR_STR, __func__); return 0; } static int drv_baro_st_lps22hb_close(void) { int ret = 0; ret = drv_baro_st_lps22hb_set_power_mode(&lps22hb_ctx, DEV_POWER_OFF); if (unlikely(ret)) { return -1; } LOG("%s %s successfully \n", SENSOR_STR, __func__); return 0; } static int drv_baro_st_lps22hb_read(void *buf, size_t len) { int ret = 0; size_t size; uint8_t data[3]; barometer_data_t *pdata = (barometer_data_t *)buf; if (buf == NULL) { return -1; } size = sizeof(barometer_data_t); if (len < size) { return -1; } ret = sensor_i2c_read(&lps22hb_ctx, LPS22HB_PRESS_OUT_XL_REG, &data[0], I2C_DATA_LEN, I2C_OP_RETRIES); ret |= sensor_i2c_read(&lps22hb_ctx, LPS22HB_PRESS_OUT_L_REG, &data[1], I2C_DATA_LEN, I2C_OP_RETRIES); ret |= sensor_i2c_read(&lps22hb_ctx, LPS22HB_PRESS_OUT_H_REG, &data[2], I2C_DATA_LEN, I2C_OP_RETRIES); if (unlikely(ret)) { return -1; } /* hatch the baro data here*/ for (int i = 0; i < 3; i++) { pdata->p |= (((uint32_t)data[i]) << (8 * i)); } /* convert the 2's complement 24 bit to 2's complement 32 bit */ if ((pdata->p & 0x00800000) != 0) { pdata->p |= 0xFF000000; } pdata->p = ((pdata->p) * 100) / 4096; // pdata->p = pdata->p/100; pdata->timestamp = aos_now_ms(); return (int)size; } static int drv_baro_st_lps22hb_write(const void *buf, size_t len) { return 0; } static int drv_baro_st_lps22hb_ioctl(int cmd, unsigned long arg) { int ret = 0; switch (cmd) { case SENSOR_IOCTL_ODR_SET: { lps22hb_odr_e odr = drv_baro_st_lps22hb_hz2odr(arg); ret = drv_baro_st_lps22hb_set_odr(&lps22hb_ctx, odr); if (unlikely(ret)) { return -1; } } break; case SENSOR_IOCTL_SET_POWER: { ret = drv_baro_st_lps22hb_set_power_mode(&lps22hb_ctx, arg); if (unlikely(ret)) { return -1; } } break; case SENSOR_IOCTL_GET_INFO: { /* fill the dev info here */ dev_sensor_info_t *info = (dev_sensor_info_t *)arg; info->model = "LPS22HB"; info->range_max = 1260; info->range_min = 260; info->unit = pa; } break; default: break; } LOG("%s %s successfully \n", SENSOR_STR, __func__); return 0; } int drv_baro_st_lps22hb_init(void) { int ret = 0; sensor_obj_t sensor; memset(&sensor, 0, sizeof(sensor)); /* fill the sensor obj parameters here */ sensor.tag = TAG_DEV_BARO; sensor.path = dev_baro_path; sensor.io_port = I2C_PORT; sensor.open = drv_baro_st_lps22hb_open; sensor.close = drv_baro_st_lps22hb_close; sensor.read = drv_baro_st_lps22hb_read; sensor.write = drv_baro_st_lps22hb_write; sensor.ioctl = drv_baro_st_lps22hb_ioctl; sensor.irq_handle = drv_baro_st_lps22hb_irq_handle; ret = sensor_create_obj(&sensor); if (unlikely(ret)) { return -1; } ret = drv_baro_st_lps22hb_validate_id(&lps22hb_ctx, LPS22HB_WHO_AM_I_VAL); if (unlikely(ret)) { return -1; } /* set the default config for the sensor here */ ret = drv_baro_st_lps22hb_set_default_config(&lps22hb_ctx); if (unlikely(ret)) { return -1; } LOG("%s %s successfully \n", SENSOR_STR, __func__); return 0; } SENSOR_DRV_ADD(drv_baro_st_lps22hb_init);