summaryrefslogtreecommitdiff
path: root/zephyr/emul/emul_lis2dw12.c
diff options
context:
space:
mode:
Diffstat (limited to 'zephyr/emul/emul_lis2dw12.c')
-rw-r--r--zephyr/emul/emul_lis2dw12.c158
1 files changed, 158 insertions, 0 deletions
diff --git a/zephyr/emul/emul_lis2dw12.c b/zephyr/emul/emul_lis2dw12.c
index 07fba6091f..e14c184504 100644
--- a/zephyr/emul/emul_lis2dw12.c
+++ b/zephyr/emul/emul_lis2dw12.c
@@ -29,10 +29,20 @@ struct lis2dw12_emul_data {
struct i2c_common_emul_data common;
/** Emulated who-am-i register */
uint8_t who_am_i_reg;
+ /** Emulated ctrl1 register */
+ uint8_t ctrl1_reg;
/** Emulated ctrl2 register */
uint8_t ctrl2_reg;
+ /** Emulated ctrl3 register */
+ uint8_t ctrl3_reg;
+ /** Emulated ctrl6 register */
+ uint8_t ctrl6_reg;
+ /** Emulated status register */
+ uint8_t status_reg;
/** Soft reset count */
uint32_t soft_reset_count;
+ /** Current X, Y, and Z output data registers */
+ int16_t accel_data[3];
};
struct lis2dw12_emul_cfg {
@@ -59,8 +69,14 @@ void lis2dw12_emul_reset(const struct emul *emul)
i2c_common_emul_set_read_func(i2c_emul, NULL, NULL);
i2c_common_emul_set_write_func(i2c_emul, NULL, NULL);
data->who_am_i_reg = LIS2DW12_WHO_AM_I;
+ data->ctrl1_reg = 0;
data->ctrl2_reg = 0;
+ data->ctrl3_reg = 0;
+ data->ctrl6_reg = 0;
+ data->status_reg = 0;
data->soft_reset_count = 0;
+
+ memset(data->accel_data, 0, sizeof(data->accel_data));
}
void lis2dw12_emul_set_who_am_i(const struct emul *emul, uint8_t who_am_i)
@@ -87,16 +103,103 @@ static int lis2dw12_emul_read_byte(struct i2c_emul *emul, int reg, uint8_t *val,
__ASSERT_NO_MSG(bytes == 0);
*val = data->who_am_i_reg;
break;
+ case LIS2DW12_CTRL1_ADDR:
+ __ASSERT_NO_MSG(bytes == 0);
+ *val = data->ctrl1_reg;
+ break;
case LIS2DW12_CTRL2_ADDR:
__ASSERT_NO_MSG(bytes == 0);
*val = data->ctrl2_reg;
break;
+ case LIS2DW12_CTRL3_ADDR:
+ __ASSERT_NO_MSG(bytes == 0);
+ *val = data->ctrl3_reg;
+ break;
+ case LIS2DW12_CTRL6_ADDR:
+ __ASSERT_NO_MSG(bytes == 0);
+ *val = data->ctrl6_reg;
+ break;
+ case LIS2DW12_STATUS_REG:
+ __ASSERT_NO_MSG(bytes == 0);
+ *val = data->status_reg;
+ break;
+ case LIS2DW12_OUT_X_L_ADDR:
+ case LIS2DW12_OUT_X_H_ADDR:
+ case LIS2DW12_OUT_Y_L_ADDR:
+ case LIS2DW12_OUT_Y_H_ADDR:
+ case LIS2DW12_OUT_Z_L_ADDR:
+ case LIS2DW12_OUT_Z_H_ADDR:
+ /* Allow multi-byte reads within this range of registers.
+ * `bytes` is actually an offset past the starting register
+ * `reg`.
+ */
+
+ __ASSERT_NO_MSG(LIS2DW12_OUT_X_L_ADDR + bytes <=
+ LIS2DW12_OUT_Z_H_ADDR);
+
+ /* 0 is OUT_X_L_ADDR .. 5 is OUT_Z_H_ADDR */
+ int offset_into_odrs = reg - LIS2DW12_OUT_X_L_ADDR + bytes;
+
+ /* Which of the 3 channels we're reading. 0 = X, 1 = Y, 2 = Z */
+ int channel = offset_into_odrs / 2;
+
+ if (offset_into_odrs % 2 == 0) {
+ /* Get the LSB (L reg) */
+ *val = data->accel_data[channel] & 0xFF;
+ } else {
+ /* Get the MSB (H reg) */
+ *val = (data->accel_data[channel] >> 8) & 0xFF;
+ }
+ break;
default:
+ __ASSERT(false, "No read handler for register 0x%02x", reg);
return -EINVAL;
}
return 0;
}
+uint8_t lis2dw12_emul_peek_reg(struct i2c_emul *emul, int reg)
+{
+ __ASSERT(emul, "emul is NULL");
+
+ uint8_t val;
+ int rv;
+
+ rv = lis2dw12_emul_read_byte(emul, reg, &val, 0);
+ __ASSERT(rv == 0, "Read function returned non-zero: %d", rv);
+
+ return val;
+}
+
+uint8_t lis2dw12_emul_peek_odr(struct i2c_emul *emul)
+{
+ __ASSERT(emul, "emul is NULL");
+
+ uint8_t reg = lis2dw12_emul_peek_reg(emul, LIS2DW12_ACC_ODR_ADDR);
+
+ return (reg & LIS2DW12_ACC_ODR_MASK) >>
+ __builtin_ctz(LIS2DW12_ACC_ODR_MASK);
+}
+
+uint8_t lis2dw12_emul_peek_mode(struct i2c_emul *emul)
+{
+ __ASSERT(emul, "emul is NULL");
+
+ uint8_t reg = lis2dw12_emul_peek_reg(emul, LIS2DW12_ACC_MODE_ADDR);
+
+ return (reg & LIS2DW12_ACC_MODE_MASK) >>
+ __builtin_ctz(LIS2DW12_ACC_MODE_MASK);
+}
+
+uint8_t lis2dw12_emul_peek_lpmode(struct i2c_emul *emul)
+{
+ __ASSERT(emul, "emul is NULL");
+
+ uint8_t reg = lis2dw12_emul_peek_reg(emul, LIS2DW12_ACC_LPMODE_ADDR);
+
+ return (reg & LIS2DW12_ACC_LPMODE_MASK);
+}
+
static int lis2dw12_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val,
int bytes)
{
@@ -106,6 +209,9 @@ static int lis2dw12_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val,
case LIS2DW12_WHO_AM_I_REG:
LOG_ERR("Can't write to who-am-i register");
return -EINVAL;
+ case LIS2DW12_CTRL1_ADDR:
+ data->ctrl1_reg = val;
+ break;
case LIS2DW12_CTRL2_ADDR:
__ASSERT_NO_MSG(bytes == 1);
if ((val & LIS2DW12_SOFT_RESET_MASK) != 0) {
@@ -114,7 +220,28 @@ static int lis2dw12_emul_write_byte(struct i2c_emul *emul, int reg, uint8_t val,
}
data->ctrl2_reg = val & ~LIS2DW12_SOFT_RESET_MASK;
break;
+ case LIS2DW12_CTRL3_ADDR:
+ data->ctrl3_reg = val;
+ break;
+ case LIS2DW12_CTRL6_ADDR:
+ data->ctrl6_reg = val;
+ break;
+ case LIS2DW12_STATUS_REG:
+ __ASSERT(false,
+ "Attempt to write to read-only status register");
+ return -EINVAL;
+ case LIS2DW12_OUT_X_L_ADDR:
+ case LIS2DW12_OUT_X_H_ADDR:
+ case LIS2DW12_OUT_Y_L_ADDR:
+ case LIS2DW12_OUT_Y_H_ADDR:
+ case LIS2DW12_OUT_Z_L_ADDR:
+ case LIS2DW12_OUT_Z_H_ADDR:
+ __ASSERT(false,
+ "Attempt to write to data output register 0x%02x",
+ reg);
+ return -EINVAL;
default:
+ __ASSERT(false, "No write handler for register 0x%02x", reg);
return -EINVAL;
}
return 0;
@@ -137,6 +264,37 @@ static int emul_lis2dw12_init(const struct emul *emul,
return i2c_emul_register(parent, emul->dev_label, &data->common.emul);
}
+int lis2dw12_emul_set_accel_reading(const struct emul *emul, intv3_t reading)
+{
+ __ASSERT(emul, "emul is NULL");
+ struct lis2dw12_emul_data *data = emul->data;
+
+ for (int i = X; i <= Z; i++) {
+ /* Ensure we fit in a 14-bit signed integer */
+ if (reading[i] < LIS2DW12_SAMPLE_MIN ||
+ reading[i] > LIS2DW12_SAMPLE_MAX) {
+ return -EINVAL;
+ }
+ /* Readings are left-aligned, so shift over by 2 */
+ data->accel_data[i] = reading[i] * 4;
+ }
+
+ /* Set the DRDY (data ready) bit */
+ data->status_reg |= LIS2DW12_STS_DRDY_UP;
+
+ return 0;
+}
+
+void lis2dw12_emul_clear_accel_reading(const struct emul *emul)
+{
+ __ASSERT(emul, "emul is NULL");
+ struct lis2dw12_emul_data *data = emul->data;
+
+ /* Zero out the registers and reset DRDY bit */
+ memset(data->accel_data, 0, sizeof(data->accel_data));
+ data->status_reg &= ~LIS2DW12_STS_DRDY_UP;
+}
+
#define INIT_LIS2DW12(n) \
static struct lis2dw12_emul_data lis2dw12_emul_data_##n = { \
.common = { \