mirror of
https://github.com/dalathegreat/Battery-Emulator.git
synced 2025-10-03 17:59:27 +02:00
Merge branch 'main' into feature/tesla-balancing
This commit is contained in:
commit
d638626bbe
16 changed files with 127 additions and 30 deletions
1
.github/workflows/compile-all-hardware.yml
vendored
1
.github/workflows/compile-all-hardware.yml
vendored
|
@ -60,6 +60,7 @@ jobs:
|
||||||
- HW_LILYGO
|
- HW_LILYGO
|
||||||
- HW_STARK
|
- HW_STARK
|
||||||
- HW_3LB
|
- HW_3LB
|
||||||
|
- HW_DEVKIT
|
||||||
|
|
||||||
# This is the platform GitHub will use to run our workflow.
|
# This is the platform GitHub will use to run our workflow.
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
|
@ -58,6 +58,7 @@
|
||||||
//#define HW_LILYGO
|
//#define HW_LILYGO
|
||||||
//#define HW_STARK
|
//#define HW_STARK
|
||||||
//#define HW_3LB
|
//#define HW_3LB
|
||||||
|
//#define HW_DEVKIT
|
||||||
|
|
||||||
/* Contactor settings. If you have a battery that does not activate contactors via CAN, configure this section */
|
/* Contactor settings. If you have a battery that does not activate contactors via CAN, configure this section */
|
||||||
#define PRECHARGE_TIME_MS 500 //Precharge time in milliseconds. Modify to suit your inverter (See wiki for more info)
|
#define PRECHARGE_TIME_MS 500 //Precharge time in milliseconds. Modify to suit your inverter (See wiki for more info)
|
||||||
|
|
|
@ -106,8 +106,8 @@ void update_values_battery() {
|
||||||
/*Finally print out values to serial if configured to do so*/
|
/*Finally print out values to serial if configured to do so*/
|
||||||
#ifdef DEBUG_LOG
|
#ifdef DEBUG_LOG
|
||||||
logging.println("Values going to inverter");
|
logging.println("Values going to inverter");
|
||||||
print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% ");
|
print_units("SOH: ", (datalayer.battery.status.soh_pptt * 0.01), "pct ");
|
||||||
print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% ");
|
print_units(", SOC: ", (datalayer.battery.status.reported_soc * 0.01), "pct ");
|
||||||
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
|
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
|
||||||
print_units(", Max discharge power: ", datalayer.battery.status.max_discharge_power_W, "W ");
|
print_units(", Max discharge power: ", datalayer.battery.status.max_discharge_power_W, "W ");
|
||||||
print_units(", Max charge power: ", datalayer.battery.status.max_charge_power_W, "W ");
|
print_units(", Max charge power: ", datalayer.battery.status.max_charge_power_W, "W ");
|
||||||
|
|
|
@ -695,11 +695,11 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
logging.println("Values from battery: ");
|
logging.println("Values from battery: ");
|
||||||
logging.print("SOC BMS: ");
|
logging.print("SOC BMS: ");
|
||||||
logging.print((uint16_t)SOC_BMS / 10.0, 1);
|
logging.print((uint16_t)SOC_BMS / 10.0, 1);
|
||||||
logging.print("% | SOC Display: ");
|
logging.print("pct | SOC Display: ");
|
||||||
logging.print((uint16_t)SOC_Display / 10.0, 1);
|
logging.print((uint16_t)SOC_Display / 10.0, 1);
|
||||||
logging.print("% | SOH ");
|
logging.print("pct | SOH ");
|
||||||
logging.print((uint16_t)batterySOH / 10.0, 1);
|
logging.print((uint16_t)batterySOH / 10.0, 1);
|
||||||
logging.println("%");
|
logging.println("pct");
|
||||||
logging.print((int16_t)batteryAmps / 10.0, 1);
|
logging.print((int16_t)batteryAmps / 10.0, 1);
|
||||||
logging.print(" Amps | ");
|
logging.print(" Amps | ");
|
||||||
logging.print((uint16_t)batteryVoltage / 10.0, 1);
|
logging.print((uint16_t)batteryVoltage / 10.0, 1);
|
||||||
|
|
|
@ -147,11 +147,11 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
logging.println("Values from battery: ");
|
logging.println("Values from battery: ");
|
||||||
logging.print("SOC BMS: ");
|
logging.print("SOC BMS: ");
|
||||||
logging.print((uint16_t)SOC_BMS / 10.0, 1);
|
logging.print((uint16_t)SOC_BMS / 10.0, 1);
|
||||||
logging.print("% | SOC Display: ");
|
logging.print("pct | SOC Display: ");
|
||||||
logging.print((uint16_t)SOC_Display / 10.0, 1);
|
logging.print((uint16_t)SOC_Display / 10.0, 1);
|
||||||
logging.print("% | SOH ");
|
logging.print("pct | SOH ");
|
||||||
logging.print((uint16_t)batterySOH / 10.0, 1);
|
logging.print((uint16_t)batterySOH / 10.0, 1);
|
||||||
logging.println("%");
|
logging.println("pct");
|
||||||
logging.print((int16_t)batteryAmps / 10.0, 1);
|
logging.print((int16_t)batteryAmps / 10.0, 1);
|
||||||
logging.print(" Amps | ");
|
logging.print(" Amps | ");
|
||||||
logging.print((uint16_t)batteryVoltage / 10.0, 1);
|
logging.print((uint16_t)batteryVoltage / 10.0, 1);
|
||||||
|
|
|
@ -105,9 +105,9 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
|
|
||||||
#ifdef DEBUG_LOG
|
#ifdef DEBUG_LOG
|
||||||
logging.println("Values going to inverter:");
|
logging.println("Values going to inverter:");
|
||||||
logging.print("SOH%: ");
|
logging.print("SOH: ");
|
||||||
logging.print(datalayer.battery.status.soh_pptt);
|
logging.print(datalayer.battery.status.soh_pptt);
|
||||||
logging.print(", SOC% scaled: ");
|
logging.print(", SOC scaled: ");
|
||||||
logging.print(datalayer.battery.status.reported_soc);
|
logging.print(datalayer.battery.status.reported_soc);
|
||||||
logging.print(", Voltage: ");
|
logging.print(", Voltage: ");
|
||||||
logging.print(datalayer.battery.status.voltage_dV);
|
logging.print(datalayer.battery.status.voltage_dV);
|
||||||
|
|
|
@ -2723,7 +2723,7 @@ void print_SOC(char* header, int SOC) {
|
||||||
if (hundredth < 10)
|
if (hundredth < 10)
|
||||||
logging.print(0);
|
logging.print(0);
|
||||||
logging.print(hundredth);
|
logging.print(hundredth);
|
||||||
logging.println("%");
|
logging.println("pct");
|
||||||
}
|
}
|
||||||
|
|
||||||
void printFaultCodesIfActive() {
|
void printFaultCodesIfActive() {
|
||||||
|
@ -2742,7 +2742,7 @@ void printFaultCodesIfActive() {
|
||||||
}
|
}
|
||||||
// Check each symbol and print debug information if its value is 1
|
// Check each symbol and print debug information if its value is 1
|
||||||
// 0X3AA: 938 HVP_alertMatrix1
|
// 0X3AA: 938 HVP_alertMatrix1
|
||||||
printDebugIfActive(battery_WatchdogReset, "ERROR: The processor has experienced a reset due to watchdog reset");
|
//printDebugIfActive(battery_WatchdogReset, "ERROR: The processor has experienced a reset due to watchdog reset"); //Uncommented due to not affecting usage
|
||||||
printDebugIfActive(battery_PowerLossReset, "ERROR: The processor has experienced a reset due to power loss");
|
printDebugIfActive(battery_PowerLossReset, "ERROR: The processor has experienced a reset due to power loss");
|
||||||
printDebugIfActive(battery_SwAssertion, "ERROR: An internal software assertion has failed");
|
printDebugIfActive(battery_SwAssertion, "ERROR: An internal software assertion has failed");
|
||||||
printDebugIfActive(battery_CrashEvent, "ERROR: crash signal is detected by HVP");
|
printDebugIfActive(battery_CrashEvent, "ERROR: crash signal is detected by HVP");
|
||||||
|
@ -2910,7 +2910,7 @@ void printFaultCodesIfActive_battery2() {
|
||||||
"disable the inverter protocol to proceed with contactor closing");
|
"disable the inverter protocol to proceed with contactor closing");
|
||||||
}
|
}
|
||||||
// Check each symbol and print debug information if its value is 1
|
// Check each symbol and print debug information if its value is 1
|
||||||
printDebugIfActive(battery2_WatchdogReset, "ERROR: The processor has experienced a reset due to watchdog reset");
|
//printDebugIfActive(battery2_WatchdogReset, "ERROR: The processor has experienced a reset due to watchdog reset"); //Uncommented due to not affecting usage
|
||||||
printDebugIfActive(battery2_PowerLossReset, "ERROR: The processor has experienced a reset due to power loss");
|
printDebugIfActive(battery2_PowerLossReset, "ERROR: The processor has experienced a reset due to power loss");
|
||||||
printDebugIfActive(battery2_SwAssertion, "ERROR: An internal software assertion has failed");
|
printDebugIfActive(battery2_SwAssertion, "ERROR: An internal software assertion has failed");
|
||||||
printDebugIfActive(battery2_CrashEvent, "ERROR: crash signal is detected by HVP");
|
printDebugIfActive(battery2_CrashEvent, "ERROR: crash signal is detected by HVP");
|
||||||
|
|
|
@ -56,8 +56,8 @@ void update_values_battery() { /* This function puts fake values onto the parame
|
||||||
/*Finally print out values to serial if configured to do so*/
|
/*Finally print out values to serial if configured to do so*/
|
||||||
#ifdef DEBUG_LOG
|
#ifdef DEBUG_LOG
|
||||||
logging.println("FAKE Values going to inverter");
|
logging.println("FAKE Values going to inverter");
|
||||||
print_units("SOH%: ", (datalayer.battery.status.soh_pptt * 0.01), "% ");
|
print_units("SOH: ", (datalayer.battery.status.soh_pptt * 0.01), "pct ");
|
||||||
print_units(", SOC%: ", (datalayer.battery.status.reported_soc * 0.01), "% ");
|
print_units(", SOC: ", (datalayer.battery.status.reported_soc * 0.01), "pct ");
|
||||||
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
|
print_units(", Voltage: ", (datalayer.battery.status.voltage_dV * 0.1), "V ");
|
||||||
print_units(", Max discharge power: ", datalayer.battery.status.max_discharge_power_W, "W ");
|
print_units(", Max discharge power: ", datalayer.battery.status.max_discharge_power_W, "W ");
|
||||||
print_units(", Max charge power: ", datalayer.battery.status.max_charge_power_W, "W ");
|
print_units(", Max charge power: ", datalayer.battery.status.max_charge_power_W, "W ");
|
||||||
|
@ -109,8 +109,8 @@ void update_values_battery2() { // Handle the values coming in from battery #2
|
||||||
/*Finally print out values to serial if configured to do so*/
|
/*Finally print out values to serial if configured to do so*/
|
||||||
#ifdef DEBUG_LOG
|
#ifdef DEBUG_LOG
|
||||||
logging.println("FAKE Values battery 2 going to inverter");
|
logging.println("FAKE Values battery 2 going to inverter");
|
||||||
print_units("SOH 2 %: ", (datalayer.battery2.status.soh_pptt * 0.01), "% ");
|
print_units("SOH 2: ", (datalayer.battery2.status.soh_pptt * 0.01), "pct ");
|
||||||
print_units(", SOC 2 %: ", (datalayer.battery2.status.reported_soc * 0.01), "% ");
|
print_units(", SOC 2: ", (datalayer.battery2.status.reported_soc * 0.01), "pct ");
|
||||||
print_units(", Voltage 2: ", (datalayer.battery2.status.voltage_dV * 0.1), "V ");
|
print_units(", Voltage 2: ", (datalayer.battery2.status.voltage_dV * 0.1), "V ");
|
||||||
print_units(", Max discharge power 2: ", datalayer.battery2.status.max_discharge_power_W, "W ");
|
print_units(", Max discharge power 2: ", datalayer.battery2.status.max_discharge_power_W, "W ");
|
||||||
print_units(", Max charge power 2: ", datalayer.battery2.status.max_charge_power_W, "W ");
|
print_units(", Max charge power 2: ", datalayer.battery2.status.max_charge_power_W, "W ");
|
||||||
|
|
|
@ -95,11 +95,11 @@ void update_values_battery() { //This function maps all the values fetched via
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_LOG
|
#ifdef DEBUG_LOG
|
||||||
logging.print("BMS reported SOC%: ");
|
logging.print("BMS reported SOC: ");
|
||||||
logging.println(SOC_BMS);
|
logging.println(SOC_BMS);
|
||||||
logging.print("Calculated SOC%: ");
|
logging.print("Calculated SOC: ");
|
||||||
logging.println(SOC_CALC);
|
logging.println(SOC_CALC);
|
||||||
logging.print("Rescaled SOC%: ");
|
logging.print("Rescaled SOC: ");
|
||||||
logging.println(datalayer.battery.status.reported_soc / 100);
|
logging.println(datalayer.battery.status.reported_soc / 100);
|
||||||
logging.print("Battery current: ");
|
logging.print("Battery current: ");
|
||||||
logging.println(BATT_I);
|
logging.println(BATT_I);
|
||||||
|
|
|
@ -101,9 +101,6 @@ void map_can_frame_to_variable_charger(CAN_frame rx_frame) {
|
||||||
case 0x308:
|
case 0x308:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
#ifdef DEBUG_LOG
|
|
||||||
logging.printf("CAN Rcv unknown frame MsgID=%x\n", rx_frame.MsgID);
|
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,7 +90,7 @@ void init_CAN() {
|
||||||
logging.println(settings2517.exactArbitrationBitRate() ? "yes)" : "no)");
|
logging.println(settings2517.exactArbitrationBitRate() ? "yes)" : "no)");
|
||||||
logging.print("Arbitration Sample point: ");
|
logging.print("Arbitration Sample point: ");
|
||||||
logging.print(settings2517.arbitrationSamplePointFromBitStart());
|
logging.print(settings2517.arbitrationSamplePointFromBitStart());
|
||||||
logging.println("%");
|
logging.println("pct");
|
||||||
#endif // DEBUG_LOG
|
#endif // DEBUG_LOG
|
||||||
} else {
|
} else {
|
||||||
#ifdef DEBUG_LOG
|
#ifdef DEBUG_LOG
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "hw_stark.h"
|
#include "hw_stark.h"
|
||||||
#elif defined(HW_3LB)
|
#elif defined(HW_3LB)
|
||||||
#include "hw_3LB.h"
|
#include "hw_3LB.h"
|
||||||
|
#elif defined(HW_DEVKIT)
|
||||||
|
#include "hw_devkit.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
93
Software/src/devboard/hal/hw_devkit.h
Normal file
93
Software/src/devboard/hal/hw_devkit.h
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
#ifndef __HW_DEVKIT_H__
|
||||||
|
#define __HW_DEVKIT_H__
|
||||||
|
|
||||||
|
/*
|
||||||
|
ESP32 DevKit V1 development board with 30 pins.
|
||||||
|
For more information, see: https://lastminuteengineers.com/esp32-pinout-reference/.
|
||||||
|
|
||||||
|
The pin layout below supports the following:
|
||||||
|
- 1x RS485
|
||||||
|
- 2x CAN (1x via SN65HVD230 (UART), 1x via MCP2515 (SPI))
|
||||||
|
- 1x CANFD (via MCP2518FD (SPI))
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Board boot-up time
|
||||||
|
#define BOOTUP_TIME 1000 // Time in ms it takes before system is considered fully started up
|
||||||
|
|
||||||
|
// Core assignment
|
||||||
|
#define CORE_FUNCTION_CORE 1
|
||||||
|
#define MODBUS_CORE 0
|
||||||
|
#define WIFI_CORE 0
|
||||||
|
|
||||||
|
// RS485
|
||||||
|
#define RS485_TX_PIN GPIO_NUM_1
|
||||||
|
#define RS485_RX_PIN GPIO_NUM_3
|
||||||
|
|
||||||
|
// CAN settings
|
||||||
|
#define CAN_1_TYPE ESP32CAN
|
||||||
|
//#define CAN_2_TYPE MCP2515
|
||||||
|
//#define CAN_3_TYPE MCP2518FD
|
||||||
|
|
||||||
|
// CAN1 PIN mappings, do not change these unless you are adding on extra hardware to the PCB
|
||||||
|
#define CAN_TX_PIN GPIO_NUM_27
|
||||||
|
#define CAN_RX_PIN GPIO_NUM_26
|
||||||
|
|
||||||
|
// CAN_ADDON defines
|
||||||
|
#define MCP2515_SCK GPIO_NUM_22 // SCK input of MCP2515
|
||||||
|
#define MCP2515_MOSI GPIO_NUM_21 // SDI input of MCP2515
|
||||||
|
#define MCP2515_MISO GPIO_NUM_19 // SDO output of MCP2515
|
||||||
|
#define MCP2515_CS GPIO_NUM_18 // CS input of MCP2515
|
||||||
|
#define MCP2515_INT GPIO_NUM_23 // INT output of MCP2515
|
||||||
|
|
||||||
|
// CANFD_ADDON defines
|
||||||
|
#define MCP2517_SCK GPIO_NUM_33 // SCK input of MCP2517
|
||||||
|
#define MCP2517_SDI GPIO_NUM_32 // SDI input of MCP2517
|
||||||
|
#define MCP2517_SDO GPIO_NUM_35 // SDO output of MCP2517 | Pin 35 is input only, without pullup/down resistors
|
||||||
|
#define MCP2517_CS GPIO_NUM_25 // CS input of MCP2517
|
||||||
|
#define MCP2517_INT GPIO_NUM_34 // INT output of MCP2517 | Pin 34 is input only, without pullup/down resistors
|
||||||
|
|
||||||
|
// Contactor handling
|
||||||
|
#define POSITIVE_CONTACTOR_PIN GPIO_NUM_5
|
||||||
|
#define NEGATIVE_CONTACTOR_PIN GPIO_NUM_16
|
||||||
|
#define PRECHARGE_PIN GPIO_NUM_17
|
||||||
|
|
||||||
|
// SMA CAN contactor pins
|
||||||
|
#define INVERTER_CONTACTOR_ENABLE_PIN GPIO_NUM_14
|
||||||
|
|
||||||
|
// LED
|
||||||
|
#define LED_PIN GPIO_NUM_4
|
||||||
|
#define LED_MAX_BRIGHTNESS 40
|
||||||
|
#define INVERTER_CONTACTOR_ENABLE_LED_PIN GPIO_NUM_2
|
||||||
|
|
||||||
|
// Equipment stop pin
|
||||||
|
#define EQUIPMENT_STOP_PIN GPIO_NUM_12
|
||||||
|
|
||||||
|
// BMW_I3_BATTERY wake up pin
|
||||||
|
#ifdef BMW_I3_BATTERY
|
||||||
|
#define WUP_PIN1 GPIO_NUM_25 // Wake up pin for battery 1
|
||||||
|
#ifdef DOUBLE_BATTERY
|
||||||
|
#define WUP_PIN2 GPIO_NUM_32 // Wake up pin for battery 2
|
||||||
|
#endif // DOUBLE_BATTERY
|
||||||
|
#endif // BMW_I3_BATTERY
|
||||||
|
|
||||||
|
/* ----- Error checks below, don't change (can't be moved to separate file) ----- */
|
||||||
|
#ifndef HW_CONFIGURED
|
||||||
|
#define HW_CONFIGURED
|
||||||
|
#else
|
||||||
|
#error Multiple HW defined! Please select a single HW
|
||||||
|
#endif // HW_CONFIGURED
|
||||||
|
|
||||||
|
#ifdef CHADEMO_BATTERY
|
||||||
|
#error CHADEMO pins are not defined for this hardware.
|
||||||
|
#endif // CHADEMO_BATTERY
|
||||||
|
|
||||||
|
#ifdef BMW_I3_BATTERY
|
||||||
|
#if defined(WUP_PIN1) && defined(CANFD_ADDON)
|
||||||
|
#error GPIO PIN 25 cannot be used for both BMWi3 Wakeup and a CANFD addon board using these pins. Choose between BMW_I3_BATTERY and CANFD_ADDON
|
||||||
|
#endif // defined(WUP_PIN1) && defined(CANFD_ADDON)
|
||||||
|
#if defined(WUP_PIN2) && defined(CANFD_ADDON)
|
||||||
|
#error GPIO PIN 32 cannot be used for both BMWi3 Wakeup and a CANFD addon board using these pins. Choose between BMW_I3_BATTERY and CANFD_ADDON
|
||||||
|
#endif // defined(WUP_PIN2) && defined(CANFD_ADDON)
|
||||||
|
#endif // BMW_I3_BATTERY
|
||||||
|
|
||||||
|
#endif // __HW_DEVKIT_H__
|
|
@ -83,6 +83,11 @@
|
||||||
#error Multiple HW defined! Please select a single HW
|
#error Multiple HW defined! Please select a single HW
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CAN_ADDON) && defined(CANFD_ADDON)
|
||||||
|
// Check that user did not try to use dual can and fd-can on same hardware pins
|
||||||
|
#error CAN_ADDON AND CANFD_ADDON CANNOT BE USED SIMULTANEOUSLY
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CHADEMO_BATTERY
|
#ifdef CHADEMO_BATTERY
|
||||||
#ifdef CAN_ADDON
|
#ifdef CAN_ADDON
|
||||||
#error CHADEMO and CAN_ADDON cannot coexist due to overlapping GPIO pin usage
|
#error CHADEMO and CAN_ADDON cannot coexist due to overlapping GPIO pin usage
|
||||||
|
|
|
@ -650,7 +650,10 @@ String get_firmware_info_processor(const String& var) {
|
||||||
#endif // HW_STARK
|
#endif // HW_STARK
|
||||||
#ifdef HW_3LB
|
#ifdef HW_3LB
|
||||||
doc["hardware"] = "3LB board";
|
doc["hardware"] = "3LB board";
|
||||||
#endif // HW_STARK
|
#endif // HW_3LB
|
||||||
|
#ifdef HW_DEVKIT
|
||||||
|
doc["hardware"] = "ESP32 DevKit V1";
|
||||||
|
#endif // HW_DEVKIT
|
||||||
|
|
||||||
doc["firmware"] = String(version_number);
|
doc["firmware"] = String(version_number);
|
||||||
serializeJson(doc, content);
|
serializeJson(doc, content);
|
||||||
|
|
|
@ -23,11 +23,6 @@
|
||||||
#error You must select a target hardware in the USER_SERTTINGS.h file!
|
#error You must select a target hardware in the USER_SERTTINGS.h file!
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(CAN_ADDON) && defined(CANFD_ADDON)
|
|
||||||
// Check that user did not try to use dual can and fd-can on same hardware pins
|
|
||||||
#error CAN_ADDON AND CANFD_ADDON CANNOT BE USED SIMULTANEOUSLY
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_CANFD_INTERFACE_AS_CLASSIC_CAN
|
#ifdef USE_CANFD_INTERFACE_AS_CLASSIC_CAN
|
||||||
#if !defined(CANFD_ADDON)
|
#if !defined(CANFD_ADDON)
|
||||||
// Check that user did not try to use classic CAN over FD, without FD component
|
// Check that user did not try to use classic CAN over FD, without FD component
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue