Added PAH8001 driver and WIP BMM150 driver.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
parent
8280fe22c9
commit
954c38ac5a
|
@ -10,6 +10,8 @@ set(IMSENSORS_SRCS
|
|||
"src/dht/dht_bme280.c"
|
||||
"src/franklin/franklin_as3935.c"
|
||||
"src/imu/imu_lsm6dsl.c"
|
||||
"src/magnetic/magnetic_bmm150.c"
|
||||
"src/ppg/ppg_pah8001.c"
|
||||
)
|
||||
|
||||
set(IMSENSORS_INCS
|
||||
|
@ -18,6 +20,8 @@ set(IMSENSORS_INCS
|
|||
"include/imsensors/dht"
|
||||
"include/imsensors/franklin"
|
||||
"include/imsensors/imu"
|
||||
"include/imsensors/magnetic"
|
||||
"include/imsensors/ppg"
|
||||
)
|
||||
|
||||
set(IMSENSORS_INTF_INCS
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#ifndef IMS_BMM150_H
|
||||
#define IMS_BMM150_H
|
||||
|
||||
#include "imsensors/common/sensors_common.h"
|
||||
|
||||
typedef enum {
|
||||
IMS_BMM150_ODR_10HZ = 0U,
|
||||
IMS_BMM150_ODR_2HZ = 1U,
|
||||
IMS_BMM150_ODR_6HZ = 2U,
|
||||
IMS_BMM150_ODR_8HZ = 3U,
|
||||
IMS_BMM150_ODR_15HZ = 4U,
|
||||
IMS_BMM150_ODR_20HZ = 5U,
|
||||
IMS_BMM150_ODR_25HZ = 6U,
|
||||
IMS_BMM150_ODR_30HZ = 7U,
|
||||
} ims_bmm150_odr_t;
|
||||
|
||||
typedef enum {
|
||||
IMS_BMM150_PRESET_LOWPOWER,
|
||||
IMS_BMM150_PRESET_REGULAR,
|
||||
IMS_BMM150_PRESET_ENHANCED_REGULAR,
|
||||
IMS_BMM150_PRESET_HIGH_ACCURACY,
|
||||
} ims_bmm150_preset_t;
|
||||
|
||||
typedef enum {
|
||||
IMS_BMM150_MODE_SLEEP,
|
||||
IMS_BMM150_MODE_FORCED,
|
||||
IMS_BMM150_MODE_NORMAL,
|
||||
} ims_bmm150_mode_t;
|
||||
|
||||
typedef struct {
|
||||
|
||||
} ims_bmm150_result_t;
|
||||
|
||||
typedef struct {
|
||||
ims_i2c_xfer_t i2c_xfer;
|
||||
ims_delay_t delay;
|
||||
} ims_bmm150_cb_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t rep_xy;
|
||||
uint8_t rep_z;
|
||||
ims_bmm150_odr_t odr;
|
||||
} ims_bmm150_config_t;
|
||||
|
||||
typedef struct {
|
||||
ims_bmm150_cb_t cb;
|
||||
void *pdev;
|
||||
uint8_t i2c_addr;
|
||||
|
||||
} ims_bmm150_t;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef PPG_PAH8001_H
|
||||
#define PPG_PAH8001_H
|
||||
|
||||
#include "imsensors/common/sensors_common.h"
|
||||
|
||||
typedef enum {
|
||||
IMS_PPG_ALG_A,
|
||||
IMS_PPG_ALG_C,
|
||||
} ims_pah8001_alg_t;
|
||||
|
||||
typedef struct {
|
||||
ims_i2c_xfer_t i2c_xfer;
|
||||
ims_delay_t delay;
|
||||
} ims_pah8001_cb_t;
|
||||
|
||||
typedef struct {
|
||||
ims_pah8001_cb_t cb;
|
||||
void *pdev;
|
||||
} ims_pah8001_t;
|
||||
|
||||
ims_ret_t ims_pah8001_init(ims_pah8001_t *pah);
|
||||
ims_ret_t ims_pah8001_power(ims_pah8001_t *pah, const bool on);
|
||||
ims_ret_t ims_pah8001_touched(ims_pah8001_t *pah, bool *touched);
|
||||
ims_ret_t ims_pah8001_read_alg_hr(ims_pah8001_t *pah, ims_pah8001_alg_t alg, uint8_t *hr);
|
||||
|
||||
#endif // PPG_PAH8001_H
|
|
@ -99,8 +99,8 @@ static const ims_bme280_config_t ims_bme280_presets[] = {
|
|||
static ims_ret_t ims_bme280_reset(ims_bme280_t *bme);
|
||||
static ims_ret_t ims_bme280_read_trim_data(ims_bme280_t *bme);
|
||||
static ims_ret_t ims_bme280_set_mode(ims_bme280_t *bme, ims_bme280_mode_t mode);
|
||||
static ims_ret_t ims_bme_get_mode(ims_bme280_t *bme, ims_bme280_mode_t *mode);
|
||||
static ims_ret_t ims_bme_wait_measure_complete(ims_bme280_t *bme, uint32_t timeout_ms);
|
||||
static ims_ret_t ims_bme280_get_mode(ims_bme280_t *bme, ims_bme280_mode_t *mode);
|
||||
static ims_ret_t ims_bme280_wait_measure_complete(ims_bme280_t *bme, uint32_t timeout_ms);
|
||||
static ims_ret_t ims_bme280_read_raw_data(ims_bme280_t *bme, uint32_t *raw_t, uint32_t *raw_p, uint32_t *raw_h);
|
||||
|
||||
static ims_ret_t ims_bme280_read_register(ims_bme280_t *bme, uint8_t reg, uint8_t *data, uint16_t len);
|
||||
|
@ -147,7 +147,7 @@ ims_ret_t ims_bme280_config(ims_bme280_t *bme, ims_bme280_config_t *config) {
|
|||
|
||||
ims_bme280_mode_t mode;
|
||||
|
||||
ret = ims_bme_get_mode(bme, &mode);
|
||||
ret = ims_bme280_get_mode(bme, &mode);
|
||||
if (ret != IMS_SUCCESS) return ret;
|
||||
|
||||
if (mode != IMS_BME280_MODE_SLEEP) {
|
||||
|
@ -205,7 +205,7 @@ ims_ret_t ims_bme280_read_forced(ims_bme280_t *bme, ims_bme280_result_t *result)
|
|||
|
||||
ims_bme280_mode_t mode;
|
||||
|
||||
ret = ims_bme_get_mode(bme, &mode);
|
||||
ret = ims_bme280_get_mode(bme, &mode);
|
||||
if (ret != IMS_SUCCESS) return ret;
|
||||
|
||||
/*
|
||||
|
@ -218,7 +218,7 @@ ims_ret_t ims_bme280_read_forced(ims_bme280_t *bme, ims_bme280_result_t *result)
|
|||
if (ret != IMS_SUCCESS) return ret;
|
||||
}
|
||||
|
||||
ret = ims_bme_wait_measure_complete(bme, IMS_BME280_FORCED_TIMEOUT_MS);
|
||||
ret = ims_bme280_wait_measure_complete(bme, IMS_BME280_FORCED_TIMEOUT_MS);
|
||||
if (ret != IMS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
@ -341,7 +341,7 @@ static ims_ret_t ims_bme280_set_mode(ims_bme280_t *bme, ims_bme280_mode_t mode)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bme_get_mode(ims_bme280_t *bme, ims_bme280_mode_t *mode) {
|
||||
static ims_ret_t ims_bme280_get_mode(ims_bme280_t *bme, ims_bme280_mode_t *mode) {
|
||||
ims_ret_t ret;
|
||||
|
||||
uint8_t ctrl_meas;
|
||||
|
@ -354,7 +354,7 @@ static ims_ret_t ims_bme_get_mode(ims_bme280_t *bme, ims_bme280_mode_t *mode) {
|
|||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bme_wait_measure_complete(ims_bme280_t *bme, uint32_t timeout_ms) {
|
||||
static ims_ret_t ims_bme280_wait_measure_complete(ims_bme280_t *bme, uint32_t timeout_ms) {
|
||||
ims_ret_t ret;
|
||||
|
||||
uint8_t loop_count = 0U;
|
||||
|
|
|
@ -0,0 +1,144 @@
|
|||
#include <stddef.h>
|
||||
|
||||
/* Private */
|
||||
#include "magnetic_bmm150.h"
|
||||
|
||||
static ims_ret_t ims_bmm150_read_register(ims_bmm150_t *bmm, uint8_t addr, uint8_t *val, uint8_t len) {
|
||||
ims_i2c_xfer_desc_t desc = {
|
||||
.tx_data = &addr,
|
||||
.tx_size = 1U,
|
||||
.rx_data = val,
|
||||
.rx_size = len,
|
||||
};
|
||||
|
||||
return bmm->cb.i2c_xfer(bmm->pdev, &desc);
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bmm150_write_register(ims_bmm150_t *bmm, uint8_t addr, uint8_t val) {
|
||||
uint8_t tx_buf[2] = {addr, val};
|
||||
ims_i2c_xfer_desc_t desc = {
|
||||
.tx_data = tx_buf,
|
||||
.tx_size = 2U,
|
||||
.rx_data = NULL,
|
||||
.rx_size = 0U,
|
||||
};
|
||||
|
||||
return bmm->cb.i2c_xfer(bmm->pdev, &desc);
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bmm150_set_mode(ims_bmm150_t *bmm, ims_bmm150_mode_t mode) {
|
||||
uint8_t b_mode;
|
||||
if (ims_bmm150_read_register(bmm, 0x4C, &b_mode, 0x01) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
switch (mode) {
|
||||
case IMS_BMM150_MODE_SLEEP:
|
||||
b_mode |= (0x03U << 1U);
|
||||
break;
|
||||
case IMS_BMM150_MODE_NORMAL:
|
||||
b_mode &= (0x03U << 1U);
|
||||
break;
|
||||
case IMS_BMM150_MODE_FORCED:
|
||||
b_mode &= (0x03U << 1U);
|
||||
b_mode |= (0x01U << 1U);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ims_bmm150_write_register(bmm, 0x4C, b_mode) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bmm150_enable_drdy(ims_bmm150_t *bmm) {
|
||||
uint8_t reg;
|
||||
if (ims_bmm150_read_register(bmm, 0x4E, ®, 0x01) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
reg |= (1U << 7);
|
||||
|
||||
if (ims_bmm150_write_register(bmm, 0x4E, reg) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bmm150_set_thresholds(ims_bmm150_t *bmm, uint8_t high, uint8_t low) {
|
||||
if (ims_bmm150_write_register(bmm, 0x4F, low) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
if (ims_bmm150_write_register(bmm, 0x50, high) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bmm150_set_repetitions(ims_bmm150_t *bmm, uint8_t xy, uint8_t z) {
|
||||
if (ims_bmm150_write_register(bmm, 0x51, xy) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
if (ims_bmm150_write_register(bmm, 0x52, z) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
static ims_ret_t ims_bmm150_reset(ims_bmm150_t *bmm) {
|
||||
if (ims_bmm150_write_register(bmm, 0x4B, 0x00) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
if (ims_bmm150_write_register(bmm, 0x4B, 0x01) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t ims_bmm150_init(ims_bmm150_t *bmm) {
|
||||
if (!bmm) return IMS_FAIL;
|
||||
|
||||
if (ims_bmm150_reset(bmm) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t ims_bmm150_config(ims_bmm150_t *bmm, ims_bmm150_config_t *cfg) {
|
||||
if (ims_bmm150_set_repetitions(bmm, cfg->rep_xy, cfg->rep_z) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
uint8_t b_mode;
|
||||
|
||||
if (ims_bmm150_read_register(bmm, 0x4C, &b_mode, 0x01) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
b_mode &= (7U << 3);
|
||||
b_mode |= (cfg->odr << 3);
|
||||
|
||||
if (ims_bmm150_write_register(bmm, 0x4C, b_mode) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t ims_bmm150_watch(ims_bmm150_t *bmm) {
|
||||
/* Enable interrupts and ... */
|
||||
if (ims_bmm150_set_thresholds(bmm, 0, 0) != IMS_SUCCESS) {
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
#include "ppg_pah8001.h"
|
||||
|
||||
#define PAH8001_R_CONFIG ((0U << 8U) | 0x06)
|
||||
#define PAH8001_R_CONFIG_RESET_Pos 7
|
||||
#define PAH8001_R_CONFIG_RESET_Msk (1U << PAH8001_R_CONFIG_RESET_Pos)
|
||||
#define PAH8001_R_CONFIG_POWERDOWN_Pos 3
|
||||
#define PAH8001_R_CONFIG_POWERDOWN_Msk (1U << PAH8001_R_CONFIG_POWERDOWN_Pos)
|
||||
|
||||
#define PAH8001_R_TOUCH_DET ((0U << 8U) | 0x59)
|
||||
#define PAH8001_R_TOUCH_DET_DETECTED_Pos 7
|
||||
#define PAH8001_R_TOUCH_DET_DETECTED_Msk (1U << PAH8001_R_TOUCH_DET_DETECTED_Pos)
|
||||
|
||||
#define PAH8001_R_HR_ALG_A ((1U << 8U) | 0x1A)
|
||||
|
||||
#define PAH8001_R_HR_ALG_C ((1U << 8U) | 0x1C)
|
||||
|
||||
#define PAH8001_ERROR_CHECK(x) \
|
||||
if (x != IMS_SUCCESS) return IMS_FAIL
|
||||
|
||||
static ims_ret_t ims_pah8001_register_write(ims_pah8001_t *pah, const uint16_t addr, uint8_t data) {
|
||||
ims_ret_t ret;
|
||||
|
||||
uint8_t tx_buf[] = {0x7F, (addr >> 8U)};
|
||||
|
||||
ims_i2c_xfer_desc_t xfer_desc = {
|
||||
.tx_data = tx_buf,
|
||||
.tx_size = 2U,
|
||||
.rx_data = NULL,
|
||||
.rx_size = 0U,
|
||||
};
|
||||
|
||||
/* Switch register bank */
|
||||
ret = pah->cb.i2c_xfer(pah->pdev, &xfer_desc);
|
||||
if (ret != IMS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
tx_buf[0] = (addr & 0xFFU);
|
||||
tx_buf[1] = data;
|
||||
|
||||
ret = pah->cb.i2c_xfer(pah->pdev, &xfer_desc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ims_ret_t ims_pah8001_register_read(ims_pah8001_t *pah, const uint16_t addr, uint8_t *data) {
|
||||
ims_ret_t ret;
|
||||
|
||||
uint8_t tx_buf[] = {0x7F, (addr >> 8U)};
|
||||
|
||||
ims_i2c_xfer_desc_t xfer_desc = {
|
||||
.tx_data = tx_buf,
|
||||
.tx_size = 2U,
|
||||
.rx_data = NULL,
|
||||
.rx_size = 0U,
|
||||
};
|
||||
|
||||
/* Switch register bank */
|
||||
ret = pah->cb.i2c_xfer(pah->pdev, &xfer_desc);
|
||||
if (ret != IMS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
tx_buf[0] = (addr & 0xFFU);
|
||||
|
||||
xfer_desc.tx_size = 1U;
|
||||
xfer_desc.rx_data = data;
|
||||
xfer_desc.rx_size = 1U;
|
||||
|
||||
ret = pah->cb.i2c_xfer(pah->pdev, &xfer_desc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ims_ret_t ims_pah8001_reset(ims_pah8001_t *pah) {
|
||||
uint8_t wdata = PAH8001_R_CONFIG_RESET_Msk | 2U;
|
||||
PAH8001_ERROR_CHECK(ims_pah8001_register_write(pah, PAH8001_R_CONFIG, wdata));
|
||||
|
||||
pah->cb.delay(pah->pdev, 5);
|
||||
|
||||
wdata = PAH8001_R_CONFIG_POWERDOWN_Msk | 2U;
|
||||
PAH8001_ERROR_CHECK(ims_pah8001_register_write(pah, PAH8001_R_CONFIG, wdata));
|
||||
|
||||
|
||||
pah->cb.delay(pah->pdev, 5);
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t ims_pah8001_init(ims_pah8001_t *pah) {
|
||||
PAH8001_ERROR_CHECK(ims_pah8001_reset(pah));
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t ims_pah8001_power(ims_pah8001_t *pah, const bool on) {
|
||||
ims_ret_t ret;
|
||||
uint8_t wdata;
|
||||
|
||||
ret = ims_pah8001_register_read(pah, PAH8001_R_CONFIG, &wdata);
|
||||
if (ret != IMS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!on) {
|
||||
wdata |= PAH8001_R_CONFIG_POWERDOWN_Msk;
|
||||
} else {
|
||||
wdata &= ~PAH8001_R_CONFIG_POWERDOWN_Msk;
|
||||
}
|
||||
|
||||
return ims_pah8001_register_write(pah, PAH8001_R_CONFIG, wdata);
|
||||
}
|
||||
|
||||
ims_ret_t ims_pah8001_touched(ims_pah8001_t *pah, bool *touched) {
|
||||
ims_ret_t ret;
|
||||
uint8_t rdata;
|
||||
|
||||
ret = ims_pah8001_register_read(pah, PAH8001_R_TOUCH_DET, &rdata);
|
||||
if (ret != IMS_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rdata & PAH8001_R_TOUCH_DET_DETECTED_Msk) {
|
||||
*touched = true;
|
||||
} else {
|
||||
*touched = false;
|
||||
}
|
||||
|
||||
return IMS_SUCCESS;
|
||||
}
|
||||
|
||||
ims_ret_t ims_pah8001_read_alg_hr(ims_pah8001_t *pah, ims_pah8001_alg_t alg, uint8_t *hr) {
|
||||
uint16_t rreg;
|
||||
|
||||
switch (alg) {
|
||||
case IMS_PPG_ALG_A:
|
||||
rreg = PAH8001_R_HR_ALG_A;
|
||||
break;
|
||||
case IMS_PPG_ALG_C:
|
||||
rreg = PAH8001_R_HR_ALG_C;
|
||||
break;
|
||||
default:
|
||||
return IMS_FAIL;
|
||||
}
|
||||
|
||||
return ims_pah8001_register_read(pah, rreg, hr);
|
||||
}
|
Loading…
Reference in New Issue