diff --git a/components/driver/twai/Kconfig.twai b/components/driver/twai/Kconfig.twai index 6e98a87ef4b..35a535771d4 100644 --- a/components/driver/twai/Kconfig.twai +++ b/components/driver/twai/Kconfig.twai @@ -32,14 +32,4 @@ menu "Legacy TWAI Driver Configurations" the bus whilst the reset is ongoing, the message will not be receive by the peripheral sent on the bus during the reset, the message will be lost. - config TWAI_ERRATA_FIX_RX_FIFO_CORRUPT - bool "Add SW workaround for RX FIFO corruption errata" - depends on IDF_TARGET_ESP32 - default y - help - On the ESP32, when the RX FIFO overruns and the RX message counter maxes out at 64 messages, the entire - RX FIFO is no longer recoverable. Enabling this option will add a workaround that resets the peripheral - 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. - endmenu # TWAI Configuration diff --git a/components/driver/twai/linker.lf b/components/driver/twai/linker.lf index 2d0c47b0b95..67b93ecd9c2 100644 --- a/components/driver/twai/linker.lf +++ b/components/driver/twai/linker.lf @@ -23,7 +23,7 @@ entries: twai_hal_v1: twai_hal_check_state_flags (noflash) twai_hal_v1: twai_hal_clear_rx_fifo_overrun (noflash) - if TWAI_ERRATA_FIX_RX_FRAME_INVALID = y || TWAI_ERRATA_FIX_RX_FIFO_CORRUPT = y: + if TWAI_ERRATA_FIX_RX_FRAME_INVALID = y || IDF_TARGET_ESP32 = y: twai_hal_v1: twai_hal_prepare_for_reset (noflash) twai_hal_v1: twai_hal_recover_from_reset (noflash) twai_hal_v1: twai_hal_backup_config (noflash) diff --git a/components/driver/twai/twai.c b/components/driver/twai/twai.c index 5a42e178171..bb47982bb91 100644 --- a/components/driver/twai/twai.c +++ b/components/driver/twai/twai.c @@ -226,8 +226,11 @@ static void twai_intr_handler_main(void *arg) portENTER_CRITICAL_ISR(&p_twai_obj->spinlock); events = twai_hal_get_events(p_twai_obj->hal); //Get the events that triggered the interrupt -#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || defined(CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT) +#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || TWAI_LL_HAS_RX_FIFO_ISSUE + // Errata workaround: Reset the peripheral on detection of this errata condition. + // Note that if a frame is being sent on the bus during the reset, the message will be lost. if (events & TWAI_HAL_EVENT_NEED_PERIPH_RESET) { + ESP_EARLY_LOGD(TWAI_TAG, "Triggered peripheral reset"); twai_hal_prepare_for_reset(p_twai_obj->hal); TWAI_RCC_ATOMIC() { twai_ll_reset_register(p_twai_obj->controller_id); diff --git a/components/esp_driver_twai/Kconfig b/components/esp_driver_twai/Kconfig index e9ace179f15..6b657a8521a 100644 --- a/components/esp_driver_twai/Kconfig +++ b/components/esp_driver_twai/Kconfig @@ -18,7 +18,7 @@ menu "ESP-Driver:TWAI Configurations" config TWAI_ISR_CACHE_SAFE bool "Allow TWAI ISR execute when cache disabled" if !SPI_FLASH_AUTO_SUSPEND select TWAI_ISR_IN_IRAM - select ESP_PERIPH_CTRL_FUNC_IN_IRAM if TWAI_ERRATA_FIX_RX_FRAME_INVALID || TWAI_ERRATA_FIX_RX_FIFO_CORRUPT + select ESP_PERIPH_CTRL_FUNC_IN_IRAM if TWAI_ERRATA_FIX_RX_FRAME_INVALID || IDF_TARGET_ESP32 default n help Allow TWAI works under Cache disabled (such as when writing to SPI Flash), diff --git a/components/hal/esp32/include/hal/twai_ll.h b/components/hal/esp32/include/hal/twai_ll.h index 2f8d0a75cb3..4a3654446b5 100644 --- a/components/hal/esp32/include/hal/twai_ll.h +++ b/components/hal/esp32/include/hal/twai_ll.h @@ -45,6 +45,10 @@ // bits when it detects an error (i.e., as part of an active error frame). #define TWAI_LL_HAS_LOM_DOM_ISSUE 1 +// On the ESP32, when the RX FIFO overruns and the RX message counter maxes out at 64 messages, the entire +// RX FIFO is no longer recoverable. +#define TWAI_LL_HAS_RX_FIFO_ISSUE 1 + #ifdef __cplusplus extern "C" { #endif diff --git a/components/hal/twai_hal_v1.c b/components/hal/twai_hal_v1.c index 3224c2d1bf8..f03016d325e 100644 --- a/components/hal/twai_hal_v1.c +++ b/components/hal/twai_hal_v1.c @@ -7,6 +7,7 @@ #include #include "sdkconfig.h" #include "esp_compiler.h" +#include "hal/log.h" #include "hal/twai_hal.h" #include "hal/twai_ll.h" #include "soc/soc_caps.h" @@ -177,7 +178,7 @@ void twai_hal_start_bus_recovery(twai_hal_context_t *hal_ctx) /* ------------------------------------ IRAM Content ------------------------------------ */ -#ifdef CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT +#if TWAI_LL_HAS_RX_FIFO_ISSUE //Errata condition occurs at 64 messages. Threshold set to 62 to prevent the chance of failing to detect errata condition. #define TWAI_RX_FIFO_CORRUPT_THRESH 62 #endif @@ -300,13 +301,14 @@ uint32_t twai_hal_get_events(twai_hal_context_t *hal_ctx) if (events & TWAI_HAL_EVENT_ARB_LOST) { twai_ll_clear_arb_lost_cap(hal_ctx->dev); } -#ifdef CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT +#if TWAI_LL_HAS_RX_FIFO_ISSUE //Check for errata condition (rx_msg_count >= corruption_threshold) if (events & TWAI_HAL_EVENT_RX_BUFF_FRAME && twai_ll_get_rx_msg_count(hal_ctx->dev) >= TWAI_RX_FIFO_CORRUPT_THRESH) { TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_NEED_PERIPH_RESET); + HAL_LOGD("TWAI_HAL", "RX FIFO corruption detected"); } #endif -#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || defined(CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT) +#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || TWAI_LL_HAS_RX_FIFO_ISSUE if (events & TWAI_HAL_EVENT_NEED_PERIPH_RESET) { //A peripheral reset will invalidate an RX event; TWAI_HAL_CLEAR_BITS(events, (TWAI_HAL_EVENT_RX_BUFF_FRAME)); @@ -404,7 +406,7 @@ void twai_hal_set_tx_buffer_and_transmit(twai_hal_context_t *hal_ctx, twai_hal_f twai_ll_set_cmd_tx(hal_ctx->dev); } TWAI_HAL_SET_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED); -#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || defined(CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT) +#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || TWAI_LL_HAS_RX_FIFO_ISSUE if (&hal_ctx->errata_ctx->tx_frame_save == tx_frame) { return; } @@ -412,7 +414,7 @@ void twai_hal_set_tx_buffer_and_transmit(twai_hal_context_t *hal_ctx, twai_hal_f ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-overlapping-buffers") // TODO IDF-11085 memcpy(&hal_ctx->errata_ctx->tx_frame_save, tx_frame, sizeof(twai_hal_frame_t)); ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-overlapping-buffers") -#endif //defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || defined(CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT) +#endif //defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || TWAI_LL_HAS_RX_FIFO_ISSUE } uint32_t twai_hal_get_rx_msg_count(twai_hal_context_t *hal_ctx)