Skip to content

Commit 7fa5362

Browse files
author
Alberto Iannaccone
committed
update firmware of wifi101 and wifiNINA to latest stable version
1 parent fc503b0 commit 7fa5362

File tree

3 files changed

+221
-0
lines changed

3 files changed

+221
-0
lines changed

demo/app.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,17 @@ const handleBootloaderMode = (e, port) => {
5050
daemon.setBootloaderMode(port);
5151
};
5252

53+
const handleUpdateFirmware = (e, boardId, port, wifiModule) => {
54+
e.preventDefault();
55+
daemon.updateFirmware(boardId, port, wifiModule).then(response => {
56+
console.log('Firmware updated successfully!')
57+
console.log(response)
58+
}).catch(reason => {
59+
console.log('Something went wrong when trying to update the firmware')
60+
console.error(reason)
61+
});
62+
};
63+
5364
const handleDownloadTool = e => {
5465
e.preventDefault();
5566
const toolname = document.getElementById('toolname');
@@ -179,6 +190,10 @@ class App extends React.Component {
179190
close
180191
</a> - <a href="#" onClick={(e) => handleBootloaderMode(e, device.Name)}>
181192
bootloader mode
193+
</a> - <a href="#" onClick={(e) => handleUpdateFirmware(e, 'mkrwifi1010', device.Name, 'wifiNina')}>
194+
Wifi NINA update firmware
195+
</a> - <a href="#" onClick={(e) => handleUpdateFirmware(e, 'mkr1000', device.Name, 'wifi101')}>
196+
Wifi 101 update firmware
182197
</a>
183198
</li>);
184199

src/daemon.js

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,36 @@ import {
2525
takeUntil, filter, startWith, first, distinctUntilChanged
2626
} from 'rxjs/operators';
2727

28+
const versionsMap = {
29+
wifi101: {
30+
latestVersion: 'WINC1500 19.5.4',
31+
loaderPath: null,
32+
latestVersionPath: null
33+
},
34+
wifiNina: {
35+
latestVersion: 'NINA 1.2.2',
36+
loaderPath: null,
37+
latestVersionPath: null
38+
}
39+
};
40+
2841
const POLLING_INTERVAL = 1500;
2942

43+
/* The status of the Firmware Updater Tool */
44+
const FWUToolStatusEnum = Object.freeze({
45+
NOPE: 'NOPE',
46+
OK: 'OK',
47+
CHECKING: 'CHECKING',
48+
ERROR: 'ERROR DOWNLOADING TOOL'
49+
});
50+
51+
/* The signatures needed to run the commands to use the Firmware Updater Tool */
52+
const signaturesEnum = Object.freeze({
53+
GET_FIRMWARE_INFO: 'aceffd98d331df0daa5bb3308bb49a95767d77e7a1557c07a0ec544d2f41c3ec67269f01ce9a63e01f3b43e087ab8eb22b7f1d34135b6686e8ce27d4b5dc083ec8e6149df11880d32486448a71280ef3128efccbd45a84dbd7990a9420a65ee86b3822edba3554fa8e6ca11aec12d4dd99ad072285b98bfdf7b2b64f677da50feb8bddef25a36f52d7605078487d8a5d7cbdc84bfa65d510cee97b46baefea149139a9a6ed4b545346040536e33d850e6ad84c83fe605f677e2ca77439de3fa42350ce504ad9a49cf62c6751d4c2a284500d2c628cd52cd73b4c3e7ef08ae823eb8941383f9c6ff0686da532369d3b266ded8fdd33cca1a128068a4795920f25',
54+
UPLOAD_FIRMWARE_BOSSAC: 'b2137435f74601a0b1b090ca1592b14199c1c79c87cecac4bb168456b570f17b635f438f5cd80649a101ab27085394e4a0e92f41a2b1b65932789eee8c3ebf39633a503a8a53d3291944afe10ff88f6ea06b0fd7fd7de6d70b302df3a92091a2abe2691ad1aeee051e4bb69f6afa3bd41e643855769347dca018804ae97bcb1331df796fd8921a11b333b45bebe430d323ddd151a907e8fb0e875a45d093cdb4332ec3dbd72a50341b538e058b3f25d4a528bea514b96b8e0701032d64232b7141c62f2231352f4197a1011292a4c3e900c133824e148f3703ea8374873d9097578146819e62685f1a8cbc442dd435ea603136c86ecf028df39fd10a8b3499c6',
55+
UPLOAD_FIRMWARE_AVRDUDE: '68ed3d9abdc7c77d01223d09c7ae55b08b8ff94f2a42d21a672effb4bdeeb12b10177e831805b3037d9f8d38e8eeeb8327b6c4691731a2a146cfd12398e5a12596e097160ae8d84fc488650ee57439f7fcd83f27d01e9834de555ceec7dc6951b3be5e5a3507752dce8e4ba1f6f9e6494162d537009db899882b9c4fca0868ad446b82fdeabf93bc30c5a39f8fe9c25e799842a10f4171e2896a0e19667b34258f06494663a4a102bcf9fd61d1ff8ebec18204bbd1a66de3e0b53e257ce521b41999dc82428539086ae9a4a5ea7112d87c05a2782cdace0e6576b162294f9ba47c658cc40999ba31be8a129689a703f6c4182055a600b6e41d450fad2896180d'
56+
});
57+
3058
export default class Daemon {
3159
constructor(boardsUrl = 'https://builder.arduino.cc/v3/boards') {
3260
this.BOARDS_URL = boardsUrl;
@@ -78,6 +106,12 @@ export default class Daemon {
78106
this.downloadingError = this.downloading.pipe(filter(download => download.status === this.DOWNLOAD_ERROR))
79107
.pipe(first())
80108
.pipe(takeUntil(this.downloadingDone));
109+
110+
this.downloadingDone.subscribe(() => {
111+
this.FWUToolStatus = FWUToolStatusEnum.OK;
112+
});
113+
114+
this.FWUToolStatus = FWUToolStatusEnum.NOPE;
81115
}
82116

83117
notifyUploadError(err) {
@@ -177,4 +211,175 @@ export default class Daemon {
177211
});
178212
this.openSerialMonitor(port, 1200);
179213
}
214+
215+
getFirmwareInfo(boardId, port, wifiModule) {
216+
return new Promise((resolve, reject) => {
217+
let versionsList = [];
218+
let firmwareInfoMessagesSubscription;
219+
220+
const handleFirmwareInfoMessage = message => {
221+
switch (message.ProgrammerStatus) {
222+
case 'Starting':
223+
break;
224+
case 'Busy':
225+
if (message.Msg.indexOf('Flashing with command:') >= 0) {
226+
return;
227+
}
228+
const versions = JSON.parse(message.Msg);
229+
Object.keys(versions).forEach(v => {
230+
if (versions[v][0].IsLoader) {
231+
versionsMap[wifiModule].loaderPath = versions[v][0].Path;
232+
}
233+
else {
234+
versionsList = [...versionsList, ...versions[v]];
235+
}
236+
});
237+
const latestVersion = versionsList.find(version => version.Name === versionsMap[wifiModule].latestVersion)
238+
versionsMap[wifiModule].latestVersionPath = latestVersion.Path;
239+
break;
240+
case 'Error':
241+
return reject(`Couldn't get firmware info: ${message}`)
242+
firmwareInfoMessagesSubscription.unsubscribe();
243+
break;
244+
case 'Done':
245+
firmwareInfoMessagesSubscription.unsubscribe();
246+
return resolve(versionsList);
247+
break;
248+
default:
249+
break;
250+
}
251+
}
252+
253+
if (this.FWUToolStatus !== FWUToolStatusEnum.OK) {
254+
return reject(`Can't get firmware info: couldn't find firmware updater tool`)
255+
}
256+
257+
firmwareInfoMessagesSubscription = this.appMessages.subscribe(message => {
258+
if (message.ProgrammerStatus) {
259+
handleFirmwareInfoMessage(message);
260+
}
261+
});
262+
const data = {
263+
board: boardId,
264+
port,
265+
commandline: `"{runtime.tools.fwupdater.path}/updater" -get_available_for {network.password}`,
266+
signature: signaturesEnum.GET_FIRMWARE_INFO,
267+
extra: {
268+
auth: {
269+
password: boardId
270+
}
271+
},
272+
filename: 'ListFirmwareVersionsInfo.bin'
273+
};
274+
275+
return fetch(`${this.pluginURL}/upload`, {
276+
method: 'POST',
277+
headers: {
278+
'Content-Type': 'text/plain; charset=utf-8'
279+
},
280+
body: JSON.stringify(data)
281+
}).then(response => {
282+
if (!response.ok) {
283+
return reject(`Error fetching ${this.pluginURL}/upload`);
284+
}
285+
}).catch(reason => {
286+
return reject(`Coudln't list firmware versions info.`);
287+
});
288+
})
289+
}
290+
291+
/*
292+
wifiModule can be either 'wifiNina' or 'wifi101'
293+
*/
294+
updateFirmware(boardId, port, wifiModule) {
295+
return new Promise((resolve, reject) => {
296+
if (!port) {
297+
return reject(`Can't update Firmware: no port selected.`);
298+
}
299+
this.getFirmwareInfo(boardId, port, wifiModule).then(versionsList => {
300+
if (!versionsMap[wifiModule] && !versionsMap[wifiModule].latestVersion) {
301+
return reject(`Can't update Firmware: couldn't find module '${wifiModule}'`);
302+
}
303+
const latestVersion = versionsList.find(version => version.Name === versionsMap[wifiModule].latestVersion);
304+
if (!latestVersion) {
305+
return reject(`Can't update Firmware: couldn't find version '${versionsMap[wifiModule].latestVersion}' for module '${versionsMap[wifiModule]}'`);
306+
}
307+
308+
let updateFirmwareMessagesSubscription;
309+
310+
const handleFirmwareUpdateMessage = message => {
311+
switch (message.ProgrammerStatus) {
312+
case 'Error':
313+
return reject(`Can't update Firmware: ${message.Msg}`)
314+
updateFirmwareMessagesSubscription.unsubscribe();
315+
break;
316+
case 'Done':
317+
return resolve();
318+
updateFirmwareMessagesSubscription.unsubscribe();
319+
break;
320+
default:
321+
break;
322+
}
323+
}
324+
325+
updateFirmwareMessagesSubscription = this.appMessages.subscribe(message => {
326+
if (message.ProgrammerStatus) {
327+
handleFirmwareUpdateMessage(message);
328+
}
329+
});
330+
331+
let addresses = '';
332+
const rootCertificates = [{
333+
domain: 'arduino.cc',
334+
port: 443
335+
}];
336+
337+
rootCertificates.forEach(address => {
338+
if (address.domain && address.port) {
339+
addresses += `-address ${address.domain}:${address.port} `;
340+
}
341+
});
342+
343+
const isUsingAvrdude = boardId === 'uno2018';
344+
const programmer = isUsingAvrdude ? '{runtime.tools.avrdude}/bin/avrdude' : '{runtime.tools.bossac}/bossac';
345+
346+
const loaderPath = versionsMap[wifiModule].loaderPath;
347+
if (!loaderPath) {
348+
return reject(`Can't update Firmware: invalid loaderPath`);
349+
}
350+
351+
const data = {
352+
board: boardId,
353+
port,
354+
commandline: `"{runtime.tools.fwupdater.path}/updater" -flasher {network.password} -firmware {upload.verbose} -port {serial.port} -restore_binary "{build.path}/{build.project_name}.bin" -programmer ${programmer}`,
355+
hex: '',
356+
extra: {
357+
auth: {
358+
password: loaderPath
359+
},
360+
verbose: true,
361+
params_verbose: `${versionsMap[wifiModule].latestVersionPath} ${addresses}` // eslint-disable-line camelcase
362+
},
363+
signature: isUsingAvrdude ? signaturesEnum.UPLOAD_FIRMWARE_AVRDUDE : signaturesEnum.UPLOAD_FIRMWARE_BOSSAC,
364+
filename: 'CheckFirmwareVersion.bin'
365+
};
366+
367+
fetch(`${this.pluginURL}/upload`, {
368+
method: 'POST',
369+
headers: {
370+
'Content-Type': 'text/plain; charset=utf-8'
371+
},
372+
body: JSON.stringify(data)
373+
}).then(response => {
374+
if (!response.ok) {
375+
return reject(`Can't update Firmware: Error fetching ${this.pluginURL}/upload`);
376+
}
377+
}).catch(reason => {
378+
return reject(`Can't update Firmware: ${reason}`)
379+
});
380+
}).catch(reason => {
381+
return reject(reason)
382+
});
383+
})
384+
}
180385
}

src/socket-daemon.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ export default class SocketDaemon extends Daemon {
209209
if (!driversRequested) {
210210
this.downloadTool('windows-drivers', 'latest', 'arduino');
211211
this.downloadTool('bossac', '1.7.0', 'arduino');
212+
this.downloadTool('fwupdater', 'latest', 'arduino');
212213
driversRequested = false;
213214
}
214215

0 commit comments

Comments
 (0)