def detect_highest_baud(self) -> Baudrate: """Tries to communicate in increasingly high baudrates up to 4M returns the highest one with at least 90% success rate. """ failure_threshold = 0.1 # allow up to 10% failure rate attempts = 10 # try up to 10 times per baudrate max_failures = attempts * failure_threshold last_valid_baud = Baudrate.b115200 for baud in Baudrate: # Ping1D hangs with a baudrate bigger than 3M, going to ignore it for now if baud > 3000000: continue logging.debug(f"Trying baud {baud}...") failures = 0 ping = PingDevice() ping.connect_serial(self.ping.port.device, baud) for _ in range(attempts): device_info = ping.request(COMMON_DEVICE_INFORMATION, timeout=0.1) if device_info is None: failures += 1 if failures > max_failures: break # there's no pointing in testing again if we already failed. if failures <= max_failures: last_valid_baud = baud logging.debug( f"Baudrate {baud} is {'valid' if baud==last_valid_baud else 'invalid'}" ) logging.info(f"Highest baudrate detected: {last_valid_baud}") return last_valid_baud
def detect_device(self, dev): """ Attempts to detect the Ping device attached to serial port 'dev' Returns the new path with encoded name if detected, or None if the device was not detected """ ping = PingDevice("/dev/serial/by-id/" + dev, 115200) if not ping.initialize(): return None device_info = ping.request(COMMON_DEVICE_INFORMATION) if not device_info: return self.legacy_detect_ping1d(ping) if device_info.device_type == 1: description = "/dev/serial/ping/Ping1D-id-%s-r-%s-v-%s.%s.%s" elif device_info.device_type == 2: description = "/dev/serial/ping/Ping360-id-%s-r-%s-v-%s.%s.%s" # Open device with 2M baud to setup Ping360 print("Setting baud to 2M...") ser = serial.Serial("/dev/serial/by-id/" + dev, 2000000) ser.send_break() ser.write("UUUUUUU".encode()) ser.close() self.set_low_latency(dev) else: return None return description % (device_info.src_device_id, device_info.device_revision, device_info.firmware_version_major, device_info.firmware_version_minor, device_info.firmware_version_patch)
def start(self) -> None: """Starts the driver""" baud = self.detect_highest_baud() # Do a ping connection to set the baudrate PingDevice().connect_serial(self.ping.port.device, baud) set_low_latency(self.ping.port) self.bridge = Bridge(self.ping.port, baud, "0.0.0.0", self.port)
def legacy_detect_ping1d(port: SysFS) -> Optional[PingDeviceDescriptor]: """ Detects Ping1D devices without DEVICE_INFORMATION implemented """ ping = PingDevice() ping.connect_serial(port.device, 115200) firmware_version = ping.request(PING1D_FIRMWARE_VERSION) if firmware_version is None: return None descriptor = PingDeviceDescriptor( ping_type=PingType.PING1D, device_id=firmware_version.src_device_id, device_model=firmware_version.device_model, device_revision=0, # not available in this message firmware_version_major=firmware_version.firmware_version_major, firmware_version_minor=firmware_version.firmware_version_minor, firmware_version_patch=0, port=port, ) logging.info("Identified ping device:") logging.info(descriptor) return descriptor
def detect_device(self, port: SysFS) -> Optional[PingDeviceDescriptor]: """ Attempts to detect the Ping device attached to serial port 'dev' Returns the new path with encoded name if detected, or None if the device was not detected """ try: ping = PingDevice() ping.connect_serial(port.device, 115200) except Exception as exception: if exception.args[0] and "Errno 16" in exception.args[0]: logging.info(f"Device {port.hwid} is busy. Re-trying...") return None logging.info( f"An exception has occurred while attempting to" f"talk Ping to device {port.hwid}: {exception}" f"If this is not a Ping device, this is expected." ) return None if not ping.initialize(): return None device_info = ping.request(COMMON_DEVICE_INFORMATION) if not device_info: return self.legacy_detect_ping1d(port) if device_info.device_type not in [PingType.PING1D, PingType.PING360]: logging.warning( f"PingProber was able to talk Ping to {port.hwid}," f"but the device id {device_info.device_type} is not known" ) return None descriptor = PingDeviceDescriptor( ping_type=PingType(device_info.device_type), device_id=device_info.src_device_id, device_model=0, # not available in this message device_revision=device_info.device_revision, firmware_version_major=device_info.firmware_version_major, firmware_version_minor=device_info.firmware_version_minor, firmware_version_patch=0, port=port, ) logging.info("Identified ping device:") logging.info(descriptor) return descriptor
def initialize(self): if not PingDevice.initialize(self): return False if self.legacyRequest(definitions.PING1D_GENERAL_INFO) is None: return False return True
def initialize(self): if not PingDevice.initialize(self): return False if (self.readDeviceInformation() is None): return False return True