Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

1 change: 0 additions & 1 deletion tests/drivers/gpio/gpio_event/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ tests:
- nrf5340dk/nrf5340/cpuapp
- nrf5340dk/nrf5340/cpunet
- nrf54h20dk/nrf54h20/cpuapp
- nrf54h20dk/nrf54h20/cpuflpr
- nrf54l15dk/nrf54l15/cpuapp
- nrf54lm20dk/nrf54lm20a/cpuapp
- nrf54lm20dk/nrf54lm20b/cpuapp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# Copyright (c) 2026 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# nRF54H20 FLPR has no GPIO/GPIOTE interrupts wired to this core. Disable
# interrupt-driven GPIO so the driver uses direct pin control (no GPIOTE130 in
# devicetree, no IRQs) — sufficient for polling in this test.
CONFIG_GPIO_NRFX_INTERRUPT=n

# PWM120 (fast domain) cannot use Kconfig default 200 ms; match cpuapp_fast_p7_0 /
# testcase drivers.pwm.gpio_loopback.cpuflpr so manual `west build` and Twister
# both get a valid prescaler.
CONFIG_TEST_PWM_PERIOD_USEC=10000
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright (c) 2026 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zephyr/dt-bindings/pwm/pwm.h>
#include <zephyr/dt-bindings/gpio/nordic-nrf-gpio.h>

/* Test requires wire connection between:
* - PWM120 OUT[0] at P7.0
* - GPIO input at P1.09
*/

/ {
pwm_to_gpio_loopback: pwm_to_gpio_loopback {
compatible = "test-pwm-to-gpio-loopback";
pwms = <&pwm120 0 0 PWM_POLARITY_NORMAL>;
gpios = <&gpio1 9 GPIO_ACTIVE_HIGH>;
};
};

&pinctrl {
pwm_default: pwm_default {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 7, 0)>;
};
};

pwm_sleep: pwm_sleep {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 7, 0)>;
low-power-enable;
};
};
};

&gpio1 {
status = "okay";
};

&pwm120 {
status = "okay";
pinctrl-0 = <&pwm_default>;
pinctrl-1 = <&pwm_sleep>;
pinctrl-names = "default", "sleep";
memory-regions = <&dma_fast_region>;
};

&dma_fast_region {
status = "okay";
};

&pwm130 {
status = "disabled";
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2026 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/*
* vpr_launcher runs on the application core; reserve fast PWM and GPIO for the
* FLPR test image (same pinout as cpuapp_fast_p7_0). FLPR does not use
* GPIOTE130 interrupts — the test image disables CONFIG_GPIO_NRFX_INTERRUPT and
* polls the pin, so GPIOTE130 is left out of the tree.
*/

&pinctrl {
pwm_default: pwm_default {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 7, 0)>;
};
};

pwm_sleep: pwm_sleep {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 7, 0)>;
low-power-enable;
};
};
};

/* P1.09 (loopback input) and P7.0 (PWM120 OUT0) pads */
&gpio1 {
status = "reserved";
};

&gpio7 {
status = "reserved";
};

&pwm120 {
status = "reserved";
pinctrl-0 = <&pwm_default>;
pinctrl-1 = <&pwm_sleep>;
pinctrl-names = "default", "sleep";
memory-regions = <&dma_fast_region>;
};

&dma_fast_region {
status = "okay";
};
Comment thread
nordic-segl marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[gpio_secure_1]
PIN_9 = "NonSecure"

[gpio_own_1]
PIN_9 = "Own"

[gpio_secure_7]
PIN_0 = "NonSecure"

[gpio_own_7]
PIN_0 = "Own"
50 changes: 50 additions & 0 deletions tests/drivers/pwm/gpio_loopback/src/test_pwm_to_gpio_loopback.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#define NUMBER_OF_CYCLE_TO_CAPTURE 5

#if !defined(CONFIG_SOC_NRF54H20_CPUFLPR)
static struct gpio_callback pwm_input_cb_data;
static volatile uint32_t high, low;

Expand All @@ -30,6 +31,7 @@ void pwm_input_captured_callback(const struct device *dev, struct gpio_callback
low++;
}
}
#endif /* !CONFIG_SOC_NRF54H20_CPUFLPR */

void get_test_devices(struct pwm_dt_spec *out, struct gpio_dt_spec *in)
{
Expand All @@ -46,6 +48,53 @@ void get_test_devices(struct pwm_dt_spec *out, struct gpio_dt_spec *in)
zassert_true(gpio_is_ready_dt(in), "pwm loopback in device is not ready");
}

