From 6b34c48f8f77684ab8fb00199f629ce9ae0b6bc3 Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Wed, 30 Oct 2024 14:29:01 +0900 Subject: [PATCH 01/11] =?UTF-8?q?feat:=20verify=E3=82=B3=E3=83=9E=E3=83=B3?= =?UTF-8?q?=E3=83=89=E3=81=AE=E5=AE=9F=E8=A3=85,=E3=82=B3=E3=83=9E?= =?UTF-8?q?=E3=83=B3=E3=83=89=E3=83=A2=E3=83=BC=E3=83=89=E3=81=B8=E3=81=AE?= =?UTF-8?q?=E5=85=A5=E3=82=8A=E6=96=B9=E3=82=92CRLF=E3=82=92=E9=80=81?= =?UTF-8?q?=E3=82=8B=E5=BD=A2=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCrc8.ts | 17 +++++++ src/libs/mrubyWriterConnector.ts | 82 +++++++++++++++++++++----------- src/pages/home.tsx | 72 ++++++++++++++++++++++++---- 3 files changed, 136 insertions(+), 35 deletions(-) create mode 100644 src/hooks/useCrc8.ts diff --git a/src/hooks/useCrc8.ts b/src/hooks/useCrc8.ts new file mode 100644 index 0000000..3210016 --- /dev/null +++ b/src/hooks/useCrc8.ts @@ -0,0 +1,17 @@ +export const useCrc8 = (data: Uint8Array) => { + const crc8 = data.reduce((crc, byte) => { + const poly = 0x31; + crc ^= byte; + for (let i = 0; i < 8; i++) { + if (crc & 0x80) { + crc = (crc << 1) ^ poly; + } else { + crc = crc << 1; + } + } + crc &= 0xff; + return crc; + }, 0xff); + + return crc8; +}; diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index 278c826..94f1ee0 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -9,7 +9,7 @@ type Listener = (buffer: string[]) => void; type Reader = ReadableStreamDefaultReader; type Writer = WritableStreamDefaultWriter; -type Event = "AttemptToEnterWriteMode" | "SuccessToExitWriteMode"; +type Event = "onEnterWriteMode" | "SuccessToExitWriteMode"; type Job = { job: Promise>; description: string }; const baudRates: Record = { @@ -18,13 +18,12 @@ const baudRates: Record = { } as const; const enterWriteModeKeyword: Record = { - ESP32: /mrubyc-esp32: Please push Enter key x 2 to mrbwite mode/, - RBoard: /mruby\/c v\d.\d start./, + ESP32: /\+OK mruby\/c/, ///mrubyc-esp32: Please push Enter key x 2 to mrbwite mode/, + RBoard: /\+OK mruby\/c/, ///mruby\/c v\d.\d start./, } as const; - const exitWriteModeKeyword: Record = { ESP32: /mrubyc-esp32: End mrbwrite mode/, - RBoard: /\+OK Execute mruby\/c./, + RBoard: /start./, ///\+OK Execute mruby\/c./, } as const; export class MrubyWriterConnector { @@ -198,7 +197,7 @@ export class MrubyWriterConnector { async sendCommand( command: string, - option?: { force: boolean } + option?: Partial<{ force: boolean; ignoreResponse: boolean }> ): Promise> { if (!this.port) { return Failure.error("No port."); @@ -212,12 +211,14 @@ export class MrubyWriterConnector { this.handleText(`\r\n> ${command}\r\n`); console.log("Send", { command }); - return this.sendData(this.encoder.encode(`${command}\r\n`)); + return this.sendData(this.encoder.encode(`${command}\r\n`), { + ignoreResponse: option?.ignoreResponse, + }); } async writeCode( binary: Uint8Array, - option?: { execute: boolean } + option?: Partial<{ execute: boolean }> ): Promise> { if (!this.port) { return Failure.error("No port."); @@ -245,41 +246,46 @@ export class MrubyWriterConnector { return Success.value(null); } - private async sendData(chunk: Uint8Array): Promise> { + private async sendData( + chunk: Uint8Array, + option?: Partial<{ ignoreResponse: boolean }> + ): Promise> { if (!this.port) { return Failure.error("No port."); } const send = async (): Promise> => { - const readerRes = this.getSubReader(); const writerRes = this.getWriter(); - if (readerRes.isFailure()) { - return readerRes; - } if (writerRes.isFailure()) { return writerRes; } - this.currentSubReader = readerRes.value; const writer = writerRes.value; const request = await this.write(writer, chunk); + writer.releaseLock(); if (request.isFailure()) { return request; } - + if (option?.ignoreResponse) { + return Success.value(""); + } + const readerRes = this.getSubReader(); + if (readerRes.isFailure()) { + return readerRes; + } + this.currentSubReader = readerRes.value; const response = await this.readLine(this.currentSubReader); + this.currentSubReader.releaseLock(); + if (response.isFailure()) { return response; } - if (!response.value.startsWith("+")) { - return Failure.error("Failed to enter write mode.", { - cause: response, - }); - } - - this.currentSubReader.releaseLock(); - writer.releaseLock(); + // if (!response.value.startsWith("+")) { + // return Failure.error("Failed to enter write mode.", { + // cause: response, + // }); + // } return response; }; @@ -374,8 +380,8 @@ export class MrubyWriterConnector { private async handleEvent( event: Event | null ): Promise | null> { - if (event === "AttemptToEnterWriteMode") { - return this.onAttemptEnterWriteMode(); + if (event === "onEnterWriteMode") { + return this.onEnterWriteMode(); } if (event === "SuccessToExitWriteMode") { return this.onExitWriteMode(); @@ -385,7 +391,7 @@ export class MrubyWriterConnector { private detectEvent(text: string): Success<{ event: Event | null }> { if (this.target && text.match(enterWriteModeKeyword[this.target])) { - return Success.value({ event: "AttemptToEnterWriteMode" }); + return Success.value({ event: "onEnterWriteMode" }); } if (this.target && text.match(exitWriteModeKeyword[this.target])) { return Success.value({ event: "SuccessToExitWriteMode" }); @@ -393,7 +399,22 @@ export class MrubyWriterConnector { return Success.value({ event: null }); } - + private async onEnterWriteMode(): Promise> { + if (!this.port) { + return Failure.error("No port."); + } + if (this._writeMode) { + return Failure.error("Already write mode."); + } + if (!this.subReadable) { + return Failure.error("Cannot read serial port."); + } + if (!this.port.writable) { + return Failure.error("Cannot write serial port."); + } + this._writeMode = true; + return Success.value(null); + } private async onAttemptEnterWriteMode(): Promise> { if (!this.port) { return Failure.error("No port."); @@ -491,4 +512,11 @@ export class MrubyWriterConnector { return Success.value(line); } + async verify(verifyResult: boolean) { + if (verifyResult) { + this.handleText("\r\n Verify Success\r\n"); + } else { + this.handleText("\r\n Verify Failed\r\n"); + } + } } diff --git a/src/pages/home.tsx b/src/pages/home.tsx index 8aca0e5..6e28cb2 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useState } from "react"; +import { useCallback, useEffect, useMemo, useState } from "react"; import { Box, FormLabel, @@ -29,7 +29,7 @@ import { Version, useVersions } from "hooks/useVersions"; import { useCompile } from "hooks/useCompile"; import { CompileStatusCard } from "components/CompileStatusCard"; import { useTranslation } from "react-i18next"; - +import { useCrc8 } from "hooks/useCrc8"; const targets = [ { title: "RBoard", @@ -80,6 +80,51 @@ export const Home = () => { } }, [t, connector]); + const crc8 = useMemo(() => (code ? useCrc8(code) : 0), [code]); + const verifyCode = useCallback( + async (hash: number) => { + console.log("code: " + code); + if (!code) return; + //const crc8 = useCrc8(code); + console.log("crc8: " + crc8); + if (crc8 == hash) { + return true; + } else { + return false; + } + }, + [code] + ); + //切断せずにもう一度書き込もうとするときに動くようにする + const entry = useCallback(async () => { + return new Promise((resolve, reject) => { + const interval = setInterval(async () => { + console.error(connector.isWriteMode, connector.isConnected); + if (connector.isWriteMode) { + clearInterval(interval); + resolve(); + return; + } else if (!connector.isConnected) { + clearInterval(interval); + reject(); + return; + } + //CRLFを送信 + const res = await connector.sendCommand("", { + force: true, + ignoreResponse: true, + }); + if (res.isFailure()) { + clearInterval(interval); + reject(); + console.error(res); + return; + } + console.log("SEND:CRLF\n"); + }, 1500); + }); + }, [connector]); + const connect = useCallback(async () => { const res = await connector.connect( async () => await navigator.serial.requestPort() @@ -89,8 +134,8 @@ export const Home = () => { console.log(res); return; } - await read(); - }, [t, connector, read]); + await Promise.all([read(), entry()]); + }, [t, connector, read, entry]); const disconnect = useCallback(async () => { const res = await connector.disconnect(); @@ -103,15 +148,26 @@ export const Home = () => { const send = useCallback( async (text: string) => { - const res = await connector.sendCommand(text, { force: true }); + const res = await connector.sendCommand(text, { + force: true, + }); console.log(res); if (res.isFailure()) { alert( `${t("送信中にエラーが発生しました。")}\n${res.error}\ncause: ${res.error.cause}` ); } + if (text == "verify") { + if (res.isSuccess() && res.value.includes("+OK")) { + //マイコンから帰ってくるハッシュ値だけを取り出す + const hash = res.value.split("+OK ")[1].split("\r\n")[0]; + const result = await verifyCode(parseInt(hash, 16)); + console.log("Verify Result: " + result); + if (result != undefined) connector.verify(result); + } + } }, - [t, connector] + [t, connector, verifyCode] ); const writeCode = useCallback(async () => { @@ -159,13 +215,13 @@ export const Home = () => { console.log(result); return; } - + entry(); read(); }); }; autoConnect(); - }, [autoConnectMode, connector, read]); + }, [autoConnectMode, connector, read, entry]); useEffect(() => { const locale = localStorage.getItem("locale"); From 1a0cc5aa08ab8e56562eeae2e3efc6ffd00303a1 Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Thu, 7 Nov 2024 14:01:07 +0900 Subject: [PATCH 02/11] =?UTF-8?q?feat:=20verify=E3=81=AE=E5=AE=9F=E8=A3=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/mrubyWriterConnector.ts | 2 +- src/pages/home.tsx | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index 94f1ee0..53b3f42 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -23,7 +23,7 @@ const enterWriteModeKeyword: Record = { } as const; const exitWriteModeKeyword: Record = { ESP32: /mrubyc-esp32: End mrbwrite mode/, - RBoard: /start./, ///\+OK Execute mruby\/c./, + RBoard: /mruby\/c v\d+(\.\d+)* start\./, ///\+OK Execute mruby\/c./, } as const; export class MrubyWriterConnector { diff --git a/src/pages/home.tsx b/src/pages/home.tsx index 6e28cb2..25023d9 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -80,7 +80,7 @@ export const Home = () => { } }, [t, connector]); - const crc8 = useMemo(() => (code ? useCrc8(code) : 0), [code]); + const crc8 = useMemo(() => (code ? useCrc8(code) : undefined), [code]); const verifyCode = useCallback( async (hash: number) => { console.log("code: " + code); @@ -120,8 +120,7 @@ export const Home = () => { console.error(res); return; } - console.log("SEND:CRLF\n"); - }, 1500); + }, 1000); }); }, [connector]); From e81c1777aec88b0381b466e8b9996162f534ee86 Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Mon, 11 Nov 2024 15:23:28 +0900 Subject: [PATCH 03/11] =?UTF-8?q?chore:=20=E9=80=81=E4=BF=A1=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E3=81=AA=E3=82=B3=E3=83=9E=E3=83=B3=E3=83=89=E3=81=AB?= =?UTF-8?q?Verify=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/home.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/home.tsx b/src/pages/home.tsx index c1e581d..e4c279e 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -51,6 +51,7 @@ const commands = [ "reset", "help", "showprog", + "verify", ] as const; export const Home = () => { From 613e6ffc20711234d5639c1f25ccd1e67c549762 Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Mon, 11 Nov 2024 15:37:06 +0900 Subject: [PATCH 04/11] =?UTF-8?q?chore:=20verify=E5=91=A8=E3=82=8A?= =?UTF-8?q?=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCrc8.ts | 34 +++++++++------- src/libs/mrubyWriterConnector.ts | 68 ++++++++++++++++---------------- src/pages/home.tsx | 7 ++-- 3 files changed, 57 insertions(+), 52 deletions(-) diff --git a/src/hooks/useCrc8.ts b/src/hooks/useCrc8.ts index 3210016..d264385 100644 --- a/src/hooks/useCrc8.ts +++ b/src/hooks/useCrc8.ts @@ -1,17 +1,23 @@ -export const useCrc8 = (data: Uint8Array) => { - const crc8 = data.reduce((crc, byte) => { - const poly = 0x31; - crc ^= byte; - for (let i = 0; i < 8; i++) { - if (crc & 0x80) { - crc = (crc << 1) ^ poly; - } else { - crc = crc << 1; - } - } - crc &= 0xff; - return crc; - }, 0xff); +import { useMemo } from "react"; + +export const useCrc8 = (data?: Uint8Array) => { + const crc8 = useMemo( + () => + data?.reduce((crc, byte) => { + const poly = 0x31; + crc ^= byte; + for (let i = 0; i < 8; i++) { + if (crc & 0x80) { + crc = (crc << 1) ^ poly; + } else { + crc = crc << 1; + } + } + crc &= 0xff; + return crc; + }, 0xff), + [data] + ); return crc8; }; diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index 53b3f42..d78f7ba 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -415,40 +415,40 @@ export class MrubyWriterConnector { this._writeMode = true; return Success.value(null); } - private async onAttemptEnterWriteMode(): Promise> { - if (!this.port) { - return Failure.error("No port."); - } - if (this._writeMode) { - return Failure.error("Already write mode."); - } - if (!this.subReadable) { - return Failure.error("Cannot read serial port."); - } - if (!this.port.writable) { - return Failure.error("Cannot write serial port."); - } - - const enter = async (): Promise> => { - const response = await this.sendData(this.encoder.encode("\r\n\r\n")); - if (response.isFailure()) { - return response; - } - if (!response.value.includes("+OK mruby/c")) { - return Failure.error("Cannot enter write mode"); - } - - this._writeMode = true; - return Success.value(null); - }; - - const enterJob = enter(); - this.jobQueue.push({ - job: enterJob, - description: "attempt to enter write mode", - }); - return await enterJob; - } + // private async onAttemptEnterWriteMode(): Promise> { + // if (!this.port) { + // return Failure.error("No port."); + // } + // if (this._writeMode) { + // return Failure.error("Already write mode."); + // } + // if (!this.subReadable) { + // return Failure.error("Cannot read serial port."); + // } + // if (!this.port.writable) { + // return Failure.error("Cannot write serial port."); + // } + + // const enter = async (): Promise> => { + // const response = await this.sendData(this.encoder.encode("\r\n\r\n")); + // if (response.isFailure()) { + // return response; + // } + // if (!response.value.includes("+OK mruby/c")) { + // return Failure.error("Cannot enter write mode"); + // } + + // this._writeMode = true; + // return Success.value(null); + // }; + + // const enterJob = enter(); + // this.jobQueue.push({ + // job: enterJob, + // description: "attempt to enter write mode", + // }); + // return await enterJob; + // } private async onExitWriteMode(): Promise> { this._writeMode = false; diff --git a/src/pages/home.tsx b/src/pages/home.tsx index e4c279e..0862483 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { Autocomplete, Box, @@ -93,12 +93,11 @@ export const Home = () => { } }, [t, connector]); - const crc8 = useMemo(() => (code ? useCrc8(code) : undefined), [code]); + const crc8 = useCrc8(code); const verifyCode = useCallback( async (hash: number) => { console.log("code: " + code); if (!code) return; - //const crc8 = useCrc8(code); console.log("crc8: " + crc8); if (crc8 == hash) { return true; @@ -106,7 +105,7 @@ export const Home = () => { return false; } }, - [code] + [code,crc8] ); //切断せずにもう一度書き込もうとするときに動くようにする const entry = useCallback(async () => { From 29f670e0475069275bbe39c8bc6c9ae42600f893 Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Mon, 11 Nov 2024 15:48:07 +0900 Subject: [PATCH 05/11] =?UTF-8?q?fix:=20=E5=AE=9F=E8=A1=8C=E3=81=97?= =?UTF-8?q?=E3=81=9F=E3=82=89write=E3=83=A2=E3=83=BC=E3=83=89=E3=81=8B?= =?UTF-8?q?=E3=82=89=E6=8A=9C=E3=81=91=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB?= =?UTF-8?q?=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/mrubyWriterConnector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index d78f7ba..6a6b3e5 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -23,7 +23,7 @@ const enterWriteModeKeyword: Record = { } as const; const exitWriteModeKeyword: Record = { ESP32: /mrubyc-esp32: End mrbwrite mode/, - RBoard: /mruby\/c v\d+(\.\d+)* start\./, ///\+OK Execute mruby\/c./, + RBoard: /\+OK Execute mruby\/c./, } as const; export class MrubyWriterConnector { From 6d77ca46e8b6e17f897bb22112908e4ba5da6c8a Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Mon, 11 Nov 2024 17:39:10 +0900 Subject: [PATCH 06/11] =?UTF-8?q?fix:=20=E5=AE=9F=E8=A1=8C=E3=83=9C?= =?UTF-8?q?=E3=82=BF=E3=83=B3=E3=82=92=E6=8A=BC=E3=81=97=E3=81=9F=E3=81=AE?= =?UTF-8?q?=E3=81=A1=E3=81=AB=E5=88=87=E6=96=AD=E3=81=99=E3=82=8B=E3=81=A8?= =?UTF-8?q?=E3=81=8D=E3=81=AB=E3=82=A8=E3=83=A9=E3=83=BC=E3=81=8C=E7=99=BA?= =?UTF-8?q?=E7=94=9F=E3=81=97=E3=81=A6=E3=81=84=E3=81=9F=E3=81=AE=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/mrubyWriterConnector.ts | 3 ++- src/pages/home.tsx | 16 +++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index 6a6b3e5..7a6216c 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -23,7 +23,7 @@ const enterWriteModeKeyword: Record = { } as const; const exitWriteModeKeyword: Record = { ESP32: /mrubyc-esp32: End mrbwrite mode/, - RBoard: /\+OK Execute mruby\/c./, + RBoard: /\+OK Execute mruby\/c\./, } as const; export class MrubyWriterConnector { @@ -254,6 +254,7 @@ export class MrubyWriterConnector { return Failure.error("No port."); } + console.log(new TextDecoder().decode(chunk)); const send = async (): Promise> => { const writerRes = this.getWriter(); if (writerRes.isFailure()) { diff --git a/src/pages/home.tsx b/src/pages/home.tsx index 0862483..cf9ee18 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -105,12 +105,13 @@ export const Home = () => { return false; } }, - [code,crc8] + [code, crc8] ); //切断せずにもう一度書き込もうとするときに動くようにする const entry = useCallback(async () => { return new Promise((resolve, reject) => { const interval = setInterval(async () => { + console.log("entry"); console.error(connector.isWriteMode, connector.isConnected); if (connector.isWriteMode) { clearInterval(interval); @@ -158,10 +159,11 @@ export const Home = () => { }, [t, connector]); const send = useCallback( - async (text: string) => { - const res = await connector.sendCommand(text, { - force: true, - }); + async ( + text: string, + option?: Parameters[1] + ) => { + const res = await connector.sendCommand(text, option); console.log(res); if (res.isFailure()) { alert( @@ -472,7 +474,7 @@ export const Home = () => { } - onClick={() => send("execute")} + onClick={() => send("execute",{ignoreResponse:true})} disabled={!connector.isWriteMode} color="success" /> @@ -509,7 +511,7 @@ export const Home = () => { width: "12rem", }} /> - send(command)} value="Send" /> + send(command,{force:true})} value="Send" /> From 85e6a2f26c806e0b6a42750783df5a23d5e5854d Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Thu, 12 Dec 2024 15:58:28 +0900 Subject: [PATCH 07/11] =?UTF-8?q?feat:=E6=9B=B8=E3=81=8D=E8=BE=BC=E3=81=BF?= =?UTF-8?q?=E4=BF=AE=E4=BA=86=E5=BE=8C=E3=81=AB=E3=82=B3=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E3=81=99=E3=82=8B=E3=82=88?= =?UTF-8?q?=E3=81=86=E3=81=AB=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- i18n/locales/en.json | 3 ++- i18n/locales/ja.json | 3 ++- src/hooks/useCrc8.ts | 19 ++-------------- src/libs/mrubyWriterConnector.ts | 14 ++++++++---- src/pages/home.tsx | 38 ++++++++++++++++++++++++-------- src/utils/crc8Calculator.ts | 16 ++++++++++++++ 6 files changed, 61 insertions(+), 32 deletions(-) create mode 100644 src/utils/crc8Calculator.ts diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 16a1653..4542cec 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -25,5 +25,6 @@ "ソースコードを非表示": "Hide source code", "エラーの詳細を見る": "Click to view error details", "クリックして閉じる": "Click to close", - "コマンド": "Command" + "コマンド": "Command", + "検証": "Verify" } diff --git a/i18n/locales/ja.json b/i18n/locales/ja.json index 3d4d49c..4173d63 100644 --- a/i18n/locales/ja.json +++ b/i18n/locales/ja.json @@ -25,5 +25,6 @@ "ソースコードを非表示": "ソースコードを非表示", "エラーの詳細を見る": "エラーの詳細を見る", "クリックして閉じる": "クリックして閉じる", - "コマンド": "コマンド" + "コマンド": "コマンド", + "検証": "検証" } diff --git a/src/hooks/useCrc8.ts b/src/hooks/useCrc8.ts index d264385..47298b6 100644 --- a/src/hooks/useCrc8.ts +++ b/src/hooks/useCrc8.ts @@ -1,23 +1,8 @@ import { useMemo } from "react"; +import { crc8Calculator } from "../utils/crc8Calculator"; export const useCrc8 = (data?: Uint8Array) => { - const crc8 = useMemo( - () => - data?.reduce((crc, byte) => { - const poly = 0x31; - crc ^= byte; - for (let i = 0; i < 8; i++) { - if (crc & 0x80) { - crc = (crc << 1) ^ poly; - } else { - crc = crc << 1; - } - } - crc &= 0xff; - return crc; - }, 0xff), - [data] - ); + const crc8 = useMemo(() => crc8Calculator(data), [data]); return crc8; }; diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index 2ffb600..7334064 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -1,5 +1,6 @@ import { WritableStreamDefaultWriter } from "stream/web"; import { Failure, Result, Success } from "./result"; +import { crc8Calculator } from "../utils/crc8Calculator"; export const targets = ["ESP32", "RBoard"] as const; export type Target = (typeof targets)[number]; @@ -238,7 +239,7 @@ export class MrubyWriterConnector { async writeCode( binary: Uint8Array, option?: Partial<{ execute: boolean }> - ): Promise> { + ): Promise> { if (!this.port) { return Failure.error("No port."); } @@ -262,7 +263,10 @@ export class MrubyWriterConnector { await this.sendCommand("execute"); } - return Success.value(null); + const crc = crc8Calculator(binary); + const crcRes = writeRes.value.split("+OK")[1]; + if (crc !== undefined) this.verify(crc, parseInt(crcRes, 16)); + return Success.value(writeRes.value); } private async sendData( @@ -492,11 +496,13 @@ export class MrubyWriterConnector { return Success.value(line); } - async verify(verifyResult: boolean) { - if (verifyResult) { + async verify(culcHash: number, retHash: number) { + if (culcHash === retHash) { this.handleText("\r\n Verify Success\r\n"); + return true; } else { this.handleText("\r\n Verify Failed\r\n"); + return false; } } } diff --git a/src/pages/home.tsx b/src/pages/home.tsx index 52107ac..b404b33 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -4,6 +4,7 @@ import { Flag as FlagIcon, Usb as UsbIcon, UsbOff as UsbOffIcon, + Plagiarism, } from "@mui/icons-material"; import { Autocomplete, @@ -30,6 +31,7 @@ import { isTarget } from "libs/utility"; import { useTranslation } from "react-i18next"; import ESP32 from "/images/ESP32.png"; import RBoard from "/images/Rboard.png"; +import { useCrc8 } from "../hooks/useCrc8"; const targets = [ { @@ -99,6 +101,20 @@ export const Home = () => { } }, [t, connector]); + const crc8 = useCrc8(code); + // const verifyCode = useCallback( + // async (hash: number) => { + // console.log("code: " + code); + // if (!code) return; + // console.log("crc8: " + crc8); + // if (crc8 == hash) { + // return true; + // } else { + // return false; + // } + // }, + // [code, crc8] + // ); //1秒ごとに書き込みモードに入ることを試みる const tryEntry = useCallback(async () => { return new Promise((resolve, reject) => { @@ -160,17 +176,13 @@ export const Home = () => { }` ); } - if (text == "verify") { - if (res.isSuccess() && res.value.includes("+OK")) { - //マイコンから帰ってくるハッシュ値だけを取り出す - const hash = res.value.split("+OK ")[1].split("\r\n")[0]; - const result = await verifyCode(parseInt(hash, 16)); - console.log("Verify Result: " + result); - if (result != undefined) connector.verify(result); - } + if (text == "verify" && res.isSuccess() && res.value.includes("+OK")) { + const hash = parseInt(res.value.split(" ")[1], 16); + //const result = await verifyCode(hash); + if (crc8 !== undefined) connector.verify(crc8, hash); } }, - [t, connector, verifyCode] + [t, connector, crc8] ); const writeCode = useCallback(async () => { @@ -463,6 +475,14 @@ export const Home = () => { compileStatus.status !== "success" || !connector.isWriteMode } /> + } + onClick={() => send("verify", { ignoreResponse: false })} + disabled={ + compileStatus.status !== "success" || !connector.isWriteMode + } + /> } diff --git a/src/utils/crc8Calculator.ts b/src/utils/crc8Calculator.ts new file mode 100644 index 0000000..a2c4967 --- /dev/null +++ b/src/utils/crc8Calculator.ts @@ -0,0 +1,16 @@ +export const crc8Calculator = (data?: Uint8Array)=> { + const hash = data?.reduce((crc, byte) => { + const poly = 0x31; + crc ^= byte; + for (let i = 0; i < 8; i++) { + if (crc & 0x80) { + crc = (crc << 1) ^ poly; + } else { + crc = crc << 1; + } + } + crc &= 0xff; + return crc; + }, 0xff); + return hash; +}; From f9f1ef86841fb4d3bd662cd769f7762a6b7a8d59 Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Thu, 12 Dec 2024 16:23:40 +0900 Subject: [PATCH 08/11] =?UTF-8?q?chore:=E5=BF=85=E8=A6=81=E3=81=AA?= =?UTF-8?q?=E3=81=8F=E3=81=AA=E3=81=A3=E3=81=9F=E3=82=B3=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=AE=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/home.tsx | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/pages/home.tsx b/src/pages/home.tsx index b404b33..de9c3fc 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -102,19 +102,6 @@ export const Home = () => { }, [t, connector]); const crc8 = useCrc8(code); - // const verifyCode = useCallback( - // async (hash: number) => { - // console.log("code: " + code); - // if (!code) return; - // console.log("crc8: " + crc8); - // if (crc8 == hash) { - // return true; - // } else { - // return false; - // } - // }, - // [code, crc8] - // ); //1秒ごとに書き込みモードに入ることを試みる const tryEntry = useCallback(async () => { return new Promise((resolve, reject) => { @@ -178,7 +165,6 @@ export const Home = () => { } if (text == "verify" && res.isSuccess() && res.value.includes("+OK")) { const hash = parseInt(res.value.split(" ")[1], 16); - //const result = await verifyCode(hash); if (crc8 !== undefined) connector.verify(crc8, hash); } }, @@ -478,7 +464,7 @@ export const Home = () => { } - onClick={() => send("verify", { ignoreResponse: false })} + onClick={() => send("verify")} disabled={ compileStatus.status !== "success" || !connector.isWriteMode } From ee75b2451e522c623369c0c9d07c94957ff4f362 Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Wed, 18 Dec 2024 15:06:15 +0900 Subject: [PATCH 09/11] =?UTF-8?q?chore:=20=E3=83=8F=E3=83=83=E3=82=B7?= =?UTF-8?q?=E3=83=A5=E5=80=A4=E6=AF=94=E8=BC=83=E3=81=AE=E6=9D=A1=E4=BB=B6?= =?UTF-8?q?=E3=82=92=E6=AE=96=E3=82=84=E3=81=97=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useCrc8.ts | 4 +--- src/libs/mrubyWriterConnector.ts | 3 ++- src/pages/home.tsx | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/hooks/useCrc8.ts b/src/hooks/useCrc8.ts index 47298b6..730146e 100644 --- a/src/hooks/useCrc8.ts +++ b/src/hooks/useCrc8.ts @@ -2,7 +2,5 @@ import { useMemo } from "react"; import { crc8Calculator } from "../utils/crc8Calculator"; export const useCrc8 = (data?: Uint8Array) => { - const crc8 = useMemo(() => crc8Calculator(data), [data]); - - return crc8; + return useMemo(() => crc8Calculator(data), [data]); }; diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index 7334064..e008ada 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -265,7 +265,8 @@ export class MrubyWriterConnector { const crc = crc8Calculator(binary); const crcRes = writeRes.value.split("+OK")[1]; - if (crc !== undefined) this.verify(crc, parseInt(crcRes, 16)); + if (crc !== undefined && crcRes !== undefined) + this.verify(crc, parseInt(crcRes, 16)); return Success.value(writeRes.value); } diff --git a/src/pages/home.tsx b/src/pages/home.tsx index de9c3fc..c6ae2db 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -164,8 +164,8 @@ export const Home = () => { ); } if (text == "verify" && res.isSuccess() && res.value.includes("+OK")) { - const hash = parseInt(res.value.split(" ")[1], 16); - if (crc8 !== undefined) connector.verify(crc8, hash); + const hash = parseInt(res.value.split("+OK")[1], 16); + if (crc8 !== undefined && hash!==undefined) connector.verify(crc8, hash); } }, [t, connector, crc8] From ff112893ee01f4d7e8d13d12f892ec3f5f6bcb72 Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Wed, 18 Dec 2024 15:39:47 +0900 Subject: [PATCH 10/11] =?UTF-8?q?chore:=20format=E3=82=92=E3=81=8B?= =?UTF-8?q?=E3=81=91=E3=81=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/mrubyWriterConnector.ts | 2 +- src/pages/home.tsx | 5 +++-- src/utils/crc8Calculator.ts | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index e008ada..333fba0 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -1,6 +1,6 @@ import { WritableStreamDefaultWriter } from "stream/web"; -import { Failure, Result, Success } from "./result"; import { crc8Calculator } from "../utils/crc8Calculator"; +import { Failure, Result, Success } from "./result"; export const targets = ["ESP32", "RBoard"] as const; export type Target = (typeof targets)[number]; diff --git a/src/pages/home.tsx b/src/pages/home.tsx index c6ae2db..ad11087 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -2,9 +2,9 @@ import { CheckCircleRounded as CheckCircleRoundedIcon, Edit as EditIcon, Flag as FlagIcon, + Plagiarism, Usb as UsbIcon, UsbOff as UsbOffIcon, - Plagiarism, } from "@mui/icons-material"; import { Autocomplete, @@ -165,7 +165,8 @@ export const Home = () => { } if (text == "verify" && res.isSuccess() && res.value.includes("+OK")) { const hash = parseInt(res.value.split("+OK")[1], 16); - if (crc8 !== undefined && hash!==undefined) connector.verify(crc8, hash); + if (crc8 !== undefined && hash !== undefined) + connector.verify(crc8, hash); } }, [t, connector, crc8] diff --git a/src/utils/crc8Calculator.ts b/src/utils/crc8Calculator.ts index a2c4967..89e4757 100644 --- a/src/utils/crc8Calculator.ts +++ b/src/utils/crc8Calculator.ts @@ -1,4 +1,4 @@ -export const crc8Calculator = (data?: Uint8Array)=> { +export const crc8Calculator = (data?: Uint8Array) => { const hash = data?.reduce((crc, byte) => { const poly = 0x31; crc ^= byte; From 52649b27bcbd51daf2e2728f841d776f94691b3b Mon Sep 17 00:00:00 2001 From: Suzune2741 Date: Thu, 19 Dec 2024 10:21:53 +0900 Subject: [PATCH 11/11] =?UTF-8?q?fix:=20=E6=9B=B8=E3=81=8D=E8=BE=BC?= =?UTF-8?q?=E3=81=BF=E3=83=A2=E3=83=BC=E3=83=89=E7=B5=82=E4=BA=86=E3=82=AD?= =?UTF-8?q?=E3=83=BC=E3=83=AF=E3=83=BC=E3=83=89=E3=81=AE=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/libs/mrubyWriterConnector.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index 333fba0..21db8e6 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -24,7 +24,7 @@ const enterWriteModeKeyword: Record = { } as const; const exitWriteModeKeyword: Record = { - ESP32: /mrubyc-esp32: End mrbwrite mode/, + ESP32: /mruby\/c v\d(.\d+)* start/, RBoard: /\+OK Execute mruby\/c\./, } as const;