Commit 08cc78cc authored by Bartosz Miller's avatar Bartosz Miller Committed by Anas Nashif
Browse files

tests: boards: nrf: qdec: Add testing with multiple QDEC instances

NRFX should support multiple QDEC devices operation.

Signed-off-by: default avatarBartosz Miller <bartosz.miller@nordicsemi.no>
parent f2c8a5ac
Loading
Loading
Loading
Loading
+53 −4
Changes for tests/boards/nrf/qdec/boards/nrf54h20dk_nrf54h20_cpuapp.overlay: 53 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -3,11 +3,21 @@
 * SPDX-License-Identifier: Apache-2.0
 */

/* Required loopbacks
 * P2.08 <-> P2.09
 * P2.10 <-> P2.11
 * P1.02 <-> P1.03
 * P7.01 <-> P1.05
 */

/ {
	aliases {
		qdec0 = &qdec130;
		qdec1 = &qdec131;
		qenca = &phase_a;
		qencb = &phase_b;
		qenca1 = &phase_a1;
		qencb1 = &phase_b1;
	};

	encoder-emulate {
@@ -18,34 +28,73 @@
		phase_b: phase_b {
			gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>;
		};
		phase_a1: phase_a1 {
			gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
		};
		phase_b1: phase_b1 {
			gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>;
		};
	};
};

