Optimize CAN-Native driver and event handling

This commit is contained in:
Daniel Öster 2025-03-06 19:01:13 +02:00
parent 5a43a70992
commit 8d21930101
7 changed files with 44 additions and 23 deletions

View file

@ -6,6 +6,7 @@
CAN_device_t CAN_cfg; // CAN Config CAN_device_t CAN_cfg; // CAN Config
const int rx_queue_size = 10; // Receive Queue size const int rx_queue_size = 10; // Receive Queue size
volatile bool send_ok_native = 0;
volatile bool send_ok_2515 = 0; volatile bool send_ok_2515 = 0;
volatile bool send_ok_2518 = 0; volatile bool send_ok_2518 = 0;
@ -146,7 +147,10 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface) {
for (uint8_t i = 0; i < tx_frame->DLC; i++) { for (uint8_t i = 0; i < tx_frame->DLC; i++) {
frame.data.u8[i] = tx_frame->data.u8[i]; frame.data.u8[i] = tx_frame->data.u8[i];
} }
ESP32Can.CANWriteFrame(&frame); send_ok_native = ESP32Can.CANWriteFrame(&frame);
if (!send_ok_native) {
datalayer.system.info.can_native_send_fail = true;
}
break; break;
case CAN_ADDON_MCP2515: { case CAN_ADDON_MCP2515: {
#ifdef CAN_ADDON #ifdef CAN_ADDON
@ -162,9 +166,7 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface) {
send_ok_2515 = can.tryToSend(MCP2515Frame); send_ok_2515 = can.tryToSend(MCP2515Frame);
if (!send_ok_2515) { if (!send_ok_2515) {
set_event(EVENT_CAN_BUFFER_FULL, interface); datalayer.system.info.can_2515_send_fail = true;
} else {
clear_event(EVENT_CAN_BUFFER_FULL);
} }
#else // Interface not compiled, and settings try to use it #else // Interface not compiled, and settings try to use it
set_event(EVENT_INTERFACE_MISSING, interface); set_event(EVENT_INTERFACE_MISSING, interface);
@ -187,9 +189,7 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface) {
} }
send_ok_2518 = canfd.tryToSend(MCP2518Frame); send_ok_2518 = canfd.tryToSend(MCP2518Frame);
if (!send_ok_2518) { if (!send_ok_2518) {
set_event(EVENT_CANFD_BUFFER_FULL, interface); datalayer.system.info.can_2518_send_fail = true;
} else {
clear_event(EVENT_CANFD_BUFFER_FULL);
} }
#else // Interface not compiled, and settings try to use it #else // Interface not compiled, and settings try to use it
set_event(EVENT_INTERFACE_MISSING, interface); set_event(EVENT_INTERFACE_MISSING, interface);

View file

@ -228,6 +228,12 @@ typedef struct {
uint8_t can_replay_interface = CAN_NATIVE; uint8_t can_replay_interface = CAN_NATIVE;
/** bool, determines if CAN replay should loop or not */ /** bool, determines if CAN replay should loop or not */
bool loop_playback = false; bool loop_playback = false;
/** bool, Native CAN failed to send flag */
bool can_native_send_fail = false;
/** bool, MCP2515 CAN failed to send flag */
bool can_2515_send_fail = false;
/** uint16_t, MCP2518 CANFD failed to send flag */
bool can_2518_send_fail = false;
} DATALAYER_SYSTEM_INFO_TYPE; } DATALAYER_SYSTEM_INFO_TYPE;

View file

