From 43d99f8364173a390637da474d81a53eb62840c7 Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 27 Oct 2022 17:36:31 +0800 Subject: [PATCH] twai: migrate example test to pytest --- .gitlab/ci/target-test.yml | 28 +++--- docs/docs_not_updated/esp32c2.txt | 0 examples/peripherals/.build-test-rules.yml | 30 +++--- .../gpio/generic_gpio/example_test.py | 20 ---- .../pytest_generic_gpio_example.py | 16 ++++ .../twai/twai_alert_and_recovery/README.md | 20 ++-- .../twai_alert_and_recovery/example_test.py | 21 ----- .../main/Kconfig.projbuild | 8 +- .../twai_alert_and_recovery_example_main.c | 25 ++--- .../pytest_twai_alert_recovery_example.py | 12 +++ .../peripherals/twai/twai_network/README.md | 24 ++--- .../twai/twai_network/example_test.py | 74 --------------- .../pytest_twai_network_example.py | 92 +++++++++++++++++++ .../main/Kconfig.projbuild | 8 +- .../twai_network_example_listen_only_main.c | 13 +-- .../main/Kconfig.projbuild | 8 +- .../main/twai_network_example_master_main.c | 13 +-- .../twai_network_slave/main/Kconfig.projbuild | 8 +- .../main/twai_network_example_slave_main.c | 13 +-- .../peripherals/twai/twai_self_test/README.md | 16 ++-- .../twai/twai_self_test/example_test.py | 22 ----- .../twai_self_test/main/Kconfig.projbuild | 8 +- .../main/twai_self_test_example_main.c | 18 ++-- .../pytest_twai_self_test_example.py | 12 +++ pytest.ini | 2 + tools/ci/check_copyright_ignore.txt | 8 -- 26 files changed, 237 insertions(+), 282 deletions(-) delete mode 100644 docs/docs_not_updated/esp32c2.txt delete mode 100644 examples/peripherals/gpio/generic_gpio/example_test.py create mode 100644 examples/peripherals/gpio/generic_gpio/pytest_generic_gpio_example.py delete mode 100644 examples/peripherals/twai/twai_alert_and_recovery/example_test.py create mode 100644 examples/peripherals/twai/twai_alert_and_recovery/pytest_twai_alert_recovery_example.py delete mode 100644 examples/peripherals/twai/twai_network/example_test.py create mode 100644 examples/peripherals/twai/twai_network/pytest_twai_network_example.py delete mode 100644 examples/peripherals/twai/twai_self_test/example_test.py create mode 100644 examples/peripherals/twai/twai_self_test/pytest_twai_self_test_example.py diff --git a/.gitlab/ci/target-test.yml b/.gitlab/ci/target-test.yml index fa36c001c0..ae1b099c1b 100644 --- a/.gitlab/ci/target-test.yml +++ b/.gitlab/ci/target-test.yml @@ -60,6 +60,22 @@ example_test_pytest_esp32_ir_transceiver: - build_pytest_examples_esp32 tags: [ esp32, ir_transceiver ] +example_test_pytest_esp32_twai_transceiver: + extends: + - .pytest_examples_dir_template + - .rules:test:example_test-esp32 + needs: + - build_pytest_examples_esp32 + tags: [ esp32, twai_transceiver ] + +example_test_pytest_esp32_twai_network: + extends: + - .pytest_examples_dir_template + - .rules:test:example_test-esp32 + needs: + - build_pytest_examples_esp32 + tags: [ esp32, twai_network ] + example_test_pytest_esp32s2_generic: extends: - .pytest_examples_dir_template @@ -752,18 +768,6 @@ example_test_ethernet_router: - ESP32 - Example_SDIO -example_test_004A: - extends: .example_test_esp32_template - tags: - - ESP32 - - Example_TWAI1 - -example_test_004B: - extends: .example_test_esp32_template - tags: - - ESP32 - - Example_TWAI2 - example_test_005: extends: - .example_test_esp32_template diff --git a/docs/docs_not_updated/esp32c2.txt b/docs/docs_not_updated/esp32c2.txt deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/examples/peripherals/.build-test-rules.yml b/examples/peripherals/.build-test-rules.yml index f95c82daf5..620db7212f 100644 --- a/examples/peripherals/.build-test-rules.yml +++ b/examples/peripherals/.build-test-rules.yml @@ -10,12 +10,6 @@ examples/peripherals/dac: disable: - if: SOC_DAC_SUPPORTED != 1 -examples/peripherals/gpio/generic_gpio: - disable_test: - - if: IDF_TARGET != "esp32" - temporary: true - reason: lack of runners - examples/peripherals/gpio/matrix_keyboard: enable: - if: IDF_TARGET == "esp32s2" @@ -169,27 +163,27 @@ examples/peripherals/touch_sensor/touch_sensor_v2: disable: - if: SOC_TOUCH_VERSION_2 != 1 -examples/peripherals/twai: - disable: - - if: SOC_TWAI_SUPPORTED != 1 - examples/peripherals/twai/twai_alert_and_recovery: disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + - if: SOC_TWAI_SUPPORTED != 1 disable_test: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3"] + - if: IDF_TARGET not in ["esp32"] + temporary: true + reason: lack of runners + +examples/peripherals/twai/twai_network: + disable: + - if: SOC_TWAI_SUPPORTED != 1 + disable_test: + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners examples/peripherals/twai/twai_self_test: disable: - - if: IDF_TARGET == "esp32c2" - temporary: true - reason: target esp32c2 is not supported yet + - if: SOC_TWAI_SUPPORTED != 1 disable_test: - - if: IDF_TARGET in ["esp32c3", "esp32s2", "esp32s3"] + - if: IDF_TARGET not in ["esp32"] temporary: true reason: lack of runners diff --git a/examples/peripherals/gpio/generic_gpio/example_test.py b/examples/peripherals/gpio/generic_gpio/example_test.py deleted file mode 100644 index aec3c22510..0000000000 --- a/examples/peripherals/gpio/generic_gpio/example_test.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python - -from __future__ import division, print_function, unicode_literals - -import ttfw_idf - - -@ttfw_idf.idf_example_test(env_tag='Example_TWAI1', target=['esp32', 'esp32s2'], ci_target=['esp32']) -def test_examples_gpio(env, extra_data): - app_name = 'gpio' - dut = env.get_dut(app_name, 'examples/peripherals/gpio/generic_gpio') - dut.start_app() - res = dut.expect(ttfw_idf.MINIMUM_FREE_HEAP_SIZE_RE) - if not res: - raise ValueError('Maximum heap size info not found') - ttfw_idf.print_heap_size(app_name, dut.app.config_name, dut.TARGET, res[0]) - - -if __name__ == '__main__': - test_examples_gpio() diff --git a/examples/peripherals/gpio/generic_gpio/pytest_generic_gpio_example.py b/examples/peripherals/gpio/generic_gpio/pytest_generic_gpio_example.py new file mode 100644 index 0000000000..076a227db2 --- /dev/null +++ b/examples/peripherals/gpio/generic_gpio/pytest_generic_gpio_example.py @@ -0,0 +1,16 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +from typing import Callable + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.supported_targets +@pytest.mark.generic +def test_generic_gpio_example( + dut: Dut, log_minimum_free_heap_size: Callable[..., None] +) -> None: + log_minimum_free_heap_size() + dut.expect(r'cnt: \d+') diff --git a/examples/peripherals/twai/twai_alert_and_recovery/README.md b/examples/peripherals/twai/twai_alert_and_recovery/README.md index 9ba4b9d2c9..0fc4eeccc1 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/README.md +++ b/examples/peripherals/twai/twai_alert_and_recovery/README.md @@ -17,25 +17,23 @@ Note: If you don't have an external transceiver, this example can still be run b ### Configure the project -* Set the target of the build (where `{IDF_TARGET}` stands for the target chip such as `esp32`, `esp32s2`, `esp32s2` or `esp32c3`). +* Set the target of the build (where `{IDF_TARGET}` stands for the target chip such as `esp32`, `esp32c3`). * Then run `menuconfig` to configure the example. -``` +```sh idf.py set-target {IDF_TARGET} idf.py menuconfig ``` * Under `Example Configuration`, configure the pin assignments using the options `TX GPIO Number` and `RX GPIO Number` according to how the target was connected to the transceiver. By default, `TX GPIO Number` and `RX GPIO Number` are set to the following values: - * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively - * On the ESP32-S2, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively - * On the ESP32-S3, `TX GPIO Number` and `RX GPIO Number` default to `4` and `5` respectively - * On the ESP32-C3, `TX GPIO Number` and `RX GPIO Number` default to `2` and `3` respectively + * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively + * On other chips, `TX GPIO Number` and `RX GPIO Number` default to `0` and `2` respectively ### Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: -``` +```sh idf.py -p PORT flash monitor ``` @@ -47,7 +45,7 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ## Example Output -``` +```text I (330) TWAI Alert and Recovery: Driver installed I (340) TWAI Alert and Recovery: Driver started I (340) TWAI Alert and Recovery: Starting transmissions @@ -68,19 +66,19 @@ I (7350) TWAI Alert and Recovery: Driver uninstalled ## Troubleshooting -``` +```text I (3350) TWAI Alert and Recovery: Trigger errors ``` If the example does not progress pass triggering errors, check that the target is correctly connected to the transceiver. -``` +```text I (3350) TWAI Alert and Recovery: Trigger errors I (3650) TWAI Alert and Recovery: Surpassed Error Warning Limit I (3650) TWAI Alert and Recovery: Entered Error Passive state ``` -If the example is able to trigger errors but does not enter the bus off state (i.e., stays in the error passive state), check that the triggering of the bit error is properly set to the examples operating bit rate. By default, the example runs at a bit rate of 125kbits/sec, and the bit error should be triggered after the arbitration phase of each transmitted message. +If the example is able to trigger errors but does not enter the bus off state (i.e., stays in the error passive state), check that the triggering of the bit error is properly set to the examples operating bit rate. By default, the example runs at a bit rate of 25kbits/sec, and the bit error should be triggered after the arbitration phase of each transmitted message. ## Example Breakdown diff --git a/examples/peripherals/twai/twai_alert_and_recovery/example_test.py b/examples/peripherals/twai/twai_alert_and_recovery/example_test.py deleted file mode 100644 index 1554d725fc..0000000000 --- a/examples/peripherals/twai/twai_alert_and_recovery/example_test.py +++ /dev/null @@ -1,21 +0,0 @@ -# Need Python 3 string formatting functions -from __future__ import print_function - -import ttfw_idf - -# TWAI Self Test Example constants -STR_EXPECT = ('TWAI Alert and Recovery: Driver installed', 'TWAI Alert and Recovery: Driver uninstalled') -EXPECT_TIMEOUT = 20 - - -@ttfw_idf.idf_example_test(env_tag='Example_TWAI1') -def test_twai_alert_and_recovery_example(env, extra_data): - dut = env.get_dut('dut1', 'examples/peripherals/twai/twai_alert_and_recovery', dut_class=ttfw_idf.ESP32DUT) - dut.start_app() - - for string in STR_EXPECT: - dut.expect(string, timeout=EXPECT_TIMEOUT) - - -if __name__ == '__main__': - test_twai_alert_and_recovery_example() diff --git a/examples/peripherals/twai/twai_alert_and_recovery/main/Kconfig.projbuild b/examples/peripherals/twai/twai_alert_and_recovery/main/Kconfig.projbuild index 1f9d58c4dd..1688672cec 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_alert_and_recovery/main/Kconfig.projbuild @@ -5,10 +5,8 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX - default 2 if IDF_TARGET_ESP32C3 - default 20 if IDF_TARGET_ESP32S2 default 21 if IDF_TARGET_ESP32 - default 4 if IDF_TARGET_ESP32S3 + default 0 help This option selects the GPIO pin used for the TX signal. Connect the TX signal to your transceiver. @@ -16,10 +14,8 @@ menu "Example Configuration" config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX - default 3 if IDF_TARGET_ESP32C3 - default 21 if IDF_TARGET_ESP32S2 default 22 if IDF_TARGET_ESP32 - default 5 if IDF_TARGET_ESP32S3 + default 2 help This option selects the GPIO pin used for the RX signal. Connect the RX signal to your transceiver. diff --git a/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c b/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c index a02f2674b0..fa740a8ce0 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c +++ b/examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c @@ -1,11 +1,8 @@ -/* TWAI Alert and Recovery Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ /* * The following example demonstrates how to use the alert and bus recovery @@ -29,7 +26,7 @@ #include "driver/twai.h" #include "esp_rom_gpio.h" #include "esp_rom_sys.h" -#include "soc/gpio_sig_map.h" // For TWAI_TX_IDX +#include "soc/gpio_sig_map.h" // For GPIO matrix signal index /* --------------------- Definitions and static variables ------------------ */ //Example Configuration @@ -41,6 +38,12 @@ #define ERR_PERIOD_US 80 //Approximate time for two bits at 25KBPS #define EXAMPLE_TAG "TWAI Alert and Recovery" +#if CONFIG_IDF_TARGET_ESP32C6 +#define TWAI_TX_SIGNAL_IDX TWAI0_TX_IDX +#else +#define TWAI_TX_SIGNAL_IDX TWAI_TX_IDX +#endif + static const twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL(); static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_25KBITS(); static const twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_GPIO_NUM, RX_GPIO_NUM, TWAI_MODE_NO_ACK); @@ -56,10 +59,10 @@ static void invert_tx_bits(bool enable) { if (enable) { //Inverts output of TX to trigger errors - esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, TWAI_TX_IDX, true, false); + esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, TWAI_TX_SIGNAL_IDX, true, false); } else { //Returns TX to default settings - esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, TWAI_TX_IDX, false, false); + esp_rom_gpio_connect_out_signal(TX_GPIO_NUM, TWAI_TX_SIGNAL_IDX, false, false); } } diff --git a/examples/peripherals/twai/twai_alert_and_recovery/pytest_twai_alert_recovery_example.py b/examples/peripherals/twai/twai_alert_and_recovery/pytest_twai_alert_recovery_example.py new file mode 100644 index 0000000000..200fb60709 --- /dev/null +++ b/examples/peripherals/twai/twai_alert_and_recovery/pytest_twai_alert_recovery_example.py @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.twai_transceiver +def test_twai_alert_recovery_example(dut: Dut) -> None: + dut.expect_exact('TWAI Alert and Recovery: Driver installed') + dut.expect_exact('TWAI Alert and Recovery: Driver uninstalled') diff --git a/examples/peripherals/twai/twai_network/README.md b/examples/peripherals/twai/twai_network/README.md index 4640390dcc..84a60b77eb 100644 --- a/examples/peripherals/twai/twai_network/README.md +++ b/examples/peripherals/twai/twai_network/README.md @@ -18,7 +18,7 @@ This example requires at least two targets (e.g., an ESP32 or ESP32-S2) to act a The following diagram illustrates an example network: -``` +```text ---------- ---------- -------------- | Master | | Slave | | Listen Only | | | | | | | @@ -47,26 +47,23 @@ Note: If you don't have an external transceiver, you can still run the [TWAI Sel For each node in the TWAI network (i.e., Master, Slave, Listen Only)... -* Set the target of the build (where `{IDF_TARGET}` stands for the target chip such as `eszp32` or `esp32s2`). +* Set the target of the build (where `{IDF_TARGET}` stands for the target chip such as `esp32` or `esp32s2`). * Then run `menuconfig` to configure the example. -``` +```sh idf.py set-target {IDF_TARGET} idf.py menuconfig ``` * Under `Example Configuration`, configure the pin assignments using the options `TX GPIO Number` and `RX GPIO Number` according to how the target was connected to the transceiver. By default, `TX GPIO Number` and `RX GPIO Number` are set to the following values: - * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively - * On the ESP32-S2, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively - * On the ESP32-S3, `TX GPIO Number` and `RX GPIO Number` default to `4` and `5` respectively - * On the ESP32-C3, `TX GPIO Number` and `RX GPIO Number` default to `2` and `3` respectively - + * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively + * On other chips, `TX GPIO Number` and `RX GPIO Number` default to `0` and `2` respectively ### Build and Flash For each node, build the project and flash it to the board, then run monitor tool to view serial output: -``` +```sh idf.py -p PORT flash monitor ``` @@ -79,7 +76,8 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ## Example Output Network Master -``` + +```text I (345) TWAI Master: Driver installed I (345) TWAI Master: Driver started I (345) TWAI Master: Transmitting ping @@ -109,7 +107,8 @@ I (14575) TWAI Master: Driver uninstalled ``` Network Slave -``` + +```text Slave starting in 3 Slave starting in 2 Slave starting in 1 @@ -142,7 +141,8 @@ I (18292) TWAI Slave: Driver uninstalled ``` Network Listen Only -``` + +```text I (326) TWAI Listen Only: Driver installed I (326) TWAI Listen Only: Driver started I (366) TWAI Listen Only: Received master ping diff --git a/examples/peripherals/twai/twai_network/example_test.py b/examples/peripherals/twai/twai_network/example_test.py deleted file mode 100644 index 69a2515b31..0000000000 --- a/examples/peripherals/twai/twai_network/example_test.py +++ /dev/null @@ -1,74 +0,0 @@ -# Need Python 3 string formatting functions -from __future__ import print_function - -from threading import Thread - -import ttfw_idf - -# Define tuple of strings to expect for each DUT. -master_expect = ('TWAI Master: Driver installed', 'TWAI Master: Driver uninstalled') -slave_expect = ('TWAI Slave: Driver installed', 'TWAI Slave: Driver uninstalled') -listen_only_expect = ('TWAI Listen Only: Driver installed', 'TWAI Listen Only: Driver uninstalled') - - -def dut_thread_callback(**kwargs): - # Parse keyword arguments - dut = kwargs['dut'] # Get DUT from kwargs - expected = kwargs['expected'] - result = kwargs['result'] # Get result[out] from kwargs. MUST be of mutable type e.g. list - - # Must reset again as flashing during start_app will reset multiple times, causing unexpected results - dut.reset() - - for string in expected: - dut.expect(string, 20) - - # Mark thread has run to completion without any exceptions - result[0] = True - - -@ttfw_idf.idf_example_test(env_tag='Example_TWAI2', ignore=True) -def test_twai_network_example(env, extra_data): - - # Get device under test. "dut1", "dut2", and "dut3" must be properly defined in EnvConfig - dut_master = env.get_dut('dut1', 'examples/peripherals/twai/twai_network/twai_network_master', - dut_class=ttfw_idf.ESP32DUT) - dut_slave = env.get_dut('dut2', 'examples/peripherals/twai/twai_network/twai_network_slave', - dut_class=ttfw_idf.ESP32DUT) - dut_listen_only = env.get_dut('dut3', 'examples/peripherals/twai/twai_network/twai_network_listen_only', - dut_class=ttfw_idf.ESP32DUT) - - # Flash app onto each DUT, each DUT is reset again at the start of each thread - dut_master.start_app() - dut_slave.start_app() - dut_listen_only.start_app() - - # Create dict of keyword arguments for each dut - results = [[False], [False], [False]] - master_kwargs = {'dut': dut_master, 'result': results[0], 'expected': master_expect} - slave_kwargs = {'dut': dut_slave, 'result': results[1], 'expected': slave_expect} - listen_only_kwargs = {'dut': dut_listen_only, 'result': results[2], 'expected': listen_only_expect} - - # Create thread for each dut - dut_master_thread = Thread(target=dut_thread_callback, name='Master Thread', kwargs=master_kwargs) - dut_slave_thread = Thread(target=dut_thread_callback, name='Slave Thread', kwargs=slave_kwargs) - dut_listen_only_thread = Thread(target=dut_thread_callback, name='Listen Only Thread', kwargs=listen_only_kwargs) - - # Start each thread - dut_listen_only_thread.start() - dut_master_thread.start() - dut_slave_thread.start() - - # Wait for threads to complete - dut_listen_only_thread.join() - dut_master_thread.join() - dut_slave_thread.join() - - # check each thread ran to completion - for result in results: - if result[0] is not True: - raise Exception('One or more threads did not run successfully') - - -if __name__ == '__main__': - test_twai_network_example() diff --git a/examples/peripherals/twai/twai_network/pytest_twai_network_example.py b/examples/peripherals/twai/twai_network/pytest_twai_network_example.py new file mode 100644 index 0000000000..6eb3f43327 --- /dev/null +++ b/examples/peripherals/twai/twai_network/pytest_twai_network_example.py @@ -0,0 +1,92 @@ +# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import os.path +from threading import Thread +from typing import Tuple + +import pytest +from pytest_embedded import Dut + +# Define tuple of strings to expect for each DUT. +master_expect = ('TWAI Master: Driver installed', 'TWAI Master: Driver uninstalled') +slave_expect = ('TWAI Slave: Driver installed', 'TWAI Slave: Driver uninstalled') +listen_only_expect = ( + 'TWAI Listen Only: Driver installed', + 'TWAI Listen Only: Driver uninstalled', +) + + +def dut_thread_callback(**kwargs) -> None: # type: ignore + # Parse keyword arguments + dut = kwargs['dut'] # Get DUT from kwargs + expected = kwargs['expected'] + result = kwargs[ + 'result' + ] # Get result[out] from kwargs. MUST be of mutable type e.g. list + + # Must reset again as flashing during start_app will reset multiple times, causing unexpected results + dut.reset() + + for string in expected: + dut.expect(string, 20) + + # Mark thread has run to completion without any exceptions + result[0] = True + + +@pytest.mark.esp32 +@pytest.mark.skip(reason="there's not a good approach to sync multiple DUTs") +@pytest.mark.twai_network +@pytest.mark.parametrize( + 'count, app_path', + [ + ( + 3, + f'{os.path.join(os.path.dirname(__file__), "twai_network_master")}|' + f'{os.path.join(os.path.dirname(__file__), "twai_network_slave")}|' + f'{os.path.join(os.path.dirname(__file__), "twai_network_listen_only")}', + ), + ], + indirect=True, +) +def test_twai_network_example(dut: Tuple[Dut, Dut, Dut]) -> None: + dut_master = dut[0] + dut_slave = dut[1] + dut_listen_only = dut[2] + + # Create dict of keyword arguments for each dut + results = [[False], [False], [False]] + master_kwargs = {'dut': dut_master, 'result': results[0], 'expected': master_expect} + slave_kwargs = {'dut': dut_slave, 'result': results[1], 'expected': slave_expect} + listen_only_kwargs = { + 'dut': dut_listen_only, + 'result': results[2], + 'expected': listen_only_expect, + } + + # Create thread for each dut + dut_master_thread = Thread( + target=dut_thread_callback, name='Master Thread', kwargs=master_kwargs + ) + dut_slave_thread = Thread( + target=dut_thread_callback, name='Slave Thread', kwargs=slave_kwargs + ) + dut_listen_only_thread = Thread( + target=dut_thread_callback, name='Listen Only Thread', kwargs=listen_only_kwargs + ) + + # Start each thread + dut_listen_only_thread.start() + dut_master_thread.start() + dut_slave_thread.start() + + # Wait for threads to complete + dut_listen_only_thread.join() + dut_master_thread.join() + dut_slave_thread.join() + + # check each thread ran to completion + for result in results: + if result[0] is not True: + raise Exception('One or more threads did not run successfully') diff --git a/examples/peripherals/twai/twai_network/twai_network_listen_only/main/Kconfig.projbuild b/examples/peripherals/twai/twai_network/twai_network_listen_only/main/Kconfig.projbuild index e71c1bf058..14a2c83965 100644 --- a/examples/peripherals/twai/twai_network/twai_network_listen_only/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_network/twai_network_listen_only/main/Kconfig.projbuild @@ -2,20 +2,16 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" - default 2 if IDF_TARGET_ESP32C3 - default 20 if IDF_TARGET_ESP32S2 default 21 if IDF_TARGET_ESP32 - default 4 if IDF_TARGET_ESP32S3 + default 0 help This option selects the GPIO pin used for the TX signal. Connect the TX signal to your transceiver. config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" - default 3 if IDF_TARGET_ESP32C3 - default 21 if IDF_TARGET_ESP32S2 default 22 if IDF_TARGET_ESP32 - default 5 if IDF_TARGET_ESP32S3 + default 2 help This option selects the GPIO pin used for the RX signal. Connect the RX signal to your transceiver. diff --git a/examples/peripherals/twai/twai_network/twai_network_listen_only/main/twai_network_example_listen_only_main.c b/examples/peripherals/twai/twai_network/twai_network_listen_only/main/twai_network_example_listen_only_main.c index 0f6b3b7bab..3e2e02994b 100644 --- a/examples/peripherals/twai/twai_network/twai_network_listen_only/main/twai_network_example_listen_only_main.c +++ b/examples/peripherals/twai/twai_network/twai_network_listen_only/main/twai_network_example_listen_only_main.c @@ -1,11 +1,8 @@ -/* TWAI Network Listen Only Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ /* * The following example demonstrates a Listen Only node in a TWAI network. The diff --git a/examples/peripherals/twai/twai_network/twai_network_master/main/Kconfig.projbuild b/examples/peripherals/twai/twai_network/twai_network_master/main/Kconfig.projbuild index e71c1bf058..14a2c83965 100644 --- a/examples/peripherals/twai/twai_network/twai_network_master/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_network/twai_network_master/main/Kconfig.projbuild @@ -2,20 +2,16 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" - default 2 if IDF_TARGET_ESP32C3 - default 20 if IDF_TARGET_ESP32S2 default 21 if IDF_TARGET_ESP32 - default 4 if IDF_TARGET_ESP32S3 + default 0 help This option selects the GPIO pin used for the TX signal. Connect the TX signal to your transceiver. config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" - default 3 if IDF_TARGET_ESP32C3 - default 21 if IDF_TARGET_ESP32S2 default 22 if IDF_TARGET_ESP32 - default 5 if IDF_TARGET_ESP32S3 + default 2 help This option selects the GPIO pin used for the RX signal. Connect the RX signal to your transceiver. diff --git a/examples/peripherals/twai/twai_network/twai_network_master/main/twai_network_example_master_main.c b/examples/peripherals/twai/twai_network/twai_network_master/main/twai_network_example_master_main.c index e1a7007435..5d1b4b0c45 100644 --- a/examples/peripherals/twai/twai_network/twai_network_master/main/twai_network_example_master_main.c +++ b/examples/peripherals/twai/twai_network/twai_network_master/main/twai_network_example_master_main.c @@ -1,11 +1,8 @@ -/* TWAI Network Master Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ /* * The following example demonstrates a master node in a TWAI network. The master diff --git a/examples/peripherals/twai/twai_network/twai_network_slave/main/Kconfig.projbuild b/examples/peripherals/twai/twai_network/twai_network_slave/main/Kconfig.projbuild index e71c1bf058..14a2c83965 100644 --- a/examples/peripherals/twai/twai_network/twai_network_slave/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_network/twai_network_slave/main/Kconfig.projbuild @@ -2,20 +2,16 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" - default 2 if IDF_TARGET_ESP32C3 - default 20 if IDF_TARGET_ESP32S2 default 21 if IDF_TARGET_ESP32 - default 4 if IDF_TARGET_ESP32S3 + default 0 help This option selects the GPIO pin used for the TX signal. Connect the TX signal to your transceiver. config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" - default 3 if IDF_TARGET_ESP32C3 - default 21 if IDF_TARGET_ESP32S2 default 22 if IDF_TARGET_ESP32 - default 5 if IDF_TARGET_ESP32S3 + default 2 help This option selects the GPIO pin used for the RX signal. Connect the RX signal to your transceiver. diff --git a/examples/peripherals/twai/twai_network/twai_network_slave/main/twai_network_example_slave_main.c b/examples/peripherals/twai/twai_network/twai_network_slave/main/twai_network_example_slave_main.c index 836ee61291..61b88ae30f 100644 --- a/examples/peripherals/twai/twai_network/twai_network_slave/main/twai_network_example_slave_main.c +++ b/examples/peripherals/twai/twai_network/twai_network_slave/main/twai_network_example_slave_main.c @@ -1,11 +1,8 @@ -/* TWAI Network Slave Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ /* * The following example demonstrates a slave node in a TWAI network. The slave diff --git a/examples/peripherals/twai/twai_self_test/README.md b/examples/peripherals/twai/twai_self_test/README.md index bab06eec9a..de88eb0c0d 100644 --- a/examples/peripherals/twai/twai_self_test/README.md +++ b/examples/peripherals/twai/twai_self_test/README.md @@ -17,25 +17,23 @@ Note: If you don't have an external transceiver, this example can still be run b ### Configure the project -* Set the target of the build (where `{IDF_TARGET}` stands for the target chip such as `eszp32` or `esp32s2`). +* Set the target of the build (where `{IDF_TARGET}` stands for the target chip such as `esp32` or `esp32s2`). * Then run `menuconfig` to configure the example. -``` +```sh idf.py set-target {IDF_TARGET} idf.py menuconfig ``` * Under `Example Configuration`, configure the pin assignments using the options `TX GPIO Number` and `RX GPIO Number` according to how the target was connected to the transceiver. By default, `TX GPIO Number` and `RX GPIO Number` are set to the following values: - * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively - * On the ESP32-S2, `TX GPIO Number` and `RX GPIO Number` default to `20` and `21` respectively - * On the ESP32-S3, `TX GPIO Number` and `RX GPIO Number` default to `4` and `5` respectively - * On the ESP32-C3, `TX GPIO Number` and `RX GPIO Number` default to `2` and `3` respectively + * On the ESP32, `TX GPIO Number` and `RX GPIO Number` default to `21` and `22` respectively + * On other chips, `TX GPIO Number` and `RX GPIO Number` default to `0` and `2` respectively ### Build and Flash Build the project and flash it to the board, then run monitor tool to view serial output: -``` +```sh idf.py -p PORT flash monitor ``` @@ -47,7 +45,7 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui ## Example Output -``` +```text I (345) TWAI Self Test: Driver installed I (345) TWAI Self Test: Driver started I (355) TWAI Self Test: Msg received - Data = 0 @@ -69,7 +67,7 @@ I (3615) TWAI Self Test: Driver uninstalled ## Troubleshooting -``` +```text I (345) TWAI Self Test: Driver installed I (345) TWAI Self Test: Driver started ``` diff --git a/examples/peripherals/twai/twai_self_test/example_test.py b/examples/peripherals/twai/twai_self_test/example_test.py deleted file mode 100644 index 6b06f1a049..0000000000 --- a/examples/peripherals/twai/twai_self_test/example_test.py +++ /dev/null @@ -1,22 +0,0 @@ -# Need Python 3 string formatting functions -from __future__ import print_function - -import ttfw_idf - -# TWAI Self Test Example constants -STR_EXPECT = ('TWAI Self Test: Driver installed', 'TWAI Self Test: Driver uninstalled') -EXPECT_TIMEOUT = 20 - - -@ttfw_idf.idf_example_test(env_tag='Example_TWAI1') -def test_twai_self_test_example(env, extra_data): - # Get device under test, flash and start example. "dut1" must be defined in EnvConfig - dut = env.get_dut('dut1', 'examples/peripherals/twai/twai_self_test', dut_class=ttfw_idf.ESP32DUT) - dut.start_app() - - for string in STR_EXPECT: - dut.expect(string, timeout=EXPECT_TIMEOUT) - - -if __name__ == '__main__': - test_twai_self_test_example() diff --git a/examples/peripherals/twai/twai_self_test/main/Kconfig.projbuild b/examples/peripherals/twai/twai_self_test/main/Kconfig.projbuild index 1f9d58c4dd..1688672cec 100644 --- a/examples/peripherals/twai/twai_self_test/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_self_test/main/Kconfig.projbuild @@ -5,10 +5,8 @@ menu "Example Configuration" config EXAMPLE_TX_GPIO_NUM int "TX GPIO number" range ENV_GPIO_RANGE_MIN ENV_GPIO_OUT_RANGE_MAX - default 2 if IDF_TARGET_ESP32C3 - default 20 if IDF_TARGET_ESP32S2 default 21 if IDF_TARGET_ESP32 - default 4 if IDF_TARGET_ESP32S3 + default 0 help This option selects the GPIO pin used for the TX signal. Connect the TX signal to your transceiver. @@ -16,10 +14,8 @@ menu "Example Configuration" config EXAMPLE_RX_GPIO_NUM int "RX GPIO number" range ENV_GPIO_RANGE_MIN ENV_GPIO_IN_RANGE_MAX - default 3 if IDF_TARGET_ESP32C3 - default 21 if IDF_TARGET_ESP32S2 default 22 if IDF_TARGET_ESP32 - default 5 if IDF_TARGET_ESP32S3 + default 2 help This option selects the GPIO pin used for the RX signal. Connect the RX signal to your transceiver. diff --git a/examples/peripherals/twai/twai_self_test/main/twai_self_test_example_main.c b/examples/peripherals/twai/twai_self_test/main/twai_self_test_example_main.c index 79dfb0dbcc..d7f313d339 100644 --- a/examples/peripherals/twai/twai_self_test/main/twai_self_test_example_main.c +++ b/examples/peripherals/twai/twai_self_test/main/twai_self_test_example_main.c @@ -1,11 +1,8 @@ -/* TWAI Self Test Example - - This example code is in the Public Domain (or CC0 licensed, at your option.) - - Unless required by applicable law or agreed to in writing, this - software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR - CONDITIONS OF ANY KIND, either express or implied. -*/ +/* + * SPDX-FileCopyrightText: 2010-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: CC0-1.0 + */ /* * The following example demonstrates the self testing capabilities of the TWAI @@ -43,8 +40,9 @@ static const twai_timing_config_t t_config = TWAI_TIMING_CONFIG_25KBITS(); //Filter all other IDs except MSG_ID static const twai_filter_config_t f_config = {.acceptance_code = (MSG_ID << 21), - .acceptance_mask = ~(TWAI_STD_ID_MASK << 21), - .single_filter = true}; + .acceptance_mask = ~(TWAI_STD_ID_MASK << 21), + .single_filter = true + }; //Set to NO_ACK mode due to self testing with single module static const twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT(TX_GPIO_NUM, RX_GPIO_NUM, TWAI_MODE_NO_ACK); diff --git a/examples/peripherals/twai/twai_self_test/pytest_twai_self_test_example.py b/examples/peripherals/twai/twai_self_test/pytest_twai_self_test_example.py new file mode 100644 index 0000000000..ea139a4e35 --- /dev/null +++ b/examples/peripherals/twai/twai_self_test/pytest_twai_self_test_example.py @@ -0,0 +1,12 @@ +# SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: CC0-1.0 + +import pytest +from pytest_embedded import Dut + + +@pytest.mark.esp32 +@pytest.mark.twai_transceiver +def test_twai_self_test_example(dut: Dut) -> None: + dut.expect_exact('TWAI Self Test: Driver installed') + dut.expect_exact('TWAI Self Test: Driver uninstalled') diff --git a/pytest.ini b/pytest.ini index a52b4c46f2..48ffebf9ea 100644 --- a/pytest.ini +++ b/pytest.ini @@ -46,6 +46,7 @@ markers = flash_mutli: Multiple flash chips tests psram: Chip has 4-line psram ir_transceiver: runners with a pair of IR transmitter and receiver + twai_transceiver: runners with a TWAI PHY transceiver flash_encryption_wifi_high_traffic: Flash Encryption runners with wifi high traffic support ethernet: ethernet runner ethernet_flash_8m: ethernet runner with 8mb flash @@ -70,6 +71,7 @@ markers = i154_multi_dut: tests should be used for i154, such as openthread. wifi_two_dut: tests should be run on runners which has two wifi duts connected. generic_multi_device: generic multiple devices whose corresponding gpio pins are connected to each other. + twai_network: multiple runners form a TWAI network. # host_test markers host_test: tests which shouldn not be built at the build stage, and instead built in host_test stage. diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index ee18d0ea25..b555d1df1c 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1656,14 +1656,6 @@ examples/peripherals/spi_slave_hd/append_mode/master/main/app_main.c examples/peripherals/spi_slave_hd/append_mode/slave/main/app_main.c examples/peripherals/spi_slave_hd/segment_mode/seg_master/main/app_main.c examples/peripherals/spi_slave_hd/segment_mode/seg_slave/main/app_main.c -examples/peripherals/twai/twai_alert_and_recovery/example_test.py -examples/peripherals/twai/twai_alert_and_recovery/main/twai_alert_and_recovery_example_main.c -examples/peripherals/twai/twai_network/example_test.py -examples/peripherals/twai/twai_network/twai_network_listen_only/main/twai_network_example_listen_only_main.c -examples/peripherals/twai/twai_network/twai_network_master/main/twai_network_example_master_main.c -examples/peripherals/twai/twai_network/twai_network_slave/main/twai_network_example_slave_main.c -examples/peripherals/twai/twai_self_test/example_test.py -examples/peripherals/twai/twai_self_test/main/twai_self_test_example_main.c examples/peripherals/uart/nmea0183_parser/main/nmea_parser_example_main.c examples/peripherals/uart/uart_async_rxtxtasks/main/uart_async_rxtxtasks_main.c examples/peripherals/uart/uart_echo/main/uart_echo_example_main.c