&pinctrl {
	qdec_pinctrl: qdec_pinctrl {
	qdec_130_pinctrl: qdec_130_pinctrl {
		group1 {
			psels = <NRF_PSEL(QDEC_A, 2, 8)>,
				<NRF_PSEL(QDEC_B, 2, 10)>;
		};
	};

	qdec_sleep_pinctrl: qdec_sleep_pinctrl {
	qdec_130_sleep_pinctrl: qdec_130_sleep_pinctrl {
		group1 {
			psels = <NRF_PSEL(QDEC_A, 2, 8)>,
				<NRF_PSEL(QDEC_B, 2, 10)>;
			low-power-enable;
		};
	};

	qdec_131_pinctrl: qdec_131_pinctrl {
		group1 {
			psels = <NRF_PSEL(QDEC_A, 1, 3)>,
				<NRF_PSEL(QDEC_B, 1, 5)>;
		};
	};

	qdec_131_sleep_pinctrl: qdec_131_sleep_pinctrl {
		group1 {
			psels = <NRF_PSEL(QDEC_A, 1, 3)>,
				<NRF_PSEL(QDEC_B, 1, 5)>;
			low-power-enable;
		};
	};
};

&gpio1 {
	status = "okay";
};

&gpio2 {
	status = "okay";
};

&gpio7 {
	status = "okay";
};

&qdec130 {
	status = "okay";
	pinctrl-0 = <&qdec_pinctrl>;
	pinctrl-1 = <&qdec_sleep_pinctrl>;
	pinctrl-0 = <&qdec_130_pinctrl>;
	pinctrl-1 = <&qdec_130_sleep_pinctrl>;
	pinctrl-names = "default", "sleep";
	steps = <127>;
	led-pre = <500>;
	zephyr,pm-device-runtime-auto;
};

&qdec131 {
	status = "okay";
	pinctrl-0 = <&qdec_131_pinctrl>;
	pinctrl-1 = <&qdec_131_sleep_pinctrl>;
	pinctrl-names = "default", "sleep";
	steps = <127>;
	led-pre = <500>;
+49 −4
Changes for tests/boards/nrf/qdec/boards/nrf54l15dk_nrf54l15_common.dtsi: 49 added lines, 4 removed lines.
Original line number Diff line number Diff line
@@ -3,11 +3,21 @@
 * SPDX-License-Identifier: Apache-2.0
 */

/* Required loopbacks
 * P1.8 <-> P1.9
 * P1.10 >-> P1.11
 * P2.8 <-> P2.9
 * P2.10 <-> P1.14
 */

/ {
	aliases {
		qdec0 = &qdec20;
		qdec1 = &qdec21;
		qenca = &phase_a;
		qencb = &phase_b;
		qenca1 = &phase_a1;
		qencb1 = &phase_b1;
	};

	encoder-emulate {
@@ -18,34 +28,69 @@
		phase_b: phase_b {
			gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>;
		};
		phase_a1: phase_a1 {
			gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>;
		};
		phase_b1: phase_b1 {
			gpios = <&gpio1 14 GPIO_ACTIVE_HIGH>;
		};
	};
};

&pinctrl {
	qdec_pinctrl: qdec_pinctrl {
	qdec_20_pinctrl: qdec_20_pinctrl {
		group1 {
			psels = <NRF_PSEL(QDEC_A, 1, 8)>,
				<NRF_PSEL(QDEC_B, 1, 10)>;
		};
	};

	qdec_sleep_pinctrl: qdec_sleep_pinctrl {
	qdec_20_sleep_pinctrl: qdec_20_sleep_pinctrl {
		group1 {
			psels = <NRF_PSEL(QDEC_A, 1, 8)>,
				<NRF_PSEL(QDEC_B, 1, 10)>;
			low-power-enable;
		};
	};

	qdec_21_pinctrl: qdec_21_pinctrl {
		group1 {
			psels = <NRF_PSEL(QDEC_A, 2, 8)>,
				<NRF_PSEL(QDEC_B, 2, 10)>;
		};
	};

	qdec_21_sleep_pinctrl: qdec_21_sleep_pinctrl {
		group1 {
			psels = <NRF_PSEL(QDEC_A, 2, 8)>,
				<NRF_PSEL(QDEC_B, 2, 10)>;
			low-power-enable;
		};
	};
};

&gpio1 {
	status = "okay";
};

&gpio2 {
	status = "okay";
};

&qdec20 {
	status = "okay";
	pinctrl-0 = <&qdec_pinctrl>;
	pinctrl-1 = <&qdec_sleep_pinctrl>;
	pinctrl-0 = <&qdec_20_pinctrl>;
	pinctrl-1 = <&qdec_20_sleep_pinctrl>;
	pinctrl-names = "default", "sleep";
	steps = <127>;
	led-pre = <500>;
	zephyr,pm-device-runtime-auto;
};

&qdec21 {
	status = "okay";
	pinctrl-0 = <&qdec_21_pinctrl>;
	pinctrl-1 = <&qdec_21_sleep_pinctrl>;
	pinctrl-names = "default", "sleep";
	steps = <127>;
	led-pre = <500>;
+197 −73
Changes for tests/boards/nrf/qdec/src/main.c: 197 added lines, 73 removed lines.
Original line number Diff line number Diff line
@@ -16,6 +16,15 @@ static const struct gpio_dt_spec phase_a = GPIO_DT_SPEC_GET(DT_ALIAS(qenca), gpi
static const struct gpio_dt_spec phase_b = GPIO_DT_SPEC_GET(DT_ALIAS(qencb), gpios);
static const struct device *const qdec_dev = DEVICE_DT_GET(DT_ALIAS(qdec0));
static const uint32_t qdec_config_step = DT_PROP(DT_ALIAS(qdec0), steps);

#if DT_NODE_EXISTS(DT_ALIAS(qdec1))
#define SECOND_QDEC_INSTANCE

static const struct gpio_dt_spec phase_a1 = GPIO_DT_SPEC_GET(DT_ALIAS(qenca1), gpios);
static const struct gpio_dt_spec phase_b1 = GPIO_DT_SPEC_GET(DT_ALIAS(qencb1), gpios);
static const struct device *const qdec_1_dev = DEVICE_DT_GET(DT_ALIAS(qdec1));
static const uint32_t qdec_1_config_step = DT_PROP(DT_ALIAS(qdec1), steps);
#endif
static struct sensor_trigger qdec_trigger = {.type = SENSOR_TRIG_DATA_READY,
					     .chan = SENSOR_CHAN_ROTATION};
static bool toggle_a = true;
@@ -24,7 +33,6 @@ static void qdec_trigger_handler(const struct device *dev, const struct sensor_t
{
	zassert_not_null(dev);
	zassert_not_null(trigger);
	zassert_equal_ptr(dev, qdec_dev);
	/* trigger should be stored as a pointer in a driver
	 * thus this address should match
	 */
@@ -37,8 +45,14 @@ static void qenc_emulate_work_handler(struct k_work *work)
{
	if (toggle_a) {
		gpio_pin_toggle_dt(&phase_a);
#if defined(SECOND_QDEC_INSTANCE)
		gpio_pin_toggle_dt(&phase_a1);
#endif
	} else {
		gpio_pin_toggle_dt(&phase_b);
#if defined(SECOND_QDEC_INSTANCE)
		gpio_pin_toggle_dt(&phase_b1);
#endif
	}
	toggle_a = !toggle_a;
}
@@ -75,6 +89,10 @@ static void qenc_emulate_start(k_timeout_t period, bool forward)
{
	qenc_emulate_reset_pin(&phase_a);
	qenc_emulate_reset_pin(&phase_b);
#if defined(SECOND_QDEC_INSTANCE)
	qenc_emulate_reset_pin(&phase_a1);
	qenc_emulate_reset_pin(&phase_b1);
#endif

	toggle_a = !forward;

@@ -87,15 +105,20 @@ static void qenc_emulate_stop(void)

	qenc_emulate_reset_pin(&phase_a);
	qenc_emulate_reset_pin(&phase_b);
#if defined(SECOND_QDEC_INSTANCE)
	qenc_emulate_reset_pin(&phase_a1);
	qenc_emulate_reset_pin(&phase_b1);
#endif
}

static void qenc_emulate_verify_reading(int emulator_period_ms, int emulation_duration_ms,
					bool forward, bool overflow_expected)
static void qenc_emulate_verify_reading(const struct device *const dev, int emulator_period_ms,
		int emulation_duration_ms, bool forward, bool overflow_expected,
		const uint32_t config_step)
{
	int rc;
	struct sensor_value val = {0};
	int32_t expected_steps = emulation_duration_ms / emulator_period_ms;
	int32_t expected_reading = 360 * expected_steps / qdec_config_step;
	int32_t expected_reading = 360 * expected_steps / config_step;
	int32_t delta = expected_reading / 5;

	if (!forward) {
@@ -107,7 +130,7 @@ static void qenc_emulate_verify_reading(int emulator_period_ms, int emulation_du
	/* wait for some readings */
	k_msleep(emulation_duration_ms);

	rc = sensor_sample_fetch(qdec_dev);
	rc = sensor_sample_fetch(dev);

	if (!overflow_expected) {
		zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);
@@ -115,9 +138,11 @@ static void qenc_emulate_verify_reading(int emulator_period_ms, int emulation_du
		zassert_true(rc == -EOVERFLOW, "Failed to detect overflow");
	}

	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
	rc = sensor_channel_get(dev, SENSOR_CHAN_ROTATION, &val);
	zassert_true(rc == 0, "Failed to get sample (%d)", rc);

	TC_PRINT("Expected reading: %d, actual value: %d, delta: %d\n",
			expected_reading, val.val1, delta);
	if (!overflow_expected) {
		zassert_within(val.val1, expected_reading, delta,
			       "Expected reading: %d,  but got: %d", expected_reading, val.val1);
@@ -128,30 +153,26 @@ static void qenc_emulate_verify_reading(int emulator_period_ms, int emulation_du
	/* wait and get readings to clear state */
	k_msleep(100);

	rc = sensor_sample_fetch(qdec_dev);
	rc = sensor_sample_fetch(dev);
	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);

	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
	rc = sensor_channel_get(dev, SENSOR_CHAN_ROTATION, &val);
	zassert_true(rc == 0, "Failed to get sample (%d)", rc);
}

/**
 * @brief sensor_trigger_set test disable trigger
 *
 * Confirm trigger happens after set and stops after being disabled
 *
 */
ZTEST(qdec_sensor, test_sensor_trigger_set_and_disable)
static void sensor_trigger_set_and_disable(const struct device *const dev)
{
	int rc;

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_get(qdec_dev);
		pm_device_runtime_get(dev);
	}

	k_sem_give(&sem);

	qdec_trigger.type = SENSOR_TRIG_DATA_READY;
	qdec_trigger.chan = SENSOR_CHAN_ALL;
	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
	rc = sensor_trigger_set(dev, &qdec_trigger, qdec_trigger_handler);
	zassume_true(rc != -ENOSYS, "sensor_trigger_set not supported");

	zassert_true(rc == 0, "sensor_trigger_set failed: %d", rc);
@@ -168,7 +189,7 @@ ZTEST(qdec_sensor, test_sensor_trigger_set_and_disable)
	rc = k_sem_take(&sem, K_MSEC(200));

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_dev);
		pm_device_runtime_put(dev);
	}

	/* there should be no triggers now*/
@@ -176,11 +197,11 @@ ZTEST(qdec_sensor, test_sensor_trigger_set_and_disable)
	zassert_true(rc == -EAGAIN, "qdec handler should not be triggered (%d)", rc);

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_get(qdec_dev);
		pm_device_runtime_get(dev);
	}

	/* register empty trigger - disable trigger */
	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, NULL);
	rc = sensor_trigger_set(dev, &qdec_trigger, NULL);
	zassert_true(rc == 0, "sensor_trigger_set failed: %d", rc);

	qenc_emulate_start(K_MSEC(10), true);
@@ -190,28 +211,39 @@ ZTEST(qdec_sensor, test_sensor_trigger_set_and_disable)
	zassert_true(rc == -EAGAIN, "qdec handler should not be triggered (%d)", rc);

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_dev);
		pm_device_runtime_put(dev);
	}
}

/**
 * @brief sensor_trigger_set test
 * @brief sensor_trigger_set test disable trigger
 *
 * Confirm trigger happens after set
 * Confirm trigger happens after set and stops after being disabled
 *
 */
ZTEST(qdec_sensor, test_sensor_trigger_set)
ZTEST(qdec_sensor, test_sensor_trigger_set_and_disable)
{
	TC_PRINT("Testing QDEC-0, address: %p\n", qdec_dev);
	sensor_trigger_set_and_disable(qdec_dev);
#if defined(SECOND_QDEC_INSTANCE)
	TC_PRINT("Testing QDEC-1, address: %p\n", qdec_1_dev);
	sensor_trigger_set_and_disable(qdec_1_dev);
#endif

}

static void sensor_trigger_set_test(const struct device *const dev)
{
	int rc;
	struct sensor_value val = {0};

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_get(qdec_dev);
		pm_device_runtime_get(dev);
	}

	qdec_trigger.type = SENSOR_TRIG_DATA_READY;
	qdec_trigger.chan = SENSOR_CHAN_ROTATION;
	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
	rc = sensor_trigger_set(dev, &qdec_trigger, qdec_trigger_handler);
	zassume_true(rc != -ENOSYS, "sensor_trigger_set not supported");

	zassert_true(rc == 0, "sensor_trigger_set failed: %d", rc);
@@ -222,52 +254,78 @@ ZTEST(qdec_sensor, test_sensor_trigger_set)
	rc = k_sem_take(&sem, K_MSEC(200));
	zassert_true(rc == 0, "qdec handler should be triggered (%d)", rc);

	rc = sensor_sample_fetch(qdec_dev);
	rc = sensor_sample_fetch(dev);
	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);

	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
	rc = sensor_channel_get(dev, SENSOR_CHAN_ROTATION, &val);
	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);

	TC_PRINT("QDEC reading: %d\n", val.val1);
	zassert_true(val.val1 != 0, "No readings from QDEC");

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_dev);
		pm_device_runtime_put(dev);
	}
}

