Merge branch 'main' into tesla-bugfixes

This commit is contained in:
Marijn van Galen 2025-01-27 21:08:42 +01:00 committed by GitHub
commit 30de0d8bde
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 129 additions and 1472 deletions

View file

@ -472,7 +472,7 @@ void update_values_battery() { //This function maps all the values fetched via
if (isMinCellVoltageStale && isMaxCellVoltageStale) {
datalayer.battery.status.cell_min_voltage_mV = 9999; //Stale values force stop
datalayer.battery.status.cell_max_voltage_mV = 9999; //Stale values force stop
set_event(EVENT_CAN_RX_FAILURE, 0);
set_event(EVENT_STALE_VALUE, 0);
} else {
datalayer.battery.status.cell_min_voltage_mV = min_cell_voltage; //Value is alive
datalayer.battery.status.cell_max_voltage_mV = max_cell_voltage; //Value is alive

View file

@ -614,7 +614,7 @@ void update_values_battery() { //This function maps all the values fetched via
battery_current != 0) { //Ignore stale values if there is no current flowing
datalayer.battery.status.cell_min_voltage_mV = 9999; //Stale values force stop
datalayer.battery.status.cell_max_voltage_mV = 9999; //Stale values force stop
set_event(EVENT_CAN_RX_FAILURE, 0);
set_event(EVENT_STALE_VALUE, 0);
#ifdef DEBUG_LOG
logging.println("Stale Min/Max voltage values detected during charge/discharge sending - 9999mV...");
#endif // DEBUG_LOG

View file

@ -672,14 +672,6 @@ void update_values_battery() { //This function maps all the values fetched via
set_voltage_minmax_limits(); // Count cells, and set voltage limits accordingly
}
/* Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error*/
if (!datalayer.battery.status.CAN_battery_still_alive) {
set_event(EVENT_CANFD_RX_FAILURE, 0);
} else {
datalayer.battery.status.CAN_battery_still_alive--;
clear_event(EVENT_CANFD_RX_FAILURE);
}
if (waterleakageSensor == 0) {
set_event(EVENT_WATER_INGRESS, 0);
}

File diff suppressed because it is too large Load diff

View file

@ -52,6 +52,7 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) {
switch (rx_frame.ID) {
//ID 0x212 conveys instantaneous DC charger stats
case 0x212:
datalayer.charger.CAN_charger_still_alive = CAN_STILL_ALIVE; // Let system know charger is sending CAN
charger_stat_HVcur_temp = (uint16_t)(rx_frame.data.u8[0] << 8 | rx_frame.data.u8[1]);
datalayer.charger.charger_stat_HVcur = (float)(charger_stat_HVcur_temp >> 3) * 0.05;
@ -68,6 +69,7 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) {
//ID 0x30A conveys instantaneous AC charger stats
case 0x30A:
datalayer.charger.CAN_charger_still_alive = CAN_STILL_ALIVE; // Let system know charger is sending CAN
charger_stat_ACcur_temp = (uint16_t)((rx_frame.data.u8[0] << 8 | rx_frame.data.u8[1]) >> 4);
datalayer.charger.charger_stat_ACcur = (float)(charger_stat_ACcur_temp) * 0.2;
@ -80,10 +82,13 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) {
// 0x266 and 0x308 are len 5
// 0x268 may be temperature data (len 8). Could resemble the Lear charger equivalent TODO
case 0x266:
datalayer.charger.CAN_charger_still_alive = CAN_STILL_ALIVE; // Let system know charger is sending CAN
break;
case 0x268:
datalayer.charger.CAN_charger_still_alive = CAN_STILL_ALIVE; // Let system know charger is sending CAN
break;
case 0x308:
datalayer.charger.CAN_charger_still_alive = CAN_STILL_ALIVE; // Let system know charger is sending CAN
break;
default:
#ifdef DEBUG_LOG

View file

@ -118,6 +118,7 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) {
switch (rx_frame.ID) {
case 0x679: // This message fires once when charging cable is plugged in
datalayer.charger.CAN_charger_still_alive = CAN_STILL_ALIVE; // Let system know charger is sending CAN
OBCwakeup = true;
datalayer.charger.charger_aux12V_enabled = true; //Not possible to turn off 12V charging on LEAF PDM
// Startout with default values, so that charging can begin right when user plugs in cable
@ -126,6 +127,7 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) {
datalayer.charger.charger_setpoint_HV_VDC = 400; // Target voltage
break;
case 0x390:
datalayer.charger.CAN_charger_still_alive = CAN_STILL_ALIVE; // Let system know charger is sending CAN
OBC_Charge_Status = ((rx_frame.data.u8[5] & 0x7E) >> 1);
if (OBC_Charge_Status == PLUGGED_IN_WAITING_ON_TIMER || CHARGING_OR_INTERRUPTED) {
PPStatus = true; //plug inserted
@ -146,6 +148,9 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) {
OBC_Charge_Power = ((rx_frame.data.u8[0] & 0x01) << 8) | (rx_frame.data.u8[1]);
datalayer.charger.charger_stat_HVcur = OBC_Charge_Power;
break;
case 0x393:
datalayer.charger.CAN_charger_still_alive = CAN_STILL_ALIVE; // Let system know charger is sending CAN
break;
default:
break;
}

View file

@ -6,7 +6,8 @@
CAN_device_t CAN_cfg; // CAN Config
const int rx_queue_size = 10; // Receive Queue size
volatile bool send_ok = 0;
volatile bool send_ok_2515 = 0;
volatile bool send_ok_2518 = 0;
#ifdef CAN_ADDON
static const uint32_t QUARTZ_FREQUENCY = CRYSTAL_FREQUENCY_MHZ * 1000000UL; //MHZ configured in USER_SETTINGS.h
@ -156,7 +157,13 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface) {
for (uint8_t i = 0; i < MCP2515Frame.len; i++) {
MCP2515Frame.data[i] = tx_frame->data.u8[i];
}
can.tryToSend(MCP2515Frame);
send_ok_2515 = can.tryToSend(MCP2515Frame);
if (!send_ok_2515) {
set_event(EVENT_CAN_BUFFER_FULL, interface);
} else {
clear_event(EVENT_CAN_BUFFER_FULL);
}
#else // Interface not compiled, and settings try to use it
set_event(EVENT_INTERFACE_MISSING, interface);
#endif //CAN_ADDON
@ -176,8 +183,8 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface) {
for (uint8_t i = 0; i < MCP2518Frame.len; i++) {
MCP2518Frame.data[i] = tx_frame->data.u8[i];
}
send_ok = canfd.tryToSend(MCP2518Frame);
if (!send_ok) {
send_ok_2518 = canfd.tryToSend(MCP2518Frame);
if (!send_ok_2518) {
set_event(EVENT_CANFD_BUFFER_FULL, interface);
} else {
clear_event(EVENT_CANFD_BUFFER_FULL);

View file

@ -86,7 +86,7 @@ typedef struct {
uint16_t CAN_error_counter;
/** uint8_t */
/** A counter set each time a new message comes from battery.
* This value then gets decremented each 5 seconds. Incase we reach 0
* This value then gets decremented every second. Incase we reach 0
* we report the battery as missing entirely on the CAN bus.
*/
uint8_t CAN_battery_still_alive = CAN_STILL_ALIVE;
@ -171,6 +171,12 @@ typedef struct {
bool charger_HV_enabled = false;
/** True if the 12V DC/DC output is enabled */
bool charger_aux12V_enabled = false;
/** uint8_t */
/** A counter set each time a new message comes from charger.
* This value then gets decremented every second. Incase we reach 0
* we report the battery as missing entirely on the CAN bus.
*/
uint8_t CAN_charger_still_alive = CAN_STILL_ALIVE;
} DATALAYER_CHARGER_TYPE;
typedef struct {
@ -256,7 +262,7 @@ typedef struct {
#endif
/** uint8_t */
/** A counter set each time a new message comes from inverter.
* This value then gets decremented each 5 seconds. Incase we reach 0
* This value then gets decremented every second. Incase we reach 0
* we report the inverter as missing entirely on the CAN bus.
*/
uint8_t CAN_inverter_still_alive = CAN_STILL_ALIVE;

View file

@ -163,31 +163,41 @@ void update_machineryprotection() {
// Check if the BMS is still sending CAN messages. If we go 60s without messages we raise an error
if (!datalayer.battery.status.CAN_battery_still_alive) {
set_event(EVENT_CAN_RX_FAILURE, 0);
set_event(EVENT_CAN_BATTERY_MISSING, can_config.battery);
} else {
datalayer.battery.status.CAN_battery_still_alive--;
clear_event(EVENT_CAN_RX_FAILURE);
clear_event(EVENT_CAN_BATTERY_MISSING);
}
// Too many malformed CAN messages recieved!
if (datalayer.battery.status.CAN_error_counter > MAX_CAN_FAILURES) {
set_event(EVENT_CAN_RX_WARNING, 1);
set_event(EVENT_CAN_CORRUPTED_WARNING, can_config.battery);
} else {
clear_event(EVENT_CAN_RX_WARNING);
clear_event(EVENT_CAN_CORRUPTED_WARNING);
}
#ifdef CAN_INVERTER_SELECTED
// Check if the inverter is still sending CAN messages. If we go 60s without messages we raise an error
// Check if the inverter is still sending CAN messages. If we go 60s without messages we raise a warning
if (!datalayer.system.status.CAN_inverter_still_alive) {
set_event(EVENT_CAN_INVERTER_MISSING, 0);
set_event(EVENT_CAN_INVERTER_MISSING, can_config.inverter);
} else {
datalayer.system.status.CAN_inverter_still_alive--;
clear_event(EVENT_CAN_INVERTER_MISSING);
}
#endif //CAN_INVERTER_SELECTED
#ifdef CHARGER_SELECTED
// Check if the charger is still sending CAN messages. If we go 60s without messages we raise a warning
if (!datalayer.charger.CAN_charger_still_alive) {
set_event(EVENT_CAN_CHARGER_MISSING, can_config.charger);
} else {
datalayer.charger.CAN_charger_still_alive--;
clear_event(EVENT_CAN_CHARGER_MISSING);
}
#endif //CHARGER_SELECTED
#ifdef DOUBLE_BATTERY // Additional Double-Battery safeties are checked here
// Check if the Battery 2 BMS is still sending CAN messages. If we go 60s without messages we raise an error
// Check if the Battery 2 BMS is still sending CAN messages. If we go 60s without messages we raise a warning
// Pause function is on
if (emulator_pause_request_ON) {
@ -196,17 +206,17 @@ void update_machineryprotection() {
}
if (!datalayer.battery2.status.CAN_battery_still_alive) {
set_event(EVENT_CAN2_RX_FAILURE, 0);
set_event(EVENT_CAN_BATTERY2_MISSING, can_config.battery_double);
} else {
datalayer.battery2.status.CAN_battery_still_alive--;
clear_event(EVENT_CAN2_RX_FAILURE);
clear_event(EVENT_CAN_BATTERY2_MISSING);
}
// Too many malformed CAN messages recieved!
if (datalayer.battery2.status.CAN_error_counter > MAX_CAN_FAILURES) {
set_event(EVENT_CAN_RX_WARNING, 2);
set_event(EVENT_CAN_CORRUPTED_WARNING, can_config.battery_double);
} else {
clear_event(EVENT_CAN_RX_WARNING);
clear_event(EVENT_CAN_CORRUPTED_WARNING);
}
// Cell overvoltage, critical latching error without automatic reset. Requires user action.

View file

@ -133,13 +133,13 @@ void init_events(void) {
events.entries[EVENT_CANMCP2517FD_INIT_FAILURE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CANMCP2515_INIT_FAILURE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CANFD_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_CANFD_RX_OVERRUN].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_RX_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_CAN2_RX_FAILURE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CANFD_RX_FAILURE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_CAN_RX_WARNING].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_TX_FAILURE].level = EVENT_LEVEL_ERROR;
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_BATTERY_MISSING].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_CAN_BATTERY2_MISSING].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CAN_CHARGER_MISSING].level = EVENT_LEVEL_INFO;
events.entries[EVENT_CAN_INVERTER_MISSING].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_CONTACTOR_WELDED].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_WATER_INGRESS].level = EVENT_LEVEL_ERROR;
@ -148,6 +148,7 @@ void init_events(void) {
events.entries[EVENT_12V_LOW].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_SOC_PLAUSIBILITY_ERROR].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_SOC_UNAVAILABLE].level = EVENT_LEVEL_WARNING;
events.entries[EVENT_STALE_VALUE].level = EVENT_LEVEL_ERROR;
events.entries[EVENT_KWH_PLAUSIBILITY_ERROR].level = EVENT_LEVEL_INFO;
events.entries[EVENT_BALANCING_START].level = EVENT_LEVEL_INFO;
events.entries[EVENT_BALANCING_END].level = EVENT_LEVEL_INFO;
@ -265,23 +266,23 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
case EVENT_CANMCP2515_INIT_FAILURE:
return "CAN-MCP addon initialization failed. Check hardware";
case EVENT_CANFD_BUFFER_FULL:
return "CAN-FD buffer overflowed. Some CAN messages were not sent. Contact developers.";
return "MCP2518FD buffer overflowed. Some CAN messages were not sent. Contact developers.";
case EVENT_CAN_BUFFER_FULL:
return "MCP2515 buffer overflowed. Some CAN messages were not sent. Contact developers.";
case EVENT_CAN_OVERRUN:
return "CAN message failed to send within defined time. Contact developers, CPU load might be too high.";
case EVENT_CANFD_RX_OVERRUN:
return "CAN-FD failed to receive all messages from CAN bus. Contact developers, CPU load might be too high.";
case EVENT_CAN_RX_FAILURE:
return "No CAN communication detected for 60s. Shutting down battery control.";
case EVENT_CAN2_RX_FAILURE:
return "No CAN communication detected for 60s on CAN2. Shutting down the secondary battery control.";
case EVENT_CANFD_RX_FAILURE:
return "No CANFD communication detected for 60s. Shutting down battery control.";
case EVENT_CAN_RX_WARNING:
case EVENT_CAN_CORRUPTED_WARNING:
return "High amount of corrupted CAN messages detected. Check CAN wire shielding!";
case EVENT_CAN_TX_FAILURE:
return "CAN messages failed to transmit, or no one on the bus to ACK the message!";
case EVENT_CAN_NATIVE_TX_FAILURE:
return "CAN_NATIVE failed to transmit, or no one on the bus to ACK the message!";
case EVENT_CAN_BATTERY_MISSING:
return "Battery not sending messages via CAN for the last 60 seconds. Check wiring!";
case EVENT_CAN_BATTERY2_MISSING:
return "Secondary battery not sending messages via CAN for the last 60 seconds. Check wiring!";
case EVENT_CAN_CHARGER_MISSING:
return "Charger not sending messages via CAN for the last 60 seconds. Check wiring!";
case EVENT_CAN_INVERTER_MISSING:
return "Inverter not sending messages on CAN bus. Check wiring!";
return "Inverter not sending messages via CAN for the last 60 seconds. Check wiring!";
case EVENT_CONTACTOR_WELDED:
return "Contactors sticking/welded. Inspect battery with caution!";
case EVENT_CHARGE_LIMIT_EXCEEDED:
@ -296,6 +297,8 @@ const char* get_event_message_string(EVENTS_ENUM_TYPE event) {
return "SOC reported by battery not plausible. Restart battery!";
case EVENT_SOC_UNAVAILABLE:
return "SOC not sent by BMS. Calibrate BMS via app.";
case EVENT_STALE_VALUE:
return "Important values detected as stale. System might have locked up!";
case EVENT_KWH_PLAUSIBILITY_ERROR:
return "kWh remaining reported by battery not plausible. Battery needs cycling.";
case EVENT_BALANCING_START:

View file

@ -6,7 +6,7 @@
// #define INCLUDE_EVENTS_TEST // Enable to run an event test loop, see events_test_on_target.cpp
#define EE_MAGIC_HEADER_VALUE 0x0021 // 0x0000 to 0xFFFF
#define EE_MAGIC_HEADER_VALUE 0x0022 // 0x0000 to 0xFFFF
#define GENERATE_ENUM(ENUM) ENUM,
#define GENERATE_STRING(STRING) #STRING,
@ -29,14 +29,14 @@
XX(EVENT_CANMCP2517FD_INIT_FAILURE) \
XX(EVENT_CANMCP2515_INIT_FAILURE) \
XX(EVENT_CANFD_BUFFER_FULL) \
XX(EVENT_CAN_BUFFER_FULL) \
XX(EVENT_CAN_OVERRUN) \
XX(EVENT_CANFD_RX_OVERRUN) \
XX(EVENT_CAN_RX_FAILURE) \
XX(EVENT_CAN2_RX_FAILURE) \
XX(EVENT_CANFD_RX_FAILURE) \
XX(EVENT_CAN_RX_WARNING) \
XX(EVENT_CAN_TX_FAILURE) \
XX(EVENT_CAN_CORRUPTED_WARNING) \
XX(EVENT_CAN_BATTERY_MISSING) \
XX(EVENT_CAN_BATTERY2_MISSING) \
XX(EVENT_CAN_CHARGER_MISSING) \
XX(EVENT_CAN_INVERTER_MISSING) \
XX(EVENT_CAN_NATIVE_TX_FAILURE) \
XX(EVENT_CHARGE_LIMIT_EXCEEDED) \
XX(EVENT_CONTACTOR_WELDED) \
XX(EVENT_DISCHARGE_LIMIT_EXCEEDED) \
@ -44,6 +44,7 @@
XX(EVENT_12V_LOW) \
XX(EVENT_SOC_PLAUSIBILITY_ERROR) \
XX(EVENT_SOC_UNAVAILABLE) \
XX(EVENT_STALE_VALUE) \
XX(EVENT_KWH_PLAUSIBILITY_ERROR) \
XX(EVENT_BALANCING_START) \
XX(EVENT_BALANCING_END) \

View file

@ -15,10 +15,10 @@ int ESP32CAN::CANWriteFrame(const CAN_frame_t* p_frame) {
#ifdef DEBUG_VIA_USB
Serial.println("CAN failure! Check wires");
#endif
set_event(EVENT_CAN_TX_FAILURE, 0);
set_event(EVENT_CAN_NATIVE_TX_FAILURE, 0);
start_time = millis();
} else {
clear_event(EVENT_CAN_TX_FAILURE);
clear_event(EVENT_CAN_NATIVE_TX_FAILURE);
}
} else {
if ((millis() - start_time) >= 20) {