Ford: test FW query config and versions (#29016)
* Ford: test FW query config and versions
* comments about software p/n
* should keep it in bytes
* don't need car_model
* it prints nicely
* add todo
* Update selfdrive/car/ford/tests/test_ford.py
---------
Co-authored-by: Shane Smiskol <shane@smiskol.com>
old-commit-hash: 92a7d702fc
beeps
parent
79b24a03b4
commit
a49d2d2619
2 changed files with 80 additions and 0 deletions
@ -0,0 +1,80 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
import unittest |
||||||
|
from parameterized import parameterized |
||||||
|
from typing import Dict, Iterable, Optional, Tuple |
||||||
|
|
||||||
|
import capnp |
||||||
|
|
||||||
|
from cereal import car |
||||||
|
from selfdrive.car.ford.values import FW_QUERY_CONFIG, FW_VERSIONS |
||||||
|
|
||||||
|
Ecu = car.CarParams.Ecu |
||||||
|
|
||||||
|
|
||||||
|
ECU_ADDRESSES = { |
||||||
|
Ecu.eps: 0x730, # Power Steering Control Module (PSCM) |
||||||
|
Ecu.abs: 0x760, # Anti-Lock Brake System (ABS) |
||||||
|
Ecu.fwdRadar: 0x764, # Cruise Control Module (CCM) |
||||||
|
Ecu.fwdCamera: 0x706, # Image Processing Module A (IPMA) |
||||||
|
Ecu.engine: 0x7E0, # Powertrain Control Module (PCM) |
||||||
|
Ecu.shiftByWire: 0x732, # Gear Shift Module (GSM) |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
ECU_FW_CORE = { |
||||||
|
Ecu.eps: [ |
||||||
|
b"14D003", |
||||||
|
], |
||||||
|
Ecu.abs: [ |
||||||
|
b"2D053", |
||||||
|
], |
||||||
|
Ecu.fwdRadar: [ |
||||||
|
b"14D049", |
||||||
|
], |
||||||
|
Ecu.fwdCamera: [ |
||||||
|
b"14F397", # Ford Q3 |
||||||
|
b"14H102", # Ford Q4 |
||||||
|
], |
||||||
|
Ecu.engine: [ |
||||||
|
b"14C204", |
||||||
|
], |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
class TestFordFW(unittest.TestCase): |
||||||
|
def test_fw_query_config(self): |
||||||
|
for (ecu, addr, subaddr) in FW_QUERY_CONFIG.extra_ecus: |
||||||
|
self.assertIn(ecu, ECU_ADDRESSES, "Unknown ECU") |
||||||
|
self.assertEqual(addr, ECU_ADDRESSES[ecu], "ECU address mismatch") |
||||||
|
self.assertIsNone(subaddr, "Unexpected ECU subaddress") |
||||||
|
|
||||||
|
@parameterized.expand(FW_VERSIONS.items()) |
||||||
|
def test_fw_versions(self, car_model: str, fw_versions: Dict[Tuple[capnp.lib.capnp._EnumModule, int, Optional[int]], Iterable[bytes]]): |
||||||
|
for (ecu, addr, subaddr), fws in fw_versions.items(): |
||||||
|
self.assertIn(ecu, ECU_ADDRESSES, "Unknown ECU") |
||||||
|
self.assertEqual(addr, ECU_ADDRESSES[ecu], "ECU address mismatch") |
||||||
|
self.assertIsNone(subaddr, "Unexpected ECU subaddress") |
||||||
|
|
||||||
|
# Software part number takes the form: PREFIX-CORE-SUFFIX |
||||||
|
# Prefix changes based on the family of part. It includes the model year |
||||||
|
# and likely the platform. |
||||||
|
# Core identifies the type of the item (e.g. 14D003 = PSCM, 14C204 = PCM). |
||||||
|
# Suffix specifies the version of the part. -AA would be followed by -AB. |
||||||
|
# Small increments in the suffix are usually compatible. |
||||||
|
# Details: https://forscan.org/forum/viewtopic.php?p=70008#p70008 |
||||||
|
for fw in fws: |
||||||
|
self.assertEqual(len(fw), 24, "Expected ECU response to be 24 bytes") |
||||||
|
|
||||||
|
# TODO: parse with regex, don't need detailed error message |
||||||
|
fw_parts = fw.rstrip(b'\x00').split(b'-') |
||||||
|
self.assertEqual(len(fw_parts), 3, "Expected FW to be in format: prefix-core-suffix") |
||||||
|
|
||||||
|
prefix, core, suffix = fw_parts |
||||||
|
self.assertEqual(len(prefix), 4, "Expected FW prefix to be 4 characters") |
||||||
|
self.assertIn(len(core), (5, 6), "Expected FW core to be 5-6 characters") |
||||||
|
self.assertIn(core, ECU_FW_CORE[ecu], f"Unexpected FW core for {ecu}") |
||||||
|
self.assertIn(len(suffix), (2, 3), "Expected FW suffix to be 2-3 characters") |
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
unittest.main() |
Loading…
Reference in new issue