From c4de37d3a6ad75f93354a09a3347619d0db7d013 Mon Sep 17 00:00:00 2001 From: Yuval Peress Date: Wed, 28 Jun 2023 00:15:27 -0600 Subject: [PATCH] Implement arbitration --- .gitignore | 1 + drivers/sensor/icm42688/icm42688_emul.c | 3 + include/zephyr/sensing/sensing.h | 75 ++++++------- include/zephyr/sensing/sensor.h | 1 + subsys/sensing/CMakeLists.txt | 2 + .../include/sensing/internal/sensing.h | 36 ++++++ subsys/sensing/src/sensor_arbitrate.c | 96 ++++++++++++++++ subsys/sensing/src/sensor_connections.c | 105 +++++++++++++++--- subsys/sensing/src/sensor_info.c | 3 + subsys/sensing/src/sensor_pipe.c | 26 ++++- tests/subsys/sensing/CMakeLists.txt | 8 +- tests/subsys/sensing/prj.conf | 2 + tests/subsys/sensing/src/test_arbitration.c | 71 ++++++++++++ tests/subsys/sensing/src/test_connections.c | 16 ++- 14 files changed, 387 insertions(+), 58 deletions(-) create mode 100644 subsys/sensing/include/sensing/internal/sensing.h create mode 100644 subsys/sensing/src/sensor_arbitrate.c create mode 100644 tests/subsys/sensing/src/test_arbitration.c diff --git a/.gitignore b/.gitignore index 16e54c466283d7..5944f735f791a8 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ .\#* \#*\# build*/ +/build* !doc/build/ !scripts/build !tests/drivers/build_all diff --git a/drivers/sensor/icm42688/icm42688_emul.c b/drivers/sensor/icm42688/icm42688_emul.c index 5ac652c29d719a..0216e2ee84d0c4 100644 --- a/drivers/sensor/icm42688/icm42688_emul.c +++ b/drivers/sensor/icm42688/icm42688_emul.c @@ -56,6 +56,9 @@ static void icm42688_emul_handle_write(const struct emul *target, uint8_t regn, data->reg[REG_INT_STATUS] |= BIT_INT_STATUS_RESET_DONE; } break; + default: + data->reg[regn] = value; + break; } } diff --git a/include/zephyr/sensing/sensing.h b/include/zephyr/sensing/sensing.h index 502575611f519e..7892b9f602f46f 100644 --- a/include/zephyr/sensing/sensing.h +++ b/include/zephyr/sensing/sensing.h @@ -32,7 +32,6 @@ extern "C" { #endif - /** * @struct sensing_sensor_version * @brief Sensor Version @@ -49,12 +48,9 @@ struct sensing_sensor_version { }; }; -#define SENSING_SENSOR_VERSION(_major, _minor, _hotfix, _build) \ - (FIELD_PREP(GENMASK(31, 24), _major) | \ - FIELD_PREP(GENMASK(23, 16), _minor) | \ - FIELD_PREP(GENMASK(15, 8), _hotfix) | \ - FIELD_PREP(GENMASK(7, 0), _build)) - +#define SENSING_SENSOR_VERSION(_major, _minor, _hotfix, _build) \ + (FIELD_PREP(GENMASK(31, 24), _major) | FIELD_PREP(GENMASK(23, 16), _minor) | \ + FIELD_PREP(GENMASK(15, 8), _hotfix) | FIELD_PREP(GENMASK(7, 0), _build)) /** * @brief Sensor flag indicating if this sensor is on event reporting data. @@ -62,7 +58,7 @@ struct sensing_sensor_version { * Reporting sensor data when the sensor event occurs, such as a motion detect sensor reporting * a motion or motionless detected event. */ -#define SENSING_SENSOR_FLAG_REPORT_ON_EVENT BIT(0) +#define SENSING_SENSOR_FLAG_REPORT_ON_EVENT BIT(0) /** * @brief Sensor flag indicating if this sensor is on change reporting data. @@ -71,8 +67,7 @@ struct sensing_sensor_version { * * Exclusive with \ref SENSING_SENSOR_FLAG_REPORT_ON_EVENT */ -#define SENSING_SENSOR_FLAG_REPORT_ON_CHANGE BIT(1) - +#define SENSING_SENSOR_FLAG_REPORT_ON_CHANGE BIT(1) /** * @brief Sensing subsystem sensor state. @@ -83,14 +78,12 @@ enum sensing_sensor_state { SENSING_SENSOR_STATE_OFFLINE = 1, }; - /** * @brief Define Sensing subsystem sensor handle * */ typedef void *sensing_sensor_handle_t; - /** * @brief Sensor data event receive callback. * @@ -98,9 +91,7 @@ typedef void *sensing_sensor_handle_t; * * @param buf The data buffer with sensor data. */ -typedef void (*sensing_data_event_t)( - sensing_sensor_handle_t handle, - const void *buf); +typedef void (*sensing_data_event_t)(sensing_sensor_handle_t handle, const void *buf); /** * @struct sensing_sensor_info @@ -108,7 +99,9 @@ typedef void (*sensing_data_event_t)( * */ struct sensing_sensor_info { - const struct sensor_info * info; + const struct sensor_info *info; + + const struct device *dev; /** Sensor type */ int32_t type; @@ -123,20 +116,19 @@ struct sensing_callback_list { sensing_data_event_t on_data_event; }; - - /** - * @brief Get all supported sensor instances' information. - * - * This API just returns read only information of sensor instances, pointer info will - * directly point to internal buffer, no need for caller to allocate buffer, - * no side effect to sensor instances. - * - * @param num_sensors Get number of sensor instances. - * - * @param info For receiving sensor instances' information array pointer. - * - * @return 0 on success or negative error value on failure. - */ +/** + * @brief Get all supported sensor instances' information. + * + * This API just returns read only information of sensor instances, pointer info will + * directly point to internal buffer, no need for caller to allocate buffer, + * no side effect to sensor instances. + * + * @param num_sensors Get number of sensor instances. + * + * @param info For receiving sensor instances' information array pointer. + * + * @return 0 on success or negative error value on failure. + */ int sensing_get_sensors(int *num_sensors, const struct sensing_sensor_info **info); /** @@ -155,10 +147,9 @@ int sensing_get_sensors(int *num_sensors, const struct sensing_sensor_info **inf * * @return 0 on success or negative error value on failure. */ -int sensing_open_sensor( - const struct sensing_sensor_info *info, - const struct sensing_callback_list *cb_list, - sensing_sensor_handle_t *handle); +int sensing_open_sensor(const struct sensing_sensor_info *info, + const struct sensing_callback_list *cb_list, + sensing_sensor_handle_t *handle); /** * @brief Close sensor instance. @@ -167,8 +158,16 @@ int sensing_open_sensor( * * @return 0 on success or negative error value on failure. */ -int sensing_close_sensor( - sensing_sensor_handle_t handle); +int sensing_close_sensor(sensing_sensor_handle_t handle); + +struct sensing_sensor_attribute { + enum sensor_attribute attribute; + q31_t value; + int8_t shift; +}; + +int sensing_set_attributes(sensing_sensor_handle_t handle, + struct sensing_sensor_attribute *attributes, size_t count); /** * @brief Get sensor information from sensor instance handle. @@ -177,8 +176,7 @@ int sensing_close_sensor( * * @return a const pointer to \ref sensing_sensor_info on success or NULL on failure. */ -const struct sensing_sensor_info *sensing_get_sensor_info( - sensing_sensor_handle_t handle); +const struct sensing_sensor_info *sensing_get_sensor_info(sensing_sensor_handle_t handle); __test_only void sensing_reset_connections(void); @@ -190,5 +188,4 @@ __test_only void sensing_reset_connections(void); * @} */ - #endif /*ZEPHYR_INCLUDE_SENSING_H_*/ diff --git a/include/zephyr/sensing/sensor.h b/include/zephyr/sensing/sensor.h index 434f9b7357403b..cd4614a8187d7d 100644 --- a/include/zephyr/sensing/sensor.h +++ b/include/zephyr/sensing/sensor.h @@ -19,6 +19,7 @@ sensing_sensor_info, \ SENSING_SENSOR_INFO_DT_NAME(node_id, DT_PROP_BY_IDX(node_id, prop, idx))) = { \ .info = &SENSOR_INFO_DT_NAME(DT_PHANDLE(node_id, dev)), \ + .dev = DEVICE_DT_GET(node_id), \ .type = DT_PROP_BY_IDX(node_id, prop, idx), \ }; diff --git a/subsys/sensing/CMakeLists.txt b/subsys/sensing/CMakeLists.txt index 1cf869cff59634..bd47b62c6a11b5 100644 --- a/subsys/sensing/CMakeLists.txt +++ b/subsys/sensing/CMakeLists.txt @@ -2,7 +2,9 @@ zephyr_library() zephyr_library_sources( + src/sensor_arbitrate.c src/sensor_info.c src/sensor_pipe.c src/sensor_connections.c ) +zephyr_library_include_directories(include) diff --git a/subsys/sensing/include/sensing/internal/sensing.h b/subsys/sensing/include/sensing/internal/sensing.h new file mode 100644 index 00000000000000..4db844cab09480 --- /dev/null +++ b/subsys/sensing/include/sensing/internal/sensing.h @@ -0,0 +1,36 @@ +// +// Created by peress on 27/06/23. +// + +#ifndef ZEPHYR_SUBSYS_SENSING_INCLUDE_SENSING_INTERNAL_SENSING_H +#define ZEPHYR_SUBSYS_SENSING_INCLUDE_SENSING_INTERNAL_SENSING_H + +#include +#include +#include + +#define __SENSING_POOL_MASK_BUNDLE_COUNT \ + (DIV_ROUND_UP(DIV_ROUND_UP(CONFIG_SENSING_MAX_CONNECTIONS, 8), sizeof(uint32_t))) + +struct sensing_connection { + const struct sensing_sensor_info *info; + const struct sensing_callback_list *cb_list; + q31_t attributes[SENSOR_ATTR_COMMON_COUNT]; + uint32_t attribute_mask; + struct { + uint8_t in_use: 1; + uint8_t reserved: 7; + } flags; +} __packed __aligned(4); + +extern struct sensing_connection_pool { + struct sensing_connection pool[CONFIG_SENSING_MAX_CONNECTIONS]; + sys_bitarray_t *bitarray; + struct k_mutex *lock; +} __sensing_connection_pool; + +BUILD_ASSERT(SENSOR_ATTR_COMMON_COUNT <= 32, "Too many sensor attributes"); + +void __sensing_arbitrate(); + +#endif // ZEPHYR_SUBSYS_SENSING_INCLUDE_SENSING_INTERNAL_SENSING_H diff --git a/subsys/sensing/src/sensor_arbitrate.c b/subsys/sensing/src/sensor_arbitrate.c new file mode 100644 index 00000000000000..feaf3c77eb201d --- /dev/null +++ b/subsys/sensing/src/sensor_arbitrate.c @@ -0,0 +1,96 @@ +// +// Created by peress on 27/06/23. +// + +#include +#include +#include + +#include "sensing/internal/sensing.h" + +LOG_MODULE_REGISTER(sensing_arbitrate, CONFIG_SENSING_LOG_LEVEL); + +static q31_t arbitrate_attribute_value(enum sensor_attribute attribute, q31_t current_value, + q31_t new_value) +{ + switch (attribute) { + case SENSOR_ATTR_SAMPLING_FREQUENCY: + return MAX(current_value, new_value); + default: + return current_value; + } +} + +static void set_arbitrated_value(const struct device *dev, int32_t type, + enum sensor_attribute attribute, q31_t value) +{ + enum sensor_channel chan; + switch (type) { + case SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D: + chan = SENSOR_CHAN_ACCEL_XYZ; + break; + case SENSING_SENSOR_TYPE_MOTION_GYROMETER_3D: + chan = SENSOR_CHAN_GYRO_XYZ; + break; + default: + return; + } + + struct sensor_value val = { + .val1 = FIELD_GET(GENMASK(31, 16), value), + .val2 = (FIELD_GET(GENMASK(15, 0), value) * 1000000) / INT16_MAX, + }; + LOG_DBG("Updating attribute chan=%d, value=%d/%d", chan, val.val1, val.val2); + ((const struct sensor_driver_api *)(dev->api))->attr_set(dev, chan, attribute, &val); +} + +static int arbitrate_sensor_attribute(const struct sensing_sensor_info *info, + enum sensor_attribute attribute) +{ + const struct sensing_connection *connections = __sensing_connection_pool.pool; + int connection_count = 0; + q31_t value; + + for (int i = 0; i < CONFIG_SENSING_MAX_CONNECTIONS; ++i) { + if (connections[i].info != info || !connections[i].flags.in_use) { +// LOG_DBG("Skipping connection %p, info mismatch", (void*)&connections[i]); + continue; + } + if (FIELD_GET(BIT(attribute), connections[i].attribute_mask) == 0) { +// LOG_DBG("Skipping connection %p, attribute not set", (void*)&connections[i]); + continue; + } + if (connection_count == 0) { + /* First connection */ + value = connections[i].attributes[attribute]; + LOG_DBG("Arbitrating '%s'@%p type=%d attribute=%d", info->info->dev->name, + info->info->dev, info->type, attribute); + LOG_DBG(" First connection %p, value=0x%08x", (void*)&connections[i], value); + } else { + value = arbitrate_attribute_value(attribute, value, + connections[i].attributes[attribute]); + LOG_DBG(" Updating %p, value=0x%08x", (void*)&connections[i], value); + } + connection_count++; + } + + if (connection_count != 0) { + set_arbitrated_value(info->dev, info->type, attribute, value); + } + + return connection_count; +} + +static void arbitrate_sensor_instance(const struct sensing_sensor_info *info) +{ + for (int i = 0; i < SENSOR_ATTR_COMMON_COUNT; ++i) { + arbitrate_sensor_attribute(info, i); + } +} + +void __sensing_arbitrate(void) +{ + STRUCT_SECTION_FOREACH(sensing_sensor_info, info) { + arbitrate_sensor_instance(info); + } +} diff --git a/subsys/sensing/src/sensor_connections.c b/subsys/sensing/src/sensor_connections.c index 2bc9f7eb12f773..9d199b7891a676 100644 --- a/subsys/sensing/src/sensor_connections.c +++ b/subsys/sensing/src/sensor_connections.c @@ -1,49 +1,124 @@ +#include #include #include +#include +#include -struct sensing_connection { - const struct sensing_callback_list *cb_list; -} __packed __aligned(4); +#include "sensing/internal/sensing.h" -static uint8_t __aligned(4) - connection_pool[sizeof(struct sensing_connection) * CONFIG_SENSING_MAX_CONNECTIONS]; -SYS_MEM_BLOCKS_DEFINE_WITH_EXT_BUF(connection_allocator, sizeof(struct sensing_connection), - CONFIG_SENSING_MAX_CONNECTIONS, connection_pool); +LOG_MODULE_REGISTER(sensing_connect, CONFIG_SENSING_LOG_LEVEL); + +#define __HANDLE_TO_CONNECTION(name, handle) \ + struct sensing_connection *name = handle; \ + __ASSERT_NO_MSG((uintptr_t)name >= (uintptr_t)__sensing_connection_pool.pool); \ + __ASSERT_NO_MSG((uintptr_t)name < (uintptr_t)__sensing_connection_pool.pool + \ + sizeof(__sensing_connection_pool.pool)); + +K_MUTEX_DEFINE(connection_lock); + +static uint32_t bitarray_bundles[__SENSING_POOL_MASK_BUNDLE_COUNT]; +static sys_bitarray_t bitarray = { + .num_bits = CONFIG_SENSING_MAX_CONNECTIONS, + .num_bundles = __SENSING_POOL_MASK_BUNDLE_COUNT, + .bundles = bitarray_bundles, +}; + +struct sensing_connection_pool __sensing_connection_pool = { + .bitarray = &bitarray, + .lock = &connection_lock, +}; + +#define __lock k_mutex_lock(__sensing_connection_pool.lock, K_FOREVER) +#define __unlock k_mutex_unlock(__sensing_connection_pool.lock) int sensing_open_sensor(const struct sensing_sensor_info *info, const struct sensing_callback_list *cb_list, sensing_sensor_handle_t *handle) { struct sensing_connection *connection; + size_t offset; int rc; __ASSERT_NO_MSG(info != NULL); __ASSERT_NO_MSG(cb_list != NULL); __ASSERT_NO_MSG(handle != NULL); - rc = sys_mem_blocks_alloc(&connection_allocator, 1, (void**)&connection); - + __lock; + rc = sys_bitarray_alloc(__sensing_connection_pool.bitarray, 1, &offset); if (rc != 0) { + __unlock; return rc; } + connection = &__sensing_connection_pool.pool[offset]; + + __ASSERT_NO_MSG(!connection->flags.in_use); + LOG_DBG("Connection opened @ %p (size=%d) for info @ %p", connection, + (int)sizeof(struct sensing_connection), info); + connection->flags.in_use = true; + connection->info = info; connection->cb_list = cb_list; *handle = connection; + __unlock; return 0; } int sensing_close_sensor(sensing_sensor_handle_t handle) { - return sys_mem_blocks_free(&connection_allocator, 1, &handle); + __HANDLE_TO_CONNECTION(connection, handle); + + if (!connection->flags.in_use) { + return -EINVAL; + } + connection->flags.in_use = false; + + __lock; + LOG_DBG("Releasing connection at %p", handle); + int rc = sys_bitarray_free(__sensing_connection_pool.bitarray, 1, + connection - __sensing_connection_pool.pool); + + if (rc != 0) { + connection->flags.in_use = true; + } + __unlock; + return rc; } -void sensing_reset_connections(void) +int sensing_set_attributes(sensing_sensor_handle_t handle, + struct sensing_sensor_attribute *attributes, size_t count) { - uint8_t *ptr = connection_pool; + __HANDLE_TO_CONNECTION(connection, handle); + + __lock; + for (size_t i = 0; i < count; ++i) { + const int8_t shift = 16 - attributes[i].shift; + const q31_t value = shift >= 0 ? (attributes[i].value >> shift) + : (attributes[i].value << -shift); - while (ptr < connection_pool + sizeof(connection_pool)) { - sys_mem_blocks_free(&connection_allocator, 1, (void**)&ptr); - ptr += sizeof(struct sensing_connection); + __ASSERT_NO_MSG(attributes[i].attribute < 32); + connection->attributes[attributes[i].attribute] = value; + connection->attribute_mask |= BIT(attributes[i].attribute); + LOG_DBG("Updated attribute (%d) to 0x%08x->0x%08x", attributes[i].attribute, + attributes[i].value, value); } + __sensing_arbitrate(); + __unlock; + return 0; +} + +const struct sensing_sensor_info *sensing_get_sensor_info(sensing_sensor_handle_t handle) +{ + __HANDLE_TO_CONNECTION(connection, handle); + + return connection->info; +} + +void sensing_reset_connections(void) +{ + __lock; + sys_bitarray_clear_region(__sensing_connection_pool.bitarray, + __sensing_connection_pool.bitarray->num_bits, 0); + memset(__sensing_connection_pool.pool, 0, sizeof(__sensing_connection_pool.pool)); + __unlock; } diff --git a/subsys/sensing/src/sensor_info.c b/subsys/sensing/src/sensor_info.c index 3af62d40dbdcba..03dd8e3aade80c 100644 --- a/subsys/sensing/src/sensor_info.c +++ b/subsys/sensing/src/sensor_info.c @@ -5,6 +5,9 @@ #include #include +#include + +LOG_MODULE_REGISTER(sensing, CONFIG_SENSING_LOG_LEVEL); int sensing_get_sensors(int *num_sensors, const struct sensing_sensor_info **info) { diff --git a/subsys/sensing/src/sensor_pipe.c b/subsys/sensing/src/sensor_pipe.c index fb1a1b9e797063..09def4b6136894 100644 --- a/subsys/sensing/src/sensor_pipe.c +++ b/subsys/sensing/src/sensor_pipe.c @@ -7,11 +7,27 @@ #include #include #include +#include + +LOG_MODULE_REGISTER(sensing_pipe, CONFIG_SENSING_LOG_LEVEL); #define DT_DRV_COMPAT zephyr_sensing_pipe +struct sensor_pipe_config { + const struct sensor_info *parent_info; +}; + +static int attribute_set(const struct device *dev, enum sensor_channel chan, + enum sensor_attribute attr, const struct sensor_value *val) +{ + const struct sensor_pipe_config *cfg = dev->config; + + LOG_DBG("Updating '%s' @%p", cfg->parent_info->dev->name, cfg->parent_info->dev); + return sensor_attr_set(cfg->parent_info->dev, chan, attr, val); +} + static const struct sensor_driver_api sensor_pipe_api = { - .attr_set = NULL, + .attr_set = attribute_set, .attr_get = NULL, .get_decoder = NULL, .submit = NULL, @@ -19,11 +35,17 @@ static const struct sensor_driver_api sensor_pipe_api = { static int sensing_sensor_pipe_init(const struct device *dev) { + const struct sensor_pipe_config *cfg = dev->config; + + LOG_DBG("Initializing %p with underlying device %p", dev, cfg->parent_info->dev); return 0; } #define SENSING_PIPE_INIT(inst) \ - SENSING_SENSOR_DT_INST_DEFINE(inst, sensing_sensor_pipe_init, NULL, NULL, NULL, \ + static const struct sensor_pipe_config cfg_##inst = { \ + .parent_info = &SENSOR_INFO_DT_NAME(DT_INST_PHANDLE(inst, dev)), \ + }; \ + SENSING_SENSOR_DT_INST_DEFINE(inst, sensing_sensor_pipe_init, NULL, NULL, &cfg_##inst, \ APPLICATION, 10, &sensor_pipe_api); DT_INST_FOREACH_STATUS_OKAY(SENSING_PIPE_INIT) diff --git a/tests/subsys/sensing/CMakeLists.txt b/tests/subsys/sensing/CMakeLists.txt index 1b34e474c14b0c..422c7fccb4a9e8 100644 --- a/tests/subsys/sensing/CMakeLists.txt +++ b/tests/subsys/sensing/CMakeLists.txt @@ -5,4 +5,10 @@ cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(device) -target_sources(app PRIVATE src/main.c) +target_sources(app + PRIVATE + src/main.c + src/test_arbitration.c + src/test_connections.c + src/test_list_sensors.c +) diff --git a/tests/subsys/sensing/prj.conf b/tests/subsys/sensing/prj.conf index 0e0e881d69886a..67d380c98175c5 100644 --- a/tests/subsys/sensing/prj.conf +++ b/tests/subsys/sensing/prj.conf @@ -10,6 +10,8 @@ CONFIG_GPIO=y # Enable sensors CONFIG_SENSOR=y CONFIG_SENSING=y +CONFIG_SENSING_LOG_LEVEL_DBG=y +CONFIG_SENSOR_LOG_LEVEL_DBG=y # Enable emulation CONFIG_EMUL=y diff --git a/tests/subsys/sensing/src/test_arbitration.c b/tests/subsys/sensing/src/test_arbitration.c new file mode 100644 index 00000000000000..84d912fec2db3a --- /dev/null +++ b/tests/subsys/sensing/src/test_arbitration.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2023 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +#include "icm42688_emul.h" +#include "icm42688_reg.h" + +ZTEST(sensing, test_single_connection_arbitration) +{ + const struct emul *icm42688 = EMUL_DT_GET(DT_NODELABEL(icm42688)); + const struct sensing_sensor_info *sensor = SENSING_SENSOR_INFO_GET( + DT_NODELABEL(accelgyro), SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D); + const struct sensing_callback_list cb_list; + sensing_sensor_handle_t handle; + + zassert_not_null(sensor); + + /* Open connection */ + zassert_ok(sensing_open_sensor(sensor, &cb_list, &handle)); + + struct sensing_sensor_attribute attribute = { + .attribute = SENSOR_ATTR_SAMPLING_FREQUENCY, + .value = FIELD_PREP(GENMASK(31, 24), 100), + .shift = 8, + }; + zassert_ok(sensing_set_attributes(handle, &attribute, 1)); + + uint8_t reg_val; + icm42688_emul_get_reg(icm42688, REG_ACCEL_CONFIG0, ®_val, 1); + + zassert_equal(0b1000, FIELD_GET(MASK_ACCEL_ODR, reg_val), "ACCEL_CONFIG0=0x%02x", + FIELD_GET(MASK_ACCEL_ODR, reg_val)); +} + +ZTEST(sensing, test_double_connection_arbitration) +{ + const struct emul *icm42688 = EMUL_DT_GET(DT_NODELABEL(icm42688)); + const struct sensing_sensor_info *sensor = SENSING_SENSOR_INFO_GET( + DT_NODELABEL(accelgyro), SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D); + const struct sensing_callback_list cb_list; + sensing_sensor_handle_t handles[2]; + + zassert_not_null(sensor); + + /* Open connection */ + zassert_ok(sensing_open_sensor(sensor, &cb_list, &handles[0])); + zassert_ok(sensing_open_sensor(sensor, &cb_list, &handles[1])); + + struct sensing_sensor_attribute attribute = { + .attribute = SENSOR_ATTR_SAMPLING_FREQUENCY, + .value = FIELD_PREP(GENMASK(31, 23), 100), + .shift = 9, + }; + zassert_ok(sensing_set_attributes(handles[0], &attribute, 1)); + + attribute.value = FIELD_PREP(GENMASK(31, 23), 200); + zassert_ok(sensing_set_attributes(handles[1], &attribute, 1)); + + uint8_t reg_val; + icm42688_emul_get_reg(icm42688, REG_ACCEL_CONFIG0, ®_val, 1); + + zassert_equal(0b0111, FIELD_GET(MASK_ACCEL_ODR, reg_val), "ACCEL_CONFIG0=0x%02x", + FIELD_GET(MASK_ACCEL_ODR, reg_val)); +} diff --git a/tests/subsys/sensing/src/test_connections.c b/tests/subsys/sensing/src/test_connections.c index 264280f050b41d..f79c309bc7cf20 100644 --- a/tests/subsys/sensing/src/test_connections.c +++ b/tests/subsys/sensing/src/test_connections.c @@ -23,7 +23,7 @@ ZTEST(sensing, test_open_connections_limit) } /* Try to over allocate */ - zassert_equal(-ENOMEM, sensing_open_sensor(sensor, &cb_list, + zassert_equal(-ENOSPC, sensing_open_sensor(sensor, &cb_list, &handles[CONFIG_SENSING_MAX_CONNECTIONS])); /* Free one connection */ @@ -32,3 +32,17 @@ ZTEST(sensing, test_open_connections_limit) /* Allocate one */ zassert_ok(sensing_open_sensor(sensor, &cb_list, &handles[CONFIG_SENSING_MAX_CONNECTIONS])); } + +ZTEST(sensing, test_connection_get_info) +{ + const struct sensing_sensor_info *sensor = SENSING_SENSOR_INFO_GET( + DT_NODELABEL(accelgyro), SENSING_SENSOR_TYPE_MOTION_ACCELEROMETER_3D); + const struct sensing_callback_list cb_list; + sensing_sensor_handle_t handle; + + zassert_not_null(sensor); + zassert_ok(sensing_open_sensor(sensor, &cb_list, &handle)); + + const struct sensing_sensor_info *info = sensing_get_sensor_info(handle); + zassert_equal_ptr(sensor, info); +}