Skip to content

Commit 579373d

Browse files
committed
fix(driver_twai): added errata warning for c5 listen only mode
1 parent 76cec45 commit 579373d

File tree

4 files changed

+29
-14
lines changed

4 files changed

+29
-14
lines changed

components/esp_driver_twai/esp_twai_onchip.c

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
#include "esp_twai.h"
88
#include "esp_twai_onchip.h"
9-
#include "soc/gpio_sig_map.h"
109
#include "esp_private/twai_interface.h"
1110
#include "esp_private/twai_utils.h"
1211
#include "twai_private.h"
@@ -125,17 +124,14 @@ static esp_err_t _node_config_io(twai_onchip_ctx_t *node, const twai_onchip_node
125124
{
126125
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.tx), ESP_ERR_INVALID_ARG, TAG, "Invalid tx gpio num");
127126
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(node_config->io_cfg.rx), ESP_ERR_INVALID_ARG, TAG, "Invalid rx gpio num");
128-
uint64_t reserve_mask = BIT64(node_config->io_cfg.tx);
129127

130128
// Set RX pin
131129
gpio_set_pull_mode(node_config->io_cfg.rx, GPIO_PULLUP_ONLY); // pullup to avoid noise if no connection to transceiver
132130
gpio_matrix_input(node_config->io_cfg.rx, twai_periph_signals[node->ctrlr_id].rx_sig, false);
133131

134132
// Set TX pin
135-
// If enable_listen_only, disconnect twai signal, and output high to avoid any influence to bus
136-
gpio_set_level(node_config->io_cfg.tx, 1);
137-
int tx_sig = (node_config->flags.enable_listen_only) ? SIG_GPIO_OUT_IDX : twai_periph_signals[node->ctrlr_id].tx_sig;
138-
gpio_matrix_output(node_config->io_cfg.tx, tx_sig, false, false);
133+
uint64_t reserve_mask = BIT64(node_config->io_cfg.tx);
134+
gpio_matrix_output(node_config->io_cfg.tx, twai_periph_signals[node->ctrlr_id].tx_sig, false, false);
139135

