Skip to content

Commit 6fdaf37

Browse files
committed
Merge branch 'feat/twai_esp32h4' into 'master'
feat(twai): add driver support on esp32h4 Closes IDF-12352 and IDF-12354 See merge request espressif/esp-idf!41434
2 parents c433a76 + 921e62b commit 6fdaf37

File tree

25 files changed

+1236
-166
lines changed

25 files changed

+1236
-166
lines changed

components/driver/test_apps/legacy_twai/pytest_twai.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
@idf_parametrize(
2323
'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']
2424
)
25-
def test_twai_self(dut: Dut) -> None:
25+
def test_legacy_twai_self(dut: Dut) -> None:
2626
dut.run_all_single_board_cases(group='twai-loop-back')
2727

2828

@@ -31,11 +31,11 @@ def fixture_create_socket_can() -> Bus:
3131
# Set up the socket CAN with the bitrate
3232
start_command = 'sudo ip link set can0 up type can bitrate 250000 restart-ms 100'
3333
stop_command = 'sudo ip link set can0 down'
34-
subprocess.run(start_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
34+
subprocess.run(start_command, shell=True, capture_output=True, text=True)
3535
bus = Bus(interface='socketcan', channel='can0', bitrate=250000)
3636
yield bus # test invoked here
3737
bus.shutdown()
38-
subprocess.run(stop_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
38+
subprocess.run(stop_command, shell=True, capture_output=True, text=True)
3939

4040

4141
@pytest.mark.twai_std
@@ -49,7 +49,7 @@ def fixture_create_socket_can() -> Bus:
4949
@idf_parametrize(
5050
'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']
5151
)
52-
def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
52+
def test_legacy_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
5353
dut.serial.hard_reset()
5454
dut.expect_exact('Press ENTER to see the list of tests')
5555

@@ -79,7 +79,7 @@ def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
7979
@idf_parametrize(
8080
'target', ['esp32', 'esp32c3', 'esp32c6', 'esp32h2', 'esp32s2', 'esp32s3', 'esp32p4'], indirect=['target']
8181
)
82-
def test_twai_remote_request(dut: Dut, socket_can: Bus) -> None:
82+
def test_legacy_twai_remote_request(dut: Dut, socket_can: Bus) -> None:
8383
dut.serial.hard_reset()
8484
dut.expect_exact('Press ENTER to see the list of tests')
8585

components/esp_driver_twai/esp_twai_onchip.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,8 +127,10 @@ static esp_err_t _node_config_io(twai_onchip_ctx_t *node, const twai_onchip_node
127127
{
128128
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.tx) || (node_config->flags.enable_listen_only && (node_config->io_cfg.tx == -1)), ESP_ERR_INVALID_ARG, TAG, "Invalid tx gpio num");
129129
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(node_config->io_cfg.rx), ESP_ERR_INVALID_ARG, TAG, "Invalid rx gpio num");
130-
uint64_t reserve_mask = 0;
130+
ESP_RETURN_ON_FALSE(!(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.quanta_clk_out) && (twai_periph_signals[node->ctrlr_id].clk_out_sig < 0)), ESP_ERR_NOT_SUPPORTED, TAG, "quanta_clk_out is not supported");
131+
ESP_RETURN_ON_FALSE(!(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.bus_off_indicator) && (twai_periph_signals[node->ctrlr_id].bus_off_sig < 0)), ESP_ERR_NOT_SUPPORTED, TAG, "bus_off_indicator is not supported");
131132

133+
uint64_t reserve_mask = 0;
132134
// Set RX pin
133135
gpio_set_pull_mode(node_config->io_cfg.rx, GPIO_PULLUP_ONLY); // pullup to avoid noise if no connection to transceiver
134136
gpio_matrix_input(node_config->io_cfg.rx, twai_periph_signals[node->ctrlr_id].rx_sig, false);
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
2-
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- |
1+
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
2+
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |

