espressif / arduino-esp32

Arduino core for the ESP32
GNU Lesser General Public License v2.1
12.99k stars 7.29k forks source link

TWAI ESP_ERR_INVALID_STATE on ESP32-S3 #8268

Open ruziev-dev opened 1 year ago

ruziev-dev commented 1 year ago

Board

ESP32-S3 (ESP32-S3-DevKit C N16R8)

Device Description

ESP32-S3-DevKit C N16R8 with PlatformIO on Arduino-ESP32 Framework There are few FreeRTOS tasks, one of them is CANListenerTask.

Hardware Configuration

GPIO41 - CAN_RX GPIO40 - CAN_TX (I have tried on another GPIOs and got the same errors)

As CAN transceiver I have tested SN65HVD230 and TJA1050 modules and got the same result.

To check correct messages transmitting I used two arduino with MCP2515 modules.

Version

v2.0.7

IDE Name

PlatformIO

Operating System

macOS Ventura 13.3.1

Flash frequency

40MHz

PSRAM enabled

no

Upload speed

115200

Description

I can't transmit and receive messages from ESP32-S3 with SN65HVD230. I suppose I have tried everything I've can. I tried different resistors (100, 120, 150) Ohm.

Sketch

#include "CANListener.h"
#include "driver/twai.h"

#define LOG_LOCAL_LEVEL ESP_LOG_INFO
#include "esp_log.h"
static const char *TAG = "CANListenerTask";

void CANListenerTask(void *arg)
{
    esp_log_level_set(TAG, LOG_LOCAL_LEVEL);

    esp_err_t status;
    twai_message_t message;
    uint32_t alerts_triggered;

    // twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)CAN_TX, (gpio_num_t)CAN_RX, TWAI_MODE_NORMAL);

    twai_general_config_t g_config = {
        .mode = TWAI_MODE_NORMAL,
        .tx_io = (gpio_num_t)CAN_TX, // 41
        .rx_io = (gpio_num_t)CAN_RX, // 40
        .clkout_io = TWAI_IO_UNUSED,
        .bus_off_io = TWAI_IO_UNUSED,
        .tx_queue_len = 5,
        .rx_queue_len = 5,
        .alerts_enabled = TWAI_ALERT_ALL,
        .clkout_divider = 0};

    twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();
    twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

    status = twai_driver_install(&g_config, &t_config, &f_config);
    if (status == ESP_OK)
        ESP_LOGI(TAG, "TWAI Driver installed");
    else
    {
        ESP_LOGE(TAG, "Failed to twai_driver_install()");
        vTaskDelete(NULL);
    }

    status = twai_start();
    if (status == ESP_OK)
        ESP_LOGI(TAG, "TWAI (CAN bus) has been started");
    else
    {
        ESP_LOGE(TAG, "Failed to twai_start()");
        vTaskDelete(NULL);
    }

    while (1)
    {

        message.identifier = 0x7DF;
        message.extd = 0;
        message.rtr = 0;
        message.data_length_code = 8;
        message.data[0] = 2;
        message.data[1] = 1;
        message.data[2] = 0x0C;
        message.data[3] = 0;
        message.data[4] = 0;
        message.data[5] = 0;
        message.data[6] = 0;
        message.data[7] = 0;

        status = twai_transmit(&message, pdMS_TO_TICKS(2000));
        twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(2000));

        if (status == ESP_OK)
        {
            ESP_LOGI(TAG, "TWAI transmit alert 0x%X", alerts_triggered);
            ESP_LOG_BUFFER_HEX(TAG, (void *)&message, sizeof(message));
        }
        else
        {
            ESP_LOGE(TAG, "TWAI transmit alert 0x%X", alerts_triggered);
            ESP_LOGE(TAG, "TWAI transmit status 0x%X %S", status, esp_err_to_name(status));
            twai_clear_transmit_queue();
        }

        status = twai_receive(&message, pdMS_TO_TICKS(2000));
        twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(2000));

        if (status == ESP_OK)
        {
            twai_clear_receive_queue();
            ESP_LOGI(TAG, "TWAI recieve alert 0x%X", alerts_triggered);
            ESP_LOG_BUFFER_HEX(TAG, (void *)&message, sizeof(message));
        }
        else
        {
            ESP_LOGE(TAG, "TWAI recieve alert 0x%X", alerts_triggered);
            ESP_LOGE(TAG, "TWAI recieve status 0x%X %S", status, esp_err_to_name(status));
        }
        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}

Debug Message

[ 74951][E][CANListener.cpp:77] CANListenerTask(): [CANListenerTask] TWAI transmit alert 0x0
[ 74952][E][CANListener.cpp:78] CANListenerTask(): [CANListenerTask] TWAI transmit status 0x103 ESP_ERR_INVALID_STATE
[ 78958][E][CANListener.cpp:93] CANListenerTask(): [CANListenerTask] TWAI recieve alert 0x0
[ 78959][E][CANListener.cpp:94] CANListenerTask(): [CANListenerTask] TWAI recieve status 0x107 ESP_ERR_TIMEOUT

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

