diff --git a/openpilot/cereal/log.capnp b/openpilot/cereal/log.capnp index fdf022fa63..fb4867b2a6 100644 --- a/openpilot/cereal/log.capnp +++ b/openpilot/cereal/log.capnp @@ -725,6 +725,7 @@ struct ChestnutState { pcieLtssm @7 :UInt8; supplyVoltage @8 :UInt16; # mV supplyCurrent @9 :Int16; # mA + supplyFault @10 :Bool; } struct RadarState @0x9a185389d6fdd05f { diff --git a/openpilot/selfdrive/modeld/modeld.py b/openpilot/selfdrive/modeld/modeld.py index 0db66ed880..a795f366ce 100755 --- a/openpilot/selfdrive/modeld/modeld.py +++ b/openpilot/selfdrive/modeld/modeld.py @@ -6,6 +6,7 @@ import os os.environ['GMMU'] = '0' # for chestnut fast loading, noop for qcom from tinygrad.tensor import Tensor from tinygrad.device import Device +import usb1 import struct import threading import time @@ -31,6 +32,7 @@ from openpilot.selfdrive.modeld.parse_model_outputs import Parser from openpilot.selfdrive.modeld.compile_modeld import make_input_queues, WARP_INPUTS, POLICY_INPUTS from openpilot.selfdrive.modeld.fill_model_msg import fill_model_msg, fill_driving_model_data, fill_pose_msg, PublishState from openpilot.common.file_chunker import open_file_chunked +from openpilot.common.hardware.usb import CHESTNUT_USB_IDS from openpilot.selfdrive.modeld.constants import ModelConstants, Plan from openpilot.selfdrive.modeld.helpers import chestnut_present, chestnut_compiled, modeld_pkl_path, get_tg_input_devices, load_oob @@ -79,6 +81,37 @@ class ChestnutState: self.valid = True self.sends = 0 self.metrics = {} + self._asm_usb = None + + def _close_asm_usb(self) -> None: + if self._asm_usb is not None: + self._asm_usb.close() + self._asm_usb = None + + def _open_asm_usb(self): + context = usb1.USBContext() + for vendor_id, product_id in CHESTNUT_USB_IDS: + if (handle := context.openByVendorIDAndProductID(vendor_id, product_id, skip_on_error=True)) is not None: + return handle + context.close() + + def _read_ina(self) -> tuple[int, int, bool]: + if "AMD" in Device._opened_devices and self._asm_usb is None: + try: + raw = Device["AMD"].iface.pci_dev.usb.usb.control_read(0xC0, 5) + return struct.unpack(' int: @@ -114,13 +147,15 @@ class ChestnutState: setattr(state, k, v) asm_valid = False + try: + # ASM runs on USB-C power, these still read without a gpu + state.supplyVoltage, state.supplyCurrent, state.supplyFault = self._read_ina() + asm_valid = True + except Exception: + pass if "AMD" in Device._opened_devices: try: - # ASM runs on USB-C power, these still read without a gpu - asm = Device["AMD"].iface.pci_dev.usb - state.pcieLtssm = asm.read(0xB450, 1)[0] - state.supplyVoltage, state.supplyCurrent = struct.unpack('