feat(driver_twai): bringup s31 twaifd driver support

This commit is contained in:
wanckl
2026-04-14 17:41:04 +08:00
parent 4e1b02d90c
commit aea648dbd2
19 changed files with 1626 additions and 159 deletions
@@ -25,6 +25,10 @@ static void _twai_rcc_clock_ctrl(uint8_t ctrlr_id, bool enable)
PERIPH_RCC_ATOMIC() {
twai_ll_enable_clock(ctrlr_id, enable);
}
#if TWAI_LL_SUPPORT(MEM_LP)
twai_ll_mem_power_by_pmu(ctrlr_id);
twai_ll_mem_lp_mode_sel(ctrlr_id, TWAI_LL_MEM_LP_MODE_SHUT_DOWN);
#endif
}
static void _twai_rcc_clock_sel(uint8_t ctrlr_id, twai_clock_source_t clock)
{
@@ -1,2 +1,2 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
@@ -57,7 +57,7 @@ TEST_CASE("twai install uninstall (loopback)", "[twai]")
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
node_config.io_cfg.quanta_clk_out = GPIO_NUM_NC;
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
node_config.bit_timing.bitrate = 1000000;
node_config.bit_timing.bitrate = 500000;
node_config.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH;
node_config.flags.enable_self_test = true;
node_config.flags.enable_loopback = true;
@@ -78,7 +78,7 @@ def fixture_create_socket_can() -> Bus:
# Interactive Tests
# ---------------------------------------------------------------------------
@pytest.mark.twai_std
@pytest.mark.temp_skip_ci(targets=['esp32h4'], reason='no runner')
@pytest.mark.temp_skip_ci(targets=['esp32h4', 'esp32s31'], reason='no runner')
@pytest.mark.parametrize('config', ['release'], indirect=True)
@idf_parametrize('target', soc_filtered_targets('SOC_TWAI_SUPPORTED == 1'), indirect=['target'])
def test_driver_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
@@ -99,7 +99,7 @@ def test_driver_twai_listen_only(dut: Dut, socket_can: Bus) -> None:
@pytest.mark.twai_std
@pytest.mark.temp_skip_ci(targets=['esp32h4'], reason='no runner')
@pytest.mark.temp_skip_ci(targets=['esp32h4', 'esp32s31'], reason='no runner')
@pytest.mark.parametrize('config', ['release'], indirect=True)
@idf_parametrize('target', soc_filtered_targets('SOC_TWAI_SUPPORTED == 1'), indirect=['target'])
def test_driver_twai_remote_request(dut: Dut, socket_can: Bus) -> None:
@@ -0,0 +1,211 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#pragma once
#include <string.h>
#include "hal/twai_types.h"
#include "soc/hp_sys_clkrst_struct.h"
#include "soc/hp_system_struct.h"
#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr
#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat
#define TWAI_LL_SUPPORT_TIMESTAMP 1
#define TWAI_LL_SUPPORT_RX_STATUS 1
#define TWAI_LL_SUPPORT_MEM_LP 1 // support memory low power mode
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
TWAI_LL_MEM_LP_MODE_DEEP_SLEEP, // memory will enter deep sleep during low power stage, keep memory data
TWAI_LL_MEM_LP_MODE_LIGHT_SLEEP, // memory will enter light sleep during low power stage, keep memory data
TWAI_LL_MEM_LP_MODE_SHUT_DOWN, // memory will be powered down during low power stage
TWAI_LL_MEM_LP_MODE_DISABLE, // disable the low power stage
} twai_ll_mem_lp_mode_sel_t;
/**
* @brief Enable the bus clock and module clock for TWAI module
*
* @param twai_id Hardware ID
* @param enable true to enable, false to disable
*/
static inline void twai_ll_enable_bus_clock(uint8_t twai_id, bool enable)
{
switch (twai_id) {
case 0:
HP_SYS_CLKRST.twai0_ctrl0.reg_twai0_apb_clk_en = enable;
break;
case 1:
HP_SYS_CLKRST.twai1_ctrl0.reg_twai1_apb_clk_en = enable;
break;
default:
HAL_ASSERT(false);
}
}
/**
* @brief Select the power control mode for the TWAI memory block
*
* @param twai_id Hardware ID
*/
static inline void twai_ll_mem_power_by_pmu(uint8_t twai_id)
{
switch (twai_id) {
case 0:
HP_SYSTEM.sys_can0_mem_lp_ctrl.sys_can0_mem_force_ctrl = 0;
HP_SYSTEM.sys_can0_mem_lp_ctrl.sys_can0_mem_lp_en = 0;
break;
case 1:
HP_SYSTEM.sys_can1_mem_lp_ctrl.sys_can1_mem_force_ctrl = 0;
HP_SYSTEM.sys_can1_mem_lp_ctrl.sys_can1_mem_lp_en = 0;
break;
default:
HAL_ASSERT(false);
}
}
/**
* @brief Select the low power mode for the TWAI memory block
*
* @param twai_id Hardware ID
* @param mode Low power mode
*/
static inline void twai_ll_mem_lp_mode_sel(uint8_t twai_id, twai_ll_mem_lp_mode_sel_t mode)
{
switch (twai_id) {
case 0:
HP_SYSTEM.sys_can0_mem_lp_ctrl.sys_can0_mem_lp_mode = mode;
break;
case 1:
HP_SYSTEM.sys_can1_mem_lp_ctrl.sys_can1_mem_lp_mode = mode;
break;
default:
HAL_ASSERT(false);
}
}
/**
* @brief Force the TWAI memory block to power on
*
* @param twai_id Hardware ID
*/
static inline void twai_ll_mem_force_power_on(uint8_t twai_id)
{
switch (twai_id) {
case 0:
HP_SYSTEM.sys_can0_mem_lp_ctrl.sys_can0_mem_force_ctrl = 1;
HP_SYSTEM.sys_can0_mem_lp_ctrl.sys_can0_mem_lp_en = 0;
break;
case 1:
HP_SYSTEM.sys_can1_mem_lp_ctrl.sys_can1_mem_force_ctrl = 1;
HP_SYSTEM.sys_can1_mem_lp_ctrl.sys_can1_mem_lp_en = 0;
break;
default:
HAL_ASSERT(false);
}
}
/**
* @brief Force the TWAI memory block to enter low power mode
*
* @param twai_id Hardware ID
*/
static inline void twai_ll_mem_force_low_power(uint8_t twai_id)
{
switch (twai_id) {
case 0:
HP_SYSTEM.sys_can0_mem_lp_ctrl.sys_can0_mem_force_ctrl = 1;
HP_SYSTEM.sys_can0_mem_lp_ctrl.sys_can0_mem_lp_en = 1;
break;
case 1:
HP_SYSTEM.sys_can1_mem_lp_ctrl.sys_can1_mem_force_ctrl = 1;
HP_SYSTEM.sys_can1_mem_lp_ctrl.sys_can1_mem_lp_en = 1;
break;
default:
HAL_ASSERT(false);
}
}
/**
* @brief Reset the TWAI module
*
* @param twai_id Hardware ID
*/
static inline void twai_ll_reset_register(uint8_t twai_id)
{
switch (twai_id) {
case 0:
HP_SYS_CLKRST.twai0_ctrl0.reg_twai0_rst_en = 1;
HP_SYS_CLKRST.twai0_ctrl0.reg_twai0_rst_en = 0;
break;
case 1:
HP_SYS_CLKRST.twai1_ctrl0.reg_twai1_rst_en = 1;
HP_SYS_CLKRST.twai1_ctrl0.reg_twai1_rst_en = 0;
break;
default:
HAL_ASSERT(false);
}
}
/**
* @brief Set clock source for TWAI module
*
* @param twai_id Hardware ID
* @param clk_src Clock source
*/
static inline void twai_ll_set_clock_source(uint8_t twai_id, twai_clock_source_t clk_src)
{
uint32_t clk_sel = 0;
switch (clk_src) {
case TWAI_CLK_SRC_XTAL:
clk_sel = 0;
break;
case TWAI_CLK_SRC_PLL_F80M:
clk_sel = 2;
break;
default:
HAL_ASSERT(false);
}
switch (twai_id) {
case 0:
HP_SYS_CLKRST.twai0_ctrl0.reg_twai0_clk_src_sel = clk_sel;
break;
case 1:
HP_SYS_CLKRST.twai1_ctrl0.reg_twai1_clk_src_sel = clk_sel;
break;
default:
HAL_ASSERT(false);
}
}
/**
* @brief Enable TWAI module clock source
*
* @param twai_id Hardware ID
* @param enable true to enable, false to disable
*/
static inline void twai_ll_enable_clock(uint8_t twai_id, bool enable)
{
switch (twai_id) {
case 0:
HP_SYS_CLKRST.twai0_ctrl0.reg_twai0_clk_en = enable;
break;
case 1:
HP_SYS_CLKRST.twai1_ctrl0.reg_twai1_clk_en = enable;
break;
default:
HAL_ASSERT(false);
}
}
#ifdef __cplusplus
}
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,105 @@
/*
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "hal/twai_periph.h"
#include "soc/gpio_sig_map.h"
#include "soc/interrupts.h"
#include "soc/twaifd_reg.h"
const twai_signal_conn_t twai_periph_signals[2] = {
[0] = {
.module_name = "TWAI0",
.irq_id = ETS_TWAI0_INTR_SOURCE,
.timer_irq_id = ETS_TWAI0_TIMER_INTR_SOURCE,
.tx_sig = TWAI0_TX_IDX,
.rx_sig = TWAI0_RX_IDX,
.bus_off_sig = -1,
.clk_out_sig = -1,
.stand_by_sig = -1,
},
[1] = {
.module_name = "TWAI1",
.irq_id = ETS_TWAI1_INTR_SOURCE,
.timer_irq_id = ETS_TWAI1_TIMER_INTR_SOURCE,
.tx_sig = TWAI1_TX_IDX,
.rx_sig = TWAI1_RX_IDX,
.bus_off_sig = -1,
.clk_out_sig = -1,
.stand_by_sig = -1,
},
};
/**
* TWAI Registers to be saved during sleep retention
* - TWAIFD_MODE_SETTINGS_REG
* - TWAIFD_STATUS_REG
* - TWAIFD_COMMAND_REG
* - TWAIFD_INT_ENA_SET_REG
* - TWAIFD_INT_ENA_CLR_REG
* - TWAIFD_BTR_REG
* - TWAIFD_BTR_FD_REG
* - TWAIFD_EWL_ERP_FAULT_STATE_REG
* - TWAIFD_REC_TEC_REG
* - TWAIFD_ERR_NORM_ERR_FD_REG
* - TWAIFD_FILTER_A_MASK_REG
* - TWAIFD_FILTER_A_VAL_REG
* - TWAIFD_FILTER_B_MASK_REG
* - TWAIFD_FILTER_B_VAL_REG
* - TWAIFD_FILTER_C_MASK_REG
* - TWAIFD_FILTER_C_VAL_REG
* - TWAIFD_FILTER_RAN_LOW_REG
* - TWAIFD_FILTER_RAN_HIGH_REG
* - TWAIFD_FILTER_CONTROL_FILTER_STATUS_REG
* - TWAIFD_RX_STATUS_RX_SETTINGS_REG
* - TWAIFD_TX_COMMAND_TXTB_INFO_REG
* - TWAIFD_TX_PRIORITY_REG
* - TWAIFD_TRV_DELAY_SSP_CFG_REG
* - TWAIFD_RX_FR_CTR_REG
* - TWAIFD_TX_FR_CTR_REG
*/
#define TWAI_RETENTION_REGS_CNT 25
#define TWAI_RETENTION_REGS_BASE(i) REG_TWAIFD_BASE(i)
static const uint32_t twai_regs_map[4] = {0xb27fdf37, 0x3, 0x0, 0x0};
// twai timer registers is far away from twai registers, so we need a separate link
// - TWAIFD_TIMER_INT_ENA_REG
// - TWAIFD_TIMER_CFG_REG
#define TWAI_TIMER_RETENTION_REGS_CNT 2
#define TWAI_TIMER_RETENTION_REGS_BASE(i) (REG_TWAIFD_BASE(i) + 0xfe0)
static const uint32_t twai_timer_regs_map[4] = {0x5, 0x0, 0x0, 0x0};
#define TWAI_SLEEP_RETENTION_ENTRIES(id) { \
[0] = { .config = REGDMA_LINK_ADDR_MAP_INIT( \
REGDMA_TWAI_LINK(0x00), \
TWAI_RETENTION_REGS_BASE(id), TWAI_RETENTION_REGS_BASE(id), \
TWAI_RETENTION_REGS_CNT, 0, 0, \
twai_regs_map[0], twai_regs_map[1], \
twai_regs_map[2], twai_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) }, \
[1] = { .config = REGDMA_LINK_ADDR_MAP_INIT( \
REGDMA_TWAI_LINK(0x01), \
TWAI_TIMER_RETENTION_REGS_BASE(id), TWAI_TIMER_RETENTION_REGS_BASE(id), \
TWAI_TIMER_RETENTION_REGS_CNT, 0, 0, \
twai_timer_regs_map[0], twai_timer_regs_map[1], \
twai_timer_regs_map[2], twai_timer_regs_map[3]), \
.owner = ENTRY(0) | ENTRY(2) }, \
}
static const regdma_entries_config_t twai0_regs_retention[] = TWAI_SLEEP_RETENTION_ENTRIES(0);
static const regdma_entries_config_t twai1_regs_retention[] = TWAI_SLEEP_RETENTION_ENTRIES(1);
const twai_reg_retention_info_t twai_reg_retention_info[2] = {
[0] = {
.module_id = SLEEP_RETENTION_MODULE_TWAI0,
.entry_array = twai0_regs_retention,
.array_size = ARRAY_SIZE(twai0_regs_retention)
},
[1] = {
.module_id = SLEEP_RETENTION_MODULE_TWAI1,
.entry_array = twai1_regs_retention,
.array_size = ARRAY_SIZE(twai1_regs_retention)
},
};
@@ -39,6 +39,14 @@ config SOC_MCPWM_SUPPORTED
bool
default y
config SOC_TWAI_SUPPORTED
bool
default y
config SOC_TWAI_FD_SUPPORTED
bool
default y
config SOC_ETM_SUPPORTED
bool
default y
@@ -527,6 +535,22 @@ config SOC_MWDT_SUPPORT_XTAL
bool
default y
config SOC_TWAI_CONTROLLER_NUM
int
default 2
config SOC_TWAI_MASK_FILTER_NUM
int
default 3
config SOC_TWAI_RANGE_FILTER_NUM
int
default 1
config SOC_TWAI_SUPPORT_SLEEP_RETENTION
bool
default y
config SOC_AES_GDMA
bool
default y
@@ -350,6 +350,22 @@ typedef enum {
GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M clock as the default clock choice */
} soc_periph_glitch_filter_clk_src_t;
//////////////////////////////////////////////////TWAI//////////////////////////////////////////////////////////////////
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_XTAL, (soc_periph_twai_clk_src_t)SOC_MOD_CLK_PLL_F80M}
/**
* @brief TWAI clock source
*/
typedef enum {
TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */
TWAI_CLK_SRC_PLL_F80M = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the source clock */
TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_PLL_F80M, /*!< Select PLL_F80M as the default clock choice */
} soc_periph_twai_clk_src_t;
//////////////////////////////////////////////////MCPWM/////////////////////////////////////////////////////////////////
/**
@@ -40,7 +40,8 @@
// #define SOC_LCDCAM_I80_LCD_SUPPORTED 1 // TODO: [ESP32S31] IDF-14722
// #define SOC_LCDCAM_RGB_LCD_SUPPORTED 1 // TODO: [ESP32S31] IDF-14722
#define SOC_MCPWM_SUPPORTED 1
// #define SOC_TWAI_SUPPORTED 1 // TODO: [ESP32S31] IDF-14719
#define SOC_TWAI_SUPPORTED 1
#define SOC_TWAI_FD_SUPPORTED 1
#define SOC_ETM_SUPPORTED 1
// #define SOC_PARLIO_SUPPORTED 1 // TODO: [ESP32S31] IDF-14711
#define SOC_ASYNC_MEMCPY_SUPPORTED 1
@@ -267,6 +268,12 @@
#define SOC_MWDT_SUPPORT_XTAL (1)
// #define SOC_MWDT_SUPPORT_SLEEP_RETENTION (1)
/*-------------------------- TWAI CAPS ---------------------------------------*/
#define SOC_TWAI_CONTROLLER_NUM 2U
#define SOC_TWAI_MASK_FILTER_NUM 3U
#define SOC_TWAI_RANGE_FILTER_NUM 1U
#define SOC_TWAI_SUPPORT_SLEEP_RETENTION 1
/*-------------------------- AES CAPS ----------------------------------------*/
#define SOC_AES_GDMA (1)
#define SOC_AES_SUPPORT_DMA (1)
@@ -1,19 +1,23 @@
/**
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
#pragma once
#include "soc/soc.h"
#include "esp_bit_defs.h"
#include "soc/reg_base.h"
#ifdef __cplusplus
extern "C" {
#endif
#define REG_TWAIFD_BASE(i) (DR_REG_TWAIFD0_BASE + (i) * 0x1000) // TWAIFD0 and TWAIFD1
/** TWAIFD_DEVICE_ID_VERSION_REG register
* TWAI FD device id status register
*/
#define TWAIFD_DEVICE_ID_VERSION_REG (DR_REG_TWAIFD_BASE + 0x0)
#define TWAIFD_DEVICE_ID_VERSION_REG(i) (REG_TWAIFD_BASE(i) + 0x0)
/** TWAIFD_DEVICE_ID : RO; bitpos: [15:0]; default: 51965;
* Represents whether CAN IP function is mapped correctly on its base address.
*/
@@ -39,7 +43,7 @@ extern "C" {
/** TWAIFD_MODE_SETTINGS_REG register
* TWAI FD mode setting register
*/
#define TWAIFD_MODE_SETTINGS_REG (DR_REG_TWAIFD_BASE + 0x4)
#define TWAIFD_MODE_SETTINGS_REG(i) (REG_TWAIFD_BASE(i) + 0x4)
/** TWAIFD_RST : WO; bitpos: [0]; default: 0;
* Soft reset. Writing logic 1 resets CTU CAN FD. After writing logic 1, logic 0 does
* not need to be written, this bit
@@ -260,7 +264,7 @@ extern "C" {
/** TWAIFD_STATUS_REG register
* TWAI FD status register
*/
#define TWAIFD_STATUS_REG (DR_REG_TWAIFD_BASE + 0x8)
#define TWAIFD_STATUS_REG(i) (REG_TWAIFD_BASE(i) + 0x8)
/** TWAIFD_RXNE : RO; bitpos: [0]; default: 0;
* RX buffer not empty. This bit is 1 when least one frame is stored in RX buffer.
* 0: empty
@@ -396,7 +400,7 @@ extern "C" {
/** TWAIFD_COMMAND_REG register
* TWAI FD command register
*/
#define TWAIFD_COMMAND_REG (DR_REG_TWAIFD_BASE + 0xc)
#define TWAIFD_COMMAND_REG(i) (REG_TWAIFD_BASE(i) + 0xc)
/** TWAIFD_RXRPMV : WO; bitpos: [1]; default: 0;
* RX Buffer read pointer move.
*/
@@ -481,7 +485,7 @@ extern "C" {
/** TWAIFD_INT_STAT_REG register
* TWAI FD command register
*/
#define TWAIFD_INT_STAT_REG (DR_REG_TWAIFD_BASE + 0x10)
#define TWAIFD_INT_STAT_REG(i) (REG_TWAIFD_BASE(i) + 0x10)
/** TWAIFD_RXI_INT_ST : R/W1C; bitpos: [0]; default: 0;
* The masked interrupt status of TWAIFD_RXI_INT.
* Frame received interrupt.
@@ -597,7 +601,7 @@ extern "C" {
/** TWAIFD_INT_ENA_SET_REG register
* TWAI FD interrupt enable register
*/
#define TWAIFD_INT_ENA_SET_REG (DR_REG_TWAIFD_BASE + 0x14)
#define TWAIFD_INT_ENA_SET_REG(i) (REG_TWAIFD_BASE(i) + 0x14)
/** TWAIFD_RXI_INT_ENA_MASK : R/W1S; bitpos: [0]; default: 0;
* Write 1 to enable TWAIFD_RXI_INT.
*/
@@ -686,7 +690,7 @@ extern "C" {
/** TWAIFD_INT_ENA_CLR_REG register
* TWAI FD interrupt enable clear register
*/
#define TWAIFD_INT_ENA_CLR_REG (DR_REG_TWAIFD_BASE + 0x18)
#define TWAIFD_INT_ENA_CLR_REG(i) (REG_TWAIFD_BASE(i) + 0x18)
/** TWAIFD_RXI_INT_ENA_CLR : WO; bitpos: [0]; default: 0;
* Write 1 to clear TWAIFD_RXI_INT_ENA .
*/
@@ -775,7 +779,7 @@ extern "C" {
/** TWAIFD_INT_MASK_SET_REG register
* TWAI FD interrupt mask register
*/
#define TWAIFD_INT_MASK_SET_REG (DR_REG_TWAIFD_BASE + 0x1c)
#define TWAIFD_INT_MASK_SET_REG(i) (REG_TWAIFD_BASE(i) + 0x1c)
/** TWAIFD_RXI_INT_MASK_SET : R/W1S; bitpos: [0]; default: 0;
* Write 1 to mask TWAIFD_RXI_INT.
*/
@@ -864,7 +868,7 @@ extern "C" {
/** TWAIFD_INT_MASK_CLR_REG register
* TWAI FD interrupt mask clear register
*/
#define TWAIFD_INT_MASK_CLR_REG (DR_REG_TWAIFD_BASE + 0x20)
#define TWAIFD_INT_MASK_CLR_REG(i) (REG_TWAIFD_BASE(i) + 0x20)
/** TWAIFD_RXI_INT_MASK_CLR : WO; bitpos: [0]; default: 0;
* Write 1 to clear TWAIFD_RXI_INT_MASK_CLR .
*/
@@ -953,7 +957,7 @@ extern "C" {
/** TWAIFD_BTR_REG register
* TWAI FD bit-timing register
*/
#define TWAIFD_BTR_REG (DR_REG_TWAIFD_BASE + 0x24)
#define TWAIFD_BTR_REG(i) (REG_TWAIFD_BASE(i) + 0x24)
/** TWAIFD_PROP : R/W; bitpos: [6:0]; default: 5;
* Configures the propagation segment of nominal bit rate.
* Measurement unit: time quanta
@@ -998,7 +1002,7 @@ extern "C" {
/** TWAIFD_BTR_FD_REG register
* TWAI FD bit-timing of FD register
*/
#define TWAIFD_BTR_FD_REG (DR_REG_TWAIFD_BASE + 0x28)
#define TWAIFD_BTR_FD_REG(i) (REG_TWAIFD_BASE(i) + 0x28)
/** TWAIFD_PROP_FD : R/W; bitpos: [5:0]; default: 3;
* Configures the propagation segment of data bit rate.
* Measurement unit: time quanta
@@ -1043,7 +1047,7 @@ extern "C" {
/** TWAIFD_EWL_ERP_FAULT_STATE_REG register
* TWAI FD error threshold and status register
*/
#define TWAIFD_EWL_ERP_FAULT_STATE_REG (DR_REG_TWAIFD_BASE + 0x2c)
#define TWAIFD_EWL_ERP_FAULT_STATE_REG(i) (REG_TWAIFD_BASE(i) + 0x2c)
/** TWAIFD_EW_LIMIT : R/W; bitpos: [7:0]; default: 96;
* Error warning limit. If error warning limit is reached interrupt can be generated.
* Error warning limit
@@ -1087,7 +1091,7 @@ extern "C" {
/** TWAIFD_REC_TEC_REG register
* TWAI FD error counters status register
*/
#define TWAIFD_REC_TEC_REG (DR_REG_TWAIFD_BASE + 0x30)
#define TWAIFD_REC_TEC_REG(i) (REG_TWAIFD_BASE(i) + 0x30)
/** TWAIFD_REC_VAL : RO; bitpos: [8:0]; default: 0;
* Represents the receiver error counter value.
*/
@@ -1106,7 +1110,7 @@ extern "C" {
/** TWAIFD_ERR_NORM_ERR_FD_REG register
* TWAI FD special error counters status register
*/
#define TWAIFD_ERR_NORM_ERR_FD_REG (DR_REG_TWAIFD_BASE + 0x34)
#define TWAIFD_ERR_NORM_ERR_FD_REG(i) (REG_TWAIFD_BASE(i) + 0x34)
/** TWAIFD_ERR_NORM_VAL : RO; bitpos: [15:0]; default: 0;
* Represents the number of error in the nominal bit time.
*/
@@ -1125,7 +1129,7 @@ extern "C" {
/** TWAIFD_CTR_PRES_REG register
* TWAI FD error counters pre-define configuration register
*/
#define TWAIFD_CTR_PRES_REG (DR_REG_TWAIFD_BASE + 0x38)
#define TWAIFD_CTR_PRES_REG(i) (REG_TWAIFD_BASE(i) + 0x38)
/** TWAIFD_CTPV : WO; bitpos: [8:0]; default: 0;
* Configures the pre-defined value to set the error counter.
*/
@@ -1175,7 +1179,7 @@ extern "C" {
/** TWAIFD_FILTER_A_MASK_REG register
* TWAI FD filter A mask value register
*/
#define TWAIFD_FILTER_A_MASK_REG (DR_REG_TWAIFD_BASE + 0x3c)
#define TWAIFD_FILTER_A_MASK_REG(i) (REG_TWAIFD_BASE(i) + 0x3c)
/** TWAIFD_BIT_MASK_A_VAL : R/W; bitpos: [28:0]; default: 0;
* Filter A mask. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX
@@ -1190,7 +1194,7 @@ extern "C" {
/** TWAIFD_FILTER_A_VAL_REG register
* TWAI FD filter A bit value register
*/
#define TWAIFD_FILTER_A_VAL_REG (DR_REG_TWAIFD_BASE + 0x40)
#define TWAIFD_FILTER_A_VAL_REG(i) (REG_TWAIFD_BASE(i) + 0x40)
/** TWAIFD_BIT_VAL_A_VAL : R/W; bitpos: [28:0]; default: 0;
* Filter A value. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX buffer.
@@ -1205,7 +1209,7 @@ extern "C" {
/** TWAIFD_FILTER_B_MASK_REG register
* TWAI FD filter B mask value register
*/
#define TWAIFD_FILTER_B_MASK_REG (DR_REG_TWAIFD_BASE + 0x44)
#define TWAIFD_FILTER_B_MASK_REG(i) (REG_TWAIFD_BASE(i) + 0x44)
/** TWAIFD_BIT_MASK_B_VAL : R/W; bitpos: [28:0]; default: 0;
* Filter B mask. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX
@@ -1220,7 +1224,7 @@ extern "C" {
/** TWAIFD_FILTER_B_VAL_REG register
* TWAI FD filter B bit value register
*/
#define TWAIFD_FILTER_B_VAL_REG (DR_REG_TWAIFD_BASE + 0x48)
#define TWAIFD_FILTER_B_VAL_REG(i) (REG_TWAIFD_BASE(i) + 0x48)
/** TWAIFD_BIT_VAL_B_VAL : R/W; bitpos: [28:0]; default: 0;
* Filter B value. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX buffer.
@@ -1235,7 +1239,7 @@ extern "C" {
/** TWAIFD_FILTER_C_MASK_REG register
* TWAI FD filter C mask value register
*/
#define TWAIFD_FILTER_C_MASK_REG (DR_REG_TWAIFD_BASE + 0x4c)
#define TWAIFD_FILTER_C_MASK_REG(i) (REG_TWAIFD_BASE(i) + 0x4c)
/** TWAIFD_BIT_MASK_C_VAL : R/W; bitpos: [28:0]; default: 0;
* Filter C mask. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX
@@ -1250,7 +1254,7 @@ extern "C" {
/** TWAIFD_FILTER_C_VAL_REG register
* TWAI FD filter C bit value register
*/
#define TWAIFD_FILTER_C_VAL_REG (DR_REG_TWAIFD_BASE + 0x50)
#define TWAIFD_FILTER_C_VAL_REG(i) (REG_TWAIFD_BASE(i) + 0x50)
/** TWAIFD_BIT_VAL_C_VAL : R/W; bitpos: [28:0]; default: 0;
* Filter C value. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX buffer.
@@ -1265,7 +1269,7 @@ extern "C" {
/** TWAIFD_FILTER_RAN_LOW_REG register
* TWAI FD filter range low value register
*/
#define TWAIFD_FILTER_RAN_LOW_REG (DR_REG_TWAIFD_BASE + 0x54)
#define TWAIFD_FILTER_RAN_LOW_REG(i) (REG_TWAIFD_BASE(i) + 0x54)
/** TWAIFD_BIT_RAN_LOW_VAL : R/W; bitpos: [28:0]; default: 0;
* Filter Range Low threshold. The identifier format is the same as in IDENTIFIER_W of
* TXT
@@ -1281,7 +1285,7 @@ extern "C" {
/** TWAIFD_FILTER_RAN_HIGH_REG register
* TWAI FD filter range high value register
*/
#define TWAIFD_FILTER_RAN_HIGH_REG (DR_REG_TWAIFD_BASE + 0x58)
#define TWAIFD_FILTER_RAN_HIGH_REG(i) (REG_TWAIFD_BASE(i) + 0x58)
/** TWAIFD_BIT_RAN_HIGH_VAL : R/W; bitpos: [28:0]; default: 0;
* Range filter High threshold. The identifier format is the same as in IDENTIFIER_W
* of TXT
@@ -1297,7 +1301,7 @@ extern "C" {
/** TWAIFD_FILTER_CONTROL_FILTER_STATUS_REG register
* TWAI FD filter control register
*/
#define TWAIFD_FILTER_CONTROL_FILTER_STATUS_REG (DR_REG_TWAIFD_BASE + 0x5c)
#define TWAIFD_FILTER_CONTROL_FILTER_STATUS_REG(i) (REG_TWAIFD_BASE(i) + 0x5c)
/** TWAIFD_FANB : R/W; bitpos: [0]; default: 1;
* CAN Basic Frame is accepted by filter A.
*/
@@ -1442,7 +1446,7 @@ extern "C" {
/** TWAIFD_RX_MEM_INFO_REG register
* TWAI FD rx memory information register
*/
#define TWAIFD_RX_MEM_INFO_REG (DR_REG_TWAIFD_BASE + 0x60)
#define TWAIFD_RX_MEM_INFO_REG(i) (REG_TWAIFD_BASE(i) + 0x60)
/** TWAIFD_RX_BUFF_SIZE : RO; bitpos: [12:0]; default: 128;
* Size of RX buffer in 32-bit words.
*/
@@ -1461,7 +1465,7 @@ extern "C" {
/** TWAIFD_RX_POINTERS_REG register
* TWAI FD rx memory pointer information register
*/
#define TWAIFD_RX_POINTERS_REG (DR_REG_TWAIFD_BASE + 0x64)
#define TWAIFD_RX_POINTERS_REG(i) (REG_TWAIFD_BASE(i) + 0x64)
/** TWAIFD_RX_WPP : RO; bitpos: [11:0]; default: 0;
* Write pointer position in RX buffer. Upon store of received frame write pointer is
* updated.
@@ -1482,7 +1486,7 @@ extern "C" {
/** TWAIFD_RX_STATUS_RX_SETTINGS_REG register
* TWAI FD rx status & setting register
*/
#define TWAIFD_RX_STATUS_RX_SETTINGS_REG (DR_REG_TWAIFD_BASE + 0x68)
#define TWAIFD_RX_STATUS_RX_SETTINGS_REG(i) (REG_TWAIFD_BASE(i) + 0x68)
/** TWAIFD_RXE : RO; bitpos: [0]; default: 1;
* Represents whether or not the RX buffer is empty. RX buffer is empty. There is no
* CAN Frame stored in it.
@@ -1535,7 +1539,7 @@ extern "C" {
/** TWAIFD_RX_DATA_REG register
* TWAI FD received data register
*/
#define TWAIFD_RX_DATA_REG (DR_REG_TWAIFD_BASE + 0x6c)
#define TWAIFD_RX_DATA_REG(i) (REG_TWAIFD_BASE(i) + 0x6c)
/** TWAIFD_RX_DATA : RO; bitpos: [31:0]; default: 0;
* RX buffer data at read pointer position in FIFO. By reading from this register,
* read pointer is auto-
@@ -1551,7 +1555,7 @@ extern "C" {
/** TWAIFD_TX_STATUS_REG register
* TWAI FD TX buffer status register
*/
#define TWAIFD_TX_STATUS_REG (DR_REG_TWAIFD_BASE + 0x70)
#define TWAIFD_TX_STATUS_REG(i) (REG_TWAIFD_BASE(i) + 0x70)
/** TWAIFD_TXTB0_STATE : RO; bitpos: [3:0]; default: 8;
* Status of TXT buffer 1.
* 0b0000 - TXT_NOT_EXIST - TXT buffer does not exist in the core (applies only to TXT
@@ -1624,7 +1628,7 @@ extern "C" {
/** TWAIFD_TX_COMMAND_TXTB_INFO_REG register
* TWAI FD TXT buffer command & information register
*/
#define TWAIFD_TX_COMMAND_TXTB_INFO_REG (DR_REG_TWAIFD_BASE + 0x74)
#define TWAIFD_TX_COMMAND_TXTB_INFO_REG(i) (REG_TWAIFD_BASE(i) + 0x74)
/** TWAIFD_TXCE : WO; bitpos: [0]; default: 0;
* Issues "set empty" command.
*/
@@ -1727,7 +1731,7 @@ extern "C" {
/** TWAIFD_TX_PRIORITY_REG register
* TWAI FD TXT buffer command & information register
*/
#define TWAIFD_TX_PRIORITY_REG (DR_REG_TWAIFD_BASE + 0x78)
#define TWAIFD_TX_PRIORITY_REG(i) (REG_TWAIFD_BASE(i) + 0x78)
/** TWAIFD_TXT1P : R/W; bitpos: [2:0]; default: 1;
* Priority of TXT buffer 1.
*/
@@ -1795,7 +1799,7 @@ extern "C" {
* TWAI FD error capture & retransmit counter & arbitration lost & timestamp
* integration information register
*/
#define TWAIFD_ERR_CAPT_RETR_CTR_ALC_TS_INFO_REG (DR_REG_TWAIFD_BASE + 0x7c)
#define TWAIFD_ERR_CAPT_RETR_CTR_ALC_TS_INFO_REG(i) (REG_TWAIFD_BASE(i) + 0x7c)
/** TWAIFD_ERR_POS : RO; bitpos: [4:0]; default: 31;
* 0b00000 - ERC_POS_SOF - Error in Start of Frame
* 0b00001 - ERC_POS_ARB - Error in Arbitration Filed
@@ -1870,7 +1874,7 @@ extern "C" {
/** TWAIFD_TRV_DELAY_SSP_CFG_REG register
* TWAI FD transmit delay & secondary sample point configuration register
*/
#define TWAIFD_TRV_DELAY_SSP_CFG_REG (DR_REG_TWAIFD_BASE + 0x80)
#define TWAIFD_TRV_DELAY_SSP_CFG_REG(i) (REG_TWAIFD_BASE(i) + 0x80)
/** TWAIFD_TRV_DELAY_VALUE : RO; bitpos: [6:0]; default: 0;
* Measured Transmitter delay in multiple of minimal Time quanta.
*/
@@ -1902,7 +1906,7 @@ extern "C" {
/** TWAIFD_RX_FR_CTR_REG register
* TWAI FD received frame counter register
*/
#define TWAIFD_RX_FR_CTR_REG (DR_REG_TWAIFD_BASE + 0x84)
#define TWAIFD_RX_FR_CTR_REG(i) (REG_TWAIFD_BASE(i) + 0x84)
/** TWAIFD_RX_FR_CTR_VAL : RO; bitpos: [31:0]; default: 0;
* Number of received frames by CTU CAN FD.
*/
@@ -1914,7 +1918,7 @@ extern "C" {
/** TWAIFD_TX_FR_CTR_REG register
* TWAI FD transmitted frame counter register
*/
#define TWAIFD_TX_FR_CTR_REG (DR_REG_TWAIFD_BASE + 0x88)
#define TWAIFD_TX_FR_CTR_REG(i) (REG_TWAIFD_BASE(i) + 0x88)
/** TWAIFD_TX_CTR_VAL : RO; bitpos: [31:0]; default: 0;
* Number of transmitted frames by CTU CAN FD.
*/
@@ -1926,7 +1930,7 @@ extern "C" {
/** TWAIFD_DEBUG_REG register
* TWAI FD debug register
*/
#define TWAIFD_DEBUG_REG (DR_REG_TWAIFD_BASE + 0x8c)
#define TWAIFD_DEBUG_REG(i) (REG_TWAIFD_BASE(i) + 0x8c)
/** TWAIFD_STUFF_COUNT : RO; bitpos: [2:0]; default: 0;
* Actual stuff count modulo 8 as defined in ISO FD protocol. Stuff count is erased
* in the beginning
@@ -2053,7 +2057,7 @@ extern "C" {
/** TWAIFD_YOLO_REG register
* TWAI FD transmitted frame counter register
*/
#define TWAIFD_YOLO_REG (DR_REG_TWAIFD_BASE + 0x90)
#define TWAIFD_YOLO_REG(i) (REG_TWAIFD_BASE(i) + 0x90)
/** TWAIFD_YOLO_VAL : RO; bitpos: [31:0]; default: 3735928559;
* What else could be in this register??
*/
@@ -2065,7 +2069,7 @@ extern "C" {
/** TWAIFD_TIMESTAMP_LOW_REG register
* TWAI FD transmitted frame counter register
*/
#define TWAIFD_TIMESTAMP_LOW_REG (DR_REG_TWAIFD_BASE + 0x94)
#define TWAIFD_TIMESTAMP_LOW_REG(i) (REG_TWAIFD_BASE(i) + 0x94)
/** TWAIFD_TIMESTAMP_LOW : RO; bitpos: [31:0]; default: 0;
* Bits 31:0 of time base.
*/
@@ -2077,7 +2081,7 @@ extern "C" {
/** TWAIFD_TIMESTAMP_HIGH_REG register
* TWAI FD transmitted frame counter register
*/
#define TWAIFD_TIMESTAMP_HIGH_REG (DR_REG_TWAIFD_BASE + 0x98)
#define TWAIFD_TIMESTAMP_HIGH_REG(i) (REG_TWAIFD_BASE(i) + 0x98)
/** TWAIFD_TIMESTAMP_HIGH : RO; bitpos: [31:0]; default: 0;
* Bits 63:32 of time base.
*/
@@ -2089,7 +2093,7 @@ extern "C" {
/** TWAIFD_TIMER_CLK_EN_REG register
* TWAIFD timer clock force enable register.
*/
#define TWAIFD_TIMER_CLK_EN_REG (DR_REG_TWAIFD_BASE + 0xfd4)
#define TWAIFD_TIMER_CLK_EN_REG(i) (REG_TWAIFD_BASE(i) + 0xfd4)
/** TWAIFD_CLK_EN : R/W; bitpos: [0]; default: 0;
* Set this bit to force enable TWAIFD register configuration clock signal.
*/
@@ -2108,7 +2112,7 @@ extern "C" {
/** TWAIFD_TIMER_INT_RAW_REG register
* TWAIFD raw interrupt register.
*/
#define TWAIFD_TIMER_INT_RAW_REG (DR_REG_TWAIFD_BASE + 0xfd8)
#define TWAIFD_TIMER_INT_RAW_REG(i) (REG_TWAIFD_BASE(i) + 0xfd8)
/** TWAIFD_TIMER_OVERFLOW_INT_RAW : R/SS/WTC; bitpos: [0]; default: 0;
* The raw bit signal for read_done interrupt.
*/
@@ -2120,7 +2124,7 @@ extern "C" {
/** TWAIFD_TIMER_INT_ST_REG register
* TWAIFD interrupt status register.
*/
#define TWAIFD_TIMER_INT_ST_REG (DR_REG_TWAIFD_BASE + 0xfdc)
#define TWAIFD_TIMER_INT_ST_REG(i) (REG_TWAIFD_BASE(i) + 0xfdc)
/** TWAIFD_TIMER_OVERFLOW_INT_ST : RO; bitpos: [0]; default: 0;
* The status signal for read_done interrupt.
*/
@@ -2132,7 +2136,7 @@ extern "C" {
/** TWAIFD_TIMER_INT_ENA_REG register
* TWAIFD interrupt enable register.
*/
#define TWAIFD_TIMER_INT_ENA_REG (DR_REG_TWAIFD_BASE + 0xfe0)
#define TWAIFD_TIMER_INT_ENA_REG(i) (REG_TWAIFD_BASE(i) + 0xfe0)
/** TWAIFD_TIMER_OVERFLOW_INT_ENA : R/W; bitpos: [0]; default: 0;
* The enable signal for read_done interrupt.
*/
@@ -2144,7 +2148,7 @@ extern "C" {
/** TWAIFD_TIMER_INT_CLR_REG register
* TWAIFD interrupt clear register.
*/
#define TWAIFD_TIMER_INT_CLR_REG (DR_REG_TWAIFD_BASE + 0xfe4)
#define TWAIFD_TIMER_INT_CLR_REG(i) (REG_TWAIFD_BASE(i) + 0xfe4)
/** TWAIFD_TIMER_OVERFLOW_INT_CLR : WT; bitpos: [0]; default: 0;
* The clear signal for read_done interrupt.
*/
@@ -2156,7 +2160,7 @@ extern "C" {
/** TWAIFD_TIMER_CFG_REG register
* TWAI FD timer configure register.
*/
#define TWAIFD_TIMER_CFG_REG (DR_REG_TWAIFD_BASE + 0xfe8)
#define TWAIFD_TIMER_CFG_REG(i) (REG_TWAIFD_BASE(i) + 0xfe8)
/** TWAIFD_TIMER_CE : R/W; bitpos: [0]; default: 0;
* TWAI FD timer enable register.
* 1b0: Not enable
@@ -2204,7 +2208,7 @@ extern "C" {
/** TWAIFD_TIMER_LD_VAL_L_REG register
* TWAI FD timer pre-load value low register.
*/
#define TWAIFD_TIMER_LD_VAL_L_REG (DR_REG_TWAIFD_BASE + 0xfec)
#define TWAIFD_TIMER_LD_VAL_L_REG(i) (REG_TWAIFD_BASE(i) + 0xfec)
/** TWAIFD_TIMER_LD_VAL_L : R/W; bitpos: [31:0]; default: 0;
* TWAI FD timer count pre-load value register, low part.
*/
@@ -2216,7 +2220,7 @@ extern "C" {
/** TWAIFD_TIMER_LD_VAL_H_REG register
* TWAI FD timer pre-load value high register.
*/
#define TWAIFD_TIMER_LD_VAL_H_REG (DR_REG_TWAIFD_BASE + 0xff0)
#define TWAIFD_TIMER_LD_VAL_H_REG(i) (REG_TWAIFD_BASE(i) + 0xff0)
/** TWAIFD_TIMER_LD_VAL_H : R/W; bitpos: [31:0]; default: 0;
* TWAI FD timer pre-load value register, high part.
* If timestamp valid bit-width less than 33, this field is ignored.
@@ -2229,7 +2233,7 @@ extern "C" {
/** TWAIFD_TIMER_CT_VAL_L_REG register
* TWAI FD timer count-to value low register.
*/
#define TWAIFD_TIMER_CT_VAL_L_REG (DR_REG_TWAIFD_BASE + 0xff4)
#define TWAIFD_TIMER_CT_VAL_L_REG(i) (REG_TWAIFD_BASE(i) + 0xff4)
/** TWAIFD_TIMER_CT_VAL_L : R/W; bitpos: [31:0]; default: 4294967295;
* TWAI FD timer count-to value register, low part.
*/
@@ -2241,7 +2245,7 @@ extern "C" {
/** TWAIFD_TIMER_CT_VAL_H_REG register
* TWAI FD timer count-to value high register.
*/
#define TWAIFD_TIMER_CT_VAL_H_REG (DR_REG_TWAIFD_BASE + 0xff8)
#define TWAIFD_TIMER_CT_VAL_H_REG(i) (REG_TWAIFD_BASE(i) + 0xff8)
/** TWAIFD_TIMER_CT_VAL_H : R/W; bitpos: [31:0]; default: 4294967295;
* TWAI FD timer count-to value register, high part.
* If timestamp valid bit-width less than 33, this field is ignored.
@@ -2254,7 +2258,7 @@ extern "C" {
/** TWAIFD_DATE_VER_REG register
* TWAI FD date version
*/
#define TWAIFD_DATE_VER_REG (DR_REG_TWAIFD_BASE + 0xffc)
#define TWAIFD_DATE_VER_REG(i) (REG_TWAIFD_BASE(i) + 0xffc)
/** TWAIFD_DATE_VER : R/W; bitpos: [31:0]; default: 37823088;
* TWAI FD version
*/
@@ -1,5 +1,5 @@
/**
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2025-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*/
@@ -1299,107 +1299,39 @@ typedef union {
/** Group: filter register */
/** Type of filter_a_mask register
* TWAI FD filter A mask value register
/** Type of filter_mask register
* TWAI FD filter mask value register
*/
typedef union {
struct {
/** bit_mask_a_val : R/W; bitpos: [28:0]; default: 0;
* Filter A mask. The identifier format is the same as in IDENTIFIER_W of TXT buffer
/** bit_mask_val : R/W; bitpos: [28:0]; default: 0;
* Filter mask. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX
* buffer. If filter A is not present, writes to this register have no effect and read
* buffer. If filter is not present, writes to this register have no effect and read
* will return all zeroes.
*/
uint32_t bit_mask_a_val:29;
uint32_t bit_mask_val:29;
uint32_t reserved_29:3;
};
uint32_t val;
} twaifd_filter_a_mask_reg_t;
} twaifd_filter_mask_reg_t;
/** Type of filter_a_val register
* TWAI FD filter A bit value register
/** Type of filter_val register
* TWAI FD filter bit value register
*/
typedef union {
struct {
/** bit_val_a_val : R/W; bitpos: [28:0]; default: 0;
* Filter A value. The identifier format is the same as in IDENTIFIER_W of TXT buffer
/** bit_val : R/W; bitpos: [28:0]; default: 0;
* Filter value. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX buffer.
* If filter A is not present, writes to this register have no effect and read will
* If filter is not present, writes to this register have no effect and read will
* return all zeroes.
*/
uint32_t bit_val_a_val:29;
uint32_t bit_val:29;
uint32_t reserved_29:3;
};
uint32_t val;
} twaifd_filter_a_val_reg_t;
/** Type of filter_b_mask register
* TWAI FD filter B mask value register
*/
typedef union {
struct {
/** bit_mask_b_val : R/W; bitpos: [28:0]; default: 0;
* Filter B mask. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX
* buffer. If filter A is not present, writes to this register have no effect and read
* will return all zeroes.
*/
uint32_t bit_mask_b_val:29;
uint32_t reserved_29:3;
};
uint32_t val;
} twaifd_filter_b_mask_reg_t;
/** Type of filter_b_val register
* TWAI FD filter B bit value register
*/
typedef union {
struct {
/** bit_val_b_val : R/W; bitpos: [28:0]; default: 0;
* Filter B value. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX buffer.
* If filter A is not present, writes to this register have no effect and read will
* return all zeroes.
*/
uint32_t bit_val_b_val:29;
uint32_t reserved_29:3;
};
uint32_t val;
} twaifd_filter_b_val_reg_t;
/** Type of filter_c_mask register
* TWAI FD filter C mask value register
*/
typedef union {
struct {
/** bit_mask_c_val : R/W; bitpos: [28:0]; default: 0;
* Filter C mask. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX
* buffer. If filter A is not present, writes to this register have no effect and read
* will return all zeroes.
*/
uint32_t bit_mask_c_val:29;
uint32_t reserved_29:3;
};
uint32_t val;
} twaifd_filter_c_mask_reg_t;
/** Type of filter_c_val register
* TWAI FD filter C bit value register
*/
typedef union {
struct {
/** bit_val_c_val : R/W; bitpos: [28:0]; default: 0;
* Filter C value. The identifier format is the same as in IDENTIFIER_W of TXT buffer
* or RX buffer.
* If filter A is not present, writes to this register have no effect and read will
* return all zeroes.
*/
uint32_t bit_val_c_val:29;
uint32_t reserved_29:3;
};
uint32_t val;
} twaifd_filter_c_val_reg_t;
} twaifd_filter_val_reg_t;
/** Type of filter_ran_low register
* TWAI FD filter range low value register
@@ -1806,8 +1738,66 @@ typedef union {
uint32_t val;
} twaifd_date_ver_reg_t;
/** TWAI bits filter register
*/
typedef struct {
volatile twaifd_filter_mask_reg_t filter_mask;
volatile twaifd_filter_val_reg_t filter_val;
} twaifd_mask_filter_reg_t;
/** TWAI range filter register
*/
typedef struct {
volatile twaifd_filter_ran_low_reg_t ran_low;
volatile twaifd_filter_ran_high_reg_t ran_high;
} twaifd_range_filter_reg_t;
/**
* @brief TWAI frame buffer register types
*/
typedef union twaifd_frame_buffer_t {
struct {
union {
struct {
uint32_t dlc: 4; // Data length code (0-15)
uint32_t reserved4: 1; // Reserved bit
uint32_t rtr: 1; // Remote transmission request. Note there are no remote frames in CAN FD protocol
uint32_t ide: 1; // Identifier extension bit
uint32_t fdf: 1; // Flexible data-rate format bit
uint32_t reserved8: 1; // Reserved bit
uint32_t brs: 1; // Bit rate switch flag
uint32_t esi: 1; // Error state indicator
uint32_t rwcnt: 5; // Re-transmission counter
uint32_t reserved16: 16; // Reserved bits
};
uint32_t val; // Complete 32-bit register value for format
} format;
union {
struct {
uint32_t identifier_ext: 18; // Extended identifier (18 bits)
uint32_t identifier_base: 11; // Base identifier (11 bits)
uint32_t reserved29: 3; // Reserved bits
};
uint32_t val; // Complete 32-bit register value for identifier
} identifier;
uint32_t timestamp_low; // Lower 32 bits of timestamp
uint32_t timestamp_high; // Upper 32 bits of timestamp
uint32_t data[16]; // Data payload (16 words)
};
uint32_t words[20]; // Raw 32-bit words for direct access
} twaifd_frame_buffer_t;
/** TWAI frame txt buffer registers
*/
typedef struct {
volatile twaifd_frame_buffer_t txt_buffer;
uint32_t reserved_50[44];
} twaifd_frame_mem_t;
typedef struct twaifd_dev_t {
volatile twaifd_device_id_version_reg_t device_id_version;
volatile twaifd_mode_settings_reg_t mode_settings;
volatile twaifd_status_reg_t status;
@@ -1823,14 +1813,8 @@ typedef struct {
volatile twaifd_rec_tec_reg_t rec_tec;
volatile twaifd_err_norm_err_fd_reg_t err_norm_err_fd;
volatile twaifd_ctr_pres_reg_t ctr_pres;
volatile twaifd_filter_a_mask_reg_t filter_a_mask;
volatile twaifd_filter_a_val_reg_t filter_a_val;
volatile twaifd_filter_b_mask_reg_t filter_b_mask;
volatile twaifd_filter_b_val_reg_t filter_b_val;
volatile twaifd_filter_c_mask_reg_t filter_c_mask;
volatile twaifd_filter_c_val_reg_t filter_c_val;
volatile twaifd_filter_ran_low_reg_t filter_ran_low;
volatile twaifd_filter_ran_high_reg_t filter_ran_high;
volatile twaifd_mask_filter_reg_t mask_filters[3];
volatile twaifd_range_filter_reg_t range_filters[1];
volatile twaifd_filter_control_filter_status_reg_t filter_control_filter_status;
volatile twaifd_rx_mem_info_reg_t rx_mem_info;
volatile twaifd_rx_pointers_reg_t rx_pointers;
@@ -1847,7 +1831,9 @@ typedef struct {
volatile twaifd_yolo_reg_t yolo;
volatile twaifd_timestamp_low_reg_t timestamp_low;
volatile twaifd_timestamp_high_reg_t timestamp_high;
uint32_t reserved_09c[974];
uint32_t reserved_09c[25];
volatile twaifd_frame_mem_t txt_mem_cell[8]; // only 4 are actively used
uint32_t reserved_900[437];
volatile twaifd_timer_clk_en_reg_t timer_clk_en;
volatile twaifd_timer_int_raw_reg_t timer_int_raw;
volatile twaifd_timer_int_st_reg_t timer_int_st;
@@ -1861,6 +1847,9 @@ typedef struct {
volatile twaifd_date_ver_reg_t date_ver;
} twaifd_dev_t;
extern twaifd_dev_t TWAIFD0;
extern twaifd_dev_t TWAIFD1;
#ifndef __cplusplus
_Static_assert(sizeof(twaifd_dev_t) == 0x1000, "Invalid size of twaifd_dev_t structure");
@@ -736,6 +736,10 @@ examples/peripherals/twai/twai_error_recovery:
examples/peripherals/twai/twai_network/twai_listen_only:
disable:
- if: SOC_TWAI_SUPPORTED != 1
disable_test:
- if: IDF_TARGET in ["esp32s31"]
temporary: true
reason: no runner
depends_components:
- esp_driver_twai
- esp_hal_twai
@@ -744,6 +748,10 @@ examples/peripherals/twai/twai_network/twai_listen_only:
examples/peripherals/twai/twai_network/twai_sender:
disable:
- if: SOC_TWAI_SUPPORTED != 1
disable_test:
- if: IDF_TARGET in ["esp32s31"]
temporary: true
reason: no runner
depends_components:
- esp_driver_twai
- esp_hal_twai
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
# CyberGear Motor Control Example
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
# TWAI Bus-Off Recovery Example
This example demonstrates how to recover a TWAI node from a Bus-Off error condition and resume communication. The recovery is triggered by physically inducing bus errors and handled using the ESP TWAI on-chip driver with callback support.
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
# TWAI Network Example
@@ -1,5 +1,5 @@
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- |
| Supported Targets | ESP32 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-H2 | ESP32-H21 | ESP32-H4 | ESP32-P4 | ESP32-S2 | ESP32-S3 | ESP32-S31 |
| ----------------- | ----- | -------- | -------- | -------- | -------- | --------- | -------- | -------- | -------- | -------- | --------- |
# TWAI Console Example
@@ -595,6 +595,7 @@ def test_twai_utils_range_filters(twai: TwaiTestHelper) -> None:
@pytest.mark.twai_std
@pytest.mark.temp_skip_ci(targets=['esp32h4'], reason='no runner')
@pytest.mark.temp_skip_ci(targets=['esp32s31'], reason='no runner')
@idf_parametrize('target', soc_filtered_targets('SOC_TWAI_SUPPORTED == 1'), indirect=['target'])
def test_twai_utils_external_communication(twai: TwaiTestHelper, usb_can: CanBusManager) -> None:
test_frames = [
@@ -0,0 +1 @@
CONFIG_EXAMPLE_ENABLE_TWAI_FD=y