@ -19,6 +19,26 @@ battery_pause_status emulator_pause_status = NORMAL;
//battery pause status end //battery pause status end
void update_machineryprotection() { void update_machineryprotection() {
// Check health status of CAN interfaces
if (datalayer.system.info.can_native_send_fail) {
set_event(EVENT_CAN_NATIVE_TX_FAILURE, 0);
datalayer.system.info.can_native_send_fail = false;
} else {
clear_event(EVENT_CAN_NATIVE_TX_FAILURE);
}
if (datalayer.system.info.can_2515_send_fail) {
set_event(EVENT_CAN_BUFFER_FULL, 0);
datalayer.system.info.can_2515_send_fail = false;
} else {
clear_event(EVENT_CAN_BUFFER_FULL);
}
if (datalayer.system.info.can_2518_send_fail) {
set_event(EVENT_CANFD_BUFFER_FULL, 0);
datalayer.system.info.can_2518_send_fail = false;
} else {
clear_event(EVENT_CANFD_BUFFER_FULL);
}
// Start checking that the battery is within reason. Incase we see any funny business, raise an event! // Start checking that the battery is within reason. Incase we see any funny business, raise an event!
// Pause function is on OR we have a critical fault event active // Pause function is on OR we have a critical fault event active

View file

@ -136,7 +136,7 @@ void init_events(void) {
events.entries[EVENT_CAN_BUFFER_FULL].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN_BUFFER_FULL].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_OVERRUN].level = EVENT_LEVEL_INFO; events.entries[EVENT_CAN_OVERRUN].level = EVENT_LEVEL_INFO;
events.entries[EVENT_CAN_CORRUPTED_WARNING].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN_CORRUPTED_WARNING].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_NATIVE_TX_FAILURE].level = EVENT_LEVEL_ERROR; events.entries[EVENT_CAN_NATIVE_TX_FAILURE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_BATTERY_MISSING].level = EVENT_LEVEL_ERROR; events.entries[EVENT_CAN_BATTERY_MISSING].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_CAN_BATTERY2_MISSING].level = EVENT_LEVEL_WARNING; events.entries[EVENT_CAN_BATTERY2_MISSING].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_CHARGER_MISSING].level = EVENT_LEVEL_INFO; events.entries[EVENT_CAN_CHARGER_MISSING].level = EVENT_LEVEL_INFO;
@ -275,9 +275,9 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
case EVENT_CANMCP2515_INIT_FAILURE: case EVENT_CANMCP2515_INIT_FAILURE:
return "CAN-MCP addon initialization failed. Check hardware"; return "CAN-MCP addon initialization failed. Check hardware";
case EVENT_CANFD_BUFFER_FULL: case EVENT_CANFD_BUFFER_FULL:
return "MCP2518FD buffer overflowed. Some CAN messages were not sent. Contact developers."; return "MCP2518FD message failed to send. Buffer full or no one on the bus to ACK the message!";
case EVENT_CAN_BUFFER_FULL: case EVENT_CAN_BUFFER_FULL:
return "MCP2515 buffer overflowed. Some CAN messages were not sent. Contact developers."; return "MCP2515 message failed to send. Buffer full or no one on the bus to ACK the message!";
case EVENT_CAN_OVERRUN: case EVENT_CAN_OVERRUN:
return "CAN message failed to send within defined time. Contact developers, CPU load might be too high."; return "CAN message failed to send within defined time. Contact developers, CPU load might be too high.";
case EVENT_CAN_CORRUPTED_WARNING: case EVENT_CAN_CORRUPTED_WARNING:

View file

@ -266,13 +266,13 @@ int CAN_init() {
int CAN_write_frame(const CAN_frame_t *p_frame) { int CAN_write_frame(const CAN_frame_t *p_frame) {
if (sem_tx_complete == NULL) { if (sem_tx_complete == NULL) {
return -1; return 0;
} }
// Write the frame to the controller // Write the frame to the controller
CAN_write_frame_phy(p_frame); CAN_write_frame_phy(p_frame);
return xSemaphoreTake(sem_tx_complete, 20) == pdTRUE ? 0 : -1; return xSemaphoreTake(sem_tx_complete, 20) == pdTRUE ? 1 : 0;
} }
int CAN_stop() { int CAN_stop() {

View file

@ -5,20 +5,14 @@
int ESP32CAN::CANInit() { int ESP32CAN::CANInit() {
return CAN_init(); return CAN_init();
} }
int ESP32CAN::CANWriteFrame(const CAN_frame_t* p_frame) { bool ESP32CAN::CANWriteFrame(const CAN_frame_t* p_frame) {
static unsigned long start_time; static unsigned long start_time;
int result = -1; bool result = false;
if (tx_ok) { if (tx_ok) {
result = CAN_write_frame(p_frame); result = CAN_write_frame(p_frame);
tx_ok = (result == 0) ? true : false; tx_ok = result;
if (tx_ok == false) { if (!tx_ok) {
#ifdef DEBUG_VIA_USB
Serial.println("CAN failure! Check wires");
#endif
set_event(EVENT_CAN_NATIVE_TX_FAILURE, 0);
start_time = millis(); start_time = millis();
} else {
clear_event(EVENT_CAN_NATIVE_TX_FAILURE);
} }
} else { } else {
if ((millis() - start_time) >= 20) { if ((millis() - start_time) >= 20) {
@ -27,6 +21,7 @@ int ESP32CAN::CANWriteFrame(const CAN_frame_t* p_frame) {
} }
return result; return result;
} }
int ESP32CAN::CANStop() { int ESP32CAN::CANStop() {
return CAN_stop(); return CAN_stop();
} }

View file

@ -9,7 +9,7 @@ class ESP32CAN {
bool tx_ok = true; bool tx_ok = true;
int CANInit(); int CANInit();
int CANConfigFilter(const CAN_filter_t* p_filter); int CANConfigFilter(const CAN_filter_t* p_filter);
int CANWriteFrame(const CAN_frame_t* p_frame); bool CANWriteFrame(const CAN_frame_t* p_frame);
int CANStop(); int CANStop();
void CANSetCfg(CAN_device_t* can_cfg); void CANSetCfg(CAN_device_t* can_cfg);
}; };