|
2 | 2 | <html lang="en_GB"> |
3 | 3 |
|
4 | 4 | <head> |
5 | | - <title>WebUSB tester</title> |
| 5 | + <title>WebUSB demo</title> |
6 | 6 | <!-- Bootstrap CSS --> |
7 | 7 | <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous"> |
8 | 8 | <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans"> |
|
27 | 27 | background-color: #fff; |
28 | 28 | border: 2px solid #e7e9ec; |
29 | 29 | border-radius: 6px; |
| 30 | + min-height: 100px; |
30 | 31 | } |
31 | | - |
| 32 | + |
32 | 33 | p { |
33 | 34 | margin: 0 0 15px; |
34 | 35 | font-size: 18px; |
35 | 36 | line-height: 1.8em; |
36 | 37 | } |
| 38 | + |
| 39 | + input { |
| 40 | + width: 100%; |
| 41 | + } |
37 | 42 |
|
38 | 43 | .container { |
39 | 44 | max-width: 900px; |
|
73 | 78 | </p> |
74 | 79 |
|
75 | 80 | <div class="row"> |
76 | | - <div class="col-md-4"> |
| 81 | + <div class="col-md-5"> |
77 | 82 | <ol> |
78 | 83 | <li> |
79 | 84 | <p> |
|
136 | 141 | <button onclick="printRegisters()" class="btn btn-info when-connected" disabled>Read Registers</button> |
137 | 142 | </p> |
138 | 143 | </li> |
| 144 | + <li> |
| 145 | + <p> |
| 146 | + Serial monitor: |
| 147 | + </p> |
| 148 | + <p> |
| 149 | + Baud Rate: |
| 150 | + <select id="baudRate" class="when-connected" disabled> |
| 151 | + <option value="9600">9600</option> |
| 152 | + <option value="14400">14400</option> |
| 153 | + <option value="19200">19200</option> |
| 154 | + <option value="28800">28800</option> |
| 155 | + <option value="38400">38400</option> |
| 156 | + <option value="57600">57600</option> |
| 157 | + <option value="115200">115200</option> |
| 158 | + </select> |
| 159 | + <div class="btn-group"> |
| 160 | + <button onclick="startSerialMonitor()" class="btn btn-success when-connected" disabled>Start</button> |
| 161 | + <button onclick="stopSerialMonitor()" class="btn btn-danger when-connected" disabled>Stop</button> |
| 162 | + </div> |
| 163 | + </p> |
| 164 | + </li> |
139 | 165 | </ol> |
140 | 166 | </div> |
141 | 167 |
|
142 | | - <div class="col-md-8"> |
| 168 | + <div class="col-md-7"> |
| 169 | + Output: |
143 | 170 | <pre id="logger"></pre> |
| 171 | + Serial monitor: |
| 172 | + <p> |
| 173 | + <input id="serialMonitorInput" class="when-connected" type="text" maxlength="63" placeholder="Write to a board" onchange="writeSerial()"> |
| 174 | + </p> |
| 175 | + <pre id="serialMonitor"></pre> |
144 | 176 | </div> |
145 | 177 | </div> |
146 | 178 | </div> |
|
194 | 226 | document.getElementById("logger").innerHTML = ""; |
195 | 227 | } |
196 | 228 |
|
| 229 | + function logSerial(data) { |
| 230 | + logger = document.getElementById("serialMonitor"); |
| 231 | + logger.innerHTML = logger.innerHTML + data + "\n"; |
| 232 | + } |
| 233 | + |
| 234 | + function clearLogSerial() { |
| 235 | + document.getElementById("serialMonitor").innerHTML = ""; |
| 236 | + } |
| 237 | + |
197 | 238 | /** |
198 | 239 | * Snapshot the current state of the CPU. Reads all general-purpose registers, and returns them in an array. |
199 | 240 | */ |
|
208 | 249 | } |
209 | 250 |
|
210 | 251 | async function connect() { |
| 252 | + clearLog(); |
| 253 | + clearLogSerial(); |
211 | 254 | this.hid = new DAPjs.HID(this.device); |
212 | 255 |
|
213 | 256 | log("Opening device."); |
|
218 | 261 | log("Device opened."); |
219 | 262 |
|
220 | 263 | this.dapDevice = new DAPjs.DAP(this.hid); |
| 264 | + |
221 | 265 | const xhr = new XMLHttpRequest(); |
222 | 266 | xhr.responseType = "json"; |
223 | 267 | xhr.open("GET", "../flash_targets/flash_targets.json", true); |
|
227 | 271 | let flashAlgorithm = new DAPjs.FlashAlgorithm(xhr.response, this.deviceCode); |
228 | 272 | if (!flashAlgorithm.flashAlgo) return log("No flashing algorithm can be found for this board."); |
229 | 273 |
|
| 274 | + this.serial = new DAPjs.Serial(dapDevice); |
230 | 275 | this.target = new DAPjs.FlashTarget(this.dapDevice, flashAlgorithm); |
231 | 276 |
|
232 | 277 | log("Initialising device."); |
|
296 | 341 | xhr.send(); |
297 | 342 | } |
298 | 343 |
|
| 344 | + async function startSerialMonitor() { |
| 345 | + var elem = document.getElementById("baudRate"); |
| 346 | + var baudRate = elem.options[elem.selectedIndex].value; |
| 347 | + await this.serial.initialize(baudRate); |
| 348 | + this.serial.start((data) => { |
| 349 | + logSerial(data); |
| 350 | + }); |
| 351 | + } |
| 352 | + |
| 353 | + function writeSerial() { |
| 354 | + var elem = document.getElementById("serialMonitorInput"); |
| 355 | + this.serial.write(elem.value); |
| 356 | + elem.value = ""; |
| 357 | + } |
| 358 | + |
| 359 | + function stopSerialMonitor() { |
| 360 | + this.serial.stop(); |
| 361 | + clearLogSerial(); |
| 362 | + } |
| 363 | + |
299 | 364 | async function selectBoard() { |
300 | 365 | this.device = await navigator.usb.requestDevice({ filters: [{vendorId: 0x0d28}]}); |
301 | 366 | this.deviceCode = this.device.serialNumber.slice(0, 4); |
|
309 | 374 | this.flashProgressBar = document.getElementById('flash-progress'); |
310 | 375 | this.flashProgressBarContainer = document.getElementById('progress-container'); |
311 | 376 | this.selector = new DAPjs.PlatformSelector(); |
| 377 | + navigator.usb.addEventListener('disconnect', disconnectEvent => { |
| 378 | + if (this.device && this.device.serialNumber == disconnectEvent.device.serialNumber) { |
| 379 | + this.device = null; |
| 380 | + const elements = Array.from(document.querySelectorAll(".when-connected")); |
| 381 | + for (const elem of elements) { |
| 382 | + elem.disabled = true; |
| 383 | + } |
| 384 | + clearLog(); |
| 385 | + log("Device disconnected"); |
| 386 | + clearLogSerial(); |
| 387 | + } |
| 388 | + }); |
312 | 389 | }; |
313 | 390 | </script> |
314 | 391 | </body> |
|
0 commit comments