diff --git a/tests/boards/nrf/comp/CMakeLists.txt b/tests/boards/nrf/comp/CMakeLists.txt new file mode 100644 index 00000000000..ee3c832e094 --- /dev/null +++ b/tests/boards/nrf/comp/CMakeLists.txt @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(comp) + +target_sources(app PRIVATE src/test.c) diff --git a/tests/boards/nrf/comp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/boards/nrf/comp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 00000000000..cb8e9d408b8 --- /dev/null +++ b/tests/boards/nrf/comp/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + test-comp = ∁ + }; + + zephyr,user { + first-gpios = <&gpio7 2 GPIO_ACTIVE_HIGH>; + second-gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; + }; +}; + +&gpio7 { + status = "okay"; +}; + +&gpio1 { + status = "okay"; +}; + +&comp { + status = "okay"; + psel = "AIN5"; + refsel = "AREF"; + extrefsel= "AIN1"; + sp-mode = "HIGH"; + th-up = <36>; + th-down = <30>; + isource = "DISABLED"; + enable-hyst; +}; diff --git a/tests/boards/nrf/comp/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/tests/boards/nrf/comp/boards/nrf54l15dk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..4c9944b81c3 --- /dev/null +++ b/tests/boards/nrf/comp/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2025 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + test-comp = ∁ + }; + + zephyr,user { + first-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + second-gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; + }; +}; + +&led3 { + status = "disabled"; +}; + +&button0 { + status = "disabled"; +}; + +&gpio1 { + status = "okay"; +}; + +&comp { + status = "okay"; + psel = "AIN4"; + refsel = "AREF"; + extrefsel= "AIN3"; + sp-mode = "NORMAL"; + th-up = <36>; + th-down = <30>; + isource = "DISABLED"; + enable-hyst; +}; diff --git a/tests/boards/nrf/comp/prj.conf b/tests/boards/nrf/comp/prj.conf new file mode 100644 index 00000000000..36ee3da78e7 --- /dev/null +++ b/tests/boards/nrf/comp/prj.conf @@ -0,0 +1,6 @@ +# Copyright (c) 2024 Nordic Semiconductor ASA +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_GPIO=y +CONFIG_COMPARATOR=y +CONFIG_ZTEST=y diff --git a/tests/boards/nrf/comp/src/test.c b/tests/boards/nrf/comp/src/test.c new file mode 100644 index 00000000000..01493d06811 --- /dev/null +++ b/tests/boards/nrf/comp/src/test.c @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2024, Nordic Semiconductor ASA + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +static const struct device *test_dev = DEVICE_DT_GET(DT_ALIAS(test_comp)); +static const struct gpio_dt_spec test_pin_1 = GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), first_gpios); +static const struct gpio_dt_spec test_pin_2 = GPIO_DT_SPEC_GET(DT_PATH(zephyr_user), second_gpios); + + +struct comp_nrf_comp_se_config comp_se_config = { + .psel = COMP_NRF_COMP_PSEL_AIN5, + .sp_mode = COMP_NRF_COMP_SP_MODE_HIGH, + .isource = COMP_NRF_COMP_ISOURCE_DISABLED, + .refsel = COMP_NRF_COMP_REFSEL_AREF, + .extrefsel = COMP_NRF_COMP_EXTREFSEL_AIN1, + .th_up = 32, + .th_down = 32, +}; + +struct comp_nrf_comp_diff_config comp_diff_config = { + .psel = COMP_NRF_COMP_PSEL_AIN4, + .sp_mode = COMP_NRF_COMP_SP_MODE_LOW, + .isource = COMP_NRF_COMP_ISOURCE_DISABLED, + .extrefsel = COMP_NRF_COMP_EXTREFSEL_AIN5, + .enable_hyst = true, +}; + +atomic_t counter; + +static void test_callback(const struct device *dev, void *user_data) +{ + counter++; +} + +/** + * @brief Configure comparator in single-ended mode with + * external voltage reference. + * Check if events were detected. + */ + +ZTEST(comparator_runtime_configure, test_comp_config_se_aref) +{ + int rc; + + rc = comp_nrf_comp_configure_se(test_dev, &comp_se_config); + zassert_equal(rc, 0, "Cannot configure comparator."); + + rc = comparator_set_trigger_callback(test_dev, test_callback, NULL); + zassert_equal(rc, 0, "Cannot set callback for comparator."); + + rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_BOTH_EDGES); + zassert_equal(rc, 0, "Cannot set trigger for comparator."); + + k_msleep(10); + + atomic_clear(&counter); + gpio_pin_set_dt(&test_pin_2, 1); + k_msleep(10); + zassert_equal(atomic_get(&counter), 1, "COMP was not triggered for first threshold cross"); + gpio_pin_set_dt(&test_pin_2, 0); + k_msleep(10); + zassert_equal(atomic_get(&counter), 2, "COMP was not triggered for second threshold cross"); + +} + +/** + * @brief Configure comparator in single-ended mode with + * internal voltage reference. + * Check if events were detected. + */ + + +ZTEST(comparator_runtime_configure, test_comp_config_se_vdd) +{ + int rc; + + struct comp_nrf_comp_se_config conf = comp_se_config; + +#ifdef COMP_REFSEL_REFSEL_AVDDAO1V8 + conf.refsel = COMP_NRF_COMP_REFSEL_AVDDAO1V8; +#else + conf.refsel = COMP_NRF_COMP_REFSEL_VDD; +#endif + rc = comp_nrf_comp_configure_se(test_dev, &conf); + zassert_equal(rc, 0, "Cannot configure comparator."); + + rc = comparator_set_trigger_callback(test_dev, test_callback, NULL); + zassert_equal(rc, 0, "Cannot set callback for comparator."); + + rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_BOTH_EDGES); + zassert_equal(rc, 0, "Cannot set trigger for comparator."); + + k_msleep(10); + + atomic_clear(&counter); + gpio_pin_set_dt(&test_pin_2, 1); + k_msleep(10); + zassert_equal(atomic_get(&counter), 1, "COMP was not triggered for first threshold cross"); + gpio_pin_set_dt(&test_pin_2, 0); + k_msleep(10); + zassert_equal(atomic_get(&counter), 2, "COMP was not triggered for second threshold cross"); + +} + +/** + * @brief Configure comparator in differential mode + * Check if events were detected. + */ + +ZTEST(comparator_runtime_configure, test_comp_config_diff_both) +{ + int rc; + + gpio_pin_set_dt(&test_pin_1, 1); + gpio_pin_set_dt(&test_pin_2, 0); + comparator_trigger_is_pending(test_dev); + + atomic_clear(&counter); + struct comp_nrf_comp_diff_config config = comp_diff_config; + + config.isource = COMP_NRF_COMP_ISOURCE_2UA5; + rc = comp_nrf_comp_configure_diff(test_dev, &config); + zassert_equal(rc, 0, "Cannot configure comparator."); + + rc = comparator_set_trigger_callback(test_dev, test_callback, NULL); + zassert_equal(rc, 0, "Cannot set callback for comparator."); + + rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_BOTH_EDGES); + zassert_equal(rc, 0, "Cannot set trigger for comparator."); + k_msleep(10); + + atomic_clear(&counter); + gpio_pin_set_dt(&test_pin_1, 0); + gpio_pin_set_dt(&test_pin_2, 1); + k_msleep(10); + zassert_equal(atomic_get(&counter), 1, "COMP was not triggered for first threshold cross"); + + gpio_pin_set_dt(&test_pin_2, 0); + gpio_pin_set_dt(&test_pin_1, 1); + k_msleep(10); + + zassert_equal(atomic_get(&counter), 2, "COMP was not triggered for second threshold cross"); +} + +/** + * @brief Configure comparator in differential mode + * trigger both edges, event should be detected for falling one + */ + +ZTEST(comparator_runtime_configure, test_comp_config_diff_falling) +{ + int rc; + + gpio_pin_set_dt(&test_pin_1, 0); + gpio_pin_set_dt(&test_pin_2, 1); + comparator_trigger_is_pending(test_dev); + + atomic_clear(&counter); + struct comp_nrf_comp_diff_config config = comp_diff_config; + + config.isource = COMP_NRF_COMP_ISOURCE_5UA; + rc = comp_nrf_comp_configure_diff(test_dev, &config); + + zassert_equal(rc, 0, "Cannot configure comparator."); + + rc = comparator_set_trigger_callback(test_dev, test_callback, NULL); + zassert_equal(rc, 0, "Cannot set callback for comparator."); + + rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_FALLING_EDGE); + zassert_equal(rc, 0, "Cannot set trigger for comparator."); + + atomic_clear(&counter); + gpio_pin_set_dt(&test_pin_1, 1); + gpio_pin_set_dt(&test_pin_2, 0); + k_msleep(10); + + zassert_equal(counter, 0, "COMP was triggered for rising threshold cross"); + + gpio_pin_set_dt(&test_pin_1, 0); + gpio_pin_set_dt(&test_pin_2, 1); + k_msleep(10); + + zassert_equal(atomic_get(&counter), 1, "COMP wasn't triggered for falling threshold cross"); +} + +/** + * @brief Configure comparator in differential mode + * trigger both edges, event should be detected for rising one + */ + +ZTEST(comparator_runtime_configure, test_comp_config_diff_rising) +{ + int rc; + + gpio_pin_set_dt(&test_pin_1, 1); + gpio_pin_set_dt(&test_pin_2, 0); + comparator_trigger_is_pending(test_dev); + + atomic_clear(&counter); + struct comp_nrf_comp_diff_config config = comp_diff_config; + + config.isource = COMP_NRF_COMP_ISOURCE_10UA; + rc = comp_nrf_comp_configure_diff(test_dev, &config); + zassert_equal(rc, 0, "Cannot configure comparator."); + + rc = comparator_set_trigger_callback(test_dev, test_callback, NULL); + zassert_equal(rc, 0, "Cannot set callback for comparator."); + + rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_RISING_EDGE); + zassert_equal(rc, 0, "Cannot set trigger for comparator."); + + atomic_clear(&counter); + gpio_pin_set_dt(&test_pin_1, 0); + gpio_pin_set_dt(&test_pin_2, 1); + k_msleep(10); + + zassert_equal(atomic_get(&counter), 0, "COMP was triggered for falling threshold cross"); + + gpio_pin_set_dt(&test_pin_1, 1); + gpio_pin_set_dt(&test_pin_2, 0); + k_msleep(10); + + zassert_equal(atomic_get(&counter), 1, "COMP was not triggered for rising threshold cross"); +} + +/** + * @brief Configure comparator in differential mode + * trigger both edges, event should not be detected. + */ + +ZTEST(comparator_runtime_configure, test_comp_config_diff_none) +{ + int rc; + + gpio_pin_set_dt(&test_pin_1, 1); + gpio_pin_set_dt(&test_pin_2, 0); + comparator_trigger_is_pending(test_dev); + + atomic_clear(&counter); + struct comp_nrf_comp_diff_config config = comp_diff_config; + + config.isource = COMP_NRF_COMP_ISOURCE_10UA; + rc = comp_nrf_comp_configure_diff(test_dev, &config); + zassert_equal(rc, 0, "Cannot configure comparator."); + + rc = comparator_set_trigger_callback(test_dev, test_callback, NULL); + zassert_equal(rc, 0, "Cannot set callback for comparator."); + + rc = comparator_set_trigger(test_dev, COMPARATOR_TRIGGER_NONE); + zassert_equal(rc, 0, "Cannot set trigger for comparator."); + + atomic_clear(&counter); + gpio_pin_set_dt(&test_pin_1, 0); + gpio_pin_set_dt(&test_pin_2, 1); + k_msleep(10); + + zassert_equal(atomic_get(&counter), 0, "COMP was triggered for falling threshold cross"); + + gpio_pin_set_dt(&test_pin_1, 1); + gpio_pin_set_dt(&test_pin_2, 0); + k_msleep(10); + + zassert_equal(atomic_get(&counter), 0, "COMP was not triggered for rising threshold cross"); +} + +static void *suite_setup(void) +{ + TC_PRINT("Test executed on %s\n", CONFIG_BOARD_TARGET); + TC_PRINT("===================================================================\n"); + + return NULL; +} + +static void test_before(void *f) +{ + ARG_UNUSED(f); + gpio_pin_configure_dt(&test_pin_1, GPIO_OUTPUT_INACTIVE); + gpio_pin_configure_dt(&test_pin_2, GPIO_OUTPUT_INACTIVE); + +} + +ZTEST_SUITE(comparator_runtime_configure, NULL, suite_setup, test_before, NULL, NULL); diff --git a/tests/boards/nrf/comp/testcase.yaml b/tests/boards/nrf/comp/testcase.yaml new file mode 100644 index 00000000000..d5ac3d9c267 --- /dev/null +++ b/tests/boards/nrf/comp/testcase.yaml @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Nordic Semiconductor +# SPDX-License-Identifier: Apache-2.0 + +common: + harness_config: + fixture: gpio_loopback + tags: + - drivers + - comparator +tests: + drivers.comparator.nrf_comp: + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp + - nrf54l15dk/nrf54l15/cpuapp