diff --git a/samples/sensor/pressure_interrupt/CMakeLists.txt b/samples/sensor/pressure_interrupt/CMakeLists.txt new file mode 100644 index 000000000000..09ca28e4cb17 --- /dev/null +++ b/samples/sensor/pressure_interrupt/CMakeLists.txt @@ -0,0 +1,12 @@ +# +# Copyright (c) 2024 TDK Invensense +# +# SPDX-License-Identifier: Apache-2.0 +# + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(icp201xx) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/samples/sensor/pressure_interrupt/Kconfig b/samples/sensor/pressure_interrupt/Kconfig new file mode 100644 index 000000000000..b5062e52ff29 --- /dev/null +++ b/samples/sensor/pressure_interrupt/Kconfig @@ -0,0 +1,31 @@ +# Copyright (c) 2024, TDK Invensense +# SPDX-License-Identifier: Apache-2.0 + +config LOG + default y + +config LOG_PRINTK + default y + +config SENSOR_LOG_LEVEL + default 4 + +config PRESSURE_DRDY + bool "Enable pressure data ready interrupt" + default y + +config PRESSURE_THRESHOLD + bool "Enable pressure threshold interrupt" + default y + +config PRESSURE_DELTA + bool "Enable pressure delta interrupt" + default y + +choice ICP201XX_TRIGGER_MODE + default ICP201XX_TRIGGER_GLOBAL_THREAD + depends on ICP201XX + +endchoice + +source "Kconfig.zephyr" diff --git a/samples/sensor/pressure_interrupt/README.rst b/samples/sensor/pressure_interrupt/README.rst new file mode 100644 index 000000000000..d59dce60fbd1 --- /dev/null +++ b/samples/sensor/pressure_interrupt/README.rst @@ -0,0 +1,73 @@ +.. zephyr:code-sample:: pressure_interrupt + :name: Barometric pressure and temperature sensor interrupt example + :relevant-api: sensor_interface + + Manage interrupts from a barometric pressure and temperature sensor. + +Overview +******** + +This sample application uses a pressure sensor interrupt line to: + +* Inform when a measure is available in the sensor FIFO. + Temperature and pressure data are read and displayed in terminal. + If floats are supported, estimated altitude is also displayed. +* Inform when the pressure value crosses a specified threshold. + Threshold corresponds to around a 50cm altitude increase. + A message is displayed in the terminal. +* Inform when the pressure value changed more than the specified + value between two consecutive samples. + Change value corresponds to a finger pressing the sensor. + A message is displayed in the terminal. + +Wiring +******* + +This sample uses an external breakout for the sensor. A devicetree +overlay must be provided to identify the I2C/SPI bus and GPIO used to +control the sensor. + +Building and Running +******************** + +This sample supports pressure sensor devices. Device needs +to be aliased as ``pressure-sensor``. For example: + +.. code-block:: devicetree + + / { + aliases { + pressure-sensor = &icp201xx; + }; + }; + +Make sure the aliases are in devicetree, then build and run with: + +.. zephyr-app-commands:: + :zephyr-app: samples/sensor/pressure_interrupt + :board: nrf52dk/nrf52832 + :goals: build flash + +Sample Output +============= + +.. code-block:: console + +## Default configuration + + [00:00:00.266,479] PRESS_INT_SAMPLE: Starting ICP201xx sample. + [00:00:00.273,803] PRESS_INT_SAMPLE: temp 25.49 Cel, pressure 96.271438 kPa, altitude 447.208465 m + [00:00:00.280,914] PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.271331 kPa, altitude 447.234161 m + [00:00:00.288,024] PRESS_INT_SAMPLE: temp 25.49 Cel, pressure 96.266685 kPa, altitude 447.636077 m + [00:00:00.295,135] PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.267951 kPa, altitude 447.537078 m + [00:00:00.302,246] PRESS_INT_SAMPLE: temp 25.51 Cel, pressure 96.268577 kPa, altitude 447.488281 m + [00:00:00.309,356] PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.269340 kPa, altitude 447.414978 m + [00:00:00.316,467] PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.268562 kPa, altitude 447.473663 m + [00:00:00.323,547] PRESS_INT_SAMPLE: temp 25.50 Cel, pressure 96.267341 kPa, altitude 447.596496 m + + + + [00:00:09.819,061] PRESS_INT_SAMPLE: PRESSURE CHANGE INTERRUPT + + + [00:00:09.859,039] PRESS_INT_SAMPLE: PRESSURE THRESHOLD INTERRUPT diff --git a/samples/sensor/pressure_interrupt/boards/nrf52dk_nrf52832_i2c.overlay b/samples/sensor/pressure_interrupt/boards/nrf52dk_nrf52832_i2c.overlay new file mode 100644 index 000000000000..e626d5ffc326 --- /dev/null +++ b/samples/sensor/pressure_interrupt/boards/nrf52dk_nrf52832_i2c.overlay @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2024, TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Get a node identifier for pressure sensor. + */ +/ { + aliases { + pressure-sensor = &icp201xx; + }; +}; + +/* + * Example configuration of a icp201xx device on an Arduino I2C bus. + * + * Device address 0x63 is assumed. Your device may have a different + * address; check your device documentation if unsure. + */ +&arduino_i2c { + status = "okay"; + icp201xx: icp201xx@63 { + compatible = "invensense,icp201xx"; + reg = <0x63>; + int-gpios = <&arduino_header 8 GPIO_ACTIVE_LOW>; /* D2 */ + }; +}; + +/* + * Increase native UART speed to report sensor data. + */ +&uart0 { + compatible = "nordic,nrf-uarte"; + status = "okay"; + current-speed = <1000000>; +}; diff --git a/samples/sensor/pressure_interrupt/boards/nrf52dk_nrf52832_spi.overlay b/samples/sensor/pressure_interrupt/boards/nrf52dk_nrf52832_spi.overlay new file mode 100644 index 000000000000..ad26418fd22b --- /dev/null +++ b/samples/sensor/pressure_interrupt/boards/nrf52dk_nrf52832_spi.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2024, TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Get a node identifier for pressure sensor. + */ +/ { + aliases { + pressure-sensor = &icp201xx; + }; +}; + +/* Example configuration of a ICP2021XX device on an Arduino SPI bus. */ +&arduino_spi { + status = "okay"; + cs-gpios = <&arduino_header 14 GPIO_ACTIVE_LOW>; /* D8 */ + icp201xx: icp201xx@0 { + compatible = "invensense,icp201xx"; + reg = <0>; + spi-max-frequency = <500000>; /* conservatively set to 500k */ + int-gpios = <&arduino_header 8 GPIO_ACTIVE_HIGH>; /* D2 */ + drive-strength = "current_4mA_1_8V"; /* Avoid cross talk */ + }; +}; + +/* + * Increase native UART speed. + */ +&uart0 { + compatible = "nordic,nrf-uarte"; + status = "okay"; + current-speed = <1000000>; +}; diff --git a/samples/sensor/pressure_interrupt/prj.conf b/samples/sensor/pressure_interrupt/prj.conf new file mode 100644 index 000000000000..bea79e439ebc --- /dev/null +++ b/samples/sensor/pressure_interrupt/prj.conf @@ -0,0 +1,17 @@ +# +# Copyright (c) 2024 TDK Invensense +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_SENSOR=y + +# Floating point format support +# Selecting this increases stack size requirements slightly, but increases code size significantly. +CONFIG_CBPRINTF_FP_SUPPORT=y + +# Buffer size for console. The defaults are optimized to save RAM +CONFIG_CONSOLE_SUBSYS=y +CONFIG_CONSOLE_GETCHAR=y +CONFIG_CONSOLE_GETCHAR_BUFSIZE=16 +CONFIG_CONSOLE_PUTCHAR_BUFSIZE=512 diff --git a/samples/sensor/pressure_interrupt/sample.yaml b/samples/sensor/pressure_interrupt/sample.yaml new file mode 100644 index 000000000000..e170db1509a3 --- /dev/null +++ b/samples/sensor/pressure_interrupt/sample.yaml @@ -0,0 +1,9 @@ +sample: + name: Pressure sensor interrupt +tests: + sample.sensor.pressure_interrupt: + build_only: true + tags: sensors + filter: dt_alias_exists("pressure-sensor") + integration_platforms: + - nrf52dk/nrf52832 diff --git a/samples/sensor/pressure_interrupt/src/main.c b/samples/sensor/pressure_interrupt/src/main.c new file mode 100644 index 000000000000..abf7f5adfe53 --- /dev/null +++ b/samples/sensor/pressure_interrupt/src/main.c @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024 TDK Invensense + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(PRESS_INT_SAMPLE, CONFIG_SENSOR_LOG_LEVEL); + +/* + * Get a device structure from a devicetree node from alias + * "pressure_sensor". + */ +static const struct device *get_pressure_sensor_device(void) +{ + const struct device *const dev = DEVICE_DT_GET(DT_ALIAS(pressure_sensor)); + + if (!device_is_ready(dev)) { + printk("\nError: Device \"%s\" is not ready; " + "check the driver initialization logs for errors.\n", + dev->name); + return NULL; + } + + printk("Found device \"%s\", getting sensor data\n", dev->name); + return dev; +} + +#ifdef CONFIG_PRESSURE_DRDY +static void data_ready_handler(const struct device *dev, const struct sensor_trigger *trig) +{ + + if (trig->type == SENSOR_TRIG_DATA_READY) { + int rc = sensor_sample_fetch_chan(dev, trig->chan); + + if (rc < 0) { + printf("sample fetch failed: %d\n", rc); + printf("cancelling trigger\n"); + (void)sensor_trigger_set(dev, trig, NULL); + return; + } else if (rc == 0) { + + struct sensor_value pressure; + struct sensor_value temperature; + struct sensor_value altitude; + + sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure); + sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temperature); + sensor_channel_get(dev, SENSOR_CHAN_ALTITUDE, &altitude); + + LOG_INF("temp %.2f Cel, pressure %f kPa, altitude %f m", + sensor_value_to_double(&temperature), + sensor_value_to_double(&pressure), + sensor_value_to_double(&altitude)); + } + } +} +#endif + +#ifdef CONFIG_PRESSURE_THRESHOLD +static void threshold_handler(const struct device *dev, const struct sensor_trigger *trig) +{ + if (trig->type == SENSOR_TRIG_THRESHOLD) { + LOG_INF("PRESSURE THRESHOLD INTERRUPT"); + } +} +#endif + +#ifdef CONFIG_PRESSURE_DELTA +static void delta_handler(const struct device *dev, const struct sensor_trigger *trig) +{ + if (trig->type == SENSOR_TRIG_DELTA) { + LOG_INF("PRESSURE CHANGE INTERRUPT\n"); + } +} +#endif + +int main(void) +{ + static struct sensor_trigger trigger; + const struct device *dev = get_pressure_sensor_device(); +#ifdef CONFIG_PRESSURE_THRESHOLD + struct sensor_value pressure, pressure_threshold; +#endif +#ifdef CONFIG_PRESSURE_DELTA + struct sensor_value pressure_delta; +#endif + + if (dev == NULL) { + return 0; + } +#ifdef CONFIG_PRESSURE_DRDY + /* Configure data ready trigger */ + trigger = (struct sensor_trigger){ + .type = SENSOR_TRIG_DATA_READY, + .chan = SENSOR_CHAN_ALL, + }; + if (sensor_trigger_set(dev, &trigger, data_ready_handler) < 0) { + printf("Cannot configure data trigger!!!\n"); + return 0; + } +#endif + +#ifdef CONFIG_PRESSURE_THRESHOLD + /* Configure pressure threshold trigger */ + /* Interrupt is triggered if sensor is lifted of about 50cm */ + /* Read current pressure */ + k_sleep(K_MSEC(50)); + sensor_sample_fetch_chan(dev, SENSOR_CHAN_PRESS); + sensor_channel_get(dev, SENSOR_CHAN_PRESS, &pressure); + + /* Retrieve 5 Pa, around 50cm altitude increase */ + pressure_threshold.val1 = pressure.val1; + pressure_threshold.val2 = pressure.val2 - 5000; + sensor_attr_set(dev, SENSOR_CHAN_PRESS, SENSOR_ATTR_LOWER_THRESH, &pressure_threshold); + + LOG_INF("Pressure at reset %.3f kPa, interrupt sets at %.3f kPa.\n", + sensor_value_to_double(&pressure), sensor_value_to_double(&pressure_threshold)); + + trigger = (struct sensor_trigger){ + .type = SENSOR_TRIG_THRESHOLD, + .chan = SENSOR_CHAN_PRESS, + }; + if (sensor_trigger_set(dev, &trigger, threshold_handler) < 0) { + printf("Cannot configure threshold trigger!!!\n"); + return 0; + } +#endif + +#ifdef CONFIG_PRESSURE_DELTA + /* Configure pressure delta trigger */ + /* Set pressure delta to 0.01 kPa to detect a press on the sensor */ + pressure_delta.val1 = 0; + pressure_delta.val2 = 10000; + sensor_attr_set(dev, SENSOR_CHAN_PRESS, SENSOR_ATTR_SLOPE_TH, &pressure_delta); + trigger = (struct sensor_trigger){ + .type = SENSOR_TRIG_DELTA, + .chan = SENSOR_CHAN_PRESS, + }; + if (sensor_trigger_set(dev, &trigger, delta_handler) < 0) { + printf("Cannot configure threshold trigger!!!\n"); + return 0; + } +#endif + + LOG_INF("Starting pressure event sample.\n"); + + return 0; +}