diff --git a/app/firmwares/DynamixelCsDll.dll b/app/firmwares/DynamixelCsDll.dll new file mode 100644 index 0000000000..0b6423cbbb Binary files /dev/null and b/app/firmwares/DynamixelCsDll.dll differ diff --git a/app/firmwares/OpenCM7.0.bin b/app/firmwares/OpenCM7.0.bin new file mode 100644 index 0000000000..25b43eff92 Binary files /dev/null and b/app/firmwares/OpenCM7.0.bin differ diff --git a/app/firmwares/opencm7Dfu.exe b/app/firmwares/opencm7Dfu.exe new file mode 100644 index 0000000000..482f254e2c Binary files /dev/null and b/app/firmwares/opencm7Dfu.exe differ diff --git a/app/modules/robotis_openCM70EDU.json b/app/modules/robotis_openCM70EDU.json index 75cf768715..0a5a4ae5f9 100644 --- a/app/modules/robotis_openCM70EDU.json +++ b/app/modules/robotis_openCM70EDU.json @@ -16,6 +16,14 @@ "win32-x64": "ROBOTIS/ROBOTIS CDC Driver.bat" }, "selectPort" : true, + "firmware": { + "type": "opencm7", + "offset": "0x8004000", + "name": "OpenCM7.0", + "translate" : "실과로봇 펌웨어 업데이트", + "latest_version": 21 + }, + "firmwareBaudRate": 57600, "hardware": { "type": "serial", "control": "slave", diff --git a/app/src/main/core/serial/flasher.ts b/app/src/main/core/serial/flasher.ts index 1bbbcc5399..d51e622d30 100644 --- a/app/src/main/core/serial/flasher.ts +++ b/app/src/main/core/serial/flasher.ts @@ -135,6 +135,102 @@ class Flasher { }); } + private _flashOpenCM7( + firmware: IOpenCM7TypeFirmware, + port: string, + options: { + baudRate?: number; + MCUType?: string; + } + ): Promise { + return new Promise((resolve) => { + const cmd = [ + 'opencm7Dfu.exe', + ' opencm7', + ` ${port}`, + ` ${firmware.name}.bin`, + ].join(''); + + logger.info(`OpenCM7.0 board firmware requested.\nparameter is ${cmd}`); + try { + this.flasherProcess = exec( + cmd, + { + cwd: directoryPaths.firmware(), + }, + (...args) => { + resolve(args); + } + ).on('exit', code => { + if (code != null) + { + if (code > 2147483647) + { + code = code - 4294967296; + } + } + console.log('final exit code is', code); + } + ); + } + catch (error) { + + } + }); + } + + checkOpenCM7Version( + port: string, + latest_version: number, + ): Promise { + return new Promise((resolve) => { + const cmd = [ + 'opencm7Dfu.exe', + ' opencm7', + ` ${port}`, + ' version', + ].join(''); + + logger.info(`Read OpenCM7.0 board firmware version.\nparameter is ${cmd}`); + try { + this.flasherProcess = exec( + cmd, + { + cwd: directoryPaths.firmware(), + }, + (...args) => { + resolve(args); + } + ).on('exit', code => { + if (code != null) + { + console.log('code is', code); + if (code > 2147483647) + { + code = code - 4294967296; + } + } + if (code) + { + if (code < latest_version) + { + dialog.showMessageBox({ + type: 'info', + title: `펌웨어 업데이트 안내 (v${latest_version})`, + message: '새로운 펌웨어가 배포되었습니다.\n펌웨어를 업데이트 해주세요.\nNew firmware is available.\nPlease update the firmware.\n' + }); + } + } + console.log('final exit code is', code); + } + ); + } + catch (error) { + + } + }); + } + flash( firmware: IFirmwareInfo, port: string, @@ -149,6 +245,8 @@ class Flasher { return this._flashCopy(firmware as ICopyTypeFirmware); } else if ((firmware as IESP32TypeFirmware).type === 'esp32') { return this._flashESP(firmware as IESP32TypeFirmware, port, options); + } else if ((firmware as IOpenCM7TypeFirmware).type === 'opencm7') { + return this._flashOpenCM7(firmware as IOpenCM7TypeFirmware, port, options); } else { return Promise.reject(new Error()); } diff --git a/app/src/main/core/serial/scanner.ts b/app/src/main/core/serial/scanner.ts index 4851fa931a..a4417b4a60 100644 --- a/app/src/main/core/serial/scanner.ts +++ b/app/src/main/core/serial/scanner.ts @@ -6,6 +6,7 @@ import {CloudModeTypes} from '../../../common/constants'; import BaseScanner from '../baseScanner'; import SerialConnector from './connector'; import createLogger from '../../electron/functions/createLogger'; +import Flasher from './flasher'; const logger = createLogger('core/SerialScanner.ts'); @@ -18,6 +19,7 @@ const logger = createLogger('core/SerialScanner.ts'); */ class SerialScanner extends BaseScanner { private isScanning = false; + private flasher = new Flasher(); static get SCAN_INTERVAL_MILLS() { return 1500; @@ -100,6 +102,20 @@ class SerialScanner extends BaseScanner { return; } + + const firmware = this.config.firmware; + + if (firmware) + { + if ((firmware as IOpenCM7TypeFirmware).type === 'opencm7') + { + if (selectedPorts[0] != null) + { + await this.flasher.checkOpenCM7Version(selectedPorts[0], (this.config.firmware as IOpenCM7TypeFirmware).latest_version); + } + } + } + const electedConnector = await electPort(selectedPorts, hardware, this.hwModule, (connector) => { if (this.config && this.config.firmware) { diff --git a/types/index.d.ts b/types/index.d.ts index 34c77bd298..f7da925423 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -29,11 +29,20 @@ declare type IESP32TypeFirmware = { afterDelay?: number; translate?: string; }; +declare type IOpenCM7TypeFirmware = { + type: string; + offset: string; + name: string; + latest_version: number; + afterDelay?: number; + translate?: string; +}; declare type IFirmwareInfo = | string | [{ name: string; translate: string }] | ICopyTypeFirmware - | IESP32TypeFirmware; + | IESP32TypeFirmware + | IOpenCM7TypeFirmware; declare type ICustomButtonInfo = | string | { key: string; translate: string }