From 5b55197c5efc5250dc1aed39baf7760f09d2aed8 Mon Sep 17 00:00:00 2001 From: Jaakko Haakana Date: Sun, 13 Jul 2025 09:35:11 +0300 Subject: [PATCH] Let batteries select CAN speed --- Software/src/battery/BMW-PHEV-BATTERY.cpp | 4 +-- Software/src/battery/CELLPOWER-BMS.h | 2 +- Software/src/battery/CanBattery.cpp | 12 +++---- Software/src/battery/CanBattery.h | 9 +++--- Software/src/battery/RJXZS-BMS.h | 2 +- Software/src/communication/can/comm_can.cpp | 36 ++++++++------------- Software/src/communication/can/comm_can.h | 17 ++++++++-- 7 files changed, 40 insertions(+), 42 deletions(-) diff --git a/Software/src/battery/BMW-PHEV-BATTERY.cpp b/Software/src/battery/BMW-PHEV-BATTERY.cpp index ce4820a1..65693a4d 100644 --- a/Software/src/battery/BMW-PHEV-BATTERY.cpp +++ b/Software/src/battery/BMW-PHEV-BATTERY.cpp @@ -188,12 +188,12 @@ void BmwPhevBattery::wake_battery_via_canbus() { // Followed by a Recessive interval of at least ~3 µs (min) and at most ~10 µs (max) // Then a second dominant pulse of similar timing. - slow_down_can(); + auto original_speed = change_can_speed(CAN_Speed::CAN_SPEED_250KBPS); transmit_can_frame(&BMW_PHEV_BUS_WAKEUP_REQUEST, can_config.battery); transmit_can_frame(&BMW_PHEV_BUS_WAKEUP_REQUEST, can_config.battery); - resume_full_speed(); + change_can_speed(original_speed); #ifdef DEBUG_LOG logging.println("Sent magic wakeup packet to SME at 100kbps..."); diff --git a/Software/src/battery/CELLPOWER-BMS.h b/Software/src/battery/CELLPOWER-BMS.h index 25ae6c49..77eb9713 100644 --- a/Software/src/battery/CELLPOWER-BMS.h +++ b/Software/src/battery/CELLPOWER-BMS.h @@ -11,7 +11,7 @@ class CellPowerBms : public CanBattery { public: - CellPowerBms() : CanBattery(true) {} + CellPowerBms() : CanBattery(CAN_Speed::CAN_SPEED_250KBPS) {} virtual void setup(void); virtual void handle_incoming_can_frame(CAN_frame rx_frame); diff --git a/Software/src/battery/CanBattery.cpp b/Software/src/battery/CanBattery.cpp index 18076266..ad6dadca 100644 --- a/Software/src/battery/CanBattery.cpp +++ b/Software/src/battery/CanBattery.cpp @@ -1,16 +1,12 @@ #include "CanBattery.h" #include "../../src/include.h" -CanBattery::CanBattery(bool halfSpeed) { +CanBattery::CanBattery(CAN_Speed speed) { can_interface = can_config.battery; register_transmitter(this); - register_can_receiver(this, can_interface, halfSpeed); + register_can_receiver(this, can_interface, speed); } -void CanBattery::slow_down_can() { - ::slow_down_can(can_interface); -} - -void CanBattery::resume_full_speed() { - ::resume_full_speed(can_interface); +CAN_Speed CanBattery::change_can_speed(CAN_Speed speed) { + return ::change_can_speed(can_interface, speed); } diff --git a/Software/src/battery/CanBattery.h b/Software/src/battery/CanBattery.h index 04707971..a59fe3e2 100644 --- a/Software/src/battery/CanBattery.h +++ b/Software/src/battery/CanBattery.h @@ -23,16 +23,15 @@ class CanBattery : public Battery, Transmitter, CanReceiver { protected: CAN_Interface can_interface; - CanBattery(bool halfSpeed = false); + CanBattery(CAN_Speed speed = CAN_Speed::CAN_SPEED_500KBPS); - CanBattery(CAN_Interface interface, bool halfSpeed = false) { + CanBattery(CAN_Interface interface, CAN_Speed speed = CAN_Speed::CAN_SPEED_500KBPS) { can_interface = interface; register_transmitter(this); - register_can_receiver(this, can_interface, halfSpeed); + register_can_receiver(this, can_interface, speed); } - void slow_down_can(); - void resume_full_speed(); + CAN_Speed change_can_speed(CAN_Speed speed); }; #endif diff --git a/Software/src/battery/RJXZS-BMS.h b/Software/src/battery/RJXZS-BMS.h index bbdf995c..ff5eae70 100644 --- a/Software/src/battery/RJXZS-BMS.h +++ b/Software/src/battery/RJXZS-BMS.h @@ -11,7 +11,7 @@ class RjxzsBms : public CanBattery { public: - RjxzsBms() : CanBattery(true) {} + RjxzsBms() : CanBattery(CAN_Speed::CAN_SPEED_250KBPS) {} virtual void setup(void); virtual void handle_incoming_can_frame(CAN_frame rx_frame); diff --git a/Software/src/communication/can/comm_can.cpp b/Software/src/communication/can/comm_can.cpp index 260f0647..5a8701c2 100644 --- a/Software/src/communication/can/comm_can.cpp +++ b/Software/src/communication/can/comm_can.cpp @@ -5,12 +5,13 @@ #include "../../lib/miwagner-ESP32-Arduino-CAN/ESP32CAN.h" #include "../../lib/pierremolinaro-ACAN2517FD/ACAN2517FD.h" #include "../../lib/pierremolinaro-acan2515/ACAN2515.h" +#include "comm_can.h" #include "src/devboard/sdcard/sdcard.h" #include "src/devboard/utils/logging.h" struct CanReceiverRegistration { CanReceiver* receiver; - bool halfSpeed; + CAN_Speed speed; }; static std::multimap can_receivers; @@ -32,8 +33,8 @@ bool use_canfd_as_can = use_canfd_as_can_default; void map_can_frame_to_variable(CAN_frame* rx_frame, CAN_Interface interface); -void register_can_receiver(CanReceiver* receiver, CAN_Interface interface, bool halfSpeed) { - can_receivers.insert({interface, {receiver, halfSpeed}}); +void register_can_receiver(CanReceiver* receiver, CAN_Interface interface, CAN_Speed speed) { + can_receivers.insert({interface, {receiver, speed}}); DEBUG_PRINTF("CAN receiver registered, total: %d\n", can_receivers.size()); } @@ -69,11 +70,7 @@ bool init_CAN() { digitalWrite(se_pin, LOW); } - if (nativeIt->second.halfSpeed) { - CAN_cfg.speed = CAN_SPEED_250KBPS; - } else { - CAN_cfg.speed = CAN_SPEED_500KBPS; - } + CAN_cfg.speed = (CAN_speed_t)nativeIt->second.speed; if (!esp32hal->alloc_pins("CAN", tx_pin, rx_pin)) { return false; @@ -109,7 +106,7 @@ bool init_CAN() { SPI2515.begin(sck_pin, miso_pin, mosi_pin); // CAN bit rate 250 or 500 kb/s - auto bitRate = addonIt->second.halfSpeed ? 250UL * 1000UL : 500UL * 1000UL; + auto bitRate = (int)addonIt->second.speed * 1000UL; settings2515 = new ACAN2515Settings(QUARTZ_FREQUENCY, bitRate); settings2515->mRequestedMode = ACAN2515Settings::NormalMode; @@ -133,8 +130,7 @@ bool init_CAN() { if (fdNativeIt != can_receivers.end() || fdAddonIt != can_receivers.end()) { - auto slow = (fdNativeIt != can_receivers.end() && fdNativeIt->second.halfSpeed) || - (fdAddonIt != can_receivers.end() && fdAddonIt->second.halfSpeed); + auto speed = (fdNativeIt != can_receivers.end()) ? fdNativeIt->second.speed : fdAddonIt->second.speed; auto cs_pin = esp32hal->MCP2517_CS(); auto int_pin = esp32hal->MCP2517_INT(); @@ -152,7 +148,7 @@ bool init_CAN() { logging.println("CAN FD add-on (ESP32+MCP2517) selected"); #endif // DEBUG_LOG SPI2517.begin(sck_pin, sdo_pin, sdi_pin); - auto bitRate = slow ? 250UL * 1000UL : 500UL * 1000UL; + auto bitRate = (int)speed * 1000UL; settings2517 = new ACAN2517FDSettings( CANFD_ADDON_CRYSTAL_FREQUENCY_MHZ, bitRate, DataBitRateFactor::x4); // Arbitration bit rate: 250/500 kbit/s, data bit rate: 1/2 Mbit/s @@ -446,16 +442,12 @@ void restart_can() { } } -void slow_down_can(CAN_Interface interface) { +CAN_Speed change_can_speed(CAN_Interface interface, CAN_Speed speed) { + auto oldSpeed = (CAN_Speed)CAN_cfg.speed; if (interface == CAN_Interface::CAN_NATIVE) { - CAN_cfg.speed = CAN_SPEED_100KBPS; //Slow down canbus to achieve wakeup timings - ESP32Can.CANInit(); // ReInit native CAN module at new speed - } -} - -void resume_full_speed(CAN_Interface interface) { - if (interface == CAN_Interface::CAN_NATIVE) { - CAN_cfg.speed = CAN_SPEED_500KBPS; //Resume fullspeed - ESP32Can.CANInit(); // ReInit native CAN module at new speed + CAN_cfg.speed = (CAN_speed_t)speed; + // ReInit native CAN module at new speed + ESP32Can.CANInit(); } + return oldSpeed; } diff --git a/Software/src/communication/can/comm_can.h b/Software/src/communication/can/comm_can.h index f0936eec..b2327eb3 100644 --- a/Software/src/communication/can/comm_can.h +++ b/Software/src/communication/can/comm_can.h @@ -10,10 +10,21 @@ void transmit_can_frame(CAN_frame* tx_frame, int interface); class CanReceiver; +enum class CAN_Speed { + CAN_SPEED_100KBPS = 100, + CAN_SPEED_125KBPS = 125, + CAN_SPEED_200KBPS = 200, + CAN_SPEED_250KBPS = 250, + CAN_SPEED_500KBPS = 500, + CAN_SPEED_800KBPS = 800, + CAN_SPEED_1000KBPS = 1000 +}; + // Register a receiver object for a given CAN interface. // By default receivers expect the CAN interface to be operated at "fast" speed. // If halfSpeed is true, half speed is used. -void register_can_receiver(CanReceiver* receiver, CAN_Interface interface, bool halfSpeed = false); +void register_can_receiver(CanReceiver* receiver, CAN_Interface interface, + CAN_Speed speed = CAN_Speed::CAN_SPEED_500KBPS); /** * @brief Initializes all CAN interfaces requested earlier by other modules (see register_can_receiver) @@ -75,7 +86,7 @@ void stop_can(); // Restart CAN communication for all interfaces void restart_can(); -void slow_down_can(CAN_Interface interface); -void resume_full_speed(CAN_Interface interface); +// Change the speed of the CAN interface and return the old speed. +CAN_Speed change_can_speed(CAN_Interface interface, CAN_Speed speed); #endif