Fallback mode HDA2

Revert "Fallback mode HDA2"

This reverts commit 81b2b3584227bd1aa62089770245e50e131e0a3b.

Fallback mode hda2
This commit is contained in:
firestar5683
2026-04-24 22:51:49 -05:00
parent be87ecec3e
commit 2e4c3f43ee
2 changed files with 99 additions and 7 deletions
+43 -7
View File
@@ -20,6 +20,8 @@ ENABLE_BUTTONS = (ButtonType.accelCruise, ButtonType.decelCruise, ButtonType.can
# Track when ECU disable happened - used to permanently suppress CAN errors from disabled ECU
ECU_DISABLE_TIMESTAMP = 0.0
READY_ONLY_MSGS = {0x255, 0x2e5, 0x3a0, 0x3b0, 0x3b1, 0x3b5, 0x3f0, 0x3f5}
READY_MSG_THRESHOLD = 3
class CarInterface(CarInterfaceBase):
@@ -204,25 +206,37 @@ class CarInterface(CarInterfaceBase):
if CP.flags & HyundaiFlags.CANFD_LKA_STEERING.value:
addr, bus = 0x730, CanBus(CP).ECAN
# Try ECU disable. If it succeeds (IGN-ON mode), enable longitudinal.
# If it fails (READY mode returns NRC 0x22, or timeout), strip LONG safety flag
# so panda forwards stock SCC messages normally (lateral-only mode).
ecu_log(f"=== ECU DISABLE attempt: addr=0x{addr:x}, bus={bus} ===")
ecu_disabled = disable_ecu(can_recv, can_send, bus=bus, addr=addr, com_cont_req=communication_control)
if CP.carFingerprint == CAR.HYUNDAI_IONIQ_6:
ecu_log(f"=== Checking for READY mode: addr=0x{addr:x}, bus={bus} ===")
ready_detected = CarInterface._ready_mode_detected(can_recv, bus)
if ready_detected:
params.put_bool("EcuDisableFailed", True)
CP.safetyConfigs[-1].safetyParam &= ~HyundaiSafetyFlags.LONG.value
ecu_log(f"=== READY mode detected - safetyParam stripped to {CP.safetyConfigs[-1].safetyParam}, lateral-only mode ===")
ecu_disabled = False
else:
# Try ECU disable. If it succeeds (IGN-ON mode), enable longitudinal.
# If it fails (READY mode returns NRC 0x22, or timeout), strip LONG safety flag
# so panda forwards stock SCC messages normally (lateral-only mode).
ecu_log(f"=== ECU DISABLE attempt: addr=0x{addr:x}, bus={bus} ===")
ecu_disabled = disable_ecu(can_recv, can_send, bus=bus, addr=addr, com_cont_req=communication_control)
# Ioniq 6: track success/failure to auto-switch between openpilot long and stock ACC
if ecu_disabled:
ECU_DISABLE_TIMESTAMP = time.monotonic()
params.put_bool("EcuDisableFailed", False)
params.put_bool("ExperimentalMode", True)
ecu_log("=== ECU DISABLE SUCCESS - Longitudinal + Experimental ENABLED ===")
else:
elif not ready_detected:
params.put_bool("EcuDisableFailed", True)
CP.safetyConfigs[-1].safetyParam &= ~HyundaiSafetyFlags.LONG.value
ecu_log(f"=== ECU DISABLE FAILED - safetyParam stripped to {CP.safetyConfigs[-1].safetyParam}, lateral-only mode ===")
else:
# Other cars: just log, don't change safety params or params store
# Try ECU disable. If it succeeds (IGN-ON mode), enable longitudinal.
ecu_log(f"=== ECU DISABLE attempt: addr=0x{addr:x}, bus={bus} ===")
ecu_disabled = disable_ecu(can_recv, can_send, bus=bus, addr=addr, com_cont_req=communication_control)
if ecu_disabled:
ecu_log("=== ECU DISABLE SUCCESS ===")
else:
@@ -237,6 +251,28 @@ class CarInterface(CarInterfaceBase):
communication_control = bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, 0x80 | uds.CONTROL_TYPE.ENABLE_RX_ENABLE_TX, uds.MESSAGE_TYPE.NORMAL])
CarInterface.init(CP, can_recv, can_send, communication_control)
@staticmethod
def _ready_mode_detected(can_recv, bus, timeout_s=1.0):
ready_msgs_seen = set()
all_msgs_seen = set()
start_time = time.monotonic()
while time.monotonic() - start_time < timeout_s:
for can_packets in can_recv(wait_for_one=True):
for packet in can_packets:
if packet.src == bus:
all_msgs_seen.add(packet.address)
if packet.address in READY_ONLY_MSGS:
ready_msgs_seen.add(packet.address)
if len(ready_msgs_seen) >= READY_MSG_THRESHOLD:
break
elapsed = time.monotonic() - start_time
ready_detected = len(ready_msgs_seen) >= READY_MSG_THRESHOLD
ecu_log(f"=== READY scan: ready_msgs={[hex(m) for m in ready_msgs_seen]}, total_bus_msgs={len(all_msgs_seen)}, elapsed={elapsed:.2f}s ===")
return ready_detected
def update(self, can_packets, starpilot_toggles):
ret, fp_ret = super().update(can_packets, starpilot_toggles)
@@ -1,3 +1,4 @@
import sys
from hypothesis import settings, given, strategies as st
from types import SimpleNamespace
@@ -7,6 +8,7 @@ from opendbc.can import CANPacker
from opendbc.car import Bus, ButtonType, gen_empty_fingerprint
from opendbc.car.structs import CarParams
from opendbc.car.fw_versions import build_fw_dict, match_fw_to_car
import opendbc.car.hyundai.interface as hyundai_interface
from opendbc.car.hyundai.carstate import CarState
from opendbc.car.hyundai.interface import CarInterface
from opendbc.car.hyundai import hyundaicanfd
@@ -277,6 +279,60 @@ class TestHyundaiFingerprint:
assert all(parser.can_valid for parser in can_parsers.values())
def test_ioniq_6_ready_mode_skips_ecu_disable(self, monkeypatch):
class FakeParams:
def __init__(self):
self.bools = {}
def put_bool(self, key, value):
self.bools[key] = value
class Packet:
def __init__(self, src, address):
self.src = src
self.address = address
toggles = get_test_toggles()
fingerprint = gen_empty_fingerprint()
cam_can = CanBus(None, fingerprint).CAM
fingerprint[cam_can][0x50] = 8
fingerprint[cam_can][0x110] = 8
CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, fingerprint, [], True, False, False, toggles)
assert CP.openpilotLongitudinalControl
assert CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG
fake_params = FakeParams()
monkeypatch.setitem(sys.modules, "openpilot.common.params", SimpleNamespace(Params=lambda: fake_params))
calls = {"disable_ecu": 0}
def fake_disable_ecu(*args, **kwargs):
calls["disable_ecu"] += 1
return True
time_state = {"value": -0.25}
def fake_monotonic():
time_state["value"] += 0.25
return time_state["value"]
monkeypatch.setattr(hyundai_interface, "disable_ecu", fake_disable_ecu)
monkeypatch.setattr(hyundai_interface.time, "monotonic", fake_monotonic)
ready_msgs = [
Packet(CanBus(CP).ECAN, 0x255),
Packet(CanBus(CP).ECAN, 0x2e5),
Packet(CanBus(CP).ECAN, 0x3a0),
]
def fake_can_recv(wait_for_one=True):
return [ready_msgs]
CarInterface.init(CP, fake_can_recv, lambda *args, **kwargs: None)
assert calls["disable_ecu"] == 0
assert fake_params.bools["EcuDisableFailed"] is True
assert not (CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.LONG)
def test_blacklisted_parts(self, subtests):
# Asserts no ECUs known to be shared across platforms exist in the database.
# Tucson having Santa Cruz camera and EPS for example