/**
 * @brief sensor_trigger_set test negative
 * @brief sensor_trigger_set test
 *
 * Confirm setting trigger with invalid data does not work
 * Confirm trigger happens after set
 *
 */
ZTEST(qdec_sensor, test_sensor_trigger_set_negative)
ZTEST(qdec_sensor, test_sensor_trigger_set)
{
	TC_PRINT("Testing QDEC-0, address: %p\n", qdec_dev);
	sensor_trigger_set_test(qdec_dev);
#if defined(SECOND_QDEC_INSTANCE)
	TC_PRINT("Testing QDEC-1, address: %p\n", qdec_1_dev);
	sensor_trigger_set_test(qdec_1_dev);
#endif
}

static void sensor_trigger_set_negative(const struct device *const dev)
{
	int rc;

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_get(qdec_dev);
		pm_device_runtime_get(dev);
	}

	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
	rc = sensor_trigger_set(dev, &qdec_trigger, qdec_trigger_handler);
	zassume_true(rc != -ENOSYS, "sensor_trigger_set not supported");

	qdec_trigger.type = SENSOR_TRIG_MAX;
	qdec_trigger.chan = SENSOR_CHAN_ROTATION;

	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
	rc = sensor_trigger_set(dev, &qdec_trigger, qdec_trigger_handler);
	zassume_true(rc < 0, "sensor_trigger_set should fail due to invalid trigger type");

	qdec_trigger.type = SENSOR_TRIG_DATA_READY;
	qdec_trigger.chan = SENSOR_CHAN_MAX;

	rc = sensor_trigger_set(qdec_dev, &qdec_trigger, qdec_trigger_handler);
	rc = sensor_trigger_set(dev, &qdec_trigger, qdec_trigger_handler);
	zassume_true(rc < 0, "sensor_trigger_set should fail due to invalid channel");

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_dev);
		pm_device_runtime_put(dev);
	}
}

