initial commit

This commit is contained in:
2026-04-11 12:45:18 +02:00
commit 6e1b929e2f
1246 changed files with 177580 additions and 0 deletions

20
.claude/skills/build.md Normal file
View File

@@ -0,0 +1,20 @@
# Build HC_APTBS
Build the WPF application targeting Windows x64.
## Steps
1. Run the build from the solution root:
```bash
dotnet build -r win-x64 "C:/Users/herli/Documents/ClaudeProjects/HC_APTBS/HC_APTBS.slnx"
```
2. Parse the output:
- If the build **succeeds**: report the number of warnings (if any) and confirm success.
- If the build **fails**: list each error with file path and line number, then suggest fixes.
## Notes
- Always use `-r win-x64` — native DLLs (`PCANBasic.dll`, `ftd2xx.dll`) are x64 Windows binaries.
- SDK version is pinned in `global.json`. Do not modify it.
- There is no test project. Build success is the only automated check.

View File

@@ -0,0 +1,69 @@
# KWP/FTDI edit checklist
You are about to edit timing-sensitive K-Line communication code in one of:
- `Infrastructure/Kwp/KwpCommon.cs`
- `Infrastructure/Kwp/KW1281Connection.cs`
- `Infrastructure/Kwp/FtdiInterface.cs`
- `Services/Impl/KwpService.cs`
Read the relevant file(s) first, then apply the following checks before and after your edit.
---
## Timing constraints
**`KW1281Connection.SendPacket`** calls `Thread.Sleep(5)` after each byte written.
This is the mandatory KWP inter-byte gap. Do not remove or reduce it.
**`KwpCommon.WakeUp`** implements the 5-baud slow-init sequence.
Any change to Sleep durations here will break ECU connection. Leave it alone unless
you are explicitly fixing a timing bug and have the KW1281 spec in front of you.
---
## FtdiInterface lifetime
`KwpService` constructs a `FtdiInterface` at the start of each operation and disposes it
at the end. This is intentional — the ECU expects a fresh session per dialog.
Do not try to hold `FtdiInterface` open across multiple `KwpService` calls.
`FtdiInterface._buf` is a reused `byte[1]` field for single-byte reads/writes.
Do not allocate a new array inside `ReadByte()` or `WriteByteRaw()`.
---
## Error handling invariant
Every `KwpService` method that opens an `FtdiInterface` must dispose it in all code paths:
```csharp
FtdiInterface? iface = null;
try
{
iface = new FtdiInterface(port, KLineBaudRate);
// ... work ...
}
catch (Exception ex) { /* log */ }
finally { iface?.Dispose(); }
```
If you add a new KwpService method, verify it follows this pattern.
K-Line errors throw `InvalidOperationException` or `TimeoutException`.
Do not catch and swallow these inside the method body — the ViewModel catch block depends on seeing them.
---
## Allocation patterns (known debt — do not worsen)
`KW1281Connection` uses `List<byte>` for packet buffers throughout.
If you want to reduce allocations, convert the entire packet path at once.
Converting one method in isolation creates a mixed pattern that is harder to reason about.
---
## After your edit, verify:
1. Search for `new FtdiInterface` — every occurrence has a matching `finally { iface?.Dispose(); }`
2. `Thread.Sleep(5)` in `SendPacket` is still present
3. `ProgressChanged` is still called with increasing percent values so the progress dialog updates
4. No new `Thread.Sleep`, `Console.Write`, or `Logger.WriteLine` was added inside a per-byte loop

View File

@@ -0,0 +1,74 @@
# VP44 Protocol Reference
Quick reference for hardware protocol constants used in HC_APTBS. Consult this before modifying any protocol-related code.
---
## DFI encoding (EEPROM address 0x0044 on VP44 ECU)
**Read (raw byte → DFI value):**
```csharp
dfi = (sbyte)raw * 3.0 / 256.0
```
**Write (DFI value → raw byte):**
```csharp
raw = (sbyte)((dfi * 256.0f) / 3.0f)
// If raw == 0, use 1 — the ECU rejects zero
```
**Checksum:**
```csharp
checksum = (byte)(0 - (byte)rawValue)
```
---
## IIR low-pass filter (PcanAdapter.PassFilterUpdate)
```csharp
result = Math.Round(prev + alpha * (value - prev), 4)
```
Used to smooth CAN bus sensor readings. The `alpha` coefficient controls responsiveness vs. noise rejection.
---
## OEM legitimation (PcanAdapter.Connect)
```csharp
token = (20120378UL << 32) | 21200UL
```
Sent as a CAN frame to authenticate with the bench controller. Without this, the bench ignores all commands.
---
## K-Line / KWP timing
**Inter-byte delay** (`KW1281Connection.SendPacket`):
```csharp
Thread.Sleep(5) // after each byte — KWP protocol requirement, NOT a workaround
```
**5-baud slow-init** (`KwpCommon.WakeUp`):
- Bit-bangs the ECU address at 5 baud on the K-Line
- Sleep durations in WakeUp are protocol-mandated — do not change
**Session lifetime**:
- One `FtdiInterface` open/close per KWP operation
- ECU expects a fresh session per dialog — do not pool connections
---
## CAN bus (PCAN-Basic, 500 kbps)
- Channel: `PCAN_USBBUS1`
- Baud: `PCAN_BAUD_500K`
- Read thread polls with `Thread.Sleep(2)` in `DrainMessageQueue` (known debt)
---
## Caution
Do not change any of these values without understanding the hardware protocol specification. Incorrect values can cause ECU communication failures or bench malfunction.