Skip to content

Commit

Permalink
Add support for triple CAN using 3LB
Browse files Browse the repository at this point in the history
  • Loading branch information
dalathegreat committed Nov 27, 2024
1 parent 4232da8 commit b449068
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 19 deletions.
69 changes: 69 additions & 0 deletions Software/Software.ino
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ static ACAN2515_Buffer16 gBuffer;
#ifdef CAN_FD
#include "src/lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h"
ACAN2517FD canfd(MCP2517_CS, SPI, MCP2517_INT);
#ifdef HW_3LB
//The 3LB board has 2x CAN-FD channels added on
ACAN2517FD canfd2(SECOND_MCP2517_CS, SPI, SECOND_MCP2517_INT);
#endif
#endif //CAN_FD

// ModbusRTU parameters
Expand Down Expand Up @@ -511,6 +515,38 @@ void init_CAN() {
#endif
set_event(EVENT_CANFD_INIT_FAILURE, (uint8_t)errorCode);
}
#ifdef HW_3LB
// Initialize CAN-FD2
const uint32_t errorCode2 = canfd2.begin(settings, [] { canfd2.isr(); });
canfd2.poll();
if (errorCode2 == 0) {
#ifdef DEBUG_VIA_USB
Serial.print("CAN-FD2 initialized. Bit Rate prescaler: ");
Serial.println(settings.mBitRatePrescaler);
Serial.print("Arbitration Phase segment 1: ");
Serial.println(settings.mArbitrationPhaseSegment1);
Serial.print("Arbitration Phase segment 2: ");
Serial.println(settings.mArbitrationPhaseSegment2);
Serial.print("Arbitration SJW: ");
Serial.println(settings.mArbitrationSJW);
Serial.print("Actual Arbitration Bit Rate: ");
Serial.print(settings.actualArbitrationBitRate());
Serial.println(" bit/s");
Serial.print("Exact Arbitration Bit Rate ? ");
Serial.println(settings.exactArbitrationBitRate() ? "yes" : "no");
Serial.print("Arbitration Sample point: ");
Serial.print(settings.arbitrationSamplePointFromBitStart());
Serial.println("%");
#endif
} else {
#ifdef DEBUG_VIA_USB
Serial.print("CAN-FD2 Configuration error 0x");
Serial.println(errorCode2, HEX);
#endif
set_event(EVENT_CANFD_INIT_FAILURE, (uint8_t)errorCode2);
}
#endif //HW_3LB

#endif
}

Expand Down Expand Up @@ -700,6 +736,22 @@ void receive_canfd() { // This section checks if we have a complete CAN-FD mess
receive_can(&rx_frame, CAN_ADDON_FD_MCP2518);
receive_can(&rx_frame, CANFD_NATIVE);
}
#ifdef HW_3LB
CANFDMessage frame2;
if (canfd2.available()) {
canfd2.receive(frame2);

CAN_frame rx_frame2;
rx_frame2.ID = frame2.id;
rx_frame2.ext_ID = frame2.ext;
rx_frame2.DLC = frame2.len;
for (uint8_t i = 0; i < rx_frame2.DLC && i < 64; i++) {
rx_frame2.data.u8[i] = frame2.data[i];
}
//message incoming, pass it on to the handler
receive_can(&rx_frame2, CANFD_TRIPLE);
}
#endif
}
#endif

