diff --git a/cereal/libcereal.a b/cereal/libcereal.a index 45677bf95..e24b78e71 100644 Binary files a/cereal/libcereal.a and b/cereal/libcereal.a differ diff --git a/cereal/log.capnp b/cereal/log.capnp index 05ac98a81..5510c7352 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -507,7 +507,7 @@ struct DeviceState @0xa4d8b5af2aa492eb { pmicTempC @39 :List(Float32); intakeTempC @46 :Float32; exhaustTempC @47 :Float32; - caseTempC @48 :Float32; + gnssTempC @48 :Float32; bottomSocTempC @50 :Float32; maxTempC @44 :Float32; # max of other temps, used to control fan thermalZones @38 :List(ThermalZone); @@ -522,10 +522,10 @@ struct DeviceState @0xa4d8b5af2aa492eb { } enum ThermalStatus { - green @0; - yellow @1; - red @2; - danger @3; + ok @0; + warmDEPRECATED @1; + overheated @2; + critical @3; } enum NetworkType { diff --git a/opendbc_repo/opendbc/car/hyundai/carstate.py b/opendbc_repo/opendbc/car/hyundai/carstate.py index 1f77da735..d5fe75a77 100644 --- a/opendbc_repo/opendbc/car/hyundai/carstate.py +++ b/opendbc_repo/opendbc/car/hyundai/carstate.py @@ -28,6 +28,11 @@ IONIQ_6_BLINDSPOT_LEFT_MASK = 0x10 CANFD_CAMERA_LEAD_MIN_DISTANCE = 0.1 ALT_BUS_LDA_BUTTON_BURST_DEBOUNCE_NS = int(1.3e9) +CLASSIC_MEDIA_BUTTON_CARS = frozenset({ + CAR.HYUNDAI_ELANTRA_2024, + CAR.HYUNDAI_ELANTRA_HEV_2024, +}) + def get_non_scc_cruise_signals(CP) -> tuple[str, str, str, str, str, str]: if CP.flags & HyundaiFlags.EV: @@ -437,6 +442,9 @@ class CarState(CarStateBase): ret.lowSpeedAlert = self.low_speed_alert fp_ret = custom.StarPilotCarState.new_message() + if self.CP.carFingerprint in CLASSIC_MEDIA_BUTTON_CARS: + fp_ret.modePressed = bool(cp.vl["GW_SWRC_PE"]["C_ModeSW"]) + fp_ret.customPressed = bool(cp.vl["GW_SWRC_PE"]["C_MTSSW"]) return ret, fp_ret @@ -686,6 +694,9 @@ class CarState(CarStateBase): ("BCM_PO_11", 0), ("CLU13", 0), ] + if CP.carFingerprint in CLASSIC_MEDIA_BUTTON_CARS: + # Steering-wheel media switches are event-driven on the refresh Elantra. + msgs.append(("GW_SWRC_PE", 0)) if CP.flags & HyundaiFlags.NON_SCC and not (CP.flags & HyundaiFlags.NON_SCC_NO_FCA): msgs.append(("FCA11", 0)) # Non-SCC trims can stop publishing FCA11; don't let it poison canValid diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index 6eecf52a7..258c731bf 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -654,6 +654,22 @@ class TestHyundaiFingerprint: assert DBC[CP.carFingerprint][Bus.pt] == "hyundai_can_refresh_generated" assert CP.safetyConfigs[-1].safetyParam & HyundaiSafetyFlags.CAN_REFRESH_MSGS + def test_elantra_refresh_decodes_classic_media_buttons(self): + toggles = get_test_toggles() + CP = CarInterface.get_params(CAR.HYUNDAI_ELANTRA_HEV_2024, gen_empty_fingerprint(), [], True, False, False, toggles) + FPCP = CarInterface.get_starpilot_params(CAR.HYUNDAI_ELANTRA_HEV_2024, gen_empty_fingerprint(), [], CP, toggles) + + car_state = CarState(CP, FPCP) + can_parsers = car_state.get_can_parsers(CP) + packer = CANPacker(DBC[CP.carFingerprint][Bus.pt]) + media_msg = packer.make_can_msg("GW_SWRC_PE", 0, {"C_ModeSW": 1, "C_MTSSW": 1}) + + can_parsers[Bus.pt].update([(1_000_000_000, [media_msg])]) + _, fp_ret = car_state.update(can_parsers, toggles) + + assert fp_ret.modePressed + assert fp_ret.customPressed + def test_hyundai_lkas_button_sets_starpilot_safety_flag(self): fingerprint = gen_empty_fingerprint() fingerprint[0][0x391] = 8 diff --git a/opendbc_repo/opendbc/car/nissan/interface.py b/opendbc_repo/opendbc/car/nissan/interface.py index 1a236f3ec..147b486cd 100644 --- a/opendbc_repo/opendbc/car/nissan/interface.py +++ b/opendbc_repo/opendbc/car/nissan/interface.py @@ -17,15 +17,12 @@ LEAF_ADAS_COMMAND_ADDRS = frozenset((0x1C3, 0x2B0)) LEAF_2025_SV_PLUS_CAMERA_FW = b'6WK2CDB\x04\x18\x00\x00\x00\x00\x00R=1\x18\x99\x10\x00\x00\x00\x80' # This Leaf camera uses KWP2000 rather than UDS for session management. -LEAF_KWP_AFTER_SALES_REQUEST = b"\x10\xC0" -LEAF_KWP_AFTER_SALES_RESPONSE = b"\x50\xC0" +LEAF_KWP_DATA_MONITOR_REQUEST = b"\x10\xF0" +LEAF_KWP_DATA_MONITOR_RESPONSE = b"\x50\xF0" LEAF_KWP_DISABLE_NORMAL_TX = b"\x28\x01" -LEAF_KWP_ENABLE_NORMAL_TX = b"\x29\x01" -LEAF_KWP_ENABLE_NORMAL_TX_RESPONSE = b"\x69" -LEAF_KWP_SESSIONS = ( - (LEAF_KWP_AFTER_SALES_REQUEST, LEAF_KWP_AFTER_SALES_RESPONSE), - (NISSAN_DIAGNOSTIC_REQUEST_KWP, NISSAN_DIAGNOSTIC_RESPONSE_KWP), +LEAF_KWP_TAKEOVER_SESSIONS = ( + (LEAF_KWP_DATA_MONITOR_REQUEST, LEAF_KWP_DATA_MONITOR_RESPONSE), ) @@ -68,25 +65,45 @@ def leaf_adas_commands_silent(can_recv, settle_time=0.05, observe_time=0.15): return saw_adas_bus_traffic +def leaf_adas_commands_present(can_recv, settle_time=0.05, observe_time=0.15): + """Confirm the stock ADAS command sender resumed on bus 1.""" + if can_recv is None: + return False + + try: + time.sleep(settle_time) + can_recv() + + deadline = time.monotonic() + observe_time + while time.monotonic() < deadline: + for packet in can_recv(wait_for_one=True): + if any(msg.src == LEAF_ADAS_COMMAND_BUS and msg.address in LEAF_ADAS_COMMAND_ADDRS for msg in packet): + return True + except Exception as e: + ecu_log(f"Nissan Leaf ADAS TX recovery verification exception: {e}") + return False + + ecu_log("Nissan Leaf ADAS normal TX recovery could not be verified") + return False + + def restore_leaf_adas_tx(can_recv, can_send): - """Re-enable normal KWP message transmission, trying both safe diagnostic sessions.""" + """Return to the confirmed KWP default session and verify normal TX resumes.""" if can_recv is None or can_send is None: return False - for diag_request, diag_response in LEAF_KWP_SESSIONS: - try: - ecu_log(f"Nissan Leaf ADAS TX restore using KWP session {diag_request.hex()}") - query = IsoTpParallelQuery( - can_send, can_recv, LEAF_ADAS_ECU_BUS, [LEAF_ADAS_ECU_ADDR], - [diag_request, LEAF_KWP_ENABLE_NORMAL_TX], - [diag_response, LEAF_KWP_ENABLE_NORMAL_TX_RESPONSE], - response_offset=NISSAN_RX_OFFSET, - ) - if query.get_data(0.2): - ecu_log("Nissan Leaf ADAS normal TX restored") - return True - except Exception as e: - ecu_log(f"Nissan Leaf ADAS TX restore exception: {e}") + try: + ecu_log("Nissan Leaf ADAS TX restore using KWP default session 1081") + query = IsoTpParallelQuery( + can_send, can_recv, LEAF_ADAS_ECU_BUS, [LEAF_ADAS_ECU_ADDR], + [NISSAN_DIAGNOSTIC_REQUEST_KWP], [NISSAN_DIAGNOSTIC_RESPONSE_KWP], + response_offset=NISSAN_RX_OFFSET, + ) + if query.get_data(0.2) and leaf_adas_commands_present(can_recv): + ecu_log("Nissan Leaf ADAS normal TX restored and command traffic confirmed") + return True + except Exception as e: + ecu_log(f"Nissan Leaf ADAS TX restore exception: {e}") ecu_log("Nissan Leaf ADAS normal TX restore was not confirmed") return False @@ -141,10 +158,10 @@ class CarInterface(CarInterfaceBase): from openpilot.common.params import Params params = Params() ecu_disabled = False - for diag_request, diag_response in LEAF_KWP_SESSIONS: + for diag_request, diag_response in LEAF_KWP_TAKEOVER_SESSIONS: ecu_log(f"Nissan Leaf ADAS takeover using KWP session {diag_request.hex()}") ecu_disabled = disable_ecu(can_recv, can_send, bus=LEAF_ADAS_ECU_BUS, addr=LEAF_ADAS_ECU_ADDR, - com_cont_req=LEAF_KWP_DISABLE_NORMAL_TX, require_response=True, retry=3, + com_cont_req=LEAF_KWP_DISABLE_NORMAL_TX, require_response=True, retry=1, diag_request=diag_request, diag_response=diag_response, response_offset=NISSAN_RX_OFFSET) if ecu_disabled: break diff --git a/opendbc_repo/opendbc/car/nissan/tests/test_nissan.py b/opendbc_repo/opendbc/car/nissan/tests/test_nissan.py index c8917d957..d43a23198 100644 --- a/opendbc_repo/opendbc/car/nissan/tests/test_nissan.py +++ b/opendbc_repo/opendbc/car/nissan/tests/test_nissan.py @@ -5,7 +5,8 @@ import pytest from opendbc.car import Bus, ButtonType, gen_empty_fingerprint, structs from opendbc.car.can_definitions import CanData from opendbc.car.nissan.carstate import CarState -from opendbc.car.nissan.interface import CarInterface, LEAF_2025_SV_PLUS_CAMERA_FW, leaf_adas_commands_silent, restore_leaf_adas_tx +from opendbc.car.nissan.interface import CarInterface, LEAF_2025_SV_PLUS_CAMERA_FW, leaf_adas_commands_present, \ + leaf_adas_commands_silent, restore_leaf_adas_tx from opendbc.car.nissan.values import CAR, CarControllerParams, NissanSafetyFlags @@ -143,28 +144,24 @@ def test_leaf_ecu_disable_is_strict_and_falls_back(monkeypatch, ecu_disabled): monkeypatch.setattr("opendbc.car.nissan.interface.ecu_log", lambda *_: None) CarInterface.init(CP, None, None) - assert len(calls) == (1 if ecu_disabled else 2) + assert len(calls) == 1 assert calls[0]["addr"] == 0x707 assert calls[0]["bus"] == 0 assert calls[0]["response_offset"] == 0x20 assert calls[0]["require_response"] is True - assert calls[0]["diag_request"] == b"\x10\xc0" - assert calls[0]["diag_response"] == b"\x50\xc0" + assert calls[0]["diag_request"] == b"\x10\xf0" + assert calls[0]["diag_response"] == b"\x50\xf0" assert calls[0]["com_cont_req"] == b"\x28\x01" - assert calls[0]["retry"] == 3 - if not ecu_disabled: - assert calls[1]["diag_request"] == b"\x10\x81" - assert calls[1]["diag_response"] == b"\x50\x81" + assert calls[0]["retry"] == 1 assert CP.openpilotLongitudinalControl is ecu_disabled assert CP.pcmCruise is not ecu_disabled assert bool(CP.safetyConfigs[-1].safetyParam & NissanSafetyFlags.LONG_CONTROL) is ecu_disabled -def test_leaf_kwp_session_can_confirm_ecu_disable(monkeypatch): +def test_leaf_kwp_data_monitor_session_can_confirm_ecu_disable(monkeypatch): CP = CarInterface.get_params(CAR.NISSAN_LEAF, gen_empty_fingerprint(), SUPPORTED_LEAF_FW, True, False, False, None) - results = iter((False, True)) - monkeypatch.setattr("opendbc.car.nissan.interface.disable_ecu", lambda *args, **kwargs: next(results)) + monkeypatch.setattr("opendbc.car.nissan.interface.disable_ecu", lambda *args, **kwargs: True) monkeypatch.setattr("opendbc.car.nissan.interface.leaf_adas_commands_silent", lambda *_: True) monkeypatch.setattr("opendbc.car.nissan.interface.ecu_log", lambda *_: None) CarInterface.init(CP, None, None) @@ -205,7 +202,17 @@ def test_leaf_adas_command_silence_requires_live_bus_without_stock_commands(monk assert not leaf_adas_commands_silent(lambda wait_for_one=False: [], settle_time=0, observe_time=0.001) -def test_leaf_adas_restore_uses_kwp_enable_normal_transmission(monkeypatch): +def test_leaf_adas_command_recovery_requires_stock_command(monkeypatch): + monkeypatch.setattr("opendbc.car.nissan.interface.ecu_log", lambda *_: None) + + def stock_command_traffic(wait_for_one=False): + return [] if not wait_for_one else [[CanData(0x1C3, b"\x00" * 8, 1)]] + + assert leaf_adas_commands_present(stock_command_traffic, settle_time=0, observe_time=0.001) + assert not leaf_adas_commands_present(lambda wait_for_one=False: [], settle_time=0, observe_time=0.001) + + +def test_leaf_adas_restore_returns_to_kwp_default_session(monkeypatch): queries = [] class FakeQuery: @@ -216,7 +223,8 @@ def test_leaf_adas_restore_uses_kwp_enable_normal_transmission(monkeypatch): return {(0x707, None): b""} monkeypatch.setattr("opendbc.car.nissan.interface.IsoTpParallelQuery", FakeQuery) + monkeypatch.setattr("opendbc.car.nissan.interface.leaf_adas_commands_present", lambda *_: True) monkeypatch.setattr("opendbc.car.nissan.interface.ecu_log", lambda *_: None) assert restore_leaf_adas_tx(lambda **kwargs: [], lambda msgs: None) - assert queries == [(0, [0x707], [b"\x10\xc0", b"\x29\x01"], [b"\x50\xc0", b"\x69"], 0x20)] + assert queries == [(0, [0x707], [b"\x10\x81"], [b"\x50\x81"], 0x20)] diff --git a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py index 7d40cdbd1..52ede8fb4 100644 --- a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py +++ b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py @@ -709,7 +709,7 @@ IONIQ_5_LOW_SPEED_CENTER_LAT = 0.40 IONIQ_5_LOW_SPEED_CENTER_LAT_WIDTH = 0.10 IONIQ_5_LOW_SPEED_CENTER_JERK = 0.40 IONIQ_5_LOW_SPEED_CENTER_JERK_WIDTH = 0.12 -IONIQ_5_FRICTION_JERK_DEADZONE_MAX = 0.30 +IONIQ_5_FRICTION_JERK_DEADZONE_MAX = 0.36 IONIQ_5_FRICTION_JERK_DEADZONE_LAT = 1.25 IONIQ_5_FRICTION_JERK_DEADZONE_LAT_WIDTH = 0.35 IONIQ_5_FRICTION_JERK_DEADZONE_SPEED = 18.0 diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 2c7848e2f..6f5188e73 100644 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -56,7 +56,7 @@ MonitoringPolicy = log.DriverMonitoringState.MonitoringPolicy StarPilotEventName = custom.StarPilotOnroadEvent.EventName IGNORED_SAFETY_MODES = (SafetyModel.silent, SafetyModel.noOutput) -VALID_ONLY_COMM_ISSUE_GRACE_FRAMES = max(1, round(0.25 / DT_CTRL)) +VALID_ONLY_COMM_ISSUE_GRACE_FRAMES = max(1, round(0.5 / DT_CTRL)) def evaluate_comm_issue(all_checks: bool, all_alive: bool, all_freq_ok: bool, @@ -515,7 +515,7 @@ class SelfdriveD: self.events.add(EventName.pedalPressed) # Create events for temperature, disk space, and memory - if self.sm['deviceState'].thermalStatus >= ThermalStatus.red: + if self.sm['deviceState'].thermalStatus >= ThermalStatus.overheated: self.events.add(EventName.overheat) if self.sm['deviceState'].freeSpacePercent < 7 and not SIMULATION: self.events.add(EventName.outOfSpace) diff --git a/selfdrive/selfdrived/tests/test_selfdrived.py b/selfdrive/selfdrived/tests/test_selfdrived.py index dcde96bc4..f0c2ba5e9 100644 --- a/selfdrive/selfdrived/tests/test_selfdrived.py +++ b/selfdrive/selfdrived/tests/test_selfdrived.py @@ -3,6 +3,7 @@ import cereal.messaging as messaging from cereal import car, custom, log from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR from opendbc.car.nissan.values import CAR as NISSAN_CAR +from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.selfdrived.selfdrived import ( VALID_ONLY_COMM_ISSUE_GRACE_FRAMES, @@ -27,6 +28,13 @@ def test_valid_only_comm_issue_is_debounced(): assert frames == 0 +def test_route_length_validity_cascade_stays_silent(): + frames = 0 + for _ in range(round(0.4 / DT_CTRL)): + should_alert, frames = evaluate_comm_issue(False, True, True, frames) + assert not should_alert + + def test_dead_or_slow_comm_issue_is_immediate(): assert evaluate_comm_issue(False, False, True, 0) == (True, 0) assert evaluate_comm_issue(False, True, False, 0) == (True, 0) diff --git a/selfdrive/ui/layouts/sidebar.py b/selfdrive/ui/layouts/sidebar.py index 23ef92981..2a36e191a 100644 --- a/selfdrive/ui/layouts/sidebar.py +++ b/selfdrive/ui/layouts/sidebar.py @@ -122,9 +122,9 @@ class Sidebar(Widget): thermal_status = device_state.thermalStatus temperature = f"{int(device_state.maxTempC)}°C" - if thermal_status == ThermalStatus.green: + if thermal_status == ThermalStatus.ok: self._temp_status.update(tr_noop("TEMP"), temperature, Colors.GOOD) - elif thermal_status == ThermalStatus.yellow: + elif thermal_status == ThermalStatus.warmDEPRECATED: self._temp_status.update(tr_noop("TEMP"), temperature, Colors.WARNING) else: self._temp_status.update(tr_noop("TEMP"), temperature, Colors.DANGER) diff --git a/system/hardware/base.py b/system/hardware/base.py index 17d0ec161..d0a4833cc 100644 --- a/system/hardware/base.py +++ b/system/hardware/base.py @@ -51,7 +51,8 @@ class ThermalConfig: memory: ThermalZone | None = None intake: ThermalZone | None = None exhaust: ThermalZone | None = None - case: ThermalZone | None = None + gnss: ThermalZone | None = None + bottomSoc: ThermalZone | None = None def get_msg(self): ret = {} diff --git a/system/hardware/hardwared.py b/system/hardware/hardwared.py index 9ac43e9f1..ec7c52a59 100644 --- a/system/hardware/hardwared.py +++ b/system/hardware/hardwared.py @@ -133,15 +133,21 @@ HardwareState = namedtuple("HardwareState", ['network_type', 'network_info', 'ne # List of thermal bands. We will stay within this region as long as we are within the bounds. # When exiting the bounds, we'll jump to the lower or higher band. Bands are ordered in the dict. -THERMAL_BANDS = OrderedDict({ - ThermalStatus.green: ThermalBand(None, 80.0), - ThermalStatus.yellow: ThermalBand(75.0, 96.0), - ThermalStatus.red: ThermalBand(88.0, 107.), - ThermalStatus.danger: ThermalBand(94.0, None), -}) +if HARDWARE.get_device_type() == "mici": + THERMAL_BANDS = OrderedDict({ + ThermalStatus.ok: ThermalBand(None, 100.0), + ThermalStatus.overheated: ThermalBand(92.0, 107.), + ThermalStatus.critical: ThermalBand(98.0, None), + }) +else: + THERMAL_BANDS = OrderedDict({ + ThermalStatus.ok: ThermalBand(None, 96.0), + ThermalStatus.overheated: ThermalBand(88.0, 107.), + ThermalStatus.critical: ThermalBand(94.0, None), + }) # Override to highest thermal band when offroad and above this temp -OFFROAD_DANGER_TEMP = 75 +OFFROAD_DANGER_TEMP = 85 if HARDWARE.get_device_type() == "mici" else 75 prev_offroad_states: dict[str, tuple[bool, str | None]] = {} @@ -279,7 +285,7 @@ def hardware_thread(end_event, hw_queue) -> None: started_ts: float | None = None started_seen = False startup_blocked_ts: float | None = None - thermal_status = ThermalStatus.yellow + thermal_status = ThermalStatus.ok last_hw_state = HardwareState( network_type=NetworkType.none, @@ -405,13 +411,13 @@ def hardware_thread(end_event, hw_queue) -> None: # StarPilot variables if starpilot_toggles.increase_thermal_limits: - all_comp_temp -= (THERMAL_BANDS[ThermalStatus.danger].min_temp - THERMAL_BANDS[ThermalStatus.red].min_temp) + all_comp_temp -= (THERMAL_BANDS[ThermalStatus.critical].min_temp - THERMAL_BANDS[ThermalStatus.overheated].min_temp) is_offroad_for_5_min = (started_ts is None) and ((not started_seen) or (off_ts is None) or (time.monotonic() - off_ts > 60 * 5)) if is_offroad_for_5_min and offroad_comp_temp > OFFROAD_DANGER_TEMP: # if device is offroad and already hot without the extra onroad load, # we want to cool down first before increasing load - thermal_status = ThermalStatus.danger + thermal_status = ThermalStatus.critical else: current_band = THERMAL_BANDS[thermal_status] band_idx = list(THERMAL_BANDS.keys()).index(thermal_status) @@ -434,17 +440,20 @@ def hardware_thread(end_event, hw_queue) -> None: startup_conditions["not_taking_snapshot"] = not params.get_bool("IsTakingSnapshot") # must be at an engageable thermal band to go onroad - startup_conditions["device_temp_engageable"] = thermal_status < ThermalStatus.red + startup_conditions["device_temp_engageable"] = thermal_status < ThermalStatus.overheated # ensure device is fully booted startup_conditions["device_booted"] = startup_conditions.get("device_booted", False) or HARDWARE.booted() # if the temperature enters the danger zone, go offroad to cool down - onroad_conditions["device_temp_good"] = thermal_status < ThermalStatus.danger + onroad_conditions["device_temp_good"] = thermal_status < ThermalStatus.critical extra_text = f"{offroad_comp_temp:.1f}C" show_alert = (not onroad_conditions["device_temp_good"] or not startup_conditions["device_temp_engageable"]) and onroad_conditions["ignition"] set_offroad_alert_if_changed("Offroad_TemperatureTooHigh", show_alert, extra_text=extra_text) + if show_alert: + msg.deviceState.fanSpeedPercentDesired = 100 + # *** registration check *** if not PC: # we enforce this for our software, but you are welcome @@ -563,9 +572,10 @@ def hardware_thread(end_event, hw_queue) -> None: statlog.gauge("fan_speed_percent_desired", msg.deviceState.fanSpeedPercentDesired) statlog.gauge("screen_brightness_percent", msg.deviceState.screenBrightnessPercent) - # report to server once every 10 minutes + # report to server once every 10 minutes, or every 1s when thermally blocked rising_edge_started = should_start and not should_start_prev - if rising_edge_started or (count % int(600. / DT_HW)) == 0: + status_packet_interval = 1. if show_alert else 600. + if rising_edge_started or (count % int(status_packet_interval / DT_HW)) == 0: dat = { 'count': count, 'pandaStates': [strip_deprecated_keys(p.to_dict()) for p in pandaStates], diff --git a/system/hardware/tici/hardware.py b/system/hardware/tici/hardware.py index 8f3810e1f..eacc69b0b 100644 --- a/system/hardware/tici/hardware.py +++ b/system/hardware/tici/hardware.py @@ -321,11 +321,12 @@ class Tici(HardwareBase): os.system("sudo poweroff") def get_thermal_config(self): - intake, exhaust, case = None, None, None + intake, exhaust, gnss, bottomSoc = None, None, None, None if self.get_device_type() == "mici": - case = ThermalZone("case") + gnss = ThermalZone("gnss") intake = ThermalZone("intake") exhaust = ThermalZone("exhaust") + bottomSoc = ThermalZone("bottom_soc") return ThermalConfig(cpu=[ThermalZone(f"cpu{i}-silver-usr") for i in range(4)] + [ThermalZone(f"cpu{i}-gold-usr") for i in range(4)], gpu=[ThermalZone("gpu0-usr"), ThermalZone("gpu1-usr")], @@ -334,7 +335,8 @@ class Tici(HardwareBase): pmic=[ThermalZone("pm8998_tz"), ThermalZone("pm8005_tz")], intake=intake, exhaust=exhaust, - case=case) + gnss=gnss, + bottomSoc=bottomSoc) def set_display_power(self, on): try: @@ -383,6 +385,9 @@ class Tici(HardwareBase): continue gov = 'ondemand' if powersave_enabled else 'performance' sudo_write(gov, f'/sys/devices/system/cpu/cpufreq/policy{n}/scaling_governor') + if not powersave_enabled: + # cap max core freq to 1689 Mhz + sudo_write('1689600', f'/sys/devices/system/cpu/cpufreq/policy{n}/scaling_max_freq') # *** IRQ config ***