140136
//Configure output clock pin (Optional)
141137
if (GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.quanta_clk_out)) {
@@ -519,7 +515,7 @@ static esp_err_t _node_config_mask_filter(twai_node_handle_t node, uint8_t filte
519515
// FD targets don't support Dual filter
520516
ESP_RETURN_ON_FALSE(!mask_cfg->dual_filter, ESP_ERR_NOT_SUPPORTED, TAG, "The target don't support Dual Filter");
521517
#endif
522-
ESP_RETURN_ON_FALSE(atomic_load(&twai_ctx->state) == TWAI_ERROR_BUS_OFF, ESP_ERR_INVALID_STATE, TAG, "config filter must when node stopped");
518+
ESP_RETURN_ON_FALSE(atomic_load(&twai_ctx->state) == TWAI_ERROR_BUS_OFF, ESP_ERR_INVALID_STATE, TAG, "filter config must do when node stopped");
523519

524520
twai_hal_configure_filter(twai_ctx->hal, filter_id, mask_cfg);
525521
return ESP_OK;
@@ -532,7 +528,7 @@ static esp_err_t _node_config_range_filter(twai_node_handle_t node, uint8_t filt
532528
ESP_RETURN_ON_FALSE(filter_id < SOC_TWAI_RANGE_FILTER_NUM, ESP_ERR_INVALID_ARG, TAG, "Invalid range filter id %d", filter_id);
533529
ESP_RETURN_ON_FALSE((range_cfg->range_low > range_cfg->range_high) || range_cfg->is_ext || !(range_cfg->range_high & ~TWAI_STD_ID_MASK), \
534530
ESP_ERR_INVALID_ARG, TAG, "std_id only (is_ext=0) but valid low/high id larger than 11 bits");
535-
ESP_RETURN_ON_FALSE(atomic_load(&twai_ctx->state) == TWAI_ERROR_BUS_OFF, ESP_ERR_INVALID_STATE, TAG, "config filter must when node stopped");
531+
ESP_RETURN_ON_FALSE(atomic_load(&twai_ctx->state) == TWAI_ERROR_BUS_OFF, ESP_ERR_INVALID_STATE, TAG, "filter config must do when node stopped");
536532

537533
twai_hal_configure_range_filter(twai_ctx->hal, filter_id, range_cfg);
538534
return ESP_OK;
@@ -651,6 +647,13 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
651647
.enable_self_test = node_config->flags.enable_self_test,
652648
.enable_loopback = node_config->flags.enable_loopback,
653649
};
650+
#if CONFIG_IDF_TARGET_ESP32C5
651+
// ESP32C5 has a bug that the listen only mode don't work when there are other nodes sending ACK each other
652+
// See IDF-13059 for more details
653+
if (node_config->flags.enable_listen_only) {
654+
ESP_LOGW(TAG, "Listen only mode for ESP32C5 may not work properly when there are more than 2 nodes on the bus that are sending ACKs to each other");
655+
}
656+
#endif
654657
ESP_GOTO_ON_FALSE(twai_hal_init(node->hal, &hal_config), ESP_ERR_INVALID_STATE, err, TAG, "hardware not in reset state");
655658
// Configure bus timing
656659
ESP_GOTO_ON_ERROR(_node_calc_set_bit_timing(&node->api_base, node_config->clk_src, &node_config->bit_timing, &node_config->data_timing), err, TAG, "bitrate error");

components/hal/esp32c5/include/hal/twaifd_ll.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ static inline void twaifd_ll_set_mode(twaifd_dev_t *hw, bool listen_only, bool s
165165

166166
twaifd_mode_settings_reg_t opmode = {.val = hw->mode_settings.val};
167167
opmode.stm = self_test;
168-
(void)listen_only; // listen only is not available in this chip, see "CTU FD 2v5 errata 0v2 issue 5"
168+
opmode.bmm = listen_only;
169169
opmode.ilbp = loopback;
170170

171171
hw->mode_settings.val = opmode.val;

docs/en/api-reference/peripherals/twai.rst

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ Below are additional configuration fields of the :cpp:type:`twai_onchip_node_con
9090
- :cpp:member:`twai_onchip_node_config_t::flags::enable_listen_only`: Configures the node in listen-only mode. In this mode, the node only receives and does not transmit any dominant bits, including ACK and error frames.
9191
- :cpp:member:`twai_onchip_node_config_t::flags::no_receive_rtr`: When using filters, determines whether remote frames matching the ID pattern should be filtered out.
9292

93+
.. only:: esp32c5
94+
95+
.. note::
96+
97+
Note: The listen-only mode on ESP32C5 can't work properly when there are multiple nodes on the bus that are sending ACKs to each other. An alternative is to use transceiver which supports listen-only mode itself (e.g. TJA1145), and combine it with self-test mode enabled.
98+
9399
The :cpp:func:`twai_node_enable` function starts the TWAI controller. Once enabled, the controller is connected to the bus and can transmit messages. It also generates events upon receiving messages from other nodes on the bus or when bus errors are detected.
94100

95101
The corresponding function, :cpp:func:`twai_node_disable`, immediately stops the node and disconnects it from the bus. Any ongoing transmissions will be aborted. When the node is re-enabled later, if there are pending transmissions in the queue, the driver will immediately initiate a new transmission attempt.
@@ -202,7 +208,7 @@ The following code demonstrates how to configure a baud rate of 500 Kbit/s with
202208
.. code:: c
203209
204210
twai_timing_advanced_config_t timing_cfg = {
205-
.brp = 8, // Prescaler set to 8, time quantum = 80M / 8 = 10 MHz (1M Tq)
211+
.brp = 8, // Prescaler set to 8, time quantum = 80M / 8 = 10 MHz (10M Tq)
206212
.prop_seg = 10, // Propagation segment
207213
.tseg_1 = 4, // Phase segment 1
208214
.tseg_2 = 5, // Phase segment 2
@@ -254,7 +260,7 @@ The following code demonstrates how to calculate the MASK and configure a filter
254260
Dual Filter Mode
255261
""""""""""""""""
256262

257-
{IDF_TARGET_NAME} supports dual filter mode, which allows the hardware to be configured as two parallel independent 16-bit mask filters. By enabling this, more IDs can be received. Note that when filtering 29-bit extended IDs, each filter can only filter the upper 16 bits of the ID, while the remaining 13 bits are not filtered. The following code demonstrates how to configure dual filter mode using the function :cpp:func:`twai_make_dual_filter`:
263+
{IDF_TARGET_NAME} supports dual filter mode, which allows the hardware to be configured as two parallel independent 16-bit mask filters. By enabling this, more IDs can be received. Note that using dual filter mode to filter 29-bit extended IDs, each filter can only filter the upper 16 bits of the ID, while the remaining 13 bits are not filtered. The following code demonstrates how to configure dual filter mode using the function :cpp:func:`twai_make_dual_filter`:
258264

259265
.. code:: c
260266

docs/zh_CN/api-reference/peripherals/twai.rst

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ TWAI 是一种适用于汽车和工业应用的高可靠性的多主机实时串
9090
- :cpp:member:`twai_onchip_node_config_t::flags::enable_listen_only` 配置为监听模式,节点只接收,不发送任何显性位,包括 ACK 和错误帧。
9191
- :cpp:member:`twai_onchip_node_config_t::flags::no_receive_rtr` 使用过滤器时是否同时过滤掉符合 ID 规则的远程帧。
9292

93+
.. only:: esp32c5
94+
95+
.. note::
96+
97+
注意: ESP32C5 的监听模式在总线上有多个节点相互发送 ACK 信号时无法正常工作。一种替代方案是使用本身支持监听模式的收发器(例如 TJA1145),并结合启用自测模式。
98+
9399
函数 :cpp:func:`twai_node_enable` 将启动 TWAI 控制器,此时 TWAI 控制器就连接到了总线,可以向总线发送报文。如果收到了总线上其他节点发送的报文,或者检测到了总线错误,也将产生相应事件。
94100

95101
与之对应的函数是 :cpp:func:`twai_node_disable`,该函数将立即停止节点工作并与总线断开,正在进行的传输将被中止。当下次重新启动时,如果发送队列中有未完成的任务,驱动将立即发起新的传输。
@@ -202,7 +208,7 @@ TWAI 报文有多种类型,由报头指定。一个典型的数据帧报文主
202208
.. code:: c
203209
204210
twai_timing_advanced_config_t timing_cfg = {
205-
.brp = 8, // 预分频为 8,时间量子 80M/8=1M
211+
.brp = 8, // 预分频为 8,时间量子 80M/8=10M
206212
.prop_seg = 10,
207213
.tseg_1 = 4,
208214
.tseg_2 = 5,
@@ -227,7 +233,7 @@ TWAI 报文有多种类型,由报头指定。一个典型的数据帧报文主
227233

228234
TWAI 控制器硬件可以根据 ID 对报文进行过滤,从而减少软硬件开销使节点更加高效。过滤掉报文的节点 **不会接收到该报文,但仍会应答**。
229235

230-
{IDF_TARGET_NAME} 包含 {IDF_TARGET_CONFIG_SOC_TWAI_MASK_FILTER_NUM} 个掩码过滤器,报文通过任意一个过滤器即能收到改报文。典型的 TWAI 掩码过滤器通过 ID 和 MASK 配置,其中:
236+
{IDF_TARGET_NAME} 包含 {IDF_TARGET_CONFIG_SOC_TWAI_MASK_FILTER_NUM} 个掩码过滤器,报文通过任意一个过滤器即能收到该报文。典型的 TWAI 掩码过滤器通过 ID 和 MASK 配置,其中:
231237

232238
- ID 表示期望接收的报文的标准11位或扩展29位ID。
233239
- MASK 表示对ID的过滤规则:
@@ -254,7 +260,7 @@ TWAI 控制器硬件可以根据 ID 对报文进行过滤,从而减少软硬
254260
双过滤器模式
255261
""""""""""""
256262

257-
{IDF_TARGET_NAME} 支持双过滤器模式,可将硬件配置为并列的两个独立的 16 位掩码过滤器,支持接收更多 ID,但当配置为过滤 29 位扩展ID时,每个过滤器只能过滤其ID的高 16 位,剩余13位不做过滤。以下代码展示了如何借助 :cpp:func:`twai_make_dual_filter` 配置双过滤器模式。
263+
{IDF_TARGET_NAME} 支持双过滤器模式,可将硬件配置为并列的两个独立的 16 位掩码过滤器,支持接收更多 ID。但注意,使用双过滤器模式过滤 29 位扩展ID时,每个过滤器只能过滤其ID的高 16 位,剩余13位不做过滤。以下代码展示了如何借助 :cpp:func:`twai_make_dual_filter` 配置双过滤器模式。
258264

259265
.. code:: c
260266

0 commit comments

Comments
 (0)