Skip to content

Commit 0d9f4b9

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

File tree

4 files changed

+229
-1
lines changed

4 files changed

+229
-1
lines changed

demo/app.jsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
import React from 'react';
2222
import Daemon from '../src';
23+
import FirmwareUpdater from '../src/firmware-updater';
2324

2425
import { HEX } from './serial_mirror';
2526
import V2 from './v2/v2.jsx';
@@ -33,6 +34,7 @@ const scrollToBottom = (target) => {
3334
};
3435

3536
const daemon = new Daemon('https://builder.arduino.cc/v3/boards', chromeExtensionID);
37+
const firmwareUpdater = new FirmwareUpdater(daemon);
3638

3739
const handleUpload = () => {
3840
const target = {
@@ -50,6 +52,16 @@ const handleBootloaderMode = (e, port) => {
5052
daemon.setBootloaderMode(port);
5153
};
5254

55+
const handleUpdateFirmware = (e, boardId, port, wifiModule) => {
56+
e.preventDefault();
57+
firmwareUpdater.updateFirmware(boardId, port, wifiModule).then(response => {
58+
console.log('Firmware updated successfully!');
59+
}).catch(reason => {
60+
console.log('Something went wrong when trying to update the firmware');
61+
console.error(reason);
62+
});
63+
};
64+
5365
const handleDownloadTool = e => {
5466
e.preventDefault();
5567
const toolname = document.getElementById('toolname');
@@ -179,6 +191,10 @@ class App extends React.Component {
179191
close
180192
</a> - <a href="#" onClick={(e) => handleBootloaderMode(e, device.Name)}>
181193
bootloader mode
194+
</a> - <a href="#" onClick={(e) => handleUpdateFirmware(e, 'mkrwifi1010', device.Name, 'wifiNina')}>
195+
Wifi NINA update firmware
196+
</a> - <a href="#" onClick={(e) => handleUpdateFirmware(e, 'mkr1000', device.Name, 'wifi101')}>
197+
Wifi 101 update firmware
182198
</a>
183199
</li>);
184200

src/firmware-updater.js

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
const versionsMap = {
2+
wifi101: {
3+
latestVersion: 'WINC1500 19.5.4',
4+
loaderPath: null,
5+
latestVersionPath: null
6+
},
7+
wifiNina: {
8+
latestVersion: 'NINA 1.2.2',
9+
loaderPath: null,
10+
latestVersionPath: null
11+
}
12+
};
13+
14+
/* The status of the Firmware Updater Tool */
15+
const FWUToolStatusEnum = Object.freeze({
16+
NOPE: 'NOPE',
17+
OK: 'OK',
18+
CHECKING: 'CHECKING',
19+
ERROR: 'ERROR DOWNLOADING TOOL'
20+
});
21+
22+
/* The signatures needed to run the commands to use the Firmware Updater Tool */
23+
const signaturesEnum = Object.freeze({
24+
GET_FIRMWARE_INFO: 'aceffd98d331df0daa5bb3308bb49a95767d77e7a1557c07a0ec544d2f41c3ec67269f01ce9a63e01f3b43e087ab8eb22b7f1d34135b6686e8ce27d4b5dc083ec8e6149df11880d32486448a71280ef3128efccbd45a84dbd7990a9420a65ee86b3822edba3554fa8e6ca11aec12d4dd99ad072285b98bfdf7b2b64f677da50feb8bddef25a36f52d7605078487d8a5d7cbdc84bfa65d510cee97b46baefea149139a9a6ed4b545346040536e33d850e6ad84c83fe605f677e2ca77439de3fa42350ce504ad9a49cf62c6751d4c2a284500d2c628cd52cd73b4c3e7ef08ae823eb8941383f9c6ff0686da532369d3b266ded8fdd33cca1a128068a4795920f25',
25+
UPLOAD_FIRMWARE_BOSSAC: 'b2137435f74601a0b1b090ca1592b14199c1c79c87cecac4bb168456b570f17b635f438f5cd80649a101ab27085394e4a0e92f41a2b1b65932789eee8c3ebf39633a503a8a53d3291944afe10ff88f6ea06b0fd7fd7de6d70b302df3a92091a2abe2691ad1aeee051e4bb69f6afa3bd41e643855769347dca018804ae97bcb1331df796fd8921a11b333b45bebe430d323ddd151a907e8fb0e875a45d093cdb4332ec3dbd72a50341b538e058b3f25d4a528bea514b96b8e0701032d64232b7141c62f2231352f4197a1011292a4c3e900c133824e148f3703ea8374873d9097578146819e62685f1a8cbc442dd435ea603136c86ecf028df39fd10a8b3499c6',
26+
UPLOAD_FIRMWARE_AVRDUDE: '68ed3d9abdc7c77d01223d09c7ae55b08b8ff94f2a42d21a672effb4bdeeb12b10177e831805b3037d9f8d38e8eeeb8327b6c4691731a2a146cfd12398e5a12596e097160ae8d84fc488650ee57439f7fcd83f27d01e9834de555ceec7dc6951b3be5e5a3507752dce8e4ba1f6f9e6494162d537009db899882b9c4fca0868ad446b82fdeabf93bc30c5a39f8fe9c25e799842a10f4171e2896a0e19667b34258f06494663a4a102bcf9fd61d1ff8ebec18204bbd1a66de3e0b53e257ce521b41999dc82428539086ae9a4a5ea7112d87c05a2782cdace0e6576b162294f9ba47c658cc40999ba31be8a129689a703f6c4182055a600b6e41d450fad2896180d'
27+
});
28+
29+
30+
export default class FirmwareUpdater {
31+
constructor(Daemon) {
32+
this.Daemon = Daemon;
33+
this.Daemon.downloadingDone.subscribe(() => {
34+
this.FWUToolStatus = FWUToolStatusEnum.OK;
35+
});
36+
37+
this.FWUToolStatus = FWUToolStatusEnum.NOPE;
38+
}
39+
40+
getFirmwareInfo(boardId, port, wifiModule) {
41+
return new Promise((resolve, reject) => {
42+
let versionsList = [];
43+
let firmwareInfoMessagesSubscription;
44+
45+
const handleFirmwareInfoMessage = message => {
46+
switch (message.ProgrammerStatus) {
47+
case 'Starting':
48+
break;
49+
case 'Busy':
50+
if (message.Msg.indexOf('Flashing with command:') >= 0) {
51+
return;
52+
}
53+
const versions = JSON.parse(message.Msg);
54+
Object.keys(versions).forEach(v => {
55+
if (versions[v][0].IsLoader) {
56+
versionsMap[wifiModule].loaderPath = versions[v][0].Path;
57+
}
58+
else {
59+
versionsList = [...versionsList, ...versions[v]];
60+
}
61+
});
62+
const latestVersion = versionsList.find(version => version.Name === versionsMap[wifiModule].latestVersion)
63+
versionsMap[wifiModule].latestVersionPath = latestVersion.Path;
64+
break;
65+
case 'Error':
66+
return reject(`Couldn't get firmware info: ${message}`)
67+
firmwareInfoMessagesSubscription.unsubscribe();
68+
break;
69+
case 'Done':
70+
firmwareInfoMessagesSubscription.unsubscribe();
71+
return resolve(versionsList);
72+
break;
73+
default:
74+
break;
75+
}
76+
}
77+
78+
if (this.FWUToolStatus !== FWUToolStatusEnum.OK) {
79+
return reject(`Can't get firmware info: couldn't find firmware updater tool`)
80+
}
81+
82+
firmwareInfoMessagesSubscription = this.Daemon.appMessages.subscribe(message => {
83+
if (message.ProgrammerStatus) {
84+
handleFirmwareInfoMessage(message);
85+
}
86+
});
87+
const data = {
88+
board: boardId,
89+
port,
90+
commandline: `"{runtime.tools.fwupdater.path}/updater" -get_available_for {network.password}`,
91+
signature: signaturesEnum.GET_FIRMWARE_INFO,
92+
extra: {
93+
auth: {
94+
password: boardId
95+
}
96+
},
97+
filename: 'ListFirmwareVersionsInfo.bin'
98+
};
99+
100+
return fetch(`${this.Daemon.pluginURL}/upload`, {
101+
method: 'POST',
102+
headers: {
103+
'Content-Type': 'text/plain; charset=utf-8'
104+
},
105+
body: JSON.stringify(data)
106+
}).then(response => {
107+
if (!response.ok) {
108+
return reject(`Error fetching ${this.Daemon.pluginURL}/upload`);
109+
}
110+
}).catch(reason => {
111+
return reject(`Coudln't list firmware versions info.`);
112+
});
113+
})
114+
}
115+
116+
/*
117+
wifiModule can be either 'wifiNina' or 'wifi101'
118+
*/
119+
updateFirmware(boardId, port, wifiModule) {
120+
return new Promise((resolve, reject) => {
121+
if (!port) {
122+
return reject(`Can't update Firmware: no port selected.`);
123+
}
124+
this.getFirmwareInfo(boardId, port, wifiModule).then(versionsList => {
125+
if (!versionsMap[wifiModule] && !versionsMap[wifiModule].latestVersion) {
126+
return reject(`Can't update Firmware: couldn't find module '${wifiModule}'`);
127+
}
128+
const latestVersion = versionsList.find(version => version.Name === versionsMap[wifiModule].latestVersion);
129+
if (!latestVersion) {
130+
return reject(`Can't update Firmware: couldn't find version '${versionsMap[wifiModule].latestVersion}' for module '${versionsMap[wifiModule]}'`);
131+
}
132+
133+
let updateFirmwareMessagesSubscription;
134+
135+
const handleFirmwareUpdateMessage = message => {
136+
switch (message.ProgrammerStatus) {
137+
case 'Error':
138+
return reject(`Can't update Firmware: ${message.Msg}`)
139+
updateFirmwareMessagesSubscription.unsubscribe();
140+
break;
141+
case 'Done':
142+
return resolve();
143+
updateFirmwareMessagesSubscription.unsubscribe();
144+
break;
145+
default:
146+
break;
147+
}
148+
}
149+
150+
updateFirmwareMessagesSubscription = this.Daemon.appMessages.subscribe(message => {
151+
if (message.ProgrammerStatus) {
152+
handleFirmwareUpdateMessage(message);
153+
}
154+
});
155+
156+
let addresses = '';
157+
const rootCertificates = [{
158+
domain: 'arduino.cc',
159+
port: 443
160+
}];
161+
162+
rootCertificates.forEach(address => {
163+
if (address.domain && address.port) {
164+
addresses += `-address ${address.domain}:${address.port} `;
165+
}
166+
});
167+
168+
const isUsingAvrdude = boardId === 'uno2018';
169+
const programmer = isUsingAvrdude ? '{runtime.tools.avrdude}/bin/avrdude' : '{runtime.tools.bossac}/bossac';
170+
171+
const loaderPath = versionsMap[wifiModule].loaderPath;
172+
if (!loaderPath) {
173+
return reject(`Can't update Firmware: invalid loaderPath`);
174+
}
175+
176+
const data = {
177+
board: boardId,
178+
port,
179+
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}`,
180+
hex: '',
181+
extra: {
182+
auth: {
183+
password: loaderPath
184+
},
185+
verbose: true,
186+
params_verbose: `${versionsMap[wifiModule].latestVersionPath} ${addresses}` // eslint-disable-line camelcase
187+
},
188+
signature: isUsingAvrdude ? signaturesEnum.UPLOAD_FIRMWARE_AVRDUDE : signaturesEnum.UPLOAD_FIRMWARE_BOSSAC,
189+
filename: 'CheckFirmwareVersion.bin'
190+
};
191+
192+
fetch(`${this.Daemon.pluginURL}/upload`, {
193+
method: 'POST',
194+
headers: {
195+
'Content-Type': 'text/plain; charset=utf-8'
196+
},
197+
body: JSON.stringify(data)
198+
}).then(response => {
199+
if (!response.ok) {
200+
return reject(`Can't update Firmware: Error fetching ${this.Daemon.pluginURL}/upload`);
201+
}
202+
}).catch(reason => {
203+
return reject(`Can't update Firmware: ${reason}`)
204+
});
205+
}).catch(reason => {
206+
return reject(reason)
207+
});
208+
})
209+
}
210+
}

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,9 @@
2020

2121
import SocketDaemon from './socket-daemon';
2222
import ChromeOsDaemon from './chrome-app-daemon';
23-
23+
import FirmwareUpdater from './firmware-updater';
2424

2525
const Daemon = window.navigator.userAgent.indexOf(' CrOS ') !== -1 ? ChromeOsDaemon : SocketDaemon;
2626

2727
export default Daemon;
28+
export {FirmwareUpdater};

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)