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
15 changes: 15 additions & 0 deletions tests/drivers/pwm/gpio_loopback/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#
# Copyright (c) 2024 Nordic Semiconductor ASA
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

config TEST_PWM_PERIOD_USEC
int "PWM period in microseconds"
default 200000
help
Set PWM signal period to TEST_PWM_PERIOD_USEC microseconds.
In the test, PWM pulse width will be set to half of this value.
The maximum allowable PWM period value is limited by the hardware design.

source "Kconfig.zephyr"
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2024 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,55 @@
/*
* Copyright (c) 2024 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[1] at P7.1
* - GPIO input at P1.05
*/

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

&pinctrl {
pwm_default: pwm_default {
group1 {
psels = <NRF_PSEL(PWM_OUT1, 7, 1)>;
};
};
pwm_sleep: pwm_sleep {
group1 {
psels = <NRF_PSEL(PWM_OUT1, 7, 1)>;
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,55 @@
/*
* Copyright (c) 2024 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[2] at P7.6
* - GPIO input at P1.06
*/

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

&pinctrl {
pwm_default: pwm_default {
group1 {
psels = <NRF_PSEL(PWM_OUT2, 7, 6)>;
};
};
pwm_sleep: pwm_sleep {
group1 {
psels = <NRF_PSEL(PWM_OUT2, 7, 6)>;
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,55 @@
/*
* Copyright (c) 2024 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[3] at P7.7
* - GPIO input at P1.08
*/

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

&pinctrl {
pwm_default: pwm_default {
group1 {
psels = <NRF_PSEL(PWM_OUT3, 7, 7)>;
};
};
pwm_sleep: pwm_sleep {
group1 {
psels = <NRF_PSEL(PWM_OUT3, 7, 7)>;
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";
};
4 changes: 4 additions & 0 deletions tests/drivers/pwm/gpio_loopback/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ static void *pwm_loopback_setup(void)
k_object_access_grant(out.dev, k_current_get());
k_object_access_grant(in.port, k_current_get());

TC_PRINT("Testing PWM device %s, channel %d\n", out.dev->name, out.channel);
TC_PRINT("GPIO loopback at %s, pin %d\n", in.port->name, in.pin);
TC_PRINT("===================================================================\n");

return NULL;
}

Expand Down
34 changes: 18 additions & 16 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 @@ -11,9 +11,6 @@

#include "test_pwm_to_gpio_loopback.h"

#define TEST_PWM_PERIOD_USEC 200000
#define TEST_PWM_PULSE_USEC 100000

#define NUMBER_OF_CYCLE_TO_CAPTURE 5

static struct gpio_callback pwm_input_cb_data;
Expand Down Expand Up @@ -56,14 +53,20 @@ static void test_capture(uint32_t period, uint32_t pulse, pwm_flags_t flags)

int err = 0;

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

get_test_devices(&out, &in);

/* clear edge counters */
high = 0;
low = 0;

/* configure and enable PWM */
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);

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

Expand All @@ -73,23 +76,22 @@ static void test_capture(uint32_t period, uint32_t pulse, pwm_flags_t flags)
gpio_init_callback(&pwm_input_cb_data, pwm_input_captured_callback, BIT(in.pin));
gpio_add_callback(in.port, &pwm_input_cb_data);

if (gpio_pin_get_dt(&in)) {
high = 1;
low = 0;
} else {
high = 0;
low = 1;
}

k_usleep(NUMBER_OF_CYCLE_TO_CAPTURE * period);
/* NUMBER_OF_CYCLE_TO_CAPTURE periods plus 1/4 of period to catch the last edge */
k_usleep((NUMBER_OF_CYCLE_TO_CAPTURE * period) + (period >> 2));

TC_PRINT("PWM output -high state counter: %d -low state counter: %d\n", high, low);
zassert((high >= NUMBER_OF_CYCLE_TO_CAPTURE) && (low >= NUMBER_OF_CYCLE_TO_CAPTURE),
"PWM not captured");
}

ZTEST(pwm_loopback, test_pulse_capture)
ZTEST(pwm_loopback, test_pwm_polarity_normal)
{
test_capture(CONFIG_TEST_PWM_PERIOD_USEC, (CONFIG_TEST_PWM_PERIOD_USEC >> 1),
PWM_POLARITY_NORMAL);
}

ZTEST(pwm_loopback, test_pwm_polarity_inverted)
{
test_capture(TEST_PWM_PERIOD_USEC, TEST_PWM_PULSE_USEC, PWM_POLARITY_NORMAL);
test_capture(TEST_PWM_PERIOD_USEC, TEST_PWM_PULSE_USEC, PWM_POLARITY_INVERTED);
test_capture(CONFIG_TEST_PWM_PERIOD_USEC, (CONFIG_TEST_PWM_PERIOD_USEC >> 1),
PWM_POLARITY_INVERTED);
}
38 changes: 38 additions & 0 deletions tests/drivers/pwm/gpio_loopback/testcase.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,41 @@ tests:
- nrf54h20dk/nrf54h20/cpuapp
- nrf54l15dk/nrf54l15/cpuapp
- nrf54l15pdk/nrf54l15/cpuapp

drivers.pwm.gpio_loopback.fast_p7_0:
platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
integration_platforms:
- nrf54h20dk/nrf54h20/cpuapp
extra_args:
DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_fast_p7_0.overlay"
CONFIG_TEST_PWM_PERIOD_USEC=10000

drivers.pwm.gpio_loopback.fast_p7_1:
platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
integration_platforms:
- nrf54h20dk/nrf54h20/cpuapp
extra_args:
DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_fast_p7_1.overlay"
CONFIG_TEST_PWM_PERIOD_USEC=10000

drivers.pwm.gpio_loopback.fast_p7_6:
build_only: true
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build only as CI setups contain "incompatible" loopback between P7.6-P7.7.
Test relies on GPIOTE while GPIOTE can't be used on P7.

platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
integration_platforms:
- nrf54h20dk/nrf54h20/cpuapp
extra_args:
DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_fast_p7_6.overlay"
CONFIG_TEST_PWM_PERIOD_USEC=10000

drivers.pwm.gpio_loopback.fast_p7_7:
build_only: true
platform_allow:
- nrf54h20dk/nrf54h20/cpuapp
integration_platforms:
- nrf54h20dk/nrf54h20/cpuapp
extra_args:
DTC_OVERLAY_FILE="boards/nrf54h20dk_nrf54h20_cpuapp_fast_p7_7.overlay"
CONFIG_TEST_PWM_PERIOD_USEC=10000
Loading