Skip to content

Commit 4c14a24

Browse files
committed
Rework daplink flash examples
1 parent fe063dd commit 4c14a24

File tree

5 files changed

+199
-214
lines changed

5 files changed

+199
-214
lines changed

examples/daplink-flash/common.js

Lines changed: 97 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -20,92 +20,123 @@
2020
* SOFTWARE.
2121
*/
2222

23-
const fs = require("fs");
24-
const http = require("http");
25-
const https = require("https");
26-
const readline = require("readline");
27-
const progress = require("progress");
28-
const EventEmitter = require("events");
29-
const DAPjs = require("../../");
30-
31-
// Emit keyboard input
32-
const inputEmitter = new EventEmitter();
33-
function setupEmitter() {
34-
process.stdin.setRawMode(true);
35-
process.stdin.setEncoding("utf8");
36-
process.stdin.on("readable", () => {
37-
let input;
38-
while (input = process.stdin.read()) {
39-
if (input === "\u0003") {
40-
process.exit();
41-
} else if (input !== null) {
42-
let index = parseInt(input);
43-
inputEmitter.emit("input", index);
44-
}
45-
}
46-
});
47-
}
23+
const fs = require('fs');
24+
const http = require('http');
25+
const https = require('https');
26+
const readline = require('readline');
27+
const progress = require('progress');
28+
const DAPjs = require('../../');
4829

