tests: drivers: Add more test cases for the i2c driver in controller mode
Extend coverage for the i2c master mode driver This test suite uses external sensor BME688 Signed-off-by: Bartosz Miller <bartosz.miller@nordicsemi.no>
This commit is contained in:
parent
c8faa1e380
commit
d8bffffda0
7 changed files with 577 additions and 0 deletions
9
tests/drivers/i2c/i2c_bme688/CMakeLists.txt
Normal file
9
tests/drivers/i2c/i2c_bme688/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
cmake_minimum_required(VERSION 3.20.0)
|
||||
|
||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||
project(i2c_bme688)
|
||||
|
||||
FILE(GLOB app_sources src/*.c)
|
||||
target_sources(app PRIVATE ${app_sources})
|
6
tests/drivers/i2c/i2c_bme688/README.txt
Normal file
6
tests/drivers/i2c/i2c_bme688/README.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
I2C bus controller to BME688 sensor test
|
||||
########################################
|
||||
|
||||
This test verifies I2C target driver API methods
|
||||
with external sensors device - Bosch BME688.
|
||||
I2C speed is set to standard.
|
2
tests/drivers/i2c/i2c_bme688/prj.conf
Normal file
2
tests/drivers/i2c/i2c_bme688/prj.conf
Normal file
|
@ -0,0 +1,2 @@
|
|||
CONFIG_I2C=y
|
||||
CONFIG_ZTEST=y
|
286
tests/drivers/i2c/i2c_bme688/src/main.c
Normal file
286
tests/drivers/i2c/i2c_bme688/src/main.c
Normal file
|
@ -0,0 +1,286 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <zephyr/drivers/i2c.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/ztest.h>
|
||||
#include "sensor.h"
|
||||
|
||||
#define SENSOR_NODE DT_COMPAT_GET_ANY_STATUS_OKAY(bosch_bme680)
|
||||
#define I2C_TEST_NODE DT_PARENT(SENSOR_NODE)
|
||||
#define DEVICE_ADDRESS (uint8_t)DT_REG_ADDR(SENSOR_NODE)
|
||||
|
||||
static const struct device *const i2c_device = DEVICE_DT_GET(I2C_TEST_NODE);
|
||||
static struct calibration_coeffs cal_coeffs;
|
||||
static int32_t t_fine;
|
||||
|
||||
/* Read data from the senors register */
|
||||
static uint8_t read_sensor_register(uint8_t register_address)
|
||||
{
|
||||
int err;
|
||||
uint8_t response = 0;
|
||||
|
||||
err = i2c_reg_read_byte(i2c_device, DEVICE_ADDRESS, register_address, &response);
|
||||
zassert_equal(err, 0, "i2c_read(%x)' failed with error: %d\n", register_address, err);
|
||||
TC_PRINT("I2C read reg, addr: 0x%x, val: 0x%x\n", register_address, response);
|
||||
return response;
|
||||
}
|
||||
|
||||
/* Burst read data from the sensor registers */
|
||||
static void burst_read_sensor_registers(uint8_t starting_register_address, uint8_t number_of_bytes,
|
||||
uint8_t *data_buffer)
|
||||
{
|
||||
int err;
|
||||
|
||||
zassert_true(number_of_bytes <= MAX_BURST_READ_SIZE,
|
||||
"Too many bytes to read %d, max burst read size is set to: %d",
|
||||
number_of_bytes, MAX_BURST_READ_SIZE);
|
||||
err = i2c_burst_read(i2c_device, DEVICE_ADDRESS, starting_register_address, data_buffer,
|
||||
number_of_bytes);
|
||||
zassert_equal(err, 0, "i2c_burst_read(%x, %x)' failed with error: %d\n",
|
||||
starting_register_address, number_of_bytes, err);
|
||||
TC_PRINT("I2C burst read, start addr: 0x%x, number of bytes: %d\n",
|
||||
starting_register_address, number_of_bytes);
|
||||
}
|
||||
|
||||
/* Write sensor register */
|
||||
static void write_sensor_register(uint8_t register_address, int8_t value)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = i2c_reg_write_byte(i2c_device, DEVICE_ADDRESS, register_address, value);
|
||||
zassert_equal(err, 0, "i2c_reg_write_byte(%x, %x)' failed with error: %d\n",
|
||||
register_address, value, err);
|
||||
TC_PRINT("I2C reg write, addr: 0x%x, val: 0x%x\n", register_address, value);
|
||||
}
|
||||
|
||||
/* Set IIR filter for the temperature and pressure measurements */
|
||||
static void set_sensor_iir_filter(void)
|
||||
{
|
||||
uint8_t response = 0;
|
||||
|
||||
TC_PRINT("Set IIR filter\n");
|
||||
response = read_sensor_register(CONF_REGISTER_ADDRESS);
|
||||
response &= ~IIR_FILER_ORDER_BIT_MASK;
|
||||
response |= IIR_FILER_COEFF_3 << IIR_FILER_ORDER_BIT_SHIFT;
|
||||
write_sensor_register(CONF_REGISTER_ADDRESS, response);
|
||||
read_sensor_register(CONF_REGISTER_ADDRESS);
|
||||
}
|
||||
|
||||
/* Read calibration coefficients for temperature, humifity and pressure */
|
||||
static void read_calibration_coeffs(struct calibration_coeffs *coeffs)
|
||||
{
|
||||
uint8_t register_data[MAX_BURST_READ_SIZE] = { 0 };
|
||||
|
||||
/* Humidity */
|
||||
TC_PRINT("Reading humidity calibration coefficients\n");
|
||||
burst_read_sensor_registers(HUMI_PAR_REGISTERS_START_ADDRESS, HUMI_PAR_REGISTERS_COUNT,
|
||||
register_data);
|
||||
coeffs->par_h1 = (uint16_t)(((uint16_t)register_data[HUMI_PAR_H1_MSB_BUF_POSITION] << 4) |
|
||||
(register_data[HUMI_PAR_H1_LSB_BUF_POSITION] &
|
||||
HUMI_PAR_H1_LSB_BIT_MASK));
|
||||
coeffs->par_h2 = (uint16_t)(((uint16_t)register_data[HUMI_PAR_H2_MSB_BUF_POSITION] << 4) |
|
||||
((register_data[HUMI_PAR_H2_LSB_BUF_POSITION]) >> 4));
|
||||
|
||||
coeffs->par_h3 = (uint8_t)register_data[HUMI_PAR_H3_BUF_POSITION];
|
||||
coeffs->par_h4 = (uint8_t)register_data[HUMI_PAR_H4_BUF_POSITION];
|
||||
coeffs->par_h5 = (uint8_t)register_data[HUMI_PAR_H5_BUF_POSITION];
|
||||
coeffs->par_h6 = (uint8_t)register_data[HUMI_PAR_H6_BUF_POSITION];
|
||||
coeffs->par_h7 = (uint8_t)register_data[HUMI_PAR_H7_BUF_POSITION];
|
||||
|
||||
/* Temperature */
|
||||
TC_PRINT("Reading temperature calibration coefficients\n");
|
||||
burst_read_sensor_registers(TEMP_PAR_T1_REGISTER_ADDRESS_LSB, 2, register_data);
|
||||
coeffs->par_t1 = (uint16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
|
||||
burst_read_sensor_registers(TEMP_PAR_T2_REGISTER_ADDRESS_LSB, 2, register_data);
|
||||
coeffs->par_t2 = (uint16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
|
||||
coeffs->par_t3 = (uint8_t)read_sensor_register(TEMP_PAR_T3_REGISTER_ADDRESS);
|
||||
|
||||
/* Pressure */
|
||||
TC_PRINT("Reading pressure calibration coefficients\n");
|
||||
burst_read_sensor_registers(PRES_PAR_P1_REGISTER_ADDRESS_LSB, 4, register_data);
|
||||
coeffs->par_p1 = (uint16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
|
||||
coeffs->par_p2 = (int16_t)(((uint16_t)register_data[3] << 8) | (uint16_t)register_data[2]);
|
||||
coeffs->par_p3 = (int8_t)read_sensor_register(PRES_PAR_P3_REGISTER_ADDRESS);
|
||||
burst_read_sensor_registers(PRES_PAR_P4_REGISTER_ADDRESS_LSB, 4, register_data);
|
||||
coeffs->par_p4 = (int16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
|
||||
coeffs->par_p5 = (int16_t)(((uint16_t)register_data[3] << 8) | (uint16_t)register_data[2]);
|
||||
coeffs->par_p6 = (int8_t)read_sensor_register(PRES_PAR_P6_REGISTER_ADDRESS);
|
||||
coeffs->par_p7 = (int8_t)read_sensor_register(PRES_PAR_P7_REGISTER_ADDRESS);
|
||||
burst_read_sensor_registers(PRES_PAR_P8_REGISTER_ADDRESS_LSB, 4, register_data);
|
||||
coeffs->par_p8 = (int16_t)(((uint16_t)register_data[1] << 8) | (uint16_t)register_data[0]);
|
||||
coeffs->par_p9 = (int16_t)(((uint16_t)register_data[3] << 8) | (uint16_t)register_data[2]);
|
||||
coeffs->par_p10 = read_sensor_register(PRES_PAR_P10_REGISTER_ADDRESS);
|
||||
}
|
||||
|
||||
/* Configure temperature, pressure and humidity measurements */
|
||||
static void configure_measurements(void)
|
||||
{
|
||||
unsigned char response = 0;
|
||||
|
||||
TC_PRINT("Configure measurements\n");
|
||||
|
||||
/* Humidity */
|
||||
response = read_sensor_register(CTRL_HUM_REGISTER_ADDRESS);
|
||||
response &= ~HUMIDITY_OVERSAMPLING_BIT_MSK;
|
||||
response |= HUMIDITY_OVERSAMPLING_1X << HUMIDITY_OVERSAMPLING_BIT_SHIFT;
|
||||
write_sensor_register(CTRL_HUM_REGISTER_ADDRESS, response);
|
||||
|
||||
/* Temperature*/
|
||||
response = read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
|
||||
response &= ~TEMP_OVERSAMPLING_BIT_MSK;
|
||||
response |= TEMPERATURE_OVERSAMPLING_2X << TEMP_OVERSAMPLING_BIT_SHIFT;
|
||||
|
||||
write_sensor_register(CTRL_MEAS_REGISTER_ADDRESS, response);
|
||||
|
||||
/* Pressure */
|
||||
response = read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
|
||||
response &= ~PRES_OVERSAMPLING_BIT_MSK;
|
||||
response |= PRESSURE_OVERSAMPLING_16X << PRES_OVERSAMPLING_BIT_SHIFT;
|
||||
|
||||
write_sensor_register(CTRL_MEAS_REGISTER_ADDRESS, response);
|
||||
read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
|
||||
set_sensor_iir_filter();
|
||||
}
|
||||
|
||||
/* Set the sensor operation mode */
|
||||
static void set_sensor_mode(uint8_t sensor_mode)
|
||||
{
|
||||
unsigned char response = 0;
|
||||
|
||||
TC_PRINT("Set sensor mode to: 0x%x\n", sensor_mode);
|
||||
|
||||
response = read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
|
||||
response &= ~CTRL_MEAS_MODE_BIT_MSK;
|
||||
response |= sensor_mode << CTRL_MEAS_MODE_BIT_SHIFT;
|
||||
write_sensor_register(CTRL_MEAS_REGISTER_ADDRESS, response);
|
||||
read_sensor_register(CTRL_MEAS_REGISTER_ADDRESS);
|
||||
}
|
||||
|
||||
/* Read the raw ADC temperature measurement result */
|
||||
static uint32_t read_adc_temperature(void)
|
||||
{
|
||||
uint32_t adc_temperature = 0;
|
||||
|
||||
TC_PRINT("Reading ADC temperature\n");
|
||||
adc_temperature = (uint32_t)(((uint32_t)read_sensor_register(TEMP_ADC_DATA_MSB_0) << 12) |
|
||||
((uint32_t)read_sensor_register(TEMP_ADC_DATA_LSB_0) << 4) |
|
||||
((uint32_t)read_sensor_register(TEMP_ADC_DATA_XLSB_0) >> 4));
|
||||
|
||||
return adc_temperature;
|
||||
}
|
||||
|
||||
/* Read the raw ADC pressure measurement result */
|
||||
static uint32_t read_adc_pressure(void)
|
||||
{
|
||||
uint32_t pres_adc = 0;
|
||||
|
||||
TC_PRINT("Reading ADC pressure\n");
|
||||
pres_adc = (uint32_t)(((uint32_t)read_sensor_register(PRES_ADC_DATA_MSB_0) << 12) |
|
||||
((uint32_t)read_sensor_register(PRES_ADC_DATA_LSB_0) << 4) |
|
||||
((uint32_t)read_sensor_register(PRES_ADC_DATA_XLSB_0) >> 4));
|
||||
|
||||
return pres_adc;
|
||||
}
|
||||
|
||||
/* Read the raw ADC humidity measurement result */
|
||||
static uint16_t read_adc_humidity(void)
|
||||
{
|
||||
uint16_t hum_adc = 0;
|
||||
|
||||
TC_PRINT("Reading ADC humidity\n");
|
||||
hum_adc = (uint16_t)(((uint16_t)read_sensor_register(HUM_ADC_DATA_MSB_0) << 8) |
|
||||
(uint16_t)read_sensor_register(HUM_ADC_DATA_LSB_0));
|
||||
|
||||
return hum_adc;
|
||||
}
|
||||
|
||||
ZTEST(i2c_controller_to_sensor, test_i2c_basic_memory_read)
|
||||
{
|
||||
int err;
|
||||
uint8_t entire_sensor_memory[SENSOR_MEMORY_SIZE_IN_BYTES] = { 0 };
|
||||
|
||||
TC_PRINT("Device address 0x%x\n", DEVICE_ADDRESS);
|
||||
|
||||
err = i2c_read(i2c_device, entire_sensor_memory, SENSOR_MEMORY_SIZE_IN_BYTES,
|
||||
DEVICE_ADDRESS);
|
||||
zassert_equal(err, 0, "i2c_read' failed with error: %d\n", err);
|
||||
}
|
||||
|
||||
ZTEST(i2c_controller_to_sensor, test_i2c_controlled_sensor_operation)
|
||||
{
|
||||
int err;
|
||||
uint8_t response = 0;
|
||||
int16_t temperature = 0;
|
||||
uint32_t pressure = 0;
|
||||
uint32_t humidity = 0;
|
||||
uint32_t i2c_config = I2C_SPEED_SET(I2C_SPEED_STANDARD) | I2C_MODE_CONTROLLER;
|
||||
uint8_t measurements_left = MEASUREMENT_CYCLES + 1;
|
||||
|
||||
TC_PRINT("Device address 0x%x\n", DEVICE_ADDRESS);
|
||||
|
||||
err = i2c_configure(i2c_device, i2c_config);
|
||||
zassert_equal(err, 0, "i2c_configure' failed with error: %d\n", err);
|
||||
|
||||
response = read_sensor_register(CHIP_ID_REGISTER_ADDRESS);
|
||||
TC_PRINT("Chip_Id: %d\n", response);
|
||||
|
||||
response = read_sensor_register(VARIANT_ID_REGISTER_ADDRESS);
|
||||
TC_PRINT("Variant_Id: %d\n", response);
|
||||
|
||||
write_sensor_register(RESET_REGISTER_ADDRESS, RESET_DEVICE);
|
||||
k_sleep(K_MSEC(SLEEP_TIME_MS));
|
||||
|
||||
read_calibration_coeffs(&cal_coeffs);
|
||||
|
||||
configure_measurements();
|
||||
set_sensor_mode(FORCED_MODE);
|
||||
|
||||
while (measurements_left) {
|
||||
response = read_sensor_register(MEAS_STATUS_0_REG_ADDRESS);
|
||||
TC_PRINT("Meas status 0, meas in progress: %d, new data: %d\n",
|
||||
response & MEASUREMENT_IN_PROGRESS_BIT_MASK,
|
||||
response & MEASUREMENT_NEW_DATA_BIT_MASK);
|
||||
if (response & MEASUREMENT_NEW_DATA_BIT_MASK) {
|
||||
temperature =
|
||||
calculate_temperature(read_adc_temperature(), &t_fine, &cal_coeffs);
|
||||
pressure = calculate_pressure(read_adc_pressure(), t_fine, &cal_coeffs);
|
||||
humidity = calculate_humidity(read_adc_humidity(), t_fine, &cal_coeffs);
|
||||
TC_PRINT("Temperature: %d.%d C deg\n", temperature / 100,
|
||||
temperature % 100);
|
||||
TC_PRINT("Pressure: %d hPa\n", pressure / 100);
|
||||
TC_PRINT("Humidity: %d %%\n", humidity / 1000);
|
||||
set_sensor_mode(FORCED_MODE);
|
||||
|
||||
/* Check if the results are within reasonable ranges
|
||||
* for laboratory room usage
|
||||
* This is asserted to catch values
|
||||
* that may be results of an erroneous
|
||||
* bus operation (corrupted read or write)
|
||||
*/
|
||||
zassert_true(
|
||||
(temperature / 100 >= 5) && (temperature / 100 <= 55),
|
||||
"Temperature is outside of the allowed range for labroatory use");
|
||||
zassert_true((pressure / 100 >= 700) && (pressure / 100 <= 1300),
|
||||
"Pressure is outside of the allowed range for labroatory use");
|
||||
zassert_true((humidity / 1000 >= 10) && (humidity / 1000 <= 90),
|
||||
"Humidity is outside of the allowed range for labroatory use");
|
||||
measurements_left--;
|
||||
}
|
||||
k_sleep(K_MSEC(SLEEP_TIME_MS));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test setup
|
||||
*/
|
||||
void *test_setup(void)
|
||||
{
|
||||
zassert_true(device_is_ready(i2c_device), "i2c device is not ready");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ZTEST_SUITE(i2c_controller_to_sensor, NULL, test_setup, NULL, NULL, NULL);
|
105
tests/drivers/i2c/i2c_bme688/src/sensor.c
Normal file
105
tests/drivers/i2c/i2c_bme688/src/sensor.c
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include "sensor.h"
|
||||
|
||||
/* Calculate the compensated temperature */
|
||||
int32_t calculate_temperature(uint32_t adc_temp, int32_t *t_fine,
|
||||
struct calibration_coeffs *cal_coeffs)
|
||||
{
|
||||
int16_t temperature_compensated = 0;
|
||||
int64_t var1, var2, var3;
|
||||
|
||||
var1 = ((int32_t)adc_temp >> 3) - ((int32_t)cal_coeffs->par_t1 << 1);
|
||||
var2 = (var1 * (int32_t)cal_coeffs->par_t2) >> 11;
|
||||
var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
|
||||
var3 = ((var3) * ((int32_t)cal_coeffs->par_t3 << 4)) >> 14;
|
||||
*t_fine = var2 + var3;
|
||||
temperature_compensated = (int16_t)(((*t_fine * 5) + 128) >> 8);
|
||||
return temperature_compensated;
|
||||
}
|
||||
|
||||
/* Calculate the compensated pressure
|
||||
* Note: temperature must be calculated first
|
||||
* to obtain the 't_fine'
|
||||
*/
|
||||
uint32_t calculate_pressure(uint32_t pres_adc, int32_t t_fine,
|
||||
struct calibration_coeffs *cal_coeffs)
|
||||
{
|
||||
int32_t var1;
|
||||
int32_t var2;
|
||||
int32_t var3;
|
||||
int32_t pressure_comp;
|
||||
const int32_t pres_ovf_check = INT32_C(0x40000000);
|
||||
|
||||
var1 = (((int32_t)t_fine) >> 1) - 64000;
|
||||
var2 = ((((var1 >> 2) * (var1 >> 2)) >> 11) * (int32_t)cal_coeffs->par_p6) >> 2;
|
||||
var2 = var2 + ((var1 * (int32_t)cal_coeffs->par_p5) << 1);
|
||||
var2 = (var2 >> 2) + ((int32_t)cal_coeffs->par_p4 << 16);
|
||||
var1 = (((((var1 >> 2) * (var1 >> 2)) >> 13) * ((int32_t)cal_coeffs->par_p3 << 5)) >> 3) +
|
||||
(((int32_t)cal_coeffs->par_p2 * var1) >> 1);
|
||||
var1 = var1 >> 18;
|
||||
var1 = ((32768 + var1) * (int32_t)cal_coeffs->par_p1) >> 15;
|
||||
pressure_comp = 1048576 - pres_adc;
|
||||
pressure_comp = (int32_t)((pressure_comp - (var2 >> 12)) * ((uint32_t)3125));
|
||||
if (pressure_comp >= pres_ovf_check) {
|
||||
pressure_comp = ((pressure_comp / var1) << 1);
|
||||
} else {
|
||||
pressure_comp = ((pressure_comp << 1) / var1);
|
||||
}
|
||||
|
||||
var1 = ((int32_t)cal_coeffs->par_p9 *
|
||||
(int32_t)(((pressure_comp >> 3) * (pressure_comp >> 3)) >> 13)) >>
|
||||
12;
|
||||
var2 = ((int32_t)(pressure_comp >> 2) * (int32_t)cal_coeffs->par_p8) >> 13;
|
||||
var3 = ((int32_t)(pressure_comp >> 8) * (int32_t)(pressure_comp >> 8) *
|
||||
(int32_t)(pressure_comp >> 8) * (int32_t)cal_coeffs->par_p10) >>
|
||||
17;
|
||||
pressure_comp = (int32_t)(pressure_comp) +
|
||||
((var1 + var2 + var3 + ((int32_t)cal_coeffs->par_p7 << 7)) >> 4);
|
||||
|
||||
return (uint32_t)pressure_comp;
|
||||
}
|
||||
|
||||
/* Calculate the relative humidity
|
||||
* Note: temperature must be calculated first
|
||||
* to obtain the 't_fine'
|
||||
*/
|
||||
uint32_t calculate_humidity(uint16_t hum_adc, int32_t t_fine, struct calibration_coeffs *cal_coeffs)
|
||||
{
|
||||
int32_t var1;
|
||||
int32_t var2;
|
||||
int32_t var3;
|
||||
int32_t var4;
|
||||
int32_t var5;
|
||||
int32_t var6;
|
||||
int32_t temp_scaled;
|
||||
int32_t calc_hum;
|
||||
|
||||
temp_scaled = (((int32_t)t_fine * 5) + 128) >> 8;
|
||||
var1 = (int32_t)(hum_adc - ((int32_t)((int32_t)cal_coeffs->par_h1 * 16))) -
|
||||
(((temp_scaled * (int32_t)cal_coeffs->par_h3) / ((int32_t)100)) >> 1);
|
||||
var2 = ((int32_t)cal_coeffs->par_h2 *
|
||||
(((temp_scaled * (int32_t)cal_coeffs->par_h4) / ((int32_t)100)) +
|
||||
(((temp_scaled * ((temp_scaled * (int32_t)cal_coeffs->par_h5) / ((int32_t)100))) >>
|
||||
6) /
|
||||
((int32_t)100)) +
|
||||
(int32_t)(1 << 14))) >>
|
||||
10;
|
||||
var3 = var1 * var2;
|
||||
var4 = (int32_t)cal_coeffs->par_h6 << 7;
|
||||
var4 = ((var4) + ((temp_scaled * (int32_t)cal_coeffs->par_h7) / ((int32_t)100))) >> 4;
|
||||
var5 = ((var3 >> 14) * (var3 >> 14)) >> 10;
|
||||
var6 = (var4 * var5) >> 1;
|
||||
calc_hum = (((var3 + var6) >> 10) * ((int32_t)1000)) >> 12;
|
||||
if (calc_hum > 100000) {
|
||||
calc_hum = 100000;
|
||||
} else if (calc_hum < 0) {
|
||||
calc_hum = 0;
|
||||
}
|
||||
|
||||
return (uint32_t)calc_hum;
|
||||
}
|
163
tests/drivers/i2c/i2c_bme688/src/sensor.h
Normal file
163
tests/drivers/i2c/i2c_bme688/src/sensor.h
Normal file
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
* Copyright (c) 2024 Nordic Semiconductor ASA
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef SENSOR_H
|
||||
#define SENSOR_H
|
||||
|
||||
#include <zephyr/kernel.h>
|
||||
|
||||
#define SLEEP_TIME_MS 250
|
||||
#define MEASUREMENT_CYCLES 3
|
||||
#define MAX_BURST_READ_SIZE 10
|
||||
|
||||
/* General */
|
||||
#define CHIP_ID_REGISTER_ADDRESS 0xD0
|
||||
#define VARIANT_ID_REGISTER_ADDRESS 0xF0
|
||||
#define CONF_REGISTER_ADDRESS 0x75
|
||||
#define CTRL_MEAS_REGISTER_ADDRESS 0x74
|
||||
#define CTRL_HUM_REGISTER_ADDRESS 0x72
|
||||
#define RESET_REGISTER_ADDRESS 0xE0
|
||||
#define SLEEP_MODE 0x0
|
||||
#define FORCED_MODE 0x1
|
||||
#define CTRL_MEAS_MODE_BIT_MSK 1 << 1 | 1
|
||||
#define CTRL_MEAS_MODE_BIT_SHIFT 0
|
||||
#define RESET_DEVICE 0xB6
|
||||
#define SENSOR_MEMORY_SIZE_IN_BYTES 255
|
||||
|
||||
/* Calibration coeffcients */
|
||||
#define TEMP_PAR_T1_REGISTER_ADDRESS_LSB 0xE9
|
||||
#define TEMP_PAR_T1_REGISTER_ADDRESS_MSB 0xEA
|
||||
#define TEMP_PAR_T2_REGISTER_ADDRESS_LSB 0x8A
|
||||
#define TEMP_PAR_T2_REGISTER_ADDRESS_MSB 0x8B
|
||||
#define TEMP_PAR_T3_REGISTER_ADDRESS 0x8C
|
||||
|
||||
#define HUMI_PAR_REGISTERS_START_ADDRESS 0xE1
|
||||
#define HUMI_PAR_REGISTERS_COUNT 8
|
||||
#define HUMI_PAR_H1_LSB_BUF_POSITION 1
|
||||
#define HUMI_PAR_H1_MSB_BUF_POSITION 2
|
||||
#define HUMI_PAR_H2_LSB_BUF_POSITION 1
|
||||
#define HUMI_PAR_H2_MSB_BUF_POSITION 0
|
||||
#define HUMI_PAR_H3_BUF_POSITION 3
|
||||
#define HUMI_PAR_H4_BUF_POSITION 4
|
||||
#define HUMI_PAR_H5_BUF_POSITION 5
|
||||
#define HUMI_PAR_H6_BUF_POSITION 6
|
||||
#define HUMI_PAR_H7_BUF_POSITION 7
|
||||
|
||||
#define HUMI_PAR_H1_REGISTER_ADDRESS_LSB 0xE2
|
||||
#define HUMI_PAR_H1_LSB_BIT_MASK 0xFF
|
||||
#define HUMI_PAR_H1_REGISTER_ADDRESS_MSB 0xE3
|
||||
#define HUMI_PAR_H2_REGISTER_ADDRESS_LSB 0xE2
|
||||
#define HUMI_PAR_H2_REGISTER_ADDRESS_MSB 0xE1
|
||||
#define HUMI_PAR_H3_REGISTER_ADDRESS 0xE4
|
||||
#define HUMI_PAR_H4_REGISTER_ADDRESS 0xE5
|
||||
#define HUMI_PAR_H5_REGISTER_ADDRESS 0xE6
|
||||
#define HUMI_PAR_H6_REGISTER_ADDRESS 0xE7
|
||||
#define HUMI_PAR_H7_REGISTER_ADDRESS 0xE8
|
||||
|
||||
#define PRES_PAR_P1_REGISTER_ADDRESS_LSB 0x8E
|
||||
#define PRES_PAR_P1_REGISTER_ADDRESS_MSB 0x8F
|
||||
#define PRES_PAR_P2_REGISTER_ADDRESS_LSB 0x90
|
||||
#define PRES_PAR_P2_REGISTER_ADDRESS_MSB 0x91
|
||||
#define PRES_PAR_P3_REGISTER_ADDRESS 0x92
|
||||
#define PRES_PAR_P4_REGISTER_ADDRESS_LSB 0x94
|
||||
#define PRES_PAR_P4_REGISTER_ADDRESS_MSB 0x95
|
||||
#define PRES_PAR_P5_REGISTER_ADDRESS_LSB 0x96
|
||||
#define PRES_PAR_P5_REGISTER_ADDRESS_MSB 0x97
|
||||
#define PRES_PAR_P6_REGISTER_ADDRESS 0x99
|
||||
#define PRES_PAR_P7_REGISTER_ADDRESS 0x98
|
||||
#define PRES_PAR_P8_REGISTER_ADDRESS_LSB 0x9C
|
||||
#define PRES_PAR_P8_REGISTER_ADDRESS_MSB 0x9D
|
||||
#define PRES_PAR_P9_REGISTER_ADDRESS_LSB 0x9E
|
||||
#define PRES_PAR_P9_REGISTER_ADDRESS_MSB 0x9F
|
||||
#define PRES_PAR_P10_REGISTER_ADDRESS 0xA0
|
||||
|
||||
/* IIR filter */
|
||||
#define IIR_FILER_ORDER_BIT_MASK 1 << 4 | 1 << 3 | 1 << 2
|
||||
#define IIR_FILER_ORDER_BIT_SHIFT 2
|
||||
#define IIR_FILER_COEFF_3 0x2
|
||||
|
||||
/* Temperature measurement */
|
||||
#define TEMPERATURE_OVERSAMPLING_2X 0x2
|
||||
#define TEMP_OVERSAMPLING_BIT_MSK 1 << 7 | 1 << 6 | 1 << 5
|
||||
#define TEMP_OVERSAMPLING_BIT_SHIFT 5
|
||||
|
||||
#define TEMP_ADC_DATA_MSB_0 0x22
|
||||
#define TEMP_ADC_DATA_LSB_0 0x23
|
||||
#define TEMP_ADC_DATA_XLSB_0 0x24
|
||||
|
||||
/* Pressure measurement */
|
||||
#define PRESSURE_OVERSAMPLING_16X 0x5
|
||||
#define PRES_OVERSAMPLING_BIT_MSK 1 << 4 | 1 << 3 | 1 << 2
|
||||
#define PRES_OVERSAMPLING_BIT_SHIFT 2
|
||||
|
||||
#define PRES_ADC_DATA_MSB_0 0x1F
|
||||
#define PRES_ADC_DATA_LSB_0 0x20
|
||||
#define PRES_ADC_DATA_XLSB_0 0x21
|
||||
|
||||
/* Humidity measurement */
|
||||
#define HUMIDITY_OVERSAMPLING_1X 0x1
|
||||
#define HUMIDITY_OVERSAMPLING_BIT_MSK 1 << 2 | 1 << 1 | 1
|
||||
#define HUMIDITY_OVERSAMPLING_BIT_SHIFT 0
|
||||
|
||||
#define HUM_ADC_DATA_MSB_0 0x25
|
||||
#define HUM_ADC_DATA_LSB_0 0x26
|
||||
|
||||
/* Measurement status */
|
||||
#define MEAS_STATUS_0_REG_ADDRESS 0x1D
|
||||
#define MEAS_STATUS_1_REG_ADDRESS 0x2E
|
||||
#define MEAS_STATUS_2_REG_ADDRESS 0x3F
|
||||
#define MEASUREMENT_IN_PROGRESS_BIT_MASK 1 << 5
|
||||
#define MEASUREMENT_NEW_DATA_BIT_MASK 1 << 7
|
||||
|
||||
struct calibration_coeffs {
|
||||
/* Temperature */
|
||||
uint16_t par_t1;
|
||||
uint16_t par_t2;
|
||||
uint8_t par_t3;
|
||||
|
||||
/* Humidity */
|
||||
uint16_t par_h1;
|
||||
uint16_t par_h2;
|
||||
uint8_t par_h3;
|
||||
uint8_t par_h4;
|
||||
uint8_t par_h5;
|
||||
uint8_t par_h6;
|
||||
uint8_t par_h7;
|
||||
|
||||
/* Pressure */
|
||||
uint16_t par_p1;
|
||||
int16_t par_p2;
|
||||
int8_t par_p3;
|
||||
int16_t par_p4;
|
||||
int16_t par_p5;
|
||||
int8_t par_p6;
|
||||
int8_t par_p7;
|
||||
int16_t par_p8;
|
||||
int16_t par_p9;
|
||||
uint8_t par_p10;
|
||||
};
|
||||
|
||||
/* Calculate the compensated temperature
|
||||
* Note: 't_fine' is required for other measurements
|
||||
*/
|
||||
int32_t calculate_temperature(uint32_t adc_temp, int32_t *t_fine,
|
||||
struct calibration_coeffs *cal_coeffs);
|
||||
|
||||
/* Calculate the compensated pressure
|
||||
* Note: temperature must be calculated first
|
||||
* to obtain the 't_fine'
|
||||
*/
|
||||
uint32_t calculate_pressure(uint32_t pres_adc, int32_t t_fine,
|
||||
struct calibration_coeffs *cal_coeffs);
|
||||
|
||||
/* Calculate the relative humidity
|
||||
* Note: temperature must be calculated first
|
||||
* to obtain the 't_fine'
|
||||
*/
|
||||
uint32_t calculate_humidity(uint16_t hum_adc, int32_t t_fine,
|
||||
struct calibration_coeffs *cal_coeffs);
|
||||
|
||||
#endif
|
6
tests/drivers/i2c/i2c_bme688/testcase.yaml
Normal file
6
tests/drivers/i2c/i2c_bme688/testcase.yaml
Normal file
|
@ -0,0 +1,6 @@
|
|||
common:
|
||||
tags: drivers i2c
|
||||
depends_on: i2c
|
||||
tests:
|
||||
drivers.i2c.bme688:
|
||||
filter: dt_compat_enabled("bosch,bme680")
|
Loading…
Add table
Add a link
Reference in a new issue