From c138628c00c0e1b627d35d5d6d32dd3a6c58ffd0 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 11 Jun 2015 17:00:53 +0200 Subject: [PATCH 1/4] When ports "move", they move in mysterious ways. Watching them closely so we don't miss the catch --- .../packages/uploaders/SerialUploader.java | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java b/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java index b9e7ca88c..f95344995 100644 --- a/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java +++ b/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java @@ -106,17 +106,18 @@ public class SerialUploader extends Uploader { t = prefs.get("upload.wait_for_upload_port"); boolean waitForUploadPort = (t != null) && t.equals("true"); - String uploadPort = prefs.getOrExcept("serial.port"); + String userSelectedUploadPort = prefs.getOrExcept("serial.port"); + String actualUploadPort = null; if (doTouch) { try { // Toggle 1200 bps on selected serial port to force board reset. List before = Serial.list(); - if (before.contains(uploadPort)) { + if (before.contains(userSelectedUploadPort)) { if (verbose) System.out.println( - I18n.format(_("Forcing reset using 1200bps open/close on port {0}"), uploadPort)); - Serial.touchForCDCReset(uploadPort); + I18n.format(_("Forcing reset using 1200bps open/close on port {0}"), userSelectedUploadPort)); + Serial.touchForCDCReset(userSelectedUploadPort); } Thread.sleep(400); if (waitForUploadPort) { @@ -124,18 +125,21 @@ public class SerialUploader extends Uploader { // otherwise assert DTR, which would cancel the WDT reset if // it happened within 250 ms. So we wait until the reset should // have already occured before we start scanning. - uploadPort = waitForUploadPort(uploadPort, before); + actualUploadPort = waitForUploadPort(userSelectedUploadPort, before); } } catch (SerialException e) { throw new RunnerException(e); } catch (InterruptedException e) { throw new RunnerException(e.getMessage()); } - prefs.put("serial.port", uploadPort); - if (uploadPort.startsWith("/dev/")) { - prefs.put("serial.port.file", uploadPort.substring(5)); + if (actualUploadPort == null) { + actualUploadPort = userSelectedUploadPort; + } + prefs.put("serial.port", actualUploadPort); + if (actualUploadPort.startsWith("/dev/")) { + prefs.put("serial.port.file", actualUploadPort.substring(5)); } else { - prefs.put("serial.port.file", uploadPort); + prefs.put("serial.port.file", actualUploadPort); } } @@ -158,9 +162,9 @@ public class SerialUploader extends Uploader { throw new RunnerException(e); } + String finalUploadPort = null; if (uploadResult && doTouch) { try { - String previousUploadPort = PreferencesData.get("serial.port"); if (waitForUploadPort) { // For Due/Leonardo wait until the bootloader serial port disconnects and the // sketch serial port reconnects (or timeout after a few seconds if the @@ -170,7 +174,11 @@ public class SerialUploader extends Uploader { long started = System.currentTimeMillis(); while (System.currentTimeMillis() - started < 2000) { List portList = Serial.list(); - if (portList.contains(previousUploadPort)) { + if (portList.contains(actualUploadPort)) { + finalUploadPort = actualUploadPort; + break; + } else if (portList.contains(userSelectedUploadPort)) { + finalUploadPort = userSelectedUploadPort; break; } Thread.sleep(250); @@ -181,7 +189,10 @@ public class SerialUploader extends Uploader { } } - BaseNoGui.selectSerialPort(uploadPort); + if (finalUploadPort == null) { + finalUploadPort = actualUploadPort; + } + BaseNoGui.selectSerialPort(finalUploadPort); return uploadResult; } From 8139e85ef1e78b584cffe7c835f73e2a3c75a1c3 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Thu, 11 Jun 2015 17:02:01 +0200 Subject: [PATCH 2/4] On some OSs, some boards may take time before reappearing. Better wait for them 5 reasonable seconds --- app/src/processing/app/Editor.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/processing/app/Editor.java b/app/src/processing/app/Editor.java index 43a958c7f..e9e987c2f 100644 --- a/app/src/processing/app/Editor.java +++ b/app/src/processing/app/Editor.java @@ -70,6 +70,8 @@ import cc.arduino.packages.uploaders.SerialUploader; @SuppressWarnings("serial") public class Editor extends JFrame implements RunnerListener { + public static final int MAX_TIME_AWAITING_FOR_RESUMING_SERIAL_MONITOR = 5000; + private final Platform platform; private JMenu recentSketchesMenu; @@ -2411,6 +2413,16 @@ public class Editor extends JFrame implements RunnerListener { // Return the serial monitor window to its initial state if (serialMonitor != null) { BoardPort boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port")); + long sleptFor = 0; + while (boardPort == null && sleptFor < MAX_TIME_AWAITING_FOR_RESUMING_SERIAL_MONITOR) { + try { + Thread.sleep(100); + sleptFor += 100; + boardPort = BaseNoGui.getDiscoveryManager().find(PreferencesData.get("serial.port")); + } catch (InterruptedException e) { + // noop + } + } try { if (boardPort == null) { serialMonitor.close(); From 54971e451f7bf57fb7be17943edccc5510d1632e Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 12 Jun 2015 10:57:33 +0200 Subject: [PATCH 3/4] SerialUploader: actualUploadPort may still be null, in that case fall back to userSelectedUploadPort --- .../src/cc/arduino/packages/uploaders/SerialUploader.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java b/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java index f95344995..1b5c8c9fe 100644 --- a/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java +++ b/arduino-core/src/cc/arduino/packages/uploaders/SerialUploader.java @@ -192,6 +192,9 @@ public class SerialUploader extends Uploader { if (finalUploadPort == null) { finalUploadPort = actualUploadPort; } + if (finalUploadPort == null) { + finalUploadPort = userSelectedUploadPort; + } BaseNoGui.selectSerialPort(finalUploadPort); return uploadResult; } From 64fcc716c9e43bb4b19f2c0a04a491b9a4201fba Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Fri, 12 Jun 2015 13:54:46 +0200 Subject: [PATCH 4/4] MacOSX: SystemProfilerParser nows claims to have found the device even if the name is not exactly the same --- .../app/macosx/SystemProfilerParserTest.java | 4 + .../app/macosx/system_profiler_output8.txt | 96 +++++++++++++++++++ .../app/macosx/SystemProfilerParser.java | 17 +++- 3 files changed, 112 insertions(+), 5 deletions(-) create mode 100644 app/test/processing/app/macosx/system_profiler_output8.txt diff --git a/app/test/processing/app/macosx/SystemProfilerParserTest.java b/app/test/processing/app/macosx/SystemProfilerParserTest.java index 30c6f6b63..1476822c4 100644 --- a/app/test/processing/app/macosx/SystemProfilerParserTest.java +++ b/app/test/processing/app/macosx/SystemProfilerParserTest.java @@ -74,5 +74,9 @@ public class SystemProfilerParserTest { assertEquals("0X2341_0X8036", new SystemProfilerParser().extractVIDAndPID(output, "/dev/tty.usbmodem24131")); assertEquals("0X0403_0X6015", new SystemProfilerParser().extractVIDAndPID(output, "/dev/cu.usbserial-DN0031EV")); assertEquals("0X0403_0X6015", new SystemProfilerParser().extractVIDAndPID(output, "/dev/tty.usbserial-DN0031EV")); + + output = TestHelper.inputStreamToString(SystemProfilerParserTest.class.getResourceAsStream("system_profiler_output8.txt")); + + assertEquals("0X03EB_0X2157", new SystemProfilerParser().extractVIDAndPID(output, "/dev/tty.usbmodemfd132")); } } diff --git a/app/test/processing/app/macosx/system_profiler_output8.txt b/app/test/processing/app/macosx/system_profiler_output8.txt new file mode 100644 index 000000000..13a2d7f8e --- /dev/null +++ b/app/test/processing/app/macosx/system_profiler_output8.txt @@ -0,0 +1,96 @@ +USB: + + USB Hi-Speed Bus: + + Host Controller Location: Built-in USB + Host Controller Driver: AppleUSBEHCI + PCI Device ID: 0x1c2d + PCI Revision ID: 0x0005 + PCI Vendor ID: 0x8086 + Bus Number: 0xfa + + Hub: + + Product ID: 0x2513 + Vendor ID: 0x0424 (SMSC) + Version: b.b3 + Speed: Up to 480 Mb/sec + Location ID: 0xfa100000 / 2 + Current Available (mA): 500 + Current Required (mA): 2 + + Arduino Leonardo: + + Product ID: 0x8036 + Vendor ID: 0x2341 + Version: 1.00 + Speed: Up to 12 Mb/sec + Manufacturer: Arduino LLC + Location ID: 0xfa120000 / 5 + Current Available (mA): 500 + Current Required (mA): 500 + + BRCM20702 Hub: + + Product ID: 0x4500 + Vendor ID: 0x0a5c (Broadcom Corp.) + Version: 1.00 + Speed: Up to 12 Mb/sec + Manufacturer: Apple Inc. + Location ID: 0xfa110000 / 3 + Current Available (mA): 500 + Current Required (mA): 94 + + Bluetooth USB Host Controller: + + Product ID: 0x8281 + Vendor ID: 0x05ac (Apple Inc.) + Version: 1.25 + Speed: Up to 12 Mb/sec + Manufacturer: Apple Inc. + Location ID: 0xfa113000 / 4 + Current Available (mA): 500 + Current Required (mA): 0 + + USB Hi-Speed Bus: + + Host Controller Location: Built-in USB + Host Controller Driver: AppleUSBEHCI + PCI Device ID: 0x1c26 + PCI Revision ID: 0x0005 + PCI Vendor ID: 0x8086 + Bus Number: 0xfd + + Hub: + + Product ID: 0x2513 + Vendor ID: 0x0424 (SMSC) + Version: b.b3 + Speed: Up to 480 Mb/sec + Location ID: 0xfd100000 / 2 + Current Available (mA): 500 + Current Required (mA): 2 + + EDBG CMSIS-DAP: + + Product ID: 0x2157 + Vendor ID: 0x03eb (Atmel Corporation) + Version: 1.01 + Serial Number: 00000000AZE000000310 + Speed: Up to 480 Mb/sec + Manufacturer: Atmel Corp. + Location ID: 0xfd130000 / 4 + Current Available (mA): 500 + Current Required (mA): 500 + + IR Receiver: + + Product ID: 0x8242 + Vendor ID: 0x05ac (Apple Inc.) + Version: 0.16 + Speed: Up to 1.5 Mb/sec + Manufacturer: Apple Computer, Inc. + Location ID: 0xfd110000 / 3 + Current Available (mA): 500 + Current Required (mA): 100 + diff --git a/arduino-core/src/processing/app/macosx/SystemProfilerParser.java b/arduino-core/src/processing/app/macosx/SystemProfilerParser.java index bef99387c..2e1d77462 100644 --- a/arduino-core/src/processing/app/macosx/SystemProfilerParser.java +++ b/arduino-core/src/processing/app/macosx/SystemProfilerParser.java @@ -55,7 +55,7 @@ public class SystemProfilerParser { if ((matcher = serialNumberRegex.matcher(line)).matches()) { device.put(SERIAL_NUMBER, matcher.group(1)); - if ((serial.startsWith(DEV_TTY_USBSERIAL) || serial.startsWith(DEV_CU_USBSERIAL))) { + if (serial.startsWith(DEV_TTY_USBSERIAL) || serial.startsWith(DEV_CU_USBSERIAL)) { String devicePath = devicePrefix + matcher.group(1); device.put(DEVICE_PATH, devicePath); } @@ -65,17 +65,24 @@ public class SystemProfilerParser { device.put(DEVICE_PATH, devicePath); } else if ((matcher = pidRegex.matcher(line)).matches()) { String pid = matcher.group(1); - if (pid.indexOf(" ") > 0) + if (pid.indexOf(" ") > 0) { pid = pid.substring(0, pid.indexOf(" ")); // Remove any text after the hex number + } device.put(PID, pid); } else if ((matcher = vidRegex.matcher(line)).matches()) { String vid = matcher.group(1); - if (vid.indexOf(" ") > 0) + if (vid.indexOf(" ") > 0) { vid = vid.substring(0, vid.indexOf(" ")); // Remove any text after the hex number + } device.put(VID, vid); } else if (line.equals("")) { - if (device.containsKey(DEVICE_PATH) && device.get(DEVICE_PATH).equals(serial)) { - return (device.get(VID) + "_" + device.get(PID)).toUpperCase(); + if (device.containsKey(DEVICE_PATH)) { + String computedDevicePath = device.get(DEVICE_PATH); + String computedDevicePathMinusChar = computedDevicePath.substring(0, computedDevicePath.length() - 1); + String serialMinusChar = serial.substring(0, serial.length() - 1); + if (computedDevicePath.equals(serial) || computedDevicePathMinusChar.equals(serialMinusChar)) { + return (device.get(VID) + "_" + device.get(PID)).toUpperCase(); + } } device = new HashMap(); }