49-
// Determine package URL or file path
50-
function getFileName() {
51-
return new Promise((resolve) => {
52-
if (process.argv[2]) {
53-
return resolve(process.argv[2]);
54-
}
55-
56-
let rl = readline.createInterface(process.stdin, process.stdout);
57-
rl.question("Enter a URL or file path for the firmware package: ", answer => {
58-
rl.close();
59-
resolve(answer);
60-
});
61-
rl.write("binaries/k64f-green.bin");
62-
});
30+
const getFile = async () => {
31+
const fileName = await getFileName();
32+
if (!fileName) {
33+
throw new Error('No file name specified');
34+
}
35+
36+
if (fileName.indexOf('http') === 0) {
37+
return downloadFile(fileName);
38+
}
39+
40+
return loadFile(fileName);
6341
}
6442

6543
// Load a file
66-
function loadFile(fileName, isJson=false) {
44+
const loadFile = (fileName, isJson = false) => {
6745
let file = fs.readFileSync(fileName);
6846
return isJson ? JSON.parse(file) : new Uint8Array(file).buffer;
6947
}
7048

7149
// Download a file
72-
function downloadFile(url, isJson=false) {
73-
return new Promise((resolve, reject) => {
74-
console.log("Downloading file...");
75-
let scheme = (url.indexOf("https") === 0) ? https : http;
50+
const downloadFile = async (url, isJson = false) => {
51+
console.log('Downloading file...');
52+
let scheme = (url.indexOf('https') === 0) ? https : http;
7653

54+
const data = await new Promise((resolve, reject) => {
7755
scheme.get(url, response => {
7856
let data = [];
79-
response.on("data", chunk => {
57+
response.on('data', chunk => {
8058
data.push(chunk);
8159
});
82-
response.on("end", () => {
83-
if (response.statusCode !== 200) return reject(response.statusMessage);
84-
85-
let download = Buffer.concat(data);
86-
if (isJson) {
87-
resolve(JSON.parse(data));
88-
}
89-
else {
90-
resolve(new Uint8Array(download).buffer);
60+
response.on('end', () => {
61+
if (response.statusCode !== 200) {
62+
reject(new Error(response.statusMessage));
63+
} else {
64+
resolve(data);
9165
}
9266
});
9367
})
94-
.on("error", error => {
68+
.on('error', error => {
9569
reject(error);
9670
});
9771
});
72+
73+
if (isJson) {
74+
return JSON.parse(data);
75+
} else {
76+
let download = Buffer.concat(data);
77+
return new Uint8Array(download).buffer;
78+
}
79+
}
80+
81+
// Determine package URL or file path
82+
const getFileName = async () => {
83+
if (process.argv[2]) {
84+
return process.argv[2];
85+
}
86+
87+
const rl = readline.createInterface(process.stdin, process.stdout);
88+
const fileName = await new Promise(resolve => {
89+
rl.question('Enter a URL or file path for the firmware package: ', answer => {
90+
rl.close();
91+
resolve(answer);
92+
});
93+
rl.write('binaries/k64f-green.bin');
94+
});
95+
96+
return fileName;
97+
}
98+
99+
// Select a device from the list
100+
const selectDevice = async (devices) => {
101+
if (devices.length === 0) {
102+
throw new Error('No devices found');
103+
}
104+
105+
console.log('Select a device to flash:');
106+
devices.forEach((device, index) => {
107+
console.log(`${index + 1}: ${device.name}`);
108+
});
109+
110+
const device = await new Promise(resolve => {
111+
process.stdin.setRawMode(true);
112+
process.stdin.setEncoding('utf8');
113+
process.stdin.on('readable', () => {
114+
let input;
115+
while (input = process.stdin.read()) {
116+
if (input === '\u0003') {
117+
process.exit();
118+
} else if (input !== null) {
119+
let index = parseInt(input);
120+
if (index <= devices.length) {
121+
resolve(devices[index - 1]);
122+
}
123+
}
124+
}
125+
});
126+
});
127+
128+
return device;
98129
}
99130

100131
// Update device using image buffer
101-
function flash(transport, program) {
132+
const flash = async (transport, program) => {
102133
console.log(`Using binary file ${program.byteLength} words long`);
103134
const target = new DAPjs.DAPLink(transport);
104135

105136
// Set up progressbar
106-
const progressBar = new progress("Updating firmware [:bar] :percent :etas", {
107-
complete: "=",
108-
incomplete: " ",
137+
const progressBar = new progress('Updating firmware [:bar] :percent :etas', {
138+
complete: '=',
139+
incomplete: ' ',
109140
width: 20,
110141
total: program.byteLength
111142
});
@@ -115,25 +146,14 @@ function flash(transport, program) {
115146
});
116147

117148
// Push binary to board
118-
return target.connect()
119-
.then(() => {
120-
return target.flash(program);
121-
})
122-
.then(() => {
123-
return target.disconnect();
124-
});
149+
await target.connect();
150+
await target.flash(program);
151+
await target.disconnect();
125152
}
126153

127154
module.exports = {
128-
inputEmitter: inputEmitter,
129-
setupEmitter: setupEmitter,
130-
flash: flash,
131-
getFile: () => {
132-
return getFileName()
133-
.then(fileName => {
134-
if (!fileName) throw new Error("No file name specified");
135-
if (fileName.indexOf("http") === 0) return downloadFile(fileName);
136-
return loadFile(fileName);
137-
});
138-
}
155+
DAPLINK_VENDOR: 0xD28,
156+
getFile,
157+
selectDevice,
158+
flash
139159
};

examples/daplink-flash/hid.js

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,44 +20,31 @@
2020
* SOFTWARE.
2121
*/
2222

23-
const hid = require("node-hid");
24-
const common = require("./common");
25-
const DAPjs = require("../../");
23+
const hid = require('node-hid');
24+
const common = require('./common');
25+
const DAPjs = require('../../');
2626

27-
// Allow user to select a device
28-
function selectDevice(vendorID) {
29-
return new Promise((resolve, reject) => {
30-
let devices = hid.devices();
31-
devices = devices.filter(device => device.vendorId === vendorID);
27+
// List all devices
28+
const getDevices = (vendorID) => {
29+
let devices = hid.devices();
30+
devices = devices.filter(device => device.vendorId === vendorID);
3231

33-
if (devices.length === 0) {
34-
return reject("No devices found");
35-
}
36-
37-
common.inputEmitter.addListener("input", index => {
38-
if (index <= devices.length) resolve(devices[index - 1]);
39-
});
40-
41-
console.log("Select a device to flash:");
42-
devices.forEach((device, index) => {
43-
console.log(`${index + 1}: ${device.product}`);
44-
});
45-
});
32+
return devices.map(device => ({
33+
...device,
34+
name: device.product
35+
}));
4636
}
4737

48-
common.getFile()
49-
.then(program => {
50-
common.setupEmitter();
51-
return selectDevice(0xD28)
52-
.then(device => {
38+
(async () => {
39+
try {
40+
const program = await common.getFile();
41+
const devices = getDevices(common.DAPLINK_VENDOR);
42+
const device = await common.selectDevice(devices);
5343
const transport = new DAPjs.HID(device);
54-
return common.flash(transport, program);
55-
});
56-
})
57-
.then(() => {
58-
process.exit();
59-
})
60-
.catch(error => {
61-
console.error(error.message || error);
62-
process.exit();
63-
});
44+
await common.flash(transport, program);
45+
} catch(error) {
46+
console.error(error.message || error);
47+
} finally {
48+
process.exit();
49+
}
50+
})();

examples/daplink-flash/usb.js

Lines changed: 35 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -20,63 +20,52 @@
2020
* SOFTWARE.
2121
*/
2222

23-
const usb = require("usb");
24-
const common = require("./common");
25-
const DAPjs = require("../../");
23+
const usb = require('usb');
24+
const common = require('./common');
25+
const DAPjs = require('../../');
2626

2727
// Read USB device descriptor
28-
function getStringDescriptor(device, index) {
28+
const getStringDescriptor = async (device, index) => {
29+
try {
30+
device.open();
31+
} catch (_e) {
32+
return '';
33+
}
34+
2935
return new Promise((resolve, reject) => {
30-
try {
31-
device.open();
32-
} catch (_e) {
33-
resolve("");
34-
}
3536
device.getStringDescriptor(index, (error, buffer) => {
3637
device.close();
37-
if (error) return reject(error);
38-
resolve(buffer.toString());
38+
if (error) {
39+
reject(new Error(error));
40+
} else {
41+
resolve(buffer.toString());
42+
}
3943
});
4044
});
4145
}
4246

43-
// Allow user to select a device
44-
function selectDevice(vendorID) {
45-
return new Promise((resolve, reject) => {
46-
let devices = usb.getDeviceList();
47-
devices = devices.filter(device => device.deviceDescriptor.idVendor === vendorID);
48-
49-
if (devices.length === 0) {
50-
return reject("No devices found");
51-
}
47+
// List all devices
48+
const getDevices = async (vendorID) => {
49+
let devices = usb.getDeviceList();
50+
devices = devices.filter(device => device.deviceDescriptor.idVendor === vendorID);
5251

53-
common.inputEmitter.addListener("input", index => {
54-
if (index <= devices.length) resolve(devices[index - 1]);
55-
});
52+
for (device of devices) {
53+
device.name = await getStringDescriptor(device, device.deviceDescriptor.iProduct);
54+
}
5655

57-
console.log("Select a device to flash:");
58-
devices.forEach((device, index) => {
59-
getStringDescriptor(device, device.deviceDescriptor.iProduct)
60-
.then(name => {
61-
console.log(`${index + 1}: ${name}`);
62-
});
63-
});
64-
});
56+
return devices;
6557
}
6658

67-
common.getFile()
68-
.then(program => {
69-
common.setupEmitter();
70-
return selectDevice(0xD28)
71-
.then(device => {
59+
(async () => {
60+
try {
61+
const program = await common.getFile();
62+
const devices = await getDevices(common.DAPLINK_VENDOR);
63+
const device = await common.selectDevice(devices);
7264
const transport = new DAPjs.USB(device);
73-
return common.flash(transport, program);
74-
});
75-
})
76-
.then(() => {
77-
process.exit();
78-
})
79-
.catch(error => {
80-
console.error(error.message || error);
81-
process.exit();
82-
});
65+
await common.flash(transport, program);
66+
} catch(error) {
67+
console.error(error.message || error);
68+
} finally {
69+
process.exit();
70+
}
71+
})();

0 commit comments

Comments
 (0)