firmware: add progress indication for DFU USB flash

This commit is contained in:
David Lechner
2022-07-27 15:19:36 -05:00
parent 8dadc8826c
commit 1148b169d5
3 changed files with 84 additions and 4 deletions
+54
View File
@@ -0,0 +1,54 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors
import { Intent, ProgressBar } from '@blueprintjs/core';
import React from 'react';
import { CreateToast } from '../../i18nToaster';
import { useI18n } from './i18n';
type FlashProgressProps = {
action: 'erase' | 'flash';
progress: number | undefined;
};
const FlashProgress: React.VoidFunctionComponent<FlashProgressProps> = ({
action,
progress,
}) => {
const i18n = useI18n();
return (
<>
{action === 'erase' && (
<p>
{i18n.translate('flashProgress.erasing', {
percent: progress ? i18n.formatPercentage(progress) : '',
})}
</p>
)}
{action === 'flash' && (
<p>
{i18n.translate('flashProgress.flashing', {
percent: progress ? i18n.formatPercentage(progress) : '',
})}
</p>
)}
<p>
<ProgressBar value={progress} />
</p>
</>
);
};
export const flashProgress: CreateToast<FlashProgressProps> = (onAction, props) => {
return {
message: <FlashProgress {...props} />,
icon: 'download',
intent: Intent.PRIMARY,
// close one second after progress is complete
timeout: (props.progress ?? 0) < 1 ? 0 : 1000,
onDismiss: () => onAction('dismiss'),
};
};
+4
View File
@@ -17,5 +17,9 @@
},
"firmwareMismatch": {
"message": "Cannot flash firmware. The firmware file is for a different kind of hub."
},
"flashProgress": {
"erasing": "Erasing internal flash memory: {percent}",
"flashing": "Writing new firmware: {percent}"
}
}
+26 -4
View File
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2022 The Pybricks Authors
import { IToaster } from '@blueprintjs/core';
import {
FirmwareReader,
FirmwareReaderError,
@@ -75,6 +76,7 @@ import {
firmwareInstallPybricks,
flashFirmware,
} from './actions';
import { flashProgress } from './alerts/FlashProgress';
import {
firmwareInstallPybricksDialogAccept,
firmwareInstallPybricksDialogCancel,
@@ -615,12 +617,10 @@ function* handleFlashUsbDfu(action: ReturnType<typeof firmwareFlashUsbDfu>): Gen
// forceInterfacesName is needed to get the flash layout map
{ forceInterfacesName: true },
{
// NB: info and progress are never called in dfu v0.1.5
info: console.debug,
warning: console.warn,
progress: (progress, total) => {
// TODO: bind to eventChannel and dispatch progress actions
console.log(progress, total);
},
progress: console.debug,
},
);
@@ -656,6 +656,28 @@ function* handleFlashUsbDfu(action: ReturnType<typeof firmwareFlashUsbDfu>): Gen
dfu.dfuseStartAddress = dfuFirmwareStartAddress;
const writeProc = dfu.write(1024, firmware, true);
const toaster = yield* getContext<IToaster>('toaster');
writeProc.events.on('erase/process', (sent, total) => {
toaster.show(
flashProgress(() => undefined, {
action: 'erase',
progress: sent / total,
}),
'firmware.dfu.progress',
);
});
writeProc.events.on('write/process', (sent, total) => {
toaster.show(
flashProgress(() => undefined, {
action: 'flash',
progress: sent / total,
}),
'firmware.dfu.progress',
);
});
writeProc.events.on('error', console.error);
// REVISIT: we could possibly race the 'write/end' and 'error' events