/**
 * @brief sensor_trigger_set test negative
 *
 * Confirm setting trigger with invalid data does not work
 *
 */
ZTEST(qdec_sensor, test_sensor_trigger_set_negative)
{
	TC_PRINT("Testing QDEC-0, address: %p\n", qdec_dev);
	sensor_trigger_set_negative(qdec_dev);
#if defined(SECOND_QDEC_INSTANCE)
	TC_PRINT("Testing QDEC-1, address: %p\n", qdec_1_dev);
	sensor_trigger_set_negative(qdec_1_dev);
#endif
}

/**
@@ -282,68 +340,90 @@ ZTEST(qdec_sensor, test_qdec_readings)
		pm_device_runtime_get(qdec_dev);
	}

	qenc_emulate_verify_reading(10, 100, true, false);
	qenc_emulate_verify_reading(2, 500, true, false);
	qenc_emulate_verify_reading(10, 200, false, false);
	qenc_emulate_verify_reading(1, 1000, false, true);
	qenc_emulate_verify_reading(1, 1000, true, true);
	TC_PRINT("Testing QDEC-0, address: %p\n", qdec_dev);
	qenc_emulate_verify_reading(qdec_dev, 10, 100, true, false, qdec_config_step);
	qenc_emulate_verify_reading(qdec_dev, 2, 500, true, false, qdec_config_step);
	qenc_emulate_verify_reading(qdec_dev, 10, 200, false, false, qdec_config_step);
	qenc_emulate_verify_reading(qdec_dev, 1, 1000, false, true, qdec_config_step);
	qenc_emulate_verify_reading(qdec_dev, 1, 1000, true, true, qdec_config_step);

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_dev);
	}

#if defined(SECOND_QDEC_INSTANCE)
	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_get(qdec_1_dev);
	}

/**
 * @brief sensor_channel_get test with no emulation
 *
 * Confirm getting empty reading from QDEC
 *
 */
