diff --git a/src/lib/serial/device.ts b/src/lib/serial/device.ts index 92c1be57..865204d9 100644 --- a/src/lib/serial/device.ts +++ b/src/lib/serial/device.ts @@ -440,46 +440,80 @@ export class CharaDevice { return Number(await this.send(1, "RAM").then(([bytes]) => bytes)); } - async updateFirmware(file: File): Promise { - const size = file.size; - // use separate serial connection - await this.port.open({ baudRate: this.baudRate }); - const decoderStream = new TextDecoderStream(); - this.port.readable!.pipeTo(decoderStream.writable); - - const reader = decoderStream - .readable!.pipeThrough(new TransformStream(new LineBreakTransformer())) - .getReader(); - serialLog.update((it) => { - it.push({ - type: "system", - value: "Starting firmware update", - }); - return it; - }); - - const writer = this.port.writable!.getWriter(); - try { - await writer.write(new TextEncoder().encode(`RST OTA\r\n`)); - } finally { - writer.releaseLock(); + async updateFirmware(file: File | Blob): Promise { + while (this.lock) { + await this.lock; } - - console.log((await reader.read()).value); - - await file.stream().pipeTo(this.port.writable!); - - console.log((await reader.read()).value); - - await reader.cancel(); - reader.releaseLock(); - await this.port.close(); - serialLog.update((it) => { - it.push({ - type: "system", - value: "Success?", - }); - return it; + let resolveLock: (result: true) => void; + this.lock = new Promise((resolve) => { + resolveLock = resolve; }); + try { + if (this.suspendDebounceId) { + clearTimeout(this.suspendDebounceId); + } else { + await this.wake(); + } + + serialLog.update((it) => { + it.push({ + type: "system", + value: "OTA Update", + }); + return it; + }); + + const writer = this.port.writable!.getWriter(); + try { + await writer.write(new TextEncoder().encode(`RST OTA\r\n`)); + serialLog.update((it) => { + it.push({ + type: "input", + value: "RST OTA", + }); + return it; + }); + } finally { + writer.releaseLock(); + } + + // Wait for the device to be ready + const signal = await this.reader.read(); + serialLog.update((it) => { + it.push({ + type: "output", + value: signal.value!.trim(), + }); + return it; + }); + + await file.stream().pipeTo(this.port.writable!); + + serialLog.update((it) => { + it.push({ + type: "input", + value: `...${file.size} bytes`, + }); + return it; + }); + + const result = (await this.reader.read()).value!.trim(); + serialLog.update((it) => { + it.push({ + type: "output", + value: result!, + }); + return it; + }); + + await this.suspend(); + + if (result !== "OTA OK") { + throw new Error(result); + } + } finally { + delete this.lock; + resolveLock!(true); + } } } diff --git a/src/routes/(app)/ota-update/OTA.svelte b/src/routes/(app)/ota-update/OTA.svelte new file mode 100644 index 00000000..e69de29b diff --git a/src/routes/(app)/ota-update/[device]/[version]/+page.svelte b/src/routes/(app)/ota-update/[device]/[version]/+page.svelte index dde33acd..97e7428a 100644 --- a/src/routes/(app)/ota-update/[device]/[version]/+page.svelte +++ b/src/routes/(app)/ota-update/[device]/[version]/+page.svelte @@ -4,6 +4,29 @@ let { data } = $props(); + let working = $state(false); + let success = $state(false); + let error = $state(undefined); + + async function update() { + working = true; + error = undefined; + success = false; + const port = $serialPort!; + $serialPort = undefined; + try { + const file = await fetch(otaUrl!).then((it) => it.blob()); + + await port.updateFirmware(file); + + success = true; + } catch (e) { + error = e as Error; + } finally { + working = false; + } + } + let currentDevice = $derived( $serialPort ? `${$serialPort.device.toLowerCase()}_${$serialPort.chipset.toLowerCase()}` @@ -78,7 +101,29 @@

OTA Upate

{#if data.ota} -

OTA update

+ + {#if $serialPort} +
+ Your device is ready and compatible. Click the button to perform the + update. +
+ {:else if success} +
Update successful
+ {:else if error} +
{error.message}
+ {:else if working} +
Updating your device...
+ {:else} +
+ Connect your device to continue +
+ {/if} {:else} There are no OTA files for this device. {/if} @@ -101,6 +146,7 @@

Via Serial

WIP

+ ading 0 Chordmaps.