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