test(twai): ensure the bitrate correctness by uart baudrate detector

This commit is contained in:
morris
2025-05-08 16:59:44 +08:00
parent 386a3905b5
commit 2ea460df56
7 changed files with 62 additions and 26 deletions

View File

@ -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
)

View File

@ -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)
{

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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;