From 2ea460df56ed9c8d3694a78c33cccee76411d4c4 Mon Sep 17 00:00:00 2001 From: morris Date: Thu, 8 May 2025 16:59:44 +0800 Subject: [PATCH] test(twai): ensure the bitrate correctness by uart baudrate detector --- .../test_apps/test_twai/main/CMakeLists.txt | 2 +- .../test_apps/test_twai/main/test_app_main.c | 2 +- .../test_twai/main/test_twai_common.c | 53 +++++++++++++++++++ .../hal/esp32c5/include/hal/twaifd_ll.h | 8 +-- .../soc/esp32c5/register/soc/twaifd_struct.h | 9 +--- .../soc/esp32h4/register/soc/twaifd_reg.h | 10 ---- .../soc/esp32p4/include/soc/clk_tree_defs.h | 4 +- 7 files changed, 62 insertions(+), 26 deletions(-) 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 92a85f5d69..28874f143a 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 @@ -10,6 +10,6 @@ endif() idf_component_register( SRCS ${srcs} - PRIV_REQUIRES esp_driver_twai esp_timer + PRIV_REQUIRES esp_driver_twai esp_timer esp_driver_uart WHOLE_ARCHIVE ) diff --git a/components/esp_driver_twai/test_apps/test_twai/main/test_app_main.c b/components/esp_driver_twai/test_apps/test_twai/main/test_app_main.c index 66ba95a25d..ee70625960 100644 --- a/components/esp_driver_twai/test_apps/test_twai/main/test_app_main.c +++ b/components/esp_driver_twai/test_apps/test_twai/main/test_app_main.c @@ -10,7 +10,7 @@ #include "esp_heap_caps.h" // lazy install of mutex and pm_lock occupied memorys -#define LEAKS (250) +#define LEAKS (300) void setUp(void) { diff --git a/components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.c b/components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.c index 36bef3ec61..50c5f5b985 100644 --- a/components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.c +++ b/components/esp_driver_twai/test_apps/test_twai/main/test_twai_common.c @@ -15,6 +15,7 @@ #include "freertos/FreeRTOS.h" #include "esp_twai.h" #include "esp_twai_onchip.h" +#include "driver/uart.h" // for baudrate detection #define TEST_TX_GPIO 4 #define TEST_RX_GPIO 5 @@ -100,6 +101,58 @@ TEST_CASE("twai install uninstall (loopback)", "[TWAI]") } } +static void test_twai_baudrate_correctness(twai_clock_source_t clk_src, uint32_t test_bitrate) +{ + twai_node_handle_t twai_node = NULL; + twai_onchip_node_config_t node_config = { + .clk_src = clk_src, + .io_cfg.tx = TEST_TX_GPIO, + .io_cfg.rx = TEST_TX_GPIO, + .bit_timing.bitrate = test_bitrate, + .tx_queue_depth = 1, + .flags.enable_loopback = true, + .flags.enable_self_test = true, + }; + TEST_ESP_OK(twai_new_node_onchip(&node_config, &twai_node)); + TEST_ESP_OK(twai_node_enable(twai_node)); + + // We use the UART baudrate detection submodule to measure the TWAI baudrate + uart_bitrate_detect_config_t detect_config = { + .rx_io_num = TEST_TX_GPIO, + }; + TEST_ESP_OK(uart_detect_bitrate_start(UART_NUM_1, &detect_config)); + + twai_frame_t tx_frame = { + .buffer = (uint8_t []){0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55}, + .buffer_len = 8, + .header = { + .id = 0x55555, + .ide = true, + .dlc = 8, + } + }; + TEST_ESP_OK(twai_node_transmit(twai_node, &tx_frame, 500)); + vTaskDelay(100); + + // analyze the measurement result + uart_bitrate_res_t measure_result; + TEST_ESP_OK(uart_detect_bitrate_stop(UART_NUM_1, true, &measure_result)); + uint32_t bitrate_measured = measure_result.clk_freq_hz * 4 / (measure_result.pos_period + measure_result.neg_period); + printf("TWAI bitrate measured: %"PRIu32"\r\n", bitrate_measured); + TEST_ASSERT_INT_WITHIN(1000, test_bitrate, bitrate_measured); // 1k tolerance + + TEST_ESP_OK(twai_node_disable(twai_node)); + TEST_ESP_OK(twai_node_delete(twai_node)); +} + +TEST_CASE("twai baudrate measurement", "[TWAI]") +{ + twai_clock_source_t twai_available_clk_srcs[] = SOC_TWAI_CLKS; + for (size_t i = 0; i < sizeof(twai_available_clk_srcs) / sizeof(twai_available_clk_srcs[0]); i++) { + test_twai_baudrate_correctness(twai_available_clk_srcs[i], 200000); + } +} + static IRAM_ATTR bool test_enable_disable_rx_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx) { twai_frame_t *rx_frame = user_ctx; diff --git a/components/hal/esp32c5/include/hal/twaifd_ll.h b/components/hal/esp32c5/include/hal/twaifd_ll.h index 7ef30fab40..9f015cfffb 100644 --- a/components/hal/esp32c5/include/hal/twaifd_ll.h +++ b/components/hal/esp32c5/include/hal/twaifd_ll.h @@ -154,15 +154,17 @@ static inline void twaifd_ll_enable_hw(twaifd_dev_t *hw, bool enable) * @brief Set operating mode of TWAI controller * * @param hw Start address of the TWAI registers - * @param modes Operating mode + * @param listen_only Listen only mode (a.k.a. bus monitoring mode) + * @param self_test Self test mode + * @param loopback Loopback mode */ -static inline void twaifd_ll_set_mode(twaifd_dev_t *hw, bool listen_only, bool no_ack, bool loopback) +static inline void twaifd_ll_set_mode(twaifd_dev_t *hw, bool listen_only, bool self_test, bool loopback) { //mode should be changed under disabled HAL_ASSERT(hw->mode_settings.ena == 0); twaifd_mode_settings_reg_t opmode = {.val = hw->mode_settings.val}; - opmode.stm = no_ack; + opmode.stm = self_test; opmode.bmm = listen_only; opmode.ilbp = loopback; diff --git a/components/soc/esp32c5/register/soc/twaifd_struct.h b/components/soc/esp32c5/register/soc/twaifd_struct.h index ac5561d7c6..9da0a7af19 100644 --- a/components/soc/esp32c5/register/soc/twaifd_struct.h +++ b/components/soc/esp32c5/register/soc/twaifd_struct.h @@ -120,14 +120,7 @@ typedef union { * 0b1 - TXBBM_ENABLED - TXT Buffer Backup mode enabled\\ */ uint32_t txbbm:1; - /** sam : R/W; bitpos: [11]; default: 0; - * Self-acknowledge mode.\\ - * 0b0 - SAM_DISABLE - Do not send dominant ACK bit when CTU CAN FD sends Acknowledge - * bit.\\ - * 0b1 - SAM_ENABLE - Send dominant ACK bit when CTU CAN FD transmits CAN frame.\\ - */ - uint32_t sam:1; - uint32_t reserved_12:4; + uint32_t reserved_11:5; /** rtrle : R/W; bitpos: [16]; default: 0; * Retransmitt Limit Enable. If enabled, CTU CAN FD only attempts to retransmitt each * frame up to RTR_TH diff --git a/components/soc/esp32h4/register/soc/twaifd_reg.h b/components/soc/esp32h4/register/soc/twaifd_reg.h index 084a8c1b60..78771d7ef2 100644 --- a/components/soc/esp32h4/register/soc/twaifd_reg.h +++ b/components/soc/esp32h4/register/soc/twaifd_reg.h @@ -155,16 +155,6 @@ extern "C" { #define TWAIFD_TXBBM_M (TWAIFD_TXBBM_V << TWAIFD_TXBBM_S) #define TWAIFD_TXBBM_V 0x00000001U #define TWAIFD_TXBBM_S 10 -/** TWAIFD_SAM : R/W; bitpos: [11]; default: 0; - * Self-acknowledge mode. - * 0b0 - SAM_DISABLE - Do not send dominant ACK bit when CTU CAN FD sends Acknowledge - * bit. - * 0b1 - SAM_ENABLE - Send dominant ACK bit when CTU CAN FD transmits CAN frame. - */ -#define TWAIFD_SAM (BIT(11)) -#define TWAIFD_SAM_M (TWAIFD_SAM_V << TWAIFD_SAM_S) -#define TWAIFD_SAM_V 0x00000001U -#define TWAIFD_SAM_S 11 /** TWAIFD_RTRLE : R/W; bitpos: [16]; default: 0; * Retransmitt Limit Enable. If enabled, CTU CAN FD only attempts to retransmitt each * frame up to RTR_TH diff --git a/components/soc/esp32p4/include/soc/clk_tree_defs.h b/components/soc/esp32p4/include/soc/clk_tree_defs.h index a16bce43f7..838beb8753 100644 --- a/components/soc/esp32p4/include/soc/clk_tree_defs.h +++ b/components/soc/esp32p4/include/soc/clk_tree_defs.h @@ -597,16 +597,14 @@ typedef enum { /** * @brief Array initializer for all supported clock sources of TWAI */ -#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_RC_FAST} +#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL} /** * @brief TWAI clock source */ typedef enum { TWAI_CLK_SRC_XTAL = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the source clock */ -#if SOC_CLK_TREE_SUPPORTED TWAI_CLK_SRC_RC_FAST = SOC_MOD_CLK_RC_FAST, /*!< Select RC_FAST as the source clock */ -#endif TWAI_CLK_SRC_DEFAULT = SOC_MOD_CLK_XTAL, /*!< Select XTAL as the default clock choice */ } soc_periph_twai_clk_src_t;