atanisoft commented 1 year ago

Most likely this is due to the bus not being in a compatible state for transmit and further as a result receive will fail for the same reason.

Add these lines:

twai_status_info_t status;
twai_get_status_info(&status);
ESP_LOGI(TAG, "TWAI state 0x%X", status.state);

To dump the state of the driver.

I have tested the TWAI driver on the ESP32-S3 (all variants actually) and have had no problems with it unless I reversed the RX/TX lines on the transceiver.

thankthemaker commented 10 months ago

@atanisoft : Could you please provide an example and tell us which version of the lib you're using? I got it working on a ESP32-S3 (XIAO) with IDF 5.1 but had no luck with esp32-arduino. Looks like TWAI support in esp32-arduino isn't supported (yet).

atanisoft commented 10 months ago

@thankthemaker TWAI is working perfectly fine in any of the 2.0.x releases of arduino-esp32. Note that this is based on ESP-IDF v4.4.x and not IDF v5.x.

IDF v5.x is NOT supported yet by arduino-esp32.

thankthemaker commented 10 months ago

Hmm, I tested it with 2.0.11 and had no luck. The same circuit is working like a charme with IDF. With esp32-arduino I got incompatible state errors.

Driver started
TWAI state 0x1
Failed to queue message for transmission alert 0x3380, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
Failed to queue message for transmission alert 0x0, status 0x103 ESP_ERR_INVALID_STATE
atanisoft commented 10 months ago

@thankthemaker You will need to share some code for review as the above usually indicates that the bus encountered an error and you did not initiate recover from it.

atanisoft commented 10 months ago

Also note that https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/TWAI both appear to work

thankthemaker commented 10 months ago

Here's a gist with the code. https://gist.github.com/thankthemaker/9b8565c904f6351cdba5d5f0c4c1aac6#file-xiao_esp32s3_twai_test-ino The IDF project does exactly the same. I'll try the examples

atanisoft commented 10 months ago

From your output above:

Failed to queue message for transmission alert 0x3380, status 0x103 ESP_ERR_INVALID_STATE

The alert bits are set as follows:

From your gist:

thankthemaker commented 10 months ago

Thank you very much. I'll try it.

Meanwhile I tried the examples you posted. I had to combine them to get an answer from my other CAN-device. The combined example works like a charm on a ESP32-S but doesn't work at all on an ESP32-S3. Here's the complete code. It's almost only copy and pasted from the examples. https://gist.github.com/thankthemaker/7acff3be16303db36f283e8cce823a7a

Output of ESP32-S3

Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 19
Message queued for transmission
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 20
Message queued for transmission
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 21
Message queued for transmission
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 22
Message queued for transmission
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.

Same code running on ESP32-S

Message is in Extended Format
ID: 919
Byte: 0 = 00, 1 = 00, 2 = 00, 3 = 00, 4 = ff, 5 = fa, 6 = 00, 7 = 00,
Message is in Extended Format
ID: 919
Byte: 0 = 00, 1 = 00, 2 = 00, 3 = 00, 4 = ff, 5 = fa, 6 = 00, 7 = 00,
Message is in Extended Format
ID: 919
Byte: 0 = 00, 1 = 00, 2 = 00, 3 = 00, 4 = ff, 5 = fa, 6 = 00, 7 = 00,
Message is in Extended Format
ID: 919
Byte: 0 = 00, 1 = 00, 2 = 00, 3 = 00, 4 = ff, 5 = fa, 6 = 00, 7 = 00,
Message is in Extended Format
ID: 919
Byte: 0 = 00, 1 = 00, 2 = 00, 3 = 00, 4 = ff, 5 = fa, 6 = 00, 7 = 00,
Message is in Extended Format
ID: 919
Byte: 0 = 00, 1 = 00, 2 = 00, 3 = 00, 4 = ff, 5 = fa, 6 = 00, 7 = 00,
Message is in Extended Format
ID: 919
Byte: 0 = 00, 1 = 00, 2 = 00, 3 = 00, 4 = ff, 5 = f9, 6 = 00, 7 = 00,
Message is in Extended Format
atanisoft commented 10 months ago

@thankthemaker can you do your test with IDF v4.4.3 (what is currently picked up)? I'm suspecting something was fixed AFTER IDF v4.4.3 and may be picked up by a currently pending PR to pick up IDF v4.4.4+

thankthemaker commented 10 months ago

Hi, I made several more test with the XIAO S3 and IDF. The self message examples are working, but talking to abother CAN-device always ends up in ESP_ERR_INVALID_STATE messages. Maybe there's something special about the XIAO.

I ordered some other ESP32-S3 and will continue tests when they arrive.

thankthemaker commented 8 months ago

