Merge branch 'bugfix/twai_driver_cxx_test' into 'master'

fix(twai): fixed build errors in cxx environment

Closes IDFGH-16058

See merge request espressif/esp-idf!40818
This commit is contained in:
Wan Lei
2025-08-14 09:41:23 +08:00
14 changed files with 200 additions and 212 deletions

View File

@@ -55,7 +55,7 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
/**
* @brief Helper function to configure a dual 16-bit acceptance filter.
* @note For 29bits Extended IDs, ONLY high 16bits id/mask is used for eache filter.
* @note For 29bits Extended IDs, ONLY high 16bits id/mask is used for each filter.
*
* @param id1 First ID to filter.
* @param mask1 Mask for first ID.
@@ -86,6 +86,8 @@ static inline twai_mask_filter_config_t twai_make_dual_filter(uint16_t id1, uint
.mask = is_ext ? (((mask1 & TWAI_EXT_ID_MASK) >> 13) << 16) | ((mask2 & TWAI_EXT_ID_MASK) >> 13) : \
((mask1 & TWAI_STD_ID_MASK) << 21) | ((mask2 & TWAI_STD_ID_MASK) << 5),
.is_ext = is_ext,
.no_classic = false,
.no_fd = false,
.dual_filter = true,
};
return dual_cfg;

View File

@@ -1,11 +1,11 @@
set(srcs "test_app_main.c")
if(CONFIG_SOC_TWAI_SUPPORTED)
list(APPEND srcs "test_twai_common.c" "test_twai_network.c")
list(APPEND srcs "test_twai_common.cpp" "test_twai_network.cpp")
endif()
if(CONFIG_SOC_TWAI_SUPPORT_FD)
list(APPEND srcs "test_twai_fd.c")
list(APPEND srcs "test_twai_fd.cpp")
endif()
idf_component_register(

View File

@@ -18,8 +18,8 @@
#include "esp_twai_onchip.h"
#include "driver/uart.h" // for baudrate detection
#define TEST_TX_GPIO 4
#define TEST_RX_GPIO 5
#define TEST_TX_GPIO GPIO_NUM_4
#define TEST_RX_GPIO GPIO_NUM_5
#define TEST_TWAI_QUEUE_DEPTH 5
#define TEST_TRANS_LEN 100
#define TEST_FRAME_LEN 7
@@ -27,7 +27,8 @@
static IRAM_ATTR bool test_driver_install_rx_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
{
twai_frame_t rx_frame = {0};
twai_frame_t rx_frame = {};
if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
ESP_EARLY_LOGI("Recv ", "id 0x%lx rtr %d", rx_frame.header.id, rx_frame.header.rtr);
}
@@ -41,15 +42,13 @@ TEST_CASE("twai install uninstall (loopback)", "[twai]")
{
esp_err_t ret;
twai_node_handle_t node_hdl[SOC_TWAI_CONTROLLER_NUM + 1];
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_TX_GPIO, // Using same pin for test without transceiver
.bit_timing.bitrate = 1000000,
.data_timing.bitrate = 1000000,
.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH,
.flags.enable_loopback = true,
.flags.enable_self_test = true,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
node_config.bit_timing.bitrate = 1000000;
node_config.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH;
node_config.flags.enable_self_test = true;
node_config.flags.enable_loopback = true;
// loop 10 times to check memory leak
for (uint8_t loop = 0; loop < 10; loop ++) {
@@ -60,19 +59,18 @@ TEST_CASE("twai install uninstall (loopback)", "[twai]")
}
// can't disable before enable
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, twai_node_disable(node_hdl[0]));
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_driver_install_rx_cb,
};
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_driver_install_rx_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl[0], &user_cbs, NULL));
printf("Test unregister callback\n");
user_cbs.on_rx_done = NULL;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl[0], &user_cbs, NULL));
twai_frame_t tx_frame = {
.header.id = 0x82,
.header.rtr = true,
};
twai_frame_t tx_frame = {};
tx_frame.header.id = 0x82;
tx_frame.header.rtr = true;
printf("Test transmit before enable\n");
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, twai_node_transmit(node_hdl[0], &tx_frame, 0));
TEST_ESP_OK(twai_node_enable(node_hdl[0]));
@@ -90,7 +88,7 @@ TEST_CASE("twai install uninstall (loopback)", "[twai]")
TEST_ESP_OK(twai_node_enable(node_hdl[SOC_TWAI_CONTROLLER_NUM]));
tx_frame.header.id = 0x100;
TEST_ESP_OK(twai_node_transmit(node_hdl[SOC_TWAI_CONTROLLER_NUM], &tx_frame, 0));
twai_frame_t rx_frame = {0};
twai_frame_t rx_frame = {};
printf("Test receive from task\n");
TEST_ESP_ERR(ESP_ERR_INVALID_STATE, twai_node_receive_from_isr(node_hdl[SOC_TWAI_CONTROLLER_NUM], &rx_frame));
@@ -105,34 +103,32 @@ 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,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_TX_GPIO;
node_config.clk_src = clk_src;
node_config.bit_timing.bitrate = test_bitrate;
node_config.tx_queue_depth = 1;
node_config.flags.enable_self_test = true;
node_config.flags.enable_loopback = true;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &twai_node));
TEST_ESP_OK(twai_node_enable(twai_node));
printf("TWAI driver installed @ %ld Hz\n", test_bitrate);
// 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,
};
uart_bitrate_detect_config_t detect_config = {};
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,
}
twai_frame_t tx_frame = {};
tx_frame.header.id = 0x55555;
tx_frame.header.dlc = 8;
tx_frame.header.ide = true;
tx_frame.buffer = (uint8_t []) {
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55
};
tx_frame.buffer_len = 8;
TEST_ESP_OK(twai_node_transmit(twai_node, &tx_frame, 500));
vTaskDelay(100);
@@ -140,7 +136,7 @@ static void test_twai_baudrate_correctness(twai_clock_source_t clk_src, uint32_t
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);
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));
@@ -152,7 +148,7 @@ TEST_CASE("twai baudrate measurement", "[twai]")
twai_clock_source_t twai_available_clk_srcs[] = SOC_TWAI_CLKS;
uint32_t source_freq = 0;
for (size_t i = 0; i < sizeof(twai_available_clk_srcs) / sizeof(twai_available_clk_srcs[0]); i++) {
TEST_ESP_OK(esp_clk_tree_src_get_freq_hz(twai_available_clk_srcs[i], ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &source_freq));
TEST_ESP_OK(esp_clk_tree_src_get_freq_hz((soc_module_clk_t)twai_available_clk_srcs[i], ESP_CLK_TREE_SRC_FREQ_PRECISION_APPROX, &source_freq));
printf("Test clock source %d frequency: %ld Hz\n", twai_available_clk_srcs[i], source_freq);
test_twai_baudrate_correctness(twai_available_clk_srcs[i], 200000);
@@ -162,7 +158,7 @@ TEST_CASE("twai baudrate measurement", "[twai]")
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;
twai_frame_t *rx_frame = (twai_frame_t *)user_ctx;
if (ESP_OK == twai_node_receive_from_isr(handle, rx_frame)) {
ESP_EARLY_LOGI("Recv", "RX id 0x%x len %d ext %d brs %d esi %d", rx_frame->header.id, twaifd_dlc2len(rx_frame->header.dlc), rx_frame->header.ide, rx_frame->header.brs, rx_frame->header.esi);
rx_frame->buffer += rx_frame->buffer_len;
@@ -173,34 +169,33 @@ static IRAM_ATTR bool test_enable_disable_rx_cb(twai_node_handle_t handle, const
TEST_CASE("twai transmit stop resume (loopback)", "[twai]")
{
// prepare test memory
uint8_t *send_pkg_ptr = heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_8BIT);
uint8_t *recv_pkg_ptr = heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_8BIT);
uint8_t *send_pkg_ptr = (uint8_t*)heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_8BIT);
uint8_t *recv_pkg_ptr = (uint8_t*)heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_8BIT);
TEST_ASSERT(send_pkg_ptr && recv_pkg_ptr);
printf("Transmit %d bytes package in %d frames\n", TEST_TRANS_LEN, TEST_FRAME_NUM);
twai_node_handle_t node_hdl;
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_TX_GPIO, // Using same pin for test without transceiver
.bit_timing.bitrate = 200000,
.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH,
.flags.enable_loopback = true,
.flags.enable_self_test = true,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
node_config.bit_timing.bitrate = 200000;
node_config.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH;
node_config.flags.enable_self_test = true;
node_config.flags.enable_loopback = true;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
twai_frame_t rx_frame = {
.buffer = recv_pkg_ptr,
.buffer_len = TEST_FRAME_LEN,
};
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_enable_disable_rx_cb,
};
twai_frame_t rx_frame = {};
rx_frame.buffer = recv_pkg_ptr;
rx_frame.buffer_len = TEST_FRAME_LEN;
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_enable_disable_rx_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, &rx_frame));
TEST_ESP_OK(twai_node_enable(node_hdl));
//create and enqueue all transfers
twai_frame_t *tx_msgs = heap_caps_calloc(TEST_FRAME_NUM, sizeof(twai_frame_t), MALLOC_CAP_8BIT);
twai_frame_t *tx_msgs = (twai_frame_t*)heap_caps_calloc(TEST_FRAME_NUM, sizeof(twai_frame_t), MALLOC_CAP_8BIT);
TEST_ASSERT(tx_msgs);
for (uint32_t tx_cnt = 0; tx_cnt < TEST_FRAME_NUM; tx_cnt++) {
tx_msgs[tx_cnt].header.id = tx_cnt | 0x400;
@@ -237,9 +232,9 @@ TEST_CASE("twai transmit stop resume (loopback)", "[twai]")
static void test_random_trans_generator(twai_node_handle_t node_hdl, uint32_t trans_num)
{
uint8_t send_pkg_ptr[TWAI_FRAME_MAX_LEN];
twai_frame_t tx_msg = {
.buffer = send_pkg_ptr,
};
twai_frame_t tx_msg = {};
tx_msg.buffer = send_pkg_ptr;
printf("Sending %ld random trans ...\n", trans_num);
for (uint32_t tx_cnt = 0; tx_cnt < trans_num; tx_cnt++) {
tx_msg.header.id = tx_cnt | 0xf000;
@@ -253,12 +248,12 @@ static void test_random_trans_generator(twai_node_handle_t node_hdl, uint32_t tr
static IRAM_ATTR bool test_filter_rx_done_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
{
uint8_t *test_ctrl = user_ctx;
uint8_t *test_ctrl = (uint8_t *)user_ctx;
uint8_t recv_pkg_ptr[TWAI_FRAME_MAX_LEN];
twai_frame_t rx_frame = {
.buffer = recv_pkg_ptr,
.buffer_len = TWAI_FRAME_MAX_LEN,
};
twai_frame_t rx_frame = {};
rx_frame.buffer = recv_pkg_ptr;
rx_frame.buffer_len = TWAI_FRAME_MAX_LEN;
if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
ESP_EARLY_LOGI("Recv", "RX id 0x%4x len %2d ext %d rmt %d", rx_frame.header.id, twaifd_dlc2len(rx_frame.header.dlc), rx_frame.header.ide, rx_frame.header.rtr);
switch (test_ctrl[0]) {
@@ -279,22 +274,21 @@ TEST_CASE("twai mask filter (loopback)", "[twai]")
{
uint8_t test_ctrl[2];
twai_node_handle_t node_hdl;
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_TX_GPIO, // Using same pin for test without transceiver
.bit_timing.bitrate = 1000000,
.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH,
.flags.enable_loopback = true,
.flags.enable_self_test = true,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
node_config.bit_timing.bitrate = 1000000;
node_config.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH;
node_config.flags.enable_self_test = true;
node_config.flags.enable_loopback = true;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_filter_rx_done_cb,
};
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_filter_rx_done_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, test_ctrl));
twai_mask_filter_config_t mfilter_cfg = {0};
twai_mask_filter_config_t mfilter_cfg = {};
for (uint8_t i = 0; i < SOC_TWAI_MASK_FILTER_NUM; i++) {
printf("\n--------------------------------------\n");
test_ctrl[0] = 0;
@@ -338,12 +332,12 @@ TEST_CASE("twai mask filter (loopback)", "[twai]")
#if !SOC_TWAI_SUPPORT_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 = user_ctx;
uint8_t *test_ctrl = (uint8_t *)user_ctx;
uint8_t recv_pkg_ptr[TWAI_FRAME_MAX_LEN];
twai_frame_t rx_frame = {
.buffer = recv_pkg_ptr,
.buffer_len = TWAI_FRAME_MAX_LEN,
};
twai_frame_t rx_frame = {};
rx_frame.buffer = recv_pkg_ptr;
rx_frame.buffer_len = TWAI_FRAME_MAX_LEN;
if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
ESP_EARLY_LOGI("Recv", "RX id 0x%4x len %2d ext %d rmt %d", rx_frame.header.id, twaifd_dlc2len(rx_frame.header.dlc), rx_frame.header.ide, rx_frame.header.rtr);
switch (test_ctrl[0]) {
@@ -363,19 +357,18 @@ TEST_CASE("twai dual 16bit mask filter (loopback)", "[twai]")
{
uint8_t test_ctrl[2];
twai_node_handle_t node_hdl;
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_TX_GPIO, // Using same pin for test without transceiver
.bit_timing.bitrate = 1000000,
.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH,
.flags.enable_loopback = true,
.flags.enable_self_test = true,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
node_config.bit_timing.bitrate = 1000000;
node_config.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH;
node_config.flags.enable_self_test = true;
node_config.flags.enable_loopback = true;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_dual_filter_rx_done_cb,
};
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_dual_filter_rx_done_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, test_ctrl));
printf("Testing dual filter: id1 0x%x mask1 0x%x, id2 0x%x mask2 0x%x\n", 0x020, 0x7f0, 0x013, 0x7f8);
@@ -408,7 +401,7 @@ TEST_CASE("twai dual 16bit mask filter (loopback)", "[twai]")
#if CONFIG_TWAI_ISR_CACHE_SAFE
static IRAM_ATTR bool test_iram_safe_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;
twai_frame_t *rx_frame = (twai_frame_t *)user_ctx;
if (ESP_OK == twai_node_receive_from_isr(handle, rx_frame)) {
esp_rom_printf(DRAM_STR("RX id 0x%x len %d ext %d brs %d esi %d\n"), rx_frame->header.id, twaifd_dlc2len(rx_frame->header.dlc), rx_frame->header.ide, rx_frame->header.brs, rx_frame->header.esi);
rx_frame->buffer += rx_frame->buffer_len;
@@ -431,34 +424,33 @@ static void IRAM_ATTR test_wait_trans_done_cache_disable(void *args)
TEST_CASE("twai driver cache safe (loopback)", "[twai]")
{
// prepare test memory
uint8_t *send_pkg_ptr = heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_8BIT);
uint8_t *recv_pkg_ptr = heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_8BIT);
uint8_t *send_pkg_ptr = (uint8_t *)heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_8BIT);
uint8_t *recv_pkg_ptr = (uint8_t *)heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_8BIT);
TEST_ASSERT(send_pkg_ptr && recv_pkg_ptr);
printf("Transmit %d bytes package in %d frames\n", TEST_TRANS_LEN, TEST_FRAME_NUM);
twai_node_handle_t node_hdl;
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_TX_GPIO, // Using same pin for test without transceiver
.bit_timing.bitrate = 50000, //slow bitrate to ensure cache disabled before tx_queue finish
.tx_queue_depth = TEST_FRAME_NUM,
.flags.enable_loopback = true,
.flags.enable_self_test = true,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
node_config.bit_timing.bitrate = 50000; //slow bitrate to ensure cache disabled before tx_queue finish
node_config.tx_queue_depth = TEST_FRAME_NUM;
node_config.flags.enable_loopback = true;
node_config.flags.enable_self_test = true;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
twai_frame_t rx_frame = {
.buffer = recv_pkg_ptr,
.buffer_len = TEST_FRAME_LEN,
};
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_iram_safe_rx_cb,
};
twai_frame_t rx_frame = {};
rx_frame.buffer = recv_pkg_ptr;
rx_frame.buffer_len = TEST_FRAME_LEN;
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_iram_safe_rx_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, &rx_frame));
TEST_ESP_OK(twai_node_enable(node_hdl));
//create and enqueue all transfers
twai_frame_t *tx_msgs = heap_caps_calloc(TEST_FRAME_NUM, sizeof(twai_frame_t), MALLOC_CAP_8BIT);
twai_frame_t *tx_msgs = (twai_frame_t *)heap_caps_calloc(TEST_FRAME_NUM, sizeof(twai_frame_t), MALLOC_CAP_8BIT);
TEST_ASSERT(tx_msgs);
for (uint32_t tx_cnt = 0; tx_cnt < TEST_FRAME_NUM; tx_cnt++) {
tx_msgs[tx_cnt].header.id = tx_cnt | 0x400;

View File

@@ -15,16 +15,15 @@
#include "esp_twai.h"
#include "esp_twai_onchip.h"
#define TEST_TX_GPIO 4
#define TEST_RX_GPIO 5
#define TEST_TX_GPIO GPIO_NUM_4
#define TEST_RX_GPIO GPIO_NUM_5
#define TEST_TWAI_QUEUE_DEPTH 5
static void test_random_trans_generator(twai_node_handle_t node_hdl, uint32_t trans_num)
{
uint8_t send_pkg_ptr[TWAIFD_FRAME_MAX_LEN];
twai_frame_t tx_msg = {
.buffer = send_pkg_ptr,
};
twai_frame_t tx_msg = {};
tx_msg.buffer = send_pkg_ptr;
printf("Sending %ld random trans ...\n", trans_num);
for (uint32_t tx_cnt = 0; tx_cnt < trans_num; tx_cnt++) {
tx_msg.header.id = tx_cnt | 0xf000;
@@ -39,12 +38,12 @@ static void test_random_trans_generator(twai_node_handle_t node_hdl, uint32_t tr
static IRAM_ATTR bool test_range_filter_rx_done_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
{
uint8_t *test_ctrl = user_ctx;
uint8_t *test_ctrl = (uint8_t *)user_ctx;
uint8_t recv_pkg_ptr[TWAIFD_FRAME_MAX_LEN];
twai_frame_t rx_frame = {
.buffer = recv_pkg_ptr,
.buffer_len = TWAIFD_FRAME_MAX_LEN,
};
twai_frame_t rx_frame = {};
rx_frame.buffer = recv_pkg_ptr;
rx_frame.buffer_len = TWAIFD_FRAME_MAX_LEN;
if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
ESP_EARLY_LOGI("Recv", "RX id 0x%4x len %2d ext %d rmt %d fd %d", rx_frame.header.id, twaifd_dlc2len(rx_frame.header.dlc), rx_frame.header.ide, rx_frame.header.rtr, rx_frame.header.fdf);
switch (test_ctrl[0]) {
@@ -64,35 +63,33 @@ TEST_CASE("twai range filter (loopback)", "[twai]")
{
uint8_t test_ctrl[2];
twai_node_handle_t node_hdl;
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_TX_GPIO, // Using same pin for test without transceiver
.bit_timing.bitrate = 1000000,
.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH,
.flags.enable_loopback = true,
.flags.enable_self_test = true,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
node_config.bit_timing.bitrate = 1000000;
node_config.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH;
node_config.flags.enable_self_test = true;
node_config.flags.enable_loopback = true;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_range_filter_rx_done_cb,
};
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_range_filter_rx_done_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, test_ctrl));
// disable mask filter 0 which enabled by default
twai_mask_filter_config_t mfilter_cfg = {
.id = 0xFFFFFFFF,
.mask = 0xFFFFFFFF,
};
twai_mask_filter_config_t mfilter_cfg = {};
mfilter_cfg.id = 0xFFFFFFFF;
mfilter_cfg.mask = 0xFFFFFFFF;
TEST_ESP_OK(twai_node_config_mask_filter(node_hdl, 0, &mfilter_cfg));
test_ctrl[0] = 0;
test_ctrl[1] = 0;
twai_range_filter_config_t rfilter_cfg = {
.range_low = 0x0a,
.range_high = 0x15,
.is_ext = false,
};
twai_range_filter_config_t rfilter_cfg = {};
rfilter_cfg.range_low = 0x0a;
rfilter_cfg.range_high = 0x15;
rfilter_cfg.is_ext = false;
printf("Config range filter 0: 0x%lx - 0x%lx\n", rfilter_cfg.range_low, rfilter_cfg.range_high);
TEST_ESP_OK(twai_node_config_range_filter(node_hdl, 0, &rfilter_cfg));
TEST_ESP_OK(twai_node_enable(node_hdl));
@@ -117,7 +114,7 @@ TEST_CASE("twai range filter (loopback)", "[twai]")
#define TEST_TRANS_TIME_BUF_LEN 20000
static IRAM_ATTR bool test_fd_trans_time_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;
twai_frame_t *rx_frame = (twai_frame_t *)user_ctx;
uint32_t data_len;
if (ESP_OK == twai_node_receive_from_isr(handle, rx_frame)) {
data_len = MIN(twaifd_dlc2len(rx_frame->header.dlc), rx_frame->buffer_len);
@@ -134,27 +131,28 @@ static IRAM_ATTR bool test_fd_trans_time_rx_cb(twai_node_handle_t handle, const
TEST_CASE("twai fd transmit time (loopback)", "[twai]")
{
// prepare test memory
uint8_t *send_pkg_ptr = heap_caps_malloc(TEST_TRANS_TIME_BUF_LEN, MALLOC_CAP_8BIT);
uint8_t *recv_pkg_ptr = heap_caps_malloc(TEST_TRANS_TIME_BUF_LEN, MALLOC_CAP_8BIT);
uint8_t *send_pkg_ptr = (uint8_t*)heap_caps_malloc(TEST_TRANS_TIME_BUF_LEN, MALLOC_CAP_8BIT);
uint8_t *recv_pkg_ptr = (uint8_t*)heap_caps_malloc(TEST_TRANS_TIME_BUF_LEN, MALLOC_CAP_8BIT);
TEST_ASSERT(send_pkg_ptr && recv_pkg_ptr);
twai_node_handle_t node_hdl;
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_TX_GPIO, // Using same pin for test without transceiver
.bit_timing.bitrate = 1000000,
.data_timing.bitrate = 4000000,
.data_timing.ssp_permill = 700, // ssp 70.0%
.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH,
.flags.enable_loopback = true,
.flags.enable_self_test = true,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
node_config.bit_timing.bitrate = 1000000;
node_config.data_timing.bitrate = 4000000;
node_config.data_timing.ssp_permill = 700; // ssp 70.0%
node_config.tx_queue_depth = TEST_TWAI_QUEUE_DEPTH;
node_config.flags.enable_self_test = true;
node_config.flags.enable_loopback = true;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
twai_frame_t rx_frame = {.buffer_len = 64};
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_fd_trans_time_rx_cb,
};
twai_frame_t rx_frame = {};
rx_frame.buffer_len = 64;
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_fd_trans_time_rx_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, &rx_frame));
TEST_ESP_OK(twai_node_enable(node_hdl));
printf("%-12s %-14s %-14s %-7s %-15s %s\n", "pkg_len", "frame_len", "frame_num", "brs", "trans_time/ms", "result");
@@ -168,7 +166,7 @@ TEST_CASE("twai fd transmit time (loopback)", "[twai]")
rx_frame.buffer = recv_pkg_ptr;
rx_frame.buffer_len = frame_len;
memset(recv_pkg_ptr, 0xff, TEST_TRANS_TIME_BUF_LEN);
twai_frame_t *tx_msgs = heap_caps_calloc(trans_num, sizeof(twai_frame_t), MALLOC_CAP_8BIT);
twai_frame_t *tx_msgs = (twai_frame_t *)heap_caps_calloc(trans_num, sizeof(twai_frame_t), MALLOC_CAP_8BIT);
TEST_ASSERT(tx_msgs);
time1 = esp_timer_get_time();
for (uint32_t tx_cnt = 0; tx_cnt < trans_num; tx_cnt++) {

View File

@@ -12,8 +12,8 @@
#include "esp_twai.h"
#include "esp_twai_onchip.h"
#define TEST_TX_GPIO 4
#define TEST_RX_GPIO 5
#define TEST_TX_GPIO GPIO_NUM_4
#define TEST_RX_GPIO GPIO_NUM_5
static bool IRAM_ATTR test_listen_only_rx_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
{
@@ -28,27 +28,25 @@ static bool IRAM_ATTR test_listen_only_rx_cb(twai_node_handle_t handle, const tw
TEST_CASE("twai_listen_only", "[twai_net]")
{
twai_node_handle_t node_hdl;
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_RX_GPIO,
.bit_timing.bitrate = 250000,
.tx_queue_depth = 3,
.flags.enable_listen_only = true,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_RX_GPIO;
node_config.bit_timing.bitrate = 250000;
node_config.tx_queue_depth = 3;
node_config.flags.enable_listen_only = true;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
ESP_LOGI("Test", "driver installed");
uint8_t rx_buffer[8] = {0};
twai_frame_t rx_frame = {
.buffer = rx_buffer,
.buffer_len = sizeof(rx_buffer),
};
twai_frame_t rx_frame = {};
rx_frame.buffer = rx_buffer;
rx_frame.buffer_len = sizeof(rx_buffer);
uint8_t rx_msg_cnt = 0;
void *user_data[2] = {&rx_msg_cnt, &rx_frame};
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_listen_only_rx_cb,
};
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_listen_only_rx_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, user_data));
TEST_ESP_OK(twai_node_enable(node_hdl));
@@ -69,36 +67,34 @@ TEST_CASE("twai_listen_only", "[twai_net]")
TEST_CASE("twai_remote_request", "[twai_net]")
{
twai_node_handle_t node_hdl;
twai_onchip_node_config_t node_config = {
.io_cfg.tx = TEST_TX_GPIO,
.io_cfg.rx = TEST_RX_GPIO,
.bit_timing.bitrate = 250000,
.fail_retry_cnt = -1, // retry forever if send remote frame failed
.tx_queue_depth = 3,
};
twai_onchip_node_config_t node_config = {};
node_config.io_cfg.tx = TEST_TX_GPIO;
node_config.io_cfg.rx = TEST_RX_GPIO;
node_config.bit_timing.bitrate = 250000;
node_config.tx_queue_depth = 3;
node_config.fail_retry_cnt = -1; // retry forever if send remote frame failed
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
ESP_LOGI("Test", "driver installed");
uint8_t rx_buffer[8] = {0};
twai_frame_t rx_frame = {
.buffer = rx_buffer,
.buffer_len = sizeof(rx_buffer),
};
twai_frame_t rx_frame = {};
rx_frame.buffer = rx_buffer;
rx_frame.buffer_len = sizeof(rx_buffer);
uint8_t rx_msg_cnt = 0;
void *user_data[2] = {&rx_msg_cnt, &rx_frame};
twai_event_callbacks_t user_cbs = {
.on_rx_done = test_listen_only_rx_cb,
};
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_listen_only_rx_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, user_data));
TEST_ESP_OK(twai_node_enable(node_hdl));
twai_frame_t tx_frame = {
.header.id = 0x123,
.header.dlc = 8,
.header.rtr = true,
.header.ide = true,
};
twai_frame_t tx_frame = {};
tx_frame.header.id = 0x123;
tx_frame.header.dlc = 8;
tx_frame.header.ide = true;
tx_frame.header.rtr = true;
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame, 1000));
ESP_LOGI("Test", "send remote frame");

View File

@@ -372,7 +372,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_APB}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_APB}
/**
* @brief TWAI clock source

View File

@@ -315,7 +315,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_APB}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_APB}
/**
* @brief TWAI clock source

View File

@@ -431,7 +431,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL, SOC_MOD_CLK_PLL_F80M}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_XTAL, (soc_periph_twai_clk_src_t)SOC_MOD_CLK_PLL_F80M}
/**
* @brief TWAI clock source

View File

@@ -411,7 +411,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_XTAL}
/**
* @brief TWAI clock source

View File

@@ -404,7 +404,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_XTAL}
/**
* @brief TWAI clock source

View File

@@ -278,7 +278,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_XTAL}
/**
* @brief TWAI clock source

View File

@@ -598,7 +598,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_XTAL}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_XTAL}
/**
* @brief TWAI clock source

View File

@@ -359,7 +359,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_APB}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_APB}
/**
* @brief TWAI clock source

View File

@@ -394,7 +394,7 @@ typedef enum {
/**
* @brief Array initializer for all supported clock sources of TWAI
*/
#define SOC_TWAI_CLKS {SOC_MOD_CLK_APB}
#define SOC_TWAI_CLKS {(soc_periph_twai_clk_src_t)SOC_MOD_CLK_APB}
/**
* @brief TWAI clock source