ZTEST(qdec_sensor, test_sensor_channel_get_empty)
	TC_PRINT("Testing QDEC-1, address: %p\n", qdec_1_dev);
	qenc_emulate_verify_reading(qdec_1_dev, 10, 100, true, false, qdec_1_config_step);
	qenc_emulate_verify_reading(qdec_1_dev, 2, 500, true, false, qdec_1_config_step);
	qenc_emulate_verify_reading(qdec_1_dev, 10, 200, false, false, qdec_1_config_step);
	qenc_emulate_verify_reading(qdec_1_dev, 1, 1000, false, true, qdec_1_config_step);
	qenc_emulate_verify_reading(qdec_1_dev, 1, 1000, true, true, qdec_1_config_step);

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_1_dev);
	}
#endif
}

static void sensor_channel_get_empty(const struct device *const dev)
{
	int rc;
	struct sensor_value val = {0};

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_get(qdec_dev);
		pm_device_runtime_get(dev);
	}

	/* wait for potential new readings */
	k_msleep(100);

	rc = sensor_sample_fetch(qdec_dev);
	rc = sensor_sample_fetch(dev);
	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);

	/* get readings but ignore them, as they may include reading from time
	 * when emulation was still working (i.e. during previous test)
	 */
	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
	rc = sensor_channel_get(dev, SENSOR_CHAN_ROTATION, &val);
	zassert_true(rc == 0, "Failed to get sample (%d)", rc);

	/* wait for potential new readings */
	k_msleep(100);

	rc = sensor_sample_fetch(qdec_dev);
	rc = sensor_sample_fetch(dev);
	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);

	/* emulation was not working, expect no readings */
	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_ROTATION, &val);
	rc = sensor_channel_get(dev, SENSOR_CHAN_ROTATION, &val);
	zassert_true(rc == 0, "Failed to get sample (%d)", rc);
	zassert_true(val.val1 == 0, "Expected no readings but got: %d", val.val1);
	zassert_true(val.val2 == 0, "Expected no readings but got: %d", val.val2);

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_dev);
		pm_device_runtime_put(dev);
	}
}

