Skip to content

Commit

Permalink
Add support for a progress callback
Browse files Browse the repository at this point in the history
  • Loading branch information
keeramis committed Aug 15, 2023
1 parent b1fc2c0 commit b9d5491
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 6 deletions.
7 changes: 4 additions & 3 deletions src/dfu-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ const DfuDevice = (base) => class extends base {
* @param {Number} altSetting The interface alternate setting.
* @param {Buffer} buffer The binary firmware data to be flashed.
* @param {Number} addr The starting address where the firmware will be written.
* @param {Object} options Optional options for the flashing process.
* @param {Function} progress User's callback function to log progress of the flashing process.
* @param {Object} options Optional options for the flashing process (noErase, leave).
* @returns {Promise<void>} A Promise that resolves when the firmware is successfully flashed.
*/
async writeOverDfu(altSetting, buffer, addr, options) {
async writeOverDfu({ altSetting, buffer, addr, options, progress }) {
await this._dfu.setAltSetting(altSetting);
await this._dfu.doDownload(addr, buffer, options);
await this._dfu.doDownload(addr, buffer, options, progress);
}
};

Expand Down
27 changes: 24 additions & 3 deletions src/dfu.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ class Dfu {
* @param {object} options - Options for the download process.
* @return {Promise}
*/
async doDownload(startAddr, data, options = { noErase: false, leave: false }) {
async doDownload(startAddr, data, options = { noErase: false, leave: false }, progress) {
if (!this._memoryInfo || !this._memoryInfo.segments) {
throw new Error('No memory map available');
}
Expand All @@ -265,11 +265,14 @@ class Dfu {

if (!options.noErase) {
this._log.info('Erasing DFU device memory');
await this._erase(startAddress, expectedSize);
await this._erase(startAddress, expectedSize, progress);
}

this._log.info('Copying binary data to DFU device startAddress=' + startAddress + ' total_expected_size=' + expectedSize);

if (progress) {
progress({ event: 'start-download', bytes: expectedSize });
}
let bytesSent = 0;
let address = startAddress;
while (bytesSent < expectedSize) {
Expand All @@ -289,13 +292,22 @@ class Dfu {
}

if (dfuStatus.status !== DfuDeviceStatus.OK) {
if (progress) {
progress({ event: 'failed-download' });
}
throw new Error(`DFU DOWNLOAD failed state=${dfuStatus.state}, status=${dfuStatus.status}`);
}

this._log.trace('Wrote ' + chunkSize + ' bytes');
bytesSent += chunkSize;
if (progress) {
progress({ event: 'downloaded', bytes: chunkSize });
}
}
this._log.info(`Wrote ${bytesSent} bytes total`);
if (progress) {
progress({ event: 'complete-download', bytes: bytesSent });
}

if (options.leave) {
this._log.info('Manifesting new firmware');
Expand Down Expand Up @@ -581,14 +593,17 @@ class Dfu {
* @param {number} length The length of the memory range to be erased in bytes.
* @throws {Error} If the start address or the length is outside the memory map bounds, or if erasing fails.
*/
async _erase(startAddr, length) {
async _erase(startAddr, length, progress) {
let segment = this._getSegment(startAddr);
let addr = this._getSectorStart(startAddr, segment);
const endAddr = this._getSectorEnd(startAddr + length - 1);

let bytesErased = 0;
const bytesToErase = endAddr - addr;

if (progress) {
progress({ event: 'start-erase', bytes: bytesToErase });
}
while (addr < endAddr) {
if (segment.end <= addr) {
segment = this._getSegment(addr);
Expand All @@ -605,6 +620,12 @@ class Dfu {
await this._dfuseCommand(DfuseCommand.DFUSE_COMMAND_ERASE, sectorAddr);
addr = sectorAddr + segment.sectorSize;
bytesErased += segment.sectorSize;
if (progress) {
progress({ event: 'erased', bytes: segment.sectorSize });
}
}
if (progress) {
progress({ event: 'complete-erase', bytes: bytesErased });
}
}

Expand Down

0 comments on commit b9d5491

Please sign in to comment.