diff --git a/components/driver/Kconfig b/components/driver/Kconfig index 7888cd5380..f17eb93635 100644 --- a/components/driver/Kconfig +++ b/components/driver/Kconfig @@ -172,6 +172,17 @@ menu "Driver Configurations" on detection of this errata condition. Note that if a frame is being sent on the bus during the reset bus during the reset, the message will be lost. + config TWAI_ERRATA_FIX_LISTEN_ONLY_DOM + bool "Add SW workaround for listen only transmits dominant bit errata" + depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32C3 + default y + help + When in the listen only mode, the TWAI controller must not influence the TWAI bus (i.e., must not send + any dominant bits). However, while in listen only mode on the ESP32/ESP32-S2/ESP32-S3/ESP32-C3, the + TWAI controller will still transmit dominant bits when it detects an error (i.e., as part of an active + error frame). Enabling this option will add a workaround that forces the TWAI controller into an error + passive state on initialization, thus preventing any dominant bits from being sent. + endmenu # TWAI Configuration menu "Temperature sensor Configuration" diff --git a/components/driver/twai.c b/components/driver/twai.c index 4e96929e2e..d9e2c8e55a 100644 --- a/components/driver/twai.c +++ b/components/driver/twai.c @@ -670,8 +670,14 @@ esp_err_t twai_get_status_info(twai_status_info_t *status_info) TWAI_CHECK(status_info != NULL, ESP_ERR_INVALID_ARG); TWAI_ENTER_CRITICAL(); - status_info->tx_error_counter = twai_hal_get_tec(&twai_context); - status_info->rx_error_counter = twai_hal_get_rec(&twai_context); + if (p_twai_obj->mode == TWAI_MODE_LISTEN_ONLY) { + //Error counters are frozen under listen only mode thus are meaningless. Simply return 0 in this case. + status_info->tx_error_counter = 0; + status_info->rx_error_counter = 0; + } else { + status_info->tx_error_counter = twai_hal_get_tec(&twai_context); + status_info->rx_error_counter = twai_hal_get_rec(&twai_context); + } status_info->msgs_to_tx = p_twai_obj->tx_msg_count; status_info->msgs_to_rx = p_twai_obj->rx_msg_count; status_info->tx_failed_count = p_twai_obj->tx_failed_count; diff --git a/components/hal/twai_hal.c b/components/hal/twai_hal.c index ee6163817e..11ec8e4075 100644 --- a/components/hal/twai_hal.c +++ b/components/hal/twai_hal.c @@ -1,16 +1,8 @@ -// Copyright 2015-2019 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at - -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include "sdkconfig.h" @@ -70,6 +62,21 @@ void twai_hal_configure(twai_hal_context_t *hal_ctx, const twai_timing_config_t void twai_hal_start(twai_hal_context_t *hal_ctx, twai_mode_t mode) { twai_ll_set_mode(hal_ctx->dev, mode); //Set operating mode + //Clear the TEC and REC + twai_ll_set_tec(hal_ctx->dev, 0); +#ifdef CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM + /* + Errata workaround: Prevent transmission of dominant error frame while in listen only mode by setting REC to 128 + before exiting reset mode. This forces the controller to be error passive (thus only transmits recessive bits). + The TEC/REC remain frozen in listen only mode thus ensuring we remain error passive. + */ + if (mode == TWAI_MODE_LISTEN_ONLY) { + twai_ll_set_rec(hal_ctx->dev, 128); + } else +#endif + { + twai_ll_set_rec(hal_ctx->dev, 0); + } (void) twai_ll_get_and_clear_intrs(hal_ctx->dev); //Clear any latched interrupts TWAI_HAL_SET_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_RUNNING); twai_ll_exit_reset_mode(hal_ctx->dev); diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index 77cd6f6cb3..acdf97bf30 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -779,7 +779,6 @@ components/hal/spi_slave_hal_iram.c components/hal/spi_slave_hd_hal.c components/hal/test/test_mpu.c components/hal/touch_sensor_hal.c -components/hal/twai_hal.c components/hal/twai_hal_iram.c components/hal/uart_hal_iram.c components/hal/usb_hal.c