blob: 481760da5bd4f80645aa165ead3aaecb1095cf68 [file] [log] [blame]
/*
* Copyright (c) 2024, Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/dt-bindings/comparator/nrf-comp.h>
#include <zephyr/drivers/comparator/nrf_comp.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>
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);
#define TEST_COMP_SE_PSEL_AIN _CONCAT(NRF_COMP_AIN, CONFIG_TEST_COMP_SE_PSEL_AIN_INDEX)
#define TEST_COMP_SE_EXTREFSEL_AIN _CONCAT(NRF_COMP_AIN, CONFIG_TEST_COMP_SE_EXTREFSEL_AIN_INDEX)
#define TEST_COMP_DIFF_PSEL_AIN _CONCAT(NRF_COMP_AIN, CONFIG_TEST_COMP_DIFF_PSEL_AIN_INDEX)
#define TEST_COMP_DIFF_EXTREFSEL_AIN \
_CONCAT(NRF_COMP_AIN, CONFIG_TEST_COMP_DIFF_EXTREFSEL_AIN_INDEX)
struct comp_nrf_comp_se_config comp_se_config = {
.psel = TEST_COMP_SE_PSEL_AIN,
.sp_mode = COMP_NRF_COMP_SP_MODE_HIGH,
.isource = COMP_NRF_COMP_ISOURCE_DISABLED,
.refsel = COMP_NRF_COMP_REFSEL_AREF,
.extrefsel = TEST_COMP_SE_EXTREFSEL_AIN,
.th_up = 32,
.th_down = 32,
};
struct comp_nrf_comp_diff_config comp_diff_config = {
.psel = TEST_COMP_DIFF_PSEL_AIN,
.sp_mode = COMP_NRF_COMP_SP_MODE_LOW,
.isource = COMP_NRF_COMP_ISOURCE_DISABLED,
.extrefsel = TEST_COMP_DIFF_EXTREFSEL_AIN,
.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;
#elif defined(COMP_REFSEL_REFSEL_VDD)
conf.refsel = COMP_NRF_COMP_REFSEL_VDD;
#else
/* Use internal 1.2 V derived from VDD */
conf.refsel = COMP_NRF_COMP_REFSEL_INT_1V2;
#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);