1
6
7
12
13
14
16
17
18
19
20
25
26
27
28
29
30
31
32
33
34
35
60
61
64
65
66
67
68
73
74
83
84
87
88
91
92
93
94
95
96
97
98
99
100
109
112
113
114
115
116
117
118
119
120
121
124
125
126
127
130
131
136
137
142
143
144
145
146
147
148
149
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
173
174
175
176
177
178
179
180
181
192
193
194
201
202
/* ... */
#include <stddef.h>
#include <string.h>
#include "sdkconfig.h"
#include "esp_compiler.h"
#include "hal/twai_hal.h"5 includes
#ifdef CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT
#define TWAI_RX_FIFO_CORRUPT_THRESH 62/* ... */
#endif
/* ... */
static inline uint32_t twai_hal_decode_interrupt(twai_hal_context_t *hal_ctx)
{
uint32_t events = 0;
uint32_t interrupts = twai_ll_get_and_clear_intrs(hal_ctx->dev);
uint32_t status = twai_ll_get_status(hal_ctx->dev);
uint32_t tec = twai_ll_get_tec(hal_ctx->dev);
uint32_t rec = twai_ll_get_rec(hal_ctx->dev);
uint32_t state_flags = hal_ctx->state_flags;
if (interrupts & TWAI_LL_INTR_EI) {
if (status & TWAI_LL_STATUS_BS) {
if (status & TWAI_LL_STATUS_ES) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_BUS_OFF);
TWAI_HAL_SET_BITS(state_flags, TWAI_HAL_STATE_FLAG_BUS_OFF);
TWAI_HAL_CLEAR_BITS(state_flags, TWAI_HAL_STATE_FLAG_RUNNING | TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED);
}{...} else {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_BUS_RECOV_PROGRESS);
}{...}
}{...} else {
if (status & TWAI_LL_STATUS_ES) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_ABOVE_EWL);
TWAI_HAL_SET_BITS(state_flags, TWAI_HAL_STATE_FLAG_ERR_WARN);
}{...} else if (hal_ctx->state_flags & TWAI_HAL_STATE_FLAG_RECOVERING) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_BUS_RECOV_CPLT);
TWAI_HAL_CLEAR_BITS(state_flags, TWAI_HAL_STATE_FLAG_RECOVERING | TWAI_HAL_STATE_FLAG_BUS_OFF);
}{...} else {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_BELOW_EWL);
TWAI_HAL_CLEAR_BITS(state_flags, TWAI_HAL_STATE_FLAG_ERR_WARN);
}{...}
}{...}
}{...}
if (interrupts & TWAI_LL_INTR_RI) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_RX_BUFF_FRAME);
}{...}
#ifdef CONFIG_TWAI_ERRATA_FIX_TX_INTR_LOST
if ((interrupts & TWAI_LL_INTR_TI || hal_ctx->state_flags & TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED) && status & TWAI_LL_STATUS_TBS) {
#else
if (interrupts & TWAI_LL_INTR_TI) {
#endif
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_TX_BUFF_FREE);
TWAI_HAL_CLEAR_BITS(state_flags, TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED);
}{...}
if (interrupts & TWAI_LL_INTR_EPI) {
if (tec >= TWAI_ERR_PASS_THRESH || rec >= TWAI_ERR_PASS_THRESH) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_ERROR_PASSIVE);
TWAI_HAL_SET_BITS(state_flags, TWAI_HAL_STATE_FLAG_ERR_PASSIVE);
}{...} else {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_ERROR_ACTIVE);
TWAI_HAL_CLEAR_BITS(state_flags, TWAI_HAL_STATE_FLAG_ERR_PASSIVE);
}{...}
}{...}
if (interrupts & TWAI_LL_INTR_BEI) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_BUS_ERR);
}{...}
if (interrupts & TWAI_LL_INTR_ALI) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_ARB_LOST);
}{...}
hal_ctx->state_flags = state_flags;
return events;
}{ ... }
uint32_t twai_hal_get_events(twai_hal_context_t *hal_ctx)
{
uint32_t events = twai_hal_decode_interrupt(hal_ctx);
if (events & TWAI_HAL_EVENT_BUS_OFF) {
twai_ll_set_mode(hal_ctx->dev, TWAI_MODE_LISTEN_ONLY);
#ifdef CONFIG_TWAI_ERRATA_FIX_BUS_OFF_REC
twai_ll_set_tec(hal_ctx->dev, 0);
twai_ll_set_tec(hal_ctx->dev, 255);
(void) twai_ll_get_and_clear_intrs(hal_ctx->dev); /* ... */
#endif
}{...}
if (events & TWAI_HAL_EVENT_BUS_RECOV_CPLT) {
twai_ll_enter_reset_mode(hal_ctx->dev);
}{...}
if (events & TWAI_HAL_EVENT_BUS_ERR) {
#ifdef CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID
twai_ll_err_type_t type;
twai_ll_err_dir_t dir;
twai_ll_err_seg_t seg;
twai_ll_parse_err_code_cap(hal_ctx->dev, &type, &dir, &seg);
if (dir == TWAI_LL_ERR_DIR_RX &&
((seg == TWAI_LL_ERR_SEG_DATA || seg == TWAI_LL_ERR_SEG_CRC_SEQ) ||
(seg == TWAI_LL_ERR_SEG_ACK_DELIM && type == TWAI_LL_ERR_OTHER))) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_NEED_PERIPH_RESET);
}{...}
/* ... */#endif
twai_ll_clear_err_code_cap(hal_ctx->dev);
}{...}
if (events & TWAI_HAL_EVENT_ARB_LOST) {
twai_ll_clear_arb_lost_cap(hal_ctx->dev);
}{...}
#ifdef CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT
if (events & TWAI_HAL_EVENT_RX_BUFF_FRAME && twai_ll_get_rx_msg_count(hal_ctx->dev) >= TWAI_RX_FIFO_CORRUPT_THRESH) {
TWAI_HAL_SET_BITS(events, TWAI_HAL_EVENT_NEED_PERIPH_RESET);
}{...}
#endif/* ... */
#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || defined(CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT)
if (events & TWAI_HAL_EVENT_NEED_PERIPH_RESET) {
TWAI_HAL_CLEAR_BITS(events, (TWAI_HAL_EVENT_RX_BUFF_FRAME));
}{...}
#endif/* ... */
return events;
}{ ... }
#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || defined(CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT)
void twai_hal_prepare_for_reset(twai_hal_context_t *hal_ctx)
{
uint32_t status = twai_ll_get_status(hal_ctx->dev);
if (!(status & TWAI_LL_STATUS_TBS)) {
TWAI_HAL_SET_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_TX_NEED_RETRY);
}{...}
hal_ctx->rx_msg_cnt_save = (uint8_t) twai_ll_get_rx_msg_count(hal_ctx->dev);
twai_ll_enter_reset_mode(hal_ctx->dev);
twai_ll_save_reg(hal_ctx->dev, &hal_ctx->reg_save);
}{ ... }
void twai_hal_recover_from_reset(twai_hal_context_t *hal_ctx)
{
twai_ll_enter_reset_mode(hal_ctx->dev);
twai_ll_enable_extended_reg_layout(hal_ctx->dev);
twai_ll_restore_reg(hal_ctx->dev, &hal_ctx->reg_save);
twai_ll_exit_reset_mode(hal_ctx->dev);
(void) twai_ll_get_and_clear_intrs(hal_ctx->dev);
if (hal_ctx->state_flags & TWAI_HAL_STATE_FLAG_TX_NEED_RETRY) {
twai_hal_set_tx_buffer_and_transmit(hal_ctx, &hal_ctx->tx_frame_save);
TWAI_HAL_CLEAR_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_TX_NEED_RETRY);
}{...}
}{ ... }
#endif/* ... */
void twai_hal_set_tx_buffer_and_transmit(twai_hal_context_t *hal_ctx, twai_hal_frame_t *tx_frame)
{
twai_ll_set_tx_buffer(hal_ctx->dev, tx_frame);
if (tx_frame->self_reception) {
if (tx_frame->single_shot) {
twai_ll_set_cmd_self_rx_single_shot(hal_ctx->dev);
}{...} else {
twai_ll_set_cmd_self_rx_request(hal_ctx->dev);
}{...}
}{...} else if (tx_frame->single_shot){
twai_ll_set_cmd_tx_single_shot(hal_ctx->dev);
}{...} else {
twai_ll_set_cmd_tx(hal_ctx->dev);
}{...}
TWAI_HAL_SET_BITS(hal_ctx->state_flags, TWAI_HAL_STATE_FLAG_TX_BUFF_OCCUPIED);
#if defined(CONFIG_TWAI_ERRATA_FIX_RX_FRAME_INVALID) || defined(CONFIG_TWAI_ERRATA_FIX_RX_FIFO_CORRUPT)
if (&hal_ctx->tx_frame_save == tx_frame) {
return;
}{...}
ESP_COMPILER_DIAGNOSTIC_PUSH_IGNORE("-Wanalyzer-overlapping-buffers")
memcpy(&hal_ctx->tx_frame_save, tx_frame, sizeof(twai_hal_frame_t));
ESP_COMPILER_DIAGNOSTIC_POP("-Wanalyzer-overlapping-buffers")/* ... */
#endif
}{ ... }