Expand Down Expand Up @@ -1192,6 +1244,23 @@ void transmit_can(CAN_frame* tx_frame, int interface) {
}
#else // Interface not compiled, and settings try to use it
set_event(EVENT_INTERFACE_MISSING, interface);
#endif //CAN_FD
} break;
case CANFD_TRIPLE: {
#ifdef CAN_FD
CANFDMessage MCP2518Frame2;
MCP2518Frame2.id = tx_frame->ID;
MCP2518Frame2.ext = tx_frame->ext_ID ? CAN_frame_ext : CAN_frame_std;
MCP2518Frame2.len = tx_frame->DLC;
for (uint8_t i = 0; i < MCP2518Frame2.len; i++) {
MCP2518Frame2.data[i] = tx_frame->data.u8[i];
}
send_ok = canfd2.tryToSend(MCP2518Frame2);
if (!send_ok) {
set_event(EVENT_CANFD_BUFFER_FULL, interface);
}
#else // Interface not compiled, and settings try to use it
set_event(EVENT_INTERFACE_MISSING, interface);
#endif //CAN_FD
} break;
default:
Expand Down
13 changes: 7 additions & 6 deletions Software/USER_SETTINGS.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
/* They can be defined here, or later on in the WebUI */
/* Most important is to select which CAN interface each component is connected to */
/*
CAN_NATIVE = Native CAN port on the LilyGo & Stark hardware
CANFD_NATIVE = Native CANFD port on the Stark CMR hardware
CAN_NATIVE = Native CAN port on the LilyGo, Stark and 3LB hardware
CANFD_NATIVE = Native CANFD port on the Stark CMR hardware (CAN2 on 3LB)
CAN_ADDON_MCP2515 = Add-on CAN MCP2515 connected to GPIO pins
CAN_ADDON_FD_MCP2518 = Add-on CAN-FD MCP2518 connected to GPIO pins
CANFD_TRIPLE = CAN3 on 3LB hardware
*/

volatile CAN_Configuration can_config = {
.battery = CAN_NATIVE, // Which CAN is your battery connected to?
.inverter = CAN_NATIVE, // Which CAN is your inverter connected to? (No need to configure incase you use RS485)
.battery_double = CAN_ADDON_MCP2515, // (OPTIONAL) Which CAN is your second battery connected to?
.charger = CAN_NATIVE // (OPTIONAL) Which CAN is your charger connected to?
.battery = CAN_NATIVE, // Which CAN is your battery connected to?
.inverter = CANFD_NATIVE, // Which CAN is your inverter connected to? (No need to configure incase you use RS485)
.battery_double = CANFD_TRIPLE, // (OPTIONAL) Which CAN is your second battery connected to?
.charger = CAN_NATIVE // (OPTIONAL) Which CAN is your charger connected to?
};

#ifdef WIFI
Expand Down
21 changes: 12 additions & 9 deletions Software/USER_SETTINGS.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
//#define TESLA_MODEL_SX_BATTERY
//#define TESLA_MODEL_3Y_BATTERY
//#define VOLVO_SPA_BATTERY
//#define TEST_FAKE_BATTERY
#define TEST_FAKE_BATTERY
//#define DOUBLE_BATTERY //Enable this line if you use two identical batteries at the same time (requires DUAL_CAN setup)

/* Select inverter communication protocol. See Wiki for which to use with your inverter: https://github.com/dalathegreat/BYD-Battery-Emulator-For-Gen24/wiki */
Expand All @@ -52,9 +52,9 @@
//#define SOLAX_CAN //Enable this line to emulate a "SolaX Triple Power LFP" over CAN bus

/* Select hardware used for Battery-Emulator */
#define HW_LILYGO
//#define HW_LILYGO
//#define HW_STARK
//#define HW_3LB
#define HW_3LB