/**
 * @brief sensor_channel_get test with emulation
 * @brief sensor_channel_get test with no emulation
 *
 * Confirm getting readings from QDEC
 * Confirm getting empty reading from QDEC
 *
 */
ZTEST(qdec_sensor, test_sensor_channel_get)
ZTEST(qdec_sensor, test_sensor_channel_get_empty)
{
	TC_PRINT("Testing QDEC-0, address: %p\n", qdec_dev);
	sensor_channel_get_empty(qdec_dev);
#if defined(SECOND_QDEC_INSTANCE)
	TC_PRINT("Testing QDEC-1, address: %p\n", qdec_1_dev);
	sensor_channel_get_empty(qdec_1_dev);
#endif
}

static void sensor_channel_get_test(const struct device *const dev)
{
	int rc;
	struct sensor_value val_first = {0};
@@ -391,18 +471,28 @@ ZTEST(qdec_sensor, test_sensor_channel_get)
}

/**
 * @brief sensor_channel_get test negative
 * @brief sensor_channel_get test with emulation
 *
 * Confirm getting readings from QDEC with invalid channel
 * Confirm getting readings from QDEC
 *
 */
ZTEST(qdec_sensor, test_sensor_channel_get_negative)
ZTEST(qdec_sensor, test_sensor_channel_get)
{
	TC_PRINT("Testing QDEC-0, address: %p\n", qdec_dev);
	sensor_channel_get_test(qdec_dev);
#if defined(SECOND_QDEC_INSTANCE)
	TC_PRINT("Testing QDEC-1, address: %p\n", qdec_1_dev);
	sensor_channel_get_test(qdec_1_dev);
#endif
}