It has been a while and since my last post I did some more tests with different devices. The Seeed XIAO doesn't work with TWAI. I opened a support case and the guys from Seeed also acknowledged this. I also tested the Lolin WEMOS S3 mini, which works like a charm regarding to TWAI interface.

So, I'd say the TWAI interface does work as expected

davidcyr2000 commented 4 months ago

The Internal TWAI function on the XIAO ESP32C3 works as advertised. It took much experimentation, but we finally got it working for send and receive with only the SN65HVD230 transceiver, without the expansion board with a CAN controller (e.g. MCP2515). The following two sketches are for receiving and sending CAN messages. They use GPIO4 (RX) and GPIO5 (TX).

/* ESP32 TWAI receive example.
  Receive messages and sends them over serial.
  https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/TWAI/TWAIreceive/TWAIreceive.ino
  Connect a CAN bus transceiver to the RX/TX pins.
  For example: SN65HVD230

  TWAI_MODE_LISTEN_ONLY is used so that the TWAI controller will not influence the bus.

  The API gives other possible speeds and alerts:
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html

  Example output from a can bus message:
  -> Message received
  -> Message is in Standard Format
  -> ID: 604
  -> Byte: 0 = 00, 1 = 0f, 2 = 13, 3 = 02, 4 = 00, 5 = 00, 6 = 08, 7 = 00

  Example output with alerts:
  -> Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
  -> Bus error count: 171
  -> Alert: The RX queue is full causing a received frame to be lost.
  -> RX buffered: 4  RX missed: 46 RX overrun 0

  created 05-11-2022 by Stephan Martin (designer2k2)
*/

#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
#include "driver/twai.h"

// Pins used to connect to CAN bus transceiver:
#define RX_PIN 4
#define TX_PIN 5

// Intervall:
#define POLLING_RATE_MS 1000

static bool driver_installed = false;

void setup() {
  // Start Serial:
  Serial.begin(115200);

  // Initialize configuration structures using macro initializers
  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_LISTEN_ONLY);
  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();  //Look in the api-reference for other speed sets.
  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

  // Install TWAI driver
  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    Serial.println("Driver installed");
  } else {
    Serial.println("Failed to install driver");
    return;
  }

  // Start TWAI driver
  if (twai_start() == ESP_OK) {
    Serial.println("Driver started");
  } else {
    Serial.println("Failed to start driver");
    return;
  }

  // Reconfigure alerts to detect frame receive, Bus-Off error and RX queue full states
  uint32_t alerts_to_enable = TWAI_ALERT_RX_DATA | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR | TWAI_ALERT_RX_QUEUE_FULL;
  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
    Serial.println("CAN Alerts reconfigured");
  } else {
    Serial.println("Failed to reconfigure alerts");
    return;
  }

  // TWAI driver is now successfully installed and started
  driver_installed = true;
}

static void handle_rx_message(twai_message_t& message) {
//   Serial.println("message received in *handle_rx_message*"); // for testing only
  // Process received message
  if (message.extd) {                                           // for testing only
    Serial.println("Message is in Extended Format");
  } else {
    Serial.print("Message is in Standard Format");
  }
  Serial.print(" ID=");     // was: Serial.printf(" ID: %lx\nByte:", message.identifier);
  Serial.print(message.identifier, HEX);
  if (!(message.rtr)) {
    for (int i = 0; i < message.data_length_code; i++) {
      Serial.printf(" %d = %02x,", i, message.data[i]);
    }
    Serial.println("");
  }
}

void loop() {
  if (!driver_installed) {
    // Driver not installed
    delay(1000);
    Serial.println(" Driver not installed at start of loop");
    return;
  }
//  else {  Serial.println(" Driver installed at start of loop");   }
  // Check if alert happened
  uint32_t alerts_triggered;
  twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS));
  twai_status_info_t twaistatus;
  twai_get_status_info(&twaistatus);
/// check if alert triggered
/*  if (alerts_triggered)   {       // for testing only
        Serial.println(" alerts_triggered");
                            }
*/
  // Handle alerts
  if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
    Serial.println("Alert: TWAI controller has become error passive.");
  }
  if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
    Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
    Serial.printf("Bus error count: %lu\n", twaistatus.bus_error_count);
  }
  if (alerts_triggered & TWAI_ALERT_RX_QUEUE_FULL) {
    Serial.println("Alert: The RX queue is full causing a received frame to be lost.");
    Serial.printf("RX buffered: %lu\t", twaistatus.msgs_to_rx);
    Serial.printf("RX missed: %lu\t", twaistatus.rx_missed_count);
    Serial.printf("RX overrun %lu\n", twaistatus.rx_overrun_count);
  }
//  Serial.println(" Passed error checking and before handle message call");    // for testing only
  // Check if message is received
  if (alerts_triggered & TWAI_ALERT_RX_DATA) {
    // One or more messages received. Handle all.
//  Serial.println("Entered message received alert check.");    // for testing omly
    twai_message_t message;
    while (twai_receive(&message, 0) == ESP_OK) {
      handle_rx_message(message);
    }
  }
}
/* ESP32 TWAI transmit example.
  This transmits a message every second.
https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/TWAI/TWAItransmit/TWAItransmit.ino
  Connect a CAN bus transceiver to the RX/TX pins.
  For example: SN65HVD230

  The API gives other possible speeds and alerts:
  https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/twai.html

  created 27-06-2023 by Stephan Martin (designer2k2)
*/

