1 /*
2 * Copyright 2020 Google LLC
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_DRIVERS_SENSOR_BMI160_EMUL_BMI160_H_
8 #define ZEPHYR_DRIVERS_SENSOR_BMI160_EMUL_BMI160_H_
9
10 #include <zephyr/drivers/emul.h>
11 #include <zephyr/drivers/i2c.h>
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 /**
18 * @brief Check if I2C messages are touching a given register (R or W)
19 *
20 * @param[in] msgs The I2C messages in question
21 * @param[in] num_msgs The number of messages in the @p msgs array
22 * @param[in] reg The register to check for
23 * @return True if @p reg is either read or written to
24 * @return False otherwise
25 */
emul_bmi160_i2c_is_touching_reg(struct i2c_msg * msgs,int num_msgs,uint32_t reg)26 __maybe_unused static bool emul_bmi160_i2c_is_touching_reg(struct i2c_msg *msgs, int num_msgs,
27 uint32_t reg)
28 {
29 if (num_msgs != 2) {
30 return false;
31 }
32 if (msgs[0].len != 1) {
33 return false;
34 }
35 if (i2c_is_read_op(msgs)) {
36 return false;
37 }
38
39 uint8_t start_reg = msgs[0].buf[0];
40 uint8_t read_len = msgs[1].len;
41
42 return (start_reg <= reg) && (reg < start_reg + read_len);
43 }
44
45 /**
46 * @brief Check if I2C messages are reading a specific register.
47 *
48 * @param[in] msgs The I2C messages in question
49 * @param[in] num_msgs The number of messages in the @p msgs array
50 * @param[in] reg The register to check for
51 * @return True if @p reg is read
52 * @return False otherwise
53 */
emul_bmi160_i2c_is_reading_reg(struct i2c_msg * msgs,int num_msgs,uint32_t reg)54 __maybe_unused static bool emul_bmi160_i2c_is_reading_reg(struct i2c_msg *msgs, int num_msgs,
55 uint32_t reg)
56 {
57 if (!emul_bmi160_i2c_is_touching_reg(msgs, num_msgs, reg)) {
58 return false;
59 }
60 return i2c_is_read_op(&msgs[1]);
61 }
62
63 /**
64 * @brief Check if I2C messages are writing to a specific register.
65 *
66 * @param[in] msgs The I2C messages in question
67 * @param[in] num_msgs The number of messages in the @p msgs array
68 * @param[in] reg The register to check for
69 * @return True if @p reg is written
70 * @return False otherwise
71 */
emul_bmi160_i2c_is_writing_reg(struct i2c_msg * msgs,int num_msgs,uint32_t reg)72 __maybe_unused static bool emul_bmi160_i2c_is_writing_reg(struct i2c_msg *msgs, int num_msgs,
73 uint32_t reg)
74 {
75 if (!emul_bmi160_i2c_is_touching_reg(msgs, num_msgs, reg)) {
76 return false;
77 }
78 return !i2c_is_read_op(&msgs[1]);
79 }
80
81 /**
82 * @brief Get the internal register value of the emulator
83 *
84 * @param[in] target The emulator in question
85 * @param[in] reg_number The register number to start reading at
86 * @param[out] out Buffer to store the values into
87 * @param[in] count The number of registers to read
88 * @return 0 on success
89 * @return < 0 on error
90 */
91 int emul_bmi160_get_reg_value(const struct emul *target, int reg_number, uint8_t *out,
92 size_t count);
93
94 #ifdef __cplusplus
95 }
96 #endif
97
98 #endif /* ZEPHYR_DRIVERS_SENSOR_BMI160_EMUL_BMI160_H_ */
99