components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ static IRAM_ATTR bool test_driver_install_rx_cb(twai_node_handle_t handle, const
3333
twai_frame_t rx_frame = {};
3434

3535
if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
36-
ESP_EARLY_LOGI("Recv ", "id 0x%lx rtr %d", rx_frame.header.id, rx_frame.header.rtr);
36+
esp_rom_printf("Recv id 0x%lx rtr %d", rx_frame.header.id, rx_frame.header.rtr);
3737
}
3838
if (rx_frame.header.id != 0x100) {
3939
TEST_FAIL(); //callback is unregistered, should not run here
@@ -113,6 +113,8 @@ static void test_twai_baudrate_correctness(twai_clock_source_t clk_src, uint32_t
113113
twai_onchip_node_config_t node_config = {};
114114
node_config.io_cfg.tx = TEST_TX_GPIO;
115115
node_config.io_cfg.rx = TEST_TX_GPIO;
116+
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
117+
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
116118
node_config.clk_src = clk_src;
117119
node_config.bit_timing.bitrate = test_bitrate;
118120
node_config.tx_queue_depth = 1;
@@ -497,6 +499,8 @@ TEST_CASE("twai bus off recovery (loopback)", "[twai]")
497499
twai_onchip_node_config_t node_config = {};
498500
node_config.io_cfg.tx = TEST_TX_GPIO;
499501
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
502+
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
503+
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
500504
node_config.bit_timing.bitrate = 50000; //slow bitrate to ensure soft error trigger
501505
node_config.tx_queue_depth = 1;
502506
node_config.flags.enable_self_test = true;
@@ -568,6 +572,8 @@ TEST_CASE("twai tx_wait_all_done thread safe", "[twai]")
568572
twai_onchip_node_config_t node_config = {};
569573
node_config.io_cfg.tx = TEST_TX_GPIO;
570574
node_config.io_cfg.rx = TEST_TX_GPIO; //Using same pin for test without transceiver
575+
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
576+
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
571577
node_config.bit_timing.bitrate = 100000; //slow bitrate to ensure transmite finish during wait_all_done
572578
node_config.tx_queue_depth = TEST_FRAME_NUM;
573579
node_config.flags.enable_self_test = true;

components/esp_driver_twai/test_apps/test_twai/main/test_twai_fd.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ TEST_CASE("twai range filter (loopback)", "[twai]")
6666
twai_onchip_node_config_t node_config = {};
6767
node_config.io_cfg.tx = TEST_TX_GPIO;
6868
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
69+
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
70+
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
6971
node_config.bit_timing.bitrate = 1000000;
7072
node_config.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH;
7173
node_config.flags.enable_self_test = true;
@@ -139,6 +141,8 @@ TEST_CASE("twai fd transmit time (loopback)", "[twai]")
139141
twai_onchip_node_config_t node_config = {};
140142
node_config.io_cfg.tx = TEST_TX_GPIO;
141143
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
144+
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
145+
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
142146
node_config.bit_timing.bitrate = 1000000;
143147
node_config.data_timing.bitrate = 4000000;
144148
node_config.data_timing.ssp_permill = 700; // ssp 70.0%

components/esp_driver_twai/test_apps/test_twai/main/test_twai_network.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ TEST_CASE("twai_listen_only", "[twai_net]")
3131
twai_onchip_node_config_t node_config = {};
3232
node_config.io_cfg.tx = TEST_TX_GPIO;
3333
node_config.io_cfg.rx = TEST_RX_GPIO;
34+
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
35+
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
3436
node_config.bit_timing.bitrate = 250000;
3537
node_config.tx_queue_depth = 3;
3638
node_config.flags.enable_listen_only = true;
@@ -71,6 +73,8 @@ TEST_CASE("twai_remote_request", "[twai_net]")
7173
twai_onchip_node_config_t node_config = {};
7274
node_config.io_cfg.tx = TEST_TX_GPIO;
7375
node_config.io_cfg.rx = TEST_RX_GPIO;
76+
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
77+
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
7478
node_config.bit_timing.bitrate = 250000;
7579
node_config.tx_queue_depth = 3;
7680
node_config.fail_retry_cnt = -1; // retry forever if send remote frame failed

components/esp_driver_twai/test_apps/test_twai/pytest_driver_twai.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,17 @@ def fixture_create_socket_can() -> Bus:
2626
start_command = 'sudo ip link set can0 up type can bitrate 250000'
2727
stop_command = 'sudo ip link set can0 down'
2828
try:
29-
subprocess.run(start_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
29+
subprocess.run(start_command, shell=True, capture_output=True, text=True)
3030
except Exception as e:
3131
print(f'Open bus Error: {e}')
3232
bus = Bus(interface='socketcan', channel='can0', bitrate=250000)
3333
yield bus # test invoked here
3434
bus.shutdown()
35-
subprocess.run(stop_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
35+
subprocess.run(stop_command, shell=True, capture_output=True, text=True)
3636

3737

3838
@pytest.mark.twai_std
39-
@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='no runner')
39+
@pytest.mark.temp_skip_ci(targets=['esp32c5', 'esp32h4'], reason='no runner')
4040
@pytest.mark.parametrize('config', ['release'], indirect=True)
4141
@idf_parametrize('target', soc_filtered_targets('SOC_TWAI_SUPPORTED == 1'), indirect=['target'])
4242
def test_driver_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
@@ -59,7 +59,7 @@ def test_driver_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
5959

6060

6161
@pytest.mark.twai_std
62-
@pytest.mark.temp_skip_ci(targets=['esp32c5'], reason='no runner')
62+
@pytest.mark.temp_skip_ci(targets=['esp32c5', 'esp32h4'], reason='no runner')
6363
@pytest.mark.parametrize('config', ['release'], indirect=True)
6464
@idf_parametrize('target', soc_filtered_targets('SOC_TWAI_SUPPORTED == 1'), indirect=['target'])
6565
def test_driver_twai_remote_request(dut: Dut, socket_can: Bus) -> None:

components/hal/esp32c5/include/hal/twaifd_ll.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,16 @@ static inline void twaifd_ll_reset_register(uint8_t twai_id)
9898
*/
9999
static inline void twaifd_ll_set_clock_source(uint8_t twai_id, twai_clock_source_t clk_src)
100100
{
101-
PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_sel = (clk_src == TWAI_CLK_SRC_XTAL) ? 0 : 1;
101+
switch (clk_src) {
102+
case TWAI_CLK_SRC_PLL_F80M:
103+
PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_sel = 1;
104+
break;
105+
case TWAI_CLK_SRC_XTAL:
106+
PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_sel = 0;
107+
break;
108+
default:
109+
HAL_ASSERT(false);
110+
}
102111
}
103112

104113
/**

0 commit comments

Comments
 (0)