Skip to content

Commit a490543

Browse files
committed
refactor(twai): adjust source file layout
1 parent 410e138 commit a490543

File tree

13 files changed

+175
-98
lines changed

13 files changed

+175
-98
lines changed

components/esp_driver_twai/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,7 @@ set(priv_req esp_driver_gpio esp_pm)
1010

1111
# Currently support only FD targets
1212
if(CONFIG_SOC_TWAI_SUPPORT_FD)
13-
list(APPEND srcs "onchip/esp_twai_onchip.c")
14-
list(APPEND public_include "onchip/include")
13+
list(APPEND srcs "esp_twai_onchip.c")
1514
endif()
1615

1716
idf_component_register(

components/esp_driver_twai/Kconfig

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ menu "ESP-Driver:TWAI Configurations"
33

44
config TWAI_ISR_INTO_IRAM
55
bool "Place TWAI ISR in IRAM to reduce latency"
6+
select TWAI_OBJ_CACHE_SAFE
67
default n
78
help
89
Place ISR functions to IRAM to increase performance
@@ -15,4 +16,21 @@ menu "ESP-Driver:TWAI Configurations"
1516
Allow TWAI works under Cache disabled, to enabled this config,
1617
all callbacks and user_ctx should also place in IRAM
1718

19+
config TWAI_OBJ_CACHE_SAFE
20+
bool
21+
default n
22+
help
23+
This will ensure the TWAI driver object will not be allocated from a memory region
24+
where its cache can be disabled.
25+
26+
config TWAI_ENABLE_DEBUG_LOG
27+
bool "Force enable debug log"
28+
default n
29+
help
30+
If enabled, TWAI driver component will:
31+
1. ignore the global logging settings
32+
2. compile all log messages into the binary
33+
3. set the runtime log level to VERBOSE
34+
Please enable this option by caution, as it will increase the binary size.
35+
1836
endmenu # TWAI Configuration

components/esp_driver_twai/esp_twai.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
#include <sys/param.h>
8-
#include "esp_check.h"
97
#include "esp_twai.h"
108
#include "esp_private/twai_interface.h"
11-
#include "esp_private/twai_priv.h"
12-
13-
static const char *TAG = "esp_twai";
9+
#include "esp_private/twai_utils.h"
10+
#include "twai_private.h"
1411

1512
/**
1613
* @brief Calculate twai timing param by giving bitrate and hardware limit.
@@ -44,7 +41,7 @@ uint32_t twai_node_timing_calc_param(const uint32_t source_freq, const twai_timi
4441
}
4542

4643
uint16_t default_point = (in_param->bitrate >= 800000) ? 750 : ((in_param->bitrate >= 500000) ? 800 : 875);
47-
uint16_t sample_point = in_param->sample_point ? in_param->sample_point : default_point; // default sample point based on bitrate if not configured
44+
uint16_t sample_point = in_param->sp_permill ? in_param->sp_permill : default_point; // default sample point based on bitrate if not configured
4845
uint16_t tseg_1 = (tseg * sample_point) / 1000;
4946
tseg_1 = MAX(hw_limit->tseg1_min, MIN(tseg_1, hw_limit->tseg1_max));
5047
uint16_t tseg_2 = tseg - tseg_1 - 1;
@@ -107,9 +104,9 @@ esp_err_t twai_node_config_range_filter(twai_node_handle_t node, uint8_t filter_
107104
esp_err_t twai_node_reconfig_timing(twai_node_handle_t node, const twai_timing_advanced_config_t *bit_timing, const twai_timing_advanced_config_t *data_timing)
108105
{
109106
ESP_RETURN_ON_FALSE(node && (bit_timing || data_timing), ESP_ERR_INVALID_ARG, TAG, "invalid argument: null");
110-
ESP_RETURN_ON_FALSE(node->timing_reconfig, ESP_ERR_NOT_SUPPORTED, TAG, "timing_reconfig func null");
107+
ESP_RETURN_ON_FALSE(node->reconfig_timing, ESP_ERR_NOT_SUPPORTED, TAG, "reconfig_timing func null");
111108

112-
return node->timing_reconfig(node, bit_timing, data_timing);
109+
return node->reconfig_timing(node, bit_timing, data_timing);
113110
}
114111

115112
esp_err_t twai_node_register_event_callbacks(twai_node_handle_t node, const twai_event_callbacks_t *cbs, void *user_data)
@@ -151,3 +148,11 @@ esp_err_t twai_node_receive_from_isr(twai_node_handle_t node, twai_frame_header_
151148

152149
return node->receive_isr(node, header, rx_buffer, buf_sz, received_len);
153150
}
151+
152+
#if CONFIG_TWAI_ENABLE_DEBUG_LOG
153+
__attribute__((constructor))
154+
static void twai_override_default_log_level(void)
155+
{
156+
esp_log_level_set(TAG, ESP_LOG_VERBOSE);
157+
}
158+
#endif

components/esp_driver_twai/onchip/esp_twai_onchip.c renamed to components/esp_driver_twai/esp_twai_onchip.c

Lines changed: 52 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -4,33 +4,11 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
#include <stdatomic.h>
8-
#include <stdint.h>
9-
#include "soc/soc_caps.h"
10-
#include "soc/twai_periph.h"
11-
#include "soc/io_mux_reg.h"
12-
#include "hal/twai_hal.h"
13-
#include "freertos/FreeRTOS.h"
14-
#include "esp_check.h"
15-
#include "esp_pm.h"
16-
#include "esp_heap_caps.h"
17-
#include "esp_intr_alloc.h"
18-
#include "esp_clk_tree.h"
197
#include "esp_twai.h"
208
#include "esp_twai_onchip.h"
219
#include "esp_private/twai_interface.h"
22-
#include "esp_private/twai_priv.h"
23-
#include "esp_private/gpio.h"
24-
#include "esp_private/esp_gpio_reserve.h"
25-
#include "esp_private/periph_ctrl.h"
26-
27-
static const char *TAG = "twai";
28-
29-
#ifdef CONFIG_TWAI_ISR_INTO_IRAM
30-
#define TWAI_MALLOC_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT)
31-
#else
32-
#define TWAI_MALLOC_CAPS MALLOC_CAP_DEFAULT
33-
#endif //CONFIG_TWAI_ISR_INTO_IRAM
10+
#include "esp_private/twai_utils.h"
11+
#include "twai_private.h"
3412

3513
#if !SOC_RCC_IS_INDEPENDENT
3614
#define TWAI_RCC_ATOMIC() PERIPH_RCC_ATOMIC()
@@ -203,10 +181,10 @@ static void _node_isr_main(void *arg)
203181
if (int_stat & (TWAIFD_LL_INTR_BUS_ERR | TWAIFD_LL_INTR_ARBI_LOST)) {
204182
uint32_t err_reason = twaifd_ll_get_err_reason_code(twai_ctx->hal.dev);
205183
twai_error_event_data_t e_data = {0};
206-
e_data.err_type.arb_lost = !!(int_stat & TWAIFD_LL_INTR_ARBI_LOST);
207-
e_data.err_type.bit_err = (err_reason == TWAIFD_LL_ERR_BIT_ERR);
208-
e_data.err_type.form_err = (err_reason == TWAIFD_LL_ERR_FRM_ERR);
209-
e_data.err_type.stuff_err = (err_reason == TWAIFD_LL_ERR_STUF_ERR);
184+
e_data.err_code.arb_lost = !!(int_stat & TWAIFD_LL_INTR_ARBI_LOST);
185+
e_data.err_code.bit_err = (err_reason == TWAIFD_LL_ERR_BIT_ERR);
186+
e_data.err_code.form_err = (err_reason == TWAIFD_LL_ERR_FRM_ERR);
187+
e_data.err_code.stuff_err = (err_reason == TWAIFD_LL_ERR_STUF_ERR);
210188

211189
twai_ctx->history.bus_err_num ++;
212190
if (twai_ctx->cbs.on_error) {
@@ -233,7 +211,7 @@ static void _node_isr_main(void *arg)
233211
// only call tx_done_cb when tx without error, otherwise on_error_cb should triggered if it is registered
234212
if (twai_ctx->cbs.on_tx_done && (int_stat & TWAIFD_LL_INTR_TX_DONE)) {
235213
twai_tx_done_event_data_t tx_ev = {
236-
.done_trans_tx = (twai_frame_t *)twai_ctx->p_curr_tx,
214+
.done_tx_frame = twai_ctx->p_curr_tx,
237215
};
238216
do_yield |= twai_ctx->cbs.on_tx_done(&twai_ctx->api_base, &tx_ev, twai_ctx->user_data);
239217
}
@@ -268,22 +246,31 @@ static void _node_isr_main(void *arg)
268246
}
269247
}
270248

249+
static void _node_destroy(twai_onchip_ctx_t *twai_ctx)
250+
{
251+
if (twai_ctx->pm_lock) {
252+
esp_pm_lock_delete(twai_ctx->pm_lock);
253+
}
254+
if (twai_ctx->intr_hdl) {
255+
esp_intr_free(twai_ctx->intr_hdl);
256+
}
257+
if (twai_ctx->tx_mount_queue) {
258+
vQueueDeleteWithCaps(twai_ctx->tx_mount_queue);
259+
}
260+
if (twai_ctx->ctrlr_id != -1) {
261+
_ctrlr_release(twai_ctx->ctrlr_id);
262+
}
263+
free(twai_ctx);
264+
}
265+
271266
static esp_err_t _node_delete(twai_node_handle_t node)
272267
{
273268
twai_onchip_ctx_t *twai_ctx = __containerof(node, twai_onchip_ctx_t, api_base);
274269
ESP_RETURN_ON_FALSE(atomic_load(&twai_ctx->state) == TWAI_ERROR_BUS_OFF, ESP_ERR_INVALID_STATE, TAG, "delete node must when node stopped");
275270

276271
_node_release_io(twai_ctx);
277-
_ctrlr_release(twai_ctx->ctrlr_id);
278272
_twai_rcc_clock_ctrl(twai_ctx->ctrlr_id, false);
279-
#if CONFIG_PM_ENABLE
280-
if (twai_ctx->pm_lock) {
281-
ESP_RETURN_ON_ERROR(esp_pm_lock_delete(twai_ctx->pm_lock), TAG, "delete power manager failed");
282-
}
283-
#endif //CONFIG_PM_ENABLE
284-
esp_intr_free(twai_ctx->intr_hdl);
285-
vQueueDeleteWithCaps(twai_ctx->tx_mount_queue);
286-
free(twai_ctx);
273+
_node_destroy(twai_ctx);
287274
return ESP_OK;
288275
}
289276

@@ -339,16 +326,18 @@ static esp_err_t _node_set_bit_timing(twai_node_handle_t node, const twai_timing
339326
if (timing) {
340327
twaifd_ll_set_nominal_bitrate(twai_ctx->hal.dev, timing);
341328
if (timing->ssp_offset) {
342-
ssp_offset = timing->ssp_offset;
329+
// the underlying hardware calculates the ssp in system clock cycles, not in quanta time
330+
ssp_offset = timing->ssp_offset * timing->brp;
343331
}
344332
}
345333
#if SOC_TWAI_SUPPORT_FD
346334
if (timing_fd) {
347335
twai_ctx->valid_fd_timing = true;
348336
twaifd_ll_set_fd_bitrate(twai_ctx->hal.dev, timing_fd);
337+
// Note, the ssp_offset set for the data phase can override the nominal phase, because ssp is more necessary for a high bitrate communication
349338
if (timing_fd->ssp_offset) {
350-
// prefer to config ssp by fd param
351-
ssp_offset = timing_fd->ssp_offset;
339+
// the underlying hardware calculates the ssp in system clock cycles, not in quanta time
340+
ssp_offset = timing_fd->ssp_offset * timing_fd->brp;
352341
}
353342
}
354343
#endif
@@ -475,12 +464,10 @@ static esp_err_t _node_config_range_filter(twai_node_handle_t node, uint8_t filt
475464
ESP_RETURN_ON_FALSE(filter_id < SOC_TWAI_RANGE_FILTER_NUM, ESP_ERR_INVALID_ARG, TAG, "Invalid range filter id %d", filter_id);
476465
ESP_RETURN_ON_FALSE(atomic_load(&twai_ctx->state) == TWAI_ERROR_BUS_OFF, ESP_ERR_INVALID_STATE, TAG, "config filter must when node stopped");
477466

478-
bool full_open = (range_cfg->range_high == 0) && (range_cfg->range_low == 0);
479-
bool full_close = (range_cfg->range_high == UINT32_MAX) && (range_cfg->range_low == UINT32_MAX);
480-
bool cc_ext = full_open || (!full_close && range_cfg->is_ext && !range_cfg->no_classic);
481-
bool fd_ext = full_open || (!full_close && range_cfg->is_ext && !range_cfg->no_fd);
482-
bool cc_std = full_open || (!full_close && !range_cfg->is_ext && !range_cfg->no_classic);
483-
bool fd_std = full_open || (!full_close && !range_cfg->is_ext && !range_cfg->no_fd);
467+
bool cc_ext = range_cfg->is_ext && !range_cfg->no_classic;
468+
bool fd_ext = range_cfg->is_ext && !range_cfg->no_fd;
469+
bool cc_std = !range_cfg->is_ext && !range_cfg->no_classic;
470+
bool fd_std = !range_cfg->is_ext && !range_cfg->no_fd;
484471
twaifd_ll_filter_enable_basic_ext(twai_ctx->hal.dev, filter_id, true, cc_ext);
485472
twaifd_ll_filter_enable_fd_ext(twai_ctx->hal.dev, filter_id, true, fd_ext);
486473
twaifd_ll_filter_enable_basic_std(twai_ctx->hal.dev, filter_id, true, cc_std);
@@ -575,21 +562,24 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
575562
// Allocate TWAI node object memory
576563
twai_onchip_ctx_t *node = heap_caps_calloc(1, sizeof(twai_onchip_ctx_t), TWAI_MALLOC_CAPS);
577564
ESP_RETURN_ON_FALSE(node, ESP_ERR_NO_MEM, TAG, "No mem");
565+
node->ctrlr_id = -1;
578566
// Acquire controller
579567
int ctrlr_id = _ctrlr_acquire(node);
580-
ESP_GOTO_ON_FALSE(ctrlr_id != -1, ESP_ERR_NOT_FOUND, ctrlr_err, TAG, "Controller not available");
568+
ESP_GOTO_ON_FALSE(ctrlr_id != -1, ESP_ERR_NOT_FOUND, err, TAG, "Controller not available");
581569
node->ctrlr_id = ctrlr_id;
582570

583571
// state is in bus_off before enabled
584572
atomic_store(&node->state, TWAI_ERROR_BUS_OFF);
585573
node->tx_mount_queue = xQueueCreateWithCaps(node_config->tx_queue_depth, sizeof(twai_frame_t *), TWAI_MALLOC_CAPS);
586-
ESP_GOTO_ON_FALSE(node->tx_mount_queue, ESP_ERR_NO_MEM, create_err, TAG, "no_mem");
587-
uint32_t intr_flags = node_config->intr_priority ? BIT(node_config->intr_priority) | ESP_INTR_FLAG_INTRDISABLED : ESP_INTR_FLAG_LOWMED | ESP_INTR_FLAG_INTRDISABLED;
588-
#if CONFIG_TWAI_ISR_CACHE_SAFE
589-
intr_flags |= ESP_INTR_FLAG_IRAM;
590-
#endif
574+
ESP_GOTO_ON_FALSE(node->tx_mount_queue, ESP_ERR_NO_MEM, err, TAG, "no_mem");
575+
uint32_t intr_flags = TWAI_INTR_ALLOC_FLAGS;
576+
if (node_config->intr_priority > 0) {
577+
intr_flags |= BIT(node_config->intr_priority);
578+
} else {
579+
intr_flags |= ESP_INTR_FLAG_LOWMED;
580+
}
591581
ESP_GOTO_ON_ERROR(esp_intr_alloc(twai_controller_periph_signals.controllers[ctrlr_id].irq_id, intr_flags, _node_isr_main, (void *)node, &node->intr_hdl),
592-
create_err, TAG, "Alloc interrupt failed");
582+
err, TAG, "Alloc interrupt failed");
593583

594584
// Enable bus clock and reset controller
595585
_twai_rcc_clock_ctrl(ctrlr_id, true);
@@ -599,20 +589,20 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
599589
.intr_mask = DRIVER_DEFAULT_INTERRUPTS,
600590
.enable_listen_only = node_config->flags.enable_listen_only,
601591
};
602-
ESP_GOTO_ON_FALSE(twai_hal_init(&node->hal, &hal_config), ESP_ERR_INVALID_STATE, config_err, TAG, "hardware not in reset state");
592+
ESP_GOTO_ON_FALSE(twai_hal_init(&node->hal, &hal_config), ESP_ERR_INVALID_STATE, err, TAG, "hardware not in reset state");
603593
twaifd_ll_set_mode(node->hal.dev, node_config->flags.enable_listen_only, node_config->flags.enable_self_test, node_config->flags.enable_loopback);
604594
twaifd_ll_set_tx_retrans_limit(node->hal.dev, node_config->fail_retry_cnt);
605595
twaifd_ll_filter_block_rtr(node->hal.dev, node_config->flags.no_receive_rtr);
606596
twaifd_ll_enable_filter_mode(node->hal.dev, true); // each filter still has independent enable control
607597
twaifd_ll_enable_fd_mode(node->hal.dev, true); // fd frame still controlled by `header.fdf`
608598

609599
// Configure bus timing
610-
ESP_GOTO_ON_ERROR(_node_calc_set_bit_timing(&node->api_base, node_config->clk_src, &node_config->bit_timing, &node_config->data_timing), config_err, TAG, "bitrate error");
600+
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");
611601

612602
// Configure GPIO
613-
ESP_GOTO_ON_ERROR(_node_config_io(node, node_config), config_err, TAG, "gpio config failed");
603+
ESP_GOTO_ON_ERROR(_node_config_io(node, node_config), err, TAG, "gpio config failed");
614604
#if CONFIG_PM_ENABLE
615-
ESP_GOTO_ON_ERROR(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, twai_controller_periph_signals.controllers[ctrlr_id].module_name, &node->pm_lock), config_err, TAG, "init power manager failed");
605+
ESP_GOTO_ON_ERROR(esp_pm_lock_create(ESP_PM_NO_LIGHT_SLEEP, 0, twai_controller_periph_signals.controllers[ctrlr_id].module_name, &node->pm_lock), err, TAG, "init power manager failed");
616606
#endif //CONFIG_PM_ENABLE
617607

618608
node->api_base.enable = _node_enable;
@@ -621,7 +611,7 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
621611
node->api_base.recover = _node_recover;
622612
node->api_base.config_mask_filter = _node_config_mask_filter;
623613
node->api_base.config_range_filter = _node_config_range_filter;
624-
node->api_base.timing_reconfig = _node_set_bit_timing;
614+
node->api_base.reconfig_timing = _node_set_bit_timing;
625615
node->api_base.register_cbs = _node_register_callbacks;
626616
node->api_base.transmit = _node_queue_tx;
627617
node->api_base.receive_isr = _node_parse_rx;
@@ -630,16 +620,9 @@ esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twa
630620
*node_ret = &node->api_base;
631621
return ESP_OK;
632622

633-
config_err:
634-
if (node->intr_hdl) {
635-
esp_intr_free(node->intr_hdl);
636-
}
637-
if (node->tx_mount_queue) {
638-
vQueueDeleteWithCaps(node->tx_mount_queue);
623+
err:
624+
if (node) {
625+
_node_destroy(node);
639626
}
640-
create_err:
641-
_ctrlr_release(ctrlr_id);
642-
ctrlr_err:
643-
free(node);
644627
return ret;
645628
}

components/esp_driver_twai/include/esp_private/twai_interface.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ struct twai_node_base {
7777
* - ESP_OK: Success
7878
* - ESP_ERR_INVALID_ARG: Invalid timing configuration
7979
*/
80-
esp_err_t (*timing_reconfig)(struct twai_node_base *node, const twai_timing_advanced_config_t *bit_timing, const twai_timing_advanced_config_t *data_timing);
80+
esp_err_t (*reconfig_timing)(struct twai_node_base *node, const twai_timing_advanced_config_t *bit_timing, const twai_timing_advanced_config_t *data_timing);
8181

8282
/**
8383
* @brief Transmit a TWAI frame through the TWAI node

components/esp_driver_twai/include/esp_twai.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ esp_err_t twai_node_register_event_callbacks(twai_node_handle_t node, const twai
6060
/**
6161
* @brief Reconfigure the timing settings of the TWAI node
6262
*
63+
* @note You can reconfigure the timing for the arbitration and data phase, separately or together.
64+
*
6365
* @param node Handle to the TWAI node
6466
* @param bit_timing Optional,pointer to new twai cc(classic) or arbitration phase of twai fd timing configuration
6567
* @param data_timing Optional, pointer to new twai fd timing configuration
@@ -110,7 +112,9 @@ esp_err_t twai_node_get_info(twai_node_handle_t node, twai_node_status_t *status
110112
esp_err_t twai_node_transmit(twai_node_handle_t node, const twai_frame_t *frame, int timeout_ms);
111113

112114
/**
113-
* @brief Receive a TWAI frame from 'rx_done_cb' (ONLY FROM 'rx_done_cb')
115+
* @brief Receive a TWAI frame from 'rx_done_cb'
116+
*
117+
* @note This function can only be called from the `rx_done_cb` callback, you can't call it from a task.
114118
*
115119
* @param[in] node Handle to the TWAI node
116120
* @param[out] header Where to store frame header

components/esp_driver_twai/include/esp_twai_types.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ typedef struct twai_node_base *twai_node_handle_t;
2121
* @brief TWAI bitrate timing config basic (simple) mode
2222
*/
2323
typedef struct {
24-
uint32_t bitrate; /**< Expected TWAI bus baud_rate/bitrate in bits/second */
25-
uint16_t sample_point; /**< Optional, sampling point in permill (1/1000) of the entire bit time */
26-
uint16_t ssp_permill; /**< Optional, secondary sample point(ssp) in permill (1/1000) of the entire bit time */
24+
uint32_t bitrate; /**< Expected TWAI bus baud_rate/bitrate in bits/second */
25+
uint16_t sp_permill; /**< Optional, sampling point in permill (1/1000) of the entire bit time */
26+
uint16_t ssp_permill; /**< Optional, secondary sample point(ssp) in permill (1/1000) of the entire bit time */
2727
} twai_timing_basic_config_t;
2828

2929
/**
@@ -52,8 +52,6 @@ typedef struct {
5252

5353
/**
5454
* @brief Range-based filter configuration structure
55-
*
56-
* @note Set both range_low and range_high to `0` to receive ALL frames, both `0xFFFFFFFF` to receive NONE frames
5755
*/
5856
typedef struct {
5957
uint32_t range_low; /**< Lower bound of the filtering range */
@@ -87,7 +85,7 @@ typedef struct {
8785
* @brief TWAI "TX done" event data
8886
*/
8987
typedef struct {
90-
twai_frame_t *done_trans_tx;
88+
const twai_frame_t *done_tx_frame; /**< Pointer to the frame that has been transmitted */
9189
} twai_tx_done_event_data_t;
9290

9391
/**
@@ -122,7 +120,7 @@ typedef union {
122120
* @brief TWAI "error" event data
123121
*/
124122
typedef struct {
125-
twai_error_code_t err_type;
123+
twai_error_code_t err_code; /**< Error code indicating the type of the error */
126124
} twai_error_event_data_t;
127125

128126
/**

components/esp_driver_twai/test_apps/twaifd_test/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,8 @@ set(COMPONENTS main)
66

77
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
88
project(twaifd_test)
9+
10+
message(STATUS "Checking TWAI registers are not read-write by half-word")
11+
include($ENV{IDF_PATH}/tools/ci/check_register_rw_half_word.cmake)
12+
check_register_rw_half_word(SOC_MODULES "twai*" "pcr" "hp_sys_clkrst"
13+
HAL_MODULES "twai*")

0 commit comments

Comments
 (0)