From 3d143ee7d542ce767ca677c1ff45db4832f7bff4 Mon Sep 17 00:00:00 2001 From: Yoichiro Tanaka Date: Mon, 27 Jan 2025 11:37:28 +0900 Subject: [PATCH 1/3] Change a firmware blob loading timing. --- src/actions/firmware.action.ts | 71 +++++++++++++++---- .../keyboard/build/CatalogBuild.container.ts | 6 +- .../firmware/CatalogFirmware.container.ts | 6 +- .../common/firmware/FlashFirmwareDialog.tsx | 14 ++-- src/store/reducers.ts | 7 +- src/store/state.ts | 2 + 6 files changed, 84 insertions(+), 22 deletions(-) diff --git a/src/actions/firmware.action.ts b/src/actions/firmware.action.ts index 51df5b71..05a90cb6 100644 --- a/src/actions/firmware.action.ts +++ b/src/actions/firmware.action.ts @@ -48,6 +48,7 @@ export const FLASH_FIRMWARE_DIALOG_CLEAR = `${FLASH_FIRMWARE_DIALOG_ACTIONS}/Cle export const FLASH_FIRMWARE_DIALOG_UPDATE_KEYBOARD_NAME = `${FLASH_FIRMWARE_DIALOG_ACTIONS}/UpdateKeyboardName`; export const FLASH_FIRMWARE_DIALOG_UPDATE_FLASH_MODE = `${FLASH_FIRMWARE_DIALOG_ACTIONS}/UpdateFlashMode`; export const FLASH_FIRMWARE_DIALOG_UPDATE_BUILDING_FIRMWARE_TASK = `${FLASH_FIRMWARE_DIALOG_ACTIONS}/UpdateBuildingFirmwareTask`; +export const FLASH_FIRMWARE_DIALOG_UPDATE_FIRMWARE_BLOB = `${FLASH_FIRMWARE_DIALOG_ACTIONS}/UpdateFirmwareBlob`; export const FlashFirmwareDialogActions = { updateFirmware: (firmware: IFirmware | null) => { return { @@ -117,6 +118,12 @@ export const FlashFirmwareDialogActions = { value: task, }; }, + updateFirmwareBlob: (blob: Buffer | undefined) => { + return { + type: FLASH_FIRMWARE_DIALOG_UPDATE_FIRMWARE_BLOB, + value: blob, + }; + }, }; type ActionTypes = ReturnType< @@ -171,9 +178,9 @@ export const firmwareActionsThunk = { created_at: new Date(), }) ); + await dispatch(firmwareActionsThunk.loadFirmwareBlob()); }, - // eslint-disable-next-line no-undef - flashFirmware: + loadFirmwareBlob: (): ThunkPromiseAction => async ( dispatch: ThunkDispatch, @@ -182,21 +189,17 @@ export const firmwareActionsThunk = { const handleError = (error: string, cause?: any) => { console.error(error); dispatch(NotificationActions.addError(error, cause)); - dispatch(FlashFirmwareDialogActions.appendLog(`Error: ${error}`)); - dispatch(FlashFirmwareDialogActions.updateFlashing(false)); + dispatch(FlashFirmwareDialogActions.clear()); }; - dispatch(FlashFirmwareDialogActions.updateLogs([])); - dispatch(FlashFirmwareDialogActions.updateProgressRate(0)); - dispatch(FlashFirmwareDialogActions.updateMode('flashing')); - dispatch(FlashFirmwareDialogActions.updateFlashing(true)); - const { entities, storage, serial, common } = getState(); - const firmwareWriter = serial.writer; + dispatch(FlashFirmwareDialogActions.updateMode('loading')); + dispatch(FlashFirmwareDialogActions.updateFlashing(false)); + + const { common, entities, storage } = getState(); const firmware = common.firmware.flashFirmwareDialog.firmware!; const bootloaderType = common.firmware.flashFirmwareDialog.bootloaderType!; const flashMode = common.firmware.flashFirmwareDialog.flashMode; - let flashBytes: Buffer | undefined; if (flashMode === 'fetch_and_flash') { const definitionDocument = entities.keyboardDefinitionDocument!; @@ -268,11 +271,50 @@ export const firmwareActionsThunk = { return; } } + dispatch(FlashFirmwareDialogActions.updateFirmwareBlob(flashBytes)); + dispatch(FlashFirmwareDialogActions.updateMode('instruction')); + }, + // eslint-disable-next-line no-undef + flashFirmware: + (): ThunkPromiseAction => + async ( + dispatch: ThunkDispatch, + getState: () => RootState + ) => { + const handleError = (error: string, cause?: any) => { + console.error(error); + dispatch(NotificationActions.addError(error, cause)); + dispatch(FlashFirmwareDialogActions.appendLog(`Error: ${error}`)); + dispatch(FlashFirmwareDialogActions.updateFlashing(false)); + }; + + dispatch(FlashFirmwareDialogActions.updateLogs([])); + dispatch(FlashFirmwareDialogActions.updateProgressRate(0)); + dispatch(FlashFirmwareDialogActions.updateMode('flashing')); + dispatch(FlashFirmwareDialogActions.updateFlashing(true)); + const { entities, storage, serial, common } = getState(); + const firmwareWriter = serial.writer; + const firmware = common.firmware.flashFirmwareDialog.firmware!; + const bootloaderType = + common.firmware.flashFirmwareDialog.bootloaderType!; + const flashMode = common.firmware.flashFirmwareDialog.flashMode; + + let flashBytes: Buffer | undefined = + common.firmware.flashFirmwareDialog.firmwareBlob; + if (flashBytes === undefined) { + dispatch( + NotificationActions.addError('Firmware binary is not loaded.') + ); + dispatch(FlashFirmwareDialogActions.clear()); + return; + } + dispatch( FlashFirmwareDialogActions.appendLog( - 'Reading the firmware binary done.' + 'Firmware binary has already been loaded. Start writing the firmware.' ) ); + dispatch(FlashFirmwareDialogActions.updateProgressRate(15)); const writeResult = await firmwareWriter.write( @@ -341,15 +383,14 @@ const createFlashBytes = ( return buffer; } } catch (error) { - console.error(error); + console.error('Creating a flashed bytes failed.', error); dispatch( NotificationActions.addError( 'Creating the firmware binary failed.', error ) ); - dispatch(FlashFirmwareDialogActions.appendLog(`Error: ${error}`)); - dispatch(FlashFirmwareDialogActions.updateFlashing(false)); + dispatch(FlashFirmwareDialogActions.clear()); return undefined; } }; diff --git a/src/components/catalog/keyboard/build/CatalogBuild.container.ts b/src/components/catalog/keyboard/build/CatalogBuild.container.ts index cdf9d532..b3ee71da 100644 --- a/src/components/catalog/keyboard/build/CatalogBuild.container.ts +++ b/src/components/catalog/keyboard/build/CatalogBuild.container.ts @@ -14,7 +14,10 @@ import { IFirmwareBuildingTask, IKeyboardDefinitionDocument, } from '../../../../services/storage/Storage'; -import { FlashFirmwareDialogActions } from '../../../../actions/firmware.action'; +import { + firmwareActionsThunk, + FlashFirmwareDialogActions, +} from '../../../../actions/firmware.action'; // eslint-disable-next-line no-unused-vars const mapStateToProps = (state: RootState) => { @@ -92,6 +95,7 @@ const mapDispatchToProps = (dispatch: any) => { created_at: new Date(), }) ); + dispatch(firmwareActionsThunk.loadFirmwareBlob()); }, updateBuildableFirmwareCodeParameterValues: ( values: IBuildableFirmwareCodeParameterValues diff --git a/src/components/catalog/keyboard/firmware/CatalogFirmware.container.ts b/src/components/catalog/keyboard/firmware/CatalogFirmware.container.ts index 62fdbf53..d3ec40be 100644 --- a/src/components/catalog/keyboard/firmware/CatalogFirmware.container.ts +++ b/src/components/catalog/keyboard/firmware/CatalogFirmware.container.ts @@ -7,7 +7,10 @@ import { IFirmware, IKeyboardDefinitionDocument, } from '../../../../services/storage/Storage'; -import { FlashFirmwareDialogActions } from '../../../../actions/firmware.action'; +import { + firmwareActionsThunk, + FlashFirmwareDialogActions, +} from '../../../../actions/firmware.action'; // eslint-disable-next-line no-unused-vars const mapStateToProps = (state: RootState) => { @@ -56,6 +59,7 @@ const mapDispatchToProps = (_dispatch: any) => { FlashFirmwareDialogActions.updateFlashMode('fetch_and_flash') ); _dispatch(FlashFirmwareDialogActions.updateFirmware(firmware)); + _dispatch(firmwareActionsThunk.loadFirmwareBlob()); }, }, }; diff --git a/src/components/common/firmware/FlashFirmwareDialog.tsx b/src/components/common/firmware/FlashFirmwareDialog.tsx index 712b3f95..365d4a29 100644 --- a/src/components/common/firmware/FlashFirmwareDialog.tsx +++ b/src/components/common/firmware/FlashFirmwareDialog.tsx @@ -116,10 +116,10 @@ export default function FlashFirmwareDialog( value={props.logs!.join('\n')} /> - ) : ( + ) : props.mode === 'instruction' ? (
- 3 Steps to Flash + Three Steps to Flash
instructionImage1 @@ -158,17 +158,23 @@ export default function FlashFirmwareDialog( . + ) : ( + Now loading the firmware... )} - diff --git a/src/store/reducers.ts b/src/store/reducers.ts index 4248cfc4..8f320cec 100644 --- a/src/store/reducers.ts +++ b/src/store/reducers.ts @@ -201,6 +201,7 @@ import { FLASH_FIRMWARE_DIALOG_UPDATE_BOOTLOADER_TYPE, FLASH_FIRMWARE_DIALOG_UPDATE_BUILDING_FIRMWARE_TASK, FLASH_FIRMWARE_DIALOG_UPDATE_FIRMWARE, + FLASH_FIRMWARE_DIALOG_UPDATE_FIRMWARE_BLOB, FLASH_FIRMWARE_DIALOG_UPDATE_FLASH_MODE, FLASH_FIRMWARE_DIALOG_UPDATE_FLASHING, FLASH_FIRMWARE_DIALOG_UPDATE_KEYBOARD_NAME, @@ -1196,7 +1197,8 @@ const flashFirmwareDialogReducer = ( draft.common.firmware.flashFirmwareDialog.flashing = false; draft.common.firmware.flashFirmwareDialog.progressRate = 0; draft.common.firmware.flashFirmwareDialog.logs = ['']; - draft.common.firmware.flashFirmwareDialog.mode = 'instruction'; + draft.common.firmware.flashFirmwareDialog.firmware = null; + draft.common.firmware.flashFirmwareDialog.mode = 'loading'; break; case FLASH_FIRMWARE_DIALOG_UPDATE_LOGS: draft.common.firmware.flashFirmwareDialog.logs = ['']; @@ -1214,6 +1216,9 @@ const flashFirmwareDialogReducer = ( draft.common.firmware.flashFirmwareDialog.buildingFirmwareTask = action.value; break; + case FLASH_FIRMWARE_DIALOG_UPDATE_FIRMWARE_BLOB: + draft.common.firmware.flashFirmwareDialog.firmwareBlob = action.value; + break; } }; diff --git a/src/store/state.ts b/src/store/state.ts index da75e20d..0102cd58 100644 --- a/src/store/state.ts +++ b/src/store/state.ts @@ -168,6 +168,7 @@ export const CONDITION_NOT_SELECTED: IConditionNotSelected = '---'; export const ALL_FLASH_FIRMWARE_DIALOG_MODE = [ 'instruction', 'flashing', + 'loading', ] as const; type flashFirmwareDialogModeTuple = typeof ALL_FLASH_FIRMWARE_DIALOG_MODE; export type IFlashFirmwareDialogMode = flashFirmwareDialogModeTuple[number]; @@ -463,6 +464,7 @@ export type RootState = { bootloaderType: IBootloaderType; flashMode: IFlashFirmwareDialogFlashMode; buildingFirmwareTask: IFirmwareBuildingTask | null; + firmwareBlob: Buffer | undefined; }; uploadFirmwareDialog: { open: boolean; From 8ea6194c1d9dbb614921ca2ca8132c4492502032 Mon Sep 17 00:00:00 2001 From: Yoichiro Tanaka Date: Mon, 27 Jan 2025 11:44:21 +0900 Subject: [PATCH 2/3] Define the initial value for the `firmwareBlob`. --- src/store/state.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/store/state.ts b/src/store/state.ts index 0102cd58..a9259e39 100644 --- a/src/store/state.ts +++ b/src/store/state.ts @@ -727,6 +727,7 @@ export const INIT_STATE: RootState = { bootloaderType: 'caterina', flashMode: 'fetch_and_flash', buildingFirmwareTask: null, + firmwareBlob: undefined, }, uploadFirmwareDialog: { open: false, From 1b9b6daa9cfd59a3a0944313da452c3243bc327e Mon Sep 17 00:00:00 2001 From: Yoichiro Tanaka Date: Mon, 27 Jan 2025 11:47:08 +0900 Subject: [PATCH 3/3] Delete unnecessary codes. --- src/actions/firmware.action.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/actions/firmware.action.ts b/src/actions/firmware.action.ts index 05a90cb6..0a4a926b 100644 --- a/src/actions/firmware.action.ts +++ b/src/actions/firmware.action.ts @@ -292,12 +292,10 @@ export const firmwareActionsThunk = { dispatch(FlashFirmwareDialogActions.updateProgressRate(0)); dispatch(FlashFirmwareDialogActions.updateMode('flashing')); dispatch(FlashFirmwareDialogActions.updateFlashing(true)); - const { entities, storage, serial, common } = getState(); + const { serial, common } = getState(); const firmwareWriter = serial.writer; - const firmware = common.firmware.flashFirmwareDialog.firmware!; const bootloaderType = common.firmware.flashFirmwareDialog.bootloaderType!; - const flashMode = common.firmware.flashFirmwareDialog.flashMode; let flashBytes: Buffer | undefined = common.firmware.flashFirmwareDialog.firmwareBlob;