From 30d871d2068d259c89d30ffe4b78e9cf184832e1 Mon Sep 17 00:00:00 2001 From: diplfranzhoepfinger Date: Thu, 27 Feb 2025 14:14:42 +0100 Subject: [PATCH] fix(twai): fixed twai assert fail when recover driver try start new frame in ISR however already bus off Closes https://github.com/espressif/esp-idf/issues/9697 --- components/driver/twai/twai.c | 8 +++++--- components/hal/include/hal/twai_hal.h | 9 +++++---- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/components/driver/twai/twai.c b/components/driver/twai/twai.c index 93786825c4..36fa530c8b 100644 --- a/components/driver/twai/twai.c +++ b/components/driver/twai/twai.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -191,8 +191,10 @@ static inline void twai_handle_tx_buffer_frame(twai_obj_t *p_twai_obj, BaseType_ p_twai_obj->tx_msg_count--; assert(p_twai_obj->tx_msg_count >= 0); //Sanity check - //Check if there are more frames to transmit - if (p_twai_obj->tx_msg_count > 0 && p_twai_obj->tx_queue != NULL) { + //If not bus-off, check if there are more frames to transmit + if (!twai_hal_check_state_flags(&p_twai_obj->hal, TWAI_HAL_STATE_FLAG_BUS_OFF) + && p_twai_obj->tx_msg_count > 0 + && p_twai_obj->tx_queue != NULL) { twai_hal_frame_t frame; int res = xQueueReceiveFromISR(p_twai_obj->tx_queue, &frame, task_woken); if (res == pdTRUE) { diff --git a/components/hal/include/hal/twai_hal.h b/components/hal/include/hal/twai_hal.h index 930b687cdc..f722d1666f 100644 --- a/components/hal/include/hal/twai_hal.h +++ b/components/hal/include/hal/twai_hal.h @@ -141,6 +141,7 @@ void twai_hal_stop(twai_hal_context_t *hal_ctx); */ static inline void twai_hal_start_bus_recovery(twai_hal_context_t *hal_ctx) { + TWAI_HAL_CLEAR_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED); TWAI_HAL_SET_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_RECOVERING); twai_ll_exit_reset_mode(hal_ctx->dev); } @@ -202,7 +203,7 @@ static inline bool twai_hal_check_last_tx_successful(twai_hal_context_t *hal_ctx * @param check_flags Bit mask of flags to check * @return True if one or more of the flags in check_flags are set */ - +__attribute__((always_inline)) static inline bool twai_hal_check_state_flags(twai_hal_context_t *hal_ctx, uint32_t check_flags) { return hal_ctx->state_flags & check_flags; @@ -300,7 +301,7 @@ static inline bool twai_hal_read_rx_buffer_and_clear(twai_hal_context_t *hal_ctx } #else if (twai_ll_get_status(hal_ctx->dev) & TWAI_LL_STATUS_DOS) { - //No need to release RX buffer as we'll be releaseing all RX frames in continuously later + //No need to release RX buffer as we'll be releasing all RX frames in continuously later return false; } #endif @@ -323,7 +324,7 @@ __attribute__((always_inline)) static inline uint32_t twai_hal_clear_rx_fifo_overrun(twai_hal_context_t *hal_ctx) { uint32_t msg_cnt = 0; - //Note: Need to keep polling th rx message counter incase another message arrives whilst clearing + //Note: Need to keep polling th rx message counter in case another message arrives whilst clearing while (twai_ll_get_rx_msg_count(hal_ctx->dev) > 0) { twai_ll_set_cmd_release_rx_buffer(hal_ctx->dev); msg_cnt++; @@ -347,7 +348,7 @@ static inline uint32_t twai_hal_clear_rx_fifo_overrun(twai_hal_context_t *hal_ct * - Checking if a reset will cancel a TX. If so, mark that we need to retry that message after the reset * - Save how many RX messages were lost due to this reset * - Enter reset mode to stop any the peripheral from receiving any bus activity - * - Store the regsiter state of the peripheral + * - Store the register state of the peripheral * * @param hal_ctx Context of the HAL layer */