-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Description
Hardware:
Board: Wemos LOLIN D32 Pro
CAN Bus Transceiver: SN65HVD230
Software
PLATFORM: Espressif 32 1.12.0 > WEMOS LOLIN D32 PRO
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
PACKAGES:
-- framework-arduinoespressif32 3.10004.200129 (1.0.4)
-- tool-esptoolpy 1.20600.0 (2.6.0)
-- toolchain-xtensa32 2.50200.80 (5.2.0)
Dependency Graph
--Ticker 1.1
RAM: [ ] 4.5% (used 14796 bytes from 327680 bytes)
Flash: [== ] 20.8% (used 272229 bytes from 1310720 bytes)
IDE name: Platformio.io Core 4.3.1, Home 3.1.1 using Visual Code IDE
Flash Frequency: default
PSRAM enabled: yes
Upload Speed: 460800
Computer OS: Mac OSX
Description:
I am trying to use the ESP-IDF driver for the CAN controller in my CAN BUS application. I am getting an error when trying to transmit a CAN data frame or RTR. The error appears when trying to send the second CAN data frame. However, the first frame seems to be corrupted as well when I look at it with a digital analyser directly at the Tx pin.
Why does the CAN controller enters an "invalid_state" and then it goes "bus-off"?
How exactly I need to use this API? if I were to only receive CAN frames my approach seems to work.
or can it be a hardware issue as described here (from page 16) https://esp32.com/viewtopic.php?t=380&start=170 ?
Sketch:
#include <Arduino.h>
#include <driver/can.h>
#include <driver/gpio.h>
#include <Ticker.h>
// Global objects
Ticker canBusTimer;
// Global variables
uint8_t canBusFLAG = 0;
// Prototype functions
void CAN_begin(void);
void CAN_receive(void);
void CAN_transmit_RTR(uint32_t id);
void CAN_transmit_stdData(uint32_t id, uint8_t len, uint8_t *data);
void can_flag(void);
void setup()
{
CAN_begin();
delay(1000);
canBusTimer.attach_ms(1000, can_flag);
}
void loop()
{
if (canBusFLAG == 1)
{
uint8_t canData[1] = {1};
CAN_transmit_stdData(0x003, 1, canData);
canBusFLAG = 0;
CAN_receive();
}
}
// FUNCTIONS
void can_flag(void)
{
canBusFLAG = 1;
}
void CAN_begin(void)
{
//Initialize configuration structures using macro initializers (changed GPIO type in esp idf library)
can_general_config_t g_config = CAN_GENERAL_CONFIG_DEFAULT(GPIO_NUM_22, GPIO_NUM_23, CAN_MODE_NO_ACK);
can_timing_config_t t_config = CAN_TIMING_CONFIG_25KBITS();
can_filter_config_t f_config = CAN_FILTER_CONFIG_ACCEPT_ALL();
//Install CAN driver
if (can_driver_install(&g_config, &t_config, &f_config) == ESP_OK)
printf("Driver installed\n");
else
{
printf("Failed to install driver\n");
return;
}
//Start CAN driver
if (can_start() == ESP_OK)
printf("Driver started\n");
else
{
printf("Failed to start driver\n");
return;
}
}
void CAN_receive(void)
{
can_status_info_t can_status;
can_message_t message;
//Check for received messages
can_get_status_info(&can_status);
if (can_status.msgs_to_rx >= 1)
{
if (can_receive(&message, pdMS_TO_TICKS(10)) == ESP_OK)
printf("Message received\n");
else
{
printf("Failed to receive message\n");
return;
}
//Process received message
printf("ID is %d\n", message.identifier);
for (int i = 0; i < message.data_length_code; i++)
{
printf("Data byte %d = %d\n", i, message.data[i]);
}
}
}
void CAN_transmit_stdData(uint32_t id, uint8_t len, uint8_t *data)
{
//Configure message to transmit
can_message_t message;
message.flags = CAN_MSG_FLAG_SELF;
message.identifier = id;
message.data_length_code = len;
message.data[0] = 1;
// for (uint8_t i = 0; i < len; i++)
// {
// message.data[i] = 1;
// }
can_status_info_t info;
can_get_status_info(&info);
if (info.state == CAN_STATE_RUNNING)
printf("CAN running\n");
else if (info.state == CAN_STATE_STOPPED)
printf("CAN stopped\n");
else if (info.state == CAN_STATE_RECOVERING)
printf("CAN recovering\n");
else if (info.state == CAN_STATE_BUS_OFF)
printf("CAN bus-off\n");
ESP_ERROR_CHECK_WITHOUT_ABORT(can_transmit(&message, pdMS_TO_TICKS(100)));
// //Queue message for transmission
// if (can_transmit(&message, pdMS_TO_TICKS(100)) == ESP_OK)
// printf("Message queued for transmission\n");
// else
// printf("Failed to queue message for transmission\n");
}
void CAN_transmit_RTR(uint32_t id)
{
//Configure message to transmit
can_message_t message;
message.flags = CAN_MSG_FLAG_RTR;
message.identifier = id;
message.data_length_code = 0;
//Queue message for transmission
ESP_ERROR_CHECK_WITHOUT_ABORT(can_transmit(&message, pdMS_TO_TICKS(100)));
}
Debug Messages:
ESP_ERROR_CHECK_WITHOUT_ABORT failed: esp_err_t 0x103 (ESP_ERR_INVALID_STATE) at 0x4008d8df
file: "src/main.cpp" line 122
func: void CAN_transmit_stdData(uint32_t, uint8_t, uint8_t*)
expression: can_transmit(&message, pdMS_TO_TICKS(100))
Platformio configuration
[env:lolin_d32_pro]
platform = espressif32
board = lolin_d32_pro
framework = arduino
upload_port = /dev/tty.wchusbserial1410
monitor_speed = 115200
; debug_tool = esp-prog
; debug_init_break = tbreak setup
; monitor_filters = log2file, esp32_exception_decoder
build_flags =
-DBOARD_HAS_PSRAM
-mfix-esp32-psram-cache-issue
-DCORE_DEBUG_LEVEL=4