#include "driver/twai.h"

// Pins used to connect to CAN bus transceiver:
#define RX_PIN 4
#define TX_PIN 5

// Intervall:
#define TRANSMIT_RATE_MS 1000

#define POLLING_RATE_MS 1000

static bool driver_installed = false;

unsigned long previousMillis = 0;  // will store last time a message was send

void setup() {
  // Start Serial:
  Serial.begin(115200);

  // Initialize configuration structures using macro initializers
  twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_NORMAL);
  twai_timing_config_t t_config = TWAI_TIMING_CONFIG_500KBITS();  //Look in the api-reference for other speed sets.
  twai_filter_config_t f_config = TWAI_FILTER_CONFIG_ACCEPT_ALL();

  // Install TWAI driver
  if (twai_driver_install(&g_config, &t_config, &f_config) == ESP_OK) {
    Serial.println("Driver installed");
  } else {
    Serial.println("Failed to install driver");
    return;
  }

  // Start TWAI driver
  if (twai_start() == ESP_OK) {
    Serial.println("Driver started");
  } else {
    Serial.println("Failed to start driver");
    return;
  }

  // Reconfigure alerts to detect TX alerts and Bus-Off errors
  uint32_t alerts_to_enable = TWAI_ALERT_TX_IDLE | TWAI_ALERT_TX_SUCCESS | TWAI_ALERT_TX_FAILED | TWAI_ALERT_ERR_PASS | TWAI_ALERT_BUS_ERROR;
  if (twai_reconfigure_alerts(alerts_to_enable, NULL) == ESP_OK) {
    Serial.println("CAN Alerts reconfigured");
  } else {
    Serial.println("Failed to reconfigure alerts");
    return;
  }

  // TWAI driver is now successfully installed and started
  driver_installed = true;
}

static void send_message() {
  // Send message

  // Configure message to transmit
  twai_message_t message;
  message.identifier = 0x0F6;
  message.data_length_code = 8;                     // was 4.  
  for (int i = 0; i < 8; i++) {
    message.data[i] = i+100;                        // was 0.  Test it with 0, so we see if bit stuffing works
  }

  // Queue message for transmission
  if (twai_transmit(&message, pdMS_TO_TICKS(1000)) == ESP_OK) {
    printf("Message queued for transmission\n");
  } else {
    printf("Failed to queue message for transmission\n");
  }
}

void loop() {
  if (!driver_installed) {
    // Driver not installed
    delay(1000);
    return;
  }
  // Check if alert happened
  uint32_t alerts_triggered;
  twai_read_alerts(&alerts_triggered, pdMS_TO_TICKS(POLLING_RATE_MS));
  twai_status_info_t twaistatus;
  twai_get_status_info(&twaistatus);

  // Handle alerts
  if (alerts_triggered & TWAI_ALERT_ERR_PASS) {
    Serial.println("Alert: TWAI controller has become error passive.");
  }
  if (alerts_triggered & TWAI_ALERT_BUS_ERROR) {
    Serial.println("Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.");
    Serial.printf("Bus error count: %lu\n", twaistatus.bus_error_count);
  }
  if (alerts_triggered & TWAI_ALERT_TX_FAILED) {
    Serial.println("Alert: The Transmission failed.");
    Serial.printf("TX buffered: %lu\t", twaistatus.msgs_to_tx);
    Serial.printf("TX error: %lu\t", twaistatus.tx_error_counter);
    Serial.printf("TX failed: %lu\n", twaistatus.tx_failed_count);
  }
  if (alerts_triggered & TWAI_ALERT_TX_SUCCESS) {
    Serial.println("Alert: The Transmission was successful.");
    Serial.printf("TX buffered: %lu\t", twaistatus.msgs_to_tx);
  }

  // Send message
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= TRANSMIT_RATE_MS) {
    previousMillis = currentMillis;
    send_message();
  }
}
pwilkowski commented 2 months ago

