mirror of
https://github.com/espressif/esp-idf.git
synced 2026-10-02 11:10:54 +03:00
Merge branch 'refactor/remove_twai_errata_config_v6.0' into 'release/v6.0'
refactor(driver_twai): remove twai errata config (v6.0) See merge request espressif/esp-idf!43029
This commit is contained in:
@@ -7,12 +7,6 @@ menu "Legacy TWAI Driver Configurations"
|
|||||||
help
|
help
|
||||||
Place the TWAI ISR in to IRAM to reduce latency and increase performance
|
Place the TWAI ISR in to IRAM to reduce latency and increase performance
|
||||||
|
|
||||||
config TWAI_SKIP_LEGACY_CONFLICT_CHECK
|
|
||||||
bool "Skip legacy driver conflict check"
|
|
||||||
default n
|
|
||||||
help
|
|
||||||
This configuration option used to bypass the conflict check mechanism with legacy code.
|
|
||||||
|
|
||||||
config TWAI_SUPPRESS_DEPRECATE_WARN
|
config TWAI_SUPPRESS_DEPRECATE_WARN
|
||||||
bool "Suppress legacy driver deprecated warning"
|
bool "Suppress legacy driver deprecated warning"
|
||||||
default n
|
default n
|
||||||
@@ -21,57 +15,10 @@ menu "Legacy TWAI Driver Configurations"
|
|||||||
(driver/twai.h). If you want to continue using the legacy driver,
|
(driver/twai.h). If you want to continue using the legacy driver,
|
||||||
and don't want to see related deprecation warnings, you can enable this option.
|
and don't want to see related deprecation warnings, you can enable this option.
|
||||||
|
|
||||||
config TWAI_ERRATA_FIX_BUS_OFF_REC
|
config TWAI_SKIP_LEGACY_CONFLICT_CHECK
|
||||||
bool "Add SW workaround for REC change during bus-off"
|
bool "Skip legacy driver conflict check"
|
||||||
depends on IDF_TARGET_ESP32
|
default n
|
||||||
default y
|
|
||||||
help
|
help
|
||||||
When the bus-off condition is reached, the REC should be reset to 0 and frozen (via LOM) by the
|
This configuration option used to bypass the conflict check mechanism with legacy code.
|
||||||
driver's ISR. However on the ESP32, there is an edge case where the REC will increase before the
|
|
||||||
driver's ISR can respond in time (e.g., due to the rapid occurrence of bus errors), thus causing the
|
|
||||||
REC to be non-zero after bus-off. A non-zero REC can prevent bus-off recovery as the bus-off recovery
|
|
||||||
condition is that both TEC and REC become 0. Enabling this option will add a workaround in the driver
|
|
||||||
to forcibly reset REC to zero on reaching bus-off.
|
|
||||||
|
|
||||||
config TWAI_ERRATA_FIX_TX_INTR_LOST
|
|
||||||
bool "Add SW workaround for TX interrupt lost errata"
|
|
||||||
depends on IDF_TARGET_ESP32
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
On the ESP32, when a transmit interrupt occurs, and interrupt register is read on the same APB clock
|
|
||||||
cycle, the transmit interrupt could be lost. Enabling this option will add a workaround that checks the
|
|
||||||
transmit buffer status bit to recover any lost transmit interrupt.
|
|
||||||
|
|
||||||
config TWAI_ERRATA_FIX_RX_FRAME_INVALID
|
|
||||||
bool "Add SW workaround for invalid RX frame errata"
|
|
||||||
depends on IDF_TARGET_ESP32
|
|
||||||
default y
|
|
||||||
help
|
|
||||||
On the ESP32, when receiving a data or remote frame, if a bus error occurs in the data or CRC field,
|
|
||||||
the data of the next received frame could be invalid. Enabling this option will add a workaround that
|
|
||||||
will reset the peripheral on detection of this errata condition. Note that if a frame is transmitted on
|
|
||||||
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.
|
|
||||||
|
|
||||||
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
|
endmenu # TWAI Configuration
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ entries:
|
|||||||
twai_hal_v1: twai_hal_check_state_flags (noflash)
|
twai_hal_v1: twai_hal_check_state_flags (noflash)
|
||||||
twai_hal_v1: twai_hal_clear_rx_fifo_overrun (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 IDF_TARGET_ESP32 = y: #For errata workarounds
|
||||||
twai_hal_v1: twai_hal_prepare_for_reset (noflash)
|
twai_hal_v1: twai_hal_prepare_for_reset (noflash)
|
||||||
twai_hal_v1: twai_hal_recover_from_reset (noflash)
|
twai_hal_v1: twai_hal_recover_from_reset (noflash)
|
||||||
twai_hal_v1: twai_hal_backup_config (noflash)
|
twai_hal_v1: twai_hal_backup_config (noflash)
|
||||||
|
|||||||
@@ -226,8 +226,11 @@ static void twai_intr_handler_main(void *arg)
|
|||||||
portENTER_CRITICAL_ISR(&p_twai_obj->spinlock);
|
portENTER_CRITICAL_ISR(&p_twai_obj->spinlock);
|
||||||
events = twai_hal_get_events(p_twai_obj->hal); //Get the events that triggered the interrupt
|
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 TWAI_LL_HAS_RX_FRAME_ISSUE || 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) {
|
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_hal_prepare_for_reset(p_twai_obj->hal);
|
||||||
TWAI_RCC_ATOMIC() {
|
TWAI_RCC_ATOMIC() {
|
||||||
twai_ll_reset_register(p_twai_obj->controller_id);
|
twai_ll_reset_register(p_twai_obj->controller_id);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ menu "ESP-Driver:TWAI Configurations"
|
|||||||
config TWAI_ISR_CACHE_SAFE
|
config TWAI_ISR_CACHE_SAFE
|
||||||
bool "Allow TWAI ISR execute when cache disabled" if !SPI_FLASH_AUTO_SUSPEND
|
bool "Allow TWAI ISR execute when cache disabled" if !SPI_FLASH_AUTO_SUSPEND
|
||||||
select TWAI_ISR_IN_IRAM
|
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 IDF_TARGET_ESP32 #For errata workarounds
|
||||||
default n
|
default n
|
||||||
help
|
help
|
||||||
Allow TWAI works under Cache disabled (such as when writing to SPI Flash),
|
Allow TWAI works under Cache disabled (such as when writing to SPI Flash),
|
||||||
|
|||||||
@@ -201,8 +201,11 @@ static void _node_isr_main(void *arg)
|
|||||||
twai_onchip_ctx_t *twai_ctx = arg;
|
twai_onchip_ctx_t *twai_ctx = arg;
|
||||||
uint32_t events = twai_hal_get_events(twai_ctx->hal); //Get the events that triggered the interrupt
|
uint32_t events = twai_hal_get_events(twai_ctx->hal); //Get the events that triggered the interrupt
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32 // only esp32 have this errata, TODO: IDF-13002 check errata runtime
|
#if TWAI_LL_HAS_RX_FRAME_ISSUE || 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) {
|
if (events & TWAI_HAL_EVENT_NEED_PERIPH_RESET) {
|
||||||
|
ESP_EARLY_LOGD(TAG, "Triggered peripheral reset");
|
||||||
twai_hal_prepare_for_reset(twai_ctx->hal);
|
twai_hal_prepare_for_reset(twai_ctx->hal);
|
||||||
TWAI_RCC_ATOMIC() {
|
TWAI_RCC_ATOMIC() {
|
||||||
twai_ll_reset_register(twai_ctx->ctrlr_id);
|
twai_ll_reset_register(twai_ctx->ctrlr_id);
|
||||||
@@ -498,7 +501,7 @@ static esp_err_t _node_disable(twai_node_handle_t node)
|
|||||||
ESP_RETURN_ON_ERROR(esp_intr_disable(twai_ctx->intr_hdl), TAG, "disable interrupt failed");
|
ESP_RETURN_ON_ERROR(esp_intr_disable(twai_ctx->intr_hdl), TAG, "disable interrupt failed");
|
||||||
atomic_store(&twai_ctx->state, TWAI_ERROR_BUS_OFF);
|
atomic_store(&twai_ctx->state, TWAI_ERROR_BUS_OFF);
|
||||||
twai_hal_stop(twai_ctx->hal);
|
twai_hal_stop(twai_ctx->hal);
|
||||||
#if CONFIG_IDF_TARGET_ESP32 // only esp32 have this errata, TODO: IDF-13002 check errata runtime
|
#if TWAI_LL_HAS_RX_FRAME_ISSUE
|
||||||
// when `disable` happens during hardware busy, the next RX frame is corrupted, a HW reset can fix it
|
// when `disable` happens during hardware busy, the next RX frame is corrupted, a HW reset can fix it
|
||||||
if (twai_hal_is_hw_busy(twai_ctx->hal)) {
|
if (twai_hal_is_hw_busy(twai_ctx->hal)) {
|
||||||
twai_hal_backup_config(twai_ctx->hal);
|
twai_hal_backup_config(twai_ctx->hal);
|
||||||
|
|||||||
@@ -28,7 +28,30 @@
|
|||||||
#include "soc/dport_reg.h"
|
#include "soc/dport_reg.h"
|
||||||
|
|
||||||
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
||||||
#define TWAI_LL_BRP_DIV_THRESH 128
|
|
||||||
|
// When the bus-off condition is reached, the REC should be reset to 0 and frozen (via LOM) by the
|
||||||
|
// driver's ISR. However on the ESP32, there is an edge case where the REC will increase before the
|
||||||
|
// driver's ISR can respond in time (e.g., due to the rapid occurrence of bus errors), thus causing the
|
||||||
|
// REC to be non-zero after bus-off. A non-zero REC can prevent bus-off recovery as the bus-off recovery
|
||||||
|
// condition is that both TEC and REC become 0.
|
||||||
|
#define TWAI_LL_HAS_BUSOFF_REC_ISSUE 1
|
||||||
|
|
||||||
|
// On the ESP32, when a transmit interrupt occurs, and interrupt register is read on the same APB clock
|
||||||
|
// cycle, the transmit interrupt could be lost.
|
||||||
|
#define TWAI_LL_HAS_INTR_LOST_ISSUE 1
|
||||||
|
|
||||||
|
// 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, the TWAI controller will still transmit dominant
|
||||||
|
// 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
|
||||||
|
|
||||||
|
// On the ESP32, when receiving a data or remote frame, if a bus error occurs in the data or CRC field,
|
||||||
|
// the data field of the NEXT received frame could be invalid.
|
||||||
|
#define TWAI_LL_HAS_RX_FRAME_ISSUE 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -38,6 +61,7 @@ static uint32_t twai_ll_get_brp_max(void);
|
|||||||
/* ------------------------- Defines and Typedefs --------------------------- */
|
/* ------------------------- Defines and Typedefs --------------------------- */
|
||||||
#define TWAI_LL_BRP_MIN 2
|
#define TWAI_LL_BRP_MIN 2
|
||||||
#define TWAI_LL_BRP_MAX twai_ll_get_brp_max() // max brp of esp32 is depends on chip version
|
#define TWAI_LL_BRP_MAX twai_ll_get_brp_max() // max brp of esp32 is depends on chip version
|
||||||
|
#define TWAI_LL_BRP_DIV_THRESH 128
|
||||||
#define TWAI_LL_TSEG1_MIN 1
|
#define TWAI_LL_TSEG1_MIN 1
|
||||||
#define TWAI_LL_TSEG2_MIN 1
|
#define TWAI_LL_TSEG2_MIN 1
|
||||||
#define TWAI_LL_TSEG1_MAX 16 //the max register value
|
#define TWAI_LL_TSEG1_MAX 16 //the max register value
|
||||||
|
|||||||
@@ -27,6 +27,11 @@
|
|||||||
|
|
||||||
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
||||||
|
|
||||||
|
// 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, the TWAI controller will still transmit dominant
|
||||||
|
// bits when it detects an error (i.e., as part of an active error frame).
|
||||||
|
#define TWAI_LL_HAS_LOM_DOM_ISSUE 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,6 +27,11 @@
|
|||||||
|
|
||||||
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
||||||
|
|
||||||
|
// 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, the TWAI controller will still transmit dominant
|
||||||
|
// bits when it detects an error (i.e., as part of an active error frame).
|
||||||
|
#define TWAI_LL_HAS_LOM_DOM_ISSUE 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -27,6 +27,11 @@
|
|||||||
|
|
||||||
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL)
|
||||||
|
|
||||||
|
// 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, the TWAI controller will still transmit dominant
|
||||||
|
// bits when it detects an error (i.e., as part of an active error frame).
|
||||||
|
#define TWAI_LL_HAS_LOM_DOM_ISSUE 1
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "sdkconfig.h"
|
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
#include "soc/clk_tree_defs.h"
|
#include "soc/clk_tree_defs.h"
|
||||||
|
#include "hal/config.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -56,11 +56,11 @@ extern "C" {
|
|||||||
#define TWAI_TIMING_CONFIG_10KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 200000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_10KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 200000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#endif // SOC_TWAI_BRP_MAX > 256
|
#endif // SOC_TWAI_BRP_MAX > 256
|
||||||
|
|
||||||
#if (SOC_TWAI_BRP_MAX > 128) || (CONFIG_ESP32_REV_MIN_FULL >= 200)
|
#if (SOC_TWAI_BRP_MAX > 128) || (SOC_IS(ESP32) && (HAL_CONFIG(CHIP_SUPPORT_MIN_REV) >= 200))
|
||||||
#define TWAI_TIMING_CONFIG_12_5KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 312500, .brp = 0, .prop_seg = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_12_5KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 312500, .brp = 0, .prop_seg = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#define TWAI_TIMING_CONFIG_16KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 400000, .brp = 0, .prop_seg = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_16KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 400000, .brp = 0, .prop_seg = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#define TWAI_TIMING_CONFIG_20KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 400000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_20KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 400000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#endif // (SOC_TWAI_BRP_MAX > 128) || (CONFIG_ESP32_REV_MIN_FULL >= 200)
|
#endif
|
||||||
|
|
||||||
#if SOC_TWAI_CLK_SUPPORT_XTAL
|
#if SOC_TWAI_CLK_SUPPORT_XTAL
|
||||||
#define TWAI_TIMING_CONFIG_25KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 500000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_25KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 500000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
@@ -71,7 +71,7 @@ extern "C" {
|
|||||||
#define TWAI_TIMING_CONFIG_100KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 2000000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_100KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 2000000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#define TWAI_TIMING_CONFIG_125KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 2000000, .brp = 0, .prop_seg = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_125KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 2000000, .brp = 0, .prop_seg = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#define TWAI_TIMING_CONFIG_250KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 4000000, .brp = 0, .prop_seg = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 2, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_250KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 4000000, .brp = 0, .prop_seg = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 2, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#if SOC_TWAI_CLK_SUPPORT_XTAL && CONFIG_XTAL_FREQ == 40 // TWAI_CLK_SRC_XTAL = 40M
|
#if SOC_TWAI_CLK_SUPPORT_XTAL && HAL_CONFIG(XTAL_HINT_FREQ_MHZ) == 40 // TWAI_CLK_SRC_XTAL = 40M
|
||||||
#define TWAI_TIMING_CONFIG_500KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 10000000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_500KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 10000000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#define TWAI_TIMING_CONFIG_800KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 20000000, .brp = 0, .prop_seg = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_800KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 20000000, .brp = 0, .prop_seg = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
#define TWAI_TIMING_CONFIG_1MBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 20000000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
#define TWAI_TIMING_CONFIG_1MBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 20000000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false}
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "sdkconfig.h"
|
|
||||||
#include "esp_compiler.h"
|
#include "esp_compiler.h"
|
||||||
|
#include "hal/log.h"
|
||||||
#include "hal/twai_hal.h"
|
#include "hal/twai_hal.h"
|
||||||
#include "hal/twai_ll.h"
|
#include "hal/twai_ll.h"
|
||||||
#include "soc/soc_caps.h"
|
#include "soc/soc_caps.h"
|
||||||
@@ -16,7 +16,8 @@
|
|||||||
#define TWAI_HAL_INIT_REC 0
|
#define TWAI_HAL_INIT_REC 0
|
||||||
#define TWAI_HAL_INIT_EWL 96
|
#define TWAI_HAL_INIT_EWL 96
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32 // only esp32 have this errata, TODO: IDF-13002 check errata runtime
|
#if TWAI_LL_HAS_RX_FRAME_ISSUE || TWAI_LL_HAS_RX_FIFO_ISSUE
|
||||||
|
// context for errata workarounds
|
||||||
typedef struct twai_hal_errata_ctx_t {
|
typedef struct twai_hal_errata_ctx_t {
|
||||||
twai_hal_frame_t tx_frame_save;
|
twai_hal_frame_t tx_frame_save;
|
||||||
twai_ll_reg_save_t reg_save;
|
twai_ll_reg_save_t reg_save;
|
||||||
@@ -25,7 +26,7 @@ typedef struct twai_hal_errata_ctx_t {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t twai_hal_get_mem_requirment(void) {
|
size_t twai_hal_get_mem_requirment(void) {
|
||||||
#if CONFIG_IDF_TARGET_ESP32 // only esp32 have this errata, TODO: IDF-13002 check errata runtime
|
#if TWAI_LL_HAS_RX_FRAME_ISSUE || TWAI_LL_HAS_RX_FIFO_ISSUE
|
||||||
return sizeof(twai_hal_context_t) + sizeof(twai_hal_errata_ctx_t);
|
return sizeof(twai_hal_context_t) + sizeof(twai_hal_errata_ctx_t);
|
||||||
#else
|
#else
|
||||||
return sizeof(twai_hal_context_t);
|
return sizeof(twai_hal_context_t);
|
||||||
@@ -48,7 +49,7 @@ bool twai_hal_init(twai_hal_context_t *hal_ctx, const twai_hal_config_t *config)
|
|||||||
if (!twai_ll_is_in_reset_mode(hal_ctx->dev)) { //Must enter reset mode to write to config registers
|
if (!twai_ll_is_in_reset_mode(hal_ctx->dev)) { //Must enter reset mode to write to config registers
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#if CONFIG_IDF_TARGET_ESP32 // only esp32 have this errata, TODO: IDF-13002 check errata runtime
|
#if TWAI_LL_HAS_RX_FRAME_ISSUE || TWAI_LL_HAS_RX_FIFO_ISSUE
|
||||||
hal_ctx->errata_ctx = (twai_hal_errata_ctx_t *)(hal_ctx + 1); //errata context is place at end of hal_ctx
|
hal_ctx->errata_ctx = (twai_hal_errata_ctx_t *)(hal_ctx + 1); //errata context is place at end of hal_ctx
|
||||||
#endif
|
#endif
|
||||||
#if SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT
|
#if SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT
|
||||||
@@ -143,12 +144,10 @@ void twai_hal_start(twai_hal_context_t *hal_ctx)
|
|||||||
twai_ll_set_mode(hal_ctx->dev, hal_ctx->enable_listen_only, hal_ctx->enable_self_test, hal_ctx->enable_loopback);
|
twai_ll_set_mode(hal_ctx->dev, hal_ctx->enable_listen_only, hal_ctx->enable_self_test, hal_ctx->enable_loopback);
|
||||||
//Clear the TEC and REC
|
//Clear the TEC and REC
|
||||||
twai_ll_set_tec(hal_ctx->dev, 0);
|
twai_ll_set_tec(hal_ctx->dev, 0);
|
||||||
#ifdef CONFIG_TWAI_ERRATA_FIX_LISTEN_ONLY_DOM
|
#if TWAI_LL_HAS_LOM_DOM_ISSUE
|
||||||
/*
|
// Errata workaround: Prevent transmission of dominant error frame while in listen only mode by setting REC to 128
|
||||||
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).
|
||||||
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.
|
||||||
The TEC/REC remain frozen in listen only mode thus ensuring we remain error passive.
|
|
||||||
*/
|
|
||||||
if (hal_ctx->enable_listen_only) {
|
if (hal_ctx->enable_listen_only) {
|
||||||
twai_ll_set_rec(hal_ctx->dev, 128);
|
twai_ll_set_rec(hal_ctx->dev, 128);
|
||||||
} else
|
} else
|
||||||
@@ -179,7 +178,7 @@ void twai_hal_start_bus_recovery(twai_hal_context_t *hal_ctx)
|
|||||||
|
|
||||||
/* ------------------------------------ IRAM Content ------------------------------------ */
|
/* ------------------------------------ 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.
|
//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
|
#define TWAI_RX_FIFO_CORRUPT_THRESH 62
|
||||||
#endif
|
#endif
|
||||||
@@ -231,7 +230,8 @@ static inline uint32_t twai_hal_decode_interrupt(twai_hal_context_t *hal_ctx)
|
|||||||
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_RX_BUFF_FRAME);
|
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_RX_BUFF_FRAME);
|
||||||
}
|
}
|
||||||
//Transmit interrupt set whenever TX buffer becomes free
|
//Transmit interrupt set whenever TX buffer becomes free
|
||||||
#ifdef CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST
|
#if TWAI_LL_HAS_INTR_LOST_ISSUE
|
||||||
|
// Errata workaround: Check the transmit buffer status bit to recover any lost transmit interrupt.
|
||||||
if ((interrupts & TWAI_LL_INTR_TI || hal_ctx->state_flags & TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED) && status & TWAI_LL_STATUS_TBS) {
|
if ((interrupts & TWAI_LL_INTR_TI || hal_ctx->state_flags & TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED) && status & TWAI_LL_STATUS_TBS) {
|
||||||
#else
|
#else
|
||||||
if (interrupts & TWAI_LL_INTR_TI) {
|
if (interrupts & TWAI_LL_INTR_TI) {
|
||||||
@@ -270,7 +270,7 @@ uint32_t twai_hal_get_events(twai_hal_context_t *hal_ctx)
|
|||||||
|
|
||||||
//Handle low latency events
|
//Handle low latency events
|
||||||
if (events & TWAI_HAL_EVENT_BUS_OFF) {
|
if (events & TWAI_HAL_EVENT_BUS_OFF) {
|
||||||
#ifdef CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC
|
#if TWAI_LL_HAS_BUSOFF_REC_ISSUE
|
||||||
//Errata workaround: Force REC to 0 by re-triggering bus-off (by setting TEC to 0 then 255)
|
//Errata workaround: Force REC to 0 by re-triggering bus-off (by setting TEC to 0 then 255)
|
||||||
twai_ll_set_tec(hal_ctx->dev, 0);
|
twai_ll_set_tec(hal_ctx->dev, 0);
|
||||||
twai_ll_set_tec(hal_ctx->dev, 255);
|
twai_ll_set_tec(hal_ctx->dev, 255);
|
||||||
@@ -289,25 +289,27 @@ uint32_t twai_hal_get_events(twai_hal_context_t *hal_ctx)
|
|||||||
.ack_err = (type == TWAI_LL_ERR_OTHER) && (seg == TWAI_LL_ERR_SEG_ACK_SLOT),
|
.ack_err = (type == TWAI_LL_ERR_OTHER) && (seg == TWAI_LL_ERR_SEG_ACK_SLOT),
|
||||||
};
|
};
|
||||||
hal_ctx->errors = errors;
|
hal_ctx->errors = errors;
|
||||||
#ifdef CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID
|
#if TWAI_LL_HAS_RX_FRAME_ISSUE
|
||||||
//Check for errata condition (RX message has bus error at particular segments)
|
//Check for errata condition (RX message has bus error at particular segments)
|
||||||
if (dir == TWAI_LL_ERR_DIR_RX &&
|
if (dir == TWAI_LL_ERR_DIR_RX &&
|
||||||
((seg == TWAI_LL_ERR_SEG_DATA || seg == TWAI_LL_ERR_SEG_CRC_SEQ) ||
|
((seg == TWAI_LL_ERR_SEG_DATA || seg == TWAI_LL_ERR_SEG_CRC_SEQ) ||
|
||||||
(seg == TWAI_LL_ERR_SEG_ACK_DELIM && type == TWAI_LL_ERR_OTHER))) {
|
(seg == TWAI_LL_ERR_SEG_ACK_DELIM && type == TWAI_LL_ERR_OTHER))) {
|
||||||
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_NEED_PERIPH_RESET);
|
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_NEED_PERIPH_RESET);
|
||||||
|
HAL_LOGD("TWAI_HAL", "RX frame invalid detected");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (events & TWAI_HAL_EVENT_ARB_LOST) {
|
if (events & TWAI_HAL_EVENT_ARB_LOST) {
|
||||||
twai_ll_clear_arb_lost_cap(hal_ctx->dev);
|
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)
|
//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) {
|
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);
|
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_NEED_PERIPH_RESET);
|
||||||
|
HAL_LOGD("TWAI_HAL", "RX FIFO corruption detected");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || defined(CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT)
|
#if TWAI_LL_HAS_RX_FRAME_ISSUE || TWAI_LL_HAS_RX_FIFO_ISSUE
|
||||||
if (events & TWAI_HAL_EVENT_NEED_PERIPH_RESET) {
|
if (events & TWAI_HAL_EVENT_NEED_PERIPH_RESET) {
|
||||||
//A peripheral reset will invalidate an RX event;
|
//A peripheral reset will invalidate an RX event;
|
||||||
TWAI_HAL_CLEAR_BITS(events, (TWAI_HAL_EVENT_RX_BUFF_FRAME));
|
TWAI_HAL_CLEAR_BITS(events, (TWAI_HAL_EVENT_RX_BUFF_FRAME));
|
||||||
@@ -316,7 +318,7 @@ uint32_t twai_hal_get_events(twai_hal_context_t *hal_ctx)
|
|||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_IDF_TARGET_ESP32 // only esp32 have this errata, TODO: IDF-13002 check errata runtime
|
#if TWAI_LL_HAS_RX_FRAME_ISSUE || TWAI_LL_HAS_RX_FIFO_ISSUE
|
||||||
bool twai_hal_is_hw_busy(twai_hal_context_t *hal_ctx)
|
bool twai_hal_is_hw_busy(twai_hal_context_t *hal_ctx)
|
||||||
{
|
{
|
||||||
return (TWAI_LL_STATUS_TS | TWAI_LL_STATUS_RS) & twai_ll_get_status(hal_ctx->dev);
|
return (TWAI_LL_STATUS_TS | TWAI_LL_STATUS_RS) & twai_ll_get_status(hal_ctx->dev);
|
||||||
@@ -365,7 +367,7 @@ void twai_hal_recover_from_reset(twai_hal_context_t *hal_ctx)
|
|||||||
TWAI_HAL_CLEAR_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_TX_NEED_RETRY);
|
TWAI_HAL_CLEAR_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_TX_NEED_RETRY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // CONFIG_IDF_TARGET_ESP32
|
#endif // TWAI_LL_HAS_RX_FRAME_ISSUE || TWAI_LL_HAS_RX_FIFO_ISSUE
|
||||||
|
|
||||||
void twai_hal_format_frame(const twai_hal_trans_desc_t *trans_desc, twai_hal_frame_t *frame)
|
void twai_hal_format_frame(const twai_hal_trans_desc_t *trans_desc, twai_hal_frame_t *frame)
|
||||||
{
|
{
|
||||||
@@ -405,7 +407,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_ll_set_cmd_tx(hal_ctx->dev);
|
||||||
}
|
}
|
||||||
TWAI_HAL_SET_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED);
|
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 TWAI_LL_HAS_RX_FRAME_ISSUE || TWAI_LL_HAS_RX_FIFO_ISSUE
|
||||||
if (&hal_ctx->errata_ctx->tx_frame_save == tx_frame) {
|
if (&hal_ctx->errata_ctx->tx_frame_save == tx_frame) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -413,7 +415,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
|
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));
|
memcpy(&hal_ctx->errata_ctx->tx_frame_save, tx_frame, sizeof(twai_hal_frame_t));
|
||||||
ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-overlapping-buffers")
|
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 //TWAI_LL_HAS_RX_FRAME_ISSUE || TWAI_LL_HAS_RX_FIFO_ISSUE
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t twai_hal_get_rx_msg_count(twai_hal_context_t *hal_ctx)
|
uint32_t twai_hal_get_rx_msg_count(twai_hal_context_t *hal_ctx)
|
||||||
|
|||||||
@@ -12,10 +12,6 @@ ignores:
|
|||||||
- "components/hal/platform_port/**/*"
|
- "components/hal/platform_port/**/*"
|
||||||
- "components/hal/test_apps/**/*"
|
- "components/hal/test_apps/**/*"
|
||||||
- "components/esp_hal*/test_apps/**/*"
|
- "components/esp_hal*/test_apps/**/*"
|
||||||
# the following files should be refactored to remove Kconfig macros
|
|
||||||
- "components/hal/twai_hal_v1.c"
|
|
||||||
- "components/hal/esp32/include/hal/twai_ll.h"
|
|
||||||
- "components/hal/include/hal/twai_types_deprecated.h"
|
|
||||||
rule:
|
rule:
|
||||||
any:
|
any:
|
||||||
- kind: argument_list
|
- kind: argument_list
|
||||||
@@ -47,9 +43,6 @@ ignores:
|
|||||||
- "components/hal/platform_port/**/*"
|
- "components/hal/platform_port/**/*"
|
||||||
- "components/hal/test_apps/**/*"
|
- "components/hal/test_apps/**/*"
|
||||||
- "components/esp_hal*/test_apps/**/*"
|
- "components/esp_hal*/test_apps/**/*"
|
||||||
# the following files should be refactored to remove sdkconfig.h
|
|
||||||
- "components/hal/twai_hal_v1.c"
|
|
||||||
- "components/hal/include/hal/twai_types_deprecated.h"
|
|
||||||
rule:
|
rule:
|
||||||
kind: preproc_include
|
kind: preproc_include
|
||||||
has:
|
has:
|
||||||
|
|||||||
Reference in New Issue
Block a user