From 16a86073e451582b2dbc92a3606babd7c1f748f7 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Thu, 3 Apr 2025 10:04:48 +0200 Subject: [PATCH 1/9] Fix wrong API usage in disable() and beginAutoSpeed() --- src/esp32_can_builtin.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index 8b999a0..4d6c690 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -322,7 +322,11 @@ uint32_t ESP32CAN::beginAutoSpeed() _init(); readyForTraffic = false; +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + twai_stop_v2(bus_handle); +#else twai_stop(); +#endif twai_general_cfg.mode = TWAI_MODE_LISTEN_ONLY; int idx = 0; while (valid_timings[idx].speed != 0) @@ -348,7 +352,11 @@ uint32_t ESP32CAN::beginAutoSpeed() idx++; } Serial.println("None of the tested CAN speeds worked!"); +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + twai_stop_v2(bus_handle); +#else twai_stop(); +#endif return 0; } @@ -461,9 +469,18 @@ void ESP32CAN::enable() void ESP32CAN::disable() { twai_status_info_t info; - if (twai_get_status_info(&info) == ESP_OK) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + auto result = twai_get_status_info_v2(bus_handle, &info); +#else + auto result = twai_get_status_info(&info); +#endif + if (result == ESP_OK) { if (info.state == TWAI_STATE_RUNNING) { +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + twai_stop_v2(bus_handle); +#else twai_stop(); +#endif } for (auto task : {task_CAN_handler, task_LowLevelRX_handler}) { @@ -480,7 +497,11 @@ void ESP32CAN::disable() } } +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) + twai_driver_uninstall_v2(bus_handle); +#else twai_driver_uninstall(); +#endif } else { return; } From 07f9f945c056b9b9fa48a96b82e79de99a07466a Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 4 Apr 2025 13:19:05 +0200 Subject: [PATCH 2/9] Fix loop of forwarding messages. --- src/esp32_can_builtin.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index 4d6c690..7adbc17 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -580,6 +580,8 @@ bool ESP32CAN::sendFrame(CAN_FRAME& txFrame) __TX_frame.data_length_code = txFrame.length; __TX_frame.rtr = txFrame.rtr; __TX_frame.extd = txFrame.extended; + __TX_frame.self = 0; + __TX_frame.ss = 0; for (int i = 0; i < 8; i++) __TX_frame.data[i] = txFrame.data.byte[i]; //don't wait long if the queue was full. The end user code shouldn't be sending faster From 13692f7bfbe489015d6716a190938c4ca528ad58 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Fri, 4 Apr 2025 13:22:45 +0200 Subject: [PATCH 3/9] Also set dlc_non_comp (just for completion, as seen in the twai docs) --- src/esp32_can_builtin.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index 7adbc17..631c15b 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -582,6 +582,7 @@ bool ESP32CAN::sendFrame(CAN_FRAME& txFrame) __TX_frame.extd = txFrame.extended; __TX_frame.self = 0; __TX_frame.ss = 0; + __TX_frame.dlc_non_comp = 0; for (int i = 0; i < 8; i++) __TX_frame.data[i] = txFrame.data.byte[i]; //don't wait long if the queue was full. The end user code shouldn't be sending faster From 23ec7c186f00c61da308636e3f665a2230a6bd8e Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 7 Apr 2025 15:07:15 +0200 Subject: [PATCH 4/9] Use ESP32 logging. --- src/esp32_can_builtin.cpp | 37 ++++++++++++++++++++++++------------- src/esp32_can_builtin.h | 1 + 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index 631c15b..c802d6b 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -36,6 +36,9 @@ const VALID_TIMING valid_timings[] = ESP32CAN::ESP32CAN(gpio_num_t rxPin, gpio_num_t txPin, uint8_t busNumber) : CAN_COMMON(32) { + snprintf(TAG, sizeof(TAG), "ESP32CAN%d", busNumber); + ESP_LOGI(TAG, "Create driver for bus %d", busNumber); + twai_general_cfg.rx_io = rxPin; twai_general_cfg.tx_io = txPin; cyclesSinceTraffic = 0; @@ -232,6 +235,7 @@ int ESP32CAN::_setFilter(uint32_t id, uint32_t mask, bool extended) { if (!filters[i].configured) { + ESP_LOGI(TAG, "ID 0x%x -> mailbox %d", id, i); _setFilterSpecific(i, id, mask, extended); return i; } @@ -271,11 +275,11 @@ void ESP32CAN::_init() uint32_t ESP32CAN::init(uint32_t ul_baudrate) { - ESP_LOGD("CAN", "Init called"); + ESP_LOGD(TAG, "Init called"); _init(); - ESP_LOGD("CAN", "Init done"); + ESP_LOGD(TAG, "Init done"); set_baudrate(ul_baudrate); - ESP_LOGD("CAN", "Baudrate set"); + ESP_LOGD(TAG, "Baudrate set"); if (debuggingMode) { //Reconfigure alerts to detect Error Passive and Bus-Off error states @@ -311,6 +315,7 @@ uint32_t ESP32CAN::init(uint32_t ul_baudrate) #else xTaskCreatePinnedToCore(ESP32CAN::task_LowLevelRX, canLowLevelTaskName, 4096, this, 19, NULL, 1); #endif + ESP_LOGD(TAG, "init(): readyForTraffic = true"); readyForTraffic = true; return ul_baudrate; } @@ -321,6 +326,7 @@ uint32_t ESP32CAN::beginAutoSpeed() _init(); + ESP_LOGD(TAG, "beginAutoSpeed(): readyForTraffic = false"); readyForTraffic = false; #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) twai_stop_v2(bus_handle); @@ -396,20 +402,21 @@ void ESP32CAN::setNoACKMode(bool state) void ESP32CAN::enable() { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) - if (twai_driver_install_v2(&twai_general_cfg, &twai_speed_cfg, &twai_filters_cfg, &bus_handle) == ESP_OK) { - printf("Driver installed - bus %d\n", twai_general_cfg.controller_id); + auto result = twai_driver_install_v2(&twai_general_cfg, &twai_speed_cfg, &twai_filters_cfg, &bus_handle); + if (result == ESP_OK) { + ESP_LOGI(TAG, "Driver %d installed, handle 0x%x", twai_general_cfg.controller_id, bus_handle); } else { - printf("Failed to install driver - bus %d\n", twai_general_cfg.controller_id); + ESP_LOGE(TAG, "Failed to install driver %d: error: 0x%x", twai_general_cfg.controller_id, result); return; } #else if (twai_driver_install(&twai_general_cfg, &twai_speed_cfg, &twai_filters_cfg) == ESP_OK) { - printf("TWAI Driver installed\n"); + ESP_LOGI(TAG, "TWAI Driver installed"); } else { - printf("Failed to install TWAI driver\n"); + ESP_LOGE(TAG, "Failed to install TWAI driver"); return; } #endif @@ -444,25 +451,27 @@ void ESP32CAN::enable() #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) //Start TWAI driver - if (twai_start_v2(bus_handle) == ESP_OK) { - printf("Driver started - bus %d\n", twai_general_cfg.controller_id); + result = twai_start_v2(bus_handle); + if (result == ESP_OK) { + ESP_LOGI(TAG, "TWAI Driver %d started", twai_general_cfg.controller_id); } else { - printf("Failed to start driver\n"); + ESP_LOGE(TAG, "Failed to start TWAI driver %d: error: 0x%", twai_general_cfg.controller_id, result); return; } #else // Start TWAI driver if (twai_start() == ESP_OK) { - printf("TWAI Driver started\n"); + ESP_LOGI(TAG, "TWAI Driver started"); } else { - printf("Failed to start TWAI driver\n"); + ESP_LOGE(TAG, "Failed to start TWAI driver"); return; } #endif + ESP_LOGD(TAG, "enable(): readyForTraffic = true"); readyForTraffic = true; } @@ -503,8 +512,10 @@ void ESP32CAN::disable() twai_driver_uninstall(); #endif } else { + ESP_LOGD(TAG, "disable(): twai_get_status_info returned %d", result); return; } + ESP_LOGD(TAG, "disable(): readyForTraffic = false"); readyForTraffic = false; } diff --git a/src/esp32_can_builtin.h b/src/esp32_can_builtin.h index ca7b142..9fe209d 100755 --- a/src/esp32_can_builtin.h +++ b/src/esp32_can_builtin.h @@ -114,6 +114,7 @@ class ESP32CAN : public CAN_COMMON TaskHandle_t task_LowLevelRX_handler = NULL; private: + char TAG[10] = {0}; // Pin variables ESP32_FILTER filters[BI_NUM_FILTERS]; int rxBufferSize; From 8b4a5b3f50813dd583eb9780406e591c2bd00db1 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 7 Apr 2025 15:20:14 +0200 Subject: [PATCH 5/9] Convert the printfs to ESP_LOGx --- src/esp32_can_builtin.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index c802d6b..849f6d1 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -110,7 +110,7 @@ void ESP32CAN::CAN_WatchDog_Builtin( void *pvParameters ) #endif if (result != ESP_OK) { - printf("Could not initiate bus recovery!\n"); + ESP_LOGE(espCan->TAG, "Could not initiate bus recovery, result = %d!", result); } } } @@ -294,11 +294,11 @@ uint32_t ESP32CAN::init(uint32_t ul_baudrate) #endif if (result == ESP_OK) { - printf("Alerts reconfigured\n"); + ESP_LOGI(TAG, "Alerts reconfigured"); } else { - printf("Failed to reconfigure alerts"); + ESP_LOGE(TAG, "Failed to reconfigure alerts result = %d", result); } } //this task implements our better filtering on top of the TWAI library. Accept all frames then filter in here VVVVV @@ -381,7 +381,7 @@ uint32_t ESP32CAN::set_baudrate(uint32_t ul_baudrate) } idx++; } - printf("Could not find a valid bit timing! You will need to add your desired speed to the library!\n"); + ESP_LOGW(TAG, "Could not find a valid bit timing! You will need to add your desired speed to the library!"); return 0; } @@ -421,7 +421,7 @@ void ESP32CAN::enable() } #endif - printf("Creating queues\n"); + ESP_LOGI(TAG, "Creating queues"); callbackQueue = xQueueCreate(16, sizeof(CAN_FRAME)); rx_queue = xQueueCreate(rxBufferSize, sizeof(CAN_FRAME)); @@ -438,11 +438,11 @@ void ESP32CAN::enable() const char* canLowLevelTaskName = "CAN_LORX_CAN"; #endif - printf("Starting can handler task\n"); + ESP_LOGI(TAG, "Starting can handler task %s", canHandlerTaskName); xTaskCreate(ESP32CAN::task_CAN, canHandlerTaskName, 8192, this, 15, &task_CAN_handler); #if defined(CONFIG_FREERTOS_UNICORE) - printf("Starting low level RX task\n"); + ESP_LOGI(TAG, "Starting low level RX task %s", canLowLevelTaskName); xTaskCreate(ESP32CAN::task_LowLevelRX, canLowLevelTaskName, 4096, this, 19, &task_LowLevelRX_handler); #else //this next task implements our better filtering on top of the TWAI library. Accept all frames then filter in here VVVVV From 717ee9d8afce46f4df738dc4a3af82dde9547115 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 7 Apr 2025 17:12:58 +0200 Subject: [PATCH 6/9] Setup the queues only one time during _init. --- src/esp32_can_builtin.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index 849f6d1..4a2f772 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -255,6 +255,10 @@ void ESP32CAN::_init() filters[i].configured = false; } + ESP_LOGI(TAG, "Creating queues"); + callbackQueue = xQueueCreate(16, sizeof(CAN_FRAME)); + rx_queue = xQueueCreate(rxBufferSize, sizeof(CAN_FRAME)); + if (!CAN_WatchDog_Builtin_handler) { #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) std::ostringstream canWatchDogTaskNameStream; @@ -421,11 +425,6 @@ void ESP32CAN::enable() } #endif - ESP_LOGI(TAG, "Creating queues"); - - callbackQueue = xQueueCreate(16, sizeof(CAN_FRAME)); - rx_queue = xQueueCreate(rxBufferSize, sizeof(CAN_FRAME)); - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) std::ostringstream canHandlerTaskNameStream; std::ostringstream canLowLevelTaskNameStream; @@ -500,12 +499,6 @@ void ESP32CAN::disable() } } - for (auto queue : {rx_queue, callbackQueue}) { - if (queue) { - vQueueDelete(queue); - } - } - #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) twai_driver_uninstall_v2(bus_handle); #else From 6643966a7a7e66626e0443b08b407df1fecb84b9 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 7 Apr 2025 17:15:51 +0200 Subject: [PATCH 7/9] Remove duplicate init of low level CAN task --- src/esp32_can_builtin.cpp | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index 4a2f772..3bffb10 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -305,20 +305,7 @@ uint32_t ESP32CAN::init(uint32_t ul_baudrate) ESP_LOGE(TAG, "Failed to reconfigure alerts result = %d", result); } } - //this task implements our better filtering on top of the TWAI library. Accept all frames then filter in here VVVVV -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 2, 0) - std::ostringstream canLowLevelTaskNameStream; - canLowLevelTaskNameStream << "CAN_LORX_CAN" << twai_general_cfg.controller_id; - const char* canLowLevelTaskName = canLowLevelTaskNameStream.str().c_str(); -#else - const char* canLowLevelTaskName = "CAN_LORX_CAN0"; -#endif -#if defined(CONFIG_FREERTOS_UNICORE) - xTaskCreate(ESP32CAN::task_LowLevelRX, canLowLevelTaskName, 4096, this, 19, NULL); -#else - xTaskCreatePinnedToCore(ESP32CAN::task_LowLevelRX, canLowLevelTaskName, 4096, this, 19, NULL, 1); -#endif ESP_LOGD(TAG, "init(): readyForTraffic = true"); readyForTraffic = true; return ul_baudrate; From 521080bcf36597e2846215fdfaf3271cd39fbc18 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 7 Apr 2025 17:24:29 +0200 Subject: [PATCH 8/9] Remove bottleneck which was needed to handle the deletion of the queues. --- src/esp32_can_builtin.cpp | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index 3bffb10..ee2146c 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -160,24 +160,13 @@ void ESP32CAN::task_CAN( void *pvParameters ) ESP32CAN* espCan = (ESP32CAN*)pvParameters; CAN_FRAME rxFrame; - //delay a bit upon initial start up - vTaskDelay(pdMS_TO_TICKS(100)); - while (1) { - if (uxQueueMessagesWaiting(espCan->callbackQueue)) { - //receive next CAN frame from queue and fire off the callback - if(xQueueReceive(espCan->callbackQueue, &rxFrame, portMAX_DELAY) == pdTRUE) - { - espCan->sendCallback(&rxFrame); - } + //receive next CAN frame from queue and fire off the callback + if(xQueueReceive(espCan->callbackQueue, &rxFrame, portMAX_DELAY) == pdTRUE) + { + espCan->sendCallback(&rxFrame); } - else vTaskDelay(pdMS_TO_TICKS(4)); //if you don't delay here it will slow down the whole system. Need some delay. - -//probably don't need this extra delay. Test and find out. -#if defined(CONFIG_FREERTOS_UNICORE) - vTaskDelay(pdMS_TO_TICKS(6)); -#endif } vTaskDelete(NULL); From 0acebdd8c1060b2947167c68a5671fd39c2065a5 Mon Sep 17 00:00:00 2001 From: Florian Mayer Date: Mon, 7 Apr 2025 17:26:15 +0200 Subject: [PATCH 9/9] Remove double check code. --- src/esp32_can_builtin.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/esp32_can_builtin.cpp b/src/esp32_can_builtin.cpp index ee2146c..7c4ac1b 100755 --- a/src/esp32_can_builtin.cpp +++ b/src/esp32_can_builtin.cpp @@ -608,15 +608,12 @@ uint32_t ESP32CAN::get_rx_buff(CAN_FRAME &msg) { CAN_FRAME frame; //receive next CAN frame from queue - if (uxQueueMessagesWaiting(rx_queue)) { - if(xQueueReceive(rx_queue, &frame, 0) == pdTRUE) - { - msg = frame; //do a copy in the case that the receive worked - return true; - } - else - return false; + if(xQueueReceive(rx_queue, &frame, 0) == pdTRUE) + { + msg = frame; //do a copy in the case that the receive worked + return true; } - return false; //otherwise we leave the msg variable alone and just return false + else + return false; }