diff --git a/components/esp_driver_twai/esp_twai.c b/components/esp_driver_twai/esp_twai.c index 874f42e7ce..f680a2ddcb 100644 --- a/components/esp_driver_twai/esp_twai.c +++ b/components/esp_driver_twai/esp_twai.c @@ -43,12 +43,11 @@ uint32_t twai_node_timing_calc_param(const uint32_t source_freq, const twai_timi uint16_t default_point = (in_param->bitrate >= 800000) ? 750 : ((in_param->bitrate >= 500000) ? 800 : 875); uint16_t sample_point = in_param->sp_permill ? in_param->sp_permill : default_point; // default sample point based on bitrate if not configured - uint16_t tseg_1 = (tseg * sample_point) / 1000; + uint16_t tseg_1 = (tseg * sample_point) / 1000 - 1; tseg_1 = MAX(hw_limit->tseg1_min, MIN(tseg_1, hw_limit->tseg1_max)); uint16_t tseg_2 = tseg - tseg_1 - 1; tseg_2 = MAX(hw_limit->tseg2_min, MIN(tseg_2, hw_limit->tseg2_max)); - tseg_1 = tseg - tseg_2 - 1; - uint16_t prop = tseg_1 / 2; // distribute tseg1 evenly between prop_seg and tseg_1 + uint16_t prop = MAX(1, tseg_1 / 4); // prop_seg is usually shorter than tseg_1 and at least 1 tseg_1 -= prop; out_param->quanta_resolution_hz = 0; // going to deprecated IDF-12725 diff --git a/components/esp_driver_twai/esp_twai_onchip.c b/components/esp_driver_twai/esp_twai_onchip.c index 6ae09e296b..f83b76dc31 100644 --- a/components/esp_driver_twai/esp_twai_onchip.c +++ b/components/esp_driver_twai/esp_twai_onchip.c @@ -444,7 +444,7 @@ static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, twai_clock_s .sjw_max = TWAI_LL_SJW_MAX, }; uint32_t real_baud = twai_node_timing_calc_param(source_freq, timing, &hw_const, &timing_adv); - ESP_LOGD(TAG, "norm src %ld, param %ld %d %d %d %d %d", source_freq, timing_adv.brp, timing_adv.prop_seg, timing_adv.tseg_1, timing_adv.tseg_2, timing_adv.sjw, timing_adv.ssp_offset); + ESP_LOGD(TAG, "timing: src %ld brp %ld prop %d seg1 %d seg2 %d sjw %d ssp %d", source_freq, timing_adv.brp, timing_adv.prop_seg, timing_adv.tseg_1, timing_adv.tseg_2, timing_adv.sjw, timing_adv.ssp_offset); ESP_RETURN_ON_FALSE(real_baud, ESP_ERR_INVALID_ARG, TAG, "bitrate can't achieve!"); if (timing->bitrate != real_baud) { ESP_LOGW(TAG, "bitrate precision loss, adjust from %ld to %ld", timing->bitrate, real_baud); @@ -453,7 +453,7 @@ static esp_err_t _node_calc_set_bit_timing(twai_node_handle_t node, twai_clock_s 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); - ESP_LOGD(TAG, "fd src %ld, param %ld %d %d %d %d %d", source_freq, timing_adv_fd.brp, timing_adv_fd.prop_seg, timing_adv_fd.tseg_1, timing_adv_fd.tseg_2, timing_adv_fd.sjw, timing_adv_fd.ssp_offset); + ESP_LOGD(TAG, "timing_fd: src %ld brp %ld prop %d seg1 %d seg2 %d sjw %d ssp %d", source_freq, timing_adv_fd.brp, timing_adv_fd.prop_seg, timing_adv_fd.tseg_1, timing_adv_fd.tseg_2, timing_adv_fd.sjw, timing_adv_fd.ssp_offset); ESP_RETURN_ON_FALSE(real_baud, ESP_ERR_INVALID_ARG, TAG, "bitrate can't achieve!"); if (timing_fd->bitrate != real_baud) { ESP_LOGW(TAG, "bitrate precision loss, adjust from %ld to %ld", timing_fd->bitrate, real_baud); diff --git a/components/esp_driver_twai/include/esp_twai_onchip.h b/components/esp_driver_twai/include/esp_twai_onchip.h index 68eb59ce91..e390d3abd6 100644 --- a/components/esp_driver_twai/include/esp_twai_onchip.h +++ b/components/esp_driver_twai/include/esp_twai_onchip.h @@ -57,14 +57,14 @@ 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 each filter. * - * @param id1 First ID to filter. + * @param id1 First full 11/29 bits ID to filter. * @param mask1 Mask for first ID. - * @param id2 Second ID to filter. + * @param id2 Second full 11/29 bits ID to filter. * @param mask2 Mask for second ID. * @param is_ext True if using Extended (29-bit) IDs, false for Standard (11-bit) IDs. * @return twai_mask_filter_config_t A filled filter configuration structure for dual filtering. */ -static inline twai_mask_filter_config_t twai_make_dual_filter(uint16_t id1, uint16_t mask1, uint16_t id2, uint16_t mask2, bool is_ext) +static inline twai_mask_filter_config_t twai_make_dual_filter(uint32_t id1, uint32_t mask1, uint32_t id2, uint32_t mask2, bool is_ext) { /** * Dual filter is a special mode in hardware, @@ -90,6 +90,10 @@ static inline twai_mask_filter_config_t twai_make_dual_filter(uint16_t id1, uint .no_fd = false, .dual_filter = true, }; + if ((id1 & mask1 & id2 & mask2) == 0xffffffff) { + dual_cfg.id = 0xffffffff; // recover the 'disable' code + dual_cfg.mask = 0xffffffff; + } return dual_cfg; } 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 242261196e..2d629cccf0 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 @@ -246,7 +246,7 @@ static void test_random_trans_generator(twai_node_handle_t node_hdl, uint32_t tr 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; + tx_msg.header.id = tx_cnt | 0xf000 | (tx_cnt << 16); tx_msg.header.ide = !!(tx_cnt % 2); tx_msg.header.rtr = !!(tx_cnt % 3); tx_msg.buffer_len = tx_cnt % TWAI_FRAME_MAX_LEN; @@ -350,13 +350,17 @@ static IRAM_ATTR bool test_dual_filter_rx_done_cb(twai_node_handle_t handle, con 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); + ESP_EARLY_LOGI("Recv", "id 0x%8x 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]) { - case 0: // receive something + case 0: // receive std id TEST_ASSERT(!rx_frame.header.ide); TEST_ASSERT((rx_frame.header.id >= 0x10) && (rx_frame.header.id <= 0x2f)); break; case 1: break; // receive none + case 2: // receive ext id + TEST_ASSERT(rx_frame.header.ide); + TEST_ASSERT((rx_frame.header.id >= 0x280000) || (rx_frame.header.id <= 0xfffff)); + break; default: TEST_ASSERT(false); } test_ctrl[1] ++; @@ -384,7 +388,7 @@ TEST_CASE("twai dual 16bit mask filter (loopback)", "[twai]") 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); + printf("Testing dual filter: std id1 0x%x mask1 0x%x, id2 0x%x mask2 0x%x\n", 0x020, 0x7f0, 0x013, 0x7f8); test_ctrl[0] = 0; test_ctrl[1] = 0; // filter 1 receive only std id 0x02x @@ -395,17 +399,31 @@ TEST_CASE("twai dual 16bit mask filter (loopback)", "[twai]") test_random_trans_generator(node_hdl, 50); TEST_ASSERT_EQUAL(12, test_ctrl[1]); // must receive 12 of 50 frames under filter config - printf("Disable filter\n"); + dual_config = twai_make_dual_filter(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, false); + printf("Testing disable filter by dual_maker, result: id %lx mask %lx\n", dual_config.id, dual_config.mask); + TEST_ASSERT_EQUAL(0xffffffff, dual_config.id & dual_config.mask); + + printf("Testing disable filter\n"); test_ctrl[0] = 1; test_ctrl[1] = 0; - dual_config.id = 0xFFFFFFFF; - dual_config.mask = 0xFFFFFFFF; TEST_ESP_OK(twai_node_disable(node_hdl)); TEST_ESP_OK(twai_node_config_mask_filter(node_hdl, 0, &dual_config)); TEST_ESP_OK(twai_node_enable(node_hdl)); test_random_trans_generator(node_hdl, 40); TEST_ASSERT_EQUAL(0, test_ctrl[1]); + printf("Testing dual filter: ext id1 0x%x mask1 0x%x, id2 0x%x mask2 0x%x\n", 0x0280000, 0x1ff80000, 0x0000000, 0x1ff00000); + test_ctrl[0] = 2; + test_ctrl[1] = 0; + // filter 1 receive only ext id 0x028xxxxx~0x02fxxxxx + // filter 2 receive only ext id 0x000xxxxx + dual_config = twai_make_dual_filter(0x0280000, 0x1ff80000, 0x0000000, 0x1ff00000, true); + TEST_ESP_OK(twai_node_disable(node_hdl)); + TEST_ESP_OK(twai_node_config_mask_filter(node_hdl, 0, &dual_config)); + TEST_ESP_OK(twai_node_enable(node_hdl)); + test_random_trans_generator(node_hdl, 50); + TEST_ASSERT_EQUAL(12, test_ctrl[1]); // must receive 12 of 50 frames + TEST_ESP_OK(twai_node_disable(node_hdl)); TEST_ESP_OK(twai_node_delete(node_hdl)); }