-
-
Notifications
You must be signed in to change notification settings - Fork 1k
Improve Dataflash Save To File #4627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
5a6a08e
9a8a201
ecd64f6
4b591de
d652ec8
68fe053
6d1f80f
af0f746
83e8efd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -2449,148 +2449,92 @@ MspHelper.prototype.setRawRx = function (channels) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /** | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Send a request to read a block of data from the dataflash at the given address and pass that address and a dataview | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * of the returned data to the given callback (or null for the data if an error occured). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * Send a request to read a block of data from the dataflash at the given address | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * and pass that address, a DataView of the returned data, and bytesCompressed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * to the given callback. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MspHelper.prototype.dataflashRead = function (address, blockSize, onDataCallback) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let outData = [address & 0xff, (address >> 8) & 0xff, (address >> 16) & 0xff, (address >> 24) & 0xff]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| outData = outData.concat([blockSize & 0xff, (blockSize >> 8) & 0xff]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let outData = [ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| address & 0xff, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (address >> 8) & 0xff, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (address >> 16) & 0xff, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (address >> 24) & 0xff, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| blockSize & 0xff, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| (blockSize >> 8) & 0xff, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 1, // allow compression | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Allow compression | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| outData = outData.concat([1]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const mspObj = this.msp || (typeof MSP !== "undefined" ? MSP : null); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!mspObj) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.error("MSP object not found, cannot read dataflash."); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDataCallback(address, null, 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MSP.send_message( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| mspObj.send_message( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MSPCodes.MSP_DATAFLASH_READ, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| outData, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| false, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function (response) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!response.crcError) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const chunkAddress = response.data.readU32(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let payloadView = null; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let bytesCompressed = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (response && response.data) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const headerSize = 7; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const chunkAddress = response.data.readU32(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const dataSize = response.data.readU16(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const dataCompressionType = response.data.readU8(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Verify that the address of the memory returned matches what the caller asked for and there was not a CRC error | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (chunkAddress == address) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| /* Strip that address off the front of the reply and deliver it separately so the caller doesn't have to | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| * figure out the reply format: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (dataCompressionType == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDataCallback( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| address, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| new DataView(response.data.buffer, response.data.byteOffset + headerSize, dataSize), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (dataCompressionType == 1) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Read compressed char count to avoid decoding stray bit sequences as bytes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const compressedCharCount = response.data.readU16(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Compressed format uses 2 additional bytes as a pseudo-header to denote the number of uncompressed bytes | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const compressedArray = new Uint8Array( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (chunkAddress === address) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (dataCompressionType === 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| payloadView = new DataView( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response.data.buffer, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response.data.byteOffset + headerSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dataSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytesCompressed = dataSize; // treat uncompressed as same size | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (dataCompressionType === 1) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const compressedCharCount = response.data.readU16(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const compressedArray = new Uint8Array( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response.data.buffer, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response.data.byteOffset + headerSize + 2, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dataSize - 2, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const decompressedArray = huffmanDecodeBuf( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| compressedArray, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| compressedCharCount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultHuffmanTree, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultHuffmanLenIndex, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| payloadView = new DataView(decompressedArray.buffer); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytesCompressed = compressedCharCount; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+2498
to
+2512
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. bytesCompressed is wrong for compressed chunks (breaks compression stats). For type 1 (Huffman), bytesCompressed should reflect on‑wire payload size, not the uncompressed char count. This skews the mean compression factor. - } else if (dataCompressionType === 1) {
- const compressedCharCount = response.data.readU16();
+ } else if (dataCompressionType === 1) {
+ const uncompressedLen = response.data.readU16();
const compressedArray = new Uint8Array(
response.data.buffer,
response.data.byteOffset + headerSize + 2,
- dataSize - 2,
+ dataSize - 2,
);
const decompressedArray = huffmanDecodeBuf(
compressedArray,
- compressedCharCount,
+ uncompressedLen,
defaultHuffmanTree,
defaultHuffmanLenIndex,
);
- payloadView = new DataView(decompressedArray.buffer);
- bytesCompressed = compressedCharCount;
+ payloadView = new DataView(decompressedArray.buffer, 0, uncompressedLen);
+ // Count the transmitted payload bytes (includes the 2-byte uncompressedLen header)
+ bytesCompressed = dataSize;
}📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } catch (e) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.warn("Decompression or read failed, delivering raw data anyway"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| payloadView = new DataView( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response.data.buffer, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response.data.byteOffset + headerSize + 2, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dataSize - 2, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const decompressedArray = huffmanDecodeBuf( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| compressedArray, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| compressedCharCount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultHuffmanTree, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| defaultHuffmanLenIndex, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| response.data.byteOffset + headerSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dataSize, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDataCallback(address, new DataView(decompressedArray.buffer), dataSize); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bytesCompressed = dataSize; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Report address error | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`Expected address ${address} but received ${chunkAddress} - retrying`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDataCallback(address, null); // returning null to the callback forces a retry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`Expected address ${address} but received ${chunkAddress}`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // Report crc error | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`CRC error for address ${address} - retrying`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDataCallback(address, null); // returning null to the callback forces a retry | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MspHelper.prototype.sendServoConfigurations = function (onCompleteCallback) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let nextFunction = send_next_servo_configuration; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onDataCallback(address, payloadView, bytesCompressed); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let servoIndex = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (FC.SERVO_CONFIG.length == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onCompleteCallback(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nextFunction(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function send_next_servo_configuration() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const buffer = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // send one at a time, with index | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const servoConfiguration = FC.SERVO_CONFIG[servoIndex]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| buffer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push8(servoIndex) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push16(servoConfiguration.min) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push16(servoConfiguration.max) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push16(servoConfiguration.middle) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push8(servoConfiguration.rate); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let out = servoConfiguration.indexOfChannelToForward; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (out == undefined) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| out = 255; // Cleanflight defines "CHANNEL_FORWARDING_DISABLED" as "(uint8_t)0xFF" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| buffer.push8(out).push32(servoConfiguration.reversedInputSources); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // prepare for next iteration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| servoIndex++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (servoIndex == FC.SERVO_CONFIG.length) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nextFunction = onCompleteCallback; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MSP.send_message(MSPCodes.MSP_SET_SERVO_CONFIGURATION, buffer, false, nextFunction); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MspHelper.prototype.sendModeRanges = function (onCompleteCallback) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let nextFunction = send_next_mode_range; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let modeRangeIndex = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (FC.MODE_RANGES.length == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onCompleteCallback(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| send_next_mode_range(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| function send_next_mode_range() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const modeRange = FC.MODE_RANGES[modeRangeIndex]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const buffer = []; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| buffer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push8(modeRangeIndex) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push8(modeRange.id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push8(modeRange.auxChannelIndex) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push8((modeRange.range.start - 900) / 25) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| .push8((modeRange.range.end - 900) / 25); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const modeRangeExtra = FC.MODE_RANGES_EXTRA[modeRangeIndex]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| buffer.push8(modeRangeExtra.modeLogic).push8(modeRangeExtra.linkedTo); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // prepare for next iteration | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| modeRangeIndex++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (modeRangeIndex == FC.MODE_RANGES.length) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| nextFunction = onCompleteCallback; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MSP.send_message(MSPCodes.MSP_SET_MODE_RANGE, buffer, false, nextFunction); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (!response || response.crcError) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`CRC error or missing data at address ${address} - delivering whatever we got`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (payloadView) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| console.log(`Block at ${address} received (${payloadView.byteLength} bytes)`); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| true, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ); // end of send_message | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; // end of dataflashRead | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| MspHelper.prototype.sendAdjustmentRanges = function (onCompleteCallback) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| let nextFunction = send_next_adjustment_range; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
🧩 Analysis chain
Gate the new request format by API version (avoid breaking older FCs).
You’ve changed MSP_DATAFLASH_READ to include blockSize and a compression flag. Some firmware builds expect only the 4‑byte address. Add an API guard and fall back to the legacy 4‑byte request for older targets.
If you’re unsure of the minimal API version that accepts (addr, len, compressFlag), please confirm before merging.
🏁 Script executed:
Length of output: 148916
🏁 Script executed:
Length of output: 2817
🏁 Script executed:
Length of output: 7050
Gate MSP_DATAFLASH_READ format behind an API-version check (avoid breaking older FCs).
New format adds blockSize + compression flag; older firmware can expect only the 4‑byte address — guard and fall back to the legacy 4‑byte request.
Location: src/js/msp/MSPHelper.js — dataflashRead (around lines 2456–2475)
Confirm the minimal API version that accepts (addr, len, compressFlag) before merging.
🤖 Prompt for AI Agents