diff --git a/Makefile b/Makefile index c84b18e8..d0384fbf 100644 --- a/Makefile +++ b/Makefile @@ -43,8 +43,9 @@ OBJSL = $(BINARY).o hwinit.o stm32scheduler.o params.o terminal.o terminal_prj. param_save.o errormessage.o stm32_can.o leafinv.o utils.o terminalcommands.o i3LIM.o \ chademo.o amperaheater.o amperacharger.o subaruvehicle.o iomatrix.o bmw_sbox.o NissanPDM.o teslaCharger.o extCharger.o vag_sbox.o \ daisychainbms.o simpbms.o outlanderCharger.o Can_OBD2.o cansdo.o TeslaDCDC.o BMW_E31.o F30_Lever.o \ - CPC.o ElconCharger.o RearOutlanderinverter.o linbus.o VWheater.o JLR_G1.o JLR_G2.o Foccci.o digipot.o\ - OutlanderHeartBeat.o E65_Lever.o leafbms.o V_Classic.o kangoobms.o OutlanderCanHeater.o NissLeafMng.o + CPC.o ElconCharger.o RearOutlanderinverter.o linbus.o VWCoolantHeater.o JLR_G1.o JLR_G2.o Focci.o digipot.o\ + OutlanderHeartBeat.o E65_Lever.o leafbms.o V_Classic.o kangoobms.o OutlanderCanHeater.o VWAirHeater.o\ + MGCoolantHeater.o OBJS = $(patsubst %.o,$(OUT_DIR)/%.o, $(OBJSL)) vpath %.c src/ libopeninv/src/ diff --git a/include/MGCoolantHeater.h b/include/MGCoolantHeater.h new file mode 100644 index 00000000..7bb2e95b --- /dev/null +++ b/include/MGCoolantHeater.h @@ -0,0 +1,45 @@ +/* + * This file is part of the Zombieverter VCU project. + * + * Copyright (C) 2018 Johannes Huebner + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef MGCOOLANTHEATER_H +#define MGCOOLANTHEATER_H + +//#include +#include + + +class mgCoolantHeater : public Heater +{ + public: + void SetTargetTemperature(float temp); + void SetCanInterface(CanHardware* c); + void DecodeCAN(int id, uint32_t data[2]); + void SetPower(uint16_t power, bool HeatReq); + void Task100Ms(); + + private: + int8_t currentTemperature; + int8_t desiredTemperature; + + bool shouldHeat; + static void handle2B5(uint32_t data[2]); + static void handle2B6(uint32_t data[2]); + +}; + +#endif // MGCOOLANTHEATER_H diff --git a/include/VWAirHeater.h b/include/VWAirHeater.h new file mode 100644 index 00000000..35d2a671 --- /dev/null +++ b/include/VWAirHeater.h @@ -0,0 +1,41 @@ +/* + * This file is part of the Zombieverter VCU project. + * + * Copyright (C) 2024 Tom de Bree + * Copyright (C) 2018 Johannes Huebner + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * Controls the VW LIN based heater as : https://openinverter.org/wiki/Volkswagen_Heater + */ +#ifndef VWAIRHEATER_H +#define VWAIRTHEATER_H + +//#include +#include +#include "linbus.h" + + +class vwAirHeater : public Heater +{ + public: + void SetTargetTemperature(float temp) { (void)temp; } //Not supported (yet)? + void SetPower(uint16_t power, bool HeatReq); + void SetLinInterface(LinBus* l); + + private: + bool isAwake=false; + LinBus* lin; +}; + +#endif // VWAirHEATER_H diff --git a/include/VWheater.h b/include/VWCoolantHeater.h similarity index 91% rename from include/VWheater.h rename to include/VWCoolantHeater.h index 3187a978..e38c3813 100644 --- a/include/VWheater.h +++ b/include/VWCoolantHeater.h @@ -17,16 +17,15 @@ * along with this program. If not, see . * Controls the VW LIN based heater as : https://openinverter.org/wiki/Volkswagen_Heater */ - -#ifndef VWHEATER_H -#define VWHEATER_H +#ifndef VWCOOLANTHEATER_H +#define VWCOOLANTHEATER_H //#include #include #include "linbus.h" -class vwHeater : public Heater +class vwCoolantHeater : public Heater { public: void SetTargetTemperature(float temp) { (void)temp; } //Not supported (yet)? @@ -36,6 +35,6 @@ class vwHeater : public Heater private: bool isAwake=false; LinBus* lin; -}; -#endif // VWHEATER_H +}; +#endif // VWCOOLANTHEATER_H diff --git a/include/param_prj.h b/include/param_prj.h index 20db773d..67ab283f 100644 --- a/include/param_prj.h +++ b/include/param_prj.h @@ -18,8 +18,7 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -#define VER 2.22.A +#define VER 2.30.TA /* Entries must be ordered as follows: @@ -105,7 +104,7 @@ PARAM_ENTRY(CAT_BMS, BMS_VmaxLimit, "V", 0, 10, 4.2, 93 ) \ PARAM_ENTRY(CAT_BMS, BMS_TminLimit, "°C", -100, 100, 5, 94 ) \ PARAM_ENTRY(CAT_BMS, BMS_TmaxLimit, "°C", -100, 100, 50, 95 ) \ - PARAM_ENTRY(CAT_HEATER, Heater, HTTYPE, 0, 3, 0, 57 ) \ + PARAM_ENTRY(CAT_HEATER, Heater, HTTYPE, 0, 5, 0, 57 ) \ PARAM_ENTRY(CAT_HEATER, Control, HTCTRL, 0, 2, 0, 58 ) \ PARAM_ENTRY(CAT_HEATER, HeatPwr, "W", 0, 6500, 0, 59 ) \ PARAM_ENTRY(CAT_HEATER, HeatPercnt, "%", 0, 100, 0, 124 ) \ @@ -285,7 +284,7 @@ #define ERRLIGHTS "0=Off, 4=EPC, 8=engine" #define CRUISESTATES "0=None, 1=On, 2=Disable, 4=Set, 8=Resume" #define CDMSTAT "1=Charging, 2=Malfunction, 4=ConnLock, 8=BatIncomp, 16=SystemMalfunction, 32=Stop" -#define HTTYPE "0=None, 1=Ampera, 2=VW, 3=OutlanderCan" +#define HTTYPE "0=None, 1=Ampera, 2=VWCoolant, 3=VWAir, 4=OutlanderCan, 5=MGCoolant" #define HTCTRL "0=Disable, 1=Enable, 2=Timer" #define CHGMODS "0=Off, 1=EXT_DIGI, 2=Volt_Ampera, 3=Leaf_PDM, 4=TeslaOI, 5=Out_lander, 6=Elcon" #define CHGCTRL "0=Enable, 1=Disable, 2=Timer" @@ -388,8 +387,10 @@ enum HeatType { Noheater = 0, AmpHeater = 1, - VW = 2, - OutlanderHeater = 3 + VWCoolant = 2, + VWAir = 3, + OutlanderHeater = 4, + MGCoolant = 5 }; enum BMSModes diff --git a/src/MGCoolantHeater.cpp b/src/MGCoolantHeater.cpp new file mode 100644 index 00000000..49c1fde8 --- /dev/null +++ b/src/MGCoolantHeater.cpp @@ -0,0 +1,110 @@ +/* + * This file is part of the Zombieverter VCU project. + * + * Copyright (C) 2018 Johannes Huebner + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * Controls the MG heater as : https://openinverter.org/wiki/MG_Coolant_Heater + * + * Based on reverse engineer work by Tom de Bree + * + */ + +#include + +static uint16_t HvVolt = 0; + +void mgCoolantHeater::SetPower(uint16_t power, bool HeatReq) +{ + shouldHeat = HeatReq; + power = power;//mask warning +} + +void mgCoolantHeater::SetCanInterface(CanHardware* c) +{ + + can = c; + can->RegisterUserMessage(0x2B5); + can->RegisterUserMessage(0x2B6); +} + +void mgCoolantHeater::Task100Ms() +{ + uint8_t bytes[8]; + bytes[0] = 0x00; //No Power! + bytes[1] = 0x00; //No Power! + bytes[2] = 0x01; //Fixed + bytes[3] = 0x00; //Fixed + bytes[4] = 0x00; //Fixed + bytes[5] = 0x60; //Fixed + bytes[6] = 0x00; //Fixed + bytes[7] = 0x00; //Fixed + + if (shouldHeat) + { + bytes[0] = 0x04; //Max Power!!!! 0x04 gives 19A + bytes[1] = 0x0F; //Max Power!!!! 0x0F gives 19A + } + else + { + + } + + can->Send(0x2A0, (uint32_t*)bytes, 8); +} + +void mgCoolantHeater::SetTargetTemperature(float temp) +{ + desiredTemperature = temp; +} + +void mgCoolantHeater::DecodeCAN(int id, uint32_t data[2]) +{ + switch (id) + { + case 0x2B5: + mgCoolantHeater::handle2B5(data); + break; + case 0x2B6: + mgCoolantHeater::handle2B6(data); + break; + } +} + +void mgCoolantHeater::handle2B5(uint32_t data[2]) +{ + uint8_t* bytes = (uint8_t*)data;// arrgghhh this converts the two 32bit array into bytes. See comments are useful:) + + uint8_t HvCur = bytes[4];//0.75A/1 + + Param::SetFloat(Param::powerheater,(HvVolt*HvCur*0.75)); +} + +void mgCoolantHeater::handle2B6(uint32_t data[2]) +{ + uint8_t* bytes = (uint8_t*)data;// arrgghhh this converts the two 32bit array into bytes. See comments are useful:) + + uint8_t temp1 = bytes[6]; + uint16_t temp2 = bytes[4]|((bytes[3] &0x0F)<<8); + + temp2 = temp2; //remove warning for unused variable + + HvVolt = bytes[2]; //tbc scaling + + Param::SetFloat(Param::tmpheater, temp1*0.75); //temp 1 appears to be scaled by 0.75C/1 + + + Param::SetInt(Param::udcheater,HvVolt); + +} diff --git a/src/VWAirHeater.cpp b/src/VWAirHeater.cpp new file mode 100644 index 00000000..546bc26e --- /dev/null +++ b/src/VWAirHeater.cpp @@ -0,0 +1,84 @@ +/* + * This file is part of the Zombieverter VCU project. + * + * Copyright (C) 2024 Tom de Bree + * Copyright (C) 2018 Johannes Huebner + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * Controls the VW LIN based heater as : https://openinverter.org/wiki/VAG_PTC_Air_Heater + * + * Based on reverse engineer work by Tom de Bree + * + */ + +#include + +static uint8_t processedPower=0; +static uint8_t TenCount=0; + + +void vwAirHeater::SetLinInterface(LinBus* l) +{ + lin = l; + DigIo::lin_wake.Clear();//Not used on TJA1027 + DigIo::lin_nslp.Set();//Wakes the device + +} + +void vwAirHeater::SetPower(uint16_t power, bool HeatReq) +{ + TenCount++; + if(TenCount==5)//slow down to 50ms as this is called in 10ms task. + { + TenCount=0; + HeatReq=HeatReq; + //going to ignore heatreq here, already used to determine to run this sequence. + + if(power>=255) power = 255;//Constrain power to max for VW heater. + processedPower=power;//10; + + static bool read = true; + + if (lin->HasReceived(19, 8))//0x13 hex address + { + uint8_t* data = lin->GetReceivedBytes(); + + Param::SetFloat(Param::tmpheater, data[5]*0.25);//Looks like the temp feedback 1 + Param::SetFloat(Param::udcheater, data[1]*2);//HV Voltage feedback + Param::SetFloat(Param::powerheater,data[0]*data[1]);//HV current is Byte 0 in 0.5A per/1 and HV voltage is byte 1 2V/1 so they cancel + } + + if (read) + { + lin->Request(19, 0, 0);//0x13 hex address + } + + else + { + uint8_t PowReq = Param::GetInt(Param::HeatPercnt);//VW heater uses a % setting as opposed to a set power val. Regulates its temps to this. + uint8_t lindata[8]; + lindata[0] = 0x39; //fixed + lindata[1] = 0xC5;//fixed + lindata[2] = PowReq; //Left Request 0-100, tested even at 120 to confirm max values + lindata[3] = PowReq; //Right Request 0-100, tested even at 120 to confirm max values + lindata[4] = 0; //fixed + lindata[5] = 0xAA; //fixed + lindata[6] = 0x78; //Power Limit? 0x50 and 0x78 tested + lindata[7] = 0; //fixed + lin->Request(38, lindata, sizeof(lindata));//0x26 hex address + } + + read = !read; + } +} diff --git a/src/VWheater.cpp b/src/VWCoolantHeater.cpp similarity index 95% rename from src/VWheater.cpp rename to src/VWCoolantHeater.cpp index 7abcabae..ff9171e2 100644 --- a/src/VWheater.cpp +++ b/src/VWCoolantHeater.cpp @@ -27,13 +27,13 @@ * Observed data with heater running approx 4kw : 0x32, 0xFC, 0x80, 0x80, 0x8D, 0x5D, 0x7A, 0x77 */ - #include + #include static uint8_t processedPower=0; static uint8_t TenCount=0; - void vwHeater::SetLinInterface(LinBus* l) + void vwCoolantHeater::SetLinInterface(LinBus* l) { lin = l; DigIo::lin_wake.Clear();//Not used on TJA1027 @@ -42,7 +42,7 @@ } - void vwHeater::SetPower(uint16_t power, bool HeatReq) + void vwCoolantHeater::SetPower(uint16_t power, bool HeatReq) { TenCount++; if(TenCount==5)//slow down to 50ms as this is called in 10ms task. diff --git a/src/stm32_vcu.cpp b/src/stm32_vcu.cpp index 38f66e11..49f279ce 100644 --- a/src/stm32_vcu.cpp +++ b/src/stm32_vcu.cpp @@ -95,7 +95,8 @@ #include "Foccci.h" #include "NoInverter.h" #include "linbus.h" -#include "VWheater.h" +#include "VWCoolantHeater.h" +#include "VWAirHeater.h" #include "ElconCharger.h" #include "rearoutlanderinverter.h" #include "NoVehicle.h" @@ -103,6 +104,7 @@ #include "kangoobms.h" #include "OutlanderCanHeater.h" #include "OutlanderHeartBeat.h" +#include "MGCoolantHeater.h" #define PRECHARGE_TIMEOUT 5 //5s @@ -172,7 +174,9 @@ static F30_Lever F30GearLever; static E65_Lever E65GearLever; static JLR_G1 JLRG1shift; static JLR_G2 JLRG2shift; -static vwHeater heaterVW; +static vwCoolantHeater heaterCoolantVW; +static mgCoolantHeater heaterCoolantMG; +static vwAirHeater heaterAirVW; static NoVehicle VehicleNone; static V_Classic classVehicle; static Inverter* selectedInverter = &openInv; @@ -881,9 +885,16 @@ static void UpdateHeater() case HeatType::AmpHeater: selectedHeater = &eraHeater; break; - case HeatType::VW: - selectedHeater = &heaterVW; - heaterVW.SetLinInterface(lin); + case HeatType::VWCoolant: + selectedHeater = &heaterCoolantVW; + heaterCoolantVW.SetLinInterface(lin); + break; + case HeatType::VWAir: + selectedHeater = &heaterCoolantVW; + heaterCoolantVW.SetLinInterface(lin); + break; + case HeatType::MGCoolant: + selectedHeater = &heaterCoolantMG; break; case HeatType::OutlanderHeater: selectedHeater = &outlanderCanHeater;