/* Contactor settings. If you have a battery that does not activate contactors via CAN, configure this section */
//#define CONTACTOR_CONTROL //Enable this line to have the emulator handle automatic precharge/contactor+/contactor- closing sequence (See wiki for pins)
Expand All @@ -68,12 +68,9 @@
//#define INTERLOCK_REQUIRED //Nissan LEAF specific setting, if enabled requires both high voltage conenctors to be seated before starting
//#define DUAL_CAN //Enable this line to activate an isolated secondary CAN Bus using add-on MCP2515 chip (Needed for some inverters / double battery)
#define CRYSTAL_FREQUENCY_MHZ 8 //DUAL_CAN option, what is your MCP2515 add-on boards crystal frequency?
//#define CAN_FD //Enable this line to activate an isolated secondary CAN-FD bus using add-on MCP2518FD chip / Native CANFD on Stark board
#ifdef CAN_FD // CAN_FD additional options if enabled
#define CAN_FD //Enable this line to activate an isolated secondary CAN-FD bus using add-on MCP2518FD chip / Native CANFD on Stark board
#define CAN_FD_CRYSTAL_FREQUENCY_MHZ \
ACAN2517FDSettings:: \
OSC_40MHz //CAN_FD option, what is your MCP2518 add-on boards crystal frequency? (Default OSC_40MHz)
#endif
ACAN2517FDSettings::OSC_40MHz //CAN_FD option, what is your MCP2518 add-on boards crystal frequency?
//#define USE_CANFD_INTERFACE_AS_CLASSIC_CAN // Enable this line if you intend to use the CANFD as normal CAN
//#define SERIAL_LINK_RECEIVER //Enable this line to receive battery data over RS485 pins from another Lilygo (This LilyGo interfaces with inverter)
//#define SERIAL_LINK_TRANSMITTER //Enable this line to send battery data over RS485 pins to another Lilygo (This LilyGo interfaces with battery)
Expand Down Expand Up @@ -130,7 +127,13 @@

/* Do not change any code below this line unless you are sure what you are doing */
/* Only change battery specific settings in "USER_SETTINGS.h" */
typedef enum { CAN_NATIVE = 0, CANFD_NATIVE = 1, CAN_ADDON_MCP2515 = 2, CAN_ADDON_FD_MCP2518 = 3 } CAN_Interface;
typedef enum {
CAN_NATIVE = 0,
CANFD_NATIVE = 1,
CAN_ADDON_MCP2515 = 2,
CAN_ADDON_FD_MCP2518 = 3,
CANFD_TRIPLE = 4
} CAN_Interface;
typedef struct {
CAN_Interface battery;
CAN_Interface inverter;
Expand Down
17 changes: 13 additions & 4 deletions Software/src/devboard/hal/hw_3LB.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,39 @@
#define RS485_RX_PIN 3 // 22
//#define RS485_SE_PIN 19 // 22 /SHDN

// CAN settings. CAN_2 is not defined as it can be either MCP2515 or MCP2517, defined by the user settings
// CAN settings. CAN_2/3 can be either CANFD or MCP2515
#define CAN_1_TYPE ESP32CAN
#define CAN_2_TYPE CANFD
#define CAN_3_TYPE CANFD

// 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
//#define CAN_SE_PIN 23

// CAN2 defines below

/* DOES NOT EXIST IN 3LB
// DUAL_CAN defines
#define MCP2515_SCK 12 // SCK input of MCP2515
#define MCP2515_MOSI 5 // SDI input of MCP2515
#define MCP2515_MISO 34 // SDO output of MCP2515 | Pin 34 is input only, without pullup/down resistors
#define MCP2515_CS 18 // CS input of MCP2515
#define MCP2515_INT 35 // INT output of MCP2515 | | Pin 35 is input only, without pullup/down resistors
*/

// CAN_FD defines
// CAN_FD the first defines
#define MCP2517_SCK 17 // SCK input of MCP2517
#define MCP2517_SDI 23 // SDI input of MCP2517
#define MCP2517_SDO 39 // SDO output of MCP2517
#define MCP2517_CS 21 // CS input of MCP2517 //21 or 22
#define MCP2517_INT 34 // INT output of MCP2517 //34 or 35

// CAN_FD the 2nd defines
//#define MCP2517_SCK 17 // SCK input of MCP2517 (Same as first SCK define)
//#define MCP2517_SDI 23 // SDI input of MCP2517 (Same as first SDI define)
//#define MCP2517_SDO 39 // SDO output of MCP2517 (Same as first SDO define)
#define SECOND_MCP2517_CS 22 // CS input of MCP2517 //21 or 22
#define SECOND_MCP2517_INT 35 // INT output of MCP2517 //34 or 35

// CHAdeMO support pin dependencies
#define CHADEMO_PIN_2 12
#define CHADEMO_PIN_10 5
Expand Down

0 comments on commit b449068

Please sign in to comment.