Implement Burn Bootloader
This commit is contained in:
parent
533471fba8
commit
e13c7f5757
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
<rect key="frame" x="0.0" y="0.0" width="751" height="403"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<textField verticalHuggingPriority="750" misplaced="YES" translatesAutoresizingMaskIntoConstraints="NO" id="rIR-2b-lAh">
|
||||
<rect key="frame" x="0.0" y="0.0" width="651" height="22"/>
|
||||
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="rIR-2b-lAh">
|
||||
<rect key="frame" x="0.0" y="2" width="601" height="22"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" state="on" borderStyle="bezel" drawsBackground="YES" id="EBj-i4-UsA">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="textColor" catalog="System" colorSpace="catalog"/>
|
||||
|
@ -39,10 +39,10 @@
|
|||
</connections>
|
||||
</textField>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="MOe-eO-fyb">
|
||||
<rect key="frame" x="651" y="0.0" width="50" height="20"/>
|
||||
<rect key="frame" x="601" y="0.0" width="75" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="eLx-yy-gCn"/>
|
||||
<constraint firstAttribute="width" constant="50" id="vaT-Kd-3pn"/>
|
||||
<constraint firstAttribute="width" constant="75" id="vaT-Kd-3pn"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="square" title="Send" bezelStyle="shadowlessSquare" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Xt6-lT-b4z">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
|
@ -58,9 +58,9 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="H05-Rp-UzR">
|
||||
<rect key="frame" x="701" y="0.0" width="50" height="20"/>
|
||||
<rect key="frame" x="676" y="0.0" width="75" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="50" id="FWw-BQ-WKa"/>
|
||||
<constraint firstAttribute="width" constant="75" id="FWw-BQ-WKa"/>
|
||||
<constraint firstAttribute="height" constant="20" id="s7i-ZT-S7W"/>
|
||||
</constraints>
|
||||
<buttonCell key="cell" type="square" title="Now" bezelStyle="shadowlessSquare" imagePosition="overlaps" alignment="center" state="on" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="vZ4-fd-aE8">
|
||||
|
|
|
@ -395,6 +395,12 @@
|
|||
<action selector="uploadProject:" target="-1" id="Un4-q1-nWg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Burn Bootloader/Fuses" id="vvl-LN-SXu">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="burnBootloader:" target="-1" id="FYp-at-8g4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Upload Terminal" keyEquivalent="U" id="jAF-od-ZFb">
|
||||
<connections>
|
||||
<action selector="uploadTerminal:" target="-1" id="hth-ZZ-S3I"/>
|
||||
|
|
Loading…
Reference in New Issue
Block a user