144 lines
3.5 KiB
C
144 lines
3.5 KiB
C
#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;
|
|
} |