mirror of
https://github.com/espressif/esp-idf.git
synced 2025-10-02 10:00:57 +02:00
fix(driver_twai): fixed tec_rec empty from get_info
Closes https://github.com/espressif/esp-idf/issues/17434
This commit is contained in:
@@ -79,8 +79,6 @@ typedef struct {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
_Atomic twai_error_state_t state;
|
_Atomic twai_error_state_t state;
|
||||||
uint16_t tx_error_count;
|
|
||||||
uint16_t rx_error_count;
|
|
||||||
twai_node_record_t history;
|
twai_node_record_t history;
|
||||||
|
|
||||||
atomic_bool hw_busy;
|
atomic_bool hw_busy;
|
||||||
@@ -127,8 +125,8 @@ static esp_err_t _node_config_io(twai_onchip_ctx_t *node, const twai_onchip_node
|
|||||||
{
|
{
|
||||||
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.tx) || (node_config->flags.enable_listen_only && (node_config->io_cfg.tx == -1)), ESP_ERR_INVALID_ARG, TAG, "Invalid tx gpio num");
|
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.tx) || (node_config->flags.enable_listen_only && (node_config->io_cfg.tx == -1)), ESP_ERR_INVALID_ARG, TAG, "Invalid tx gpio num");
|
||||||
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(node_config->io_cfg.rx), ESP_ERR_INVALID_ARG, TAG, "Invalid rx gpio num");
|
ESP_RETURN_ON_FALSE(GPIO_IS_VALID_GPIO(node_config->io_cfg.rx), ESP_ERR_INVALID_ARG, TAG, "Invalid rx gpio num");
|
||||||
ESP_RETURN_ON_FALSE(!(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.quanta_clk_out) && (twai_periph_signals[node->ctrlr_id].clk_out_sig < 0)), ESP_ERR_NOT_SUPPORTED, TAG, "quanta_clk_out is not supported");
|
ESP_RETURN_ON_FALSE(!(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.quanta_clk_out) && (twai_periph_signals[node->ctrlr_id].clk_out_sig < 0)), ESP_ERR_NOT_SUPPORTED, TAG, "quanta_clk_out gpio is not supported");
|
||||||
ESP_RETURN_ON_FALSE(!(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.bus_off_indicator) && (twai_periph_signals[node->ctrlr_id].bus_off_sig < 0)), ESP_ERR_NOT_SUPPORTED, TAG, "bus_off_indicator is not supported");
|
ESP_RETURN_ON_FALSE(!(GPIO_IS_VALID_OUTPUT_GPIO(node_config->io_cfg.bus_off_indicator) && (twai_periph_signals[node->ctrlr_id].bus_off_sig < 0)), ESP_ERR_NOT_SUPPORTED, TAG, "bus_off_indicator gpio is not supported");
|
||||||
|
|
||||||
uint64_t reserve_mask = 0;
|
uint64_t reserve_mask = 0;
|
||||||
// Set RX pin
|
// Set RX pin
|
||||||
@@ -569,8 +567,8 @@ static esp_err_t _node_get_status(twai_node_handle_t node, twai_node_status_t *s
|
|||||||
|
|
||||||
if (status_ret) {
|
if (status_ret) {
|
||||||
status_ret->state = atomic_load(&twai_ctx->state);
|
status_ret->state = atomic_load(&twai_ctx->state);
|
||||||
status_ret->tx_error_count = twai_ctx->tx_error_count;
|
status_ret->tx_error_count = twai_hal_get_tec(twai_ctx->hal);
|
||||||
status_ret->rx_error_count = twai_ctx->rx_error_count;
|
status_ret->rx_error_count = twai_hal_get_rec(twai_ctx->hal);
|
||||||
}
|
}
|
||||||
if (record_ret) {
|
if (record_ret) {
|
||||||
*record_ret = twai_ctx->history;
|
*record_ret = twai_ctx->history;
|
||||||
|
@@ -515,7 +515,7 @@ TEST_CASE("twai bus off recovery (loopback)", "[twai]")
|
|||||||
|
|
||||||
// send frames and trigger error, must become bus off before 50 frames
|
// send frames and trigger error, must become bus off before 50 frames
|
||||||
while ((node_status.state != TWAI_ERROR_BUS_OFF) && (tx_frame.header.id < 50)) {
|
while ((node_status.state != TWAI_ERROR_BUS_OFF) && (tx_frame.header.id < 50)) {
|
||||||
printf("sending frame %ld\n", tx_frame.header.id ++);
|
printf("sending frame %ld last tec %d rec %d\n", tx_frame.header.id ++, node_status.tx_error_count, node_status.rx_error_count);
|
||||||
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame, 500));
|
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame, 500));
|
||||||
if (tx_frame.header.id > 3) { // trigger error after 3 frames
|
if (tx_frame.header.id > 3) { // trigger error after 3 frames
|
||||||
printf("trigger bit_error now!\n");
|
printf("trigger bit_error now!\n");
|
||||||
@@ -529,6 +529,11 @@ TEST_CASE("twai bus off recovery (loopback)", "[twai]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
// recover node
|
// recover node
|
||||||
|
#if SOC_TWAI_SUPPORT_FD
|
||||||
|
TEST_ASSERT_GREATER_THAN(200, node_status.tx_error_count);
|
||||||
|
#else
|
||||||
|
TEST_ASSERT_EQUAL(128, node_status.tx_error_count); // TEC become 128 when bus off on legacy chips
|
||||||
|
#endif
|
||||||
TEST_ASSERT_EQUAL(TWAI_ERROR_BUS_OFF, node_status.state);
|
TEST_ASSERT_EQUAL(TWAI_ERROR_BUS_OFF, node_status.state);
|
||||||
printf("node offline, start recover ...\n");
|
printf("node offline, start recover ...\n");
|
||||||
TEST_ESP_OK(twai_node_recover(node_hdl));
|
TEST_ESP_OK(twai_node_recover(node_hdl));
|
||||||
@@ -539,7 +544,8 @@ TEST_CASE("twai bus off recovery (loopback)", "[twai]")
|
|||||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||||
twai_node_get_info(node_hdl, &node_status, NULL);
|
twai_node_get_info(node_hdl, &node_status, NULL);
|
||||||
}
|
}
|
||||||
printf("node recovered! continue\n");
|
printf("node recovered! current tec %d rec %d, continue\n", node_status.tx_error_count, node_status.rx_error_count);
|
||||||
|
TEST_ASSERT_LESS_THAN(96, node_status.tx_error_count);
|
||||||
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame, 500));
|
TEST_ESP_OK(twai_node_transmit(node_hdl, &tx_frame, 500));
|
||||||
|
|
||||||
TEST_ESP_OK(twai_node_disable(node_hdl));
|
TEST_ESP_OK(twai_node_disable(node_hdl));
|
||||||
@@ -597,25 +603,25 @@ TEST_CASE("twai tx_wait_all_done thread safe", "[twai]")
|
|||||||
// Test data for ISR send functionality
|
// Test data for ISR send functionality
|
||||||
typedef struct {
|
typedef struct {
|
||||||
twai_node_handle_t node;
|
twai_node_handle_t node;
|
||||||
uint32_t rx_count;
|
uint8_t rx_count;
|
||||||
uint32_t tx_isr_send_count;
|
uint8_t tx_isr_send_count;
|
||||||
uint32_t rx_isr_send_count;
|
uint8_t rx_isr_send_count;
|
||||||
|
twai_frame_t tx_isr_frame;
|
||||||
|
twai_frame_t rx_isr_frame;
|
||||||
bool test_completed;
|
bool test_completed;
|
||||||
} isr_send_test_ctx_t;
|
} isr_send_test_ctx_t;
|
||||||
|
|
||||||
static IRAM_ATTR bool test_tx_isr_send_cb(twai_node_handle_t handle, const twai_tx_done_event_data_t *edata, void *user_ctx)
|
static IRAM_ATTR bool test_tx_isr_send_cb(twai_node_handle_t handle, const twai_tx_done_event_data_t *edata, void *user_ctx)
|
||||||
{
|
{
|
||||||
isr_send_test_ctx_t *ctx = (isr_send_test_ctx_t *)user_ctx;
|
isr_send_test_ctx_t *ctx = (isr_send_test_ctx_t *)user_ctx;
|
||||||
|
twai_frame_t *isr_frame = &ctx->tx_isr_frame;
|
||||||
|
|
||||||
// Test sending from TX ISR context
|
// Test sending from TX ISR context
|
||||||
if (ctx->tx_isr_send_count < 3) {
|
if (ctx->tx_isr_send_count < 3) {
|
||||||
static twai_frame_t isr_frame = {};
|
isr_frame->header.id = 0x200 + ctx->tx_isr_send_count;
|
||||||
isr_frame.header.id = 0x200 + ctx->tx_isr_send_count;
|
isr_frame->header.dlc = 1;
|
||||||
isr_frame.header.dlc = 1;
|
|
||||||
isr_frame.buffer = (uint8_t*)(&ctx->tx_isr_send_count);
|
|
||||||
isr_frame.buffer_len = 1;
|
|
||||||
|
|
||||||
esp_err_t err = twai_node_transmit(handle, &isr_frame, 0); // timeout must be 0 in ISR
|
esp_err_t err = twai_node_transmit(handle, isr_frame, 0); // timeout must be 0 in ISR
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
ctx->tx_isr_send_count++;
|
ctx->tx_isr_send_count++;
|
||||||
}
|
}
|
||||||
@@ -627,23 +633,17 @@ static IRAM_ATTR bool test_tx_isr_send_cb(twai_node_handle_t handle, const twai_
|
|||||||
static IRAM_ATTR bool test_rx_isr_send_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
|
static IRAM_ATTR bool test_rx_isr_send_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
|
||||||
{
|
{
|
||||||
isr_send_test_ctx_t *ctx = (isr_send_test_ctx_t *)user_ctx;
|
isr_send_test_ctx_t *ctx = (isr_send_test_ctx_t *)user_ctx;
|
||||||
twai_frame_t rx_frame = {};
|
twai_frame_t *rx_frame = &ctx->rx_isr_frame;
|
||||||
uint8_t buffer[8];
|
|
||||||
rx_frame.buffer = buffer;
|
|
||||||
rx_frame.buffer_len = sizeof(buffer);
|
|
||||||
|
|
||||||
if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
|
if (ESP_OK == twai_node_receive_from_isr(handle, rx_frame)) {
|
||||||
ctx->rx_count++;
|
ctx->rx_count++;
|
||||||
|
|
||||||
// Test sending from RX ISR context (response pattern)
|
// Test sending from RX ISR context (response pattern)
|
||||||
if ((rx_frame.header.id >= 0x100) && (rx_frame.header.id < 0x103) && (ctx->rx_isr_send_count < 3)) {
|
if ((rx_frame->header.id >= 0x100) && (rx_frame->header.id < 0x103) && (ctx->rx_isr_send_count < 3)) {
|
||||||
static twai_frame_t response_frame = {};
|
rx_frame->header.id = 0x300 + ctx->rx_isr_send_count;
|
||||||
response_frame.header.id = 0x300 + ctx->rx_isr_send_count;
|
rx_frame->header.dlc = 1;
|
||||||
response_frame.header.dlc = 1;
|
|
||||||
response_frame.buffer = (uint8_t*)(&ctx->rx_isr_send_count);
|
|
||||||
response_frame.buffer_len = 1;
|
|
||||||
|
|
||||||
esp_err_t err = twai_node_transmit(handle, &response_frame, 0); // timeout must be 0 in ISR
|
esp_err_t err = twai_node_transmit(handle, rx_frame, 0); // timeout must be 0 in ISR
|
||||||
if (err == ESP_OK) {
|
if (err == ESP_OK) {
|
||||||
ctx->rx_isr_send_count++;
|
ctx->rx_isr_send_count++;
|
||||||
}
|
}
|
||||||
@@ -660,6 +660,8 @@ static IRAM_ATTR bool test_rx_isr_send_cb(twai_node_handle_t handle, const twai_
|
|||||||
TEST_CASE("twai send from ISR context (loopback)", "[twai]")
|
TEST_CASE("twai send from ISR context (loopback)", "[twai]")
|
||||||
{
|
{
|
||||||
isr_send_test_ctx_t test_ctx = {};
|
isr_send_test_ctx_t test_ctx = {};
|
||||||
|
test_ctx.tx_isr_frame.buffer = &test_ctx.tx_isr_send_count;
|
||||||
|
test_ctx.rx_isr_frame.buffer = &test_ctx.rx_isr_send_count;
|
||||||
|
|
||||||
twai_onchip_node_config_t node_config = {};
|
twai_onchip_node_config_t node_config = {};
|
||||||
node_config.io_cfg.tx = TEST_TX_GPIO;
|
node_config.io_cfg.tx = TEST_TX_GPIO;
|
||||||
@@ -702,9 +704,9 @@ TEST_CASE("twai send from ISR context (loopback)", "[twai]")
|
|||||||
}
|
}
|
||||||
|
|
||||||
printf("Test results:\n");
|
printf("Test results:\n");
|
||||||
printf(" RX count: %" PRIu32 "\n", test_ctx.rx_count);
|
printf(" RX count: %d\n", test_ctx.rx_count);
|
||||||
printf(" TX ISR sends: %" PRIu32 "\n", test_ctx.tx_isr_send_count);
|
printf(" TX ISR sends: %d\n", test_ctx.tx_isr_send_count);
|
||||||
printf(" RX ISR sends: %" PRIu32 "\n", test_ctx.rx_isr_send_count);
|
printf(" RX ISR sends: %d\n", test_ctx.rx_isr_send_count);
|
||||||
printf(" Test completed: %s\n", test_ctx.test_completed ? "YES" : "NO");
|
printf(" Test completed: %s\n", test_ctx.test_completed ? "YES" : "NO");
|
||||||
|
|
||||||
// Verify test results
|
// Verify test results
|
||||||
@@ -732,6 +734,8 @@ TEST_CASE("twai dlc range test", "[twai]")
|
|||||||
twai_onchip_node_config_t node_config = {};
|
twai_onchip_node_config_t node_config = {};
|
||||||
node_config.io_cfg.tx = TEST_TX_GPIO;
|
node_config.io_cfg.tx = TEST_TX_GPIO;
|
||||||
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
|
node_config.io_cfg.rx = TEST_TX_GPIO; // Using same pin for test without transceiver
|
||||||
|
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 = 800000;
|
node_config.bit_timing.bitrate = 800000;
|
||||||
node_config.tx_queue_depth = TEST_FRAME_NUM;
|
node_config.tx_queue_depth = TEST_FRAME_NUM;
|
||||||
node_config.flags.enable_loopback = true;
|
node_config.flags.enable_loopback = true;
|
||||||
|
@@ -210,7 +210,7 @@ void twai_hal_start_bus_recovery(twai_hal_context_t *hal_ctx);
|
|||||||
* @param hal_ctx Context of the HAL layer
|
* @param hal_ctx Context of the HAL layer
|
||||||
* @return TX Error Counter Value
|
* @return TX Error Counter Value
|
||||||
*/
|
*/
|
||||||
uint32_t twai_hal_get_tec(twai_hal_context_t *hal_ctx);
|
uint16_t twai_hal_get_tec(twai_hal_context_t *hal_ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the value of the RX Error Counter
|
* @brief Get the value of the RX Error Counter
|
||||||
@@ -218,7 +218,7 @@ uint32_t twai_hal_get_tec(twai_hal_context_t *hal_ctx);
|
|||||||
* @param hal_ctx Context of the HAL layer
|
* @param hal_ctx Context of the HAL layer
|
||||||
* @return RX Error Counter Value
|
* @return RX Error Counter Value
|
||||||
*/
|
*/
|
||||||
uint32_t twai_hal_get_rec(twai_hal_context_t *hal_ctx);
|
uint16_t twai_hal_get_rec(twai_hal_context_t *hal_ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Check if certain HAL state flags are set
|
* @brief Check if certain HAL state flags are set
|
||||||
|
@@ -113,6 +113,16 @@ void twai_hal_start_bus_recovery(twai_hal_context_t *hal_ctx)
|
|||||||
twaifd_ll_set_operate_cmd(hal_ctx->dev, TWAIFD_LL_HW_CMD_RST_ERR_CNT);
|
twaifd_ll_set_operate_cmd(hal_ctx->dev, TWAIFD_LL_HW_CMD_RST_ERR_CNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t twai_hal_get_tec(twai_hal_context_t *hal_ctx)
|
||||||
|
{
|
||||||
|
return twaifd_ll_get_tec((hal_ctx)->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t twai_hal_get_rec(twai_hal_context_t *hal_ctx)
|
||||||
|
{
|
||||||
|
return twaifd_ll_get_rec((hal_ctx)->dev);
|
||||||
|
}
|
||||||
|
|
||||||
// /* ------------------------------------ IRAM Content ------------------------------------ */
|
// /* ------------------------------------ IRAM Content ------------------------------------ */
|
||||||
|
|
||||||
void twai_hal_format_frame(const twai_hal_trans_desc_t *trans_desc, twai_hal_frame_t *frame)
|
void twai_hal_format_frame(const twai_hal_trans_desc_t *trans_desc, twai_hal_frame_t *frame)
|
||||||
|
@@ -127,12 +127,12 @@ twai_error_state_t twai_hal_get_err_state(twai_hal_context_t *hal_ctx)
|
|||||||
return (hw_state & TWAI_LL_STATUS_BS) ? TWAI_ERROR_BUS_OFF : (hw_state & TWAI_LL_STATUS_ES) ? TWAI_ERROR_PASSIVE : TWAI_ERROR_ACTIVE;
|
return (hw_state & TWAI_LL_STATUS_BS) ? TWAI_ERROR_BUS_OFF : (hw_state & TWAI_LL_STATUS_ES) ? TWAI_ERROR_PASSIVE : TWAI_ERROR_ACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t twai_hal_get_tec(twai_hal_context_t *hal_ctx)
|
uint16_t twai_hal_get_tec(twai_hal_context_t *hal_ctx)
|
||||||
{
|
{
|
||||||
return twai_ll_get_tec((hal_ctx)->dev);
|
return twai_ll_get_tec((hal_ctx)->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t twai_hal_get_rec(twai_hal_context_t *hal_ctx)
|
uint16_t twai_hal_get_rec(twai_hal_context_t *hal_ctx)
|
||||||
{
|
{
|
||||||
return twai_ll_get_rec((hal_ctx)->dev);
|
return twai_ll_get_rec((hal_ctx)->dev);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user