diff --git a/AVRsack/ASProjDoc.swift b/AVRsack/ASProjDoc.swift index fd2ed95..a68efda 100644 --- a/AVRsack/ASProjDoc.swift +++ b/AVRsack/ASProjDoc.swift @@ -464,7 +464,13 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate { @IBAction func uploadProject(sender: AnyObject) { builder.continuation = { self.selectNodeInOutline(self.files.uploadLog) - self.builder.uploadProject(self.board, programmer:self.programmer, port:self.port) + ASSerialWin.portNeededForUpload(self.port) + self.builder.continuation = { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2*NSEC_PER_SEC)), dispatch_get_main_queue(), { + ASSerialWin.portAvailableAfterUpload(self.port) + }) + } + self.builder.uploadProject(self.board, programmer:self.programmer, port:ASSerial.fileNameForPort(self.port)) } buildProject(sender) } diff --git a/AVRsack/ASSerial.h b/AVRsack/ASSerial.h index 5c489c9..49fd934 100644 --- a/AVRsack/ASSerial.h +++ b/AVRsack/ASSerial.h @@ -12,6 +12,7 @@ extern NSString * kASSerialPortsChanged; @interface ASSerial : NSObject ++ (NSString *) fileNameForPort:(NSString *)port; + (NSArray *) ports; + (NSFileHandle *)openPort:(NSString *) port withSpeed:(int)speed; + (void)restorePort:(int)fileDescriptor; diff --git a/AVRsack/ASSerial.mm b/AVRsack/ASSerial.mm index 0fc0355..bff3c66 100644 --- a/AVRsack/ASSerial.mm +++ b/AVRsack/ASSerial.mm @@ -38,10 +38,16 @@ NSString * kASSerialPortsChanged = @"PortsChanged"; return cuPorts; } ++ (NSString *) fileNameForPort:(NSString *)port +{ + if ([port containsString:@"/"]) + return port; + else + return [NSString stringWithFormat:@"/dev/cu.%@", port]; +} + + (NSFileHandle *)openPort:(NSString *)port withSpeed:(int)speed { - if (![port containsString:@"/"]) - port = [NSString stringWithFormat:@"/dev/cu.%@", port]; - int fd = open([port UTF8String], O_RDWR | O_NOCTTY | O_NONBLOCK); + int fd = open([[self fileNameForPort:port] UTF8String], O_RDWR | O_NOCTTY | O_NONBLOCK); if (fd < 0) return nil; if (ioctl(fd, TIOCEXCL) < 0) diff --git a/AVRsack/ASSerialWin.swift b/AVRsack/ASSerialWin.swift index 461340d..efdadbf 100644 --- a/AVRsack/ASSerialWin.swift +++ b/AVRsack/ASSerialWin.swift @@ -12,7 +12,6 @@ private var serialInstances = [String : ASSerialWin]() private var keyboardHandler : ACEKeyboardHandler = .Ace class ASSerialWin: NSWindowController { - @IBOutlet weak var portPopUp : NSPopUpButton! @IBOutlet weak var inputLine : NSTextField! @IBOutlet weak var logView : ACEView! @@ -40,6 +39,7 @@ class ASSerialWin: NSWindowController { var currentTheme : UInt = 0 var fontSize : UInt = 12 var portDefaults = [String: AnyObject]() + var shouldReconnect = false class func showWindowWithPort(port: String) { if let existing = serialInstances[port] { @@ -50,6 +50,16 @@ class ASSerialWin: NSWindowController { newInstance.showWindow(self) } } + class func portNeededForUpload(port: String) { + if let existing = serialInstances[port] { + existing.disconnectTemporarily() + } + } + class func portAvailableAfterUpload(port: String) { + if let existing = serialInstances[port] { + existing.reconnect() + } + } convenience init(port: String) { self.init(windowNibName:"ASSerialWin") @@ -80,7 +90,14 @@ class ASSerialWin: NSWindowController { var nc = NSNotificationCenter.defaultCenter() serialObserver = nc.addObserverForName(kASSerialPortsChanged, object: nil, queue: nil, usingBlock: { (NSNotification) in - self.rebuildPortMenu() + self.willChangeValueForKey("hasValidPort") + self.didChangeValueForKey("hasValidPort") + + if self.hasValidPort { + self.reconnect() + } else { + self.disconnectTemporarily() + } }) } @@ -97,18 +114,11 @@ class ASSerialWin: NSWindowController { logView.setFontSize(fontSize) logView.setMode(UInt(ACEModeText)) logView.alphaValue = 0.8 - rebuildPortMenu() window?.title = port connect(self) super.windowDidLoad() } - func rebuildPortMenu() { - portPopUp.removeAllItems() - portPopUp.addItemsWithTitles(ASSerial.ports()) - portPopUp.selectItemWithTitle(port) - } - @IBAction func selectPort(item: AnyObject) { port = (item as NSPopUpButton).titleOfSelectedItem! window?.title = port @@ -121,6 +131,7 @@ class ASSerialWin: NSWindowController { } @IBAction func connect(AnyObject) { + shouldReconnect = false if portHandle != nil { ASSerial.restorePort(portHandle!.fileDescriptor) portHandle!.closeFile() @@ -144,6 +155,17 @@ class ASSerialWin: NSWindowController { } } } + func disconnectTemporarily() { + if portHandle != nil { + connect(self) // Disconnect temporarily + shouldReconnect = true // But express interest to reconnect + } + } + func reconnect() { + if portHandle == nil && shouldReconnect { + connect(self) // Reconnect + } + } var connectButtonTitle : String { get { @@ -153,6 +175,11 @@ class ASSerialWin: NSWindowController { class func keyPathsForValuesAffectingConnectButtonTitle() -> NSSet { return NSSet(object: "portHandle") } + var hasValidPort : Bool { + get { + return (ASSerial.ports() as NSArray).containsObject(port) + } + } // MARK: Editor configuration diff --git a/AVRsack/ASSerialWin.xib b/AVRsack/ASSerialWin.xib index 555426c..b4964b7 100644 --- a/AVRsack/ASSerialWin.xib +++ b/AVRsack/ASSerialWin.xib @@ -1,5 +1,5 @@ - + @@ -8,7 +8,6 @@ - @@ -76,7 +75,7 @@ - - - - - - - - - - - - - - - - - - + @@ -152,21 +134,8 @@ - - + - + - - - + diff --git a/AVRsack/Base.lproj/ASPreferences.xib b/AVRsack/Base.lproj/ASPreferences.xib index 730230c..1b03559 100644 --- a/AVRsack/Base.lproj/ASPreferences.xib +++ b/AVRsack/Base.lproj/ASPreferences.xib @@ -1,7 +1,7 @@ - + - + diff --git a/AVRsack/Base.lproj/ASProjDoc.xib b/AVRsack/Base.lproj/ASProjDoc.xib index 52cc028..e2a965f 100644 --- a/AVRsack/Base.lproj/ASProjDoc.xib +++ b/AVRsack/Base.lproj/ASProjDoc.xib @@ -1,5 +1,5 @@ - +