Skip to content

Commit fc6b059

Browse files
committed
Ingore CRC on dataFlash Reads
1 parent e62fa71 commit fc6b059

File tree

2 files changed

+92
-164
lines changed

2 files changed

+92
-164
lines changed

src/js/msp/MSPHelper.js

Lines changed: 49 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -2443,147 +2443,74 @@ MspHelper.prototype.setRawRx = function (channels) {
24432443

24442444
/**
24452445
* Send a request to read a block of data from the dataflash at the given address and pass that address and a dataview
2446-
* of the returned data to the given callback (or null for the data if an error occured).
2446+
* of the returned data to the given callback (or null for the data if an error occurred).
24472447
*/
2448-
MspHelper.prototype.dataflashRead = function (address, blockSize, onDataCallback) {
2449-
let outData = [address & 0xff, (address >> 8) & 0xff, (address >> 16) & 0xff, (address >> 24) & 0xff];
2450-
2451-
outData = outData.concat([blockSize & 0xff, (blockSize >> 8) & 0xff]);
2452-
2453-
// Allow compression
2454-
outData = outData.concat([1]);
2455-
2456-
MSP.send_message(
2457-
MSPCodes.MSP_DATAFLASH_READ,
2458-
outData,
2459-
false,
2460-
function (response) {
2461-
if (!response.crcError) {
2462-
const chunkAddress = response.data.readU32();
2463-
2464-
const headerSize = 7;
2465-
const dataSize = response.data.readU16();
2466-
const dataCompressionType = response.data.readU8();
2467-
2468-
// Verify that the address of the memory returned matches what the caller asked for and there was not a CRC error
2469-
if (chunkAddress == address) {
2470-
/* Strip that address off the front of the reply and deliver it separately so the caller doesn't have to
2471-
* figure out the reply format:
2472-
*/
2473-
if (dataCompressionType == 0) {
2474-
onDataCallback(
2475-
address,
2476-
new DataView(response.data.buffer, response.data.byteOffset + headerSize, dataSize),
2477-
);
2478-
} else if (dataCompressionType == 1) {
2479-
// Read compressed char count to avoid decoding stray bit sequences as bytes
2480-
const compressedCharCount = response.data.readU16();
2448+
MspHelper.prototype.dataflashRead = function(address, blockSize, onDataCallback) {
2449+
let outData = [
2450+
address & 0xFF,
2451+
(address >> 8) & 0xFF,
2452+
(address >> 16) & 0xFF,
2453+
(address >> 24) & 0xFF,
2454+
blockSize & 0xFF,
2455+
(blockSize >> 8) & 0xFF,
2456+
1 // allow compression
2457+
];
2458+
2459+
const mspObj = this.msp || (typeof MSP !== 'undefined' ? MSP : null);
2460+
if (!mspObj) {
2461+
console.error('MSP object not found, cannot read dataflash.');
2462+
onDataCallback(address, null);
2463+
return;
2464+
}
2465+
2466+
mspObj.send_message(MSPCodes.MSP_DATAFLASH_READ, outData, false, function(response) {
2467+
let payloadView = null;
24812468

2482-
// Compressed format uses 2 additional bytes as a pseudo-header to denote the number of uncompressed bytes
2469+
if (response && response.data) {
2470+
const headerSize = 7;
2471+
const chunkAddress = response.data.readU32();
2472+
const dataSize = response.data.readU16();
2473+
const dataCompressionType = response.data.readU8();
2474+
2475+
if (chunkAddress === address) {
2476+
try {
2477+
if (dataCompressionType === 0) {
2478+
payloadView = new DataView(response.data.buffer, response.data.byteOffset + headerSize, dataSize);
2479+
} else if (dataCompressionType === 1) {
2480+
const compressedCharCount = response.data.readU16();
24832481
const compressedArray = new Uint8Array(
24842482
response.data.buffer,
24852483
response.data.byteOffset + headerSize + 2,
2486-
dataSize - 2,
2484+
dataSize - 2
24872485
);
24882486
const decompressedArray = huffmanDecodeBuf(
24892487
compressedArray,
24902488
compressedCharCount,
24912489
defaultHuffmanTree,
2492-
defaultHuffmanLenIndex,
2490+
defaultHuffmanLenIndex
24932491
);
2494-
2495-
onDataCallback(address, new DataView(decompressedArray.buffer), dataSize);
2492+
payloadView = new DataView(decompressedArray.buffer);
24962493
}
2497-
} else {
2498-
// Report address error
2499-
console.log(`Expected address ${address} but received ${chunkAddress} - retrying`);
2500-
onDataCallback(address, null); // returning null to the callback forces a retry
2494+
} catch (e) {
2495+
console.warn('Decompression or read failed, delivering raw data anyway');
2496+
payloadView = new DataView(response.data.buffer, response.data.byteOffset + headerSize, dataSize);
25012497
}
25022498
} else {
2503-
// Report crc error
2504-
console.log(`CRC error for address ${address} - retrying`);
2505-
onDataCallback(address, null); // returning null to the callback forces a retry
2499+
console.log(`Expected address ${address} but received ${chunkAddress}`);
25062500
}
2507-
},
2508-
true,
2509-
);
2510-
};
2511-
2512-
MspHelper.prototype.sendServoConfigurations = function (onCompleteCallback) {
2513-
let nextFunction = send_next_servo_configuration;
2514-
2515-
let servoIndex = 0;
2516-
2517-
if (FC.SERVO_CONFIG.length == 0) {
2518-
onCompleteCallback();
2519-
} else {
2520-
nextFunction();
2521-
}
2522-
2523-
function send_next_servo_configuration() {
2524-
const buffer = [];
2525-
2526-
// send one at a time, with index
2527-
2528-
const servoConfiguration = FC.SERVO_CONFIG[servoIndex];
2529-
2530-
buffer
2531-
.push8(servoIndex)
2532-
.push16(servoConfiguration.min)
2533-
.push16(servoConfiguration.max)
2534-
.push16(servoConfiguration.middle)
2535-
.push8(servoConfiguration.rate);
2536-
2537-
let out = servoConfiguration.indexOfChannelToForward;
2538-
if (out == undefined) {
2539-
out = 255; // Cleanflight defines "CHANNEL_FORWARDING_DISABLED" as "(uint8_t)0xFF"
25402501
}
2541-
buffer.push8(out).push32(servoConfiguration.reversedInputSources);
25422502

2543-
// prepare for next iteration
2544-
servoIndex++;
2545-
if (servoIndex == FC.SERVO_CONFIG.length) {
2546-
nextFunction = onCompleteCallback;
2547-
}
2548-
2549-
MSP.send_message(MSPCodes.MSP_SET_SERVO_CONFIGURATION, buffer, false, nextFunction);
2550-
}
2551-
};
2552-
2553-
MspHelper.prototype.sendModeRanges = function (onCompleteCallback) {
2554-
let nextFunction = send_next_mode_range;
2555-
2556-
let modeRangeIndex = 0;
2557-
2558-
if (FC.MODE_RANGES.length == 0) {
2559-
onCompleteCallback();
2560-
} else {
2561-
send_next_mode_range();
2562-
}
2503+
// Deliver payloadView if defined, otherwise pass null
2504+
onDataCallback(address, payloadView);
25632505

2564-
function send_next_mode_range() {
2565-
const modeRange = FC.MODE_RANGES[modeRangeIndex];
2566-
const buffer = [];
2567-
2568-
buffer
2569-
.push8(modeRangeIndex)
2570-
.push8(modeRange.id)
2571-
.push8(modeRange.auxChannelIndex)
2572-
.push8((modeRange.range.start - 900) / 25)
2573-
.push8((modeRange.range.end - 900) / 25);
2574-
2575-
const modeRangeExtra = FC.MODE_RANGES_EXTRA[modeRangeIndex];
2576-
2577-
buffer.push8(modeRangeExtra.modeLogic).push8(modeRangeExtra.linkedTo);
2578-
2579-
// prepare for next iteration
2580-
modeRangeIndex++;
2581-
if (modeRangeIndex == FC.MODE_RANGES.length) {
2582-
nextFunction = onCompleteCallback;
2506+
if (!response || response.crcError) {
2507+
console.log(`CRC error or missing data at address ${address} - delivering whatever we got`);
2508+
} else if (payloadView) {
2509+
console.log(`Block at ${address} received (${payloadView.byteLength} bytes)`);
25832510
}
2584-
MSP.send_message(MSPCodes.MSP_SET_MODE_RANGE, buffer, false, nextFunction);
2585-
}
2586-
};
2511+
}, true); // end of send_message
2512+
}; // end of dataflashRead
2513+
25872514

25882515
MspHelper.prototype.sendAdjustmentRanges = function (onCompleteCallback) {
25892516
let nextFunction = send_next_adjustment_range;

src/js/tabs/onboard_logging.js

Lines changed: 43 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -489,49 +489,50 @@ onboard_logging.initialize = function (callback) {
489489

490490
show_saving_dialog();
491491

492-
function onChunkRead(chunkAddress, chunkDataView, bytesCompressed) {
493-
if (chunkDataView !== null) {
494-
// Did we receive any data?
495-
if (chunkDataView.byteLength > 0) {
496-
nextAddress += chunkDataView.byteLength;
497-
if (isNaN(bytesCompressed) || isNaN(totalBytesCompressed)) {
498-
totalBytesCompressed = null;
499-
} else {
500-
totalBytesCompressed += bytesCompressed;
501-
}
502-
503-
$(".dataflash-saving progress").attr("value", (nextAddress / maxBytes) * 100);
504-
505-
const blob = new Blob([chunkDataView]);
506-
FileSystem.writeChunck(openedFile, blob).then(() => {
507-
if (saveCancelled || nextAddress >= maxBytes) {
508-
if (saveCancelled) {
509-
dismiss_saving_dialog();
510-
} else {
511-
mark_saving_dialog_done(startTime, nextAddress, totalBytesCompressed);
512-
}
513-
FileSystem.closeFile(openedFile);
514-
} else {
515-
if (!self.writeError) {
516-
mspHelper.dataflashRead(nextAddress, self.blockSize, onChunkRead);
517-
} else {
518-
dismiss_saving_dialog();
519-
FileSystem.closeFile(openedFile);
520-
}
521-
}
522-
});
523-
} else {
524-
// A zero-byte block indicates end-of-file, so we're done
525-
mark_saving_dialog_done(startTime, nextAddress, totalBytesCompressed);
526-
FileSystem.closeFile(openedFile);
527-
}
528-
} else {
529-
// There was an error with the received block (address didn't match the one we asked for), retry
530-
mspHelper.dataflashRead(nextAddress, self.blockSize, onChunkRead);
531-
}
532-
}
492+
function onChunkRead(chunkAddress, chunkDataView, bytesCompressed) {
493+
if (chunkDataView && chunkDataView.byteLength > 0) {
494+
// Always write non-empty data, even if CRC mismatch
495+
const blob = new Blob([chunkDataView]);
496+
FileSystem.writeChunck(openedFile, blob);
497+
498+
nextAddress += chunkDataView.byteLength;
499+
500+
// Track total compressed bytes, if provided
501+
if (typeof bytesCompressed === "number") {
502+
if (totalBytesCompressed == null) totalBytesCompressed = 0; // initialize if previously unknown
503+
totalBytesCompressed += bytesCompressed;
504+
}
505+
506+
$(".dataflash-saving progress").attr("value", (nextAddress / maxBytes) * 100);
507+
508+
if (saveCancelled || nextAddress >= maxBytes) {
509+
mark_saving_dialog_done(startTime, nextAddress, totalBytesCompressed);
510+
FileSystem.closeFile(openedFile);
511+
} else {
512+
mspHelper.dataflashRead(nextAddress, self.blockSize, onChunkRead);
513+
}
514+
515+
} else if (chunkDataView && chunkDataView.byteLength === 0) {
516+
// Zero-length block → EOF
517+
mark_saving_dialog_done(startTime, nextAddress, totalBytesCompressed);
518+
FileSystem.closeFile(openedFile);
519+
520+
} else {
521+
// Null block → skip ahead (hard error)
522+
console.warn(`Skipping null block at address ${nextAddress}`);
523+
nextAddress += self.blockSize;
524+
525+
if (nextAddress >= maxBytes) {
526+
mark_saving_dialog_done(startTime, nextAddress, totalBytesCompressed);
527+
FileSystem.closeFile(openedFile);
528+
} else {
529+
mspHelper.dataflashRead(nextAddress, self.blockSize, onChunkRead);
530+
}
531+
}
532+
}
533+
534+
const startTime = new Date().getTime(); // Start timestamp
533535

534-
const startTime = new Date().getTime();
535536
// Fetch the initial block
536537
FileSystem.openFile(fileWriter).then((file) => {
537538
openedFile = file;

0 commit comments

Comments
 (0)