feat(driver_twai): fd hardware support time trigger trans

This commit is contained in:
wanckl
2026-07-15 11:23:44 +08:00
parent f05afe5722
commit 9da7cc92b3
8 changed files with 149 additions and 3 deletions
@@ -923,3 +923,79 @@ TEST_CASE("twai rx timestamp", "[twai]")
TEST_ESP_OK(twai_node_delete(node_hdl));
}
}
TEST_CASE("twai schedule transmit", "[twai]")
{
twai_node_handle_t node_hdl;
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.io_cfg.quanta_clk_out = GPIO_NUM_NC;
node_config.io_cfg.bus_off_indicator = GPIO_NUM_NC;
node_config.bit_timing.bitrate = 100000;
node_config.tx_queue_depth = 10;
node_config.flags.enable_loopback = true;
node_config.flags.enable_self_test = true;
node_config.flags.enable_scheduled_tx = true;
printf("Testing schedule feature check\n");
#if !TWAI_LL_SUPPORT(TIMESTAMP)
TEST_ESP_ERR(twai_new_node_onchip(&node_config, &node_hdl), ESP_ERR_NOT_SUPPORTED);
return;
#endif
TEST_ESP_ERR(twai_new_node_onchip(&node_config, &node_hdl), ESP_ERR_INVALID_ARG);
node_config.timestamp_resolution_hz = 1000000;
TEST_ESP_OK(twai_new_node_onchip(&node_config, &node_hdl));
twai_frame_t rx_frame = {};
twai_event_callbacks_t user_cbs = {};
user_cbs.on_rx_done = test_dlc_range_cb;
TEST_ESP_OK(twai_node_register_event_callbacks(node_hdl, &user_cbs, &rx_frame));
TEST_ESP_OK(twai_node_enable(node_hdl));
twai_frame_t tx_frame[6] = {};
uint64_t time_now = esp_timer_get_time();
printf("time_now = %llu\n", time_now);
printf("Testing schedule frame 1 blocks immediate frame 2\n");
tx_frame[0].header.id = 1;
tx_frame[0].header.trigger_time = time_now + 1000000;
tx_frame[1].header.id = 2;
tx_frame[1].header.trigger_time = 0; // set 0 to send immediately but will be blocked by 1st frame
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame[0], 100));
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame[1], 100));
TEST_ESP_OK(twai_node_transmit_wait_all_done(node_hdl, -1));
// should receive 2nd frame in same time
TEST_ASSERT_EQUAL(tx_frame[1].header.id, rx_frame.header.id);
TEST_ASSERT_INT32_WITHIN(1000000 / 100, 1000000, rx_frame.header.timestamp - time_now);
printf("\nTesting schedule time sequence\n");
time_now = esp_timer_get_time();
tx_frame[0].header.trigger_time = time_now + 1000000;
for (int i = 1; i < 6; i++) {
tx_frame[i].header.id = i;
tx_frame[i].header.trigger_time = tx_frame[i - 1].header.trigger_time + i * 1000000;
printf("Schedule frame %d after %lld s\n", i, (tx_frame[i].header.trigger_time - time_now) / 1000000);
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame[i], 0));
}
printf("\nWaiting for checking result\n");
uint64_t last_time = rx_frame.header.timestamp;
for (int i = 0; i < 5; i++) {
time_now = esp_timer_get_time();
int second_cnt = 0;
while (rx_frame.header.timestamp == last_time) {
vTaskDelay(1);
second_cnt++;
if (second_cnt % 1000 == 0) { // print time every 1 second
esp_rom_printf("%d ", second_cnt / 1000);
}
}
last_time = rx_frame.header.timestamp;
printf("\nFrame %d received after %d s\n", i, second_cnt / 1000);
TEST_ASSERT_INT32_WITHIN(1000000 / 100, second_cnt * 1000, rx_frame.header.timestamp - time_now);
}
TEST_ESP_OK(twai_node_disable(node_hdl));
TEST_ESP_OK(twai_node_delete(node_hdl));
}