Merge branch 'refactor/twai_example_pytest' into 'master'

twai: migrate example test to pytest

See merge request espressif/esp-idf!20857
This commit is contained in:
morris 2022-11-01 11:05:01 +08:00
commit 9cb53256a0
26 changed files with 237 additions and 282 deletions

View File

@ -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

View File

@ -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

View File

@ -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()

View File

@ -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+')

View File

@ -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

View File

@ -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()

View File

@ -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.

View File

@ -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);
}
}

View File

@ -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')

View File

@ -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

View File

@ -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()

View File

@ -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')

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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
```

View File

@ -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()

View File

@ -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.

View File

@ -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);

View File

@ -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')

View File

@ -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.

View File

@ -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