diff --git a/tests/boards/espressif/wifi/socs/esp32c3_usb.overlay b/tests/boards/espressif/wifi/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..872f2dfe2ea --- /dev/null +++ b/tests/boards/espressif/wifi/socs/esp32c3_usb.overlay @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&wifi { + status = "okay"; +}; diff --git a/tests/drivers/adc/adc_api/socs/esp32c3_usb.conf b/tests/drivers/adc/adc_api/socs/esp32c3_usb.conf new file mode 100644 index 00000000000..b6c5c80f924 --- /dev/null +++ b/tests/drivers/adc/adc_api/socs/esp32c3_usb.conf @@ -0,0 +1 @@ +CONFIG_ADC_ASYNC=n diff --git a/tests/drivers/adc/adc_api/socs/esp32c3_usb.overlay b/tests/drivers/adc/adc_api/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..c288312aa3a --- /dev/null +++ b/tests/drivers/adc/adc_api/socs/esp32c3_usb.overlay @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Wolter HV + * Copyright (c) 2023 Benjamin Björnsson + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + zephyr,user { + /* adjust channel number according to pinmux in board.dts */ + io-channels = <&adc0 0>, <&adc0 1>; + }; +}; + +&adc0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/tests/drivers/counter/counter_basic_api/socs/esp32c3_usb.overlay b/tests/drivers/counter/counter_basic_api/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..b5ba7f57398 --- /dev/null +++ b/tests/drivers/counter/counter_basic_api/socs/esp32c3_usb.overlay @@ -0,0 +1,7 @@ +&timer0 { + status = "okay"; +}; + +&rtc { + slow-clk-src = ; +}; diff --git a/tests/drivers/dma/chan_blen_transfer/socs/esp32c3_usb.conf b/tests/drivers/dma/chan_blen_transfer/socs/esp32c3_usb.conf new file mode 100644 index 00000000000..56bf25e718b --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/socs/esp32c3_usb.conf @@ -0,0 +1,3 @@ +CONFIG_DMA_TRANSFER_CHANNEL_NR_0=5 +CONFIG_DMA_TRANSFER_CHANNEL_NR_1=0 +CONFIG_HEAP_MEM_POOL_SIZE=32768 diff --git a/tests/drivers/dma/chan_blen_transfer/socs/esp32c3_usb.overlay b/tests/drivers/dma/chan_blen_transfer/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..6ac9ff08336 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/socs/esp32c3_usb.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +tst_dma0: &dma { }; diff --git a/tests/drivers/dma/loop_transfer/socs/esp32c3_usb.conf b/tests/drivers/dma/loop_transfer/socs/esp32c3_usb.conf new file mode 100644 index 00000000000..311bfc8f535 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/socs/esp32c3_usb.conf @@ -0,0 +1,2 @@ +CONFIG_DMA_LOOP_TRANSFER_CHANNEL_NR=0 +CONFIG_DMA_LOOP_TRANSFER_SIZE=4094 diff --git a/tests/drivers/dma/loop_transfer/socs/esp32c3_usb.overlay b/tests/drivers/dma/loop_transfer/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..6ac9ff08336 --- /dev/null +++ b/tests/drivers/dma/loop_transfer/socs/esp32c3_usb.overlay @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&dma { + status = "okay"; +}; + +tst_dma0: &dma { }; diff --git a/tests/drivers/flash/common/socs/esp32c3_usb.conf b/tests/drivers/flash/common/socs/esp32c3_usb.conf new file mode 100644 index 00000000000..2bcf636958b --- /dev/null +++ b/tests/drivers/flash/common/socs/esp32c3_usb.conf @@ -0,0 +1 @@ +CONFIG_HEAP_MEM_POOL_SIZE=16384 diff --git a/tests/drivers/gpio/gpio_basic_api/socs/esp32c3_usb.overlay b/tests/drivers/gpio/gpio_basic_api/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..313d947d0c8 --- /dev/null +++ b/tests/drivers/gpio/gpio_basic_api/socs/esp32c3_usb.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + resources { + compatible = "test-gpio-basic-api"; + out-gpios = <&gpio0 4 0>; + in-gpios = <&gpio0 5 0>; + }; +}; diff --git a/tests/drivers/pwm/pwm_api/socs/esp32c3_usb.overlay b/tests/drivers/pwm/pwm_api/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..173073cecd1 --- /dev/null +++ b/tests/drivers/pwm/pwm_api/socs/esp32c3_usb.overlay @@ -0,0 +1,34 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include + +/ { + aliases { + pwm-0 = &ledc0; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = ; + output-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + channel0@0 { + reg = <0x0>; + timer = <0>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/CMakeLists.txt b/tests/drivers/pwm/pwm_gpio_loopback/CMakeLists.txt new file mode 100644 index 00000000000..7dfed72d0be --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/CMakeLists.txt @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: Apache-2.0 + +cmake_minimum_required(VERSION 3.20.0) +find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) +project(pwm_gpio) + +FILE(GLOB app_sources src/*.c) +target_sources(app PRIVATE ${app_sources}) diff --git a/tests/drivers/pwm/pwm_gpio_loopback/Kconfig b/tests/drivers/pwm/pwm_gpio_loopback/Kconfig new file mode 100644 index 00000000000..e88cbd0169f --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/Kconfig @@ -0,0 +1,29 @@ +# Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. +# SPDX-License-Identifier: Apache-2.0 + +mainmenu "PWM GPIO loopback test" + +source "Kconfig.zephyr" + +config SAMPLING_TIME + int "Sampling wait time (ms)" + default 50 + help + Time to wait for PWM edge sampling, in milliseconds. + +config SKIP_EDGE_NUM + int "Number of edges to skip before sampling PWM" + default 2 + help + Number of PWM edges to skip before starting sampling. + This parameter improves measurement precision as there can be significant + latency in the first sampled edge. + +config ALLOWED_DEVIATION + int "Allowed deviation (%) for PWM timing checks" + default 5 + range 0 100 + help + Maximum allowed deviation (%) from the programmed values for the test to be + considered a PASS. For example, if set to 5, the measured period or duty cycle + can deviate by up to 5% from the programmed values for the test to pass. diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay new file mode 100644 index 00000000000..8b5846df92d --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/nrf54h20dk_nrf54h20_cpuapp.overlay @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + * + * Test requires wire connection between: + * - PWM130 OUT[0] at P0.00 <-> GPIO input at P0.01 + * - PWM120 OUT[0] at P7.00 <-> GPIO input at P1.09 + * - PWM120 OUT[1] at P7.01 <-> GPIO input at P1.05 + */ + +/ { + zephyr,user { + pwms = <&pwm130 0 160000 PWM_POLARITY_NORMAL>, + <&pwm120 0 80000 PWM_POLARITY_NORMAL>, + <&pwm120 1 80000 PWM_POLARITY_NORMAL>; + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>, + <&gpio1 9 GPIO_ACTIVE_HIGH>, + <&gpio1 5 GPIO_ACTIVE_HIGH>; + }; +}; + +&pinctrl { + pwm130_default: pwm130_default { + group1 { + psels = ; + }; + }; + + pwm130_sleep: pwm130_sleep { + group1 { + psels = ; + low-power-enable; + }; + }; + + pwm120_default: pwm120_default { + group1 { + psels = , + ; + }; + }; + pwm120_sleep: pwm120_sleep { + group1 { + psels = , + ; + low-power-enable; + }; + }; +}; + +&gpio1 { + status = "okay"; +}; + +&pwm120 { + status = "okay"; + pinctrl-0 = <&pwm120_default>; + pinctrl-1 = <&pwm120_sleep>; + pinctrl-names = "default", "sleep"; + memory-regions = <&dma_fast_region>; +}; + +&dma_fast_region { + status = "okay"; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay b/tests/drivers/pwm/pwm_gpio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay new file mode 100644 index 00000000000..4ecece17892 --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/boards/nrf54l15dk_nrf54l15_cpuapp.overlay @@ -0,0 +1,14 @@ +/* + * Copyright (c) 2024 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + * + * Test requires jumper between: + * - PWM20 OUT[0] at P1.10 <-> GPIO input at P1.11 + */ + +/ { + zephyr,user { + pwms = <&pwm20 0 160000 PWM_POLARITY_NORMAL>; + gpios = <&gpio1 11 GPIO_ACTIVE_HIGH>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/prj.conf b/tests/drivers/pwm/pwm_gpio_loopback/prj.conf new file mode 100644 index 00000000000..f98ca9b0d16 --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/prj.conf @@ -0,0 +1,2 @@ +CONFIG_PWM=y +CONFIG_ZTEST=y diff --git a/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32_procpu.overlay b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32_procpu.overlay new file mode 100644 index 00000000000..0f727fe87e7 --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32_procpu.overlay @@ -0,0 +1,66 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2025 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include +#include + +/ { + zephyr,user { + /* GPIO input pins order must match PWM pinctrl config */ + gpios = <&gpio0 2 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 3 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 4 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 5 ESP32_GPIO_PIN_OUT_EN>; + + pwms = <&ledc0 0 160000 PWM_POLARITY_NORMAL>, + <&ledc0 5 80000 PWM_POLARITY_INVERTED>, + <&ledc0 9 1000000 PWM_POLARITY_NORMAL>, + <&ledc0 10 1000000 PWM_POLARITY_INVERTED>; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = , + , + , + ; + input-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel0@0 { + reg = <0x0>; + timer = <0>; + }; + + channel5@5 { + reg = <0x5>; + timer = <1>; + }; + + /* HS channel */ + channel9@9 { + reg = <0x9>; + timer = <0>; + }; + + /* share same timer with ch9 */ + channel10@a { + reg = <0xa>; + timer = <0>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c2.overlay b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c2.overlay new file mode 100644 index 00000000000..7901b44125c --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c2.overlay @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include +#include + +/ { + zephyr,user { + /* GPIO input pins order must match PWM pinctrl config */ + gpios = <&gpio0 2 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 3 ESP32_GPIO_PIN_OUT_EN>; + + pwms = <&ledc0 0 160000 PWM_POLARITY_NORMAL>, + <&ledc0 5 80000 PWM_POLARITY_INVERTED>; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = , + ; + input-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel0@0 { + reg = <0x0>; + timer = <0>; + }; + + channel5@5 { + reg = <0x5>; + timer = <1>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c3.overlay b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c3.overlay new file mode 100644 index 00000000000..7901b44125c --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c3.overlay @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include +#include + +/ { + zephyr,user { + /* GPIO input pins order must match PWM pinctrl config */ + gpios = <&gpio0 2 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 3 ESP32_GPIO_PIN_OUT_EN>; + + pwms = <&ledc0 0 160000 PWM_POLARITY_NORMAL>, + <&ledc0 5 80000 PWM_POLARITY_INVERTED>; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = , + ; + input-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel0@0 { + reg = <0x0>; + timer = <0>; + }; + + channel5@5 { + reg = <0x5>; + timer = <1>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c3_usb.overlay b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..7901b44125c --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c3_usb.overlay @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include +#include + +/ { + zephyr,user { + /* GPIO input pins order must match PWM pinctrl config */ + gpios = <&gpio0 2 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 3 ESP32_GPIO_PIN_OUT_EN>; + + pwms = <&ledc0 0 160000 PWM_POLARITY_NORMAL>, + <&ledc0 5 80000 PWM_POLARITY_INVERTED>; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = , + ; + input-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel0@0 { + reg = <0x0>; + timer = <0>; + }; + + channel5@5 { + reg = <0x5>; + timer = <1>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c6.overlay b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c6.overlay new file mode 100644 index 00000000000..7901b44125c --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32c6.overlay @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include +#include + +/ { + zephyr,user { + /* GPIO input pins order must match PWM pinctrl config */ + gpios = <&gpio0 2 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 3 ESP32_GPIO_PIN_OUT_EN>; + + pwms = <&ledc0 0 160000 PWM_POLARITY_NORMAL>, + <&ledc0 5 80000 PWM_POLARITY_INVERTED>; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = , + ; + input-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel0@0 { + reg = <0x0>; + timer = <0>; + }; + + channel5@5 { + reg = <0x5>; + timer = <1>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32s2.overlay b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32s2.overlay new file mode 100644 index 00000000000..7901b44125c --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32s2.overlay @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include +#include + +/ { + zephyr,user { + /* GPIO input pins order must match PWM pinctrl config */ + gpios = <&gpio0 2 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 3 ESP32_GPIO_PIN_OUT_EN>; + + pwms = <&ledc0 0 160000 PWM_POLARITY_NORMAL>, + <&ledc0 5 80000 PWM_POLARITY_INVERTED>; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = , + ; + input-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel0@0 { + reg = <0x0>; + timer = <0>; + }; + + channel5@5 { + reg = <0x5>; + timer = <1>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32s3_procpu.overlay b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32s3_procpu.overlay new file mode 100644 index 00000000000..7901b44125c --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/socs/esp32s3_procpu.overlay @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + * + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + */ + +#include +#include +#include + +/ { + zephyr,user { + /* GPIO input pins order must match PWM pinctrl config */ + gpios = <&gpio0 2 ESP32_GPIO_PIN_OUT_EN>, + <&gpio0 3 ESP32_GPIO_PIN_OUT_EN>; + + pwms = <&ledc0 0 160000 PWM_POLARITY_NORMAL>, + <&ledc0 5 80000 PWM_POLARITY_INVERTED>; + }; +}; + +&pinctrl { + ledc0_default: ledc0_default { + group1 { + pinmux = , + ; + input-enable; + }; + }; +}; + +&ledc0 { + pinctrl-0 = <&ledc0_default>; + pinctrl-names = "default"; + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + + channel0@0 { + reg = <0x0>; + timer = <0>; + }; + + channel5@5 { + reg = <0x5>; + timer = <1>; + }; +}; diff --git a/tests/drivers/pwm/pwm_gpio_loopback/src/main.c b/tests/drivers/pwm/pwm_gpio_loopback/src/main.c new file mode 100644 index 00000000000..16c2357f9b9 --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/src/main.c @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Generate PWM signals in different configurations and use a GPIO + * input pin to check the programmed timing. This test uses the systimer as + * benchmark, so it assumes the system tick is verified and precise. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static struct gpio_callback gpio_cb; + +#define TEST_PWM_COUNT DT_PROP_LEN(DT_PATH(zephyr_user), pwms) +#define TEST_PWM_CONFIG_ENTRY(idx, node_id) PWM_DT_SPEC_GET_BY_IDX(node_id, idx) +#define TEST_PWM_CONFIG_ARRAY(node_id) \ + { \ + LISTIFY(TEST_PWM_COUNT, TEST_PWM_CONFIG_ENTRY, (,), node_id) \ + } + +#define TEST_GPIO_COUNT DT_PROP_LEN(DT_PATH(zephyr_user), gpios) +#define TEST_GPIO_CONFIG_ENTRY(idx, node_id) GPIO_DT_SPEC_GET_BY_IDX(node_id, gpios, idx) +#define TEST_GPIO_CONFIG_ARRAY(node_id) \ + { \ + LISTIFY(TEST_GPIO_COUNT, TEST_GPIO_CONFIG_ENTRY, (,), node_id) \ + } + +static const struct pwm_dt_spec pwms_dt[] = TEST_PWM_CONFIG_ARRAY(DT_PATH(zephyr_user)); +static const struct gpio_dt_spec gpios_dt[] = TEST_GPIO_CONFIG_ARRAY(DT_PATH(zephyr_user)); + +static struct test_context { + uint32_t last_edge_time; + uint32_t high_time; + uint32_t low_time; + bool sampling_done; + uint8_t skip_cnt; +} ctx; + +static void gpio_edge_isr(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + int pin_state; + uint32_t current_time = k_cycle_get_32(); + + if (ctx.sampling_done || ++ctx.skip_cnt < CONFIG_SKIP_EDGE_NUM) { + return; + } + + if (!ctx.last_edge_time) { + /* init last_edge_time for first delta */ + ctx.last_edge_time = current_time; + return; + } + + uint32_t elapsed_time = current_time - ctx.last_edge_time; + + int pin = __builtin_ffs(pins) - 1; + + if (pin >= 0) { + pin_state = gpio_pin_get(dev, pin); + } else { + return; + } + + if (pin_state) { + ctx.low_time = elapsed_time; + } else { + ctx.high_time = elapsed_time; + } + + /* sampling is done when both high and low times were stored */ + if (ctx.high_time && ctx.low_time) { + ctx.sampling_done = true; + } + + ctx.last_edge_time = current_time; +} + +static void setup_edge_detect(void) +{ + ctx.last_edge_time = 0; + ctx.high_time = 0; + ctx.low_time = 0; + ctx.sampling_done = false; + ctx.skip_cnt = 0; +} + +static void config_gpio(const struct gpio_dt_spec *gpio_dt) +{ + /* Configure GPIO pin for edge detection */ + gpio_pin_configure_dt(gpio_dt, GPIO_INPUT); + + gpio_cb.pin_mask = BIT(gpio_dt->pin); + + gpio_init_callback(&gpio_cb, gpio_edge_isr, gpio_cb.pin_mask); + gpio_add_callback(gpio_dt->port, &gpio_cb); + gpio_pin_interrupt_configure(gpio_dt->port, gpio_dt->pin, GPIO_INT_EDGE_BOTH); +} + +static void unconfig_gpio(const struct gpio_dt_spec *gpio_dt) +{ + /* Disable interrupt for already tested channel */ + gpio_pin_interrupt_configure(gpio_dt->port, gpio_dt->pin, GPIO_INT_DISABLE); + + gpio_cb.pin_mask &= ~BIT(gpio_dt->pin); +} + +static bool check_range(float refval, float measval) +{ + float delta = fabsf(refval - measval); + float allowed_deviation = (refval * (float)CONFIG_ALLOWED_DEVIATION) / 100; + + return delta <= allowed_deviation; +} + +static int check_timing(const struct pwm_dt_spec *pwm_dt, const struct gpio_dt_spec *gpio_dt, + uint8_t duty) +{ + uint64_t cycles_s_sys, cycles_s_pwm; + int pin_state; + bool inverted = (pwm_dt->flags & PWM_POLARITY_INVERTED) ? true : false; + + /* reset parameters for edge detection */ + setup_edge_detect(); + + /* wait for sampling */ + k_sleep(K_MSEC(CONFIG_SAMPLING_TIME)); + + /* store pin state for duty == 100% or 0% checks */ + pin_state = gpio_pin_get_dt(gpio_dt); + + if (inverted) { + pin_state = !pin_state; + } + + cycles_s_sys = (uint64_t)sys_clock_hw_cycles_per_sec(); + pwm_get_cycles_per_sec(pwm_dt->dev, pwm_dt->channel, &cycles_s_pwm); + + /* sampling_done should be false for 0 and 100% duty (no switching) */ + TC_PRINT("Sampling done: %s\n", ctx.sampling_done ? "true" : "false"); + + if (duty == 100) { + if ((pin_state == 1) && !ctx.sampling_done) { + return TC_PASS; + } else { + return TC_FAIL; + } + } else if (duty == 0) { + if ((pin_state == 0) && !ctx.sampling_done) { + return TC_PASS; + } else { + return TC_FAIL; + } + } else { + uint32_t measured_period = ctx.high_time + ctx.low_time; + uint32_t measured_period_ns = (measured_period * 1e9) / cycles_s_sys; + uint32_t pulse_time = inverted ? ctx.low_time : ctx.high_time; + float measured_duty = (pulse_time * 100.0f) / measured_period; + uint32_t measured_duty_2p = (uint32_t)(measured_duty * 100); + uint32_t period_deviation_2p = + (uint64_t)10000 * abs(measured_period_ns - pwm_dt->period) / pwm_dt->period; + uint32_t duty_deviation_2p = + (uint32_t)10000 * fabs(measured_duty - (float)duty) / duty; + + TC_PRINT("Measured period: %u cycles, high: %u, low: %u [unit: systimer ticks]\n", + measured_period, ctx.high_time, ctx.low_time); + TC_PRINT("Measured period: %u ns, deviation: %d.%d%%\n", measured_period_ns, + period_deviation_2p / 100, period_deviation_2p % 100); + TC_PRINT("Measured duty: %d.%d%%, deviation: %d.%d%%\n", measured_duty_2p / 100, + measured_duty_2p % 100, duty_deviation_2p / 100, duty_deviation_2p % 100); + + /* Compare measured values with expected ones */ + if (check_range(measured_period_ns, pwm_dt->period) && + check_range(measured_duty, duty)) { + TC_PRINT("PWM output matches the programmed values\n"); + return TC_PASS; + } + + TC_PRINT("PWM output does NOT match the programmed values\n"); + return TC_FAIL; + } +} + +static void test_run(const struct pwm_dt_spec *pwm_dt, const struct gpio_dt_spec *gpio_dt, + uint8_t duty, bool set_channel) +{ + int result; + uint32_t pulse = (uint32_t)((pwm_dt->period * duty) / 100); + bool inverted = (pwm_dt->flags & PWM_POLARITY_INVERTED) ? true : false; + + TC_PRINT("Test case: [Channel: %" PRIu32 "] [Period: %" PRIu32 "] [Pulse: %" PRIu32 + "] [Inverted: %s]\n", + pwm_dt->channel, pwm_dt->period, pulse, inverted ? "Yes" : "No"); + + if (set_channel) { + result = pwm_set_dt(pwm_dt, pwm_dt->period, pulse); + zassert_false(result, "Failed on pwm_set() call"); + } + + config_gpio(gpio_dt); + + result = check_timing(pwm_dt, gpio_dt, duty); + + unconfig_gpio(gpio_dt); + + zassert_equal(result, TC_PASS, "Test case failed"); +} + +ZTEST(pwm_gpio_loopback, test_pwm) +{ + for (int i = 0; i < TEST_PWM_COUNT; i++) { + zassert_true(device_is_ready(pwms_dt[i].dev), "PWM device is not ready"); + zassert_true(device_is_ready(gpios_dt[i].port), "GPIO device is not ready"); + + /* Test case: [Duty: 25%] */ + test_run(&pwms_dt[i], &gpios_dt[i], 25, true); + + /* Test case: [Duty: 100%] */ + test_run(&pwms_dt[i], &gpios_dt[i], 100, true); + + /* Test case: [Duty: 0%] */ + test_run(&pwms_dt[i], &gpios_dt[i], 0, true); + + /* Test case: [Duty: 80%] */ + test_run(&pwms_dt[i], &gpios_dt[i], 80, true); + } +} + +ZTEST(pwm_gpio_loopback, test_pwm_cross) +{ + for (int i = 0; i < TEST_PWM_COUNT; i++) { + /* Test case: [Duty: 40%] */ + test_run(&pwms_dt[i], &gpios_dt[i], 40, true); + } + + /* Set all channels and check if they retain the original + * configuration without calling pwm_set again + */ + for (int i = 0; i < TEST_PWM_COUNT; i++) { + test_run(&pwms_dt[i], &gpios_dt[i], 40, false); + } +} + +ZTEST_SUITE(pwm_gpio_loopback, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml b/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml new file mode 100644 index 00000000000..1cc0dd5b797 --- /dev/null +++ b/tests/drivers/pwm/pwm_gpio_loopback/testcase.yaml @@ -0,0 +1,22 @@ +common: + depends_on: pwm + tags: + - drivers + - pwm + harness: ztest + harness_config: + fixture: gpio_loopback +tests: + drivers.pwm.gpio_loopback.esp: + platform_allow: + - esp32_devkitc_wrover/esp32/procpu + - esp8684_devkitm + - esp32c3_devkitm + - esp32c6_devkitc + - esp32s2_saola + - esp32s3_devkitm/esp32s3/procpu + + drivers.pwm.gpio_loopback.nrf: + platform_allow: + - nrf54h20dk/nrf54h20/cpuapp + - nrf54l15dk/nrf54l15/cpuapp diff --git a/tests/drivers/spi/spi_loopback/socs/esp32c3_usb.conf b/tests/drivers/spi/spi_loopback/socs/esp32c3_usb.conf new file mode 100644 index 00000000000..3438f794f66 --- /dev/null +++ b/tests/drivers/spi/spi_loopback/socs/esp32c3_usb.conf @@ -0,0 +1,2 @@ +CONFIG_SPI_ESP32_INTERRUPT=y +CONFIG_HEAP_MEM_POOL_SIZE=32768 diff --git a/tests/drivers/spi/spi_loopback/socs/esp32c3_usb.overlay b/tests/drivers/spi/spi_loopback/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..7436f9b6aec --- /dev/null +++ b/tests/drivers/spi/spi_loopback/socs/esp32c3_usb.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022 Kumar Gala + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + spim2_loopback: spim2_loopback { + group1 { + pinmux = ; + output-enable; /* Enable internal loopback */ + }; + group2 { + pinmux = ; + input-enable; /* Enable internal loopback */ + }; + group3 { + pinmux = , + ; + }; + }; +}; + +&spi2 { + slow@0 { + compatible = "test-spi-loopback-slow"; + reg = <0>; + spi-max-frequency = <500000>; + }; + fast@0 { + compatible = "test-spi-loopback-fast"; + reg = <0>; + spi-max-frequency = <16000000>; + }; +}; + +&spi2 { + #address-cells = <1>; + #size-cells = <0>; + dma-enabled; + pinctrl-0 = <&spim2_loopback>; + pinctrl-names = "default"; + status = "okay"; +}; diff --git a/tests/drivers/uart/uart_async_api/socs/esp32c3_usb.conf b/tests/drivers/uart/uart_async_api/socs/esp32c3_usb.conf new file mode 100644 index 00000000000..76f7644d896 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/socs/esp32c3_usb.conf @@ -0,0 +1,2 @@ +CONFIG_HEAP_MEM_POOL_SIZE=32768 +CONFIG_DMA=y diff --git a/tests/drivers/uart/uart_async_api/socs/esp32c3_usb.overlay b/tests/drivers/uart/uart_async_api/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..3582e7dcf94 --- /dev/null +++ b/tests/drivers/uart/uart_async_api/socs/esp32c3_usb.overlay @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2022 Espressif Systems (Shanghai) Co., Ltd. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart1_test: uart1_test { + group1 { + pinmux = ; + input-enable; + }; + group2 { + pinmux = ; + output-enable; + }; + }; +}; + +dut: &uart1 { + status = "okay"; + current-speed = <115200>; + pinctrl-0 = <&uart1_test>; + pinctrl-names = "default"; + dmas = <&dma 0>, <&dma 1>; + dma-names = "rx", "tx"; +}; + +&dma { + status = "okay"; +}; diff --git a/tests/drivers/uart/uart_elementary/socs/esp32c3_usb.overlay b/tests/drivers/uart/uart_elementary/socs/esp32c3_usb.overlay new file mode 100644 index 00000000000..d2df77b7ebc --- /dev/null +++ b/tests/drivers/uart/uart_elementary/socs/esp32c3_usb.overlay @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2024 Espressif Systems (Shanghai) Co., Ltd. + * SPDX-License-Identifier: Apache-2.0 + */ + +&pinctrl { + uart1_test: uart1_test { + group1 { + pinmux = , + ; + input-enable; + output-high; + }; + group2 { + pinmux = , + ; + output-enable; + bias-pull-up; + }; + }; +}; + +dut: &uart1 { + status = "okay"; + pinctrl-0 = <&uart1_test>; + pinctrl-names = "default"; + current-speed = <115200>; +};