diff --git a/AVRsack/ASBuilder.swift b/AVRsack/ASBuilder.swift
index a468922..ec59ee0 100644
--- a/AVRsack/ASBuilder.swift
+++ b/AVRsack/ASBuilder.swift
@@ -57,25 +57,19 @@ class ASBuilder {
let libPath = (ASLibraries.instance().directories as NSArray).componentsJoinedByString(":")
var args = [NSString]()
let boardProp = ASHardware.instance().boards[board]!
- var corePath = ""
+ let library = boardProp["library"]!
+ var corePath = library+"/cores/"+boardProp["build.core"]!
var variantPath : NSString?
- for hw in ASHardware.instance().directories {
- corePath = hw+"/cores/"+boardProp["build.core"]!
- if fileManager.fileExistsAtPath(corePath) {
- if let variantName = boardProp["build.variant"] {
- variantPath = hw+"/variants/"+variantName
- if fileManager.fileExistsAtPath(variantPath!) {
- args.append("variant="+variantName)
- } else {
- variantPath = nil
- }
+ if fileManager.fileExistsAtPath(corePath) {
+ if let variantName = boardProp["build.variant"] {
+ variantPath = library+"/variants/"+variantName
+ if fileManager.fileExistsAtPath(variantPath!) {
+ args.append("variant="+variantName)
+ } else {
+ variantPath = nil
}
- break
- } else {
- corePath = ""
}
- }
- if corePath == "" {
+ } else {
NSLog("Unable to find core %s\n", boardProp["build.core"]!)
return
}
@@ -98,8 +92,16 @@ class ASBuilder {
task!.arguments = args;
task!.launch()
}
-
- func uploadProject(board: String, programmer: String, port: String, terminal: Bool = false) {
+
+ enum Mode {
+ case Upload
+ case BurnBootloader
+ case Interactive
+ }
+
+ func uploadProject(board: String, programmer: String, port: String, mode: Mode = .Upload) {
+ let useProgrammer = mode != .Upload
+ let interactive = mode == .Interactive
let portPath = ASSerial.fileNameForPort(port)
let toolChain = (NSApplication.sharedApplication().delegate as ASApplication).preferences.toolchainPath
task = NSTask()
@@ -108,7 +110,7 @@ class ASBuilder {
let fileManager = NSFileManager.defaultManager()
var logOut : NSFileHandle
- if terminal {
+ if interactive {
let inputPipe = NSPipe()
let outputPipe = NSPipe()
logOut = outputPipe.fileHandleForWriting
@@ -116,6 +118,7 @@ class ASBuilder {
task!.standardOutput = outputPipe
task!.standardError = outputPipe
} else {
+ ASSerialWin.portNeededForUpload(port)
let logURL = dir.URLByAppendingPathComponent("build/upload.log")
fileManager.createFileAtPath(logURL.path!, contents: NSData(), attributes: nil)
logOut = NSFileHandle(forWritingAtPath: logURL.path!)!
@@ -126,7 +129,7 @@ class ASBuilder {
let libPath = (ASLibraries.instance().directories as NSArray).componentsJoinedByString(":")
let boardProp = ASHardware.instance().boards[board]!
let progProp = ASHardware.instance().programmers[programmer]
- let hasBootloader = boardProp["upload.protocol"] != nil
+ let hasBootloader = !useProgrammer && boardProp["upload.protocol"] != nil
let leonardish = hasBootloader && (boardProp["bootloader.path"] ?? "").hasPrefix("caterina")
let proto = hasBootloader ? boardProp["upload.protocol"] : progProp?["protocol"]
let speed = hasBootloader ? boardProp["upload.speed"] : progProp?["speed"]
@@ -135,10 +138,59 @@ class ASBuilder {
args += [
"-C", toolChain+"/etc/avrdude.conf",
"-p", boardProp["build.mcu"]!, "-c", proto!, "-P", portPath]
- if terminal {
- args += ["-t"]
- } else {
+ switch mode {
+ case .Upload:
+ if hasBootloader {
+ args += ["-D"]
+ }
args += ["-U", "flash:w:build/"+board+"/"+dir.lastPathComponent+".hex:i"]
+ continuation = {
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2*NSEC_PER_SEC)), dispatch_get_main_queue(), {
+ ASSerialWin.portAvailableAfterUpload(port)
+ })
+ }
+ case .BurnBootloader:
+ var loaderArgs = args
+ args += ["-e"]
+ if let unlock = boardProp["bootloader.unlock_bits"] {
+ args += ["-Ulock:w:"+unlock+":m"]
+ }
+ if let efuse = boardProp["bootloader.extended_fuses"] {
+ args += ["-Uefuse:w:"+efuse+":m"]
+ }
+ let hfuse = boardProp["bootloader.high_fuses"]!
+ let lfuse = boardProp["bootloader.low_fuses"]!
+ args += ["-Uhfuse:w:"+hfuse+":m", "-Ulfuse:w:"+lfuse+":m"]
+ var needPhase2 = false
+ if let loaderPath = boardProp["bootloader.path"] {
+ let loader = boardProp["library"]!+"/bootloaders/"+loaderPath+"/"+boardProp["bootloader.file"]!
+ loaderArgs += ["-Uflash:w:"+loader+":i"]
+ needPhase2 = true
+ }
+ if let lock = boardProp["bootloader.lock_bits"] {
+ loaderArgs += ["-Ulock:w:"+lock+":m"]
+ needPhase2 = true
+ }
+ if needPhase2 {
+ let task2 = NSTask()
+ task2.currentDirectoryPath = dir.path!
+ task2.launchPath = toolChain+"/bin/avrdude"
+ task2.arguments = loaderArgs
+ task2.standardOutput = logOut
+ task2.standardError = logOut
+ continuation = {
+ let cmdLine = task2.launchPath+" "+(loaderArgs as NSArray).componentsJoinedByString(" ")+"\n"
+ logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
+ task2.launch()
+ self.continuation = {
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(2*NSEC_PER_SEC)), dispatch_get_main_queue(), {
+ ASSerialWin.portAvailableAfterUpload(port)
+ })
+ }
+ }
+ }
+ case .Interactive:
+ args += ["-t"]
}
if speed != nil {
args.append("-b")
@@ -171,7 +223,7 @@ class ASBuilder {
logOut.writeData(cmdLine.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!)
task!.arguments = args;
task!.launch()
- if terminal {
+ if interactive {
let intSpeed = speed?.toInt() ?? 19200
ASSerialWin.showWindowWithPort(port, task:task!, speed:intSpeed)
task = nil
diff --git a/AVRsack/ASHardware.swift b/AVRsack/ASHardware.swift
index 7f649e2..7d3a780 100644
--- a/AVRsack/ASHardware.swift
+++ b/AVRsack/ASHardware.swift
@@ -72,6 +72,7 @@ class ASHardware {
if seen.updateValue(true, forKey: board) == nil {
boards[board] = ASPropertyEntry()
boards[board]!["provenience"] = provenience
+ boards[board]!["library"] = dir
}
boards[board]![property] = value
}
diff --git a/AVRsack/ASProjDoc.swift b/AVRsack/ASProjDoc.swift
index 0274e1a..fe3970d 100644
--- a/AVRsack/ASProjDoc.swift
+++ b/AVRsack/ASProjDoc.swift
@@ -468,12 +468,6 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
@IBAction func uploadProject(sender: AnyObject) {
builder.continuation = {
self.selectNodeInOutline(self.files.uploadLog)
- 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)
- })
- }
dispatch_async(dispatch_get_main_queue(), {
self.builder.uploadProject(self.board, programmer:self.programmer, port:self.port)
})
@@ -482,7 +476,12 @@ class ASProjDoc: NSDocument, NSOutlineViewDelegate, NSMenuDelegate {
}
@IBAction func uploadTerminal(sender: AnyObject) {
- builder.uploadProject(board, programmer:programmer, port:port, terminal:true)
+ builder.uploadProject(board, programmer:programmer, port:port, mode:.Interactive)
+ }
+
+ @IBAction func burnBootloader(sender: AnyObject) {
+ self.selectNodeInOutline(self.files.uploadLog)
+ builder.uploadProject(board, programmer:programmer, port:port, mode:.BurnBootloader)
}
@IBAction func disassembleProject(sender: AnyObject) {
diff --git a/AVRsack/ASSerialWin.xib b/AVRsack/ASSerialWin.xib
index e6e18d5..e920db2 100644
--- a/AVRsack/ASSerialWin.xib
+++ b/AVRsack/ASSerialWin.xib
@@ -22,8 +22,8 @@
-
-
+
+
@@ -39,10 +39,10 @@