@davidcyr2000 your code does not work for me (nor any other code i found here or in libraries.

My setup: waveshare esp32-s3-devkit-n8r8 transceiver: waveshare SN65HVD230 Using pins 4 & 5 (tried different ones, swapped RX/TX)

I have tested this in both arduino-esp32 as well as raw espidf, error is as follows:

Driver installed
Driver started
CAN Alerts reconfigured
Message queued for transmission
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 1
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 2
Alert: TWAI controller has become error passive.
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 25
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 66
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 92
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 118
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 144
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 171
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 197
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 224
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 250
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 277
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 303
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 329
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 356
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 382
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 409
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 435
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 462
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 488
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 514
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 541
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 567
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 594
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 620
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 647
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 673
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 700
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 726
Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus.
Bus error count: 752

and it goes to infinity.

Packages used and their version:

PACKAGES:
 - framework-espidf @ 3.50101.230828 (5.1.1)
 - tool-cmake @ 3.16.4
 - tool-esptoolpy @ 1.40501.0 (4.5.1)
 - tool-idf @ 1.0.1
 - tool-mconf @ 1.4060000.20190628 (406.0.0)
 - tool-mkfatfs @ 2.0.1
 - tool-mklittlefs @ 1.203.210628 (2.3)
 - tool-mkspiffs @ 2.230.0 (2.30)
 - tool-ninja @ 1.9.0
 - tool-riscv32-esp-elf-gdb @ 11.2.0+20220823
 - tool-xtensa-esp-elf-gdb @ 11.2.0+20230208
 - toolchain-esp32ulp @ 1.23500.220830 (2.35.0)
 - toolchain-riscv32-esp @ 12.2.0+20230208
 - toolchain-xtensa-esp32s3 @ 12.2.0+20230208

Any ideas?

davidcyr2000 commented 2 months ago

What code are you referring to? I can't help if I don't know what code you say is mine! Please give me a link to the code you picked up or list the code here. Thanks!     David Cyr


From: pwilkowski @.> Sent: May 4, 2024 18:49 To: espressif/arduino-esp32 @.> Cc: David Cyr @.>; Mention @.> Subject: Re: [espressif/arduino-esp32] TWAI ESP_ERR_INVALID_STATE on ESP32-S3 (Issue #8268)

@davidcyr2000https://github.com/davidcyr2000 your code does not work for me (nor any other code i found here or in libraries.

My setup: waveshare esp32-s3-devkit-n8r8 transceiver: waveshare SN65HVD230 Using pins 4 & 5 (tried different ones, swapped RX/TX)

I have tested this in both arduino-esp32 as well as raw espidf, error is as follows:

Driver installed Driver started CAN Alerts reconfigured Message queued for transmission Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 1 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 2 Alert: TWAI controller has become error passive. Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 25 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 66 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 92 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 118 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 144 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 171 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 197 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 224 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 250 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 277 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 303 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 329 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 356 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 382 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 409 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 435 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 462 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 488 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 514 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 541 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 567 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 594 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 620 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 647 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 673 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 700 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 726 Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 752

and it goes to infinity.

Packages used and their version:

PACKAGES:

Any ideas?

— Reply to this email directly, view it on GitHubhttps://github.com/espressif/arduino-esp32/issues/8268#issuecomment-2094493564, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACQ5MEZSE2CJF25GD77KCDDZAVQXDAVCNFSM6AAAAAAYTUA5A2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJUGQ4TGNJWGQ. You are receiving this because you were mentioned.Message ID: @.***>

pwilkowski commented 2 months ago

@davidcyr2000 the one above my post, marked as "ESP32 TWAI transmit example."

You mentioned

but we finally got it working for send and receive with only the SN65HVD230 transceiver

However that is not the case for me. I copied code 1:1 (and for espidf i just changed serial.print to printf)

davidcyr2000 commented 2 months ago

It's hard to know why it isn't working for you. I used two XIAO ESP32-C3, and pins 4 and 5 for TWAI, and the latest version of the Arduino IDE. Two UNOs that have MCP2515/MCP2561 breakout boards send and receive CANbus messages. Two XIAO ESP32-C3s have SN65HVD230 breakout boards that each have 120 ohm resistors.

I have two UNOs, one sending and one receiving, and I attached the ESP32-C3/SN65HVD230 transceivers to that network. One of the ESP32-C3s receives and the other sends a message, so there are several CAN IDs on the bus with 4 participants.

What are you using as a CANbus message generator when testing the RECEIVE sketch? Are you sure you have something valid to read? Once you get the receive going with a valid CAN message, then the transmit should also work. It will be harder to debug if you expect the same device to send and receive. Later on I combined the two sketches (send and receive) and forgot to change the g_config "Normal". twai_general_config_t g_config = TWAI_GENERAL_CONFIG_DEFAULT((gpio_num_t)TX_PIN, (gpio_num_t)RX_PIN, TWAI_MODE_NORMAL);

The only thing I can say is that there must be a problem with your setup, but I can't see that...

Tomorrow I will make sure I have the proper combined send/receive sketch and send it to you.


From: pwilkowski @.> Sent: May 4, 2024 21:56 To: espressif/arduino-esp32 @.> Cc: David Cyr @.>; Mention @.> Subject: Re: [espressif/arduino-esp32] TWAI ESP_ERR_INVALID_STATE on ESP32-S3 (Issue #8268)

@davidcyr2000https://github.com/davidcyr2000 the one above my post, marked as "ESP32 TWAI transmit example."

You mentioned

but we finally got it working for send and receive with only the SN65HVD230 transceiver

However that is not the case for me. I copied code 1:1 (and for espidf i just changed serial.print to printf)

— Reply to this email directly, view it on GitHubhttps://github.com/espressif/arduino-esp32/issues/8268#issuecomment-2094550236, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACQ5ME7NVFJ7SUVFNWUZ4ZDZAWGVXAVCNFSM6AAAAAAYTUA5A2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJUGU2TAMRTGY. You are receiving this because you were mentioned.

pwilkowski commented 2 months ago

@davidcyr2000 i dug up even further and it seems like this problem is present when there is either: nothing connected to CAN (not sure why would can throw errors because of that) other side (another SN65HVD230) is underpowered other side isn't listening.

Ultimately i swapped out to stm32 and it does work I have also tried connecting esp32 to stm32 via canbus (2x SN65HVD230) And it does work as well.

There was nothing electrically wrong with my setup, so I guess the question now is how to make it work without "mandatory" other side?

Long story short, I want to implement can as open port (kinda like OBD2) where there could be nothing connected and i wouldn't get 9001 bus errors. Is this even possible?

davidcyr2000 commented 2 months ago

I don't think your "9001 bus errors" are related to not having someone listening. If you have two SN65HVD230 breakout boardshttps://www.aliexpress.us/item/3256802657010294.html?src=google&src=google&albch=shopping&acnt=708-803-3821&slnk=&plac=&mtctp=&albbt=Google_7_shopping&albagn=888888&isSmbAutoCall=false&needSmbHouyi=false&albcp=19158444193&albag=&trgt=&crea=en3256802657010294&netw=x&device=c&albpg=&albpd=en3256802657010294&gad_source=1&gclid=CjwKCAjw3NyxBhBmEiwAyofDYTVzKNKUw8a3d9HalUkPSIZZ4_tj-UvwWuLtBhJ28t-nxa6pnWX3jhoCl9sQAvD_BwE&gclsrc=aw.ds&aff_fcid=7419e24ba0c54fd3a64da9af8960a8cb-1714952160173-00104-UneMJZVf&aff_fsk=UneMJZVf&aff_platform=aaf&sk=UneMJZVf&aff_trace_key=7419e24ba0c54fd3a64da9af8960a8cb-1714952160173-00104-UneMJZVf&terminal_id=b7886ab8998c49a99128a720a1e2cf25&afSmartRedirect=y&gatewayAdapt=glo2usa and two MCUs that can talk to each other, then a third CAN (TWAI) device like the ESP32-S3 will work on the established CAN bus. Note that you must have two 120 ohm resistors terminating the CAN network, which the SN65HVD230https://www.aliexpress.us/item/3256802657010294.html?src=google&src=google&albch=shopping&acnt=708-803-3821&slnk=&plac=&mtctp=&albbt=Google_7_shopping&albagn=888888&isSmbAutoCall=false&needSmbHouyi=false&albcp=19158444193&albag=&trgt=&crea=en3256802657010294&netw=x&device=c&albpg=&albpd=en3256802657010294&gad_source=1&gclid=CjwKCAjw3NyxBhBmEiwAyofDYTVzKNKUw8a3d9HalUkPSIZZ4_tj-UvwWuLtBhJ28t-nxa6pnWX3jhoCl9sQAvD_BwE&gclsrc=aw.ds&aff_fcid=7419e24ba0c54fd3a64da9af8960a8cb-1714952160173-00104-UneMJZVf&aff_fsk=UneMJZVf&aff_platform=aaf&sk=UneMJZVf&aff_trace_key=7419e24ba0c54fd3a64da9af8960a8cb-1714952160173-00104-UneMJZVf&terminal_id=b7886ab8998c49a99128a720a1e2cf25&afSmartRedirect=y&gatewayAdapt=glo2usa provides. Your ESP32-S3 transceiver should not have a terminating resistor. I tested this with the attached code with the second SN65HVD230https://www.aliexpress.us/item/3256802657010294.html?src=google&src=google&albch=shopping&acnt=708-803-3821&slnk=&plac=&mtctp=&albbt=Google_7_shopping&albagn=888888&isSmbAutoCall=false&needSmbHouyi=false&albcp=19158444193&albag=&trgt=&crea=en3256802657010294&netw=x&device=c&albpg=&albpd=en3256802657010294&gad_source=1&gclid=CjwKCAjw3NyxBhBmEiwAyofDYTVzKNKUw8a3d9HalUkPSIZZ4_tj-UvwWuLtBhJ28t-nxa6pnWX3jhoCl9sQAvD_BwE&gclsrc=aw.ds&aff_fcid=7419e24ba0c54fd3a64da9af8960a8cb-1714952160173-00104-UneMJZVf&aff_fsk=UneMJZVf&aff_platform=aaf&sk=UneMJZVf&aff_trace_key=7419e24ba0c54fd3a64da9af8960a8cb-1714952160173-00104-UneMJZVf&terminal_id=b7886ab8998c49a99128a720a1e2cf25&afSmartRedirect=y&gatewayAdapt=glo2usa not powered and the network kept going as shown below, which is output from the serial monitor from the ESP32-C3. See the attached block diagram to see how to ensure it works the way you want (kinda like OBD2).

SN65HVD230 breakout board [cid:a2abd933-6686-4087-b2e3-cf8956805d76] You will have to check the pin choice on the ESP32-S3 because it's different from the C3. Also, note that the pinouts for the C3 and S3 are different. Make sure you select these properly and connect to the correct physical pins (I had that difficulty).

C3 pinout - I used the purple numbers in the sketch

[cid:e1ea1598-8b54-4489-80b3-a211805c8b16]https://sigmdel.ca/michel/ha/xiao/xiao_esp32c3_intro_en.html

S3 pinout - IO 4 and 5 are different physical pins from the C3[cid:57a2d522-8512-4193-a17c-684fa4ff8a76]https://dronebotworkshop.com/xiao-esp32s3-sense/

Output from ESP32C3

17:31:13.023 -> Message is in Standard Format ID=743 0 = 40, 1 = 1f, 2 = 64, 3 = 64, 4 = 32, 5 = e6, 6 = c8, 7 = 0a,

17:31:13.023 -> Message is in Standard Format ID=200 0 = 21, 1 = 65, 2 = 66, 3 = 67, 4 = 68, 5 = 69, 6 = 6a, 7 = 7b,

17:31:13.148 -> Message is in Standard Format ID=743 0 = 40, 1 = 1f, 2 = 64, 3 = 64, 4 = 32, 5 = e6, 6 = c8, 7 = 0a,

17:31:13.148 -> Alert: The Transmission was successful.

17:31:13.148 -> TX buffered: 0 Message is in Standard Format ID=200 0 = 21, 1 = 65, 2 = 66, 3 = 67, 4 = 68, 5 = 69, 6 = 6a, 7 = 7b,

17:31:13.331 -> Message is in Standard Format ID=743 0 = 40, 1 = 1f, 2 = 64, 3 = 64, 4 = 32, 5 = e6, 6 = c8, 7 = 0a,

17:31:13.331 -> Message is in Standard Format ID=200 0 = 21, 1 = 65, 2 = 66, 3 = 67, 4 = 68, 5 = 69, 6 = 6a, 7 = 7b,

I used "MCP2515, MCP2551 Interface Evaluation Boardshttps://www.digikey.com/en/products/detail/mikroelektronika/MIKROE-68/4495625" with two UNOs to generate and validate (send and receive) CAN messages to know that I had a good CAN bus going. These boards do not have the 120 ohm terminating resistors. [cid:afa8729d-741f-43c3-b239-0b298b955e90] I had a very difficult time getting the right code for the Dual Filter Mode, but the filters do work. So if you want or need that, this code works too.

Good luck!


From: pwilkowski @.> Sent: May 5, 2024 01:46 To: espressif/arduino-esp32 @.> Cc: David Cyr @.>; Mention @.> Subject: Re: [espressif/arduino-esp32] TWAI ESP_ERR_INVALID_STATE on ESP32-S3 (Issue #8268)

@davidcyr2000https://github.com/davidcyr2000 i dug up even further and it seems like this problem is present when there is either: nothing connected to CAN (not sure why would can throw errors because of that) other side (another SN65HVD230) is underpowered other side isn't listening.

Ultimately i swapped out to stm32 and it does work I have also tried connecting esp32 to stm32 via canbus (2x SN65HVD230) And it does work as well.

There was nothing electrically wrong with my setup, so I guess the question now is how to make it work without "mandatory" other side?

Long story short, I want to implement can as open port (kinda like OBD2) where there could be nothing connected and i wouldn't get 9001 bus errors. Is this even possible?

— Reply to this email directly, view it on GitHubhttps://github.com/espressif/arduino-esp32/issues/8268#issuecomment-2094642442, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACQ5ME7BTKMOQ7AYVK6PMZTZAXBUJAVCNFSM6AAAAAAYTUA5A2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJUGY2DENBUGI. You are receiving this because you were mentioned.

pwilkowski commented 2 months ago

I don't think your "9001 bus errors" are related to not having someone listening.

I currently have two MCUs connected to one another, both are using SN65HVD230 from waveshare which does have 120ohm terminator resistor: image

If other mcu is in suspended state, for example when im uploading new firmware, and ESP32 sends frame in that time, I get

Alert: A (Bit, Stuff, CRC, Form, ACK) error has occurred on the bus. Bus error count: 752 That loops until the other mcu wakes up.

Pinout is certainly not a problem because if both mcu are up and running, they can send data to each other no problem: https://cdn.discordapp.com/attachments/710084652798312518/1236759558806835281/YoloMouse_IWJiXyf9r9.mp4?ex=66392d98&is=6637dc18&hm=7735f743c4f87c01a570288be391c2d31065248c4eb79442a9cb9dd767c5cf5a&

Left side RP2040, right side ESP32

At this point i think there is no other way rather than just ignore those errors?

atanisoft commented 2 months ago

FYI, the ESP32 will report bus errors whenever it is alone on the bus (even if there is a second transceiver and proper bus termination). It doesn't always enter a bus-off condition when the TX error count exceeds warning limits from my experience.

i think there is no other way rather than just ignore those errors?

Unfortunately that is likely best at this point. In my usages I have a TX queue and attempt to send the first entry until it succeeds, it's far from perfect since it can sit there for a while with errors being reported. I also have a background watchdog like task which monitors the status, when the bus enters an error / suspended state it will initiate recovery etc. When the TX or RX queue does not drain as expected the background task will purge the queues to ensure system stability and records them as dropped frames.

You can see the code I'm using, forked from ESP-IDF and wrapped with a VFS interface here.

also note that this is NOT an arduino-esp32 issue but instead an ESP-IDF issue and likely should end up reported upstream.

davidcyr2000 commented 2 months ago

Mike,

If I wanted to plagiarize your recovery routines for use with the Arduino IDE, are there compatible include Arduino modules? Or would I have to use the ESP-IDF?

Thanks, David Cyr

Get Outlook for Androidhttps://aka.ms/AAb9ysg


From: Mike Dunston @.> Sent: Monday, May 6, 2024 9:15:10 AM To: espressif/arduino-esp32 @.> Cc: David Cyr @.>; Mention @.> Subject: Re: [espressif/arduino-esp32] TWAI ESP_ERR_INVALID_STATE on ESP32-S3 (Issue #8268)

FYI, the ESP32 will report bus errors whenever it is alone on the bus (even if there is a second transceiver and proper bus termination). It doesn't always enter a bus-off condition when the TX error count exceeds warning limits from my experience.

i think there is no other way rather than just ignore those errors?

Unfortunately that is likely best at this point. In my usages I have a TX queue and attempt to send the first entry until it succeeds, it's far from perfect since it can sit there for a while with errors being reported. I also have a background watchdog like task which monitors the status, when the bus enters an error / suspended state it will initiate recovery etc. When the TX or RX queue does not drain as expected the background task will purge the queues to ensure system stability and records them as dropped frames.

You can see the code I'm using, forked from ESP-IDF and wrapped with a VFS interface herehttps://github.com/atanisoft/OpenMRNIDF/blob/5.1.0/src/freertos_drivers/esp32/Esp32HardwareTwai.cpp.

also note that this is NOT an arduino-esp32 issue but instead an ESP-IDF issue and likely should end up reported upstream.

— Reply to this email directly, view it on GitHubhttps://github.com/espressif/arduino-esp32/issues/8268#issuecomment-2095994296, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACQ5ME4Z2YP2F7FTD66KW23ZA5655AVCNFSM6AAAAAAYTUA5A2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJVHE4TIMRZGY. You are receiving this because you were mentioned.Message ID: @.***>

atanisoft commented 2 months ago

are there compatible include Arduino modules?

The code should work as-is in both ESP-IDF and Arduino, for a version that is known to work with Arduino-esp32 2.x versions please use code from https://github.com/openmrn/OpenMRNLite as the version I linked to above was modified to fit with ESP-IDF v5.x which had a number of changes.

davidcyr2000 commented 2 months ago

Hi Mike, Which example were you suggesting to use: "ESP32C3CanLoadTest" or "ESP32C3IOBoard" or another, given we are using the ESP32-C3? Thanks, David Cyr


From: Mike Dunston @.> Sent: May 7, 2024 07:38 To: espressif/arduino-esp32 @.> Cc: David Cyr @.>; Mention @.> Subject: Re: [espressif/arduino-esp32] TWAI ESP_ERR_INVALID_STATE on ESP32-S3 (Issue #8268)

are there compatible include Arduino modules?

The code should work as-is in both ESP-IDF and Arduino, for a version that is known to work with Arduino-esp32 2.x versions please use code from https://github.com/openmrn/OpenMRNLite as the version I linked to above was modified to fit with ESP-IDF v5.x which had a number of changes.

— Reply to this email directly, view it on GitHubhttps://github.com/espressif/arduino-esp32/issues/8268#issuecomment-2098200424, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACQ5ME5L6ASC7GRHQYBKQOTZBC4JTAVCNFSM6AAAAAAYTUA5A2VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOJYGIYDANBSGQ. You are receiving this because you were mentioned.

atanisoft commented 1 month ago

given we are using the ESP32-C3?

I'd likely suggest using ESP32C3IOBoard as it is the basic IO board for LCC (NMRA model railroad standard which OpenMRN implements). Be sure to set the NODE_ID field uniquely for all ESP32-C3 devices in use.

I'd also only use these as examples to confirm that everything is working as expected. The actual TWAI driver in use for OpenMRN is a clone of the one in ESP-IDF with an alternative interface (VFS supporting the usage of select() and using an internal can_frame representation rather than twai_message).