#if defined(CONFIG_SOC_NRF54H20_CPUFLPR)
/*
* nRF54H20 FLPR has no GPIO pin interrupts; sample the loopback pin in a timed
* busy loop and count rising/falling edges (same thresholds as the GPIOTE path).
*/
static void test_capture(uint32_t period, uint32_t pulse, pwm_flags_t flags)
{
struct pwm_dt_spec out;
struct gpio_dt_spec in;
int err;
uint32_t high_cnt = 0;
uint32_t low_cnt = 0;
const uint32_t duration_us =
(NUMBER_OF_CYCLE_TO_CAPTURE * period) + (period >> 2);

TC_PRINT("Pulse/period: %u/%u usec\n", pulse, period);

get_test_devices(&out, &in);

err = pwm_set(out.dev, out.channel, PWM_USEC(period), PWM_USEC(pulse),
out.flags ^= (flags & PWM_POLARITY_MASK));
zassert_equal(err, 0, "failed to set pwm output (err %d)", err);

err = gpio_pin_configure_dt(&in, GPIO_INPUT);
zassert_equal(err, 0, "failed to configure input pin (err %d)", err);

int last = gpio_pin_get_dt(&in);

for (uint32_t us = 0; us < duration_us; us++) {
k_busy_wait(1);
int now = gpio_pin_get_dt(&in);

if (now != last) {
if (now) {
high_cnt++;
} else {
low_cnt++;
}
last = now;
}
}

TC_PRINT("PWM output -high state counter: %u -low state counter: %u\n", high_cnt, low_cnt);
zassert((high_cnt >= NUMBER_OF_CYCLE_TO_CAPTURE) && (low_cnt >= NUMBER_OF_CYCLE_TO_CAPTURE),
"PWM not captured");
}
#else
static void test_capture(uint32_t period, uint32_t pulse, pwm_flags_t flags)
{
struct pwm_dt_spec out;
Expand Down Expand Up @@ -83,6 +132,7 @@ static void test_capture(uint32_t period, uint32_t pulse, pwm_flags_t flags)
zassert((high >= NUMBER_OF_CYCLE_TO_CAPTURE) && (low >= NUMBER_OF_CYCLE_TO_CAPTURE),
"PWM not captured");
}
#endif /* CONFIG_SOC_NRF54H20_CPUFLPR */

ZTEST(pwm_loopback, test_pwm_polarity_normal)
{
Expand Down
14 changes: 14 additions & 0 deletions tests/drivers/pwm/gpio_loopback/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,17 @@ tests:
extra_args:
- DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_fast_p7_7.overlay"
- CONFIG_TEST_PWM_PERIOD_USEC=10000

drivers.pwm.gpio_loopback.cpuflpr:
sysbuild: true
required_snippets:
- nordic-log-stm
platform_allow:
- nrf54h20dk/nrf54h20/cpuflpr
integration_platforms:
- nrf54h20dk/nrf54h20/cpuflpr
extra_args:
- DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuflpr.overlay"
- vpr_launcher_EXTRA_DTC_OVERLAY_FILE="${ZEPHYR_NRF_MODULE_DIR}/tests/drivers/pwm/gpio_loopback/boards/nrf54h20dk_nrf54h20_cpuflpr_launcher.overlay"
- vpr_launcher_SNIPPET=nordic-log-stm
- vpr_launcher_CONFIG_BOOT_BANNER=n
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright (c) 2026 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

/*
* Same PWM instances and pinout as nrf54h20dk_nrf54h20_cpuapp.overlay.
* PWM120 uses dma_fast_region; PWM130–133 use cpuapp_dma_region (enabled below).
*/

&pinctrl {
pwm120_default_test: pwm120_default_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 7, 0)>;
};
};

pwm120_sleep_test: pwm120_sleep_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 7, 0)>;
low-power-enable;
};
};

pwm130_default_test: pwm130_default_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 9, 2)>;
};
};

pwm130_sleep_test: pwm130_sleep_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 9, 2)>;
low-power-enable;
};
};

pwm131_default_test: pwm131_default_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 1, 2)>;
};
};

pwm131_sleep_test: pwm131_sleep_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 1, 2)>;
low-power-enable;
};
};

pwm132_default_test: pwm132_default_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 2, 8)>;
};
};

pwm132_sleep_test: pwm132_sleep_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 2, 8)>;
low-power-enable;
};
};

pwm133_default_test: pwm133_default_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 0, 2)>;
};
};

pwm133_sleep_test: pwm133_sleep_test {
group1 {
psels = <NRF_PSEL(PWM_OUT0, 0, 2)>;
low-power-enable;
};
};
};

&cpuapp_dma_region {
status = "okay";
};

&dma_fast_region {
status = "okay";
};

&pwm120 {
status = "okay";
pinctrl-0 = <&pwm120_default_test>;
pinctrl-1 = <&pwm120_sleep_test>;
pinctrl-names = "default", "sleep";
memory-regions = <&dma_fast_region>;
};

&pwm130 {
status = "okay";
pinctrl-0 = <&pwm130_default_test>;
pinctrl-1 = <&pwm130_sleep_test>;
pinctrl-names = "default", "sleep";
memory-regions = <&cpuapp_dma_region>;
};

&pwm131 {
status = "okay";
pinctrl-0 = <&pwm131_default_test>;
pinctrl-1 = <&pwm131_sleep_test>;
pinctrl-names = "default", "sleep";
memory-regions = <&cpuapp_dma_region>;
};

&pwm132 {
status = "okay";
pinctrl-0 = <&pwm132_default_test>;
pinctrl-1 = <&pwm132_sleep_test>;
pinctrl-names = "default", "sleep";
memory-regions = <&cpuapp_dma_region>;
};

&pwm133 {
status = "okay";
pinctrl-0 = <&pwm133_default_test>;
pinctrl-1 = <&pwm133_sleep_test>;
pinctrl-names = "default", "sleep";
memory-regions = <&cpuapp_dma_region>;
};
Loading
Loading