Skip to content
This repository was archived by the owner on Oct 1, 2024. It is now read-only.

Commit 1af89ca

Browse files
czgtestSneezry
authored andcommitted
upload using programmer (#553)
1 parent 0695332 commit 1af89ca

File tree

8 files changed

+225
-0
lines changed

8 files changed

+225
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ This extension provides several commands in the Command Palette (`F1` or `Ctrl +
4747
- **Arduino: Select Serial Port**: Change the current serial port.
4848
- **Arduino: Send Text to Serial Port**: Send a line of text via the current serial port.
4949
- **Arduino: Upload**: Build sketch and upload to Arduino board.
50+
- **Arduino: Upload Using Programmer**: Upload using an external programmer.
5051
- **Arduino: Verify**: Build sketch.
5152

5253
## Options

package.json

+10
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@
3636
"*",
3737
"onCommand:arduino.verify",
3838
"onCommand:arduino.upload",
39+
"onCommand:arduino.uploadUsingProgrammer",
40+
"onCommand:arduino.selectProgrammer",
3941
"onCommand:arduino.selectSerialPort",
4042
"onCommand:arduino.changeBaudRate",
4143
"onCommand:arduino.addLibPath",
@@ -75,6 +77,14 @@
7577
"command": "arduino.upload",
7678
"title": "Arduino: Upload"
7779
},
80+
{
81+
"command": "arduino.uploadUsingProgrammer",
82+
"title": "Arduino: Upload Using Programmer"
83+
},
84+
{
85+
"command": "arduino.selectProgrammer",
86+
"title": "Arduino: Select Programmer"
87+
},
7888
{
7989
"command": "arduino.selectSerialPort",
8090
"title": "Arduino: Select Serial Port"

src/arduino/arduino.ts

+78
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { arduinoChannel } from "../common/outputChannel";
2222
import { ArduinoWorkspace } from "../common/workspace";
2323
import { SerialMonitor } from "../serialmonitor/serialMonitor";
2424
import { UsbDetector } from "../serialmonitor/usbDetector";
25+
import { ProgrammerManager } from "./programmerManager";
2526

2627
/**
2728
* Represent an Arduino application based on the official Arduino IDE.
@@ -34,6 +35,8 @@ export class ArduinoApp {
3435

3536
private _exampleManager: ExampleManager;
3637

38+
private _programmerManager: ProgrammerManager;
39+
3740
/**
3841
* @param {IArduinoSettings} _settings ArduinoSetting object.
3942
*/
@@ -154,6 +157,64 @@ export class ArduinoApp {
154157
});
155158
}
156159

160+
public async uploadUsingProgrammer() {
161+
const dc = DeviceContext.getInstance();
162+
const boardDescriptor = this.getBoardBuildString();
163+
if (!boardDescriptor) {
164+
return;
165+
}
166+
167+
const selectProgrammer = this.getProgrammerString();
168+
if (!selectProgrammer) {
169+
return;
170+
}
171+
172+
if (!ArduinoWorkspace.rootPath) {
173+
vscode.window.showWarningMessage("Cannot find the sketch file.");
174+
return;
175+
}
176+
177+
if (!dc.sketch || !util.fileExistsSync(path.join(ArduinoWorkspace.rootPath, dc.sketch))) {
178+
await this.getMainSketch(dc);
179+
}
180+
if (!dc.port) {
181+
vscode.window.showErrorMessage("Please specify the upload serial port.");
182+
return;
183+
}
184+
185+
arduinoChannel.show();
186+
arduinoChannel.start(`Upload sketch - ${dc.sketch}`);
187+
188+
const serialMonitor = SerialMonitor.getInstance();
189+
190+
const needRestore = await serialMonitor.closeSerialMonitor(dc.port);
191+
UsbDetector.getInstance().pauseListening();
192+
await vscode.workspace.saveAll(false);
193+
194+
const appPath = path.join(ArduinoWorkspace.rootPath, dc.sketch);
195+
const args = ["--upload", "--board", boardDescriptor, "--port", dc.port, "--useprogrammer",
196+
"--pref", "programmer=" + selectProgrammer, appPath];
197+
if (VscodeSettings.getInstance().logLevel === "verbose") {
198+
args.push("--verbose");
199+
}
200+
if (dc.output) {
201+
const outputPath = path.resolve(ArduinoWorkspace.rootPath, dc.output);
202+
args.push("--pref", `build.path=${outputPath}`);
203+
} else {
204+
const msg = "Output path is not specified. Unable to reuse previously compiled files. Upload could be slow. See README.";
205+
arduinoChannel.warning(msg);
206+
}
207+
await util.spawn(this._settings.commandPath, arduinoChannel.channel, args).then(async () => {
208+
UsbDetector.getInstance().resumeListening();
209+
if (needRestore) {
210+
await serialMonitor.openSerialMonitor();
211+
}
212+
arduinoChannel.end(`Uploaded the sketch: ${dc.sketch}${os.EOL}`);
213+
}, (reason) => {
214+
arduinoChannel.error(`Exit with code=${reason.code}${os.EOL}`);
215+
});
216+
}
217+
157218
public async verify(output: string = "") {
158219
const dc = DeviceContext.getInstance();
159220
const boardDescriptor = this.getBoardBuildString();
@@ -528,6 +589,23 @@ export class ArduinoApp {
528589
this._exampleManager = value;
529590
}
530591

592+
public get programmerManager() {
593+
return this._programmerManager;
594+
}
595+
596+
public set programmerManager(value: ProgrammerManager) {
597+
this._programmerManager = value;
598+
}
599+
600+
private getProgrammerString(): string {
601+
const selectProgrammer = this.programmerManager.currentProgrammer;
602+
if (!selectProgrammer) {
603+
Logger.notifyUserError("getProgrammerString", new Error(constants.messages.NO_PROGRAMMMER_SELECTED));
604+
return;
605+
}
606+
return selectProgrammer;
607+
}
608+
531609
private getBoardBuildString(): string {
532610
const selectedBoard = this.boardManager.currentBoard;
533611
if (!selectedBoard) {

src/arduino/programmerManager.ts

+104
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
import * as vscode from "vscode";
2+
import * as constants from "../common/constants";
3+
import { ArduinoApp } from "./arduino";
4+
import { IArduinoSettings } from "./arduinoSettings";
5+
import { ArduinoSettings } from "./arduinoSettings";
6+
7+
export enum ProgrammerList {
8+
"AVR ISP",
9+
"AVRISP mkII",
10+
"USBtinyISP",
11+
"ArduinoISP",
12+
"ArduinoISP.org",
13+
"USBasp",
14+
"Parallel Programmer",
15+
"Arduino as ISP",
16+
"Arduino Gemma",
17+
"BusPirate as ISP",
18+
"Atmel STK500 development board",
19+
"Atmel JTAGICE3 (ISP mode)",
20+
"Atmel JTAGICE3 (JTAG mode)",
21+
"Atmel-ICE (AVR)",
22+
}
23+
24+
export class ProgrammerManager {
25+
26+
private static _programmerManager: ProgrammerManager = null;
27+
28+
private _currentprogrammer: ProgrammerList;
29+
30+
private _programmervalue: string;
31+
32+
private _programmerStatusBar: vscode.StatusBarItem;
33+
34+
constructor(private _settings: IArduinoSettings, private _arduinoApp: ArduinoApp) {
35+
this._programmerStatusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, constants.statusBarPriority.PROGRAMMER);
36+
this._programmerStatusBar.command = "arduino.selectProgrammer";
37+
this._programmerStatusBar.tooltip = "Select Programmer";
38+
this._programmerStatusBar.text = "<Select Programmer>";
39+
this._programmerStatusBar.show();
40+
}
41+
42+
public get currentProgrammer(): string {
43+
return this._programmervalue;
44+
}
45+
46+
public async selectProgrammer() {
47+
const chosen: string | undefined = await vscode.window.showQuickPick(Object.keys(ProgrammerList)
48+
.filter((key) => {
49+
return !isNaN(Number(ProgrammerList[key]));
50+
}), { placeHolder: "Select programmer" });
51+
if (!chosen) {
52+
return;
53+
}
54+
this._currentprogrammer = ProgrammerList[chosen];
55+
this.getProgrammer(this._currentprogrammer);
56+
this._programmerStatusBar.text = chosen;
57+
}
58+
59+
public getProgrammer(newProgrammer: ProgrammerList) {
60+
switch (newProgrammer) {
61+
case ProgrammerList["AVR ISP"]:
62+
this._programmervalue = "arduino:avrisp";
63+
break;
64+
case ProgrammerList["AVRISP mkII"]:
65+
this._programmervalue = "arduino:avrispmkii";
66+
break;
67+
case ProgrammerList.USBtinyISP:
68+
this._programmervalue = "arduino:usbtinyisp";
69+
break;
70+
case ProgrammerList.ArduinoISP:
71+
this._programmervalue = "arduino:arduinoisp";
72+
break;
73+
case ProgrammerList.USBasp:
74+
this._programmervalue = "arduino:usbasp";
75+
break;
76+
case ProgrammerList["Parallel Programmer"]:
77+
this._programmervalue = "arduino:parallel";
78+
break;
79+
case ProgrammerList["Arduino as ISP"]:
80+
this._programmervalue = "arduino:arduinoasisp";
81+
break;
82+
case ProgrammerList["Arduino Gemma"]:
83+
this._programmervalue = "arduino:usbGemma";
84+
break;
85+
case ProgrammerList["BusPirate as ISP"]:
86+
this._programmervalue = "arduino:buspirate";
87+
break;
88+
case ProgrammerList["Atmel STK500 development board"]:
89+
this._programmervalue = "arduino:stk500";
90+
break;
91+
case ProgrammerList["Atmel JTAGICE3 (ISP mode)"]:
92+
this._programmervalue = "arduino:jtag3isp";
93+
break;
94+
case ProgrammerList["Atmel JTAGICE3 (JTAG mode)"]:
95+
this._programmervalue = "arduino:jtag3";
96+
break;
97+
case ProgrammerList["Atmel-ICE (AVR)"]:
98+
this._programmervalue = "arduino:atmel_ice";
99+
break;
100+
default:
101+
break;
102+
}
103+
}
104+
}

src/arduinoActivator.ts

+2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { BoardManager } from "./arduino/boardManager";
99
import { ExampleManager } from "./arduino/exampleManager";
1010
import { ExampleProvider } from "./arduino/exampleProvider";
1111
import { LibraryManager } from "./arduino/libraryManager";
12+
import { ProgrammerManager } from "./arduino/programmerManager";
1213
import ArduinoContext from "./arduinoContext";
1314
import { DeviceContext } from "./deviceContext";
1415

@@ -37,6 +38,7 @@ class ArduinoActivator {
3738
await arduinoApp.boardManager.loadPackages();
3839
arduinoApp.libraryManager = new LibraryManager(arduinoSettings, arduinoApp);
3940
arduinoApp.exampleManager = new ExampleManager(arduinoSettings, arduinoApp);
41+
arduinoApp.programmerManager = new ProgrammerManager(arduinoSettings, arduinoApp);
4042
ArduinoContext.arduinoApp = arduinoApp;
4143

4244
const exampleProvider = new ExampleProvider(arduinoApp.exampleManager, arduinoApp.boardManager);

src/common/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const messages = {
2626
FAILED_SEND_SERIALPORT: "Failed to send message to serial port.",
2727
SERIAL_PORT_NOT_STARTED: "Serial Monitor has not been started.",
2828
SEND_BEFORE_OPEN_SERIALPORT: "Please open a serial port first.",
29+
NO_PROGRAMMMER_SELECTED: "Please select the programmer first.",
2930
};
3031

3132
export const statusBarPriority = {
@@ -35,4 +36,5 @@ export const statusBarPriority = {
3536
BOARD: 60,
3637
ENDING: 70,
3738
SKETCH: 80,
39+
PROGRAMMER: 90,
3840
};

src/extension.ts

+26
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,32 @@ export async function activate(context: vscode.ExtensionContext) {
193193
deviceContext.showStatusBar();
194194
});
195195

196+
registerArduinoCommand("arduino.uploadUsingProgrammer", async () => {
197+
if (!status.compile) {
198+
status.compile = "upload";
199+
try {
200+
await ArduinoContext.arduinoApp.uploadUsingProgrammer();
201+
} catch (ex) {
202+
}
203+
delete status.compile;
204+
}
205+
}, () => {
206+
return { board: ArduinoContext.boardManager.currentBoard.name };
207+
});
208+
209+
registerArduinoCommand("arduino.selectProgrammer", async () => {
210+
if (!status.compile) {
211+
status.compile = "upload";
212+
try {
213+
await ArduinoContext.arduinoApp.programmerManager.selectProgrammer();
214+
} catch (ex) {
215+
}
216+
delete status.compile;
217+
}
218+
}, () => {
219+
return { board: ArduinoContext.boardManager.currentBoard.name };
220+
});
221+
196222
registerArduinoCommand("arduino.addLibPath", (path) => ArduinoContext.arduinoApp.addLibPath(path));
197223
registerArduinoCommand("arduino.openExample", (path) => ArduinoContext.arduinoApp.openExample(path));
198224
registerArduinoCommand("arduino.loadPackages", async () => await ArduinoContext.boardManager.loadPackages(true));

test/extension.test.ts

+2
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ suite("Arduino: Extension Tests", () => {
3434
const ARDUINO_COMMANDS = [
3535
"arduino.verify",
3636
"arduino.upload",
37+
"arduino.uploadUsingProgrammer",
38+
"arduino.selectProgrammer",
3739
"arduino.showBoardManager",
3840
"arduino.showLibraryManager",
3941
"arduino.showBoardConfig",

0 commit comments

Comments
 (0)