static void sensor_channel_get_negative(const struct device *const dev)
{
	int rc;
	struct sensor_value val = {0};

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_get(qdec_dev);
		pm_device_runtime_get(dev);
	}

	qenc_emulate_start(K_MSEC(10), true);
@@ -410,47 +500,73 @@ ZTEST(qdec_sensor, test_sensor_channel_get_negative)
	/* wait for some readings*/
	k_msleep(100);

	rc = sensor_sample_fetch(qdec_dev);
	rc = sensor_sample_fetch(dev);
	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);

	rc = sensor_channel_get(qdec_dev, SENSOR_CHAN_MAX, &val);
	rc = sensor_channel_get(dev, SENSOR_CHAN_MAX, &val);
	zassert_true(rc < 0, "Should failed to get sample (%d)", rc);
	zassert_true(val.val1 == 0, "Some readings from QDEC: %d", val.val1);
	zassert_true(val.val2 == 0, "Some readings from QDEC: %d", val.val2);

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_dev);
		pm_device_runtime_put(dev);
	}
}

/**
 * @brief sensor_sample_fetch(_chan) test
 * @brief sensor_channel_get test negative
 *
 * Confirm fetching work with QDEC specific channel - rotation
 * Confirm getting readings from QDEC with invalid channel
 *
 */
ZTEST(qdec_sensor, test_sensor_sample_fetch)
ZTEST(qdec_sensor, test_sensor_channel_get_negative)
{
	TC_PRINT("Testing QDEC-0, address: %p\n", qdec_dev);
	sensor_channel_get_negative(qdec_dev);
#if defined(SECOND_QDEC_INSTANCE)
	TC_PRINT("Testing QDEC-1, address: %p\n", qdec_1_dev);
	sensor_channel_get_negative(qdec_1_dev);
#endif
}

static void sensor_sample_fetch_test(const struct device *const dev)
{
	int rc;

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_get(qdec_dev);
		pm_device_runtime_get(dev);
	}

	rc = sensor_sample_fetch(qdec_dev);
	rc = sensor_sample_fetch(dev);
	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);

	rc = sensor_sample_fetch_chan(qdec_dev, SENSOR_CHAN_ROTATION);
	rc = sensor_sample_fetch_chan(dev, SENSOR_CHAN_ROTATION);
	zassert_true(rc == 0, "Failed to fetch sample (%d)", rc);

	rc = sensor_sample_fetch_chan(qdec_dev, SENSOR_CHAN_MAX);
	rc = sensor_sample_fetch_chan(dev, SENSOR_CHAN_MAX);
	zassert_true(rc < 0, "Should fail to fetch sample from invalid channel (%d)", rc);

	if (IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME)) {
		pm_device_runtime_put(qdec_dev);
		pm_device_runtime_put(dev);
	}
}

/**
 * @brief sensor_sample_fetch(_chan) test
 *
 * Confirm fetching work with QDEC specific channel - rotation
 *
 */
ZTEST(qdec_sensor, test_sensor_sample_fetch)
{
	TC_PRINT("Testing QDEC-0, address: %p\n", qdec_dev);
	sensor_sample_fetch_test(qdec_dev);
#if defined(SECOND_QDEC_INSTANCE)
	TC_PRINT("Testing QDEC-1, address: %p\n", qdec_1_dev);
	sensor_sample_fetch_test(qdec_1_dev);
#endif
}

static void *setup(void)
{
	int rc;
@@ -461,6 +577,14 @@ static void *setup(void)
	qenc_emulate_setup_pin(&phase_a);
	qenc_emulate_setup_pin(&phase_b);

#if defined(SECOND_QDEC_INSTANCE)
	rc = device_is_ready(qdec_1_dev);
	zassert_true(rc, "QDEC 1 device not ready: %d", rc);

	qenc_emulate_setup_pin(&phase_a1);
	qenc_emulate_setup_pin(&phase_b1);
#endif

	return NULL;
}