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 new file mode 100644 index 0000000..730146e --- /dev/null +++ b/src/hooks/useCrc8.ts @@ -0,0 +1,6 @@ +import { useMemo } from "react"; +import { crc8Calculator } from "../utils/crc8Calculator"; + +export const useCrc8 = (data?: Uint8Array) => { + return useMemo(() => crc8Calculator(data), [data]); +}; diff --git a/src/libs/mrubyWriterConnector.ts b/src/libs/mrubyWriterConnector.ts index 8c75780..21db8e6 100644 --- a/src/libs/mrubyWriterConnector.ts +++ b/src/libs/mrubyWriterConnector.ts @@ -1,4 +1,5 @@ import { WritableStreamDefaultWriter } from "stream/web"; +import { crc8Calculator } from "../utils/crc8Calculator"; import { Failure, Result, Success } from "./result"; export const targets = ["ESP32", "RBoard"] as const; @@ -23,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; @@ -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,11 @@ 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 && crcRes !== undefined) + this.verify(crc, parseInt(crcRes, 16)); + return Success.value(writeRes.value); } private async sendData( @@ -492,4 +497,13 @@ export class MrubyWriterConnector { return Success.value(line); } + 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 491f65a..ad11087 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -2,6 +2,7 @@ import { CheckCircleRounded as CheckCircleRoundedIcon, Edit as EditIcon, Flag as FlagIcon, + Plagiarism, Usb as UsbIcon, UsbOff as UsbOffIcon, } from "@mui/icons-material"; @@ -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 = [ { @@ -51,6 +53,7 @@ const commands = [ "reset", "help", "showprog", + "verify", ] as const; export const Home = () => { @@ -98,6 +101,7 @@ export const Home = () => { } }, [t, connector]); + const crc8 = useCrc8(code); //1秒ごとに書き込みモードに入ることを試みる const tryEntry = useCallback(async () => { return new Promise((resolve, reject) => { @@ -159,8 +163,13 @@ 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); + } }, - [t, connector] + [t, connector, crc8] ); const writeCode = useCallback(async () => { @@ -453,6 +462,14 @@ export const Home = () => { compileStatus.status !== "success" || !connector.isWriteMode } /> + } + onClick={() => send("verify")} + disabled={ + compileStatus.status !== "success" || !connector.isWriteMode + } + /> } diff --git a/src/utils/crc8Calculator.ts b/src/utils/crc8Calculator.ts new file mode 100644 index 0000000..89e4757 --- /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; +};