diff --git a/components/driver/CMakeLists.txt b/components/driver/CMakeLists.txt index 8f222aeecf..d3c3e125ed 100644 --- a/components/driver/CMakeLists.txt +++ b/components/driver/CMakeLists.txt @@ -32,7 +32,7 @@ endif() # TWAI related source files # TWAIFD is not supported by the legacy driver -if(CONFIG_SOC_TWAI_SUPPORTED AND NOT CONFIG_SOC_TWAI_SUPPORT_FD) +if(CONFIG_SOC_TWAI_SUPPORTED AND NOT CONFIG_SOC_TWAI_FD_SUPPORTED) list(APPEND srcs "twai/twai.c") list(APPEND ldfragments "twai/linker.lf") endif() @@ -45,7 +45,7 @@ else() idf_component_register(SRCS "${srcs}" INCLUDE_DIRS ${includes} PRIV_REQUIRES esp_timer esp_mm esp_driver_gpio esp_ringbuf esp_pm - REQUIRES freertos soc hal esp_hw_support esp_hal_i2c + REQUIRES esp_hal_i2c esp_hal_twai LDFRAGMENTS ${ldfragments} ) endif() diff --git a/components/driver/test_apps/.build-test-rules.yml b/components/driver/test_apps/.build-test-rules.yml index 1b3de67e68..79b8aef954 100644 --- a/components/driver/test_apps/.build-test-rules.yml +++ b/components/driver/test_apps/.build-test-rules.yml @@ -10,7 +10,7 @@ components/driver/test_apps/legacy_i2c_driver: components/driver/test_apps/legacy_twai: disable: - - if: SOC_TWAI_SUPPORTED != 1 or SOC_TWAI_SUPPORT_FD == 1 + - if: SOC_TWAI_SUPPORTED != 1 or SOC_TWAI_FD_SUPPORTED == 1 reason: legacy driver doesn't support FD - if: IDF_TARGET == "esp32p4" temporary: true diff --git a/components/driver/twai/linker.lf b/components/driver/twai/linker.lf index 968506ed33..fa7c168e69 100644 --- a/components/driver/twai/linker.lf +++ b/components/driver/twai/linker.lf @@ -8,7 +8,7 @@ entries: twai: twai_intr_handler_main (noflash) [mapping:twai_hal_legacy] -archive: libhal.a +archive: libesp_hal_twai.a entries: if TWAI_ISR_IN_IRAM = y || TWAI_ISR_IN_IRAM_LEGACY = y: twai_hal_v1: twai_hal_decode_interrupt (noflash) diff --git a/components/driver/twai/twai.c b/components/driver/twai/twai.c index 3b107c7b71..141abe966f 100644 --- a/components/driver/twai/twai.c +++ b/components/driver/twai/twai.c @@ -27,7 +27,7 @@ #include "soc/soc_caps.h" #include "soc/soc.h" #include "soc/io_mux_reg.h" -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "hal/twai_hal.h" #include "hal/twai_ll.h" #include "esp_rom_gpio.h" @@ -139,7 +139,7 @@ static void twai_alert_handler(twai_obj_t *p_twai_obj, uint32_t alert_code, int static inline void twai_handle_rx_buffer_frames(twai_obj_t *p_twai_obj, BaseType_t *task_woken, int *alert_req) { -#ifdef SOC_TWAI_SUPPORTS_RX_STATUS +#if TWAI_LL_SUPPORT(RX_STATUS) uint32_t msg_count = twai_hal_get_rx_msg_count(p_twai_obj->hal); for (uint32_t i = 0; i < msg_count; i++) { @@ -158,7 +158,7 @@ static inline void twai_handle_rx_buffer_frames(twai_obj_t *p_twai_obj, BaseType twai_alert_handler(p_twai_obj, TWAI_ALERT_RX_FIFO_OVERRUN, alert_req); } } -#else //SOC_TWAI_SUPPORTS_RX_STATUS +#else uint32_t msg_count = twai_hal_get_rx_msg_count(p_twai_obj->hal); bool overrun = false; //Clear all valid RX frames @@ -183,7 +183,7 @@ static inline void twai_handle_rx_buffer_frames(twai_obj_t *p_twai_obj, BaseType p_twai_obj->rx_overrun_count += twai_hal_clear_rx_fifo_overrun(p_twai_obj->hal); twai_alert_handler(p_twai_obj, TWAI_ALERT_RX_FIFO_OVERRUN, alert_req); } -#endif //SOC_TWAI_SUPPORTS_RX_STATUS +#endif // TWAI_LL_SUPPORT(RX_STATUS) } static inline void twai_handle_tx_buffer_frame(twai_obj_t *p_twai_obj, bool tx_success, BaseType_t *task_woken, int *alert_req) @@ -429,7 +429,7 @@ static esp_err_t twai_alloc_driver_obj(const twai_general_config_t *g_config, tw p_obj->hal = (twai_hal_context_t *)(p_obj + 1); //hal context is place at end of driver context #if CONFIG_PM_ENABLE -#if SOC_TWAI_CLK_SUPPORT_APB +#if TWAI_LL_SUPPORT(APB_CLK) // 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 @@ -444,7 +444,7 @@ static esp_err_t twai_alloc_driver_obj(const twai_general_config_t *g_config, tw if (ret != ESP_OK) { goto err; } -#endif //SOC_TWAI_CLK_SUPPORT_APB +#endif // TWAI_LL_SUPPORT(APB_CLK) #endif //CONFIG_PM_ENABLE #if TWAI_USE_RETENTION_LINK diff --git a/components/esp_driver_twai/CMakeLists.txt b/components/esp_driver_twai/CMakeLists.txt index fcbc89d540..bf4cf0ca48 100644 --- a/components/esp_driver_twai/CMakeLists.txt +++ b/components/esp_driver_twai/CMakeLists.txt @@ -15,6 +15,7 @@ endif() idf_component_register( SRCS ${srcs} INCLUDE_DIRS ${public_include} + REQUIRES esp_hal_twai PRIV_REQUIRES ${priv_req} LDFRAGMENTS "linker.lf" ) diff --git a/components/esp_driver_twai/esp_twai_onchip.c b/components/esp_driver_twai/esp_twai_onchip.c index 31e42b22d5..5311c5953f 100644 --- a/components/esp_driver_twai/esp_twai_onchip.c +++ b/components/esp_driver_twai/esp_twai_onchip.c @@ -9,6 +9,11 @@ #include "esp_private/twai_interface.h" #include "esp_private/twai_utils.h" #include "twai_private.h" +#include "hal/twai_periph.h" +#include "hal/twai_hal.h" +#if SOC_HAS(TWAI_FD) +#include "hal/twaifd_ll.h" +#endif #if !SOC_RCC_IS_INDEPENDENT #define TWAI_RCC_ATOMIC() PERIPH_RCC_ATOMIC() @@ -22,26 +27,6 @@ #define TWAI_PERI_ATOMIC() #endif -#if SOC_TWAI_SUPPORT_FD -#include "hal/twaifd_ll.h" -static void _twai_rcc_clock_ctrl(uint8_t ctrlr_id, bool enable) -{ - TWAI_RCC_ATOMIC() { - twaifd_ll_enable_bus_clock(ctrlr_id, enable); - twaifd_ll_reset_register(ctrlr_id); - } - TWAI_PERI_ATOMIC() { - twaifd_ll_enable_clock(ctrlr_id, enable); - } -} -static void _twai_rcc_clock_sel(uint8_t ctrlr_id, twai_clock_source_t clock) -{ - TWAI_PERI_ATOMIC() { - twaifd_ll_set_clock_source(ctrlr_id, clock); - } -} -#else -#include "hal/twai_ll.h" static void _twai_rcc_clock_ctrl(uint8_t ctrlr_id, bool enable) { TWAI_RCC_ATOMIC() { @@ -58,7 +43,6 @@ static void _twai_rcc_clock_sel(uint8_t ctrlr_id, twai_clock_source_t clock) twai_ll_set_clock_source(ctrlr_id, clock); } } -#endif //SOC_TWAI_SUPPORT_FD #define TWAI_IDLE_EVENT_BIT BIT0 //event used for tx_wait_all_done @@ -254,7 +238,7 @@ static void _node_isr_main(void *arg) if (events & TWAI_HAL_EVENT_RX_BUFF_FRAME) { while (twai_hal_get_rx_msg_count(twai_ctx->hal)) { if (twai_hal_read_rx_fifo(twai_ctx->hal, &twai_ctx->rcv_buff)) { -#if !SOC_TWAI_SUPPORT_FD +#if !SOC_HAS(TWAI_FD) // the legacy hardware filter don't support split frame format std/ext in filter, check in software if (!twai_hal_soft_filter_check_msg(twai_ctx->hal, &twai_ctx->rcv_buff)) { continue; // soft filter to check if id type match the filter config @@ -267,7 +251,7 @@ static void _node_isr_main(void *arg) atomic_store(&twai_ctx->rx_isr, false); } } else { // failed to read from RX fifo because message is overrun -#if !SOC_TWAI_SUPPORTS_RX_STATUS +#if !TWAI_LL_SUPPORT(RX_STATUS) twai_hal_clear_rx_fifo_overrun(twai_ctx->hal); break; #endif @@ -415,7 +399,7 @@ static esp_err_t _node_set_bit_timing(twai_node_handle_t node, const twai_timing if (timing) { twai_hal_configure_timing(twai_ctx->hal, timing); } -#if SOC_TWAI_SUPPORT_FD +#if SOC_HAS(TWAI_FD) if (timing_fd) { twai_ctx->valid_fd_timing = true; twai_hal_configure_timing_fd(twai_ctx->hal, timing_fd); @@ -428,7 +412,7 @@ static esp_err_t _node_set_bit_timing(twai_node_handle_t node, const twai_timing static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, twai_clock_source_t clk_src, const twai_timing_basic_config_t *timing, const twai_timing_basic_config_t *timing_fd) { ESP_RETURN_ON_FALSE(timing->bitrate, ESP_ERR_INVALID_ARG, TAG, "classic timing config is required"); -#if !SOC_TWAI_SUPPORT_FD +#if !SOC_HAS(TWAI_FD) ESP_RETURN_ON_FALSE((!timing_fd->bitrate) || (timing_fd->bitrate == timing->bitrate), ESP_ERR_INVALID_ARG, TAG, "FD stage bitrate is not supported"); #endif twai_clock_source_t root_clock_src = clk_src ? clk_src : TWAI_CLK_SRC_DEFAULT; @@ -452,7 +436,7 @@ static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, twai_clock_s if (timing->bitrate != real_baud) { ESP_LOGW(TAG, "bitrate precision loss, adjust from %ld to %ld", timing->bitrate, real_baud); } -#if SOC_TWAI_SUPPORT_FD +#if SOC_HAS(TWAI_FD) twai_timing_advanced_config_t timing_adv_fd = { .clk_src = root_clock_src, }; if (timing_fd->bitrate) { real_baud = twai_node_timing_calc_param(source_freq, timing_fd, &hw_const, &timing_adv_fd); @@ -528,13 +512,13 @@ static esp_err_t _node_config_mask_filter(twai_node_handle_t node, uint8_t filte uint32_t id = mask_cfg->num_of_ids ? mask_cfg->id_list[0] : mask_cfg->id; bool full_close = (mask_cfg->mask == UINT32_MAX) && (id == UINT32_MAX); ESP_RETURN_ON_FALSE(full_close || mask_cfg->dual_filter || mask_cfg->is_ext || !((mask_cfg->mask | id) & ~TWAI_STD_ID_MASK), ESP_ERR_INVALID_ARG, TAG, "std_id only (is_ext=0) but valid id/mask larger than 11 bits"); -#if SOC_TWAI_SUPPORT_FD +#if SOC_HAS(TWAI_FD) // FD targets don't support Dual filter ESP_RETURN_ON_FALSE(!mask_cfg->dual_filter, ESP_ERR_NOT_SUPPORTED, TAG, "The target don't support Dual Filter"); #endif ESP_RETURN_ON_FALSE(atomic_load(&twai_ctx->state) == TWAI_ERROR_BUS_OFF, ESP_ERR_INVALID_STATE, TAG, "filter config must do when node stopped"); - twai_hal_configure_filter(twai_ctx->hal, filter_id, mask_cfg); + twai_hal_configure_mask_filter(twai_ctx->hal, filter_id, mask_cfg); return ESP_OK; } @@ -588,7 +572,7 @@ static esp_err_t _node_queue_tx(twai_node_handle_t node, const twai_frame_t *fra if (frame->header.dlc && frame->buffer_len) { ESP_RETURN_ON_FALSE_ISR(frame->header.dlc == twaifd_len2dlc(frame->buffer_len), ESP_ERR_INVALID_ARG, TAG, "unmatched dlc(%i) and buffer_len(%i)", frame->header.dlc, twaifd_len2dlc(frame->buffer_len)); } -#if !SOC_TWAI_SUPPORT_FD +#if !SOC_HAS(TWAI_FD) ESP_RETURN_ON_FALSE_ISR(!frame->header.fdf || frame->buffer_len <= TWAI_FRAME_MAX_LEN, ESP_ERR_INVALID_ARG, TAG, "fdf flag or buffer_len not supported"); #endif ESP_RETURN_ON_FALSE_ISR((frame->header.dlc <= TWAIFD_FRAME_MAX_DLC) && \ @@ -715,13 +699,13 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa // Configure GPIO ESP_GOTO_ON_ERROR(_node_config_io(node, node_config), err, TAG, "gpio config failed"); #if CONFIG_PM_ENABLE -#if SOC_TWAI_CLK_SUPPORT_APB +#if TWAI_LL_SUPPORT(APB_CLK) // DFS can change APB frequency. So add lock to prevent sleep and APB freq from changing ESP_GOTO_ON_ERROR(esp_pm_lock_create(ESP_PM_APB_FREQ_MAX, 0, twai_periph_signals[ctrlr_id].module_name, &node->pm_lock), err, TAG, "init power manager failed"); #else // XTAL // XTAL freq can be closed in light sleep, so we need to create a lock to prevent light sleep ESP_GOTO_ON_ERROR(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, twai_periph_signals[ctrlr_id].module_name, &node->pm_lock), err, TAG, "init power manager failed"); -#endif //SOC_TWAI_CLK_SUPPORT_APB +#endif //TWAI_LL_SUPPORT(APB_CLK) #endif //CONFIG_PM_ENABLE node->api_base.enable = _node_enable; diff --git a/components/esp_driver_twai/include/esp_twai_onchip.h b/components/esp_driver_twai/include/esp_twai_onchip.h index e390d3abd6..643cc3177e 100644 --- a/components/esp_driver_twai/include/esp_twai_onchip.h +++ b/components/esp_driver_twai/include/esp_twai_onchip.h @@ -31,8 +31,8 @@ typedef struct { int intr_priority; /**< Interrupt priority, [0:3] */ struct { uint32_t enable_self_test: 1; /**< Transmission does not require acknowledgment. Use this mode for self testing */ - uint32_t enable_loopback: 1; /**< The TWAI controller receive back frames what it send out */ - uint32_t enable_listen_only: 1; /**< The TWAI controller will not influence the bus (No transmissions or acknowledgments) but can receive messages */ + uint32_t enable_loopback: 1; /**< The TWAI controller receives back frames that it sends out, but does not acknowledge them */ + uint32_t enable_listen_only: 1; /**< No transmissions or acknowledgements. The controller only monitors the bus without participating */ uint32_t no_receive_rtr: 1; /**< Don't receive remote frames */ } flags; /**< Misc configuration flags */ } twai_onchip_node_config_t; diff --git a/components/esp_driver_twai/linker.lf b/components/esp_driver_twai/linker.lf index 813335e170..2fcbcef592 100644 --- a/components/esp_driver_twai/linker.lf +++ b/components/esp_driver_twai/linker.lf @@ -12,10 +12,10 @@ entries: esp_twai: twai_node_transmit (noflash) [mapping:twai_hal] -archive: libhal.a +archive: libesp_hal_twai.a entries: if TWAI_ISR_IN_IRAM = y: - if SOC_TWAI_SUPPORT_FD = y: + if SOC_TWAI_FD_SUPPORTED = y: twai_hal_v2: twai_hal_format_frame (noflash) twai_hal_v2: twai_hal_parse_frame (noflash) twai_hal_v2: twai_hal_set_tx_buffer_and_transmit (noflash) diff --git a/components/esp_driver_twai/test_apps/test_twai/CMakeLists.txt b/components/esp_driver_twai/test_apps/test_twai/CMakeLists.txt index 1ce0b1532e..37e33fcf5b 100644 --- a/components/esp_driver_twai/test_apps/test_twai/CMakeLists.txt +++ b/components/esp_driver_twai/test_apps/test_twai/CMakeLists.txt @@ -15,10 +15,18 @@ check_register_rw_half_word(SOC_MODULES "twai*" "pcr" "hp_sys_clkrst" HAL_MODULES "twai*") if(CONFIG_COMPILER_DUMP_RTL_FILES) + # Collect RTL directories in a variable for readability. Join them + # with commas so they are passed as a single --rtl-dirs argument to the script. + set(TWAI_RTL_DIRS + ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_twai + ${CMAKE_BINARY_DIR}/esp-idf/hal + ${CMAKE_BINARY_DIR}/esp-idf/esp_hal_twai + ) + string(JOIN "," TWAI_RTL_DIRS_JOINED ${TWAI_RTL_DIRS}) add_custom_target( check_test_app_sections ALL COMMAND ${PYTHON} $ENV{IDF_PATH}/tools/ci/check_callgraph.py - --rtl-dirs ${CMAKE_BINARY_DIR}/esp-idf/esp_driver_twai/,${CMAKE_BINARY_DIR}/esp-idf/hal/ + --rtl-dirs ${TWAI_RTL_DIRS_JOINED} --elf-file ${CMAKE_BINARY_DIR}/test_twai.elf find-refs --from-sections=.iram0.text diff --git a/components/esp_driver_twai/test_apps/test_twai/main/CMakeLists.txt b/components/esp_driver_twai/test_apps/test_twai/main/CMakeLists.txt index a667ea09ec..aac256b989 100644 --- a/components/esp_driver_twai/test_apps/test_twai/main/CMakeLists.txt +++ b/components/esp_driver_twai/test_apps/test_twai/main/CMakeLists.txt @@ -4,7 +4,7 @@ if(CONFIG_SOC_TWAI_SUPPORTED) list(APPEND srcs "test_twai_common.cpp" "test_twai_network.cpp") endif() -if(CONFIG_SOC_TWAI_SUPPORT_FD) +if(CONFIG_SOC_TWAI_FD_SUPPORTED) list(APPEND srcs "test_twai_fd.cpp") endif() diff --git a/components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.cpp b/components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.cpp index 1c74670546..86fb1b720f 100644 --- a/components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.cpp +++ b/components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.cpp @@ -17,7 +17,7 @@ #include "freertos/FreeRTOS.h" #include "esp_twai.h" #include "esp_twai_onchip.h" -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "esp_private/gpio.h" #include "driver/uart.h" // for baudrate detection @@ -344,7 +344,7 @@ TEST_CASE("twai mask filter (loopback)", "[twai]") } //------------------ Dual Filter Test -------------------// -#if !SOC_TWAI_SUPPORT_FD +#if !SOC_HAS(TWAI_FD) static IRAM_ATTR bool test_dual_filter_rx_done_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx) { uint8_t *test_ctrl = (uint8_t *)user_ctx; @@ -551,7 +551,7 @@ TEST_CASE("twai bus off recovery (loopback)", "[twai]") } // recover node -#if SOC_TWAI_SUPPORT_FD +#if SOC_HAS(TWAI_FD) TEST_ASSERT_GREATER_THAN(200, node_status.tx_error_count); #else TEST_ASSERT_EQUAL(128, node_status.tx_error_count); // TEC become 128 when bus off on legacy chips diff --git a/components/esp_driver_twai/twai_private.h b/components/esp_driver_twai/twai_private.h index 539e1c56a1..db4364163c 100644 --- a/components/esp_driver_twai/twai_private.h +++ b/components/esp_driver_twai/twai_private.h @@ -25,8 +25,6 @@ #include "esp_check.h" #include "esp_err.h" #include "soc/soc_caps.h" -#include "soc/twai_periph.h" -#include "hal/twai_hal.h" #include "esp_intr_alloc.h" #include "esp_heap_caps.h" #include "esp_clk_tree.h" diff --git a/components/esp_hal_gpio/esp32/rtc_io_periph.c b/components/esp_hal_gpio/esp32/rtc_io_periph.c index 98fb5727f5..2f364a484b 100644 --- a/components/esp_hal_gpio/esp32/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" diff --git a/components/esp_hal_gpio/esp32/sdm_periph.c b/components/esp_hal_gpio/esp32/sdm_periph.c index c165727652..a9646d6820 100644 --- a/components/esp_hal_gpio/esp32/sdm_periph.c +++ b/components/esp_hal_gpio/esp32/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32c2/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32c2/dedic_gpio_periph.c index 4a3b097549..d19d00379e 100644 --- a/components/esp_hal_gpio/esp32c2/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32c2/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32c3/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32c3/dedic_gpio_periph.c index 4a3b097549..d19d00379e 100644 --- a/components/esp_hal_gpio/esp32c3/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32c3/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32c3/sdm_periph.c b/components/esp_hal_gpio/esp32c3/sdm_periph.c index 31a8d63b95..f9059af45c 100644 --- a/components/esp_hal_gpio/esp32c3/sdm_periph.c +++ b/components/esp_hal_gpio/esp32c3/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32c5/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32c5/dedic_gpio_periph.c index 43056dc5e6..d9949ab4dd 100644 --- a/components/esp_hal_gpio/esp32c5/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32c5/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32c5/rtc_io_periph.c b/components/esp_hal_gpio/esp32c5/rtc_io_periph.c index 78ef135737..045d35e624 100644 --- a/components/esp_hal_gpio/esp32c5/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32c5/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" diff --git a/components/esp_hal_gpio/esp32c5/sdm_periph.c b/components/esp_hal_gpio/esp32c5/sdm_periph.c index ce758065f4..315a4c5d79 100644 --- a/components/esp_hal_gpio/esp32c5/sdm_periph.c +++ b/components/esp_hal_gpio/esp32c5/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32c6/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32c6/dedic_gpio_periph.c index 6406e449c5..66eb7d1bed 100644 --- a/components/esp_hal_gpio/esp32c6/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32c6/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32c6/rtc_io_periph.c b/components/esp_hal_gpio/esp32c6/rtc_io_periph.c index 640da05890..450f5c9b43 100644 --- a/components/esp_hal_gpio/esp32c6/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32c6/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" diff --git a/components/esp_hal_gpio/esp32c6/sdm_periph.c b/components/esp_hal_gpio/esp32c6/sdm_periph.c index 372fa1be0d..9356660742 100644 --- a/components/esp_hal_gpio/esp32c6/sdm_periph.c +++ b/components/esp_hal_gpio/esp32c6/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32c61/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32c61/dedic_gpio_periph.c index 43056dc5e6..d9949ab4dd 100644 --- a/components/esp_hal_gpio/esp32c61/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32c61/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32c61/rtc_io_periph.c b/components/esp_hal_gpio/esp32c61/rtc_io_periph.c index 128e55b3e5..5afb6fe371 100644 --- a/components/esp_hal_gpio/esp32c61/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32c61/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" diff --git a/components/esp_hal_gpio/esp32h2/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32h2/dedic_gpio_periph.c index 4a3b097549..d19d00379e 100644 --- a/components/esp_hal_gpio/esp32h2/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32h2/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32h2/rtc_io_periph.c b/components/esp_hal_gpio/esp32h2/rtc_io_periph.c index 6e55c7071d..15ca372278 100644 --- a/components/esp_hal_gpio/esp32h2/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32h2/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" #include "soc/rtc_io_channel.h" diff --git a/components/esp_hal_gpio/esp32h2/sdm_periph.c b/components/esp_hal_gpio/esp32h2/sdm_periph.c index 372fa1be0d..9356660742 100644 --- a/components/esp_hal_gpio/esp32h2/sdm_periph.c +++ b/components/esp_hal_gpio/esp32h2/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32h21/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32h21/dedic_gpio_periph.c index 6406e449c5..66eb7d1bed 100644 --- a/components/esp_hal_gpio/esp32h21/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32h21/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32h21/rtc_io_periph.c b/components/esp_hal_gpio/esp32h21/rtc_io_periph.c index a051fb229f..0f05a79e22 100644 --- a/components/esp_hal_gpio/esp32h21/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32h21/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" diff --git a/components/esp_hal_gpio/esp32h21/sdm_periph.c b/components/esp_hal_gpio/esp32h21/sdm_periph.c index ea6c9c3899..8b6bb9bdca 100644 --- a/components/esp_hal_gpio/esp32h21/sdm_periph.c +++ b/components/esp_hal_gpio/esp32h21/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32h4/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32h4/dedic_gpio_periph.c index b9ea58e0f6..5b78bd718a 100644 --- a/components/esp_hal_gpio/esp32h4/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32h4/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32h4/sdm_periph.c b/components/esp_hal_gpio/esp32h4/sdm_periph.c index 9e1f8de169..e2a876388f 100644 --- a/components/esp_hal_gpio/esp32h4/sdm_periph.c +++ b/components/esp_hal_gpio/esp32h4/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32p4/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32p4/dedic_gpio_periph.c index 9d9822dd8c..68dba8b09b 100644 --- a/components/esp_hal_gpio/esp32p4/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32p4/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/gpio_sig_map.h" diff --git a/components/esp_hal_gpio/esp32p4/rtc_io_periph.c b/components/esp_hal_gpio/esp32p4/rtc_io_periph.c index 6b13592efd..b72382fa0d 100644 --- a/components/esp_hal_gpio/esp32p4/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32p4/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" diff --git a/components/esp_hal_gpio/esp32p4/sdm_periph.c b/components/esp_hal_gpio/esp32p4/sdm_periph.c index f15b435f38..b122519496 100644 --- a/components/esp_hal_gpio/esp32p4/sdm_periph.c +++ b/components/esp_hal_gpio/esp32p4/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32s2/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32s2/dedic_gpio_periph.c index 6e91c8438a..2fca6e3e38 100644 --- a/components/esp_hal_gpio/esp32s2/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32s2/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/dedic_gpio_periph.h" diff --git a/components/esp_hal_gpio/esp32s2/rtc_io_periph.c b/components/esp_hal_gpio/esp32s2/rtc_io_periph.c index 4b244bb6d2..aa717d670b 100644 --- a/components/esp_hal_gpio/esp32s2/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32s2/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" diff --git a/components/esp_hal_gpio/esp32s2/sdm_periph.c b/components/esp_hal_gpio/esp32s2/sdm_periph.c index c165727652..a9646d6820 100644 --- a/components/esp_hal_gpio/esp32s2/sdm_periph.c +++ b/components/esp_hal_gpio/esp32s2/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/esp32s3/dedic_gpio_periph.c b/components/esp_hal_gpio/esp32s3/dedic_gpio_periph.c index c419eac102..93ec9b452e 100644 --- a/components/esp_hal_gpio/esp32s3/dedic_gpio_periph.c +++ b/components/esp_hal_gpio/esp32s3/dedic_gpio_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/dedic_gpio_periph.h" diff --git a/components/esp_hal_gpio/esp32s3/rtc_io_periph.c b/components/esp_hal_gpio/esp32s3/rtc_io_periph.c index c9a3275138..0bdc6ce6f8 100644 --- a/components/esp_hal_gpio/esp32s3/rtc_io_periph.c +++ b/components/esp_hal_gpio/esp32s3/rtc_io_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2018-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/rtc_io_periph.h" diff --git a/components/esp_hal_gpio/esp32s3/sdm_periph.c b/components/esp_hal_gpio/esp32s3/sdm_periph.c index c165727652..a9646d6820 100644 --- a/components/esp_hal_gpio/esp32s3/sdm_periph.c +++ b/components/esp_hal_gpio/esp32s3/sdm_periph.c @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "hal/sdm_periph.h" diff --git a/components/esp_hal_gpio/include/hal/dedic_gpio_periph.h b/components/esp_hal_gpio/include/hal/dedic_gpio_periph.h index 38d777b8d4..8cc727dd16 100644 --- a/components/esp_hal_gpio/include/hal/dedic_gpio_periph.h +++ b/components/esp_hal_gpio/include/hal/dedic_gpio_periph.h @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #pragma once diff --git a/components/esp_hal_gpio/include/hal/rtc_io_periph.h b/components/esp_hal_gpio/include/hal/rtc_io_periph.h index edaa555ac2..5154525920 100644 --- a/components/esp_hal_gpio/include/hal/rtc_io_periph.h +++ b/components/esp_hal_gpio/include/hal/rtc_io_periph.h @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #pragma once diff --git a/components/esp_hal_gpio/include/hal/sdm_periph.h b/components/esp_hal_gpio/include/hal/sdm_periph.h index 492b41a073..27cff9cbc8 100644 --- a/components/esp_hal_gpio/include/hal/sdm_periph.h +++ b/components/esp_hal_gpio/include/hal/sdm_periph.h @@ -1,7 +1,7 @@ /* * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #pragma once diff --git a/components/esp_hal_twai/CMakeLists.txt b/components/esp_hal_twai/CMakeLists.txt new file mode 100644 index 0000000000..bc924149c3 --- /dev/null +++ b/components/esp_hal_twai/CMakeLists.txt @@ -0,0 +1,25 @@ +idf_build_get_property(target IDF_TARGET) +if(${target} STREQUAL "linux") + return() # This component is not supported by the POSIX/Linux simulator +endif() + +set(srcs) +set(public_include "include") + +if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/${target}/include") + list(APPEND public_include "${target}/include") +endif() + +if(CONFIG_SOC_TWAI_SUPPORTED) + list(APPEND srcs "${target}/twai_periph.c") + + if(CONFIG_SOC_TWAI_FD_SUPPORTED) + list(APPEND srcs "twai_hal_v2.c") + else() + list(APPEND srcs "twai_hal_v1.c") + endif() +endif() + +idf_component_register(SRCS ${srcs} + INCLUDE_DIRS ${public_include} + REQUIRES soc hal) diff --git a/components/esp_hal_twai/README.md b/components/esp_hal_twai/README.md new file mode 100644 index 0000000000..6cc65bc737 --- /dev/null +++ b/components/esp_hal_twai/README.md @@ -0,0 +1,49 @@ +# ESP Hardware Abstraction Layer for TWAI Peripheral + +> [!NOTE] +> This component is currently in beta. Its API, behavior, and compatibility may change at any time and without notice; backward compatibility is not guaranteed. Use caution when integrating into production systems. + +## Overview + +The `esp_hal_twai` component provides a **Hardware Abstraction Layer** for the TWAI (Two-Wire Automotive Interface) peripheral across all ESP-IDF supported targets. TWAI is Espressif's implementation of the CAN (Controller Area Network) protocol, widely used in automotive and industrial applications for reliable communication between microcontrollers and devices. + +## Architecture + +The TWAI HAL is structured in two main sub-layers: + +1. **HAL Layer (Upper)**: Defines the operational steps and data structures required to control the TWAI peripheral (e.g., initialization, message transmission/reception, error handling, bus recovery). + +2. **Low-Level Layer (Bottom)**: Serves as a translation layer between the HAL and the register files defined in the `soc` component, handling target-specific register configurations. + +## Supported TWAI Controllers + +This HAL supports two versions of TWAI controllers depending on the ESP chip: + +- **TWAI Version 1**: Standard CAN 2.0 controller supporting standard and extended frame formats + - Implementation: `twai_hal_v1.c` + +- **TWAI Version 2**: Enhanced controller with TWAI-FD (CAN-FD) support, enabling flexible data-rate for higher bandwidth communication + - Implementation: `twai_hal_v2.c` + +## Features + +- Message transmission and reception with configurable filtering +- Standard (11-bit) and extended (29-bit) identifier support +- Configurable bit timing and baud rates +- Error detection and error state management +- Bus-off recovery mechanisms +- Interrupt-driven operations +- Self-test mode support +- Acceptance filters for selective message reception +- CAN-FD support with flexible data-rate (on supported chips) + +## Usage + +The HAL functions primarily serve ESP-IDF peripheral drivers such as the `esp_driver_twai` component. + +Advanced developers can use these interfaces directly when implementing custom drivers, with the understanding that API stability is not guaranteed. + +## Dependencies + +- `soc`: Provides chip-specific register definitions +- `hal`: Core hardware abstraction utilities and macros diff --git a/components/hal/esp32/include/hal/twai_ll.h b/components/esp_hal_twai/esp32/include/hal/twai_ll.h similarity index 98% rename from components/hal/esp32/include/hal/twai_ll.h rename to components/esp_hal_twai/esp32/include/hal/twai_ll.h index 036a8e6c61..286893afa3 100644 --- a/components/hal/esp32/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32/include/hal/twai_ll.h @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - -// The Lowlevel layer for TWAI - #pragma once #include @@ -23,10 +15,15 @@ #include "hal/twai_types.h" #include "hal/efuse_hal.h" #include "soc/chip_revision.h" -#include "soc/twai_periph.h" #include "soc/twai_struct.h" #include "soc/dport_reg.h" +#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr +#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat + +#define TWAI_LL_SUPPORT_APB_CLK 1 +#define TWAI_LL_SUPPORT_MULTI_ADDRESS_LAYOUT 1 + #define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL) // When the bus-off condition is reached, the REC should be reset to 0 and frozen (via LOM) by the @@ -584,9 +581,9 @@ __attribute__((always_inline)) static inline void twai_ll_parse_err_code_cap(twai_dev_t *hw, twai_ll_err_type_t *type, twai_ll_err_dir_t *dir, twai_ll_err_seg_t *seg) { uint32_t ecc = hw->error_code_capture_reg.val; - *type = (twai_ll_err_type_t) ((ecc >> 6) & 0x3); - *dir = (twai_ll_err_dir_t) ((ecc >> 5) & 0x1); - *seg = (twai_ll_err_seg_t) (ecc & 0x1F); + *type = (twai_ll_err_type_t)((ecc >> 6) & 0x3); + *dir = (twai_ll_err_dir_t)((ecc >> 5) & 0x1); + *seg = (twai_ll_err_seg_t)(ecc & 0x1F); } /* ----------------------------- EWL Register ------------------------------- */ @@ -754,7 +751,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; diff --git a/components/soc/esp32/twai_periph.c b/components/esp_hal_twai/esp32/twai_periph.c similarity index 73% rename from components/soc/esp32/twai_periph.c rename to components/esp_hal_twai/esp32/twai_periph.c index 2137f6718a..df83ef5f5d 100644 --- a/components/soc/esp32/twai_periph.c +++ b/components/esp_hal_twai/esp32/twai_periph.c @@ -1,14 +1,14 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #include "soc/soc.h" -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/gpio_sig_map.h" -const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM] = { +const twai_signal_conn_t twai_periph_signals[1] = { [0] = { .module_name = "TWAI0", .irq_id = ETS_TWAI_INTR_SOURCE, diff --git a/components/hal/esp32c3/include/hal/twai_ll.h b/components/esp_hal_twai/esp32c3/include/hal/twai_ll.h similarity index 97% rename from components/hal/esp32c3/include/hal/twai_ll.h rename to components/esp_hal_twai/esp32c3/include/hal/twai_ll.h index c1a19c68c2..eb81fc4d42 100644 --- a/components/hal/esp32c3/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32c3/include/hal/twai_ll.h @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - -// The Lowlevel layer for TWAI - #pragma once #include @@ -21,10 +13,15 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/twai_types.h" -#include "soc/twai_periph.h" #include "soc/twai_struct.h" #include "soc/system_struct.h" +#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr +#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat + +#define TWAI_LL_SUPPORT_RX_STATUS 1 +#define TWAI_LL_SUPPORT_APB_CLK 1 + #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 @@ -510,9 +507,9 @@ __attribute__((always_inline)) static inline void twai_ll_parse_err_code_cap(twai_dev_t *hw, twai_ll_err_type_t *type, twai_ll_err_dir_t *dir, twai_ll_err_seg_t *seg) { uint32_t ecc = hw->error_code_capture_reg.val; - *type = (twai_ll_err_type_t) ((ecc >> 6) & 0x3); - *dir = (twai_ll_err_dir_t) ((ecc >> 5) & 0x1); - *seg = (twai_ll_err_seg_t) (ecc & 0x1F); + *type = (twai_ll_err_type_t)((ecc >> 6) & 0x3); + *dir = (twai_ll_err_dir_t)((ecc >> 5) & 0x1); + *seg = (twai_ll_err_seg_t)(ecc & 0x1F); } /* ----------------------------- EWL Register ------------------------------- */ @@ -680,7 +677,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; diff --git a/components/soc/esp32c3/twai_periph.c b/components/esp_hal_twai/esp32c3/twai_periph.c similarity index 71% rename from components/soc/esp32c3/twai_periph.c rename to components/esp_hal_twai/esp32c3/twai_periph.c index 2cf0f906bd..7f707767c0 100644 --- a/components/soc/esp32c3/twai_periph.c +++ b/components/esp_hal_twai/esp32c3/twai_periph.c @@ -1,13 +1,14 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" -const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM] = { +const twai_signal_conn_t twai_periph_signals[1] = { [0] = { .module_name = "TWAI0", .irq_id = ETS_TWAI_INTR_SOURCE, diff --git a/components/esp_hal_twai/esp32c5/include/hal/twai_ll.h b/components/esp_hal_twai/esp32c5/include/hal/twai_ll.h new file mode 100644 index 0000000000..cca704e263 --- /dev/null +++ b/components/esp_hal_twai/esp32c5/include/hal/twai_ll.h @@ -0,0 +1,82 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/twai_types.h" +#include "soc/pcr_reg.h" +#include "soc/pcr_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 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @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) +{ + PCR.twai[twai_id].twai_conf.twai_clk_en = enable; +} + +/** + * @brief Reset the twai module + * + * @param twai_id Hardware ID + */ +static inline void twai_ll_reset_register(uint8_t twai_id) +{ + PCR.twai[twai_id].twai_conf.twai_rst_en = 1; + PCR.twai[twai_id].twai_conf.twai_rst_en = 0; +} + +/** + * @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) +{ + switch (clk_src) { + case TWAI_CLK_SRC_PLL_F80M: + PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_sel = 1; + break; + case TWAI_CLK_SRC_XTAL: + PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_sel = 0; + 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) +{ + PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_en = enable; + if (enable) { + while (!PCR.twai[twai_id].twai_conf.twai_ready); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32c5/include/hal/twaifd_ll.h b/components/esp_hal_twai/esp32c5/include/hal/twaifd_ll.h similarity index 68% rename from components/hal/esp32c5/include/hal/twaifd_ll.h rename to components/esp_hal_twai/esp32c5/include/hal/twaifd_ll.h index f6c8baa4fa..ae57172b29 100644 --- a/components/hal/esp32c5/include/hal/twaifd_ll.h +++ b/components/esp_hal_twai/esp32c5/include/hal/twaifd_ll.h @@ -4,17 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The Lowlevel layer for TWAI is not public api, don't use in application code. - ******************************************************************************/ - #pragma once -#ifdef __cplusplus -extern "C" { -#endif - #include #include "soc/pcr_reg.h" #include "soc/pcr_struct.h" @@ -53,76 +44,35 @@ extern "C" { #define TWAIFD_LL_HW_CMD_RST_ERR_CNT TWAIFD_ERCRST // Error Counters Reset #define TWAIFD_LL_HW_CMD_RST_RX_CNT TWAIFD_RXFCRST // Clear RX bus traffic counter #define TWAIFD_LL_HW_CMD_RST_TX_CNT TWAIFD_TXFCRST // Clear TX bus traffic counter +#define TWAIFD_LL_HW_CMD_CLR_OVERRUN TWAIFD_CDO // Clear RX buffer overrun flag +#define TWAIFD_LL_HW_CMD_RX_FLUSH TWAIFD_RRB // Flush RX buffer (read and write pointers are set to 0 and the frame counter is set to 0) #define TWAIFD_LL_INTR_TX_DONE TWAIFD_TXBHCI_INT_ST// Transmit finish (ok or error) -#define TWAIFD_LL_INTR_TX_SUCCESS TWAIFD_TXI_INT_ST // Transmit success without error +#define TWAIFD_LL_INTR_TX_FRAME TWAIFD_TXI_INT_ST // A frame is transmitted +#define TWAIFD_LL_INTR_RX_FRAME TWAIFD_RXI_INT_ST // A frame is received #define TWAIFD_LL_INTR_RX_NOT_EMPTY TWAIFD_RBNEI_INT_ST // RX buffer not empty interrupt #define TWAIFD_LL_INTR_RX_FULL TWAIFD_RXFI_INT_ST // RX buffer full interrupt -#define TWAIFD_LL_INTR_ERR_WARN TWAIFD_EWLI_INT_ST // Error Interrupt +#define TWAIFD_LL_INTR_OVERLOAD TWAIFD_OFI_INT_ST // Overload Frame Interrupt +#define TWAIFD_LL_INTR_ERR_WARN TWAIFD_EWLI_INT_ST // Error warning limit Interrupt #define TWAIFD_LL_INTR_BUS_ERR TWAIFD_BEI_INT_ST // Bus error interrupt #define TWAIFD_LL_INTR_FSM_CHANGE TWAIFD_FCSI_INT_ST // Fault confinement state changed interrupt -#define TWAIFD_LL_INTR_ARBI_LOST TWAIFD_ALI_INT_ST // Arbitration Lost Interrupt +#define TWAIFD_LL_INTR_ARBIT_LOST TWAIFD_ALI_INT_ST // Arbitration Lost Interrupt #define TWAIFD_LL_INTR_DATA_OVERRUN TWAIFD_DOI_INT_ST // Data Overrun Interrupt +#define TWAIFD_LL_INTR_TIMER_OVERFLOW TWAIFD_TIMER_OVERFLOW_INT_ST // Timer overflow interrupt + #define TWAI_LL_DRIVER_INTERRUPTS (TWAIFD_LL_INTR_TX_DONE | TWAIFD_LL_INTR_RX_NOT_EMPTY | TWAIFD_LL_INTR_RX_FULL | \ TWAIFD_LL_INTR_ERR_WARN | TWAIFD_LL_INTR_BUS_ERR | TWAIFD_LL_INTR_FSM_CHANGE | \ - TWAIFD_LL_INTR_ARBI_LOST | TWAIFD_LL_INTR_DATA_OVERRUN) + TWAIFD_LL_INTR_ARBIT_LOST | TWAIFD_LL_INTR_DATA_OVERRUN) -/** - * @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 twaifd_ll_enable_bus_clock(uint8_t twai_id, bool enable) -{ - PCR.twai[twai_id].twai_conf.twai_clk_en = enable; -} +#ifdef __cplusplus +extern "C" { +#endif -/** - * @brief Reset the twai module - * - * @param twai_id Hardware ID - */ -static inline void twaifd_ll_reset_register(uint8_t twai_id) -{ - PCR.twai[twai_id].twai_conf.twai_rst_en = 1; - PCR.twai[twai_id].twai_conf.twai_rst_en = 0; -} - -/** - * @brief Set clock source for TWAI module - * - * @param twai_id Hardware ID - * @param clk_src Clock source - */ -static inline void twaifd_ll_set_clock_source(uint8_t twai_id, twai_clock_source_t clk_src) -{ - switch (clk_src) { - case TWAI_CLK_SRC_PLL_F80M: - PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_sel = 1; - break; - case TWAI_CLK_SRC_XTAL: - PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_sel = 0; - 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 twaifd_ll_enable_clock(uint8_t twai_id, bool enable) -{ - PCR.twai[twai_id].twai_func_clk_conf.twai_func_clk_en = enable; - if (enable) { - while (!PCR.twai[twai_id].twai_conf.twai_ready); - } -} +typedef enum { + TWAIFD_LL_TS_POINT_EOF = 0, // in 6th bit of end of frame (moment when the received frame is considered valid) + TWAIFD_LL_TS_POINT_SOF = 1, // start of frame bit +} twaifd_ll_timestamp_point_t; /** * @brief Waits for pending changes to take effect in the hardware. @@ -134,7 +84,6 @@ static inline void twaifd_ll_waiting_state_change(twaifd_dev_t *hw) while (!hw->int_stat.fcsi_int_st); // Wait until the change is applied } - /* ---------------------------- Mode Register ------------------------------- */ // WARNING!! Following 'mode_settings' should in same spin_lock` !!! @@ -151,6 +100,9 @@ static inline void twaifd_ll_reset(twaifd_dev_t *hw) /** * @brief Enable or disable hardware. * + * @note After enable, the node will join the bus after receiving 11 consecutive recessive bits + * @note If disable, the node becomes "bus-off", all TX buffers goes to "empty" state without resetting the memories, RX buffer is flushed. + * * @param hw Pointer to hardware structure. * @param enable Boolean flag to enable (true) or disable (false). */ @@ -187,6 +139,8 @@ static inline void twaifd_ll_set_mode(twaifd_dev_t *hw, bool listen_only, bool s /** * @brief Set the TX retransmission limit. * + * @note First attempt to transmit TWAI frames does not count as retransmission. + * * @param hw Pointer to the TWAI-FD device hardware. * @param limit Retransmission limit (0-15, or negative for infinite). */ @@ -199,20 +153,31 @@ static inline void twaifd_ll_set_tx_retrans_limit(twaifd_dev_t *hw, int8_t limit /** * set bit rate flexible between nominal field and data field - * when set this bit, all frame will be regarded as CANFD frame, even though nominal bit rate and data bit rate are the same + * when set this bit, all frame will be regarded as TWAI FD frame, even though nominal bit rate and data bit rate are the same */ static inline void twaifd_ll_enable_fd_mode(twaifd_dev_t *hw, bool ena) { hw->mode_settings.fde = ena; } +/** + * @brief Whether to enable protocol exception handling + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param ena Set to true to enable PEX, false to disable. + */ +static inline void twaifd_ll_enable_pex(twaifd_dev_t *hw, bool ena) +{ + hw->mode_settings.pex = ena; +} + /** * @brief Enable or disable the RX fifo automatic increase when read to register * * @param hw Pointer to the TWAI-FD device hardware. * @param ena Set to true to enable RX automatic mode, false to disable. */ -static inline void twaifd_ll_enable_rxfifo_auto_incrase(twaifd_dev_t *hw, bool ena) +static inline void twaifd_ll_enable_rxfifo_auto_increase(twaifd_dev_t *hw, bool ena) { hw->mode_settings.rxbam = ena; } @@ -231,12 +196,36 @@ static inline void twaifd_ll_enable_filter_mode(twaifd_dev_t* hw, bool enable) } /** - * @brief Set remote frame filtering behaviour. + * @brief Enable or disable the test mode for the TWAI-FD peripheral. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param enable Set to true to enable test mode, false to disable. + */ +static inline void twaifd_ll_enable_test_mode(twaifd_dev_t* hw, bool enable) +{ + hw->mode_settings.tstm = enable; +} + +/** + * @brief Enable or disable the parity error detection for the RX and TX buffers. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param enable Set to true to enable parity error detection, false to disable. + */ +static inline void twaifd_ll_enable_parity_error_detection(twaifd_dev_t* hw, bool enable) +{ + // Must be called when hardware is disabled. + HAL_ASSERT(hw->mode_settings.ena == 0); + hw->mode_settings.pchke = enable; +} + +/** + * @brief Whether to drop the RTR frames in filter. * * @param hw Pointer to hardware structure. - * @param en True to drop, false to Receive to next filter + * @param en True to drop, false to pass it to the next filter */ -static inline void twaifd_ll_filter_block_rtr(twaifd_dev_t* hw, bool en) +static inline void twaifd_ll_filter_drop_rtr(twaifd_dev_t* hw, bool en) { hw->mode_settings.fdrf = en; } @@ -244,6 +233,8 @@ static inline void twaifd_ll_filter_block_rtr(twaifd_dev_t* hw, bool en) /** * @brief Enable or disable the time-triggered transmission mode for the TWAI-FD peripheral. * + * @note Time triggered transmission is always considered only from the highest priority TX buffer in “ready” state. + * * @param hw Pointer to the TWAI-FD device hardware. * @param enable Set to true to enable time-triggered transmission mode, false to disable. */ @@ -252,6 +243,19 @@ static inline void twaifd_ll_enable_time_trig_trans_mode(twaifd_dev_t* hw, bool hw->mode_settings.tttm = enable; } +/** + * @brief Whether to treat bus-off as TX failure + * + * @note Disable it, it allows going bus-off and re-integrating without the need of software interaction with TX buffers. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param enable Set to true to enable, false to disable. + */ +static inline void twaifd_ll_enable_bus_off_tx_fail_mode(twaifd_dev_t* hw, bool enable) +{ + hw->mode_settings.tbfbo = enable; +} + /* --------------------------- Command Register ----------------------------- */ /** * @brief Set command to TWAIFD hardware @@ -365,6 +369,17 @@ static inline void twaifd_ll_config_secondary_sample_point(twaifd_dev_t *hw, uin HAL_FORCE_MODIFY_U32_REG_FIELD(hw->trv_delay_ssp_cfg, ssp_offset, offset_val); } +/** + * @brief Get measured transmitter delay + * + * @param hw Start address of the TWAI registers + * @return Transmitter Delay Value in clock source cycles, include the input delay of TWAI FD (2 cycles) + */ +static inline uint32_t twaifd_ll_get_transmitter_delay(twaifd_dev_t *hw) +{ + return hw->trv_delay_ssp_cfg.trv_delay_value; +} + /* ----------------------------- ERR Capt Register ------------------------------- */ /** @@ -426,10 +441,10 @@ static inline twai_error_state_t twaifd_ll_get_fault_state(twaifd_dev_t *hw) } /** - * @brief Get the error count in normal mode for the TWAI-FD peripheral. + * @brief Get the error count in nominal bit rate stage. * * @param hw Pointer to the TWAI-FD device hardware. - * @return Error count in normal mode. + * @return Error count in nominal bit rate stage. */ static inline uint32_t twaifd_ll_get_err_count_norm(twaifd_dev_t *hw) { @@ -437,10 +452,10 @@ static inline uint32_t twaifd_ll_get_err_count_norm(twaifd_dev_t *hw) } /** - * @brief Get the error count in FD mode for the TWAI-FD peripheral. + * @brief Get the error count in FD data bit rate stage. * * @param hw Pointer to the TWAI-FD device hardware. - * @return Error count in FD mode. + * @return Error count in FD data bit rate stage. */ static inline uint32_t twaifd_ll_get_err_count_fd(twaifd_dev_t *hw) { @@ -475,122 +490,174 @@ static inline uint32_t twaifd_ll_get_tec(twaifd_dev_t *hw) /* ---------------------- Acceptance Filter Registers ----------------------- */ /** - * @brief Enable or disable filter to receive basic frame with std id + * @brief Enable or disable mask filter to receive classic frame with std id * * @param hw Pointer to the TWAI FD hardware instance - * @param filter_id The unique ID of the filter to configure - * @param is_range Setting for range filter or mask filter - * @param en True to receive, False to drop + * @param filter_id The unique ID of the mask filter to configure + * @param accept True to accept the frame, False to drop the frame */ -static inline void twaifd_ll_filter_enable_basic_std(twaifd_dev_t* hw, uint8_t filter_id, bool is_range, bool en) +static inline void twaifd_ll_mask_filter_accept_classic_std(twaifd_dev_t* hw, uint8_t filter_id, bool accept) { - HAL_ASSERT(filter_id < (is_range ? SOC_TWAI_RANGE_FILTER_NUM : SOC_TWAI_MASK_FILTER_NUM)); - // The hw_filter_id of range_filter is indexed after mask_filter - uint8_t hw_filter_id = is_range ? filter_id + SOC_TWAI_MASK_FILTER_NUM : filter_id; - if (en) { - hw->filter_control_filter_status.val |= TWAIFD_FANB << (hw_filter_id * TWAIFD_FBNB_S); + if (accept) { + hw->filter_control_filter_status.val |= 0x01 << (filter_id * 4); } else { - hw->filter_control_filter_status.val &= ~(TWAIFD_FANB << (hw_filter_id * TWAIFD_FBNB_S)); + hw->filter_control_filter_status.val &= ~(0x01 << (filter_id * 4)); } } /** - * @brief Enable or disable filter to receive basic frame with ext id + * @brief Enable or disable mask filter to receive classic frame with ext id * * @param hw Pointer to the TWAI FD hardware instance - * @param filter_id The unique ID of the filter to configure - * @param is_range Setting for range filter or mask filter - * @param en True to receive, False to drop + * @param filter_id The unique ID of the mask filter to configure + * @param accept True to accept the frame, False to drop the frame */ -static inline void twaifd_ll_filter_enable_basic_ext(twaifd_dev_t* hw, uint8_t filter_id, bool is_range, bool en) +static inline void twaifd_ll_mask_filter_accept_classic_ext(twaifd_dev_t* hw, uint8_t filter_id, bool accept) { - HAL_ASSERT(filter_id < (is_range ? SOC_TWAI_RANGE_FILTER_NUM : SOC_TWAI_MASK_FILTER_NUM)); - // The hw_filter_id of range_filter is indexed after mask_filter - uint8_t hw_filter_id = is_range ? filter_id + SOC_TWAI_MASK_FILTER_NUM : filter_id; - if (en) { - hw->filter_control_filter_status.val |= TWAIFD_FANE << (hw_filter_id * TWAIFD_FBNB_S); + if (accept) { + hw->filter_control_filter_status.val |= 0x02 << (filter_id * 4); } else { - hw->filter_control_filter_status.val &= ~(TWAIFD_FANE << (hw_filter_id * TWAIFD_FBNB_S)); + hw->filter_control_filter_status.val &= ~(0x02 << (filter_id * 4)); } } /** - * @brief Enable or disable filter to receive fd frame with std id + * @brief Enable or disable mask filter to receive fd frame with std id * * @param hw Pointer to the TWAI FD hardware instance - * @param filter_id The unique ID of the filter to configure - * @param is_range Setting for range filter or mask filter - * @param en True to receive, False to drop + * @param filter_id The unique ID of the mask filter to configure + * @param accept True to accept the frame, False to drop the frame */ -static inline void twaifd_ll_filter_enable_fd_std(twaifd_dev_t* hw, uint8_t filter_id, bool is_range, bool en) +static inline void twaifd_ll_mask_filter_accept_fd_std(twaifd_dev_t* hw, uint8_t filter_id, bool accept) { - HAL_ASSERT(filter_id < (is_range ? SOC_TWAI_RANGE_FILTER_NUM : SOC_TWAI_MASK_FILTER_NUM)); - // The hw_filter_id of range_filter is indexed after mask_filter - uint8_t hw_filter_id = is_range ? filter_id + SOC_TWAI_MASK_FILTER_NUM : filter_id; - if (en) { - hw->filter_control_filter_status.val |= TWAIFD_FAFB << (hw_filter_id * TWAIFD_FBNB_S); + if (accept) { + hw->filter_control_filter_status.val |= 0x04 << (filter_id * 4); } else { - hw->filter_control_filter_status.val &= ~(TWAIFD_FAFB << (hw_filter_id * TWAIFD_FBNB_S)); + hw->filter_control_filter_status.val &= ~(0x04 << (filter_id * 4)); } } /** - * @brief Enable or disable filter to receive fd frame with ext id + * @brief Enable or disable mask filter to receive fd frame with ext id * * @param hw Pointer to the TWAI FD hardware instance - * @param filter_id The unique ID of the filter to configure - * @param is_range Setting for range filter or mask filter - * @param en True to receive, False to drop + * @param filter_id The unique ID of the mask filter to configure + * @param accept True to accept the frame, False to drop the frame */ -static inline void twaifd_ll_filter_enable_fd_ext(twaifd_dev_t* hw, uint8_t filter_id, bool is_range, bool en) +static inline void twaifd_ll_mask_filter_accept_fd_ext(twaifd_dev_t* hw, uint8_t filter_id, bool accept) { - HAL_ASSERT(filter_id < (is_range ? SOC_TWAI_RANGE_FILTER_NUM : SOC_TWAI_MASK_FILTER_NUM)); - // The hw_filter_id of range_filter is indexed after mask_filter - uint8_t hw_filter_id = is_range ? filter_id + SOC_TWAI_MASK_FILTER_NUM : filter_id; - if (en) { - hw->filter_control_filter_status.val |= TWAIFD_FAFE << (hw_filter_id * TWAIFD_FBNB_S); + if (accept) { + hw->filter_control_filter_status.val |= 0x08 << (filter_id * 4); } else { - hw->filter_control_filter_status.val &= ~(TWAIFD_FAFE << (hw_filter_id * TWAIFD_FBNB_S)); + hw->filter_control_filter_status.val &= ~(0x08 << (filter_id * 4)); } } /** - * @brief Set Bit Acceptance Filter + * @brief Enable or disable range filter to receive classic frame with std id + * + * @param hw Pointer to the TWAI FD hardware instance + * @param filter_id The unique ID of the range filter to configure + * @param accept True to accept the frame, False to drop the frame + */ +static inline void twaifd_ll_range_filter_accept_classic_std(twaifd_dev_t* hw, uint8_t filter_id, bool accept) +{ + uint8_t hw_filter_id = filter_id + 3; + if (accept) { + hw->filter_control_filter_status.val |= 0x01 << (hw_filter_id * 4); + } else { + hw->filter_control_filter_status.val &= ~(0x01 << (hw_filter_id * 4)); + } +} + +/** + * @brief Enable or disable range filter to receive classic frame with ext id + * + * @param hw Pointer to the TWAI FD hardware instance + * @param filter_id The unique ID of the range filter to configure + * @param accept True to accept the frame, False to drop the frame + */ +static inline void twaifd_ll_range_filter_accept_classic_ext(twaifd_dev_t* hw, uint8_t filter_id, bool accept) +{ + uint8_t hw_filter_id = filter_id + 3; + if (accept) { + hw->filter_control_filter_status.val |= 0x02 << (hw_filter_id * 4); + } else { + hw->filter_control_filter_status.val &= ~(0x02 << (hw_filter_id * 4)); + } +} + +/** + * @brief Enable or disable range filter to receive fd frame with std id + * + * @param hw Pointer to the TWAI FD hardware instance + * @param filter_id The unique ID of the range filter to configure + * @param accept True to accept the frame, False to drop the frame + */ +static inline void twaifd_ll_range_filter_accept_fd_std(twaifd_dev_t* hw, uint8_t filter_id, bool accept) +{ + uint8_t hw_filter_id = filter_id + 3; + if (accept) { + hw->filter_control_filter_status.val |= 0x04 << (hw_filter_id * 4); + } else { + hw->filter_control_filter_status.val &= ~(0x04 << (hw_filter_id * 4)); + } +} + +/** + * @brief Enable or disable range filter to receive fd frame with ext id + * + * @param hw Pointer to the TWAI FD hardware instance + * @param filter_id The unique ID of the range filter to configure + * @param accept True to accept the frame, False to drop the frame + */ +static inline void twaifd_ll_range_filter_accept_fd_ext(twaifd_dev_t* hw, uint8_t filter_id, bool accept) +{ + uint8_t hw_filter_id = filter_id + 3; + if (accept) { + hw->filter_control_filter_status.val |= 0x08 << (hw_filter_id * 4); + } else { + hw->filter_control_filter_status.val &= ~(0x08 << (hw_filter_id * 4)); + } +} + +/** + * @brief Set the ID and mask for mask filter * @param hw Start address of the TWAI registers * @param filter_id Filter number id * @param is_ext Filter for ext_id or std_id * @param code Acceptance Code * @param mask Acceptance Mask */ -static inline void twaifd_ll_filter_set_id_mask(twaifd_dev_t* hw, uint8_t filter_id, bool is_ext, uint32_t code, uint32_t mask) +static inline void twaifd_ll_mask_filter_set_id_mask(twaifd_dev_t* hw, uint8_t filter_id, bool is_ext, uint32_t code, uint32_t mask) { hw->mask_filters[filter_id].filter_mask.bit_mask_val = is_ext ? mask : (mask << TWAIFD_IDENTIFIER_BASE_S); hw->mask_filters[filter_id].filter_val.bit_val = is_ext ? code : (code << TWAIFD_IDENTIFIER_BASE_S); } /** - * @brief Set Range Acceptance Filter + * @brief Set the ID range for range filter * @param hw Start address of the TWAI registers * @param filter_id Filter number id * @param is_ext Filter for ext_id or std_id * @param high The id range high limit * @param low The id range low limit */ -static inline void twaifd_ll_filter_set_range(twaifd_dev_t* hw, uint8_t filter_id, bool is_ext, uint32_t high, uint32_t low) +static inline void twaifd_ll_range_filter_set_id_thres(twaifd_dev_t* hw, uint8_t filter_id, bool is_ext, uint32_t high, uint32_t low) { hw->range_filters[filter_id].ran_low.bit_ran_low_val = is_ext ? low : (low << TWAIFD_IDENTIFIER_BASE_S); - hw->range_filters[filter_id].ran_high.bit_ran_high_val = is_ext ? high : (high << TWAIFD_IDENTIFIER_BASE_S); + hw->range_filters[filter_id].ran_high.bit_ran_high_val = is_ext ? high : (high << TWAIFD_IDENTIFIER_BASE_S) | 0x3FFFF; } /* ------------------------- TX Buffer Registers ------------------------- */ /** - * @brief Get the number of TX buffers available. + * @brief Get the number of TX buffers that are preset in the hardware. * * @param hw Pointer to the TWAI-FD device hardware. * @return The number of TX buffers available. */ -static inline uint32_t twaifd_ll_get_tx_buffer_quantity(twaifd_dev_t *hw) +static inline uint32_t twaifd_ll_get_tx_buffer_total(twaifd_dev_t *hw) { return hw->tx_command_txtb_info.txt_buffer_count; } @@ -604,24 +671,24 @@ static inline uint32_t twaifd_ll_get_tx_buffer_quantity(twaifd_dev_t *hw) */ static inline uint32_t twaifd_ll_get_tx_buffer_status(twaifd_dev_t *hw, uint8_t buffer_idx) { - HAL_ASSERT(buffer_idx < twaifd_ll_get_tx_buffer_quantity(hw)); // Ensure buffer index is valid + HAL_ASSERT(buffer_idx < twaifd_ll_get_tx_buffer_total(hw)); // Ensure buffer index is valid uint32_t reg_val = hw->tx_status.val; return reg_val & (TWAIFD_TX2S_V << (TWAIFD_TX2S_S * buffer_idx)); // Get status for buffer } /** - * @brief Set TX Buffer command + * @brief Set TX Buffer command * * Setting the TX command will cause the TWAI controller to attempt to transmit * the frame stored in the TX buffer. The TX buffer will be occupied (i.e., * locked) until TX completes. * * @param hw Start address of the TWAI registers - * @param buffer_idx + * @param buffer_idx The tx buffer index to set the command * @param cmd The command want to set, see `TWAIFD_LL_TX_CMD_` */ __attribute__((always_inline)) -static inline void twaifd_ll_set_tx_cmd(twaifd_dev_t *hw, uint8_t buffer_idx, uint32_t cmd) +static inline void twaifd_ll_set_tx_buffer_cmd(twaifd_dev_t *hw, uint8_t buffer_idx, uint32_t cmd) { hw->tx_command_txtb_info.val = (cmd | BIT(buffer_idx + TWAIFD_TXB1_S)); } @@ -629,13 +696,15 @@ static inline void twaifd_ll_set_tx_cmd(twaifd_dev_t *hw, uint8_t buffer_idx, ui /** * @brief Set the priority for a specific TX buffer. * + * @note If two TX buffers have equal priority, TX buffer with the lower index has precedence. + * * @param hw Pointer to the TWAI-FD device hardware. * @param buffer_idx Index of the TX buffer (0-7). - * @param priority The priority level to set for the buffer. + * @param priority The priority level to set for the buffer. Higher values indicate higher priority. */ static inline void twaifd_ll_set_tx_buffer_priority(twaifd_dev_t *hw, uint8_t buffer_idx, uint32_t priority) { - HAL_ASSERT(buffer_idx < twaifd_ll_get_tx_buffer_quantity(hw)); // Ensure buffer index is valid + HAL_ASSERT(buffer_idx < twaifd_ll_get_tx_buffer_total(hw)); // Ensure buffer index is valid uint32_t reg_val = hw->tx_priority.val; reg_val &= ~(TWAIFD_TXT1P_V << (TWAIFD_TXT2P_S * buffer_idx)); // Clear old priority reg_val |= priority << (TWAIFD_TXT2P_S * buffer_idx); // Set new priority @@ -665,14 +734,27 @@ static inline void twaifd_ll_mount_tx_buffer(twaifd_dev_t *hw, twaifd_frame_buff /** * @brief Get the size of the RX buffer. * + * @note It contains a single RX buffer where received frames are stored. + * * @param hw Pointer to the TWAI-FD device hardware. - * @return Size of the RX buffer. + * @return Size of the RX buffer, in multiple of 32-bit words. */ static inline uint32_t twaifd_ll_get_rx_buffer_size(twaifd_dev_t *hw) { return hw->rx_mem_info.rx_buff_size; } +/** + * @brief Get the free space in the RX buffer. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @return Free space in the RX buffer, in multiple of 32-bit words. + */ +static inline uint32_t twaifd_ll_get_rx_free_space(twaifd_dev_t *hw) +{ + return hw->rx_mem_info.rx_free; +} + /** * @brief Get the number of frames in the RX buffer. * @@ -689,15 +771,26 @@ static inline uint32_t twaifd_ll_get_rx_frame_count(twaifd_dev_t *hw) * @brief Check if the RX FIFO is empty. * * @param hw Pointer to the TWAI-FD device hardware. - * @return 1 if RX FIFO is empty, 0 otherwise. + * @return true if RX FIFO is empty, false otherwise. */ -static inline uint32_t twaifd_ll_is_rx_buffer_empty(twaifd_dev_t *hw) +static inline bool twaifd_ll_is_rx_buffer_empty(twaifd_dev_t *hw) { return hw->rx_status_rx_settings.rxe; } /** - * @brief Copy a received frame from the RX buffer for parsing + * @brief Check if the RX FIFO is full. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @return true if RX FIFO is full, false otherwise. + */ +static inline bool twaifd_ll_is_rx_buffer_full(twaifd_dev_t *hw) +{ + return hw->rx_status_rx_settings.rxf; +} + +/** + * @brief Copy a received frame from the RX buffer for parsing * * @param hw Start address of the TWAI registers * @param rx_frame Pointer to store formatted frame @@ -835,18 +928,29 @@ static inline uint32_t twaifd_ll_get_tx_traffic_counter(twaifd_dev_t *hw) /* ------------------------- Timestamp Register ------------------------- */ /** - * @brief Enable or disable the timer clock. + * @brief Set the sample point for the timestamp. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param sample_point Sample point for the timestamp. + */ +static inline void twaifd_ll_ts_set_sample_point(twaifd_dev_t *hw, twaifd_ll_timestamp_point_t sample_point) +{ + hw->rx_status_rx_settings.rtsop = sample_point; +} + +/** + * @brief Whether to force enable the register config clock of the timer * * @param hw Pointer to the TWAI-FD device hardware. * @param enable True to enable, false to disable. */ -static inline void twaifd_ll_timer_enable_clock(twaifd_dev_t *hw, bool enable) +static inline void twaifd_ll_timer_force_enable_cfg_clock(twaifd_dev_t *hw, bool enable) { hw->timer_clk_en.clk_en = enable; } /** - * @brief Enable or disable timer power. + * @brief Enable or disable the timer. * * @param hw Pointer to the TWAI-FD device hardware. * @param enable True to enable, false to disable. @@ -856,9 +960,34 @@ static inline void twaifd_ll_timer_enable(twaifd_dev_t *hw, bool enable) hw->timer_cfg.timer_ce = enable; } +/** + * @brief Get the bit width of the timer. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @return Bit width of the timer. + */ +static inline uint8_t twaifd_ll_timer_get_bitwidth(twaifd_dev_t *hw) +{ + return hw->err_capt_retr_ctr_alc_ts_info.ts_bits + 1; +} + +/** + * @brief Get the current timer count. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @return Current timer count as a 64-bit value. + */ +static inline uint64_t twaifd_ll_timer_get_count(twaifd_dev_t *hw) +{ + uint64_t count = ((uint64_t)hw->timestamp_high.val << 32) | hw->timestamp_low.val; + return count; +} + /** * @brief Set the timer step value. * + * @note This is to determine the resolution of the timer. We can also treat it as a prescaler. + * * @param hw Pointer to the TWAI-FD device hardware. * @param step Step value to set (actual step = step - 1). */ diff --git a/components/soc/esp32c5/twai_periph.c b/components/esp_hal_twai/esp32c5/twai_periph.c similarity index 88% rename from components/soc/esp32c5/twai_periph.c rename to components/esp_hal_twai/esp32c5/twai_periph.c index 831fe48f4c..5d770948e4 100644 --- a/components/soc/esp32c5/twai_periph.c +++ b/components/esp_hal_twai/esp32c5/twai_periph.c @@ -1,11 +1,12 @@ /* * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" const twai_signal_conn_t twai_periph_signals[2] = { [0] = { diff --git a/components/hal/esp32c6/include/hal/twai_ll.h b/components/esp_hal_twai/esp32c6/include/hal/twai_ll.h similarity index 97% rename from components/hal/esp32c6/include/hal/twai_ll.h rename to components/esp_hal_twai/esp32c6/include/hal/twai_ll.h index 86a947a4a2..47b0fe786d 100644 --- a/components/hal/esp32c6/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32c6/include/hal/twai_ll.h @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - -// The Lowlevel layer for TWAI - #pragma once #include @@ -21,11 +13,15 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/twai_types.h" -#include "soc/twai_periph.h" #include "soc/twai_reg.h" #include "soc/twai_struct.h" #include "soc/pcr_struct.h" +#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr +#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat + +#define TWAI_LL_SUPPORT_RX_STATUS 1 + #define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI0) : (&TWAI1)) #ifdef __cplusplus @@ -521,9 +517,9 @@ __attribute__((always_inline)) static inline void twai_ll_parse_err_code_cap(twai_dev_t *hw, twai_ll_err_type_t *type, twai_ll_err_dir_t *dir, twai_ll_err_seg_t *seg) { uint32_t ecc = hw->err_code_cap.val; - *type = (twai_ll_err_type_t) ((ecc >> 6) & 0x3); - *dir = (twai_ll_err_dir_t) ((ecc >> 5) & 0x1); - *seg = (twai_ll_err_seg_t) (ecc & 0x1F); + *type = (twai_ll_err_type_t)((ecc >> 6) & 0x3); + *dir = (twai_ll_err_dir_t)((ecc >> 5) & 0x1); + *seg = (twai_ll_err_seg_t)(ecc & 0x1F); } /* ----------------------------- EWL Register ------------------------------- */ @@ -691,7 +687,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; diff --git a/components/soc/esp32c6/twai_periph.c b/components/esp_hal_twai/esp32c6/twai_periph.c similarity index 91% rename from components/soc/esp32c6/twai_periph.c rename to components/esp_hal_twai/esp32c6/twai_periph.c index b8de652afc..c8f24fbc60 100644 --- a/components/soc/esp32c6/twai_periph.c +++ b/components/esp_hal_twai/esp32c6/twai_periph.c @@ -1,14 +1,15 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/twai_reg.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" -const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM] = { +const twai_signal_conn_t twai_periph_signals[2] = { [0] = { .module_name = "TWAI0", .irq_id = ETS_TWAI0_INTR_SOURCE, @@ -62,7 +63,7 @@ static const uint32_t twai_regs_map[4] = {0x9fffe0d1, 0xdf, 0x0, 0x0}; 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[SOC_TWAI_CONTROLLER_NUM] = { +const twai_reg_retention_info_t twai_reg_retention_info[2] = { [0] = { .module_id = SLEEP_RETENTION_MODULE_TWAI0, .entry_array = twai0_regs_retention, diff --git a/components/hal/esp32h2/include/hal/twai_ll.h b/components/esp_hal_twai/esp32h2/include/hal/twai_ll.h similarity index 97% rename from components/hal/esp32h2/include/hal/twai_ll.h rename to components/esp_hal_twai/esp32h2/include/hal/twai_ll.h index d1edfe429f..909e8db2e2 100644 --- a/components/hal/esp32h2/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32h2/include/hal/twai_ll.h @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - -// The Lowlevel layer for TWAI - #pragma once #include @@ -21,11 +13,15 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/twai_types.h" -#include "soc/twai_periph.h" #include "soc/twai_reg.h" #include "soc/twai_struct.h" #include "soc/pcr_struct.h" +#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr +#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat + +#define TWAI_LL_SUPPORT_RX_STATUS 1 + #define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI0) : NULL) #ifdef __cplusplus @@ -499,9 +495,9 @@ __attribute__((always_inline)) static inline void twai_ll_parse_err_code_cap(twai_dev_t *hw, twai_ll_err_type_t *type, twai_ll_err_dir_t *dir, twai_ll_err_seg_t *seg) { uint32_t ecc = hw->err_code_cap.val; - *type = (twai_ll_err_type_t) ((ecc >> 6) & 0x3); - *dir = (twai_ll_err_dir_t) ((ecc >> 5) & 0x1); - *seg = (twai_ll_err_seg_t) (ecc & 0x1F); + *type = (twai_ll_err_type_t)((ecc >> 6) & 0x3); + *dir = (twai_ll_err_dir_t)((ecc >> 5) & 0x1); + *seg = (twai_ll_err_seg_t)(ecc & 0x1F); } /* ----------------------------- EWL Register ------------------------------- */ @@ -669,7 +665,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; diff --git a/components/soc/esp32h2/twai_periph.c b/components/esp_hal_twai/esp32h2/twai_periph.c similarity index 89% rename from components/soc/esp32h2/twai_periph.c rename to components/esp_hal_twai/esp32h2/twai_periph.c index de2dc1d62e..ea0ca46bef 100644 --- a/components/soc/esp32h2/twai_periph.c +++ b/components/esp_hal_twai/esp32h2/twai_periph.c @@ -1,14 +1,15 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/twai_reg.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" -const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM] = { +const twai_signal_conn_t twai_periph_signals[1] = { [0] = { .module_name = "TWAI0", .irq_id = ETS_TWAI0_INTR_SOURCE, @@ -51,7 +52,7 @@ static const uint32_t twai_regs_map[4] = {0x9fffe0d1, 0xdf, 0x0, 0x0}; } static const regdma_entries_config_t twai0_regs_retention[] = TWAI_SLEEP_RETENTION_ENTRIES(0); -const twai_reg_retention_info_t twai_reg_retention_info[SOC_TWAI_CONTROLLER_NUM] = { +const twai_reg_retention_info_t twai_reg_retention_info[1] = { [0] = { .module_id = SLEEP_RETENTION_MODULE_TWAI0, .entry_array = twai0_regs_retention, diff --git a/components/hal/esp32h21/include/hal/twai_ll.h b/components/esp_hal_twai/esp32h21/include/hal/twai_ll.h similarity index 97% rename from components/hal/esp32h21/include/hal/twai_ll.h rename to components/esp_hal_twai/esp32h21/include/hal/twai_ll.h index 3757cd4d0a..76aa0ffbda 100644 --- a/components/hal/esp32h21/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32h21/include/hal/twai_ll.h @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - -// The Lowlevel layer for TWAI - #pragma once #include @@ -21,11 +13,15 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/twai_types.h" -#include "soc/twai_periph.h" #include "soc/twai_reg.h" #include "soc/twai_struct.h" #include "soc/pcr_struct.h" +#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr +#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat + +#define TWAI_LL_SUPPORT_RX_STATUS 1 + #define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI) : NULL) #ifdef __cplusplus @@ -499,9 +495,9 @@ __attribute__((always_inline)) static inline void twai_ll_parse_err_code_cap(twai_dev_t *hw, twai_ll_err_type_t *type, twai_ll_err_dir_t *dir, twai_ll_err_seg_t *seg) { uint32_t ecc = hw->err_code_cap.val; - *type = (twai_ll_err_type_t) ((ecc >> 6) & 0x3); - *dir = (twai_ll_err_dir_t) ((ecc >> 5) & 0x1); - *seg = (twai_ll_err_seg_t) (ecc & 0x1F); + *type = (twai_ll_err_type_t)((ecc >> 6) & 0x3); + *dir = (twai_ll_err_dir_t)((ecc >> 5) & 0x1); + *seg = (twai_ll_err_seg_t)(ecc & 0x1F); } /* ----------------------------- EWL Register ------------------------------- */ @@ -669,7 +665,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; diff --git a/components/soc/esp32h21/twai_periph.c b/components/esp_hal_twai/esp32h21/twai_periph.c similarity index 89% rename from components/soc/esp32h21/twai_periph.c rename to components/esp_hal_twai/esp32h21/twai_periph.c index 55ee091a59..b733fe6c3d 100644 --- a/components/soc/esp32h21/twai_periph.c +++ b/components/esp_hal_twai/esp32h21/twai_periph.c @@ -1,14 +1,15 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/twai_reg.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" -const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM] = { +const twai_signal_conn_t twai_periph_signals[1] = { [0] = { .module_name = "TWAI0", .irq_id = ETS_TWAI0_INTR_SOURCE, @@ -51,7 +52,7 @@ static const uint32_t twai_regs_map[4] = {0x9fffe0d1, 0xdf, 0x0, 0x0}; } static const regdma_entries_config_t twai0_regs_retention[] = TWAI_SLEEP_RETENTION_ENTRIES(0); -const twai_reg_retention_info_t twai_reg_retention_info[SOC_TWAI_CONTROLLER_NUM] = { +const twai_reg_retention_info_t twai_reg_retention_info[1] = { [0] = { .module_id = SLEEP_RETENTION_MODULE_TWAI0, .entry_array = twai0_regs_retention, diff --git a/components/esp_hal_twai/esp32h4/include/hal/twai_ll.h b/components/esp_hal_twai/esp32h4/include/hal/twai_ll.h new file mode 100644 index 0000000000..4eb03be2e7 --- /dev/null +++ b/components/esp_hal_twai/esp32h4/include/hal/twai_ll.h @@ -0,0 +1,87 @@ +/* + * SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "hal/twai_types.h" +#include "soc/pcr_reg.h" +#include "soc/pcr_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 + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @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) +{ + PCR.twai0_conf.twai0_clk_en = enable; +} + +/** + * @brief Reset the twai module + * + * @param twai_id Hardware ID + */ +static inline void twai_ll_reset_register(uint8_t twai_id) +{ + PCR.twai0_conf.twai0_rst_en = 1; + PCR.twai0_conf.twai0_rst_en = 0; +} + +/** + * @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) +{ + switch (clk_src) { + case TWAI_CLK_SRC_XTAL: + PCR.twai0_func_clk_conf.twai0_func_clk_sel = 0; + break; + case TWAI_CLK_SRC_PLL_F96M: + PCR.twai0_func_clk_conf.twai0_func_clk_sel = 2; + break; + // We do not plan to support the TWAI_CLK_SRC_RC_FAST clock source, + // as the accuracy of this clock does not meet the requirements for the baud rate + // case TWAI_CLK_SRC_RC_FAST: + // PCR.twai0_func_clk_conf.twai0_func_clk_sel = 1; + // 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) +{ + PCR.twai0_func_clk_conf.twai0_func_clk_en = enable; + if (enable) { + while (!PCR.twai0_conf.twai0_ready); + } +} + +#ifdef __cplusplus +} +#endif diff --git a/components/hal/esp32h4/include/hal/twaifd_ll.h b/components/esp_hal_twai/esp32h4/include/hal/twaifd_ll.h similarity index 68% rename from components/hal/esp32h4/include/hal/twaifd_ll.h rename to components/esp_hal_twai/esp32h4/include/hal/twaifd_ll.h index f61b833df1..fbb9c74280 100644 --- a/components/hal/esp32h4/include/hal/twaifd_ll.h +++ b/components/esp_hal_twai/esp32h4/include/hal/twaifd_ll.h @@ -4,17 +4,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The Lowlevel layer for TWAI is not public api, don't use in application code. - ******************************************************************************/ - #pragma once -#ifdef __cplusplus -extern "C" { -#endif - #include #include "soc/pcr_reg.h" #include "soc/pcr_struct.h" @@ -53,81 +44,35 @@ extern "C" { #define TWAIFD_LL_HW_CMD_RST_ERR_CNT TWAIFD_ERCRST // Error Counters Reset #define TWAIFD_LL_HW_CMD_RST_RX_CNT TWAIFD_RXFCRST // Clear RX bus traffic counter #define TWAIFD_LL_HW_CMD_RST_TX_CNT TWAIFD_TXFCRST // Clear TX bus traffic counter +#define TWAIFD_LL_HW_CMD_CLR_OVERRUN TWAIFD_CDO // Clear RX buffer overrun flag +#define TWAIFD_LL_HW_CMD_RX_FLUSH TWAIFD_RRB // Flush RX buffer (read and write pointers are set to 0 and the frame counter is set to 0) #define TWAIFD_LL_INTR_TX_DONE TWAIFD_TXBHCI_INT_ST// Transmit finish (ok or error) -#define TWAIFD_LL_INTR_TX_SUCCESS TWAIFD_TXI_INT_ST // Transmit success without error +#define TWAIFD_LL_INTR_TX_FRAME TWAIFD_TXI_INT_ST // A frame is transmitted +#define TWAIFD_LL_INTR_RX_FRAME TWAIFD_RXI_INT_ST // A frame is received #define TWAIFD_LL_INTR_RX_NOT_EMPTY TWAIFD_RBNEI_INT_ST // RX buffer not empty interrupt #define TWAIFD_LL_INTR_RX_FULL TWAIFD_RXFI_INT_ST // RX buffer full interrupt -#define TWAIFD_LL_INTR_ERR_WARN TWAIFD_EWLI_INT_ST // Error Interrupt +#define TWAIFD_LL_INTR_OVERLOAD TWAIFD_OFI_INT_ST // Overload Frame Interrupt +#define TWAIFD_LL_INTR_ERR_WARN TWAIFD_EWLI_INT_ST // Error warning limit Interrupt #define TWAIFD_LL_INTR_BUS_ERR TWAIFD_BEI_INT_ST // Bus error interrupt #define TWAIFD_LL_INTR_FSM_CHANGE TWAIFD_FCSI_INT_ST // Fault confinement state changed interrupt -#define TWAIFD_LL_INTR_ARBI_LOST TWAIFD_ALI_INT_ST // Arbitration Lost Interrupt +#define TWAIFD_LL_INTR_ARBIT_LOST TWAIFD_ALI_INT_ST // Arbitration Lost Interrupt #define TWAIFD_LL_INTR_DATA_OVERRUN TWAIFD_DOI_INT_ST // Data Overrun Interrupt +#define TWAIFD_LL_INTR_TIMER_OVERFLOW TWAIFD_TIMER_OVERFLOW_INT_ST // Timer overflow interrupt + #define TWAI_LL_DRIVER_INTERRUPTS (TWAIFD_LL_INTR_TX_DONE | TWAIFD_LL_INTR_RX_NOT_EMPTY | TWAIFD_LL_INTR_RX_FULL | \ TWAIFD_LL_INTR_ERR_WARN | TWAIFD_LL_INTR_BUS_ERR | TWAIFD_LL_INTR_FSM_CHANGE | \ - TWAIFD_LL_INTR_ARBI_LOST | TWAIFD_LL_INTR_DATA_OVERRUN) + TWAIFD_LL_INTR_ARBIT_LOST | TWAIFD_LL_INTR_DATA_OVERRUN) -/** - * @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 twaifd_ll_enable_bus_clock(uint8_t twai_id, bool enable) -{ - PCR.twai0_conf.twai0_clk_en = enable; -} +#ifdef __cplusplus +extern "C" { +#endif -/** - * @brief Reset the twai module - * - * @param twai_id Hardware ID - */ -static inline void twaifd_ll_reset_register(uint8_t twai_id) -{ - PCR.twai0_conf.twai0_rst_en = 1; - PCR.twai0_conf.twai0_rst_en = 0; -} - -/** - * @brief Set clock source for TWAI module - * - * @param twai_id Hardware ID - * @param clk_src Clock source - */ -static inline void twaifd_ll_set_clock_source(uint8_t twai_id, twai_clock_source_t clk_src) -{ - switch (clk_src) { - case TWAI_CLK_SRC_XTAL: - PCR.twai0_func_clk_conf.twai0_func_clk_sel = 0; - break; - case TWAI_CLK_SRC_PLL_F96M: - PCR.twai0_func_clk_conf.twai0_func_clk_sel = 2; - break; - // We do not plan to support the TWAI_CLK_SRC_RC_FAST clock source, - // as the accuracy of this clock does not meet the requirements for the baud rate - // case TWAI_CLK_SRC_RC_FAST: - // PCR.twai0_func_clk_conf.twai0_func_clk_sel = 1; - // 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 twaifd_ll_enable_clock(uint8_t twai_id, bool enable) -{ - PCR.twai0_func_clk_conf.twai0_func_clk_en = enable; - if (enable) { - while (!PCR.twai0_conf.twai0_ready); - } -} +typedef enum { + TWAIFD_LL_TS_POINT_EOF = 0, // in 6th bit of end of frame (moment when the received frame is considered valid) + TWAIFD_LL_TS_POINT_SOF = 1, // start of frame bit +} twaifd_ll_timestamp_point_t; /** * @brief Waits for pending changes to take effect in the hardware. @@ -139,7 +84,6 @@ static inline void twaifd_ll_waiting_state_change(twaifd_dev_t *hw) while (!hw->int_stat.fcsi_int_st); // Wait until the change is applied } - /* ---------------------------- Mode Register ------------------------------- */ // WARNING!! Following 'mode_settings' should in same spin_lock` !!! @@ -156,6 +100,9 @@ static inline void twaifd_ll_reset(twaifd_dev_t *hw) /** * @brief Enable or disable hardware. * + * @note After enable, the node will join the bus after receiving 11 consecutive recessive bits + * @note If disable, the node becomes "bus-off", all TX buffers goes to "empty" state without resetting the memories, RX buffer is flushed. + * * @param hw Pointer to hardware structure. * @param enable Boolean flag to enable (true) or disable (false). */ @@ -191,6 +138,8 @@ static inline void twaifd_ll_set_mode(twaifd_dev_t *hw, bool listen_only, bool s /** * @brief Set the TX retransmission limit. * + * @note First attempt to transmit TWAI frames does not count as retransmission. + * * @param hw Pointer to the TWAI-FD device hardware. * @param limit Retransmission limit (0-15, or negative for infinite). */ @@ -203,20 +152,31 @@ static inline void twaifd_ll_set_tx_retrans_limit(twaifd_dev_t *hw, int8_t limit /** * set bit rate flexible between nominal field and data field - * when set this bit, all frame will be regarded as CANFD frame, even though nominal bit rate and data bit rate are the same + * when set this bit, all frame will be regarded as TWAI FD frame, even though nominal bit rate and data bit rate are the same */ static inline void twaifd_ll_enable_fd_mode(twaifd_dev_t *hw, bool ena) { hw->mode_settings.fde = ena; } +/** + * @brief Whether to enable protocol exception handling + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param ena Set to true to enable PEX, false to disable. + */ +static inline void twaifd_ll_enable_pex(twaifd_dev_t *hw, bool ena) +{ + hw->mode_settings.pex = ena; +} + /** * @brief Enable or disable the RX fifo automatic increase when read to register * * @param hw Pointer to the TWAI-FD device hardware. * @param ena Set to true to enable RX automatic mode, false to disable. */ -static inline void twaifd_ll_enable_rxfifo_auto_incrase(twaifd_dev_t *hw, bool ena) +static inline void twaifd_ll_enable_rxfifo_auto_increase(twaifd_dev_t *hw, bool ena) { hw->mode_settings.rxbam = ena; } @@ -235,12 +195,36 @@ static inline void twaifd_ll_enable_filter_mode(twaifd_dev_t* hw, bool enable) } /** - * @brief Set remote frame filtering behaviour. + * @brief Enable or disable the test mode for the TWAI-FD peripheral. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param enable Set to true to enable test mode, false to disable. + */ +static inline void twaifd_ll_enable_test_mode(twaifd_dev_t* hw, bool enable) +{ + hw->mode_settings.tstm = enable; +} + +/** + * @brief Enable or disable the parity error detection for the RX and TX buffers. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param enable Set to true to enable parity error detection, false to disable. + */ +static inline void twaifd_ll_enable_parity_error_detection(twaifd_dev_t* hw, bool enable) +{ + // Must be called when hardware is disabled. + HAL_ASSERT(hw->mode_settings.ena == 0); + hw->mode_settings.pchke = enable; +} + +/** + * @brief Whether to drop the RTR frames in filter. * * @param hw Pointer to hardware structure. - * @param en True to drop, false to Receive to next filter + * @param en True to drop, false to pass it to the next filter */ -static inline void twaifd_ll_filter_block_rtr(twaifd_dev_t* hw, bool en) +static inline void twaifd_ll_filter_drop_rtr(twaifd_dev_t* hw, bool en) { hw->mode_settings.fdrf = en; } @@ -248,6 +232,8 @@ static inline void twaifd_ll_filter_block_rtr(twaifd_dev_t* hw, bool en) /** * @brief Enable or disable the time-triggered transmission mode for the TWAI-FD peripheral. * + * @note Time triggered transmission is always considered only from the highest priority TX buffer in “ready” state. + * * @param hw Pointer to the TWAI-FD device hardware. * @param enable Set to true to enable time-triggered transmission mode, false to disable. */ @@ -256,6 +242,19 @@ static inline void twaifd_ll_enable_time_trig_trans_mode(twaifd_dev_t* hw, bool hw->mode_settings.tttm = enable; } +/** + * @brief Whether to treat bus-off as TX failure + * + * @note Disable it, it allows going bus-off and re-integrating without the need of software interaction with TX buffers. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param enable Set to true to enable, false to disable. + */ +static inline void twaifd_ll_enable_bus_off_tx_fail_mode(twaifd_dev_t* hw, bool enable) +{ + hw->mode_settings.tbfbo = enable; +} + /* --------------------------- Command Register ----------------------------- */ /** * @brief Set command to TWAIFD hardware @@ -369,6 +368,17 @@ static inline void twaifd_ll_config_secondary_sample_point(twaifd_dev_t *hw, uin HAL_FORCE_MODIFY_U32_REG_FIELD(hw->trv_delay_ssp_cfg, ssp_offset, offset_val); } +/** + * @brief Get measured transmitter delay + * + * @param hw Start address of the TWAI registers + * @return Transmitter Delay Value in clock source cycles, include the input delay of TWAI FD (2 cycles) + */ +static inline uint32_t twaifd_ll_get_transmitter_delay(twaifd_dev_t *hw) +{ + return hw->trv_delay_ssp_cfg.trv_delay_value; +} + /* ----------------------------- ERR Capt Register ------------------------------- */ /** @@ -430,10 +440,10 @@ static inline twai_error_state_t twaifd_ll_get_fault_state(twaifd_dev_t *hw) } /** - * @brief Get the error count in normal mode for the TWAI-FD peripheral. + * @brief Get the error count in nominal bit rate stage. * * @param hw Pointer to the TWAI-FD device hardware. - * @return Error count in normal mode. + * @return Error count in nominal bit rate stage. */ static inline uint32_t twaifd_ll_get_err_count_norm(twaifd_dev_t *hw) { @@ -441,10 +451,10 @@ static inline uint32_t twaifd_ll_get_err_count_norm(twaifd_dev_t *hw) } /** - * @brief Get the error count in FD mode for the TWAI-FD peripheral. + * @brief Get the error count in FD data bit rate stage. * * @param hw Pointer to the TWAI-FD device hardware. - * @return Error count in FD mode. + * @return Error count in FD data bit rate stage. */ static inline uint32_t twaifd_ll_get_err_count_fd(twaifd_dev_t *hw) { @@ -479,122 +489,174 @@ static inline uint32_t twaifd_ll_get_tec(twaifd_dev_t *hw) /* ---------------------- Acceptance Filter Registers ----------------------- */ /** - * @brief Enable or disable filter to receive basic frame with std id + * @brief Enable or disable mask filter to receive classic frame with std id * * @param hw Pointer to the TWAI FD hardware instance - * @param filter_id The unique ID of the filter to configure - * @param is_range Setting for range filter or mask filter - * @param en True to receive, False to drop + * @param filter_id The unique ID of the mask filter to configure + * @param accept True to accept the frame, False to drop the frame */ -static inline void twaifd_ll_filter_enable_basic_std(twaifd_dev_t* hw, uint8_t filter_id, bool is_range, bool en) +static inline void twaifd_ll_mask_filter_accept_classic_std(twaifd_dev_t* hw, uint8_t filter_id, bool accept) { - HAL_ASSERT(filter_id < (is_range ? SOC_TWAI_RANGE_FILTER_NUM : SOC_TWAI_MASK_FILTER_NUM)); - // The hw_filter_id of range_filter is indexed after mask_filter - uint8_t hw_filter_id = is_range ? filter_id + SOC_TWAI_MASK_FILTER_NUM : filter_id; - if (en) { - hw->filter_control_filter_status.val |= TWAIFD_FANB << (hw_filter_id * TWAIFD_FBNB_S); + if (accept) { + hw->filter_control_filter_status.val |= 0x01 << (filter_id * 4); } else { - hw->filter_control_filter_status.val &= ~(TWAIFD_FANB << (hw_filter_id * TWAIFD_FBNB_S)); + hw->filter_control_filter_status.val &= ~(0x01 << (filter_id * 4)); } } /** - * @brief Enable or disable filter to receive basic frame with ext id + * @brief Enable or disable mask filter to receive classic frame with ext id * * @param hw Pointer to the TWAI FD hardware instance - * @param filter_id The unique ID of the filter to configure - * @param is_range Setting for range filter or mask filter - * @param en True to receive, False to drop + * @param filter_id The unique ID of the mask filter to configure + * @param accept True to accept the frame, False to drop the frame */ -static inline void twaifd_ll_filter_enable_basic_ext(twaifd_dev_t* hw, uint8_t filter_id, bool is_range, bool en) +static inline void twaifd_ll_mask_filter_accept_classic_ext(twaifd_dev_t* hw, uint8_t filter_id, bool accept) { - HAL_ASSERT(filter_id < (is_range ? SOC_TWAI_RANGE_FILTER_NUM : SOC_TWAI_MASK_FILTER_NUM)); - // The hw_filter_id of range_filter is indexed after mask_filter - uint8_t hw_filter_id = is_range ? filter_id + SOC_TWAI_MASK_FILTER_NUM : filter_id; - if (en) { - hw->filter_control_filter_status.val |= TWAIFD_FANE << (hw_filter_id * TWAIFD_FBNB_S); + if (accept) { + hw->filter_control_filter_status.val |= 0x02 << (filter_id * 4); } else { - hw->filter_control_filter_status.val &= ~(TWAIFD_FANE << (hw_filter_id * TWAIFD_FBNB_S)); + hw->filter_control_filter_status.val &= ~(0x02 << (filter_id * 4)); } } /** - * @brief Enable or disable filter to receive fd frame with std id + * @brief Enable or disable mask filter to receive fd frame with std id * * @param hw Pointer to the TWAI FD hardware instance - * @param filter_id The unique ID of the filter to configure - * @param is_range Setting for range filter or mask filter - * @param en True to receive, False to drop + * @param filter_id The unique ID of the mask filter to configure + * @param accept True to accept the frame, False to drop the frame */ -static inline void twaifd_ll_filter_enable_fd_std(twaifd_dev_t* hw, uint8_t filter_id, bool is_range, bool en) +static inline void twaifd_ll_mask_filter_accept_fd_std(twaifd_dev_t* hw, uint8_t filter_id, bool accept) { - HAL_ASSERT(filter_id < (is_range ? SOC_TWAI_RANGE_FILTER_NUM : SOC_TWAI_MASK_FILTER_NUM)); - // The hw_filter_id of range_filter is indexed after mask_filter - uint8_t hw_filter_id = is_range ? filter_id + SOC_TWAI_MASK_FILTER_NUM : filter_id; - if (en) { - hw->filter_control_filter_status.val |= TWAIFD_FAFB << (hw_filter_id * TWAIFD_FBNB_S); + if (accept) { + hw->filter_control_filter_status.val |= 0x04 << (filter_id * 4); } else { - hw->filter_control_filter_status.val &= ~(TWAIFD_FAFB << (hw_filter_id * TWAIFD_FBNB_S)); + hw->filter_control_filter_status.val &= ~(0x04 << (filter_id * 4)); } } /** - * @brief Enable or disable filter to receive fd frame with ext id + * @brief Enable or disable mask filter to receive fd frame with ext id * * @param hw Pointer to the TWAI FD hardware instance - * @param filter_id The unique ID of the filter to configure - * @param is_range Setting for range filter or mask filter - * @param en True to receive, False to drop + * @param filter_id The unique ID of the mask filter to configure + * @param accept True to accept the frame, False to drop the frame */ -static inline void twaifd_ll_filter_enable_fd_ext(twaifd_dev_t* hw, uint8_t filter_id, bool is_range, bool en) +static inline void twaifd_ll_mask_filter_accept_fd_ext(twaifd_dev_t* hw, uint8_t filter_id, bool accept) { - HAL_ASSERT(filter_id < (is_range ? SOC_TWAI_RANGE_FILTER_NUM : SOC_TWAI_MASK_FILTER_NUM)); - // The hw_filter_id of range_filter is indexed after mask_filter - uint8_t hw_filter_id = is_range ? filter_id + SOC_TWAI_MASK_FILTER_NUM : filter_id; - if (en) { - hw->filter_control_filter_status.val |= TWAIFD_FAFE << (hw_filter_id * TWAIFD_FBNB_S); + if (accept) { + hw->filter_control_filter_status.val |= 0x08 << (filter_id * 4); } else { - hw->filter_control_filter_status.val &= ~(TWAIFD_FAFE << (hw_filter_id * TWAIFD_FBNB_S)); + hw->filter_control_filter_status.val &= ~(0x08 << (filter_id * 4)); } } /** - * @brief Set Bit Acceptance Filter + * @brief Enable or disable range filter to receive classic frame with std id + * + * @param hw Pointer to the TWAI FD hardware instance + * @param filter_id The unique ID of the range filter to configure + * @param accept True to accept the frame, False to drop the frame + */ +static inline void twaifd_ll_range_filter_accept_classic_std(twaifd_dev_t* hw, uint8_t filter_id, bool accept) +{ + uint8_t hw_filter_id = filter_id + 3; + if (accept) { + hw->filter_control_filter_status.val |= 0x01 << (hw_filter_id * 4); + } else { + hw->filter_control_filter_status.val &= ~(0x01 << (hw_filter_id * 4)); + } +} + +/** + * @brief Enable or disable range filter to receive classic frame with ext id + * + * @param hw Pointer to the TWAI FD hardware instance + * @param filter_id The unique ID of the range filter to configure + * @param accept True to accept the frame, False to drop the frame + */ +static inline void twaifd_ll_range_filter_accept_classic_ext(twaifd_dev_t* hw, uint8_t filter_id, bool accept) +{ + uint8_t hw_filter_id = filter_id + 3; + if (accept) { + hw->filter_control_filter_status.val |= 0x02 << (hw_filter_id * 4); + } else { + hw->filter_control_filter_status.val &= ~(0x02 << (hw_filter_id * 4)); + } +} + +/** + * @brief Enable or disable range filter to receive fd frame with std id + * + * @param hw Pointer to the TWAI FD hardware instance + * @param filter_id The unique ID of the range filter to configure + * @param accept True to accept the frame, False to drop the frame + */ +static inline void twaifd_ll_range_filter_accept_fd_std(twaifd_dev_t* hw, uint8_t filter_id, bool accept) +{ + uint8_t hw_filter_id = filter_id + 3; + if (accept) { + hw->filter_control_filter_status.val |= 0x04 << (hw_filter_id * 4); + } else { + hw->filter_control_filter_status.val &= ~(0x04 << (hw_filter_id * 4)); + } +} + +/** + * @brief Enable or disable range filter to receive fd frame with ext id + * + * @param hw Pointer to the TWAI FD hardware instance + * @param filter_id The unique ID of the range filter to configure + * @param accept True to accept the frame, False to drop the frame + */ +static inline void twaifd_ll_range_filter_accept_fd_ext(twaifd_dev_t* hw, uint8_t filter_id, bool accept) +{ + uint8_t hw_filter_id = filter_id + 3; + if (accept) { + hw->filter_control_filter_status.val |= 0x08 << (hw_filter_id * 4); + } else { + hw->filter_control_filter_status.val &= ~(0x08 << (hw_filter_id * 4)); + } +} + +/** + * @brief Set the ID and mask for mask filter * @param hw Start address of the TWAI registers * @param filter_id Filter number id * @param is_ext Filter for ext_id or std_id * @param code Acceptance Code * @param mask Acceptance Mask */ -static inline void twaifd_ll_filter_set_id_mask(twaifd_dev_t* hw, uint8_t filter_id, bool is_ext, uint32_t code, uint32_t mask) +static inline void twaifd_ll_mask_filter_set_id_mask(twaifd_dev_t* hw, uint8_t filter_id, bool is_ext, uint32_t code, uint32_t mask) { hw->mask_filters[filter_id].filter_mask.bit_mask_val = is_ext ? mask : (mask << TWAIFD_IDENTIFIER_BASE_S); hw->mask_filters[filter_id].filter_val.bit_val = is_ext ? code : (code << TWAIFD_IDENTIFIER_BASE_S); } /** - * @brief Set Range Acceptance Filter + * @brief Set the ID range for range filter * @param hw Start address of the TWAI registers * @param filter_id Filter number id * @param is_ext Filter for ext_id or std_id * @param high The id range high limit * @param low The id range low limit */ -static inline void twaifd_ll_filter_set_range(twaifd_dev_t* hw, uint8_t filter_id, bool is_ext, uint32_t high, uint32_t low) +static inline void twaifd_ll_range_filter_set_id_thres(twaifd_dev_t* hw, uint8_t filter_id, bool is_ext, uint32_t high, uint32_t low) { hw->range_filters[filter_id].ran_low.bit_ran_low_val = is_ext ? low : (low << TWAIFD_IDENTIFIER_BASE_S); - hw->range_filters[filter_id].ran_high.bit_ran_high_val = is_ext ? high : (high << TWAIFD_IDENTIFIER_BASE_S); + hw->range_filters[filter_id].ran_high.bit_ran_high_val = is_ext ? high : (high << TWAIFD_IDENTIFIER_BASE_S) | 0x3FFFF; } /* ------------------------- TX Buffer Registers ------------------------- */ /** - * @brief Get the number of TX buffers available. + * @brief Get the number of TX buffers that are preset in the hardware. * * @param hw Pointer to the TWAI-FD device hardware. * @return The number of TX buffers available. */ -static inline uint32_t twaifd_ll_get_tx_buffer_quantity(twaifd_dev_t *hw) +static inline uint32_t twaifd_ll_get_tx_buffer_total(twaifd_dev_t *hw) { return hw->tx_command_txtb_info.txt_buffer_count; } @@ -608,24 +670,24 @@ static inline uint32_t twaifd_ll_get_tx_buffer_quantity(twaifd_dev_t *hw) */ static inline uint32_t twaifd_ll_get_tx_buffer_status(twaifd_dev_t *hw, uint8_t buffer_idx) { - HAL_ASSERT(buffer_idx < twaifd_ll_get_tx_buffer_quantity(hw)); // Ensure buffer index is valid + HAL_ASSERT(buffer_idx < twaifd_ll_get_tx_buffer_total(hw)); // Ensure buffer index is valid uint32_t reg_val = hw->tx_status.val; return reg_val & (TWAIFD_TX2S_V << (TWAIFD_TX2S_S * buffer_idx)); // Get status for buffer } /** - * @brief Set TX Buffer command + * @brief Set TX Buffer command * * Setting the TX command will cause the TWAI controller to attempt to transmit * the frame stored in the TX buffer. The TX buffer will be occupied (i.e., * locked) until TX completes. * * @param hw Start address of the TWAI registers - * @param buffer_idx + * @param buffer_idx The tx buffer index to set the command * @param cmd The command want to set, see `TWAIFD_LL_TX_CMD_` */ __attribute__((always_inline)) -static inline void twaifd_ll_set_tx_cmd(twaifd_dev_t *hw, uint8_t buffer_idx, uint32_t cmd) +static inline void twaifd_ll_set_tx_buffer_cmd(twaifd_dev_t *hw, uint8_t buffer_idx, uint32_t cmd) { hw->tx_command_txtb_info.val = (cmd | BIT(buffer_idx + TWAIFD_TXB1_S)); } @@ -633,13 +695,15 @@ static inline void twaifd_ll_set_tx_cmd(twaifd_dev_t *hw, uint8_t buffer_idx, ui /** * @brief Set the priority for a specific TX buffer. * + * @note If two TX buffers have equal priority, TX buffer with the lower index has precedence. + * * @param hw Pointer to the TWAI-FD device hardware. * @param buffer_idx Index of the TX buffer (0-7). - * @param priority The priority level to set for the buffer. + * @param priority The priority level to set for the buffer. Higher values indicate higher priority. */ static inline void twaifd_ll_set_tx_buffer_priority(twaifd_dev_t *hw, uint8_t buffer_idx, uint32_t priority) { - HAL_ASSERT(buffer_idx < twaifd_ll_get_tx_buffer_quantity(hw)); // Ensure buffer index is valid + HAL_ASSERT(buffer_idx < twaifd_ll_get_tx_buffer_total(hw)); // Ensure buffer index is valid uint32_t reg_val = hw->tx_priority.val; reg_val &= ~(TWAIFD_TXT1P_V << (TWAIFD_TXT2P_S * buffer_idx)); // Clear old priority reg_val |= priority << (TWAIFD_TXT2P_S * buffer_idx); // Set new priority @@ -669,14 +733,27 @@ static inline void twaifd_ll_mount_tx_buffer(twaifd_dev_t *hw, twaifd_frame_buff /** * @brief Get the size of the RX buffer. * + * @note It contains a single RX buffer where received frames are stored. + * * @param hw Pointer to the TWAI-FD device hardware. - * @return Size of the RX buffer. + * @return Size of the RX buffer, in multiple of 32-bit words. */ static inline uint32_t twaifd_ll_get_rx_buffer_size(twaifd_dev_t *hw) { return hw->rx_mem_info.rx_buff_size; } +/** + * @brief Get the free space in the RX buffer. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @return Free space in the RX buffer, in multiple of 32-bit words. + */ +static inline uint32_t twaifd_ll_get_rx_free_space(twaifd_dev_t *hw) +{ + return hw->rx_mem_info.rx_free; +} + /** * @brief Get the number of frames in the RX buffer. * @@ -693,15 +770,26 @@ static inline uint32_t twaifd_ll_get_rx_frame_count(twaifd_dev_t *hw) * @brief Check if the RX FIFO is empty. * * @param hw Pointer to the TWAI-FD device hardware. - * @return 1 if RX FIFO is empty, 0 otherwise. + * @return true if RX FIFO is empty, false otherwise. */ -static inline uint32_t twaifd_ll_is_rx_buffer_empty(twaifd_dev_t *hw) +static inline bool twaifd_ll_is_rx_buffer_empty(twaifd_dev_t *hw) { return hw->rx_status_rx_settings.rxe; } /** - * @brief Copy a received frame from the RX buffer for parsing + * @brief Check if the RX FIFO is full. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @return true if RX FIFO is full, false otherwise. + */ +static inline bool twaifd_ll_is_rx_buffer_full(twaifd_dev_t *hw) +{ + return hw->rx_status_rx_settings.rxf; +} + +/** + * @brief Copy a received frame from the RX buffer for parsing * * @param hw Start address of the TWAI registers * @param rx_frame Pointer to store formatted frame @@ -839,18 +927,29 @@ static inline uint32_t twaifd_ll_get_tx_traffic_counter(twaifd_dev_t *hw) /* ------------------------- Timestamp Register ------------------------- */ /** - * @brief Enable or disable the timer clock. + * @brief Set the sample point for the timestamp. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @param sample_point Sample point for the timestamp. + */ +static inline void twaifd_ll_ts_set_sample_point(twaifd_dev_t *hw, twaifd_ll_timestamp_point_t sample_point) +{ + hw->rx_status_rx_settings.rtsop = sample_point; +} + +/** + * @brief Whether to force enable the register config clock of the timer * * @param hw Pointer to the TWAI-FD device hardware. * @param enable True to enable, false to disable. */ -static inline void twaifd_ll_timer_enable_clock(twaifd_dev_t *hw, bool enable) +static inline void twaifd_ll_timer_force_enable_cfg_clock(twaifd_dev_t *hw, bool enable) { hw->timer_clk_en.clk_en = enable; } /** - * @brief Enable or disable timer power. + * @brief Enable or disable the timer. * * @param hw Pointer to the TWAI-FD device hardware. * @param enable True to enable, false to disable. @@ -860,9 +959,34 @@ static inline void twaifd_ll_timer_enable(twaifd_dev_t *hw, bool enable) hw->timer_cfg.timer_ce = enable; } +/** + * @brief Get the bit width of the timer. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @return Bit width of the timer. + */ +static inline uint8_t twaifd_ll_timer_get_bitwidth(twaifd_dev_t *hw) +{ + return hw->err_capt_retr_ctr_alc_ts_info.ts_bits + 1; +} + +/** + * @brief Get the current timer count. + * + * @param hw Pointer to the TWAI-FD device hardware. + * @return Current timer count as a 64-bit value. + */ +static inline uint64_t twaifd_ll_timer_get_count(twaifd_dev_t *hw) +{ + uint64_t count = ((uint64_t)hw->timestamp_high.val << 32) | hw->timestamp_low.val; + return count; +} + /** * @brief Set the timer step value. * + * @note This is to determine the resolution of the timer. We can also treat it as a prescaler. + * * @param hw Pointer to the TWAI-FD device hardware. * @param step Step value to set (actual step = step - 1). */ diff --git a/components/soc/esp32h4/twai_periph.c b/components/esp_hal_twai/esp32h4/twai_periph.c similarity index 82% rename from components/soc/esp32h4/twai_periph.c rename to components/esp_hal_twai/esp32h4/twai_periph.c index 12df11526b..a27443fbdd 100644 --- a/components/soc/esp32h4/twai_periph.c +++ b/components/esp_hal_twai/esp32h4/twai_periph.c @@ -1,11 +1,12 @@ /* * SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" const twai_signal_conn_t twai_periph_signals[1] = { [0] = { diff --git a/components/hal/esp32p4/include/hal/twai_ll.h b/components/esp_hal_twai/esp32p4/include/hal/twai_ll.h similarity index 98% rename from components/hal/esp32p4/include/hal/twai_ll.h rename to components/esp_hal_twai/esp32p4/include/hal/twai_ll.h index 2eb02c75fc..2e4b65b7a1 100644 --- a/components/hal/esp32p4/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32p4/include/hal/twai_ll.h @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - -// The Lowlevel layer for TWAI - #pragma once #include @@ -21,11 +13,15 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/twai_types.h" -#include "soc/twai_periph.h" #include "soc/twai_reg.h" #include "soc/twai_struct.h" #include "soc/hp_sys_clkrst_struct.h" +#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr +#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat + +#define TWAI_LL_SUPPORT_RX_STATUS 1 + #define TWAI_LL_GET_HW(controller_id) ((controller_id == 0) ? (&TWAI0) : (controller_id == 1) ? (&TWAI1) : (&TWAI2)) #ifdef __cplusplus diff --git a/components/soc/esp32p4/twai_periph.c b/components/esp_hal_twai/esp32p4/twai_periph.c similarity index 93% rename from components/soc/esp32p4/twai_periph.c rename to components/esp_hal_twai/esp32p4/twai_periph.c index 18ebc43138..0280ec432d 100644 --- a/components/soc/esp32p4/twai_periph.c +++ b/components/esp_hal_twai/esp32p4/twai_periph.c @@ -1,14 +1,15 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/twai_reg.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" -const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM] = { +const twai_signal_conn_t twai_periph_signals[3] = { [0] = { .module_name = "TWAI0", .irq_id = ETS_TWAI0_INTR_SOURCE, @@ -72,7 +73,7 @@ static const regdma_entries_config_t twai0_regs_retention[] = TWAI_SLEEP_RETENTI static const regdma_entries_config_t twai1_regs_retention[] = TWAI_SLEEP_RETENTION_ENTRIES(1); static const regdma_entries_config_t twai2_regs_retention[] = TWAI_SLEEP_RETENTION_ENTRIES(2); -const twai_reg_retention_info_t twai_reg_retention_info[SOC_TWAI_CONTROLLER_NUM] = { +const twai_reg_retention_info_t twai_reg_retention_info[3] = { [0] = { .module_id = SLEEP_RETENTION_MODULE_TWAI0, .entry_array = twai0_regs_retention, diff --git a/components/hal/esp32s2/include/hal/twai_ll.h b/components/esp_hal_twai/esp32s2/include/hal/twai_ll.h similarity index 97% rename from components/hal/esp32s2/include/hal/twai_ll.h rename to components/esp_hal_twai/esp32s2/include/hal/twai_ll.h index a224b9523f..bb670d63b0 100644 --- a/components/hal/esp32s2/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32s2/include/hal/twai_ll.h @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - -// The Lowlevel layer for TWAI - #pragma once #include @@ -21,10 +13,15 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/twai_types.h" -#include "soc/twai_periph.h" #include "soc/twai_struct.h" #include "soc/system_reg.h" +#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr +#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat + +#define TWAI_LL_SUPPORT_RX_STATUS 1 +#define TWAI_LL_SUPPORT_APB_CLK 1 + #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 @@ -513,9 +510,9 @@ __attribute__((always_inline)) static inline void twai_ll_parse_err_code_cap(twai_dev_t *hw, twai_ll_err_type_t *type, twai_ll_err_dir_t *dir, twai_ll_err_seg_t *seg) { uint32_t ecc = hw->error_code_capture_reg.val; - *type = (twai_ll_err_type_t) ((ecc >> 6) & 0x3); - *dir = (twai_ll_err_dir_t) ((ecc >> 5) & 0x1); - *seg = (twai_ll_err_seg_t) (ecc & 0x1F); + *type = (twai_ll_err_type_t)((ecc >> 6) & 0x3); + *dir = (twai_ll_err_dir_t)((ecc >> 5) & 0x1); + *seg = (twai_ll_err_seg_t)(ecc & 0x1F); } /* ----------------------------- EWL Register ------------------------------- */ @@ -683,7 +680,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; diff --git a/components/soc/esp32s2/twai_periph.c b/components/esp_hal_twai/esp32s2/twai_periph.c similarity index 71% rename from components/soc/esp32s2/twai_periph.c rename to components/esp_hal_twai/esp32s2/twai_periph.c index 2cf0f906bd..7f707767c0 100644 --- a/components/soc/esp32s2/twai_periph.c +++ b/components/esp_hal_twai/esp32s2/twai_periph.c @@ -1,13 +1,14 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" -const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM] = { +const twai_signal_conn_t twai_periph_signals[1] = { [0] = { .module_name = "TWAI0", .irq_id = ETS_TWAI_INTR_SOURCE, diff --git a/components/hal/esp32s3/include/hal/twai_ll.h b/components/esp_hal_twai/esp32s3/include/hal/twai_ll.h similarity index 97% rename from components/hal/esp32s3/include/hal/twai_ll.h rename to components/esp_hal_twai/esp32s3/include/hal/twai_ll.h index 538a40e129..ddef2cbfc0 100644 --- a/components/hal/esp32s3/include/hal/twai_ll.h +++ b/components/esp_hal_twai/esp32s3/include/hal/twai_ll.h @@ -4,14 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The ll is not public api, don't use in application code. - * See readme.md in hal/include/hal/readme.md - ******************************************************************************/ - -// The Lowlevel layer for TWAI - #pragma once #include @@ -21,10 +13,15 @@ #include "hal/misc.h" #include "hal/assert.h" #include "hal/twai_types.h" -#include "soc/twai_periph.h" #include "soc/twai_struct.h" #include "soc/system_struct.h" +#define TWAI_LL_GET(_attr) TWAI_LL_ ## _attr +#define TWAI_LL_SUPPORT(_feat) TWAI_LL_SUPPORT_ ## _feat + +#define TWAI_LL_SUPPORT_RX_STATUS 1 +#define TWAI_LL_SUPPORT_APB_CLK 1 + #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 @@ -510,9 +507,9 @@ __attribute__((always_inline)) static inline void twai_ll_parse_err_code_cap(twai_dev_t *hw, twai_ll_err_type_t *type, twai_ll_err_dir_t *dir, twai_ll_err_seg_t *seg) { uint32_t ecc = hw->error_code_capture_reg.val; - *type = (twai_ll_err_type_t) ((ecc >> 6) & 0x3); - *dir = (twai_ll_err_dir_t) ((ecc >> 5) & 0x1); - *seg = (twai_ll_err_seg_t) (ecc & 0x1F); + *type = (twai_ll_err_type_t)((ecc >> 6) & 0x3); + *dir = (twai_ll_err_dir_t)((ecc >> 5) & 0x1); + *seg = (twai_ll_err_seg_t)(ecc & 0x1F); } /* ----------------------------- EWL Register ------------------------------- */ @@ -680,7 +677,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; diff --git a/components/soc/esp32s3/twai_periph.c b/components/esp_hal_twai/esp32s3/twai_periph.c similarity index 71% rename from components/soc/esp32s3/twai_periph.c rename to components/esp_hal_twai/esp32s3/twai_periph.c index 2cf0f906bd..7f707767c0 100644 --- a/components/soc/esp32s3/twai_periph.c +++ b/components/esp_hal_twai/esp32s3/twai_periph.c @@ -1,13 +1,14 @@ /* * SPDX-FileCopyrightText: 2022-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ -#include "soc/twai_periph.h" +#include "hal/twai_periph.h" #include "soc/gpio_sig_map.h" +#include "soc/interrupts.h" -const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM] = { +const twai_signal_conn_t twai_periph_signals[1] = { [0] = { .module_name = "TWAI0", .irq_id = ETS_TWAI_INTR_SOURCE, diff --git a/components/hal/include/hal/twai_hal.h b/components/esp_hal_twai/include/hal/twai_hal.h similarity index 96% rename from components/hal/include/hal/twai_hal.h rename to components/esp_hal_twai/include/hal/twai_hal.h index 31db1b9c59..d3a26148fd 100644 --- a/components/hal/include/hal/twai_hal.h +++ b/components/esp_hal_twai/include/hal/twai_hal.h @@ -4,11 +4,6 @@ * SPDX-License-Identifier: Apache-2.0 */ -/******************************************************************************* - * NOTICE - * The hal is not public api, don't use in application code. - ******************************************************************************/ - #pragma once #include @@ -16,23 +11,22 @@ #include "soc/soc_caps.h" #include "hal/twai_types.h" -#if SOC_TWAI_SUPPORTED - -#if SOC_TWAI_SUPPORT_FD -typedef struct twaifd_dev_t *twai_soc_handle_t; -typedef union twaifd_frame_buffer_t twai_hal_frame_t; -#else -typedef struct twai_dev_t *twai_soc_handle_t; -typedef union twai_ll_frame_buffer_t twai_hal_frame_t; -#endif -typedef struct twai_hal_errata_ctx_t twai_hal_errata_ctx_t; - #ifdef __cplusplus extern "C" { #endif /* ------------------------- Defines and Typedefs --------------------------- */ +typedef struct twai_hal_errata_ctx_t twai_hal_errata_ctx_t; + +#if SOC_HAS(TWAI_FD) +typedef struct twaifd_dev_t *twai_soc_handle_t; +typedef union twaifd_frame_buffer_t twai_hal_frame_t; +#else +typedef struct twai_dev_t *twai_soc_handle_t; +typedef union twai_ll_frame_buffer_t twai_hal_frame_t; +#endif // SOC_HAS(TWAI_FD) + #define TWAI_HAL_SET_BITS(var, flag) ((var) |= (flag)) #define TWAI_HAL_CLEAR_BITS(var, flag) ((var) &= ~(flag)) @@ -156,7 +150,7 @@ void twai_hal_configure_timing_fd(twai_hal_context_t *hal_ctx, const twai_timing * @param filter_id Which filter to be configured * @param f_config Pointer to filter configuration structure */ -void twai_hal_configure_filter(twai_hal_context_t *hal_ctx, uint8_t filter_id, const twai_mask_filter_config_t *f_config); +void twai_hal_configure_mask_filter(twai_hal_context_t *hal_ctx, uint8_t filter_id, const twai_mask_filter_config_t *f_config); /** * @brief Configure the TWAI range filter @@ -350,7 +344,6 @@ void twai_hal_set_tx_buffer_and_transmit(twai_hal_context_t *hal_ctx, twai_hal_f */ bool twai_hal_read_rx_fifo(twai_hal_context_t *hal_ctx, twai_hal_frame_t *rx_frame); -#ifndef SOC_TWAI_SUPPORTS_RX_STATUS /** * @brief Clear the RX FIFO of overrun frames * @@ -361,7 +354,6 @@ bool twai_hal_read_rx_fifo(twai_hal_context_t *hal_ctx, twai_hal_frame_t *rx_fra * @return Number of overrun messages cleared from RX FIFO */ uint32_t twai_hal_clear_rx_fifo_overrun(twai_hal_context_t *hal_ctx); -#endif //SOC_TWAI_SUPPORTS_RX_STATUS /* --------------------------- Errata Workarounds --------------------------- */ @@ -428,4 +420,3 @@ uint32_t twai_hal_get_reset_lost_rx_cnt(twai_hal_context_t *hal_ctx); #ifdef __cplusplus } #endif -#endif // SOC_TWAI_SUPPORTED diff --git a/components/soc/include/soc/twai_periph.h b/components/esp_hal_twai/include/hal/twai_periph.h similarity index 79% rename from components/soc/include/soc/twai_periph.h rename to components/esp_hal_twai/include/hal/twai_periph.h index fa18bb20ce..55d3d81e8e 100644 --- a/components/soc/include/soc/twai_periph.h +++ b/components/esp_hal_twai/include/hal/twai_periph.h @@ -1,30 +1,32 @@ /* * SPDX-FileCopyrightText: 2019-2025 Espressif Systems (Shanghai) CO LTD * - * SPDX-License-Identifier: Apache-2.0 OR MIT + * SPDX-License-Identifier: Apache-2.0 */ #pragma once #include #include "soc/soc_caps.h" -#include "soc/periph_defs.h" -#if SOC_PAU_SUPPORTED #include "soc/regdma.h" +#if SOC_HAS(PAU) #include "soc/retention_periph_defs.h" #endif +#if SOC_HAS(TWAI) +#include "hal/twai_ll.h" +#endif #ifdef __cplusplus extern "C" { #endif -#if SOC_TWAI_SUPPORTED +#if SOC_HAS(TWAI) typedef struct { const char *module_name; // peripheral name const int irq_id; // interrupt source ID -#if SOC_TWAI_SUPPORT_TIMESTAMP - const int timer_irq_id; +#if TWAI_LL_SUPPORT(TIMESTAMP) + const int timer_irq_id; // time base interrupt source ID #endif const int tx_sig; // TX signal ID in GPIO matrix const int rx_sig; // RX signal ID in GPIO matrix @@ -35,7 +37,7 @@ typedef struct { extern const twai_signal_conn_t twai_periph_signals[SOC_TWAI_CONTROLLER_NUM]; -#if SOC_PAU_SUPPORTED +#if SOC_HAS(PAU) typedef struct { const periph_retention_module_t module_id; const regdma_entries_config_t *entry_array; @@ -43,9 +45,9 @@ typedef struct { } twai_reg_retention_info_t; extern const twai_reg_retention_info_t twai_reg_retention_info[SOC_TWAI_CONTROLLER_NUM]; -#endif // SOC_PAU_SUPPORTED +#endif // SOC_HAS(PAU) -#endif // SOC_TWAI_SUPPORTED +#endif // SOC_HAS(TWAI) #ifdef __cplusplus } diff --git a/components/hal/include/hal/twai_types.h b/components/esp_hal_twai/include/hal/twai_types.h similarity index 95% rename from components/hal/include/hal/twai_types.h rename to components/esp_hal_twai/include/hal/twai_types.h index c4a399964d..488f4b8197 100644 --- a/components/hal/include/hal/twai_types.h +++ b/components/esp_hal_twai/include/hal/twai_types.h @@ -88,7 +88,7 @@ typedef twai_timing_config_t twai_timing_advanced_config_t; * @brief Configuration for TWAI mask filter */ typedef struct { - union{ + union { uint32_t id; /**< Single base ID for filtering */ struct { uint32_t *id_list; /**< Base ID list array for filtering, which share the same `mask` */ @@ -108,8 +108,8 @@ typedef struct { * @brief Range-based filter configuration structure */ typedef struct { - uint32_t range_low; /**< Lower bound of the filtering range */ - uint32_t range_high; /**< Upper bound of the filtering range */ + uint32_t range_low; /**< Lower bound of the ID filtering range, included */ + uint32_t range_high; /**< Upper bound of the ID filtering range, included */ struct { uint32_t is_ext: 1; /**< True for extended ID filtering, false for standard ID */ uint32_t no_classic: 1; /**< If true, Classic TWAI frames are excluded (only TWAI FD allowed) */ @@ -142,7 +142,8 @@ typedef struct { * @return The byte length of DLC stand for */ __attribute__((always_inline)) -static inline uint16_t twaifd_dlc2len(uint16_t dlc) { +static inline uint16_t twaifd_dlc2len(uint16_t dlc) +{ HAL_ASSERT(dlc <= TWAIFD_FRAME_MAX_DLC); return (dlc <= 8) ? dlc : (dlc <= 12) ? (dlc - 8) * 4 + 8 : @@ -156,7 +157,8 @@ static inline uint16_t twaifd_dlc2len(uint16_t dlc) { * @return The FD adopted frame DLC code */ __attribute__((always_inline)) -static inline uint16_t twaifd_len2dlc(uint16_t byte_len) { +static inline uint16_t twaifd_len2dlc(uint16_t byte_len) +{ HAL_ASSERT(byte_len <= TWAIFD_FRAME_MAX_LEN); return (byte_len <= 8) ? byte_len : (byte_len <= 24) ? (byte_len - 8 + 3) / 4 + 8 : diff --git a/components/hal/include/hal/twai_types_deprecated.h b/components/esp_hal_twai/include/hal/twai_types_deprecated.h similarity index 94% rename from components/hal/include/hal/twai_types_deprecated.h rename to components/esp_hal_twai/include/hal/twai_types_deprecated.h index 1752c78666..7695cd71e3 100644 --- a/components/hal/include/hal/twai_types_deprecated.h +++ b/components/esp_hal_twai/include/hal/twai_types_deprecated.h @@ -39,9 +39,6 @@ extern "C" { #define TWAI_MSG_FLAG_SELF 0x08 /**< Transmit as a Self Reception Request. Unused for received. */ #define TWAI_MSG_FLAG_DLC_NON_COMP 0x10 /**< Message's Data length code is larger than 8. This will break compliance with TWAI */ -#define TWAI_BRP_MAX SOC_TWAI_BRP_MAX /**< Maximum configurable BRP value */ -#define TWAI_BRP_MIN SOC_TWAI_BRP_MIN /**< Minimum configurable BRP value */ - /** * @brief Initializer macros for timing configuration structure * @@ -50,32 +47,32 @@ extern "C" { * * @note The available bit rates are dependent on the chip target and ECO version. */ -#if SOC_TWAI_BRP_MAX > 256 #define TWAI_TIMING_CONFIG_1KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 20000, .brp = 0, .prop_seg = 0, .tseg_1 = 15, .tseg_2 = 4, .sjw = 3, .ssp_offset = 0, .triple_sampling = false} #define TWAI_TIMING_CONFIG_5KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 100000, .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 -#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_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} + +#if SOC_IS(ESP32) || SOC_IS(ESP32S2) || SOC_IS(ESP32C3) || SOC_IS(ESP32S3) +// default clock source is APB=80MHz +#define TWAI_TIMING_CONFIG_25KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 625000, .brp = 0, .prop_seg = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .ssp_offset = 0, .triple_sampling = false} +#else +#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} #endif -#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} -#else // APB80M -#define TWAI_TIMING_CONFIG_25KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 625000, .brp = 0, .prop_seg = 0, .tseg_1 = 16, .tseg_2 = 8, .sjw = 3, .ssp_offset = 0, .triple_sampling = false} -#endif #define TWAI_TIMING_CONFIG_50KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 1000000, .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_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 && HAL_CONFIG(XTAL_HINT_FREQ_MHZ) == 40 // TWAI_CLK_SRC_XTAL = 40M + +#if SOC_IS(ESP32C6) || SOC_IS(ESP32P4) +// default clock source is XTAL=40MHz #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_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} -#else // 32M, 48M, APB80M +#else #define TWAI_TIMING_CONFIG_500KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 8000000, .brp = 0, .prop_seg = 0, .tseg_1 = 11, .tseg_2 = 4, .sjw = 2, .ssp_offset = 0, .triple_sampling = false} #define TWAI_TIMING_CONFIG_800KBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 8000000, .brp = 0, .prop_seg = 0, .tseg_1 = 6, .tseg_2 = 3, .sjw = 1, .ssp_offset = 0, .triple_sampling = false} #define TWAI_TIMING_CONFIG_1MBITS() {.clk_src = TWAI_CLK_SRC_DEFAULT, .quanta_resolution_hz = 8000000, .brp = 0, .prop_seg = 0, .tseg_1 = 5, .tseg_2 = 2, .sjw = 1, .ssp_offset = 0, .triple_sampling = false} diff --git a/components/hal/twai_hal_v1.c b/components/esp_hal_twai/twai_hal_v1.c similarity index 97% rename from components/hal/twai_hal_v1.c rename to components/esp_hal_twai/twai_hal_v1.c index a3590816eb..952ae75af2 100644 --- a/components/hal/twai_hal_v1.c +++ b/components/esp_hal_twai/twai_hal_v1.c @@ -25,7 +25,8 @@ typedef struct twai_hal_errata_ctx_t { } twai_hal_errata_ctx_t; #endif -size_t twai_hal_get_mem_requirment(void) { +size_t twai_hal_get_mem_requirment(void) +{ #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); #else @@ -52,7 +53,7 @@ bool twai_hal_init(twai_hal_context_t *hal_ctx, const twai_hal_config_t *config) #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 #endif -#if SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT +#if TWAI_LL_SUPPORT(MULTI_ADDRESS_LAYOUT) twai_ll_enable_extended_reg_layout(hal_ctx->dev); //Changes the address layout of the registers #endif twai_ll_set_mode(hal_ctx->dev, true, false, false); //Freeze REC by changing to LOM mode @@ -108,7 +109,7 @@ void twai_hal_configure_timing(twai_hal_context_t *hal_ctx, const twai_timing_ad twai_ll_set_clkout(hal_ctx->dev, brp); } -void twai_hal_configure_filter(twai_hal_context_t *hal_ctx, uint8_t filter_id, const twai_mask_filter_config_t *f_config) +void twai_hal_configure_mask_filter(twai_hal_context_t *hal_ctx, uint8_t filter_id, const twai_mask_filter_config_t *f_config) { uint32_t id = f_config->num_of_ids ? f_config->id_list[0] : f_config->id; bool full_open = (f_config->mask == 0) && (id == 0); @@ -292,8 +293,8 @@ uint32_t twai_hal_get_events(twai_hal_context_t *hal_ctx) #if TWAI_LL_HAS_RX_FRAME_ISSUE //Check for errata condition (RX message has bus error at particular segments) 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_ACK_DELIM && type == TWAI_LL_ERR_OTHER))) { + ((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))) { TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_NEED_PERIPH_RESET); HAL_LOGD("TWAI_HAL", "RX frame invalid detected"); } @@ -401,7 +402,7 @@ void twai_hal_set_tx_buffer_and_transmit(twai_hal_context_t *hal_ctx, twai_hal_f } else { twai_ll_set_cmd_self_rx_request(hal_ctx->dev); } - } else if (tx_frame->single_shot){ + } else if (tx_frame->single_shot) { twai_ll_set_cmd_tx_single_shot(hal_ctx->dev); } else { twai_ll_set_cmd_tx(hal_ctx->dev); @@ -425,7 +426,7 @@ uint32_t twai_hal_get_rx_msg_count(twai_hal_context_t *hal_ctx) bool twai_hal_read_rx_fifo(twai_hal_context_t *hal_ctx, twai_hal_frame_t *rx_frame) { -#ifdef SOC_TWAI_SUPPORTS_RX_STATUS +#if TWAI_LL_SUPPORT(RX_STATUS) if (twai_ll_get_status(hal_ctx->dev) & TWAI_LL_STATUS_MS) { //Release the buffer for this particular overrun frame twai_ll_set_cmd_release_rx_buffer(hal_ctx->dev); diff --git a/components/hal/twai_hal_v2.c b/components/esp_hal_twai/twai_hal_v2.c similarity index 83% rename from components/hal/twai_hal_v2.c rename to components/esp_hal_twai/twai_hal_v2.c index b6f86a643c..b477fcd732 100644 --- a/components/hal/twai_hal_v2.c +++ b/components/esp_hal_twai/twai_hal_v2.c @@ -8,7 +8,8 @@ #include "hal/twai_hal.h" #include "hal/twaifd_ll.h" -size_t twai_hal_get_mem_requirment(void) { +size_t twai_hal_get_mem_requirment(void) +{ return sizeof(twai_hal_context_t); } @@ -24,10 +25,12 @@ bool twai_hal_init(twai_hal_context_t *hal_ctx, const twai_hal_config_t *config) twaifd_ll_enable_hw(hal_ctx->dev, false); //mode should be changed under disabled twaifd_ll_set_mode(hal_ctx->dev, config->enable_listen_only, config->enable_self_test, config->enable_loopback); twaifd_ll_set_tx_retrans_limit(hal_ctx->dev, config->retry_cnt); - twaifd_ll_filter_block_rtr(hal_ctx->dev, config->no_receive_rtr); + twaifd_ll_filter_drop_rtr(hal_ctx->dev, config->no_receive_rtr); twaifd_ll_enable_filter_mode(hal_ctx->dev, true); // each filter still has independent enable control twaifd_ll_enable_fd_mode(hal_ctx->dev, true); // fd frame still controlled by `header.fdf` - twaifd_ll_enable_rxfifo_auto_incrase(hal_ctx->dev, true); + twaifd_ll_enable_bus_off_tx_fail_mode(hal_ctx->dev, true); // all buffers go to "TX failed" state upon bus-off + twaifd_ll_enable_rxfifo_auto_increase(hal_ctx->dev, true); + twaifd_ll_ts_set_sample_point(hal_ctx->dev, TWAIFD_LL_TS_POINT_EOF); twaifd_ll_enable_intr(hal_ctx->dev, config->intr_mask); return true; } @@ -63,7 +66,7 @@ void twai_hal_configure_timing_fd(twai_hal_context_t *hal_ctx, const twai_timing } } -void twai_hal_configure_filter(twai_hal_context_t *hal_ctx, uint8_t filter_id, const twai_mask_filter_config_t *f_config) +void twai_hal_configure_mask_filter(twai_hal_context_t *hal_ctx, uint8_t filter_id, const twai_mask_filter_config_t *f_config) { uint32_t id = f_config->num_of_ids ? f_config->id_list[0] : f_config->id; bool full_open = (f_config->mask == 0) && (id == 0); @@ -72,11 +75,11 @@ void twai_hal_configure_filter(twai_hal_context_t *hal_ctx, uint8_t filter_id, c bool fd_ext = full_open || (!full_close && f_config->is_ext && !f_config->no_fd); bool cc_std = full_open || (!full_close && !f_config->is_ext && !f_config->no_classic); bool fd_std = full_open || (!full_close && !f_config->is_ext && !f_config->no_fd); - twaifd_ll_filter_enable_basic_ext(hal_ctx->dev, filter_id, false, cc_ext); - twaifd_ll_filter_enable_fd_ext(hal_ctx->dev, filter_id, false, fd_ext); - twaifd_ll_filter_enable_basic_std(hal_ctx->dev, filter_id, false, cc_std); - twaifd_ll_filter_enable_fd_std(hal_ctx->dev, filter_id, false, fd_std); - twaifd_ll_filter_set_id_mask(hal_ctx->dev, filter_id, f_config->is_ext, id, f_config->mask); + twaifd_ll_mask_filter_accept_classic_std(hal_ctx->dev, filter_id, cc_std); + twaifd_ll_mask_filter_accept_classic_ext(hal_ctx->dev, filter_id, cc_ext); + twaifd_ll_mask_filter_accept_fd_std(hal_ctx->dev, filter_id, fd_std); + twaifd_ll_mask_filter_accept_fd_ext(hal_ctx->dev, filter_id, fd_ext); + twaifd_ll_mask_filter_set_id_mask(hal_ctx->dev, filter_id, f_config->is_ext, id, f_config->mask); } void twai_hal_configure_range_filter(twai_hal_context_t *hal_ctx, uint8_t filter_id, const twai_range_filter_config_t *f_config) @@ -85,11 +88,11 @@ void twai_hal_configure_range_filter(twai_hal_context_t *hal_ctx, uint8_t filter bool fd_ext = f_config->is_ext && !f_config->no_fd; bool cc_std = !f_config->is_ext && !f_config->no_classic; bool fd_std = !f_config->is_ext && !f_config->no_fd; - twaifd_ll_filter_enable_basic_ext(hal_ctx->dev, filter_id, true, cc_ext); - twaifd_ll_filter_enable_fd_ext(hal_ctx->dev, filter_id, true, fd_ext); - twaifd_ll_filter_enable_basic_std(hal_ctx->dev, filter_id, true, cc_std); - twaifd_ll_filter_enable_fd_std(hal_ctx->dev, filter_id, true, fd_std); - twaifd_ll_filter_set_range(hal_ctx->dev, 0, f_config->is_ext, f_config->range_high, f_config->range_low); + twaifd_ll_range_filter_accept_classic_std(hal_ctx->dev, filter_id, cc_std); + twaifd_ll_range_filter_accept_classic_ext(hal_ctx->dev, filter_id, cc_ext); + twaifd_ll_range_filter_accept_fd_std(hal_ctx->dev, filter_id, fd_std); + twaifd_ll_range_filter_accept_fd_ext(hal_ctx->dev, filter_id, fd_ext); + twaifd_ll_range_filter_set_id_thres(hal_ctx->dev, 0, f_config->is_ext, f_config->range_high, f_config->range_low); } void twai_hal_start(twai_hal_context_t *hal_ctx) @@ -152,7 +155,7 @@ void twai_hal_parse_frame(const twai_hal_frame_t *frame, twai_frame_header_t *he void twai_hal_set_tx_buffer_and_transmit(twai_hal_context_t *hal_ctx, twai_hal_frame_t *tx_frame, uint8_t buffer_idx) { twaifd_ll_mount_tx_buffer(hal_ctx->dev, tx_frame, buffer_idx); - twaifd_ll_set_tx_cmd(hal_ctx->dev, buffer_idx, TWAIFD_LL_TX_CMD_READY); + twaifd_ll_set_tx_buffer_cmd(hal_ctx->dev, buffer_idx, TWAIFD_LL_TX_CMD_READY); } uint32_t twai_hal_get_rx_msg_count(twai_hal_context_t *hal_ctx) @@ -176,7 +179,7 @@ uint32_t twai_hal_get_events(twai_hal_context_t *hal_ctx) if (int_stat & (TWAIFD_LL_INTR_TX_DONE)) { hal_events |= TWAI_HAL_EVENT_TX_BUFF_FREE; - if (int_stat & TWAIFD_LL_INTR_TX_SUCCESS) { + if (int_stat & TWAIFD_LL_INTR_TX_FRAME) { hal_events |= TWAI_HAL_EVENT_TX_SUCCESS; } } @@ -187,7 +190,7 @@ uint32_t twai_hal_get_events(twai_hal_context_t *hal_ctx) hal_ctx->errors = twaifd_ll_get_err_reason(hal_ctx->dev); hal_events |= TWAI_HAL_EVENT_BUS_ERR; } - if (int_stat & TWAIFD_LL_INTR_ARBI_LOST) { + if (int_stat & TWAIFD_LL_INTR_ARBIT_LOST) { hal_events |= TWAI_HAL_EVENT_ARB_LOST; } if (int_stat & (TWAIFD_LL_INTR_FSM_CHANGE | TWAIFD_LL_INTR_ERR_WARN)) { diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index cda10334a1..5ffa44d759 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -93,6 +93,7 @@ else() esp_hal_rmt esp_hal_parlio esp_hal_cam + esp_hal_twai LDFRAGMENTS "linker.lf" "app.lf") add_subdirectory(port) diff --git a/components/esp_system/port/soc/esp32c5/clk.c b/components/esp_system/port/soc/esp32c5/clk.c index 458b44cd69..cffc44fd66 100644 --- a/components/esp_system/port/soc/esp32c5/clk.c +++ b/components/esp_system/port/soc/esp32c5/clk.c @@ -55,7 +55,7 @@ #include "hal/spi_ll.h" #include "hal/temperature_sensor_ll.h" #include "hal/timer_ll.h" -#include "hal/twaifd_ll.h" +#include "hal/twai_ll.h" #include "hal/uart_ll.h" #include "hal/uhci_ll.h" #include "hal/usb_serial_jtag_ll.h" @@ -290,10 +290,10 @@ __attribute__((weak)) void esp_perip_clk_init(void) timer_ll_enable_clock(1, 0, false); _timg_ll_enable_bus_clock(0, false); _timg_ll_enable_bus_clock(1, false); - twaifd_ll_enable_clock(0, false); - twaifd_ll_enable_bus_clock(0, false); - twaifd_ll_enable_clock(1, false); - twaifd_ll_enable_bus_clock(1, false); + twai_ll_enable_clock(0, false); + twai_ll_enable_bus_clock(0, false); + twai_ll_enable_clock(1, false); + twai_ll_enable_bus_clock(1, false); i2s_ll_enable_bus_clock(0, false); i2s_ll_tx_disable_clock(&I2S0); i2s_ll_rx_disable_clock(&I2S0); diff --git a/components/hal/CMakeLists.txt b/components/hal/CMakeLists.txt index 4f74be5e7e..f12b0ea905 100644 --- a/components/hal/CMakeLists.txt +++ b/components/hal/CMakeLists.txt @@ -105,14 +105,6 @@ elseif(NOT BOOTLOADER_BUILD) list(APPEND srcs "uhci_hal.c") endif() - if(CONFIG_SOC_TWAI_SUPPORTED) - if(CONFIG_SOC_TWAI_SUPPORT_FD) - list(APPEND srcs "twai_hal_v2.c") - else() - list(APPEND srcs "twai_hal_v1.c") - endif() - endif() - if(CONFIG_SOC_SDMMC_HOST_SUPPORTED) list(APPEND srcs "sdmmc_hal.c") endif() diff --git a/components/soc/CMakeLists.txt b/components/soc/CMakeLists.txt index c973922fe9..6a8087fad0 100644 --- a/components/soc/CMakeLists.txt +++ b/components/soc/CMakeLists.txt @@ -109,10 +109,6 @@ if(CONFIG_SOC_TOUCH_SENSOR_SUPPORTED) list(APPEND srcs "${target_folder}/touch_sensor_periph.c") endif() -if(CONFIG_SOC_TWAI_SUPPORTED) - list(APPEND srcs "${target_folder}/twai_periph.c") -endif() - if(CONFIG_SOC_IEEE802154_SUPPORTED) list(APPEND srcs "${target_folder}/ieee802154_periph.c") endif() diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index 848dc27845..5788d9ace3 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -583,18 +583,6 @@ config SOC_TWAI_MASK_FILTER_NUM int default 1 -config SOC_TWAI_BRP_MIN - int - default 2 - -config SOC_TWAI_CLK_SUPPORT_APB - bool - default y - -config SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT - bool - default y - config SOC_UART_NUM int default 3 diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 152e41fb15..20255f145b 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -289,14 +289,6 @@ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1U #define SOC_TWAI_MASK_FILTER_NUM 1U -#define SOC_TWAI_BRP_MIN 2 -#if SOC_CAPS_ECO_VER >= 200 -# define SOC_TWAI_BRP_MAX 256 -#else -# define SOC_TWAI_BRP_MAX 128 -#endif -#define SOC_TWAI_CLK_SUPPORT_APB 1 -#define SOC_TWAI_SUPPORT_MULTI_ADDRESS_LAYOUT 1 /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32 have 3 UART. diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 6879a0145e..64b3cceef0 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -787,22 +787,6 @@ config SOC_TWAI_MASK_FILTER_NUM int default 1 -config SOC_TWAI_CLK_SUPPORT_APB - bool - default y - -config SOC_TWAI_BRP_MIN - int - default 2 - -config SOC_TWAI_BRP_MAX - int - default 16384 - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - config SOC_EFUSE_DIS_DOWNLOAD_ICACHE bool default y diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 379c8193aa..ace847a87d 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -349,10 +349,6 @@ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1U #define SOC_TWAI_MASK_FILTER_NUM 1U -#define SOC_TWAI_CLK_SUPPORT_APB 1 -#define SOC_TWAI_BRP_MIN 2 -#define SOC_TWAI_BRP_MAX 16384 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 /*-------------------------- eFuse CAPS----------------------------*/ #define SOC_EFUSE_DIS_DOWNLOAD_ICACHE 1 diff --git a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in index ca151f8d36..9d97fdd315 100644 --- a/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c5/include/soc/Kconfig.soc_caps.in @@ -47,6 +47,10 @@ config SOC_TWAI_SUPPORTED bool default y +config SOC_TWAI_FD_SUPPORTED + bool + default y + config SOC_ETM_SUPPORTED bool default y @@ -1167,30 +1171,6 @@ config SOC_TWAI_RANGE_FILTER_NUM int default 1 -config SOC_TWAI_BRP_MIN - int - default 1 - -config SOC_TWAI_BRP_MAX - int - default 255 - -config SOC_TWAI_CLK_SUPPORT_XTAL - bool - default y - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - -config SOC_TWAI_SUPPORT_FD - bool - default y - -config SOC_TWAI_SUPPORT_TIMESTAMP - bool - default y - config SOC_EFUSE_DIS_PAD_JTAG bool default y diff --git a/components/soc/esp32c5/include/soc/soc_caps.h b/components/soc/esp32c5/include/soc/soc_caps.h index f34d172e02..6ca3b28398 100644 --- a/components/soc/esp32c5/include/soc/soc_caps.h +++ b/components/soc/esp32c5/include/soc/soc_caps.h @@ -34,6 +34,7 @@ #define SOC_PCNT_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 #define SOC_TWAI_SUPPORTED 1 +#define SOC_TWAI_FD_SUPPORTED 1 #define SOC_ETM_SUPPORTED 1 #define SOC_PARLIO_SUPPORTED 1 #define SOC_PARLIO_LCD_SUPPORTED 1 @@ -477,12 +478,6 @@ #define SOC_TWAI_CONTROLLER_NUM 2 #define SOC_TWAI_MASK_FILTER_NUM 3 #define SOC_TWAI_RANGE_FILTER_NUM 1U -#define SOC_TWAI_BRP_MIN 1U -#define SOC_TWAI_BRP_MAX 255 -#define SOC_TWAI_CLK_SUPPORT_XTAL 1 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 -#define SOC_TWAI_SUPPORT_FD 1 -#define SOC_TWAI_SUPPORT_TIMESTAMP 1 /*-------------------------- eFuse CAPS----------------------------*/ #define SOC_EFUSE_DIS_PAD_JTAG 1 diff --git a/components/soc/esp32c5/register/soc/twaifd_struct.h b/components/soc/esp32c5/register/soc/twaifd_struct.h index 3a4c22ca5d..3ce67d9cbb 100644 --- a/components/soc/esp32c5/register/soc/twaifd_struct.h +++ b/components/soc/esp32c5/register/soc/twaifd_struct.h @@ -1754,7 +1754,7 @@ typedef union twaifd_frame_buffer_t { struct { uint32_t dlc: 4; // Data length code (0-15) uint32_t reserved4: 1; // Reserved bit - uint32_t rtr: 1; // Remote transmission request + 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 @@ -1824,7 +1824,7 @@ typedef struct twaifd_dev_t { volatile twaifd_timestamp_low_reg_t timestamp_low; volatile twaifd_timestamp_high_reg_t timestamp_high; uint32_t reserved_09c[25]; - volatile twaifd_frame_mem_t txt_mem_cell[8]; + 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; diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 2e6785ae6f..eec5990618 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -1015,22 +1015,6 @@ config SOC_TWAI_MASK_FILTER_NUM int default 1 -config SOC_TWAI_CLK_SUPPORT_XTAL - bool - default y - -config SOC_TWAI_BRP_MIN - int - default 2 - -config SOC_TWAI_BRP_MAX - int - default 32768 - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - config SOC_TWAI_SUPPORT_SLEEP_RETENTION bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 34facb5946..a0f2618f88 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -425,10 +425,6 @@ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 2 #define SOC_TWAI_MASK_FILTER_NUM 1U -#define SOC_TWAI_CLK_SUPPORT_XTAL 1 -#define SOC_TWAI_BRP_MIN 2 -#define SOC_TWAI_BRP_MAX 32768 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 #define SOC_TWAI_SUPPORT_SLEEP_RETENTION 1 /*-------------------------- eFuse CAPS----------------------------*/ diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 751b58d43f..f23539f765 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -1019,22 +1019,6 @@ config SOC_TWAI_MASK_FILTER_NUM int default 1 -config SOC_TWAI_CLK_SUPPORT_XTAL - bool - default y - -config SOC_TWAI_BRP_MIN - int - default 2 - -config SOC_TWAI_BRP_MAX - int - default 32768 - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - config SOC_TWAI_SUPPORT_SLEEP_RETENTION bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 19baea9aa7..9fc735a6d8 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -438,10 +438,6 @@ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1U #define SOC_TWAI_MASK_FILTER_NUM 1U -#define SOC_TWAI_CLK_SUPPORT_XTAL 1 -#define SOC_TWAI_BRP_MIN 2 -#define SOC_TWAI_BRP_MAX 32768 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 #define SOC_TWAI_SUPPORT_SLEEP_RETENTION 1 /*-------------------------- eFuse CAPS----------------------------*/ diff --git a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in index 2b24aaca17..b0703d1b5d 100644 --- a/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h21/include/soc/Kconfig.soc_caps.in @@ -823,22 +823,6 @@ config SOC_TWAI_MASK_FILTER_NUM int default 1 -config SOC_TWAI_CLK_SUPPORT_XTAL - bool - default y - -config SOC_TWAI_BRP_MIN - int - default 2 - -config SOC_TWAI_BRP_MAX - int - default 32768 - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - config SOC_TWAI_SUPPORT_SLEEP_RETENTION bool default y diff --git a/components/soc/esp32h21/include/soc/soc_caps.h b/components/soc/esp32h21/include/soc/soc_caps.h index d672b6d0a4..894385d132 100644 --- a/components/soc/esp32h21/include/soc/soc_caps.h +++ b/components/soc/esp32h21/include/soc/soc_caps.h @@ -412,10 +412,6 @@ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1U #define SOC_TWAI_MASK_FILTER_NUM 1U -#define SOC_TWAI_CLK_SUPPORT_XTAL 1 -#define SOC_TWAI_BRP_MIN 2 -#define SOC_TWAI_BRP_MAX 32768 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 #define SOC_TWAI_SUPPORT_SLEEP_RETENTION 1 /*-------------------------- eFuse CAPS----------------------------*/ diff --git a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in index bfb0ddf52c..4a8a94fe98 100644 --- a/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h4/include/soc/Kconfig.soc_caps.in @@ -35,6 +35,10 @@ config SOC_TWAI_SUPPORTED bool default y +config SOC_TWAI_FD_SUPPORTED + bool + default y + config SOC_ETM_SUPPORTED bool default y @@ -763,30 +767,6 @@ config SOC_TWAI_RANGE_FILTER_NUM int default 1 -config SOC_TWAI_BRP_MIN - int - default 1 - -config SOC_TWAI_BRP_MAX - int - default 255 - -config SOC_TWAI_CLK_SUPPORT_XTAL - bool - default y - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - -config SOC_TWAI_SUPPORT_FD - bool - default y - -config SOC_TWAI_SUPPORT_TIMESTAMP - bool - default y - config SOC_EFUSE_DIS_DOWNLOAD_ICACHE bool default n diff --git a/components/soc/esp32h4/include/soc/soc_caps.h b/components/soc/esp32h4/include/soc/soc_caps.h index 6def11c9e7..609cbfe4fa 100644 --- a/components/soc/esp32h4/include/soc/soc_caps.h +++ b/components/soc/esp32h4/include/soc/soc_caps.h @@ -41,6 +41,7 @@ #define SOC_PCNT_SUPPORTED 1 #define SOC_MCPWM_SUPPORTED 1 #define SOC_TWAI_SUPPORTED 1 +#define SOC_TWAI_FD_SUPPORTED 1 #define SOC_ETM_SUPPORTED 1 // #define SOC_PARLIO_SUPPORTED 1 // TODO: [ESP32H4] IDF-12345 IDF-12347 // #define SOC_BT_SUPPORTED 1 @@ -417,12 +418,6 @@ #define SOC_TWAI_CONTROLLER_NUM 1U #define SOC_TWAI_MASK_FILTER_NUM 3 #define SOC_TWAI_RANGE_FILTER_NUM 1U -#define SOC_TWAI_BRP_MIN 1U -#define SOC_TWAI_BRP_MAX 255 -#define SOC_TWAI_CLK_SUPPORT_XTAL 1 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 -#define SOC_TWAI_SUPPORT_FD 1 -#define SOC_TWAI_SUPPORT_TIMESTAMP 1 /*-------------------------- eFuse CAPS----------------------------*/ #define SOC_EFUSE_DIS_DOWNLOAD_ICACHE 0 diff --git a/components/soc/esp32h4/register/soc/twaifd_struct.h b/components/soc/esp32h4/register/soc/twaifd_struct.h index 0d5ff67a19..21e5ebaa1b 100644 --- a/components/soc/esp32h4/register/soc/twaifd_struct.h +++ b/components/soc/esp32h4/register/soc/twaifd_struct.h @@ -1761,7 +1761,7 @@ typedef union twaifd_frame_buffer_t { struct { uint32_t dlc: 4; // Data length code (0-15) uint32_t reserved4: 1; // Reserved bit - uint32_t rtr: 1; // Remote transmission request + 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 diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 028eb12553..41d60fdbfa 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -1587,22 +1587,6 @@ config SOC_TWAI_MASK_FILTER_NUM int default 1 -config SOC_TWAI_CLK_SUPPORT_XTAL - bool - default y - -config SOC_TWAI_BRP_MIN - int - default 2 - -config SOC_TWAI_BRP_MAX - int - default 32768 - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - config SOC_TWAI_SUPPORT_SLEEP_RETENTION bool default y diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 136b8ace6b..ad1736fb85 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -609,10 +609,6 @@ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 3 #define SOC_TWAI_MASK_FILTER_NUM 1U -#define SOC_TWAI_CLK_SUPPORT_XTAL 1 -#define SOC_TWAI_BRP_MIN 2 -#define SOC_TWAI_BRP_MAX 32768 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 #define SOC_TWAI_SUPPORT_SLEEP_RETENTION 1 /*-------------------------- eFuse CAPS----------------------------*/ diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 088f8f0fb0..38b6b20061 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -707,22 +707,6 @@ config SOC_TWAI_MASK_FILTER_NUM int default 1 -config SOC_TWAI_CLK_SUPPORT_APB - bool - default y - -config SOC_TWAI_BRP_MIN - int - default 2 - -config SOC_TWAI_BRP_MAX - int - default 32768 - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - config SOC_UART_NUM int default 2 diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index 4b94f01243..7d16b3d355 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -314,10 +314,6 @@ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1U #define SOC_TWAI_MASK_FILTER_NUM 1U -#define SOC_TWAI_CLK_SUPPORT_APB 1 -#define SOC_TWAI_BRP_MIN 2 -#define SOC_TWAI_BRP_MAX 32768 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-S2 has 2 UART. diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index 5a062d5c0e..f36b2a4208 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -847,22 +847,6 @@ config SOC_TWAI_MASK_FILTER_NUM int default 1 -config SOC_TWAI_CLK_SUPPORT_APB - bool - default y - -config SOC_TWAI_BRP_MIN - int - default 2 - -config SOC_TWAI_BRP_MAX - int - default 16384 - -config SOC_TWAI_SUPPORTS_RX_STATUS - bool - default y - config SOC_UART_NUM int default 3 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 088b27a256..2bc2d58e1a 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -349,10 +349,6 @@ /*-------------------------- TWAI CAPS ---------------------------------------*/ #define SOC_TWAI_CONTROLLER_NUM 1U #define SOC_TWAI_MASK_FILTER_NUM 1U -#define SOC_TWAI_CLK_SUPPORT_APB 1 -#define SOC_TWAI_BRP_MIN 2 -#define SOC_TWAI_BRP_MAX 16384 -#define SOC_TWAI_SUPPORTS_RX_STATUS 1 /*-------------------------- UART CAPS ---------------------------------------*/ // ESP32-S3 has 3 UARTs diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile index 2d7a436f0d..f9040d7da8 100644 --- a/docs/doxygen/Doxyfile +++ b/docs/doxygen/Doxyfile @@ -176,6 +176,7 @@ INPUT = \ $(PROJECT_PATH)/components/esp_hal_mspi/include/hal/spi_flash_types.h \ $(PROJECT_PATH)/components/esp_hal_pcnt/include/hal/pcnt_types.h \ $(PROJECT_PATH)/components/esp_hal_rmt/include/hal/rmt_types.h \ + $(PROJECT_PATH)/components/esp_hal_twai/include/hal/twai_types.h \ $(PROJECT_PATH)/components/esp_http_client/include/esp_http_client.h \ $(PROJECT_PATH)/components/esp_http_server/include/esp_http_server.h \ $(PROJECT_PATH)/components/esp_https_ota/include/esp_https_ota.h \ @@ -268,7 +269,6 @@ INPUT = \ $(PROJECT_PATH)/components/hal/include/hal/sdio_slave_types.h \ $(PROJECT_PATH)/components/hal/include/hal/spi_types.h \ $(PROJECT_PATH)/components/hal/include/hal/temperature_sensor_types.h \ - $(PROJECT_PATH)/components/hal/include/hal/twai_types.h \ $(PROJECT_PATH)/components/hal/include/hal/uart_types.h \ $(PROJECT_PATH)/components/hal/include/hal/efuse_hal.h \ $(PROJECT_PATH)/components/hal/include/hal/eth_types.h \ diff --git a/docs/en/api-reference/peripherals/twai.rst b/docs/en/api-reference/peripherals/twai.rst index c38374b4e2..ec2666923b 100644 --- a/docs/en/api-reference/peripherals/twai.rst +++ b/docs/en/api-reference/peripherals/twai.rst @@ -15,11 +15,11 @@ Overview TWAI is a highly reliable, multi-master, real-time, serial asynchronous communication protocol designed for automotive and industrial applications. It is compatible with the frame structure defined in the ISO 11898-1 standard and supports both standard frames with 11-bit identifiers and extended frames with 29-bit identifiers. The protocol supports message prioritization with lossless arbitration, automatic retransmission, and fault confinement mechanisms. The {IDF_TARGET_NAME} includes {IDF_TARGET_CONFIG_SOC_TWAI_CONTROLLER_NUM} TWAI controllers, allowing for the creation of {IDF_TARGET_CONFIG_SOC_TWAI_CONTROLLER_NUM} driver instances. -.. only:: SOC_TWAI_SUPPORT_FD +.. only:: SOC_TWAI_FD_SUPPORTED The TWAI controllers on the {IDF_TARGET_NAME} also compatible with FD format (a.k.a. CAN FD) frames defined in ISO 11898-1, and can transmit and receive both classic and FD format frames. -.. only:: not SOC_TWAI_SUPPORT_FD +.. only:: not SOC_TWAI_FD_SUPPORTED The TWAI controllers on the {IDF_TARGET_NAME} are **not compatible with FD format frames and will interpret such frames as errors.** @@ -277,7 +277,7 @@ The following code demonstrates how to calculate the MASK and configure a filter }; ESP_ERROR_CHECK(twai_node_config_mask_filter(node_hdl, 0, &mfilter_cfg)); // Configure on filter 0 -.. only:: not SOC_TWAI_SUPPORT_FD +.. only:: not SOC_TWAI_FD_SUPPORTED Dual Filter Mode ^^^^^^^^^^^^^^^^ @@ -291,7 +291,7 @@ The following code demonstrates how to calculate the MASK and configure a filter twai_mask_filter_config_t dual_config = twai_make_dual_filter(0x020, 0x7f0, 0x013, 0x7f8, false); // id1, mask1, id2, mask2, no extend ID ESP_ERROR_CHECK(twai_node_config_mask_filter(node_hdl, 0, &dual_config)); -.. only:: SOC_TWAI_SUPPORT_FD +.. only:: SOC_TWAI_FD_SUPPORTED Range Filter ^^^^^^^^^^^^ diff --git a/docs/zh_CN/api-reference/peripherals/twai.rst b/docs/zh_CN/api-reference/peripherals/twai.rst index ca56c29193..13c17a3298 100644 --- a/docs/zh_CN/api-reference/peripherals/twai.rst +++ b/docs/zh_CN/api-reference/peripherals/twai.rst @@ -15,11 +15,11 @@ TWAI 是一种适用于汽车和工业应用的高可靠性的多主机实时串行异步通信协议。它兼容 ISO11898-1 标准定义的帧结构,可以支持 11 位 ID 的标准帧和 29 位 ID 的扩展帧。支持报文优先级和无损仲裁,支持自动重传和故障自动隔离机制。{IDF_TARGET_NAME} 包含 {IDF_TARGET_CONFIG_SOC_TWAI_CONTROLLER_NUM} 个 TWAI 控制器,可以创建 {IDF_TARGET_CONFIG_SOC_TWAI_CONTROLLER_NUM} 个驱动实例。 -.. only:: SOC_TWAI_SUPPORT_FD +.. only:: SOC_TWAI_FD_SUPPORTED {IDF_TARGET_NAME} TWAI 控制器兼容 ISO11898-1 FD (a.k.a. CAN FD) 格式帧,可以发送和接收经典格式和 FD 格式帧。 -.. only:: not SOC_TWAI_SUPPORT_FD +.. only:: not SOC_TWAI_FD_SUPPORTED {IDF_TARGET_NAME} TWAI 控制器 **不兼容 ISO11898-1 FD 格式帧,并会将这些帧解析为错误。** @@ -277,7 +277,7 @@ TWAI 控制器硬件可以根据 ID 对报文进行过滤,从而减少软硬 }; ESP_ERROR_CHECK(twai_node_config_mask_filter(node_hdl, 0, &mfilter_cfg)); //配置过滤器0 -.. only:: not SOC_TWAI_SUPPORT_FD +.. only:: not SOC_TWAI_FD_SUPPORTED 双过滤器模式 ^^^^^^^^^^^^ @@ -291,7 +291,7 @@ TWAI 控制器硬件可以根据 ID 对报文进行过滤,从而减少软硬 twai_mask_filter_config_t dual_config = twai_make_dual_filter(0x020, 0x7f0, 0x013, 0x7f8, false); // id1, mask1, id2, mask2, 不接收扩展ID ESP_ERROR_CHECK(twai_node_config_mask_filter(node_hdl, 0, &dual_config)); -.. only:: SOC_TWAI_SUPPORT_FD +.. only:: SOC_TWAI_FD_SUPPORTED 范围过滤器 ^^^^^^^^^^ diff --git a/examples/peripherals/twai/twai_utils/main/Kconfig.projbuild b/examples/peripherals/twai/twai_utils/main/Kconfig.projbuild index 06f67ff4b1..ca20ab0b34 100644 --- a/examples/peripherals/twai/twai_utils/main/Kconfig.projbuild +++ b/examples/peripherals/twai/twai_utils/main/Kconfig.projbuild @@ -5,7 +5,7 @@ menu "TWAI Configuration" config EXAMPLE_ENABLE_TWAI_FD bool "Enable TWAI-FD Support" - depends on SOC_TWAI_SUPPORT_FD + depends on SOC_TWAI_FD_SUPPORTED default false help Enable TWAI-FD (Flexible Data-rate) support. diff --git a/examples/peripherals/twai/twai_utils/main/cmd_twai_dump.c b/examples/peripherals/twai/twai_utils/main/cmd_twai_dump.c index ea7dc915fd..6da21a3aca 100644 --- a/examples/peripherals/twai/twai_utils/main/cmd_twai_dump.c +++ b/examples/peripherals/twai/twai_utils/main/cmd_twai_dump.c @@ -388,8 +388,6 @@ static int twai_dump_handler(int argc, char **argv) ret = twai_node_disable(controller->node_handle); ESP_RETURN_ON_ERROR(ret, TAG, "Failed to disable TWAI node%d for filter configuration: %s", controller_id, esp_err_to_name(ret)); - ret = (SOC_TWAI_MASK_FILTER_NUM > 0) ? ESP_OK : ESP_ERR_INVALID_STATE; - ESP_RETURN_ON_ERROR(ret, TAG, "TWAI%d does not support %d mask filters", controller_id, SOC_TWAI_MASK_FILTER_NUM); if (mask_count > 0) { for (int i = 0; i < mask_count; i++) { ret = twai_node_config_mask_filter(controller->node_handle, i, diff --git a/examples/peripherals/twai/twai_utils/pytest_twai_utils.py b/examples/peripherals/twai/twai_utils/pytest_twai_utils.py index e4b9dd48f6..eec9f1d28d 100644 --- a/examples/peripherals/twai/twai_utils/pytest_twai_utils.py +++ b/examples/peripherals/twai/twai_utils/pytest_twai_utils.py @@ -477,7 +477,7 @@ def test_twai_utils_send_various_frames(twai: TwaiTestHelper) -> None: @pytest.mark.generic -@idf_parametrize('target', soc_filtered_targets('SOC_TWAI_SUPPORT_FD == 1'), indirect=['target']) +@idf_parametrize('target', soc_filtered_targets('SOC_TWAI_FD_SUPPORTED == 1'), indirect=['target']) def test_twai_utils_fd_frames(twai: TwaiTestHelper) -> None: with twai.session(): FD_FRAMES = [