1 /*
2 * Copyright (c) 2023 Google LLC
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <zephyr/devicetree.h>
7 #include <zephyr/drivers/emul.h>
8 #include <zephyr/drivers/sensor.h>
9 #include <zephyr/ztest.h>
10
11 #include "akm09918c.h"
12 #include "akm09918c_emul.h"
13 #include "akm09918c_reg.h"
14
15 struct akm09918c_fixture {
16 const struct device *dev;
17 const struct emul *target;
18 };
19
akm09918c_setup(void)20 static void *akm09918c_setup(void)
21 {
22 static struct akm09918c_fixture fixture = {
23 .dev = DEVICE_DT_GET(DT_NODELABEL(akm09918c)),
24 .target = EMUL_DT_GET(DT_NODELABEL(akm09918c)),
25 };
26
27 zassert_not_null(fixture.dev);
28 zassert_not_null(fixture.target);
29 return &fixture;
30 }
31
akm09918c_before(void * f)32 static void akm09918c_before(void *f)
33 {
34 struct akm09918c_fixture *fixture = f;
35
36 akm09918c_emul_reset(fixture->target);
37 }
38
39 ZTEST_SUITE(akm09918c, NULL, akm09918c_setup, akm09918c_before, NULL, NULL);
40
ZTEST_F(akm09918c,test_fetch_fail_no_ready_data)41 ZTEST_F(akm09918c, test_fetch_fail_no_ready_data)
42 {
43 uint8_t status = 0;
44
45 akm09918c_emul_set_reg(fixture->target, AKM09918C_REG_ST1, &status, 1);
46 zassert_equal(-EBUSY, sensor_sample_fetch(fixture->dev));
47 }
48
test_fetch_magnetic_field(const struct akm09918c_fixture * fixture,const int16_t magn_percent[3])49 static void test_fetch_magnetic_field(const struct akm09918c_fixture *fixture,
50 const int16_t magn_percent[3])
51 {
52 struct sensor_value values[3];
53 int64_t expect_ugauss;
54 int64_t actual_ugauss;
55 uint8_t register_buffer[6];
56
57 /* Set the ST1 register to show we have data */
58 register_buffer[0] = AKM09918C_ST1_DRDY;
59 akm09918c_emul_set_reg(fixture->target, AKM09918C_REG_ST1, register_buffer, 1);
60
61 /* Set the data magn_percent * range */
62 for (int i = 0; i < 3; ++i) {
63 register_buffer[i * 2 + 1] = (magn_percent[i] >> 8) & GENMASK(7, 0);
64 register_buffer[i * 2] = magn_percent[i] & GENMASK(7, 0);
65 }
66 akm09918c_emul_set_reg(fixture->target, AKM09918C_REG_HXL, register_buffer, 6);
67
68 /* Fetch the data */
69 zassert_ok(sensor_sample_fetch(fixture->dev));
70 zassert_ok(sensor_channel_get(fixture->dev, SENSOR_CHAN_MAGN_XYZ, values));
71
72 /* Assert the data is within 0.000005 Gauss */
73 actual_ugauss = values[0].val1 * INT64_C(1000000) + values[0].val2;
74 expect_ugauss = magn_percent[0] * AKM09918C_MICRO_GAUSS_PER_BIT;
75 zassert_within(expect_ugauss, actual_ugauss, INT64_C(5),
76 "(X) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss",
77 expect_ugauss, actual_ugauss);
78
79 actual_ugauss = values[1].val1 * INT64_C(1000000) + values[1].val2;
80 expect_ugauss = magn_percent[1] * AKM09918C_MICRO_GAUSS_PER_BIT;
81 zassert_within(expect_ugauss, actual_ugauss, INT64_C(5),
82 "(Y) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss",
83 expect_ugauss, actual_ugauss);
84
85 actual_ugauss = values[2].val1 * INT64_C(1000000) + values[2].val2;
86 expect_ugauss = magn_percent[2] * AKM09918C_MICRO_GAUSS_PER_BIT;
87 zassert_within(expect_ugauss, actual_ugauss, INT64_C(5),
88 "(Z) expected %" PRIi64 " micro-gauss, got %" PRIi64 " micro-gauss",
89 expect_ugauss, actual_ugauss);
90 }
91
ZTEST_F(akm09918c,test_fetch_magn)92 ZTEST_F(akm09918c, test_fetch_magn)
93 {
94 /* Use (0.25, -0.33..., 0.91) as the factors */
95 const int16_t magn_percent[3] = {
96 INT16_C(AKM09918C_MAGN_MAX_DATA_REG) / INT16_C(4),
97 INT16_C(AKM09918C_MAGN_MIN_DATA_REG) / INT16_C(3),
98 (int16_t)(INT16_C(AKM09918C_MAGN_MAX_DATA_REG) * INT32_C(91) / INT32_C(100)),
99 };
100
101 test_fetch_magnetic_field(fixture, magn_percent);
102 }
103