From fdeeced62cddc980e74271575cf5088a07936923 Mon Sep 17 00:00:00 2001 From: wanlei Date: Tue, 14 Feb 2023 15:25:10 +0800 Subject: [PATCH] twai: h2 support twai driver --- components/driver/test_apps/twai/README.md | 4 +- .../driver/test_apps/twai/pytest_twai.py | 3 + components/driver/twai/twai.c | 35 ++- .../include/hal/twai_ll.h | 129 ++++++----- components/hal/include/hal/twai_types.h | 12 + .../esp32h2/include/soc/Kconfig.soc_caps.in | 4 + .../soc/esp32h2/include/soc/clk_tree_defs.h | 4 +- .../soc/esp32h2/include/soc/gpio_sig_map.h | 12 +- components/soc/esp32h2/include/soc/soc_caps.h | 3 +- components/soc/esp32h2/twai_periph.c | 22 ++ .../soc/esp32h4/include/soc/clk_tree_defs.h | 15 -- .../soc/esp32h4/include/soc/twai_struct.h | 209 ------------------ docs/docs_not_updated/esp32h2.txt | 1 - docs/en/api-reference/peripherals/twai.rst | 2 +- .../twai/twai_alert_and_recovery/README.md | 4 +- .../peripherals/twai/twai_network/README.md | 4 +- .../peripherals/twai/twai_self_test/README.md | 4 +- 17 files changed, 141 insertions(+), 326 deletions(-) rename components/hal/{esp32h4 => esp32h2}/include/hal/twai_ll.h (86%) create mode 100644 components/soc/esp32h2/twai_periph.c delete mode 100644 components/soc/esp32h4/include/soc/twai_struct.h diff --git a/components/driver/test_apps/twai/README.md b/components/driver/test_apps/twai/README.md index 4d24f6538c..2eccd3e551 100644 --- a/components/driver/test_apps/twai/README.md +++ b/components/driver/test_apps/twai/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | # Enable Socket CAN Device with bitrate 250Kbps diff --git a/components/driver/test_apps/twai/pytest_twai.py b/components/driver/test_apps/twai/pytest_twai.py index 870c2727ce..85c0479857 100644 --- a/components/driver/test_apps/twai/pytest_twai.py +++ b/components/driver/test_apps/twai/pytest_twai.py @@ -12,6 +12,7 @@ from pytest_embedded import Dut @pytest.mark.esp32 @pytest.mark.esp32c3 @pytest.mark.esp32c6 +@pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.generic @@ -39,6 +40,7 @@ def fixture_create_socket_can() -> Bus: @pytest.mark.esp32 @pytest.mark.esp32c3 @pytest.mark.esp32c6 +@pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.skip(reason='Runner not set up yet') @@ -70,6 +72,7 @@ def test_twai_listen_only(dut: Dut, socket_can: Bus) -> None: @pytest.mark.esp32 @pytest.mark.esp32c3 @pytest.mark.esp32c6 +@pytest.mark.esp32h2 @pytest.mark.esp32s2 @pytest.mark.esp32s3 @pytest.mark.skip(reason='Runner not set up yet') diff --git a/components/driver/twai/twai.c b/components/driver/twai/twai.c index 40092377a1..08e7123357 100644 --- a/components/driver/twai/twai.c +++ b/components/driver/twai/twai.c @@ -16,6 +16,8 @@ #include "esp_pm.h" #include "esp_attr.h" #include "esp_heap_caps.h" +#include "clk_tree.h" +#include "clk_ctrl_os.h" #include "driver/gpio.h" #include "esp_private/periph_ctrl.h" #include "esp_private/esp_clk.h" @@ -426,24 +428,7 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_ if (clk_src == 0) { clk_src = TWAI_CLK_SRC_DEFAULT; } - - switch (clk_src) { -#if SOC_TWAI_CLK_SUPPORT_APB - case TWAI_CLK_SRC_APB: - clock_source_hz = esp_clk_apb_freq(); - break; -#endif //SOC_TWAI_CLK_SUPPORT_APB - -#if SOC_TWAI_CLK_SUPPORT_XTAL - case TWAI_CLK_SRC_XTAL: - clock_source_hz = esp_clk_xtal_freq(); - break; -#endif //SOC_TWAI_CLK_SUPPORT_XTAL - - default: - //Invalid clock source - TWAI_CHECK(false, ESP_ERR_INVALID_ARG); - } + clk_tree_src_get_freq_hz(clk_src, CLK_TREE_SRC_FREQ_PRECISION_CACHED, &clock_source_hz); //Check brp validation uint32_t brp = t_config->brp; @@ -469,8 +454,9 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_ p_twai_obj_dummy->alerts_enabled = g_config->alerts_enabled; p_twai_obj_dummy->module = twai_controller_periph_signals.controllers[controller_id].module; - -#if CONFIG_PM_ENABLE && SOC_TWAI_CLK_SUPPORT_APB +#if CONFIG_PM_ENABLE +#if SOC_TWAI_CLK_SUPPORT_APB + // DFS can change APB frequency. So add lock to prevent sleep and APB freq from changing if (clk_src == TWAI_CLK_SRC_APB) { // TODO: pm_lock name should also reflect the controller ID ret = esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, "twai", &(p_twai_obj_dummy->pm_lock)); @@ -478,7 +464,14 @@ esp_err_t twai_driver_install(const twai_general_config_t *g_config, const twai_ goto err; } } -#endif //CONFIG_PM_ENABLE && SOC_TWAI_CLK_SUPPORT_APB +#else // XTAL + // XTAL freq can be closed in light sleep, so we need to create a lock to prevent light sleep + ret = esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, "twai", &(p_twai_obj_dummy->pm_lock)); + if (ret != ESP_OK) { + goto err; + } +#endif //SOC_TWAI_CLK_SUPPORT_APB +#endif //CONFIG_PM_ENABLE //Initialize TWAI peripheral registers, and allocate interrupt TWAI_ENTER_CRITICAL(); diff --git a/components/hal/esp32h4/include/hal/twai_ll.h b/components/hal/esp32h2/include/hal/twai_ll.h similarity index 86% rename from components/hal/esp32h4/include/hal/twai_ll.h rename to components/hal/esp32h2/include/hal/twai_ll.h index a43eca92be..eaffcce348 100644 --- a/components/hal/esp32h4/include/hal/twai_ll.h +++ b/components/hal/esp32h2/include/hal/twai_ll.h @@ -24,8 +24,9 @@ #include "hal/twai_types.h" #include "soc/twai_periph.h" #include "soc/twai_struct.h" +#include "soc/pcr_struct.h" -#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL) +#define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI0) : NULL) #ifdef __cplusplus extern "C" { @@ -96,7 +97,7 @@ ESP_STATIC_ASSERT(sizeof(twai_ll_frame_buffer_t) == 13, "TX/RX buffer type shoul __attribute__((always_inline)) static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) { - (void)hw; + PCR.twai0_func_clk_conf.twai0_func_clk_en = en; } /** @@ -108,8 +109,13 @@ static inline void twai_ll_enable_clock(twai_dev_t *hw, bool en) __attribute__((always_inline)) static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t clk_src) { - (void)hw; - HAL_ASSERT(clk_src == TWAI_CLK_SRC_APB); + switch (clk_src) { + case TWAI_CLK_SRC_DEFAULT: + PCR.twai0_func_clk_conf.twai0_func_clk_sel = 0; + break; + default: + HAL_ASSERT(false); + } } /* ---------------------------- Mode Register ------------------------------- */ @@ -128,7 +134,7 @@ static inline void twai_ll_set_clock_source(twai_dev_t *hw, twai_clock_source_t __attribute__((always_inline)) static inline void twai_ll_enter_reset_mode(twai_dev_t *hw) { - hw->mode_reg.rm = 1; + hw->mode.reset_mode = 1; } /** @@ -145,7 +151,7 @@ static inline void twai_ll_enter_reset_mode(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_exit_reset_mode(twai_dev_t *hw) { - hw->mode_reg.rm = 0; + hw->mode.reset_mode = 0; } /** @@ -156,7 +162,7 @@ static inline void twai_ll_exit_reset_mode(twai_dev_t *hw) __attribute__((always_inline)) static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw) { - return hw->mode_reg.rm; + return hw->mode.reset_mode; } /** @@ -170,15 +176,15 @@ static inline bool twai_ll_is_in_reset_mode(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode) { - if (mode == TWAI_MODE_NORMAL) { //Normal Operating mode - hw->mode_reg.lom = 0; - hw->mode_reg.stm = 0; - } else if (mode == TWAI_MODE_NO_ACK) { //Self Test Mode (No Ack) - hw->mode_reg.lom = 0; - hw->mode_reg.stm = 1; - } else if (mode == TWAI_MODE_LISTEN_ONLY) { //Listen Only Mode - hw->mode_reg.lom = 1; - hw->mode_reg.stm = 0; + if (mode == TWAI_MODE_NORMAL) { //Normal Operating mode + hw->mode.listen_only_mode = 0; + hw->mode.self_test_mode = 0; + } else if (mode == TWAI_MODE_NO_ACK) { //Self Test Mode (No Ack) + hw->mode.listen_only_mode = 0; + hw->mode.self_test_mode = 1; + } else if (mode == TWAI_MODE_LISTEN_ONLY) { //Listen Only Mode + hw->mode.listen_only_mode = 1; + hw->mode.self_test_mode = 0; } } @@ -200,7 +206,7 @@ static inline void twai_ll_set_mode(twai_dev_t *hw, twai_mode_t mode) __attribute__((always_inline)) static inline void twai_ll_set_cmd_tx(twai_dev_t *hw) { - hw->command_reg.tr = 1; + hw->cmd.tx_request = 1; } /** @@ -218,7 +224,7 @@ static inline void twai_ll_set_cmd_tx(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw) { - hw->command_reg.val = 0x03; //Set command_reg.tr and command_reg.at simultaneously for single shot transmittion request + hw->cmd.val = 0x03; //Set cmd.tx_request and cmd.abort_tx simultaneously for single shot transmitting request } /** @@ -238,7 +244,7 @@ static inline void twai_ll_set_cmd_tx_single_shot(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_cmd_abort_tx(twai_dev_t *hw) { - hw->command_reg.at = 1; + hw->cmd.abort_tx = 1; } /** @@ -251,7 +257,7 @@ static inline void twai_ll_set_cmd_abort_tx(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_cmd_release_rx_buffer(twai_dev_t *hw) { - hw->command_reg.rrb = 1; + hw->cmd.release_buffer = 1; } /** @@ -264,7 +270,7 @@ static inline void twai_ll_set_cmd_release_rx_buffer(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_cmd_clear_data_overrun(twai_dev_t *hw) { - hw->command_reg.cdo = 1; + hw->cmd.clear_data_overrun = 1; } /** @@ -284,7 +290,7 @@ static inline void twai_ll_set_cmd_clear_data_overrun(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw) { - hw->command_reg.srr = 1; + hw->cmd.self_rx_request = 1; } /** @@ -303,7 +309,7 @@ static inline void twai_ll_set_cmd_self_rx_request(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw) { - hw->command_reg.val = 0x12; //Set command_reg.srr and command_reg.at simultaneously for single shot self reception request + hw->cmd.val = 0x12; //Set cmd.self_rx_request and cmd.abort_tx simultaneously for single shot self reception request } /* --------------------------- Status Register ------------------------------ */ @@ -317,7 +323,7 @@ static inline void twai_ll_set_cmd_self_rx_single_shot(twai_dev_t *hw) __attribute__((always_inline)) static inline uint32_t twai_ll_get_status(twai_dev_t *hw) { - return hw->status_reg.val; + return hw->status.val; } /** @@ -329,7 +335,7 @@ static inline uint32_t twai_ll_get_status(twai_dev_t *hw) __attribute__((always_inline)) static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw) { - return hw->status_reg.dos; + return hw->status.status_overrun; } /** @@ -341,7 +347,7 @@ static inline bool twai_ll_is_fifo_overrun(twai_dev_t *hw) __attribute__((always_inline)) static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw) { - return hw->status_reg.tcs; + return hw->status.status_transmission_complete; } /* -------------------------- Interrupt Register ---------------------------- */ @@ -358,7 +364,7 @@ static inline bool twai_ll_is_last_tx_successful(twai_dev_t *hw) __attribute__((always_inline)) static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw) { - return hw->interrupt_reg.val; + return hw->interrupt.val; } /* ----------------------- Interrupt Enable Register ------------------------ */ @@ -374,7 +380,7 @@ static inline uint32_t twai_ll_get_and_clear_intrs(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_enabled_intrs(twai_dev_t *hw, uint32_t intr_mask) { - hw->interrupt_enable_reg.val = intr_mask; + hw->interrupt_enable.val = intr_mask; } /* ------------------------ Bus Timing Registers --------------------------- */ @@ -405,16 +411,16 @@ static inline bool twai_ll_check_brp_validation(uint32_t brp) * @param triple_sampling Triple Sampling enable/disable * * @note Must be called in reset mode - * @note ESP32H4 brp can be any even number between 2 to 32768 + * @note ESP32H2 brp can be any even number between 2 to 32768 */ __attribute__((always_inline)) static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t sjw, uint32_t tseg1, uint32_t tseg2, bool triple_sampling) { - hw->bus_timing_0_reg.brp = (brp / 2) - 1; - hw->bus_timing_0_reg.sjw = sjw - 1; - hw->bus_timing_1_reg.tseg1 = tseg1 - 1; - hw->bus_timing_1_reg.tseg2 = tseg2 - 1; - hw->bus_timing_1_reg.sam = triple_sampling; + hw->bus_timing_0.baud_presc = (brp / 2) - 1; + hw->bus_timing_0.sync_jump_width = sjw - 1; + hw->bus_timing_1.time_segment1 = tseg1 - 1; + hw->bus_timing_1.time_segment2 = tseg2 - 1; + hw->bus_timing_1.time_sampling = triple_sampling; } /* ----------------------------- ALC Register ------------------------------- */ @@ -429,7 +435,7 @@ static inline void twai_ll_set_bus_timing(twai_dev_t *hw, uint32_t brp, uint32_t __attribute__((always_inline)) static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) { - (void)hw->arbitration_lost_captue_reg.val; + (void)hw->arb_lost_cap.val; } /* ----------------------------- ECC Register ------------------------------- */ @@ -444,7 +450,7 @@ static inline void twai_ll_clear_arb_lost_cap(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw) { - (void)hw->error_code_capture_reg.val; + (void)hw->err_code_cap.val; } /* ----------------------------- EWL Register ------------------------------- */ @@ -460,7 +466,7 @@ static inline void twai_ll_clear_err_code_cap(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_err_warn_lim(twai_dev_t *hw, uint32_t ewl) { - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->error_warning_limit_reg, ewl, ewl); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->err_warning_limit, err_warning_limit, ewl); } /** @@ -472,7 +478,7 @@ static inline void twai_ll_set_err_warn_lim(twai_dev_t *hw, uint32_t ewl) __attribute__((always_inline)) static inline uint32_t twai_ll_get_err_warn_lim(twai_dev_t *hw) { - return hw->error_warning_limit_reg.val; + return hw->err_warning_limit.val; } /* ------------------------ RX Error Count Register ------------------------- */ @@ -489,7 +495,7 @@ static inline uint32_t twai_ll_get_err_warn_lim(twai_dev_t *hw) __attribute__((always_inline)) static inline uint32_t twai_ll_get_rec(twai_dev_t *hw) { - return hw->rx_error_counter_reg.val; + return hw->rx_err_cnt.val; } /** @@ -503,7 +509,7 @@ static inline uint32_t twai_ll_get_rec(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_rec(twai_dev_t *hw, uint32_t rec) { - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_error_counter_reg, rxerr, rec); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->rx_err_cnt, rx_err_cnt, rec); } /* ------------------------ TX Error Count Register ------------------------- */ @@ -519,7 +525,7 @@ static inline void twai_ll_set_rec(twai_dev_t *hw, uint32_t rec) __attribute__((always_inline)) static inline uint32_t twai_ll_get_tec(twai_dev_t *hw) { - return hw->tx_error_counter_reg.val; + return hw->tx_err_cnt.val; } /** @@ -533,7 +539,7 @@ static inline uint32_t twai_ll_get_tec(twai_dev_t *hw) __attribute__((always_inline)) static inline void twai_ll_set_tec(twai_dev_t *hw, uint32_t tec) { - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_error_counter_reg, txerr, tec); + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->tx_err_cnt, tx_err_cnt, tec); } /* ---------------------- Acceptance Filter Registers ----------------------- */ @@ -548,15 +554,15 @@ static inline void twai_ll_set_tec(twai_dev_t *hw, uint32_t tec) * @note Must be called in reset mode */ __attribute__((always_inline)) -static inline void twai_ll_set_acc_filter(twai_dev_t* hw, uint32_t code, uint32_t mask, bool single_filter) +static inline void twai_ll_set_acc_filter(twai_dev_t *hw, uint32_t code, uint32_t mask, bool single_filter) { - uint32_t code_swapped = __builtin_bswap32(code); - uint32_t mask_swapped = __builtin_bswap32(mask); + uint32_t code_swapped = HAL_SWAP32(code); + uint32_t mask_swapped = HAL_SWAP32(mask); for (int i = 0; i < 4; i++) { HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.acr[i], byte, ((code_swapped >> (i * 8)) & 0xFF)); HAL_FORCE_MODIFY_U32_REG_FIELD(hw->acceptance_filter.amr[i], byte, ((mask_swapped >> (i * 8)) & 0xFF)); } - hw->mode_reg.afm = single_filter; + hw->mode.acceptance_filter_mode = single_filter; } /* ------------------------- TX/RX Buffer Registers ------------------------- */ @@ -591,7 +597,7 @@ static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t { //Copy RX buffer registers into frame for (int i = 0; i < 13; i++) { - rx_frame->bytes[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->tx_rx_buffer[i], byte); + rx_frame->bytes[i] = HAL_FORCE_READ_U32_REG_FIELD(hw->tx_rx_buffer[i], byte); } } @@ -612,7 +618,7 @@ static inline void twai_ll_get_rx_buffer(twai_dev_t *hw, twai_ll_frame_buffer_t */ __attribute__((always_inline)) static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const uint8_t *data, - uint32_t flags, twai_ll_frame_buffer_t *tx_frame) + uint32_t flags, twai_ll_frame_buffer_t *tx_frame) { bool is_extd = flags & TWAI_MSG_FLAG_EXTD; bool is_rtr = flags & TWAI_MSG_FLAG_RTR; @@ -626,12 +632,12 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u //Set ID. The ID registers are big endian and left aligned, therefore a bswap will be required if (is_extd) { - uint32_t id_temp = __builtin_bswap32((id & TWAI_EXTD_ID_MASK) << 3); //((id << 3) >> 8*(3-i)) + uint32_t id_temp = HAL_SWAP32((id & TWAI_EXTD_ID_MASK) << 3); //((id << 3) >> 8*(3-i)) for (int i = 0; i < 4; i++) { tx_frame->extended.id[i] = (id_temp >> (8 * i)) & 0xFF; } } else { - uint32_t id_temp = __builtin_bswap16((id & TWAI_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i)) + uint32_t id_temp = HAL_SWAP16((id & TWAI_STD_ID_MASK) << 5); //((id << 5) >> 8*(1-i)) for (int i = 0; i < 2; i++) { tx_frame->standard.id[i] = (id_temp >> (8 * i)) & 0xFF; } @@ -656,7 +662,7 @@ static inline void twai_ll_format_frame_buffer(uint32_t id, uint8_t dlc, const u */ __attribute__((always_inline)) static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame, uint32_t *id, uint8_t *dlc, - uint8_t *data, uint32_t *flags) + uint8_t *data, uint32_t *flags) { //Copy frame information *dlc = rx_frame->dlc; @@ -672,14 +678,14 @@ static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame, for (int i = 0; i < 4; i++) { id_temp |= rx_frame->extended.id[i] << (8 * i); } - id_temp = __builtin_bswap32(id_temp) >> 3; //((byte[i] << 8*(3-i)) >> 3) + id_temp = HAL_SWAP32(id_temp) >> 3; //((byte[i] << 8*(3-i)) >> 3) *id = id_temp & TWAI_EXTD_ID_MASK; } else { uint32_t id_temp = 0; for (int i = 0; i < 2; i++) { id_temp |= rx_frame->standard.id[i] << (8 * i); } - id_temp = __builtin_bswap16(id_temp) >> 5; //((byte[i] << 8*(1-i)) >> 5) + id_temp = HAL_SWAP16(id_temp) >> 5; //((byte[i] << 8*(1-i)) >> 5) *id = id_temp & TWAI_STD_ID_MASK; } @@ -706,7 +712,7 @@ static inline void twai_ll_parse_frame_buffer(twai_ll_frame_buffer_t *rx_frame, __attribute__((always_inline)) static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw) { - return hw->rx_message_counter_reg.val; + return hw->rx_message_counter.val; } /* ------------------------- Clock Divider Register ------------------------- */ @@ -714,7 +720,7 @@ static inline uint32_t twai_ll_get_rx_msg_count(twai_dev_t *hw) /** * @brief Set CLKOUT Divider and enable/disable * - * Configure CLKOUT. CLKOUT is a pre-scaled version of APB CLK. Divider can be + * Configure CLKOUT. CLKOUT is a pre-scaled version of peripheral source clock. Divider can be * 1, or any even number from 2 to 490. Set the divider to 0 to disable CLKOUT. * * @param hw Start address of the TWAI registers @@ -724,15 +730,16 @@ __attribute__((always_inline)) static inline void twai_ll_set_clkout(twai_dev_t *hw, uint32_t divider) { if (divider >= 2 && divider <= 490) { - hw->clock_divider_reg.co = 0; - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider_reg, cd, (divider / 2) - 1); + hw->clock_divider.clock_off = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, (divider / 2) - 1); } else if (divider == 1) { //Setting the divider reg to max value (255) means a divider of 1 - hw->clock_divider_reg.co = 0; - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider_reg, cd, 255); + hw->clock_divider.clock_off = 0; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 255); } else { - hw->clock_divider_reg.co = 1; - HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider_reg, cd, 0); + hw->clock_divider.clock_off = 1; + HAL_FORCE_MODIFY_U32_REG_FIELD(hw->clock_divider, cd, 0); + } } diff --git a/components/hal/include/hal/twai_types.h b/components/hal/include/hal/twai_types.h index 594d9e2850..2b753d8154 100644 --- a/components/hal/include/hal/twai_types.h +++ b/components/hal/include/hal/twai_types.h @@ -64,6 +64,17 @@ extern "C" { #define TWAI_TIMING_CONFIG_20KBITS() {.quanta_resolution_hz = 400000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} #endif // (SOC_TWAI_BRP_MAX > 128) || (CONFIG_ESP32_REV_MIN_FULL >= 200) +#if CONFIG_XTAL_FREQ == 32 // TWAI_CLK_SRC_XTAL = 32M +#define TWAI_TIMING_CONFIG_25KBITS() {.quanta_resolution_hz = 400000, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} +#define TWAI_TIMING_CONFIG_50KBITS() {.quanta_resolution_hz = 1000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} +#define TWAI_TIMING_CONFIG_100KBITS() {.quanta_resolution_hz = 2000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} +#define TWAI_TIMING_CONFIG_125KBITS() {.quanta_resolution_hz = 4000000, .tseg_1 = 23, .tseg_2 = 8, .sjw = 3, .triple_sampling = false} +#define TWAI_TIMING_CONFIG_250KBITS() {.quanta_resolution_hz = 4000000, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} +#define TWAI_TIMING_CONFIG_500KBITS() {.quanta_resolution_hz = 8000000, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} +#define TWAI_TIMING_CONFIG_800KBITS() {.quanta_resolution_hz = 16000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} +#define TWAI_TIMING_CONFIG_1MBITS() {.quanta_resolution_hz = 16000000, .tseg_1 = 11, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} + +#elif CONFIG_XTAL_FREQ == 40 // TWAI_CLK_SRC_XTAL = 40M #define TWAI_TIMING_CONFIG_25KBITS() {.quanta_resolution_hz = 625000, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false} #define TWAI_TIMING_CONFIG_50KBITS() {.quanta_resolution_hz = 1000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} #define TWAI_TIMING_CONFIG_100KBITS() {.quanta_resolution_hz = 2000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} @@ -72,6 +83,7 @@ extern "C" { #define TWAI_TIMING_CONFIG_500KBITS() {.quanta_resolution_hz = 10000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} #define TWAI_TIMING_CONFIG_800KBITS() {.quanta_resolution_hz = 20000000, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .triple_sampling = false} #define TWAI_TIMING_CONFIG_1MBITS() {.quanta_resolution_hz = 20000000, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .triple_sampling = false} +#endif //CONFIG_XTAL_FREQ /** * @brief Initializer macro for filter configuration to accept all IDs diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 1359968bf0..50f1293e46 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -27,6 +27,10 @@ config SOC_MCPWM_SUPPORTED bool default y +config SOC_TWAI_SUPPORTED + bool + default y + config SOC_GPTIMER_SUPPORTED bool default y diff --git a/components/soc/esp32h2/include/soc/clk_tree_defs.h b/components/soc/esp32h2/include/soc/clk_tree_defs.h index 32986416f9..53effc8534 100644 --- a/components/soc/esp32h2/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h2/include/soc/clk_tree_defs.h @@ -389,8 +389,8 @@ typedef enum { * @brief TWAI clock source */ typedef enum { - TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ - TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ + TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ + TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ } soc_periph_twai_clk_src_t; //////////////////////////////////////////////////ADC/////////////////////////////////////////////////////////////////// diff --git a/components/soc/esp32h2/include/soc/gpio_sig_map.h b/components/soc/esp32h2/include/soc/gpio_sig_map.h index baa9a4f6d3..f4b106bf13 100644 --- a/components/soc/esp32h2/include/soc/gpio_sig_map.h +++ b/components/soc/esp32h2/include/soc/gpio_sig_map.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -135,14 +135,14 @@ #define RMT_SIG_IN1_IDX 72 #define RMT_SIG_OUT1_IDX 72 #define MODEM_DIAG9_IDX 72 -#define CAN0_RX_IDX 73 -#define CAN0_TX_IDX 73 +#define TWAI_RX_IDX 73 +#define TWAI_TX_IDX 73 #define MODEM_DIAG10_IDX 73 -#define CAN0_BUS_OFF_ON_IDX 74 +#define TWAI_BUS_OFF_ON_IDX 74 #define MODEM_DIAG11_IDX 74 -#define CAN0_CLKOUT_IDX 75 +#define TWAI_CLKOUT_IDX 75 #define MODEM_DIAG12_IDX 75 -#define CAN0_STANDBY_IDX 76 +#define TWAI_STANDBY_IDX 76 #define MODEM_DIAG13_IDX 76 #define CTE_ANT6_IDX 77 #define CTE_ANT7_IDX 78 diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 1235bda15b..2fc2667ba0 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -32,7 +32,7 @@ #define SOC_ASYNC_MEMCPY_SUPPORTED 1 #define SOC_PCNT_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 -// #define SOC_TWAI_SUPPORTED 1 // TODO: IDF-6217 +#define SOC_TWAI_SUPPORTED 1 // #define SOC_BT_SUPPORTED 1 // TODO: IDF-6416 // #define SOC_IEEE802154_SUPPORTED 1 // TODO: IDF-6577 #define SOC_GPTIMER_SUPPORTED 1 @@ -359,7 +359,6 @@ #define SOC_TIMER_GROUP_TOTAL_TIMERS (2) #define SOC_TIMER_SUPPORT_ETM (1) -// TODO: IDF-6217 (Copy from esp32c6, need check) /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1 #define SOC_TWAI_CLK_SUPPORT_XTAL 1 diff --git a/components/soc/esp32h2/twai_periph.c b/components/soc/esp32h2/twai_periph.c new file mode 100644 index 0000000000..5104c78ed8 --- /dev/null +++ b/components/soc/esp32h2/twai_periph.c @@ -0,0 +1,22 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "soc/twai_periph.h" +#include "soc/gpio_sig_map.h" + +const twai_controller_signal_conn_t twai_controller_periph_signals = { + .controllers = { + [0] = { + .module = PERIPH_TWAI0_MODULE, + .irq_id = ETS_TWAI0_INTR_SOURCE, + .tx_sig = TWAI_TX_IDX, + .rx_sig = TWAI_RX_IDX, + .bus_off_sig = TWAI_BUS_OFF_ON_IDX, + .clk_out_sig = TWAI_CLKOUT_IDX, + .stand_by_sig = TWAI_STANDBY_IDX, + } + } +}; diff --git a/components/soc/esp32h4/include/soc/clk_tree_defs.h b/components/soc/esp32h4/include/soc/clk_tree_defs.h index 0c0fc8eab4..6e4cc77920 100644 --- a/components/soc/esp32h4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32h4/include/soc/clk_tree_defs.h @@ -296,21 +296,6 @@ typedef enum { GLITCH_FILTER_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB 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_MOD_CLK_APB} - -/** - * @brief TWAI clock source - */ -typedef enum { - TWAI_CLK_SRC_APB = SOC_MOD_CLK_APB, /*!< Select APB as the source clock */ - TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_APB, /*!< Select APB as the default clock choice */ -} soc_periph_twai_clk_src_t; - //////////////////////////////////////////////////ADC/////////////////////////////////////////////////////////////////// /** diff --git a/components/soc/esp32h4/include/soc/twai_struct.h b/components/soc/esp32h4/include/soc/twai_struct.h deleted file mode 100644 index 1178672d84..0000000000 --- a/components/soc/esp32h4/include/soc/twai_struct.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/* ---------------------------- Register Layout ------------------------------ */ - -/* The TWAI peripheral's registers are 8bits, however the ESP32-H4 can only access - * peripheral registers every 32bits. Therefore each TWAI register is mapped to - * the least significant byte of every 32bits. - */ - -typedef volatile struct twai_dev_s { - //Configuration and Control Registers - union { - struct { - uint32_t rm: 1; /* MOD.0 Reset Mode */ - uint32_t lom: 1; /* MOD.1 Listen Only Mode */ - uint32_t stm: 1; /* MOD.2 Self Test Mode */ - uint32_t afm: 1; /* MOD.3 Acceptance Filter Mode */ - uint32_t reserved4: 28; /* Internal Reserved. MOD.4 Sleep Mode not supported */ - }; - uint32_t val; - } mode_reg; /* Address 0x0000 */ - union { - struct { - uint32_t tr: 1; /* CMR.0 Transmission Request */ - uint32_t at: 1; /* CMR.1 Abort Transmission */ - uint32_t rrb: 1; /* CMR.2 Release Receive Buffer */ - uint32_t cdo: 1; /* CMR.3 Clear Data Overrun */ - uint32_t srr: 1; /* CMR.4 Self Reception Request */ - uint32_t reserved5: 27; /* Internal Reserved */ - }; - uint32_t val; - } command_reg; /* Address 0x0004 */ - union { - struct { - uint32_t rbs: 1; /* SR.0 Receive Buffer Status */ - uint32_t dos: 1; /* SR.1 Data Overrun Status */ - uint32_t tbs: 1; /* SR.2 Transmit Buffer Status */ - uint32_t tcs: 1; /* SR.3 Transmission Complete Status */ - uint32_t rs: 1; /* SR.4 Receive Status */ - uint32_t ts: 1; /* SR.5 Transmit Status */ - uint32_t es: 1; /* SR.6 Error Status */ - uint32_t bs: 1; /* SR.7 Bus Status */ - uint32_t ms: 1; /* SR.8 Miss Status */ - uint32_t reserved9: 23; /* Internal Reserved */ - }; - uint32_t val; - } status_reg; /* Address 0x0008 */ - union { - struct { - uint32_t ri: 1; /* IR.0 Receive Interrupt */ - uint32_t ti: 1; /* IR.1 Transmit Interrupt */ - uint32_t ei: 1; /* IR.2 Error Interrupt */ - uint32_t doi: 1; /* IR.3 Data Overrun Interrupt */ - uint32_t reserved4: 1; /* Internal Reserved (Wake-up not supported) */ - uint32_t epi: 1; /* IR.5 Error Passive Interrupt */ - uint32_t ali: 1; /* IR.6 Arbitration Lost Interrupt */ - uint32_t bei: 1; /* IR.7 Bus Error Interrupt */ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } interrupt_reg; /* Address 0x000C */ - union { - struct { - uint32_t rie: 1; /* IER.0 Receive Interrupt Enable */ - uint32_t tie: 1; /* IER.1 Transmit Interrupt Enable */ - uint32_t eie: 1; /* IER.2 Error Interrupt Enable */ - uint32_t doie: 1; /* IER.3 Data Overrun Interrupt Enable */ - uint32_t reserved4: 1; /* Internal Reserved (Wake-up not supported) */ - uint32_t epie: 1; /* IER.5 Error Passive Interrupt Enable */ - uint32_t alie: 1; /* IER.6 Arbitration Lost Interrupt Enable */ - uint32_t beie: 1; /* IER.7 Bus Error Interrupt Enable */ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } interrupt_enable_reg; /* Address 0x0010 */ - uint32_t reserved_14; - union { - struct { - uint32_t brp: 13; /* BTR0[12:0] Baud Rate Prescaler */ - uint32_t reserved13: 1; /* Internal Reserved */ - uint32_t sjw: 2; /* BTR0[15:14] Synchronization Jump Width*/ - uint32_t reserved16: 16; /* Internal Reserved */ - }; - uint32_t val; - } bus_timing_0_reg; /* Address 0x0018 */ - union { - struct { - uint32_t tseg1: 4; /* BTR1[3:0] Timing Segment 1 */ - uint32_t tseg2: 3; /* BTR1[6:4] Timing Segment 2 */ - uint32_t sam: 1; /* BTR1.7 Sampling*/ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } bus_timing_1_reg; /* Address 0x001C */ - uint32_t reserved_20; /* Address 0x0020 (Output control not supported) */ - uint32_t reserved_24; /* Address 0x0024 (Test Register not supported) */ - uint32_t reserved_28; /* Address 0x0028 */ - - //Capture and Counter Registers - union { - struct { - uint32_t alc: 5; /* ALC[4:0] Arbitration lost capture */ - uint32_t reserved5: 27; /* Internal Reserved */ - }; - uint32_t val; - } arbitration_lost_captue_reg; /* Address 0x002C */ - union { - struct { - uint32_t seg: 5; /* ECC[4:0] Error Code Segment 0 to 5 */ - uint32_t dir: 1; /* ECC.5 Error Direction (TX/RX) */ - uint32_t errc: 2; /* ECC[7:6] Error Code */ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } error_code_capture_reg; /* Address 0x0030 */ - union { - struct { - uint32_t ewl: 8; /* EWL[7:0] Error Warning Limit */ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } error_warning_limit_reg; /* Address 0x0034 */ - union { - struct { - uint32_t rxerr: 8; /* RXERR[7:0] Receive Error Counter */ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } rx_error_counter_reg; /* Address 0x0038 */ - union { - struct { - uint32_t txerr: 8; /* TXERR[7:0] Receive Error Counter */ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } tx_error_counter_reg; /* Address 0x003C */ - - //Shared Registers (TX Buff/RX Buff/Acc Filter) - union { - struct { - union { - struct { - uint32_t byte: 8; /* ACRx[7:0] Acceptance Code */ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } acr[4]; - union { - struct { - uint32_t byte: 8; /* AMRx[7:0] Acceptance Mask */ - uint32_t reserved8: 24; /* Internal Reserved */ - }; - uint32_t val; - } amr[4]; - uint32_t reserved_60; - uint32_t reserved_64; - uint32_t reserved_68; - uint32_t reserved_6c; - uint32_t reserved_70; - } acceptance_filter; - union { - struct { - uint32_t byte: 8; /* TX/RX Byte X [7:0] */ - uint32_t reserved24: 24; /* Internal Reserved */ - }; - uint32_t val; - } tx_rx_buffer[13]; - }; /* Address 0x0040 - 0x0070 */ - - //Misc Registers - union { - struct { - uint32_t rmc: 7; /* RMC[6:0] RX Message Counter */ - uint32_t reserved7: 25; /* Internal Reserved */ - }; - uint32_t val; - } rx_message_counter_reg; /* Address 0x0074 */ - uint32_t reserved_78; /* Address 0x0078 (RX Buffer Start Address not supported) */ - union { - struct { - uint32_t cd: 8; /* CDR[7:0] CLKOUT frequency selector based of fOSC */ - uint32_t co: 1; /* CDR.8 CLKOUT enable/disable */ - uint32_t reserved9: 23; /* Internal Reserved */ - }; - uint32_t val; - } clock_divider_reg; /* Address 0x007C */ -} twai_dev_t; - -#ifndef __cplusplus -_Static_assert(sizeof(twai_dev_t) == 128, "TWAI registers should be 32 * 4 bytes"); -#endif - -extern twai_dev_t TWAI; - -#ifdef __cplusplus -} -#endif diff --git a/docs/docs_not_updated/esp32h2.txt b/docs/docs_not_updated/esp32h2.txt index 20eba225d8..80b163e26b 100644 --- a/docs/docs_not_updated/esp32h2.txt +++ b/docs/docs_not_updated/esp32h2.txt @@ -51,7 +51,6 @@ api-reference/peripherals/sdspi_share api-reference/peripherals/adc_continuous api-reference/peripherals/adc_oneshot api-reference/peripherals/usb_host -api-reference/peripherals/twai api-reference/peripherals/usb_device api-reference/peripherals/sdspi_host api-reference/peripherals/i2s diff --git a/docs/en/api-reference/peripherals/twai.rst b/docs/en/api-reference/peripherals/twai.rst index 2457acc186..69bde327fe 100644 --- a/docs/en/api-reference/peripherals/twai.rst +++ b/docs/en/api-reference/peripherals/twai.rst @@ -159,7 +159,7 @@ The operating bit rate of the TWAI driver is configured using the :cpp:type:`twa 2. **Timing Segment 1** consists of 1 to 16 time quanta before sample point 3. **Timing Segment 2** consists of 1 to 8 time quanta after sample point -{IDF_TARGET_MAX_BRP:default="128", esp32="128", esp32s2="32768", esp32c3="16384", esp32c6="16384"} +{IDF_TARGET_MAX_BRP:default="128", esp32="128", esp32s2="32768", esp32s3="16384", esp32c3="16384", esp32c6="32768", esp32h2="32768"} The **Baudrate Prescaler** is used to determine the period of each time quantum by dividing the TWAI controller's source clock. On the {IDF_TARGET_NAME}, the ``brp`` can be **any even number from 2 to {IDF_TARGET_MAX_BRP}**. Alternatively, you can decide the resolution of each quantum, by setting :cpp:member:`twai_timing_config_t::quanta_resolution_hz` to a non-zero value. In this way, the driver can calculate the underlying ``brp`` value for you. It's useful when you set different clock sources but want the bitrate to keep the same. diff --git a/examples/peripherals/twai/twai_alert_and_recovery/README.md b/examples/peripherals/twai/twai_alert_and_recovery/README.md index 22dd94c812..0c8b1c9a96 100644 --- a/examples/peripherals/twai/twai_alert_and_recovery/README.md +++ b/examples/peripherals/twai/twai_alert_and_recovery/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | # TWAI Alert and Recovery Example diff --git a/examples/peripherals/twai/twai_network/README.md b/examples/peripherals/twai/twai_network/README.md index 1d0e4af6e5..dd0fd36ccf 100644 --- a/examples/peripherals/twai/twai_network/README.md +++ b/examples/peripherals/twai/twai_network/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | # TWAI Network Example diff --git a/examples/peripherals/twai/twai_self_test/README.md b/examples/peripherals/twai/twai_self_test/README.md index 7e57402ea7..38902161dd 100644 --- a/examples/peripherals/twai/twai_self_test/README.md +++ b/examples/peripherals/twai/twai_self_test/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | # TWAI Self Test Example