Compare commits
13 Commits
877508d047
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 2c9e7a8bbe | |||
| b7fcd2b301 | |||
| e36ba2ccc5 | |||
| 02e3f2643f | |||
| ee59f69890 | |||
| 7acbd66907 | |||
| fb721f7392 | |||
| 5dc715558f | |||
| f566427835 | |||
| 00f359250c | |||
| 7de46b8160 | |||
| 20339b738b | |||
| 3580123a39 |
@@ -4,3 +4,4 @@ stm32_charger*
|
|||||||
linker.map
|
linker.map
|
||||||
*.layout
|
*.layout
|
||||||
*.out
|
*.out
|
||||||
|
.DS_Store
|
||||||
|
|||||||
+9
-4
@@ -39,15 +39,15 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
//Define a version string of your firmware here
|
//Define a version string of your firmware here
|
||||||
#define VER 1.19.R
|
#define VER 1.20.R
|
||||||
|
|
||||||
/* Entries must be ordered as follows:
|
/* Entries must be ordered as follows:
|
||||||
1. Saveable parameters (id != 0)
|
1. Saveable parameters (id != 0)
|
||||||
2. Temporary parameters (id = 0)
|
2. Temporary parameters (id = 0)
|
||||||
3. Display values
|
3. Display values
|
||||||
*/
|
*/
|
||||||
//Next param id (increase when adding new parameter!): 23
|
//Next param id (increase when adding new parameter!): 24
|
||||||
//Next value Id: 2051
|
//Next value Id: 2052
|
||||||
/* category name unit min max default id */
|
/* category name unit min max default id */
|
||||||
#define PARAM_LIST \
|
#define PARAM_LIST \
|
||||||
PARAM_ENTRY(CAT_CHARGER, idclim, "A", 0, 45, 45, 3 ) \
|
PARAM_ENTRY(CAT_CHARGER, idclim, "A", 0, 45, 45, 3 ) \
|
||||||
@@ -63,6 +63,7 @@
|
|||||||
PARAM_ENTRY(CAT_CHARGER, enablepol, POLARITIES,0, 1, 0, 18 ) \
|
PARAM_ENTRY(CAT_CHARGER, enablepol, POLARITIES,0, 1, 0, 18 ) \
|
||||||
PARAM_ENTRY(CAT_CHARGER, idckp, "", 0, 10000, 1, 20 ) \
|
PARAM_ENTRY(CAT_CHARGER, idckp, "", 0, 10000, 1, 20 ) \
|
||||||
PARAM_ENTRY(CAT_CHARGER, idcki, "", 0, 10000, 10, 21 ) \
|
PARAM_ENTRY(CAT_CHARGER, idcki, "", 0, 10000, 10, 21 ) \
|
||||||
|
PARAM_ENTRY(CAT_CHARGER, vcuchglim, "%", 20, 100, 80, 23 ) \
|
||||||
VALUE_ENTRY(state, STATES, 2043 ) \
|
VALUE_ENTRY(state, STATES, 2043 ) \
|
||||||
VALUE_ENTRY(uptime, "s", 2048 ) \
|
VALUE_ENTRY(uptime, "s", 2048 ) \
|
||||||
VALUE_ENTRY(lasterr, errorListString, 2002 ) \
|
VALUE_ENTRY(lasterr, errorListString, 2002 ) \
|
||||||
@@ -107,6 +108,7 @@
|
|||||||
VALUE_ENTRY(c3iac, "A", 2034 ) \
|
VALUE_ENTRY(c3iac, "A", 2034 ) \
|
||||||
VALUE_ENTRY(c3udc, "V", 2035 ) \
|
VALUE_ENTRY(c3udc, "V", 2035 ) \
|
||||||
VALUE_ENTRY(c3idc, "A", 2036 ) \
|
VALUE_ENTRY(c3idc, "A", 2036 ) \
|
||||||
|
VALUE_ENTRY(tmpobcmax, "°C", 2051 ) \
|
||||||
VALUE_ENTRY(test_time, "s", 3000 ) \
|
VALUE_ENTRY(test_time, "s", 3000 ) \
|
||||||
VALUE_ENTRY(test_timer_flag, "X", 3001 ) \
|
VALUE_ENTRY(test_timer_flag, "X", 3001 ) \
|
||||||
VALUE_ENTRY(test_timer_icvalue, "X", 3002 ) \
|
VALUE_ENTRY(test_timer_icvalue, "X", 3002 ) \
|
||||||
@@ -124,7 +126,10 @@
|
|||||||
#define CAT_CHARGER "Charger"
|
#define CAT_CHARGER "Charger"
|
||||||
#define CAT_COMM "Communication"
|
#define CAT_COMM "Communication"
|
||||||
|
|
||||||
#define VERSTR STRINGIFY(4=VER)
|
// SKUDAK customization suffix: bump on every Skudak-side change so the OpenInverter
|
||||||
|
// web UI shows a distinct version (e.g. "4=1.20.R-S4") and we can visually confirm
|
||||||
|
// the right firmware is flashed. Match the stm32-sine -S<N> convention.
|
||||||
|
#define VERSTR STRINGIFY(4=VER-S5)
|
||||||
|
|
||||||
/***** enums ******/
|
/***** enums ******/
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -85,9 +85,15 @@ bool CheckTimeout()
|
|||||||
bool CheckDelay()
|
bool CheckDelay()
|
||||||
{
|
{
|
||||||
uint32_t now = rtc_get_counter_val();
|
uint32_t now = rtc_get_counter_val();
|
||||||
uint32_t start = Param::GetInt(Param::timedly) * 60;
|
// Upstream uses uint32_t here, which wraps a negative timedly (the param's
|
||||||
|
// documented -1 "no delay" sentinel) into a ~4 billion-second timeout that
|
||||||
|
// never expires — leaving the state machine wedged in WaitStart forever.
|
||||||
|
// Use signed math for the short-circuit so timedly <= 0 still means
|
||||||
|
// "start immediately." The cast on the elapsed-comparison side is only
|
||||||
|
// reached when start > 0, so it can't reinterpret a negative as huge.
|
||||||
|
int start = Param::GetInt(Param::timedly) * 60;
|
||||||
|
|
||||||
return start <= 0 || (now - startTime) > start;
|
return start <= 0 || (now - startTime) > (uint32_t)start;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+23
-2
@@ -100,6 +100,27 @@ void ChargerCAN::MapMessages(CanMap* can)
|
|||||||
can->AddSend(Param::idc, 0x109, 24, 16, 1);
|
can->AddSend(Param::idc, 0x109, 24, 16, 1);
|
||||||
can->AddSend(Param::opmode, 0x109, 40, 3, 5); //Set charging and connlock at once
|
can->AddSend(Param::opmode, 0x109, 40, 3, 5); //Set charging and connlock at once
|
||||||
|
|
||||||
/***** Auxiliary TX *****/
|
/***** SKUDAK VCU command RX (0x212) — SKUDAK-516 user ChargeLimit *****/
|
||||||
can->AddSend(Param::uaux, 0x210, 0, 8, 10); //12V aux battery: byte 0, gain=10 (0.1V/decivolts, SKUDAK-448)
|
// Byte 0: ChargeLimit_pct (0-100). Bytes 1-7 reserved 0x00.
|
||||||
|
// Param::Change(vcuchglim) translates % to udcspnt setpoint (see src/main.cpp).
|
||||||
|
// VCU broadcasts every 200 ms once teslacharger detected; charger holds last
|
||||||
|
// value if VCU goes silent.
|
||||||
|
can->AddRecv(Param::vcuchglim, 0x212, 0, 8, 1);
|
||||||
|
|
||||||
|
/***** SKUDAK VCU telemetry (0x211) — SKUDAK-448 expanded charger telemetry *****/
|
||||||
|
// Byte 0: state (0=Off, 1=WaitStart, 2=Enable, 3=Activate, 4=Run, 5=Stop)
|
||||||
|
// Bytes 1-2: udc (V, gain=1)
|
||||||
|
// Bytes 3-4: idc (0.1A, gain=10)
|
||||||
|
// Byte 5: uaux (decivolts, gain=10) — 12V aux battery rail
|
||||||
|
// Byte 6: soc (%, gain=1)
|
||||||
|
// Byte 7: tmpobcmax (°C, gain=1, offset=-40) — worst-case across all
|
||||||
|
// 9 OBC probes; matches Tesla OBC's own CAN offset
|
||||||
|
// so receivers can decode with the same formula.
|
||||||
|
// Consumed by stm32-hal-vcu Core/Src/main.c CHARGER_CAN_ID_OI_OBC_AUX handler.
|
||||||
|
can->AddSend(Param::state, 0x211, 0, 8, 1);
|
||||||
|
can->AddSend(Param::udc, 0x211, 8, 16, 1);
|
||||||
|
can->AddSend(Param::idc, 0x211, 24, 16, 10);
|
||||||
|
can->AddSend(Param::uaux, 0x211, 40, 8, 10);
|
||||||
|
can->AddSend(Param::soc, 0x211, 48, 8, 1);
|
||||||
|
can->AddSend(Param::tmpobcmax, 0x211, 56, 8, 1, 40); // offset 40 → wire byte = temp + 40
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-1
@@ -77,6 +77,32 @@ static void Ms100Task(void)
|
|||||||
|
|
||||||
EvseRead();
|
EvseRead();
|
||||||
|
|
||||||
|
// SKUDAK: derive a single "worst case" OBC temperature for downstream
|
||||||
|
// consumers (Polarity VCU broadcasts it on STATUS_SCREEN bytes 23/26).
|
||||||
|
// Aggregates the 9 per-module probes the Tesla OBC publishes on CAN
|
||||||
|
// 0x237/0x239/0x23B — max wins. Modules without a sensor read -40 °C
|
||||||
|
// (the DBC offset; raw byte 0); we ignore those so an absent module
|
||||||
|
// doesn't drag the worst-case down. If no probes are valid we leave
|
||||||
|
// tmpobcmax at -40 °C, which the VCU will display as "—".
|
||||||
|
{
|
||||||
|
const Param::PARAM_NUM probes[] = {
|
||||||
|
Param::c1tmp1, Param::c1tmp2, Param::c1tmpin,
|
||||||
|
Param::c2tmp1, Param::c2tmp2, Param::c2tmpin,
|
||||||
|
Param::c3tmp1, Param::c3tmp2, Param::c3tmpin,
|
||||||
|
};
|
||||||
|
int worst = -40;
|
||||||
|
bool any_ok = false;
|
||||||
|
for (unsigned i = 0; i < sizeof(probes) / sizeof(probes[0]); i++) {
|
||||||
|
int t = Param::GetInt(probes[i]);
|
||||||
|
if (t <= -40) continue; // No sensor / module not present
|
||||||
|
if (!any_ok || t > worst) {
|
||||||
|
worst = t;
|
||||||
|
any_ok = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Param::SetInt(Param::tmpobcmax, any_ok ? worst : -40);
|
||||||
|
}
|
||||||
|
|
||||||
canMap->SendAll();
|
canMap->SendAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,6 +140,27 @@ void Param::Change(Param::PARAM_NUM paramNum)
|
|||||||
spnt = MIN(Param::Get(Param::idcspnt), Param::Get(Param::idclim));
|
spnt = MIN(Param::Get(Param::idcspnt), Param::Get(Param::idclim));
|
||||||
dcCurController.SetRef(spnt);
|
dcCurController.SetRef(spnt);
|
||||||
break;
|
break;
|
||||||
|
case Param::vcuchglim:
|
||||||
|
{
|
||||||
|
// SKUDAK-516: VCU sends user-set ChargeLimit_pct on CAN 0x212. Translate
|
||||||
|
// percentage to udcspnt (DC voltage setpoint) using a linear cell-voltage
|
||||||
|
// ramp. 96-cell pack (Tesla LDU / VW MEB compatible):
|
||||||
|
// pct=20 → 3.30 V/cell × 96 = 316.8 V (storage / deep-cycle floor)
|
||||||
|
// pct=80 → 3.94 V/cell × 96 = 378.0 V (recommended daily ceiling)
|
||||||
|
// pct=100 → 4.15 V/cell × 96 = 398.4 V (matches existing udclim default)
|
||||||
|
// Endpoints chosen to be safe across Tesla/VW/Volt2 chemistries — adjust
|
||||||
|
// here if a particular pack needs a tighter range. The VCU validates 20-100
|
||||||
|
// before transmit so out-of-range values never arrive.
|
||||||
|
int pct = Param::GetInt(Param::vcuchglim);
|
||||||
|
if (pct < 20) pct = 20;
|
||||||
|
if (pct > 100) pct = 100;
|
||||||
|
const float CELL_LOW_V = 3.30f;
|
||||||
|
const float CELL_HIGH_V = 4.15f;
|
||||||
|
const float CELL_COUNT = 96.0f;
|
||||||
|
float cell_target = CELL_LOW_V + (CELL_HIGH_V - CELL_LOW_V) * (pct - 20) / 80.0f;
|
||||||
|
Param::SetFloat(Param::udcspnt, cell_target * CELL_COUNT);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
//Handle general parameter changes here. Add paramNum labels for handling specific parameters
|
//Handle general parameter changes here. Add paramNum labels for handling specific parameters
|
||||||
break;
|
break;
|
||||||
@@ -137,7 +184,11 @@ extern "C" void tim2_isr(void)
|
|||||||
scheduler->Run();
|
scheduler->Run();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int main(void)
|
// C++ forbids a linkage specification on `main` (-Wpedantic). The reset_handler
|
||||||
|
// in libopencm3's vector.c forward-declares `int main(void)` with default
|
||||||
|
// linkage and resolves it at link time by symbol name, so dropping `extern "C"`
|
||||||
|
// here doesn't affect how main is invoked at boot.
|
||||||
|
int main(void)
|
||||||
{
|
{
|
||||||
extern const TERM_CMD termCmds[];
|
extern const TERM_CMD termCmds[];
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user