blob: 580bf64b761f126c9147ea236dec23e26e06746d [file] [log] [blame]
/*
* Copyright (c) 2023 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/devicetree.h>
#include <zephyr/drivers/emul.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/gpio/gpio_emul.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/ztest.h>
#include "akm09918c.h"
#include "akm09918c_emul.h"
#include "akm09918c_reg.h"
struct akm09918c_fixture {
const struct device *dev;
const struct emul *target;
};
static void *akm09918c_setup(void)
{
static struct akm09918c_fixture fixture = {
.dev = DEVICE_DT_GET(DT_NODELABEL(akm09918c)),
.target = EMUL_DT_GET(DT_NODELABEL(akm09918c)),
};
zassert_not_null(fixture.dev);
zassert_not_null(fixture.target);
return &fixture;
}
static void akm09918c_before(void *f)
{
struct akm09918c_fixture *fixture = f;
akm09918c_emul_reset(fixture->target);
}
ZTEST_SUITE(akm09918c, NULL, akm09918c_setup, akm09918c_before, NULL, NULL);
ZTEST_F(akm09918c, test_fetch_fail_no_ready_data)
{
uint8_t status = 0;
akm09918c_emul_set_reg(fixture->target, AKM09918C_REG_ST1, &status, 1);
zassert_equal(-EBUSY, sensor_sample_fetch(fixture->dev));
}
static void test_fetch_magnetic_field(const struct akm09918c_fixture *fixture,
const int16_t magn_percent[3])
{
struct sensor_value values[3];
int64_t expect_ugauss;
int64_t actual_ugauss;
uint8_t register_buffer[6];
/* Set the ST1 register to show we have data */
register_buffer[0] = AKM09918C_ST1_DRDY;
akm09918c_emul_set_reg(fixture->target, AKM09918C_REG_ST1, register_buffer, 1);
/* Set the data magn_percent * range */
for (int i = 0; i < 3; ++i) {
register_buffer[i * 2 + 1] = (magn_percent[i] >> 8) & GENMASK(7, 0);
register_buffer[i * 2] = magn_percent[i] & GENMASK(7, 0);
}
akm09918c_emul_set_reg(fixture->target, AKM09918C_REG_HXL, register_buffer, 6);
/* Fetch the data */
zassert_ok(sensor_sample_fetch(fixture->dev));
zassert_ok(sensor_channel_get(fixture->dev, SENSOR_CHAN_MAGN_XYZ, values));
/* Assert the data is within 0.000005 Gauss */
actual_ugauss = values[0].val1 * INT64_C(1000000) + values[0].val2;
expect_ugauss = magn_percent[0] * AKM09918C_MICRO_GAUSS_PER_BIT;
zassert_within(expect_ugauss, actual_ugauss, INT64_C(5),
"(X) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss",
expect_ugauss, actual_ugauss);
actual_ugauss = values[1].val1 * INT64_C(1000000) + values[1].val2;
expect_ugauss = magn_percent[1] * AKM09918C_MICRO_GAUSS_PER_BIT;
zassert_within(expect_ugauss, actual_ugauss, INT64_C(5),
"(Y) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss",
expect_ugauss, actual_ugauss);
actual_ugauss = values[2].val1 * INT64_C(1000000) + values[2].val2;
expect_ugauss = magn_percent[2] * AKM09918C_MICRO_GAUSS_PER_BIT;
zassert_within(expect_ugauss, actual_ugauss, INT64_C(5),
"(Z) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss",
expect_ugauss, actual_ugauss);
}
ZTEST_F(akm09918c, test_fetch_magn)
{
/* Use (0.25, -0.33..., 0.91) as the factors */
const int16_t magn_percent[3] = {
INT16_C(AKM09918C_MAGN_MAX_DATA_REG) / INT16_C(4),
INT16_C(AKM09918C_MAGN_MIN_DATA_REG) / INT16_C(3),
(int16_t)(INT16_C(AKM09918C_MAGN_MAX_DATA_REG) * INT32_C(91) / INT32_C(100)),
};
test_fetch_magnetic_field(fixture, magn_percent);
}