Skip to content

Commit e8ec954

Browse files
committed
Merge branch 'fix/c5_twai_listen_only_workaround' into 'master'
fix(driver_twai): added ctu_official workaround, fixed error count info Closes IDFGH-16314, IDFGH-16278, IDFGH-16364, IDFGH-16383, IDFCI-3106, and IDFCI-3107 See merge request espressif/esp-idf!41570
2 parents ce9563d + 550e989 commit e8ec954

File tree

15 files changed

+97
-86
lines changed

15 files changed

+97
-86
lines changed

components/esp_driver_twai/esp_twai.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,11 @@ uint32_t twai_node_timing_calc_param(const uint32_t source_freq, const twai_timi
4343

4444
uint16_t default_point = (in_param->bitrate >= 800000) ? 750 : ((in_param->bitrate >= 500000) ? 800 : 875);
4545
uint16_t sample_point = in_param->sp_permill ? in_param->sp_permill : default_point; // default sample point based on bitrate if not configured
46-
uint16_t tseg_1 = (tseg * sample_point) / 1000;
46+
uint16_t tseg_1 = (tseg * sample_point) / 1000 - 1;
4747
tseg_1 = MAX(hw_limit->tseg1_min, MIN(tseg_1, hw_limit->tseg1_max));
4848
uint16_t tseg_2 = tseg - tseg_1 - 1;
4949
tseg_2 = MAX(hw_limit->tseg2_min, MIN(tseg_2, hw_limit->tseg2_max));
50-
tseg_1 = tseg - tseg_2 - 1;
51-
uint16_t prop = tseg_1 / 2; // distribute tseg1 evenly between prop_seg and tseg_1
50+
uint16_t prop = MAX(1, tseg_1 / 4); // prop_seg is usually shorter than tseg_1 and at least 1
5251
tseg_1 -= prop;
5352

5453
out_param->quanta_resolution_hz = 0; // going to deprecated IDF-12725

components/esp_driver_twai/esp_twai_onchip.c

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,6 @@ typedef struct {
7979
#endif
8080

8181
_Atomic twai_error_state_t state;
82-
uint16_t tx_error_count;
83-
uint16_t rx_error_count;
8482
twai_node_record_t history;
8583

8684
atomic_bool hw_busy;
@@ -127,8 +125,8 @@ static esp_err_t _node_config_io(twai_onchip_ctx_t *node, const twai_onchip_node
127125
{
128126
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");
129127
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(node_config->io_cfg.rx), ESP_ERR_INVALID_ARG, TAG, "Invalid rx gpio num");
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");
128+
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 gpio is not supported");
129+
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 gpio is not supported");
132130

133131
uint64_t reserve_mask = 0;
134132
// Set RX pin
@@ -446,7 +444,7 @@ static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, twai_clock_s
446444
.sjw_max = TWAI_LL_SJW_MAX,
447445
};
448446
uint32_t real_baud = twai_node_timing_calc_param(source_freq, timing, &hw_const, &timing_adv);
449-
ESP_LOGD(TAG, "norm src %ld, param %ld %d %d %d %d %d", source_freq, timing_adv.brp, timing_adv.prop_seg, timing_adv.tseg_1, timing_adv.tseg_2, timing_adv.sjw, timing_adv.ssp_offset);
447+
ESP_LOGD(TAG, "timing: src %ld brp %ld prop %d seg1 %d seg2 %d sjw %d ssp %d", source_freq, timing_adv.brp, timing_adv.prop_seg, timing_adv.tseg_1, timing_adv.tseg_2, timing_adv.sjw, timing_adv.ssp_offset);
450448
ESP_RETURN_ON_FALSE(real_baud, ESP_ERR_INVALID_ARG, TAG, "bitrate can't achieve!");
451449
if (timing->bitrate != real_baud) {
452450
ESP_LOGW(TAG, "bitrate precision loss, adjust from %ld to %ld", timing->bitrate, real_baud);
@@ -455,7 +453,7 @@ static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, twai_clock_s
455453
twai_timing_advanced_config_t timing_adv_fd = { .clk_src = root_clock_src, };
456454
if (timing_fd->bitrate) {
457455
real_baud = twai_node_timing_calc_param(source_freq, timing_fd, &hw_const, &timing_adv_fd);
458-
ESP_LOGD(TAG, "fd src %ld, param %ld %d %d %d %d %d", source_freq, timing_adv_fd.brp, timing_adv_fd.prop_seg, timing_adv_fd.tseg_1, timing_adv_fd.tseg_2, timing_adv_fd.sjw, timing_adv_fd.ssp_offset);
456+
ESP_LOGD(TAG, "timing_fd: src %ld brp %ld prop %d seg1 %d seg2 %d sjw %d ssp %d", source_freq, timing_adv_fd.brp, timing_adv_fd.prop_seg, timing_adv_fd.tseg_1, timing_adv_fd.tseg_2, timing_adv_fd.sjw, timing_adv_fd.ssp_offset);
459457
ESP_RETURN_ON_FALSE(real_baud, ESP_ERR_INVALID_ARG, TAG, "bitrate can't achieve!");
460458
if (timing_fd->bitrate != real_baud) {
461459
ESP_LOGW(TAG, "bitrate precision loss, adjust from %ld to %ld", timing_fd->bitrate, real_baud);
@@ -569,8 +567,8 @@ static esp_err_t _node_get_status(twai_node_handle_t node, twai_node_status_t *s
569567

570568
if (status_ret) {
571569
status_ret->state = atomic_load(&twai_ctx->state);
572-
status_ret->tx_error_count = twai_ctx->tx_error_count;
573-
status_ret->rx_error_count = twai_ctx->rx_error_count;
570+
status_ret->tx_error_count = twai_hal_get_tec(twai_ctx->hal);
571+
status_ret->rx_error_count = twai_hal_get_rec(twai_ctx->hal);
574572
}
575573
if (record_ret) {
576574
*record_ret = twai_ctx->history;
@@ -707,13 +705,6 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
707705
.enable_self_test = node_config->flags.enable_self_test,
708706
.enable_loopback = node_config->flags.enable_loopback,
709707
};
710-
#if CONFIG_IDF_TARGET_ESP32C5
711-
// ESP32C5 has a bug that the listen only mode don't work when there are other nodes sending ACK each other
712-
// See IDF-13059 for more details
713-
if (node_config->flags.enable_listen_only) {
714-
ESP_LOGW(TAG, "Listen only mode for ESP32C5 may not work properly when there are more than 2 nodes on the bus that are sending ACKs to each other");
715-
}
716-
#endif
717708
ESP_GOTO_ON_FALSE(twai_hal_init(node->hal, &hal_config), ESP_ERR_INVALID_STATE, err, TAG, "hardware not in reset state");
718709
// Configure bus timing
719710
ESP_GOTO_ON_ERROR(_node_calc_set_bit_timing(&node->api_base, node_config->clk_src, &node_config->bit_timing, &node_config->data_timing), err, TAG, "bitrate error");

components/esp_driver_twai/include/esp_twai_onchip.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,14 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
5757
* @brief Helper function to configure a dual 16-bit acceptance filter.
5858
* @note For 29bits Extended IDs, ONLY high 16bits id/mask is used for each filter.
5959
*
60-
* @param id1 First ID to filter.
60+
* @param id1 First full 11/29 bits ID to filter.
6161
* @param mask1 Mask for first ID.
62-
* @param id2 Second ID to filter.
62+
* @param id2 Second full 11/29 bits ID to filter.
6363
* @param mask2 Mask for second ID.
6464
* @param is_ext True if using Extended (29-bit) IDs, false for Standard (11-bit) IDs.
6565
* @return twai_mask_filter_config_t A filled filter configuration structure for dual filtering.
6666
*/
67-
static inline twai_mask_filter_config_t twai_make_dual_filter(uint16_t id1, uint16_t mask1, uint16_t id2, uint16_t mask2, bool is_ext)
67+
static inline twai_mask_filter_config_t twai_make_dual_filter(uint32_t id1, uint32_t mask1, uint32_t id2, uint32_t mask2, bool is_ext)
6868
{
6969
/**
7070
* Dual filter is a special mode in hardware,
@@ -90,6 +90,10 @@ static inline twai_mask_filter_config_t twai_make_dual_filter(uint16_t id1, uint
9090
.no_fd = false,
9191
.dual_filter = true,
9292
};
93+
if ((id1 & mask1 & id2 & mask2) == 0xffffffff) {
94+
dual_cfg.id = 0xffffffff; // recover the 'disable' code
95+
dual_cfg.mask = 0xffffffff;
96+
}
9397
return dual_cfg;
9498
}
9599

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

Lines changed: 58 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ static void test_random_trans_generator(twai_node_handle_t node_hdl, uint32_t tr
246246

247247
printf("Sending %ld random trans ...\n", trans_num);
248248
for (uint32_t tx_cnt = 0; tx_cnt < trans_num; tx_cnt++) {
249-
tx_msg.header.id = tx_cnt | 0xf000;
249+
tx_msg.header.id = tx_cnt | 0xf000 | (tx_cnt << 16);
250250
tx_msg.header.ide = !!(tx_cnt % 2);
251251
tx_msg.header.rtr = !!(tx_cnt % 3);
252252
tx_msg.buffer_len = tx_cnt % TWAI_FRAME_MAX_LEN;
@@ -350,13 +350,17 @@ static IRAM_ATTR bool test_dual_filter_rx_done_cb(twai_node_handle_t handle, con
350350
rx_frame.buffer_len = TWAI_FRAME_MAX_LEN;
351351

352352
if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
353-
ESP_EARLY_LOGI("Recv", "RX id 0x%4x len %2d ext %d rmt %d", rx_frame.header.id, twaifd_dlc2len(rx_frame.header.dlc), rx_frame.header.ide, rx_frame.header.rtr);
353+
ESP_EARLY_LOGI("Recv", "id 0x%8x len %2d ext %d rmt %d", rx_frame.header.id, twaifd_dlc2len(rx_frame.header.dlc), rx_frame.header.ide, rx_frame.header.rtr);
354354
switch (test_ctrl[0]) {
355-
case 0: // receive something
355+
case 0: // receive std id
356356
TEST_ASSERT(!rx_frame.header.ide);
357357
TEST_ASSERT((rx_frame.header.id >= 0x10) && (rx_frame.header.id <= 0x2f));
358358
break;
359359
case 1: break; // receive none
360+
case 2: // receive ext id
361+
TEST_ASSERT(rx_frame.header.ide);
362+
TEST_ASSERT((rx_frame.header.id >= 0x280000) || (rx_frame.header.id <= 0xfffff));
363+
break;
360364
default: TEST_ASSERT(false);
361365
}
362366
test_ctrl[1] ++;
@@ -384,7 +388,7 @@ TEST_CASE("twai dual 16bit mask filter (loopback)", "[twai]")
384388
user_cbs.on_rx_done = test_dual_filter_rx_done_cb;
385389
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, test_ctrl));
386390

387-
printf("Testing dual filter: id1 0x%x mask1 0x%x, id2 0x%x mask2 0x%x\n", 0x020, 0x7f0, 0x013, 0x7f8);
391+
printf("Testing dual filter: std id1 0x%x mask1 0x%x, id2 0x%x mask2 0x%x\n", 0x020, 0x7f0, 0x013, 0x7f8);
388392
test_ctrl[0] = 0;
389393
test_ctrl[1] = 0;
390394
// filter 1 receive only std id 0x02x
@@ -395,17 +399,31 @@ TEST_CASE("twai dual 16bit mask filter (loopback)", "[twai]")
395399
test_random_trans_generator(node_hdl, 50);
396400
TEST_ASSERT_EQUAL(12, test_ctrl[1]); // must receive 12 of 50 frames under filter config
397401

398-
printf("Disable filter\n");
402+
dual_config = twai_make_dual_filter(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, false);
403+
printf("Testing disable filter by dual_maker, result: id %lx mask %lx\n", dual_config.id, dual_config.mask);
404+
TEST_ASSERT_EQUAL(0xffffffff, dual_config.id & dual_config.mask);
405+
406+
printf("Testing disable filter\n");
399407
test_ctrl[0] = 1;
400408
test_ctrl[1] = 0;
401-
dual_config.id = 0xFFFFFFFF;
402-
dual_config.mask = 0xFFFFFFFF;
403409
TEST_ESP_OK(twai_node_disable(node_hdl));
404410
TEST_ESP_OK(twai_node_config_mask_filter(node_hdl, 0, &dual_config));
405411
TEST_ESP_OK(twai_node_enable(node_hdl));
406412
test_random_trans_generator(node_hdl, 40);
407413
TEST_ASSERT_EQUAL(0, test_ctrl[1]);
408414

415+
printf("Testing dual filter: ext id1 0x%x mask1 0x%x, id2 0x%x mask2 0x%x\n", 0x0280000, 0x1ff80000, 0x0000000, 0x1ff00000);
416+
test_ctrl[0] = 2;
417+
test_ctrl[1] = 0;
418+
// filter 1 receive only ext id 0x028xxxxx~0x02fxxxxx
419+
// filter 2 receive only ext id 0x000xxxxx
420+
dual_config = twai_make_dual_filter(0x0280000, 0x1ff80000, 0x0000000, 0x1ff00000, true);
421+
TEST_ESP_OK(twai_node_disable(node_hdl));
422+
TEST_ESP_OK(twai_node_config_mask_filter(node_hdl, 0, &dual_config));
423+
TEST_ESP_OK(twai_node_enable(node_hdl));
424+
test_random_trans_generator(node_hdl, 50);
425+
TEST_ASSERT_EQUAL(12, test_ctrl[1]); // must receive 12 of 50 frames
426+
409427
TEST_ESP_OK(twai_node_disable(node_hdl));
410428
TEST_ESP_OK(twai_node_delete(node_hdl));
411429
}
@@ -515,7 +533,7 @@ TEST_CASE("twai bus off recovery (loopback)", "[twai]")
515533

516534
// send frames and trigger error, must become bus off before 50 frames
517535
while ((node_status.state != TWAI_ERROR_BUS_OFF) && (tx_frame.header.id < 50)) {
518-
printf("sending frame %ld\n", tx_frame.header.id ++);
536+
printf("sending frame %ld last tec %d rec %d\n", tx_frame.header.id ++, node_status.tx_error_count, node_status.rx_error_count);
519537
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame, 500));
520538
if (tx_frame.header.id > 3) { // trigger error after 3 frames
521539
printf("trigger bit_error now!\n");
@@ -529,6 +547,11 @@ TEST_CASE("twai bus off recovery (loopback)", "[twai]")
529547
}
530548

531549
// recover node
550+
#if SOC_TWAI_SUPPORT_FD
551+
TEST_ASSERT_GREATER_THAN(200, node_status.tx_error_count);
552+
#else
553+
TEST_ASSERT_EQUAL(128, node_status.tx_error_count); // TEC become 128 when bus off on legacy chips
554+
#endif
532555
TEST_ASSERT_EQUAL(TWAI_ERROR_BUS_OFF, node_status.state);
533556
printf("node offline, start recover ...\n");
534557
TEST_ESP_OK(twai_node_recover(node_hdl));
@@ -539,7 +562,8 @@ TEST_CASE("twai bus off recovery (loopback)", "[twai]")
539562
vTaskDelay(pdMS_TO_TICKS(1000));
540563
twai_node_get_info(node_hdl, &node_status, NULL);
541564
}
542-
printf("node recovered! continue\n");
565+
printf("node recovered! current tec %d rec %d, continue\n", node_status.tx_error_count, node_status.rx_error_count);
566+
TEST_ASSERT_LESS_THAN(96, node_status.tx_error_count);
543567
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame, 500));
544568

545569
TEST_ESP_OK(twai_node_disable(node_hdl));
@@ -597,25 +621,25 @@ TEST_CASE("twai tx_wait_all_done thread safe", "[twai]")
597621
// Test data for ISR send functionality
598622
typedef struct {
599623
twai_node_handle_t node;
600-
uint32_t rx_count;
601-
uint32_t tx_isr_send_count;
602-
uint32_t rx_isr_send_count;
624+
uint8_t rx_count;
625+
uint8_t tx_isr_send_count;
626+
uint8_t rx_isr_send_count;
627+
twai_frame_t tx_isr_frame;
628+
twai_frame_t rx_isr_frame;
603629
bool test_completed;
604630
} isr_send_test_ctx_t;
605631

606632
static IRAM_ATTR bool test_tx_isr_send_cb(twai_node_handle_t handle, const twai_tx_done_event_data_t *edata, void *user_ctx)
607633
{
608634
isr_send_test_ctx_t *ctx = (isr_send_test_ctx_t *)user_ctx;
635+
twai_frame_t *isr_frame = &ctx->tx_isr_frame;
609636

610637
// Test sending from TX ISR context
611638
if (ctx->tx_isr_send_count < 3) {
612-
twai_frame_t isr_frame = {};
613-
isr_frame.header.id = 0x200 + ctx->tx_isr_send_count;
614-
isr_frame.header.dlc = 1;
615-
isr_frame.buffer = (uint8_t*)(&ctx->tx_isr_send_count);
616-
isr_frame.buffer_len = 1;
639+
isr_frame->header.id = 0x200 + ctx->tx_isr_send_count;
640+
isr_frame->header.dlc = 1;
617641

618-
esp_err_t err = twai_node_transmit(handle, &isr_frame, 0); // timeout must be 0 in ISR
642+
esp_err_t err = twai_node_transmit(handle, isr_frame, 0); // timeout must be 0 in ISR
619643
if (err == ESP_OK) {
620644
ctx->tx_isr_send_count++;
621645
}
@@ -627,23 +651,17 @@ static IRAM_ATTR bool test_tx_isr_send_cb(twai_node_handle_t handle, const twai_
627651
static IRAM_ATTR bool test_rx_isr_send_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
628652
{
629653
isr_send_test_ctx_t *ctx = (isr_send_test_ctx_t *)user_ctx;
630-
twai_frame_t rx_frame = {};
631-
uint8_t buffer[8];
632-
rx_frame.buffer = buffer;
633-
rx_frame.buffer_len = sizeof(buffer);
654+
twai_frame_t *rx_frame = &ctx->rx_isr_frame;
634655

635-
if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
656+
if (ESP_OK == twai_node_receive_from_isr(handle, rx_frame)) {
636657
ctx->rx_count++;
637658

638659
// Test sending from RX ISR context (response pattern)
639-
if ((rx_frame.header.id >= 0x100) && (rx_frame.header.id < 0x103) && (ctx->rx_isr_send_count < 3)) {
640-
twai_frame_t response_frame = {};
641-
response_frame.header.id = 0x300 + ctx->rx_isr_send_count;
642-
response_frame.header.dlc = 1;
643-
response_frame.buffer = (uint8_t*)(&ctx->rx_isr_send_count);
644-
response_frame.buffer_len = 1;
645-
646-
esp_err_t err = twai_node_transmit(handle, &response_frame, 0); // timeout must be 0 in ISR
660+
if ((rx_frame->header.id >= 0x100) && (rx_frame->header.id < 0x103) && (ctx->rx_isr_send_count < 3)) {
661+
rx_frame->header.id = 0x300 + ctx->rx_isr_send_count;
662+
rx_frame->header.dlc = 1;
663+
664+
esp_err_t err = twai_node_transmit(handle, rx_frame, 0); // timeout must be 0 in ISR
647665
if (err == ESP_OK) {
648666
ctx->rx_isr_send_count++;
649667
}
@@ -660,6 +678,8 @@ static IRAM_ATTR bool test_rx_isr_send_cb(twai_node_handle_t handle, const twai_
660678
TEST_CASE("twai send from ISR context (loopback)", "[twai]")
661679
{
662680
isr_send_test_ctx_t test_ctx = {};
681+
test_ctx.tx_isr_frame.buffer = &test_ctx.tx_isr_send_count;
682+
test_ctx.rx_isr_frame.buffer = &test_ctx.rx_isr_send_count;
663683

664684
twai_onchip_node_config_t node_config = {};
665685
node_config.io_cfg.tx = TEST_TX_GPIO;
@@ -682,13 +702,11 @@ TEST_CASE("twai send from ISR context (loopback)", "[twai]")
682702
printf("Testing ISR context sending...\n");
683703

684704
// Send initial frames to trigger RX ISR responses
685-
for (int i = 0; i < 3; i++) {
705+
for (uint8_t i = 0; i < 3; i++) {
686706
twai_frame_t trigger_frame = {};
687707
trigger_frame.header.id = 0x100 + i;
688708
trigger_frame.header.dlc = 1;
689-
trigger_frame.buffer = (uint8_t[]) {
690-
(uint8_t)i
691-
};
709+
trigger_frame.buffer = &i;
692710
trigger_frame.buffer_len = 1;
693711

694712
TEST_ESP_OK(twai_node_transmit(test_ctx.node, &trigger_frame, 500));
@@ -704,9 +722,9 @@ TEST_CASE("twai send from ISR context (loopback)", "[twai]")
704722
}
705723

706724
printf("Test results:\n");
707-
printf(" RX count: %" PRIu32 "\n", test_ctx.rx_count);
708-
printf(" TX ISR sends: %" PRIu32 "\n", test_ctx.tx_isr_send_count);
709-
printf(" RX ISR sends: %" PRIu32 "\n", test_ctx.rx_isr_send_count);
725+
printf(" RX count: %d\n", test_ctx.rx_count);
726+
printf(" TX ISR sends: %d\n", test_ctx.tx_isr_send_count);
727+
printf(" RX ISR sends: %d\n", test_ctx.rx_isr_send_count);
710728
printf(" Test completed: %s\n", test_ctx.test_completed ? "YES" : "NO");
711729

712730
// Verify test results
@@ -717,8 +735,6 @@ TEST_CASE("twai send from ISR context (loopback)", "[twai]")
717735

718736
TEST_ESP_OK(twai_node_disable(test_ctx.node));
719737
TEST_ESP_OK(twai_node_delete(test_ctx.node));
720-
721-
printf("ISR send test passed!\n");
722738
}
723739

724740
static IRAM_ATTR bool test_dlc_range_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
@@ -736,6 +752,8 @@ TEST_CASE("twai dlc range test", "[twai]")
736752
twai_onchip_node_config_t node_config = {};
737753
node_config.io_cfg.tx = TEST_TX_GPIO;
738754
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
755+
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
756+
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
739757
node_config.bit_timing.bitrate = 800000;
740758
node_config.tx_queue_depth = TEST_FRAME_NUM;
741759
node_config.flags.enable_loopback = true;

components/esp_driver_twai/test_apps/test_twai/pytest_driver_twai.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def fixture_create_socket_can() -> Bus:
3636

3737

3838
@pytest.mark.twai_std
39-
@pytest.mark.temp_skip_ci(targets=['esp32c5', 'esp32h4'], reason='no runner')
39+
@pytest.mark.temp_skip_ci(targets=['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', 'esp32h4'], reason='no runner')
62+
@pytest.mark.temp_skip_ci(targets=['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: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,11 @@ static inline void twaifd_ll_set_mode(twaifd_dev_t *hw, bool listen_only, bool s
174174

175175
twaifd_mode_settings_reg_t opmode = {.val = hw->mode_settings.val};
176176
opmode.stm = self_test;
177+
// esp32c5 using `rom` and `acf` together with `bmm` to warkaround the errata 0v2 issue 5
178+
// see issue https://github.com/espressif/esp-idf/issues/17461
177179
opmode.bmm = listen_only;
180+
opmode.rom = listen_only;
181+
opmode.acf = listen_only;
178182
opmode.ilbp = loopback;
179183

180184
hw->mode_settings.val = opmode.val;

components/hal/esp32h4/include/hal/twaifd_ll.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,9 @@ static inline void twaifd_ll_set_mode(twaifd_dev_t *hw, bool listen_only, bool s
180180
twaifd_mode_settings_reg_t opmode = {.val = hw->mode_settings.val};
181181
opmode.stm = self_test;
182182
opmode.bmm = listen_only;
183+
// esp32h4 using `rom` together with `bmm` although errata 0v2 issue 5 is fixed
184+
// see detail in https://github.com/espressif/esp-idf/issues/17461
185+
opmode.rom = listen_only;
183186
opmode.ilbp = loopback;
184187

185188
hw->mode_settings.val = opmode.val;

0 commit comments

Comments
 (0)