Compare commits
8 Commits
307853bea8
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 2c9e7a8bbe | |||
| b7fcd2b301 | |||
| e36ba2ccc5 | |||
| 02e3f2643f | |||
| ee59f69890 | |||
| 7acbd66907 | |||
| fb721f7392 | |||
| 5dc715558f |
@@ -4,3 +4,4 @@ stm32_charger*
|
||||
linker.map
|
||||
*.layout
|
||||
*.out
|
||||
.DS_Store
|
||||
|
||||
+4
-3
@@ -47,7 +47,7 @@
|
||||
3. Display values
|
||||
*/
|
||||
//Next param id (increase when adding new parameter!): 24
|
||||
//Next value Id: 2051
|
||||
//Next value Id: 2052
|
||||
/* category name unit min max default id */
|
||||
#define PARAM_LIST \
|
||||
PARAM_ENTRY(CAT_CHARGER, idclim, "A", 0, 45, 45, 3 ) \
|
||||
@@ -108,6 +108,7 @@
|
||||
VALUE_ENTRY(c3iac, "A", 2034 ) \
|
||||
VALUE_ENTRY(c3udc, "V", 2035 ) \
|
||||
VALUE_ENTRY(c3idc, "A", 2036 ) \
|
||||
VALUE_ENTRY(tmpobcmax, "°C", 2051 ) \
|
||||
VALUE_ENTRY(test_time, "s", 3000 ) \
|
||||
VALUE_ENTRY(test_timer_flag, "X", 3001 ) \
|
||||
VALUE_ENTRY(test_timer_icvalue, "X", 3002 ) \
|
||||
@@ -126,9 +127,9 @@
|
||||
#define CAT_COMM "Communication"
|
||||
|
||||
// SKUDAK customization suffix: bump on every Skudak-side change so the OpenInverter
|
||||
// web UI shows a distinct version (e.g. "4=1.19.R-S1") and we can visually confirm
|
||||
// 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-S1)
|
||||
#define VERSTR STRINGIFY(4=VER-S5)
|
||||
|
||||
/***** enums ******/
|
||||
|
||||
|
||||
+8
-2
@@ -85,9 +85,15 @@ bool CheckTimeout()
|
||||
bool CheckDelay()
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+14
-11
@@ -108,16 +108,19 @@ void ChargerCAN::MapMessages(CanMap* can)
|
||||
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: reserved
|
||||
// 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::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
|
||||
}
|
||||
|
||||
+31
-1
@@ -77,6 +77,32 @@ static void Ms100Task(void)
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -158,7 +184,11 @@ extern "C" void tim2_isr(void)
|
||||
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[];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user