1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/drivers/i2c.h>
8 #include <zephyr/kernel.h>
9 #include <zephyr/ztest.h>
10 #include "sensor.h"
11 
12 #define SENSOR_NODE    DT_COMPAT_GET_ANY_STATUS_OKAY(bosch_bme680)
13 #define I2C_TEST_NODE  DT_PARENT(SENSOR_NODE)
14 #define DEVICE_ADDRESS (uint8_t) DT_REG_ADDR(SENSOR_NODE)
15 
16 static const struct device *const i2c_device = DEVICE_DT_GET(I2C_TEST_NODE);
17 static struct calibration_coeffs cal_coeffs;
18 static int32_t t_fine;
19 
20 /* Read data from the senors register */
read_sensor_register(uint8_t register_address)21 static uint8_t read_sensor_register(uint8_t register_address)
22 {
23 	int err;
24 	uint8_t response = 0;
25 
26 	err = i2c_reg_read_byte(i2c_device, DEVICE_ADDRESS, register_address, &response);
27 	zassert_equal(err, 0, "i2c_read(%x)' failed with error: %d\n", register_address, err);
28 	TC_PRINT("I2C read reg, addr: 0x%x, val: 0x%x\n", register_address, response);
29 	return response;
30 }
31 
32 /* Burst read data from the sensor registers */
burst_read_sensor_registers(uint8_t starting_register_address,uint8_t number_of_bytes,uint8_t * data_buffer)33 static void burst_read_sensor_registers(uint8_t starting_register_address, uint8_t number_of_bytes,
34 					uint8_t *data_buffer)
35 {
36 	int err;
37 
38 	zassert_true(number_of_bytes <= MAX_BURST_READ_SIZE,
39 		     "Too many bytes to read %d, max burst read size is set to: %d",
40 		     number_of_bytes, MAX_BURST_READ_SIZE);
41 	err = i2c_burst_read(i2c_device, DEVICE_ADDRESS, starting_register_address, data_buffer,
42 			     number_of_bytes);
43 	zassert_equal(err, 0, "i2c_burst_read(%x, %x)' failed with error: %d\n",
44 		      starting_register_address, number_of_bytes, err);
45 	TC_PRINT("I2C burst read, start addr: 0x%x, number of bytes: %d\n",
46 		 starting_register_address, number_of_bytes);
47 }
48 
49 /* Write sensor register */
write_sensor_register(uint8_t register_address,int8_t value)50 static void write_sensor_register(uint8_t register_address, int8_t value)
51 {
52 	int err;
53 
54 	err = i2c_reg_write_byte(i2c_device, DEVICE_ADDRESS, register_address, value);
55 	zassert_equal(err, 0, "i2c_reg_write_byte(%x, %x)' failed with error: %d\n",
56 		      register_address, value, err);
57 	TC_PRINT("I2C reg write, addr: 0x%x, val: 0x%x\n", register_address, value);
58 }
59 
60 /* Set IIR filter for the temperature and pressure measurements */
set_sensor_iir_filter(void)61 static void set_sensor_iir_filter(void)
62 {
63 	uint8_t response = 0;
64 
65 	TC_PRINT("Set IIR filter\n");
66 	response = read_sensor_register(CONF_REGISTER_ADDRESS);
67 	response &= ~IIR_FILER_ORDER_BIT_MASK;
68 	response |= IIR_FILER_COEFF_3 << IIR_FILER_ORDER_BIT_SHIFT;
69 	write_sensor_register(CONF_REGISTER_ADDRESS, response);
70 	read_sensor_register(CONF_REGISTER_ADDRESS);
71 }
72 
73 /* Read calibration coefficients for temperature, humifity and pressure */
read_calibration_coeffs(struct calibration_coeffs * coeffs)74 static void read_calibration_coeffs(struct calibration_coeffs *coeffs)
75 {
76 	uint8_t register_data[MAX_BURST_READ_SIZE] = {0};
77 
78 	/* Humidity */
79 	TC_PRINT("Reading humidity calibration coefficients\n");
80 	burst_read_sensor_registers(HUMI_PAR_REGISTERS_START_ADDRESS, HUMI_PAR_REGISTERS_COUNT,
81 				    register_data);
82 	coeffs->par_h1 = (uint16_t)(((uint16_t)register_data[HUMI_PAR_H1_MSB_BUF_POSITION] << 4) |
83 				    (register_data[HUMI_PAR_H1_LSB_BUF_POSITION] &
84 				     HUMI_PAR_H1_LSB_BIT_MASK));
85 	coeffs->par_h2 = (uint16_t)(((uint16_t)register_data[HUMI_PAR_H2_MSB_BUF_POSITION] << 4) |
86 				    ((register_data[HUMI_PAR_H2_LSB_BUF_POSITION]) >> 4));
87 
88 	coeffs->par_h3 = (uint8_t)register_data[HUMI_PAR_H3_BUF_POSITION];
89 	coeffs->par_h4 = (uint8_t)register_data[HUMI_PAR_H4_BUF_POSITION];
90 	coeffs->par_h5 = (uint8_t)register_data[HUMI_PAR_H5_BUF_POSITION];
91 	coeffs->par_h6 = (uint8_t)register_data[HUMI_PAR_H6_BUF_POSITION];
92 	coeffs->par_h7 = (uint8_t)register_data[HUMI_PAR_H7_BUF_POSITION];
93 
94 	/* Temperature */
95 	TC_PRINT("Reading temperature calibration coefficients\n");
96 	burst_read_sensor_registers(TEMP_PAR_T1_REGISTER_ADDRESS_LSB, 2, register_data);
97 	coeffs->par_t1 = (uint16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
98 	burst_read_sensor_registers(TEMP_PAR_T2_REGISTER_ADDRESS_LSB, 2, register_data);
99 	coeffs->par_t2 = (uint16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
100 	coeffs->par_t3 = (uint8_t)read_sensor_register(TEMP_PAR_T3_REGISTER_ADDRESS);
101 
102 	/* Pressure */
103 	TC_PRINT("Reading pressure calibration coefficients\n");
104 	burst_read_sensor_registers(PRES_PAR_P1_REGISTER_ADDRESS_LSB, 4, register_data);
105 	coeffs->par_p1 = (uint16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
106 	coeffs->par_p2 = (int16_t)(((uint16_t)register_data[3] << 8) | (uint16_t)register_data[2]);
107 	coeffs->par_p3 = (int8_t)read_sensor_register(PRES_PAR_P3_REGISTER_ADDRESS);
108 	burst_read_sensor_registers(PRES_PAR_P4_REGISTER_ADDRESS_LSB, 4, register_data);
109 	coeffs->par_p4 = (int16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
110 	coeffs->par_p5 = (int16_t)(((uint16_t)register_data[3] << 8) | (uint16_t)register_data[2]);
111 	coeffs->par_p6 = (int8_t)read_sensor_register(PRES_PAR_P6_REGISTER_ADDRESS);
112 	coeffs->par_p7 = (int8_t)read_sensor_register(PRES_PAR_P7_REGISTER_ADDRESS);
113 	burst_read_sensor_registers(PRES_PAR_P8_REGISTER_ADDRESS_LSB, 4, register_data);
114 	coeffs->par_p8 = (int16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
115 	coeffs->par_p9 = (int16_t)(((uint16_t)register_data[3] << 8) | (uint16_t)register_data[2]);
116 	coeffs->par_p10 = read_sensor_register(PRES_PAR_P10_REGISTER_ADDRESS);
117 }
118 
119 /* Configure temperature, pressure and humidity measurements */
configure_measurements(void)120 static void configure_measurements(void)
121 {
122 	unsigned char response = 0;
123 
124 	TC_PRINT("Configure measurements\n");
125 
126 	/* Humidity */
127 	response = read_sensor_register(CTRL_HUM_REGISTER_ADDRESS);
128 	response &= ~HUMIDITY_OVERSAMPLING_BIT_MSK;
129 	response |= HUMIDITY_OVERSAMPLING_1X << HUMIDITY_OVERSAMPLING_BIT_SHIFT;
130 	write_sensor_register(CTRL_HUM_REGISTER_ADDRESS, response);
131 
132 	/* Temperature*/
133 	response = read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
134 	response &= ~TEMP_OVERSAMPLING_BIT_MSK;
135 	response |= TEMPERATURE_OVERSAMPLING_2X << TEMP_OVERSAMPLING_BIT_SHIFT;
136 
137 	write_sensor_register(CTRL_MEAS_REGISTER_ADDRESS, response);
138 
139 	/* Pressure */
140 	response = read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
141 	response &= ~PRES_OVERSAMPLING_BIT_MSK;
142 	response |= PRESSURE_OVERSAMPLING_16X << PRES_OVERSAMPLING_BIT_SHIFT;
143 
144 	write_sensor_register(CTRL_MEAS_REGISTER_ADDRESS, response);
145 	read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
146 	set_sensor_iir_filter();
147 }
148 
149 /* Set the sensor operation mode */
set_sensor_mode(uint8_t sensor_mode)150 static void set_sensor_mode(uint8_t sensor_mode)
151 {
152 	unsigned char response = 0;
153 
154 	TC_PRINT("Set sensor mode to: 0x%x\n", sensor_mode);
155 
156 	response = read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
157 	response &= ~CTRL_MEAS_MODE_BIT_MSK;
158 	response |= sensor_mode << CTRL_MEAS_MODE_BIT_SHIFT;
159 	write_sensor_register(CTRL_MEAS_REGISTER_ADDRESS, response);
160 	read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
161 }
162 
163 /* Read the raw ADC temperature measurement result */
read_adc_temperature(void)164 static uint32_t read_adc_temperature(void)
165 {
166 	uint32_t adc_temperature = 0;
167 
168 	TC_PRINT("Reading ADC temperature\n");
169 	adc_temperature = (uint32_t)(((uint32_t)read_sensor_register(TEMP_ADC_DATA_MSB_0) << 12) |
170 				     ((uint32_t)read_sensor_register(TEMP_ADC_DATA_LSB_0) << 4) |
171 				     ((uint32_t)read_sensor_register(TEMP_ADC_DATA_XLSB_0) >> 4));
172 
173 	return adc_temperature;
174 }
175 
176 /* Read the raw ADC pressure measurement result */
read_adc_pressure(void)177 static uint32_t read_adc_pressure(void)
178 {
179 	uint32_t pres_adc = 0;
180 
181 	TC_PRINT("Reading ADC pressure\n");
182 	pres_adc = (uint32_t)(((uint32_t)read_sensor_register(PRES_ADC_DATA_MSB_0) << 12) |
183 			      ((uint32_t)read_sensor_register(PRES_ADC_DATA_LSB_0) << 4) |
184 			      ((uint32_t)read_sensor_register(PRES_ADC_DATA_XLSB_0) >> 4));
185 
186 	return pres_adc;
187 }
188 
189 /* Read the raw ADC humidity measurement result */
read_adc_humidity(void)190 static uint16_t read_adc_humidity(void)
191 {
192 	uint16_t hum_adc = 0;
193 
194 	TC_PRINT("Reading ADC humidity\n");
195 	hum_adc = (uint16_t)(((uint16_t)read_sensor_register(HUM_ADC_DATA_MSB_0) << 8) |
196 			     (uint16_t)read_sensor_register(HUM_ADC_DATA_LSB_0));
197 
198 	return hum_adc;
199 }
200 
ZTEST(i2c_controller_to_sensor,test_i2c_basic_memory_read)201 ZTEST(i2c_controller_to_sensor, test_i2c_basic_memory_read)
202 {
203 	int err;
204 	uint32_t i2c_config = I2C_SPEED_SET(CONFIG_TEST_I2C_SPEED) | I2C_MODE_CONTROLLER;
205 	uint8_t entire_sensor_memory[SENSOR_MEMORY_SIZE_IN_BYTES] = {0};
206 
207 	TC_PRINT("Device address 0x%x\n", DEVICE_ADDRESS);
208 	TC_PRINT("I2C speed setting: %d\n", CONFIG_TEST_I2C_SPEED);
209 
210 	err = i2c_configure(i2c_device, i2c_config);
211 	zassert_equal(err, 0, "i2c_configure' failed with error: %d\n", err);
212 
213 	err = i2c_read(i2c_device, entire_sensor_memory, SENSOR_MEMORY_SIZE_IN_BYTES,
214 		       DEVICE_ADDRESS);
215 	zassert_equal(err, 0, "i2c_read' failed with error: %d\n", err);
216 }
217 
ZTEST(i2c_controller_to_sensor,test_i2c_nack_handling)218 ZTEST(i2c_controller_to_sensor, test_i2c_nack_handling)
219 {
220 	int err;
221 	uint8_t test_data;
222 
223 	TC_PRINT("Device address 0x%x\n", DEVICE_ADDRESS);
224 
225 	err = i2c_read(i2c_device, &test_data, 1, DEVICE_ADDRESS + 1);
226 	zassert_equal(err, -EIO, "Invalid device address not detected, err: %d\n", err);
227 
228 	err = i2c_reg_read_byte(i2c_device, DEVICE_ADDRESS, CHIP_ID_REGISTER_ADDRESS, &test_data);
229 	zassert_equal(err, 0, "Failed to read device register after previous address NACK: %d\n",
230 		      err);
231 }
232 
ZTEST(i2c_controller_to_sensor,test_i2c_bus_recovery)233 ZTEST(i2c_controller_to_sensor, test_i2c_bus_recovery)
234 {
235 	int err;
236 	uint8_t test_data;
237 
238 	TC_PRINT("Device address 0x%x\n", DEVICE_ADDRESS);
239 
240 	err = i2c_recover_bus(i2c_device);
241 	zassert_equal(err, 0, "'i2c_recover_bus' failed with error: %d\n", err);
242 
243 	err = i2c_reg_read_byte(i2c_device, DEVICE_ADDRESS, CHIP_ID_REGISTER_ADDRESS, &test_data);
244 	zassert_equal(err, 0, "Failed to read device register after bus recovery: %d\n", err);
245 }
246 
ZTEST(i2c_controller_to_sensor,test_i2c_controlled_sensor_operation)247 ZTEST(i2c_controller_to_sensor, test_i2c_controlled_sensor_operation)
248 {
249 	int err;
250 	uint8_t response = 0;
251 	int16_t temperature = 0;
252 	uint32_t pressure = 0;
253 	uint32_t humidity = 0;
254 	uint32_t i2c_config = I2C_SPEED_SET(CONFIG_TEST_I2C_SPEED) | I2C_MODE_CONTROLLER;
255 	uint8_t measurements_left = MEASUREMENT_CYCLES + 1;
256 
257 	TC_PRINT("Device address 0x%x\n", DEVICE_ADDRESS);
258 	TC_PRINT("I2C speed setting: %d\n", CONFIG_TEST_I2C_SPEED);
259 
260 	err = i2c_configure(i2c_device, i2c_config);
261 	zassert_equal(err, 0, "i2c_configure' failed with error: %d\n", err);
262 
263 	response = read_sensor_register(CHIP_ID_REGISTER_ADDRESS);
264 	TC_PRINT("Chip_Id: %d\n", response);
265 
266 	response = read_sensor_register(VARIANT_ID_REGISTER_ADDRESS);
267 	TC_PRINT("Variant_Id: %d\n", response);
268 
269 	write_sensor_register(RESET_REGISTER_ADDRESS, RESET_DEVICE);
270 	k_sleep(K_MSEC(SLEEP_TIME_MS));
271 
272 	read_calibration_coeffs(&cal_coeffs);
273 
274 	configure_measurements();
275 	set_sensor_mode(FORCED_MODE);
276 
277 	while (measurements_left) {
278 		response = read_sensor_register(MEAS_STATUS_0_REG_ADDRESS);
279 		TC_PRINT("Meas status 0, meas in progress: %d, new data: %d\n",
280 			 response & MEASUREMENT_IN_PROGRESS_BIT_MASK,
281 			 response & MEASUREMENT_NEW_DATA_BIT_MASK);
282 		if (response & MEASUREMENT_NEW_DATA_BIT_MASK) {
283 			temperature =
284 				calculate_temperature(read_adc_temperature(), &t_fine, &cal_coeffs);
285 			pressure = calculate_pressure(read_adc_pressure(), t_fine, &cal_coeffs);
286 			humidity = calculate_humidity(read_adc_humidity(), t_fine, &cal_coeffs);
287 			TC_PRINT("Temperature: %d.%d C deg\n", temperature / 100,
288 				 temperature % 100);
289 			TC_PRINT("Pressure: %d hPa\n", pressure / 100);
290 			TC_PRINT("Humidity: %d %%\n", humidity / 1000);
291 			set_sensor_mode(FORCED_MODE);
292 
293 			/* Check if the results are within reasonable ranges
294 			 * for laboratory room usage
295 			 * This is asserted to catch values
296 			 * that may be results of an erroneous
297 			 * bus operation (corrupted read or write)
298 			 */
299 			zassert_true(
300 				(temperature / 100 >= 5) && (temperature / 100 <= 55),
301 				"Temperature is outside of the allowed range for labroatory use");
302 			zassert_true((pressure / 100 >= 700) && (pressure / 100 <= 1300),
303 				     "Pressure is outside of the allowed range for labroatory use");
304 			zassert_true((humidity / 1000 >= 10) && (humidity / 1000 <= 90),
305 				     "Humidity is outside of the allowed range for labroatory use");
306 			measurements_left--;
307 		}
308 		k_sleep(K_MSEC(SLEEP_TIME_MS));
309 	}
310 }
311 
312 /*
313  * Test setup
314  */
test_setup(void)315 void *test_setup(void)
316 {
317 	zassert_true(device_is_ready(i2c_device), "i2c device is not ready");
318 	return NULL;
319 }
320 
321 ZTEST_SUITE(i2c_controller_to_sensor, NULL, test_setup, NULL, NULL, NULL);
322