mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 08:15:30 +03:00
whitespace trimming run
This commit is contained in:
parent
0607ccbff4
commit
9b29f78e3e
44 changed files with 1208 additions and 1208 deletions
|
@ -17,27 +17,27 @@ function configuration_backup() {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
var backup = function() {
|
||||
var chosenFileEntry = null;
|
||||
|
||||
|
||||
var accepts = [{
|
||||
extensions: ['txt']
|
||||
}];
|
||||
|
||||
|
||||
// generate timestamp for the backup file
|
||||
var d = new Date();
|
||||
var now = d.getUTCFullYear() + '.' + d.getDate() + '.' + (d.getMonth() + 1) + '.' + d.getHours() + '.' + d.getMinutes();
|
||||
var now = d.getUTCFullYear() + '.' + d.getDate() + '.' + (d.getMonth() + 1) + '.' + d.getHours() + '.' + d.getMinutes();
|
||||
|
||||
// create or load the file
|
||||
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: 'bf_mw_backup_' + now, accepts: accepts}, function(fileEntry) {
|
||||
if (!fileEntry) {
|
||||
console.log('No file selected, backup aborted.');
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
chosenFileEntry = fileEntry;
|
||||
|
||||
chosenFileEntry = fileEntry;
|
||||
|
||||
// echo/console log path specified
|
||||
chrome.fileSystem.getDisplayPath(chosenFileEntry, function(path) {
|
||||
|
@ -50,7 +50,7 @@ function configuration_backup() {
|
|||
chrome.fileSystem.isWritableEntry(fileEntryWritable, function(isWritable) {
|
||||
if (isWritable) {
|
||||
chosenFileEntry = fileEntryWritable;
|
||||
|
||||
|
||||
// create config object that will be used to store all downloaded data
|
||||
var configuration = {
|
||||
'firmware_version': CONFIG.version,
|
||||
|
@ -61,29 +61,29 @@ function configuration_backup() {
|
|||
'AccelTrim': CONFIG.accelerometerTrims,
|
||||
'MISC': MISC
|
||||
};
|
||||
|
||||
|
||||
// crunch the config object
|
||||
var serialized_config_object = JSON.stringify(configuration);
|
||||
var blob = new Blob([serialized_config_object], {type: 'text/plain'}); // first parameter for Blob needs to be an array
|
||||
|
||||
|
||||
chosenFileEntry.createWriter(function(writer) {
|
||||
writer.onerror = function (e) {
|
||||
console.error(e);
|
||||
};
|
||||
|
||||
|
||||
var truncated = false;
|
||||
writer.onwriteend = function() {
|
||||
if (!truncated) {
|
||||
// onwriteend will be fired again when truncation is finished
|
||||
truncated = true;
|
||||
writer.truncate(blob.size);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
console.log('Write SUCCESSFUL');
|
||||
};
|
||||
|
||||
|
||||
writer.write(blob);
|
||||
}, function (e) {
|
||||
console.error(e);
|
||||
|
@ -100,25 +100,25 @@ function configuration_backup() {
|
|||
|
||||
function configuration_restore() {
|
||||
var chosenFileEntry = null;
|
||||
|
||||
|
||||
var accepts = [{
|
||||
extensions: ['txt']
|
||||
}];
|
||||
|
||||
|
||||
// load up the file
|
||||
chrome.fileSystem.chooseEntry({type: 'openFile', accepts: accepts}, function(fileEntry) {
|
||||
if (!fileEntry) {
|
||||
console.log('No file selected, restore aborted.');
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
chosenFileEntry = fileEntry;
|
||||
|
||||
|
||||
chosenFileEntry = fileEntry;
|
||||
|
||||
// echo/console log path specified
|
||||
chrome.fileSystem.getDisplayPath(chosenFileEntry, function(path) {
|
||||
console.log('Restore file path: ' + path);
|
||||
});
|
||||
});
|
||||
|
||||
// read contents into variable
|
||||
chosenFileEntry.file(function(file) {
|
||||
|
@ -131,31 +131,31 @@ function configuration_restore() {
|
|||
reader.abort();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
reader.onloadend = function(e) {
|
||||
if (e.total != 0 && e.total == e.loaded) {
|
||||
console.log('Read SUCCESSFUL');
|
||||
|
||||
|
||||
try { // check if string provided is a valid JSON
|
||||
var deserialized_configuration_object = JSON.parse(e.target.result);
|
||||
} catch (e) {
|
||||
// data provided != valid json object
|
||||
console.log('Data provided != valid JSON string, restore aborted.');
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// replacing "old configuration" with configuration from backup file
|
||||
var configuration = deserialized_configuration_object;
|
||||
|
||||
|
||||
// some configuration.VERSION code goes here? will see
|
||||
|
||||
|
||||
PIDs = configuration.PID;
|
||||
AUX_CONFIG_values = configuration.AUX_val;
|
||||
RC_tuning = configuration.RC;
|
||||
CONFIG.accelerometerTrims = configuration.AccelTrim;
|
||||
MISC = configuration.MISC;
|
||||
|
||||
|
||||
// all of the arrays/objects are set, upload changes
|
||||
configuration_upload();
|
||||
}
|
||||
|
@ -177,11 +177,11 @@ function configuration_upload() {
|
|||
var PID_buffer_needle = 0;
|
||||
for (var i = 0; i < PIDs.length; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 7:
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
PID_buffer_out[PID_buffer_needle] = parseInt(PIDs[i][0] * 10);
|
||||
|
@ -193,20 +193,20 @@ function configuration_upload() {
|
|||
PID_buffer_out[PID_buffer_needle + 1] = parseInt(PIDs[i][1] * 100);
|
||||
PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2]);
|
||||
break;
|
||||
case 5:
|
||||
case 5:
|
||||
case 6:
|
||||
PID_buffer_out[PID_buffer_needle] = parseInt(PIDs[i][0] * 10);
|
||||
PID_buffer_out[PID_buffer_needle + 1] = parseInt(PIDs[i][1] * 100);
|
||||
PID_buffer_out[PID_buffer_needle + 2] = parseInt(PIDs[i][2] * 1000);
|
||||
break;
|
||||
break;
|
||||
}
|
||||
PID_buffer_needle += 3;
|
||||
}
|
||||
|
||||
|
||||
// Send over the PID changes
|
||||
send_message(MSP_codes.MSP_SET_PID, PID_buffer_out, false, function() {
|
||||
rc_tuning();
|
||||
});
|
||||
});
|
||||
|
||||
var rc_tuning = function() {
|
||||
// RC Tuning section
|
||||
|
@ -218,23 +218,23 @@ function configuration_upload() {
|
|||
RC_tuning_buffer_out[4] = parseInt(RC_tuning.dynamic_THR_PID * 100);
|
||||
RC_tuning_buffer_out[5] = parseInt(RC_tuning.throttle_MID * 100);
|
||||
RC_tuning_buffer_out[6] = parseInt(RC_tuning.throttle_EXPO * 100);
|
||||
|
||||
|
||||
// Send over the RC_tuning changes
|
||||
send_message(MSP_codes.MSP_SET_RC_TUNING, RC_tuning_buffer_out, false, function() {
|
||||
aux();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
var aux = function() {
|
||||
// AUX section
|
||||
var AUX_val_buffer_out = new Array();
|
||||
|
||||
|
||||
var needle = 0;
|
||||
for (var i = 0; i < AUX_CONFIG_values.length; i++) {
|
||||
AUX_val_buffer_out[needle++] = lowByte(AUX_CONFIG_values[i]);
|
||||
AUX_val_buffer_out[needle++] = highByte(AUX_CONFIG_values[i]);
|
||||
}
|
||||
|
||||
|
||||
// Send over the AUX changes
|
||||
send_message(MSP_codes.MSP_SET_BOX, AUX_val_buffer_out, false, function() {
|
||||
trim();
|
||||
|
@ -248,7 +248,7 @@ function configuration_upload() {
|
|||
buffer_out[0] = lowByte(CONFIG.accelerometerTrims[0]);
|
||||
buffer_out[1] = highByte(CONFIG.accelerometerTrims[0]);
|
||||
buffer_out[2] = lowByte(CONFIG.accelerometerTrims[1]);
|
||||
buffer_out[3] = highByte(CONFIG.accelerometerTrims[1]);
|
||||
buffer_out[3] = highByte(CONFIG.accelerometerTrims[1]);
|
||||
|
||||
// Send over the new trims
|
||||
send_message(MSP_codes.MSP_SET_ACC_TRIM, buffer_out, false, function() {
|
||||
|
@ -282,7 +282,7 @@ function configuration_upload() {
|
|||
buffer_out[19] = MISC.vbatmincellvoltage;
|
||||
buffer_out[20] = MISC.vbatmaxcellvoltage;
|
||||
buffer_out[21] = 0; // vbatlevel_crit (unused)
|
||||
|
||||
|
||||
// Send ove the new MISC
|
||||
send_message(MSP_codes.MSP_SET_MISC, buffer_out, false, function() {
|
||||
// Save changes to EEPROM
|
||||
|
@ -290,5 +290,5 @@ function configuration_upload() {
|
|||
GUI.log('EEPROM <span style="color: green">saved</span>');
|
||||
});
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
|
@ -10,7 +10,7 @@ var CONFIG = {
|
|||
activeSensors: 0,
|
||||
mode: 0,
|
||||
profile: 0,
|
||||
|
||||
|
||||
uid: [0, 0, 0],
|
||||
accelerometerTrims: [0, 0]
|
||||
};
|
||||
|
@ -71,7 +71,7 @@ var GPS_DATA = {
|
|||
distanceToHome: 0,
|
||||
ditectionToHome: 0,
|
||||
update: 0,
|
||||
|
||||
|
||||
// baseflight specific gps stuff
|
||||
chn: new Array(),
|
||||
svid: new Array(),
|
||||
|
|
104
js/gui.js
104
js/gui.js
|
@ -6,7 +6,7 @@ var GUI_control = function() {
|
|||
this.operating_system;
|
||||
this.interval_array = [];
|
||||
this.timeout_array = [];
|
||||
|
||||
|
||||
// check which operating system is user running
|
||||
if (navigator.appVersion.indexOf("Win") != -1) this.operating_system = "Windows";
|
||||
else if (navigator.appVersion.indexOf("Mac") != -1) this.operating_system = "MacOS";
|
||||
|
@ -23,19 +23,19 @@ var GUI_control = function() {
|
|||
// first = true/false if code should be ran initially before next timer interval hits
|
||||
GUI_control.prototype.interval_add = function(name, code, interval, first) {
|
||||
var data = {'name': name, 'timer': undefined, 'code': code, 'interval': interval, 'fired': 0, 'paused': false};
|
||||
|
||||
|
||||
if (first == true) {
|
||||
code(); // execute code
|
||||
|
||||
|
||||
data.fired++; // increment counter
|
||||
}
|
||||
|
||||
|
||||
data.timer = setInterval(function() {
|
||||
code(); // execute code
|
||||
|
||||
|
||||
data.fired++; // increment counter
|
||||
}, interval);
|
||||
|
||||
|
||||
this.interval_array.push(data); // push to primary interval array
|
||||
};
|
||||
|
||||
|
@ -44,13 +44,13 @@ GUI_control.prototype.interval_remove = function(name) {
|
|||
for (var i = 0; i < this.interval_array.length; i++) {
|
||||
if (this.interval_array[i].name == name) {
|
||||
clearInterval(this.interval_array[i].timer); // stop timer
|
||||
|
||||
|
||||
this.interval_array.splice(i, 1); // remove element/object from array
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -60,11 +60,11 @@ GUI_control.prototype.interval_pause = function(name) {
|
|||
if (this.interval_array[i].name == name) {
|
||||
clearInterval(this.interval_array[i].timer);
|
||||
this.interval_array[i].paused = true;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -73,19 +73,19 @@ GUI_control.prototype.interval_resume = function(name) {
|
|||
for (var i = 0; i < this.interval_array.length; i++) {
|
||||
if (this.interval_array[i].name == name && this.interval_array[i].paused) {
|
||||
var obj = this.interval_array[i];
|
||||
|
||||
|
||||
obj.timer = setInterval(function() {
|
||||
obj.code(); // execute code
|
||||
|
||||
|
||||
obj.fired++; // increment counter
|
||||
}, obj.interval);
|
||||
|
||||
|
||||
obj.paused = false;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -94,7 +94,7 @@ GUI_control.prototype.interval_resume = function(name) {
|
|||
GUI_control.prototype.interval_kill_all = function(keep_array) {
|
||||
var self = this;
|
||||
var timers_killed = 0;
|
||||
|
||||
|
||||
for (var i = (this.interval_array.length - 1); i >= 0; i--) { // reverse iteration
|
||||
var keep = false;
|
||||
if (keep_array) { // only run through the array if it exists
|
||||
|
@ -104,17 +104,17 @@ GUI_control.prototype.interval_kill_all = function(keep_array) {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (!keep) {
|
||||
clearInterval(this.interval_array[i].timer); // stop timer
|
||||
this.interval_array[i].timer = undefined; // set timer property to undefined (mostly for debug purposes, but it doesn't hurt to have it here)
|
||||
|
||||
|
||||
this.interval_array.splice(i, 1); // remove element/object from array
|
||||
|
||||
|
||||
timers_killed++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return timers_killed;
|
||||
};
|
||||
|
||||
|
@ -126,10 +126,10 @@ GUI_control.prototype.timeout_add = function(name, code, timeout) {
|
|||
// start timer with "cleaning" callback
|
||||
var timer = setTimeout(function() {
|
||||
code(); // execute code
|
||||
|
||||
|
||||
self.timeout_remove(name); // cleanup
|
||||
}, timeout);
|
||||
|
||||
|
||||
this.timeout_array.push({'name': name, 'timer': timer, 'timeout': timeout}); // push to primary timeout array
|
||||
};
|
||||
|
||||
|
@ -138,13 +138,13 @@ GUI_control.prototype.timeout_remove = function(name) {
|
|||
for (var i = 0; i < this.timeout_array.length; i++) {
|
||||
if (this.timeout_array[i].name == name) {
|
||||
clearTimeout(this.timeout_array[i].timer); // stop timer
|
||||
|
||||
|
||||
this.timeout_array.splice(i, 1); // remove element/object from array
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -152,15 +152,15 @@ GUI_control.prototype.timeout_remove = function(name) {
|
|||
// return = returns timers killed in last call
|
||||
GUI_control.prototype.timeout_kill_all = function() {
|
||||
var timers_killed = 0;
|
||||
|
||||
|
||||
for (var i = 0; i < this.timeout_array.length; i++) {
|
||||
clearTimeout(this.timeout_array[i].timer); // stop timer
|
||||
|
||||
|
||||
timers_killed++;
|
||||
}
|
||||
|
||||
|
||||
this.timeout_array = []; // drop objects
|
||||
|
||||
|
||||
return timers_killed;
|
||||
};
|
||||
|
||||
|
@ -168,12 +168,12 @@ GUI_control.prototype.timeout_kill_all = function() {
|
|||
GUI_control.prototype.log = function(message) {
|
||||
var command_log = $('div#log');
|
||||
var d = new Date();
|
||||
var time = ((d.getHours() < 10) ? '0' + d.getHours(): d.getHours())
|
||||
+ ':' + ((d.getMinutes() < 10) ? '0' + d.getMinutes(): d.getMinutes())
|
||||
var time = ((d.getHours() < 10) ? '0' + d.getHours(): d.getHours())
|
||||
+ ':' + ((d.getMinutes() < 10) ? '0' + d.getMinutes(): d.getMinutes())
|
||||
+ ':' + ((d.getSeconds() < 10) ? '0' + d.getSeconds(): d.getSeconds());
|
||||
|
||||
|
||||
$('div.wrapper', command_log).append('<p>' + time + ' -- ' + message + '</p>');
|
||||
command_log.scrollTop($('div.wrapper', command_log).height());
|
||||
command_log.scrollTop($('div.wrapper', command_log).height());
|
||||
};
|
||||
|
||||
// Method is called every time a valid tab change event is received
|
||||
|
@ -181,56 +181,56 @@ GUI_control.prototype.log = function(message) {
|
|||
// default switch doesn't require callback to be set
|
||||
GUI_control.prototype.tab_switch_cleanup = function(callback) {
|
||||
MSP.callbacks_cleanup(); // we don't care about any old data that might or might not arrive
|
||||
|
||||
|
||||
switch (this.active_tab) {
|
||||
case 'initial_setup':
|
||||
GUI.interval_remove('initial_setup_data_pull');
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
break;
|
||||
case 'pid_tuning':
|
||||
GUI.interval_remove('pid_data_poll');
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
break;
|
||||
case 'receiver':
|
||||
GUI.interval_remove('receiver_poll');
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
break;
|
||||
case 'auxiliary_configuration':
|
||||
GUI.interval_remove('aux_data_poll');
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
break;
|
||||
case 'servos':
|
||||
GUI.interval_remove('servos_data_poll');
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
break;
|
||||
case 'gps':
|
||||
GUI.interval_remove('gps_pull');
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
break;
|
||||
case 'motor_outputs':
|
||||
GUI.interval_remove('motor_poll');
|
||||
|
||||
|
||||
// only enforce mincommand if necessary
|
||||
if (MOTOR_DATA != undefined) {
|
||||
var update = false;
|
||||
|
||||
|
||||
for (var i = 0; i < MOTOR_DATA.length; i++) {
|
||||
if (MOTOR_DATA[i] > MISC.mincommand) {
|
||||
update = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (update) {
|
||||
// send data to mcu
|
||||
var buffer_out = [];
|
||||
|
||||
|
||||
for (var i = 0; i < 8; i++) {
|
||||
buffer_out.push(lowByte(MISC.mincommand));
|
||||
buffer_out.push(highByte(MISC.mincommand));
|
||||
|
@ -249,17 +249,17 @@ GUI_control.prototype.tab_switch_cleanup = function(callback) {
|
|||
case 'sensors':
|
||||
GUI.interval_kill_all(['port_usage']);
|
||||
serial.empty_output_buffer();
|
||||
|
||||
|
||||
// sensor data tab uses scrollbars, emptying the content before loading another tab
|
||||
// prevents scrollbar exposure to any of the tabs while new content is loaded in
|
||||
$('#content').empty();
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
break;
|
||||
case 'cli':
|
||||
var bufferOut = new ArrayBuffer(5);
|
||||
var bufView = new Uint8Array(bufferOut);
|
||||
|
||||
|
||||
bufView[0] = 0x65; // e
|
||||
bufView[1] = 0x78; // x
|
||||
bufView[2] = 0x69; // i
|
||||
|
@ -274,18 +274,18 @@ GUI_control.prototype.tab_switch_cleanup = function(callback) {
|
|||
GUI.timeout_add('waiting_for_bootup', function() {
|
||||
CLI_active = false;
|
||||
CLI_valid = false;
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
}, 5000); // if we dont allow enough time to reboot, CRC of "first" command sent will fail, keep an eye for this one
|
||||
});
|
||||
break;
|
||||
|
||||
|
||||
case 'firmware_flasher':
|
||||
PortHandler.flush_callbacks();
|
||||
|
||||
|
||||
if (callback) callback();
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
if (callback) callback();
|
||||
}
|
||||
|
|
188
js/msp.js
188
js/msp.js
|
@ -21,7 +21,7 @@ var MSP_codes = {
|
|||
MSP_WP: 118,
|
||||
MSP_BOXIDS: 119,
|
||||
MSP_SERVO_CONF: 120,
|
||||
|
||||
|
||||
MSP_SET_RAW_RC: 200,
|
||||
MSP_SET_RAW_GPS: 201,
|
||||
MSP_SET_PID: 202,
|
||||
|
@ -36,14 +36,14 @@ var MSP_codes = {
|
|||
MSP_SET_HEAD: 211,
|
||||
MSP_SET_SERVO_CONF: 212,
|
||||
MSP_SET_MOTOR: 214,
|
||||
|
||||
|
||||
// MSP_BIND: 240,
|
||||
|
||||
|
||||
MSP_EEPROM_WRITE: 250,
|
||||
|
||||
|
||||
MSP_DEBUGMSG: 253,
|
||||
MSP_DEBUG: 254,
|
||||
|
||||
|
||||
// Additional baseflight commands that are not compatible with MultiWii
|
||||
MSP_UID: 160, // Unique device ID
|
||||
MSP_ACC_TRIM: 240, // get acc angle trim values
|
||||
|
@ -63,29 +63,29 @@ var MSP = {
|
|||
message_buffer: undefined,
|
||||
message_buffer_uint8_view: undefined,
|
||||
message_checksum: 0,
|
||||
|
||||
|
||||
callbacks: [],
|
||||
packet_error: 0,
|
||||
|
||||
|
||||
callbacks_cleanup: function() {
|
||||
for (var i = 0; i < this.callbacks.length; i++) {
|
||||
clearInterval(this.callbacks[i].timer);
|
||||
}
|
||||
|
||||
|
||||
this.callbacks = [];
|
||||
},
|
||||
|
||||
|
||||
disconnect_cleanup: function() {
|
||||
this.state = 0; // reset packet state for "clean" initial entry (this is only required if user hot-disconnects)
|
||||
this.packet_error = 0; // reset CRC packet error counter for next session
|
||||
|
||||
|
||||
this.callbacks_cleanup();
|
||||
}
|
||||
};
|
||||
|
||||
MSP.read = function(readInfo) {
|
||||
var data = new Uint8Array(readInfo.data);
|
||||
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
switch (this.state) {
|
||||
case 0: // sync char 1
|
||||
|
@ -106,24 +106,24 @@ MSP.read = function(readInfo) {
|
|||
} else { // unknown
|
||||
message_status = 0;
|
||||
}
|
||||
|
||||
|
||||
this.state++;
|
||||
break;
|
||||
case 3:
|
||||
this.message_length_expected = data[i];
|
||||
|
||||
|
||||
this.message_checksum = data[i];
|
||||
|
||||
|
||||
// setup arraybuffer
|
||||
this.message_buffer = new ArrayBuffer(this.message_length_expected);
|
||||
this.message_buffer_uint8_view = new Uint8Array(this.message_buffer);
|
||||
|
||||
|
||||
this.state++;
|
||||
break;
|
||||
case 4:
|
||||
this.code = data[i];
|
||||
this.message_checksum ^= data[i];
|
||||
|
||||
|
||||
if (this.message_length_expected != 0) { // standard message
|
||||
this.state++;
|
||||
} else { // MSP_ACC_CALIBRATION, etc...
|
||||
|
@ -134,7 +134,7 @@ MSP.read = function(readInfo) {
|
|||
this.message_buffer_uint8_view[this.message_length_received] = data[i];
|
||||
this.message_checksum ^= data[i];
|
||||
this.message_length_received++;
|
||||
|
||||
|
||||
if (this.message_length_received >= this.message_length_expected) {
|
||||
this.state++;
|
||||
}
|
||||
|
@ -145,24 +145,24 @@ MSP.read = function(readInfo) {
|
|||
this.process_data(this.code, this.message_buffer, this.message_length_expected);
|
||||
} else {
|
||||
console.log('code: ' + this.code + ' - crc failed');
|
||||
|
||||
|
||||
this.packet_error++;
|
||||
$('span.packet-error').html(this.packet_error);
|
||||
}
|
||||
|
||||
|
||||
// Reset variables
|
||||
this.message_length_received = 0;
|
||||
this.state = 0;
|
||||
this.state = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
char_counter++;
|
||||
}
|
||||
};
|
||||
|
||||
MSP.process_data = function(code, message_buffer, message_length) {
|
||||
var data = new DataView(message_buffer, 0); // DataView (allowing us to view arrayBuffer as struct/union)
|
||||
|
||||
|
||||
switch (code) {
|
||||
case MSP_codes.MSP_IDENT:
|
||||
CONFIG.version = parseFloat((data.getUint8(0) / 100).toFixed(2));
|
||||
|
@ -176,7 +176,7 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
CONFIG.activeSensors = data.getUint16(4, 1);
|
||||
CONFIG.mode = data.getUint32(6, 1);
|
||||
CONFIG.profile = data.getUint8(10);
|
||||
|
||||
|
||||
sensor_status(CONFIG.activeSensors);
|
||||
$('span.cycle-time').html(CONFIG.cycleTime);
|
||||
break;
|
||||
|
@ -186,7 +186,7 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
SENSOR_DATA.accelerometer[0] = data.getInt16(0, 1) / 512;
|
||||
SENSOR_DATA.accelerometer[1] = data.getInt16(2, 1) / 512;
|
||||
SENSOR_DATA.accelerometer[2] = data.getInt16(4, 1) / 512;
|
||||
|
||||
|
||||
// properly scaled
|
||||
SENSOR_DATA.gyroscope[0] = data.getInt16(6, 1) * (4 / 16.4);
|
||||
SENSOR_DATA.gyroscope[1] = data.getInt16(8, 1) * (4 / 16.4);
|
||||
|
@ -201,29 +201,29 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
var needle = 0;
|
||||
for (var i = 0; i < 8; i++) {
|
||||
SERVO_DATA[i] = data.getUint16(needle, 1);
|
||||
|
||||
|
||||
needle += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MSP_codes.MSP_MOTOR:
|
||||
var needle = 0;
|
||||
for (var i = 0; i < 8; i++) {
|
||||
MOTOR_DATA[i] = data.getUint16(needle, 1);
|
||||
|
||||
|
||||
needle += 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MSP_codes.MSP_RC:
|
||||
RC.roll = data.getUint16(0, 1);
|
||||
RC.pitch = data.getUint16(2, 1);
|
||||
RC.yaw = data.getUint16(4, 1);
|
||||
RC.throttle = data.getUint16(6, 1);
|
||||
|
||||
|
||||
RC.AUX1 = data.getUint16(8, 1);
|
||||
RC.AUX2 = data.getUint16(10, 1);
|
||||
RC.AUX3 = data.getUint16(12, 1);
|
||||
RC.AUX4 = data.getUint16(14, 1);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_RAW_GPS:
|
||||
GPS_DATA.fix = data.getUint8(0);
|
||||
GPS_DATA.numSat = data.getUint8(1);
|
||||
|
@ -232,26 +232,26 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
GPS_DATA.alt = data.getUint16(10, 1);
|
||||
GPS_DATA.speed = data.getUint16(12, 1);
|
||||
GPS_DATA.ground_course = data.getUint16(14, 1);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_COMP_GPS:
|
||||
GPS_DATA.distanceToHome = data.getUint16(0, 1);
|
||||
GPS_DATA.directionToHome = data.getUint16(2, 1);
|
||||
GPS_DATA.update = data.getUint8(4);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_ATTITUDE:
|
||||
SENSOR_DATA.kinematicsX = data.getInt16(0, 1) / 10.0;
|
||||
SENSOR_DATA.kinematicsY = data.getInt16(2, 1) / 10.0;
|
||||
SENSOR_DATA.kinematicsZ = data.getInt16(4, 1);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_ALTITUDE:
|
||||
SENSOR_DATA.altitude = parseFloat((data.getInt32(0, 1) / 100.0).toFixed(2)); // correct scale factor
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_ANALOG:
|
||||
ANALOG.voltage = data.getUint8(0) / 10.0;
|
||||
ANALOG.power = data.getUint16(1, 1);
|
||||
ANALOG.rssi = data.getUint16(3, 1);
|
||||
ANALOG.amperage = data.getUint16(5, 1);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_RC_TUNING:
|
||||
RC_tuning.RC_RATE = parseFloat((data.getUint8(0) / 100).toFixed(2));
|
||||
RC_tuning.RC_EXPO = parseFloat((data.getUint8(1) / 100).toFixed(2));
|
||||
|
@ -260,17 +260,17 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
RC_tuning.dynamic_THR_PID = parseFloat((data.getUint8(4) / 100).toFixed(2));
|
||||
RC_tuning.throttle_MID = parseFloat((data.getUint8(5) / 100).toFixed(2));
|
||||
RC_tuning.throttle_EXPO = parseFloat((data.getUint8(6) / 100).toFixed(2));
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_PID:
|
||||
// PID data arrived, we need to scale it and save to appropriate bank / array
|
||||
for (var i = 0, needle = 0; i < (message_length / 3); i++, needle += 3) {
|
||||
// main for loop selecting the pid section
|
||||
// main for loop selecting the pid section
|
||||
switch (i) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 7:
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
case 3:
|
||||
case 7:
|
||||
case 8:
|
||||
case 9:
|
||||
PIDs[i][0] = data.getUint8(needle) / 10;
|
||||
|
@ -282,24 +282,24 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
PIDs[i][1] = data.getUint8(needle + 1) / 100;
|
||||
PIDs[i][2] = data.getUint8(needle + 2) / 1000;
|
||||
break;
|
||||
case 5:
|
||||
case 5:
|
||||
case 6:
|
||||
PIDs[i][0] = data.getUint8(needle) / 10;
|
||||
PIDs[i][1] = data.getUint8(needle + 1) / 100;
|
||||
PIDs[i][2] = data.getUint8(needle + 2) / 1000;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_BOX:
|
||||
// dump previous data (if there was any)
|
||||
AUX_CONFIG_values = new Array();
|
||||
|
||||
|
||||
// fill in current data
|
||||
for (var i = 0; i < data.byteLength; i += 2) { // + 2 because uint16_t = 2 bytes
|
||||
AUX_CONFIG_values.push(data.getUint16(i, 1));
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_MISC: // 22 bytes
|
||||
MISC.PowerTrigger1 = data.getInt16(0, 1);
|
||||
MISC.minthrottle = data.getUint16(2, 1); // 0-2000
|
||||
|
@ -313,29 +313,29 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
MISC.vbatmincellvoltage = data.getUint8(19, 1) / 10; // 10-50
|
||||
MISC.vbatmaxcellvoltage = data.getUint8(20, 1) / 10; // 10-50
|
||||
MISC.empty = data.getUint8(21, 1);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_MOTOR_PINS:
|
||||
console.log(data);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_BOXNAMES:
|
||||
AUX_CONFIG = []; // empty the array as new data is coming in
|
||||
|
||||
|
||||
var buff = new Array();
|
||||
for (var i = 0; i < data.byteLength; i++) {
|
||||
if (data.getUint8(i) == 0x3B) { // ; (delimeter char)
|
||||
AUX_CONFIG.push(String.fromCharCode.apply(null, buff)); // convert bytes into ASCII and save as strings
|
||||
|
||||
|
||||
// empty buffer
|
||||
buff = [];
|
||||
} else {
|
||||
buff.push(data.getUint8(i));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_PIDNAMES:
|
||||
console.log(data);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_WP:
|
||||
console.log(data);
|
||||
break;
|
||||
|
@ -345,43 +345,43 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
case MSP_codes.MSP_SERVO_CONF:
|
||||
// drop previous data
|
||||
SERVO_CONFIG = [];
|
||||
|
||||
|
||||
for (var i = 0; i < 56; i += 7) {
|
||||
var arr = {
|
||||
'min': data.getInt16(i, 1),
|
||||
'max': data.getInt16(i + 2, 1),
|
||||
'middle': data.getInt16(i + 4, 1),
|
||||
'min': data.getInt16(i, 1),
|
||||
'max': data.getInt16(i + 2, 1),
|
||||
'middle': data.getInt16(i + 4, 1),
|
||||
'rate': data.getInt8(i + 6)
|
||||
};
|
||||
|
||||
|
||||
SERVO_CONFIG.push(arr);
|
||||
}
|
||||
break;
|
||||
case MSP_codes.MSP_SET_RAW_RC:
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_SET_RAW_GPS:
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_SET_PID:
|
||||
console.log('PID settings saved');
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_SET_BOX:
|
||||
console.log('AUX Configuration saved');
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_SET_RC_TUNING:
|
||||
console.log('RC Tuning saved');
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_ACC_CALIBRATION:
|
||||
console.log('Accel calibration executed');
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_MAG_CALIBRATION:
|
||||
console.log('Mag calibration executed');
|
||||
break;
|
||||
case MSP_codes.MSP_SET_MISC:
|
||||
console.log('MISC Configuration saved');
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_RESET_CONF:
|
||||
console.log('Settings Reset');
|
||||
|
||||
|
||||
// With new flight software settings in place, we have to re-pull
|
||||
// latest values
|
||||
send_message(MSP_codes.MSP_IDENT, MSP_codes.MSP_IDENT);
|
||||
|
@ -390,22 +390,22 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
send_message(MSP_codes.MSP_RC_TUNING, MSP_codes.MSP_RC_TUNING);
|
||||
send_message(MSP_codes.MSP_BOXNAMES, MSP_codes.MSP_BOXNAMES);
|
||||
send_message(MSP_codes.MSP_BOX, MSP_codes.MSP_BOX);
|
||||
|
||||
|
||||
// baseflight specific
|
||||
send_message(MSP_codes.MSP_UID, MSP_codes.MSP_UID);
|
||||
send_message(MSP_codes.MSP_ACC_TRIM, MSP_codes.MSP_ACC_TRIM);
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_SELECT_SETTING:
|
||||
console.log('Profile selected');
|
||||
break;
|
||||
case MSP_codes.MSP_SET_SERVO_CONF:
|
||||
console.log('Servo Configuration saved');
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_EEPROM_WRITE:
|
||||
console.log('Settings Saved in EEPROM');
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_DEBUGMSG:
|
||||
break;
|
||||
break;
|
||||
case MSP_codes.MSP_DEBUG:
|
||||
for (var i = 0; i < 4; i++)
|
||||
SENSOR_DATA.debug[i] = data.getInt16((2 * i), 1);
|
||||
|
@ -429,39 +429,39 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
case MSP_codes.MSP_GPSSVINFO:
|
||||
if (data.byteLength > 0) {
|
||||
var numCh = data.getUint8(0);
|
||||
|
||||
|
||||
var needle = 1;
|
||||
for (var i = 0; i < numCh; i++) {
|
||||
GPS_DATA.chn[i] = data.getUint8(needle);
|
||||
GPS_DATA.svid[i] = data.getUint8(needle + 1);
|
||||
GPS_DATA.quality[i] = data.getUint8(needle + 2);
|
||||
GPS_DATA.cno[i] = data.getUint8(needle + 3);
|
||||
|
||||
|
||||
needle += 4;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
console.log('Unknown code detected: ' + code);
|
||||
}
|
||||
|
||||
|
||||
// trigger callbacks, cleanup/remove callback after trigger
|
||||
for (var i = (this.callbacks.length - 1); i >= 0; i--) { // itterating in reverse because we use .splice which modifies array length
|
||||
if (this.callbacks[i].code == code) {
|
||||
// saving current obj for after-callback comparison
|
||||
var obj = this.callbacks[i];
|
||||
|
||||
|
||||
// remove timeout
|
||||
clearInterval(obj.timer);
|
||||
|
||||
|
||||
// fire callback
|
||||
if (obj.callback) obj.callback({'command': code, 'data': data, 'length': message_length});
|
||||
|
||||
|
||||
// remove object from array
|
||||
// we need to check if the callback object still exists as it could have been touched/moved/removed in callback routine
|
||||
var index = this.callbacks.indexOf(obj);
|
||||
|
||||
|
||||
if (index > -1) this.callbacks.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
@ -470,26 +470,26 @@ MSP.process_data = function(code, message_buffer, message_length) {
|
|||
function send_message(code, data, callback_sent, callback_msp) {
|
||||
var bufferOut;
|
||||
var bufView;
|
||||
|
||||
|
||||
// always reserve 6 bytes for protocol overhead !
|
||||
if (typeof data === 'object') {
|
||||
var size = data.length + 6;
|
||||
var checksum = 0;
|
||||
|
||||
|
||||
bufferOut = new ArrayBuffer(size);
|
||||
bufView = new Uint8Array(bufferOut);
|
||||
|
||||
bufView = new Uint8Array(bufferOut);
|
||||
|
||||
bufView[0] = 36; // $
|
||||
bufView[1] = 77; // M
|
||||
bufView[2] = 60; // <
|
||||
bufView[3] = data.length;
|
||||
bufView[4] = code;
|
||||
|
||||
|
||||
checksum = bufView[3] ^ bufView[4];
|
||||
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
bufView[i + 5] = data[i];
|
||||
|
||||
|
||||
checksum ^= bufView[i + 5];
|
||||
}
|
||||
|
||||
|
@ -497,7 +497,7 @@ function send_message(code, data, callback_sent, callback_msp) {
|
|||
} else {
|
||||
bufferOut = new ArrayBuffer(7);
|
||||
bufView = new Uint8Array(bufferOut);
|
||||
|
||||
|
||||
bufView[0] = 36; // $
|
||||
bufView[1] = 77; // M
|
||||
bufView[2] = 60; // <
|
||||
|
@ -514,14 +514,14 @@ function send_message(code, data, callback_sent, callback_msp) {
|
|||
return false; // skips the code below
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var obj = {'code': code, 'callback': (callback_msp) ? callback_msp : false};
|
||||
obj.timer = setInterval(function() {
|
||||
console.log('MSP data request timed-out: ' + code);
|
||||
|
||||
|
||||
serial.send(bufferOut, function(writeInfo) {});
|
||||
}, 1000); // we should be able to define timeout in the future
|
||||
|
||||
|
||||
MSP.callbacks.push(obj);
|
||||
|
||||
serial.send(bufferOut, function(writeInfo) {
|
||||
|
@ -529,6 +529,6 @@ function send_message(code, data, callback_sent, callback_msp) {
|
|||
if (callback_sent) callback_sent();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
function port_handler() {
|
||||
this.main_timeout_reference;
|
||||
this.initial_ports = false;
|
||||
|
||||
|
||||
this.port_detected_callbacks = [];
|
||||
this.port_removed_callbacks = [];
|
||||
}
|
||||
|
@ -13,12 +13,12 @@ port_handler.prototype.initialize = function() {
|
|||
|
||||
port_handler.prototype.check = function() {
|
||||
var self = this;
|
||||
|
||||
|
||||
serial.getDevices(function(current_ports) {
|
||||
// port got removed or initial_ports wasn't initialized yet
|
||||
if (self.array_difference(self.initial_ports, current_ports).length > 0 || !self.initial_ports) {
|
||||
var removed_ports = self.array_difference(self.initial_ports, current_ports);
|
||||
|
||||
|
||||
if (self.initial_ports != false) {
|
||||
if (removed_ports.length > 1) {
|
||||
console.log('PortHandler - Removed: ' + removed_ports);
|
||||
|
@ -26,7 +26,7 @@ port_handler.prototype.check = function() {
|
|||
console.log('PortHandler - Removed: ' + removed_ports[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// disconnect "UI" if necessary
|
||||
// Keep in mind that this routine can not fire during atmega32u4 reboot procedure !!!
|
||||
if (GUI.connected_to) {
|
||||
|
@ -36,35 +36,35 @@ port_handler.prototype.check = function() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
self.update_port_select(current_ports);
|
||||
|
||||
|
||||
// trigger callbacks (only after initialization)
|
||||
if (self.initial_ports) {
|
||||
for (var i = (self.port_removed_callbacks.length - 1); i >= 0; i--) {
|
||||
var obj = self.port_removed_callbacks[i];
|
||||
|
||||
|
||||
// remove timeout
|
||||
clearTimeout(obj.timer);
|
||||
|
||||
|
||||
// trigger callback
|
||||
obj.code(removed_ports);
|
||||
|
||||
|
||||
// remove object from array
|
||||
var index = self.port_removed_callbacks.indexOf(obj);
|
||||
if (index > -1) self.port_removed_callbacks.splice(index, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// auto-select last used port (only during initialization)
|
||||
if (!self.initial_ports) {
|
||||
chrome.storage.local.get('last_used_port', function(result) {
|
||||
// if last_used_port was set, we try to select it
|
||||
if (result.last_used_port) {
|
||||
if (result.last_used_port) {
|
||||
current_ports.forEach(function(port) {
|
||||
if (port == result.last_used_port) {
|
||||
console.log('Selecting last used port: ' + result.last_used_port);
|
||||
|
||||
|
||||
$('div#port-picker .port select').val(result.last_used_port);
|
||||
}
|
||||
});
|
||||
|
@ -73,7 +73,7 @@ port_handler.prototype.check = function() {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (!self.initial_ports) {
|
||||
// initialize
|
||||
self.initial_ports = current_ports;
|
||||
|
@ -83,26 +83,26 @@ port_handler.prototype.check = function() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// new port detected
|
||||
var new_ports = self.array_difference(current_ports, self.initial_ports);
|
||||
|
||||
|
||||
if (new_ports.length) {
|
||||
if (new_ports.length > 1) {
|
||||
console.log('PortHandler - Found: ' + new_ports);
|
||||
} else {
|
||||
console.log('PortHandler - Found: ' + new_ports[0]);
|
||||
}
|
||||
|
||||
|
||||
self.update_port_select(current_ports);
|
||||
|
||||
|
||||
// select / highlight new port, if connected -> select connected port
|
||||
if (!GUI.connected_to) {
|
||||
$('div#port-picker .port select').val(new_ports[0]);
|
||||
} else {
|
||||
} else {
|
||||
$('div#port-picker .port select').val(GUI.connected_to);
|
||||
}
|
||||
|
||||
|
||||
// start connect procedure (if statement is valid)
|
||||
if (GUI.auto_connect && !GUI.connecting_to && !GUI.connected_to) {
|
||||
// we need firmware flasher protection over here
|
||||
|
@ -112,25 +112,25 @@ port_handler.prototype.check = function() {
|
|||
}, 50); // small timeout so we won't get any nasty connect errors due to system initializing the bus
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// trigger callbacks
|
||||
for (var i = (self.port_detected_callbacks.length - 1); i >= 0; i--) {
|
||||
var obj = self.port_detected_callbacks[i];
|
||||
|
||||
|
||||
// remove timeout
|
||||
clearTimeout(obj.timer);
|
||||
|
||||
|
||||
// trigger callback
|
||||
obj.code(new_ports);
|
||||
|
||||
|
||||
// remove object from array
|
||||
var index = self.port_detected_callbacks.indexOf(obj);
|
||||
if (index > -1) self.port_detected_callbacks.splice(index, 1);
|
||||
}
|
||||
|
||||
|
||||
self.initial_ports = current_ports;
|
||||
}
|
||||
|
||||
|
||||
self.main_timeout_reference = setTimeout(function() {
|
||||
self.check();
|
||||
}, 250);
|
||||
|
@ -139,27 +139,27 @@ port_handler.prototype.check = function() {
|
|||
|
||||
port_handler.prototype.update_port_select = function(ports) {
|
||||
$('div#port-picker .port select').html(''); // drop previous one
|
||||
|
||||
|
||||
if (ports.length > 0) {
|
||||
for (var i = 0; i < ports.length; i++) {
|
||||
$('div#port-picker .port select').append($("<option/>", {value: ports[i], text: ports[i]}));
|
||||
}
|
||||
} else {
|
||||
$('div#port-picker .port select').append($("<option/>", {value: 0, text: 'No Ports'}));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
port_handler.prototype.port_detected = function(name, code, timeout, ignore_timeout) {
|
||||
var self = this;
|
||||
var obj = {'name': name, 'code': code, 'timeout': (timeout) ? timeout : 10000};
|
||||
|
||||
|
||||
if (!ignore_timeout) {
|
||||
obj.timer = setTimeout(function() {
|
||||
console.log('PortHandler - timeout - ' + obj.name);
|
||||
|
||||
|
||||
// trigger callback
|
||||
code(false);
|
||||
|
||||
|
||||
// remove object from array
|
||||
var index = self.port_detected_callbacks.indexOf(obj);
|
||||
if (index > -1) self.port_detected_callbacks.splice(index, 1);
|
||||
|
@ -168,7 +168,7 @@ port_handler.prototype.port_detected = function(name, code, timeout, ignore_time
|
|||
obj.timer = false;
|
||||
obj.timeout = false;
|
||||
}
|
||||
|
||||
|
||||
this.port_detected_callbacks.push(obj);
|
||||
|
||||
return obj;
|
||||
|
@ -177,14 +177,14 @@ port_handler.prototype.port_detected = function(name, code, timeout, ignore_time
|
|||
port_handler.prototype.port_removed = function(name, code, timeout, ignore_timeout) {
|
||||
var self = this;
|
||||
var obj = {'name': name, 'code': code, 'timeout': (timeout) ? timeout : 10000};
|
||||
|
||||
|
||||
if (!ignore_timeout) {
|
||||
obj.timer = setTimeout(function() {
|
||||
console.log('PortHandler - timeout - ' + obj.name);
|
||||
|
||||
|
||||
// trigger callback
|
||||
code(false);
|
||||
|
||||
|
||||
// remove object from array
|
||||
var index = self.port_removed_callbacks.indexOf(obj);
|
||||
if (index > -1) self.port_removed_callbacks.splice(index, 1);
|
||||
|
@ -193,44 +193,44 @@ port_handler.prototype.port_removed = function(name, code, timeout, ignore_timeo
|
|||
obj.timer = false;
|
||||
obj.timeout = false;
|
||||
}
|
||||
|
||||
|
||||
this.port_removed_callbacks.push(obj);
|
||||
|
||||
|
||||
return obj;
|
||||
};
|
||||
|
||||
// accepting single level array with "value" as key
|
||||
port_handler.prototype.array_difference = function(firstArray, secondArray) {
|
||||
var cloneArray = [];
|
||||
|
||||
|
||||
// create hardcopy
|
||||
for (var i = 0; i < firstArray.length; i++) {
|
||||
cloneArray.push(firstArray[i]);
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i < secondArray.length; i++) {
|
||||
if (cloneArray.indexOf(secondArray[i]) != -1) {
|
||||
cloneArray.splice(cloneArray.indexOf(secondArray[i]), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return cloneArray;
|
||||
};
|
||||
|
||||
port_handler.prototype.flush_callbacks = function() {
|
||||
var killed = 0;
|
||||
|
||||
for (var i = this.port_detected_callbacks.length - 1; i >= 0; i--) {
|
||||
|
||||
for (var i = this.port_detected_callbacks.length - 1; i >= 0; i--) {
|
||||
if (this.port_detected_callbacks[i].timer) clearTimeout(this.port_detected_callbacks[i].timer);
|
||||
this.port_detected_callbacks.splice(i, 1);
|
||||
|
||||
|
||||
killed++;
|
||||
}
|
||||
|
||||
|
||||
for (var i = this.port_removed_callbacks.length - 1; i >= 0; i--) {
|
||||
if (this.port_removed_callbacks[i].timer) clearTimeout(this.port_removed_callbacks[i].timer);
|
||||
this.port_removed_callbacks.splice(i, 1);
|
||||
|
||||
|
||||
killed++;
|
||||
}
|
||||
|
||||
|
|
48
js/serial.js
48
js/serial.js
|
@ -2,25 +2,25 @@ var serial = {
|
|||
connectionId: -1,
|
||||
bytes_received: 0,
|
||||
bytes_sent: 0,
|
||||
|
||||
|
||||
transmitting: false,
|
||||
output_buffer: [],
|
||||
|
||||
|
||||
connect: function(path, options, callback) {
|
||||
var self = this;
|
||||
|
||||
|
||||
chrome.serial.connect(path, options, function(connectionInfo) {
|
||||
if (connectionInfo !== undefined) {
|
||||
self.connectionId = connectionInfo.connectionId;
|
||||
self.bytes_received = 0;
|
||||
self.bytes_sent = 0;
|
||||
|
||||
|
||||
self.onReceive.addListener(function log_bytes_received(info) {
|
||||
self.bytes_received += info.data.byteLength;
|
||||
});
|
||||
|
||||
|
||||
console.log('SERIAL: Connection opened with ID: ' + connectionInfo.connectionId + ', Baud: ' + connectionInfo.bitrate);
|
||||
|
||||
|
||||
callback(connectionInfo);
|
||||
} else {
|
||||
console.log('SERIAL: Failed to open serial port');
|
||||
|
@ -30,25 +30,25 @@ var serial = {
|
|||
},
|
||||
disconnect: function(callback) {
|
||||
var self = this;
|
||||
|
||||
|
||||
self.empty_output_buffer();
|
||||
|
||||
// remove listeners
|
||||
for (var i = (self.onReceive.listeners.length - 1); i >= 0; i--) {
|
||||
self.onReceive.removeListener(self.onReceive.listeners[i]);
|
||||
}
|
||||
|
||||
|
||||
chrome.serial.disconnect(this.connectionId, function(result) {
|
||||
if (result) {
|
||||
console.log('SERIAL: Connection with ID: ' + self.connectionId + ' closed');
|
||||
} else {
|
||||
console.log('SERIAL: Failed to close connection with ID: ' + self.connectionId + ' closed');
|
||||
}
|
||||
|
||||
|
||||
console.log('SERIAL: Statistics - Sent: ' + self.bytes_sent + ' bytes, Received: ' + self.bytes_received + ' bytes');
|
||||
|
||||
|
||||
self.connectionId = -1;
|
||||
|
||||
|
||||
callback(result);
|
||||
});
|
||||
},
|
||||
|
@ -58,7 +58,7 @@ var serial = {
|
|||
devices_array.forEach(function(device) {
|
||||
devices.push(device.path);
|
||||
});
|
||||
|
||||
|
||||
callback(devices);
|
||||
});
|
||||
},
|
||||
|
@ -68,54 +68,54 @@ var serial = {
|
|||
send: function(data, callback) {
|
||||
var self = this;
|
||||
self.output_buffer.push({'data': data, 'callback': callback});
|
||||
|
||||
|
||||
if (!self.transmitting) {
|
||||
self.transmitting = true;
|
||||
|
||||
|
||||
var sending = function() {
|
||||
// store inside separate variables in case array gets destroyed
|
||||
var data = self.output_buffer[0].data;
|
||||
var callback = self.output_buffer[0].callback;
|
||||
|
||||
|
||||
chrome.serial.send(self.connectionId, data, function(sendInfo) {
|
||||
callback(sendInfo);
|
||||
self.output_buffer.shift();
|
||||
|
||||
|
||||
self.bytes_sent += sendInfo.bytesSent;
|
||||
|
||||
|
||||
if (self.output_buffer.length) {
|
||||
// keep the buffer withing reasonable limits
|
||||
while (self.output_buffer.length > 500) {
|
||||
self.output_buffer.pop();
|
||||
}
|
||||
|
||||
|
||||
sending();
|
||||
} else {
|
||||
self.transmitting = false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
sending();
|
||||
}
|
||||
},
|
||||
onReceive: {
|
||||
listeners: [],
|
||||
|
||||
|
||||
addListener: function(function_reference) {
|
||||
var listener = chrome.serial.onReceive.addListener(function_reference);
|
||||
|
||||
|
||||
this.listeners.push(function_reference);
|
||||
},
|
||||
removeListener: function(function_reference) {
|
||||
removeListener: function(function_reference) {
|
||||
for (var i = (this.listeners.length - 1); i >= 0; i--) {
|
||||
if (this.listeners[i] == function_reference) {
|
||||
chrome.serial.onReceive.removeListener(function_reference);
|
||||
|
||||
|
||||
this.listeners.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
empty_output_buffer: function() {
|
||||
|
|
|
@ -2,55 +2,55 @@ var configuration_received = false;
|
|||
var CLI_active = false;
|
||||
var CLI_valid = false;
|
||||
|
||||
$(document).ready(function() {
|
||||
$(document).ready(function() {
|
||||
$('div#port-picker a.connect').click(function() {
|
||||
if (GUI.connect_lock != true) { // GUI control overrides the user control
|
||||
var clicks = $(this).data('clicks');
|
||||
|
||||
|
||||
var selected_port = String($('div#port-picker .port select').val());
|
||||
var selected_baud = parseInt($('div#port-picker #baud').val());
|
||||
|
||||
|
||||
if (selected_port != '0') {
|
||||
if (!clicks) {
|
||||
console.log('Connecting to: ' + selected_port);
|
||||
GUI.connecting_to = selected_port;
|
||||
|
||||
|
||||
// lock port select & baud while we are connecting / connected
|
||||
$('div#port-picker #port, div#port-picker #baud, div#port-picker #delay').prop('disabled', true);
|
||||
$('div#port-picker a.connect').text('Connecting');
|
||||
|
||||
$('div#port-picker a.connect').text('Connecting');
|
||||
|
||||
serial.connect(selected_port, {bitrate: selected_baud}, onOpen);
|
||||
} else {
|
||||
// Disable any active "data pulling" timer
|
||||
GUI.interval_kill_all();
|
||||
|
||||
|
||||
GUI.tab_switch_cleanup();
|
||||
GUI.timeout_remove('connecting');
|
||||
|
||||
|
||||
serial.disconnect(onClosed);
|
||||
|
||||
|
||||
GUI.connected_to = false;
|
||||
|
||||
|
||||
// Reset various UI elements
|
||||
$('span.port-usage').html('0%');
|
||||
$('.software-version').html('0.0');
|
||||
$('span.cycle-time').html('0');
|
||||
|
||||
|
||||
MSP.disconnect_cleanup();
|
||||
configuration_received = false; // reset valid config received variable (used to block tabs while not connected properly)
|
||||
|
||||
|
||||
// unlock port select & baud
|
||||
$('div#port-picker #port').prop('disabled', false);
|
||||
if (!GUI.auto_connect) $('div#port-picker #baud').prop('disabled', false);
|
||||
|
||||
|
||||
$(this).text('Connect');
|
||||
$(this).removeClass('active');
|
||||
|
||||
|
||||
sensor_status(sensors_detected = 0); // reset active sensor indicators
|
||||
$('#tabs > ul li').removeClass('active'); // de-select any selected tabs
|
||||
tab_initialize_default();
|
||||
}
|
||||
|
||||
|
||||
$(this).data("clicks", !clicks);
|
||||
}
|
||||
}
|
||||
|
@ -61,62 +61,62 @@ $(document).ready(function() {
|
|||
if (typeof result.auto_connect === 'undefined') {
|
||||
// auto_connect wasn't saved yet, save and push true to the GUI
|
||||
GUI.auto_connect = true;
|
||||
|
||||
|
||||
$('input.auto_connect').prop('checked', true);
|
||||
$('input.auto_connect, span.auto_connect').prop('title', 'Auto-Connect: Enabled - Configurator automatically tries to connect when new port is detected');
|
||||
$('select#baud').val(115200).prop('disabled', true);
|
||||
|
||||
|
||||
// save
|
||||
chrome.storage.local.set({'auto_connect': true});
|
||||
} else {
|
||||
if (result.auto_connect) {
|
||||
if (result.auto_connect) {
|
||||
// enabled by user
|
||||
GUI.auto_connect = true;
|
||||
|
||||
|
||||
$('input.auto_connect').prop('checked', true);
|
||||
$('input.auto_connect, span.auto_connect').prop('title', 'Auto-Connect: Enabled - Configurator automatically tries to connect when new serial port is detected');
|
||||
|
||||
|
||||
$('select#baud').val(115200).prop('disabled', true);
|
||||
} else {
|
||||
} else {
|
||||
// disabled by user
|
||||
GUI.auto_connect = false;
|
||||
|
||||
|
||||
$('input.auto_connect').prop('checked', false);
|
||||
$('input.auto_connect, span.auto_connect').prop('title', 'Auto-Connect: Disabled - User needs to select the correct serial port and click "Connect" button on its own');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// bind UI hook to auto-connect checkbos
|
||||
$('input.auto_connect').change(function() {
|
||||
GUI.auto_connect = $(this).is(':checked');
|
||||
|
||||
|
||||
// update title/tooltip
|
||||
if (GUI.auto_connect) {
|
||||
$('input.auto_connect, span.auto_connect').prop('title', 'Auto-Connect: Enabled - Configurator automatically tries to connect when new port is detected');
|
||||
|
||||
|
||||
$('select#baud').val(115200).prop('disabled', true);
|
||||
} else {
|
||||
$('input.auto_connect, span.auto_connect').prop('title', 'Auto-Connect: Disabled - User needs to select the correct serial port and click "Connect" button on its own');
|
||||
|
||||
|
||||
if (!GUI.connected_to && !GUI.connecting_to) $('select#baud').prop('disabled', false);
|
||||
}
|
||||
|
||||
|
||||
chrome.storage.local.set({'auto_connect': GUI.auto_connect});
|
||||
});
|
||||
});
|
||||
PortHandler.initialize();
|
||||
});
|
||||
});
|
||||
|
||||
function onOpen(openInfo) {
|
||||
function onOpen(openInfo) {
|
||||
if (openInfo) {
|
||||
// update connected_to
|
||||
GUI.connected_to = GUI.connecting_to;
|
||||
|
||||
|
||||
// reset connecting_to
|
||||
GUI.connecting_to = false;
|
||||
|
||||
|
||||
GUI.log('Serial port <span style="color: green">successfully</span> opened with ID: ' + openInfo.connectionId);
|
||||
|
||||
|
||||
// save selected port with chrome.storage if the port differs
|
||||
chrome.storage.local.get('last_used_port', function(result) {
|
||||
if (typeof result.last_used_port != 'undefined') {
|
||||
|
@ -138,12 +138,12 @@ function onOpen(openInfo) {
|
|||
|
||||
serial.onReceive.addListener(read_serial);
|
||||
GUI.interval_add('port_usage', port_usage, 1000, true);
|
||||
|
||||
|
||||
// disconnect after 10 seconds with error if we don't get IDENT data
|
||||
GUI.timeout_add('connecting', function() {
|
||||
if (!configuration_received) {
|
||||
GUI.log('No configuration received within <span style="color: red">10 seconds</span>, communication <span style="color: red">failed</span>');
|
||||
|
||||
|
||||
$('div#port-picker a.connect').click(); // disconnect
|
||||
}
|
||||
}, 10000);
|
||||
|
@ -153,11 +153,11 @@ function onOpen(openInfo) {
|
|||
GUI.log('Unique device ID <span style="color: green">received</span> - <strong>0x' + CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16) + '</strong>');
|
||||
send_message(MSP_codes.MSP_IDENT, MSP_codes.MSP_IDENT, false, function() {
|
||||
GUI.timeout_remove('connecting'); // kill connecting timer
|
||||
|
||||
|
||||
if (CONFIG.version >= firmware_version_accepted) {
|
||||
// Update UI elements that doesn't need consistent refreshing
|
||||
$('.software-version').html(CONFIG.version);
|
||||
|
||||
|
||||
configuration_received = true;
|
||||
$('div#port-picker a.connect').text('Disconnect').addClass('active');
|
||||
$('#tabs li a:first').click();
|
||||
|
@ -170,13 +170,13 @@ function onOpen(openInfo) {
|
|||
} else {
|
||||
console.log('Failed to open serial port');
|
||||
GUI.log('Failed to open serial port', 'red');
|
||||
|
||||
|
||||
$('div#port-picker a.connect').text('Connect');
|
||||
$('div#port-picker a.connect').removeClass('active');
|
||||
|
||||
$('div#port-picker a.connect').removeClass('active');
|
||||
|
||||
// unlock port select & baud
|
||||
$('div#port-picker #port, div#port-picker #baud, div#port-picker #delay').prop('disabled', false);
|
||||
|
||||
|
||||
// reset data
|
||||
$('div#port-picker a.connect').data("clicks", false);
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ function onClosed(result) {
|
|||
GUI.log('Serial port <span style="color: green">successfully</span> closed');
|
||||
} else { // Something went wrong
|
||||
GUI.log('<span style="color: red">Failed</span> to close serial port');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function read_serial(info) {
|
||||
|
@ -199,7 +199,7 @@ function read_serial(info) {
|
|||
}
|
||||
|
||||
function port_usage() {
|
||||
var port_usage = (char_counter * 10 / parseInt($('div#port-picker #baud').val())) * 100;
|
||||
var port_usage = (char_counter * 10 / parseInt($('div#port-picker #baud').val())) * 100;
|
||||
$('span.port-usage').html(parseInt(port_usage) + '%');
|
||||
|
||||
// reset counter
|
||||
|
@ -211,11 +211,11 @@ function sensor_status(sensors_detected) {
|
|||
if (typeof sensor_status.previous_sensors_detected == 'undefined') {
|
||||
sensor_status.previous_sensors_detected = 0;
|
||||
}
|
||||
|
||||
|
||||
// update UI (if necessary)
|
||||
if (sensor_status.previous_sensors_detected != sensors_detected) {
|
||||
var e_sensor_status = $('div#sensor-status');
|
||||
|
||||
|
||||
if (bit_check(sensors_detected, 0)) { // Gyroscope & accel detected
|
||||
$('.gyro', e_sensor_status).addClass('on');
|
||||
$('.accel', e_sensor_status).addClass('on');
|
||||
|
@ -228,26 +228,26 @@ function sensor_status(sensors_detected) {
|
|||
$('.baro', e_sensor_status).addClass('on');
|
||||
} else {
|
||||
$('.baro', e_sensor_status).removeClass('on');
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_check(sensors_detected, 2)) { // Magnetometer detected
|
||||
$('.mag', e_sensor_status).addClass('on');
|
||||
} else {
|
||||
$('.mag', e_sensor_status).removeClass('on');
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_check(sensors_detected, 3)) { // GPS detected
|
||||
$('.gps', e_sensor_status).addClass('on');
|
||||
} else {
|
||||
$('.gps', e_sensor_status).removeClass('on');
|
||||
}
|
||||
}
|
||||
|
||||
if (bit_check(sensors_detected, 4)) { // Sonar detected
|
||||
$('.sonar', e_sensor_status).addClass('on');
|
||||
} else {
|
||||
$('.sonar', e_sensor_status).removeClass('on');
|
||||
}
|
||||
|
||||
|
||||
// set current value
|
||||
sensor_status.previous_sensors_detected = sensors_detected;
|
||||
}
|
||||
|
|
200
js/stm32.js
200
js/stm32.js
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
STM32 F103 serial bus seems to properly initialize with quite a huge auto-baud range
|
||||
From 921600 down to 1200, i don't recommend getting any lower then that
|
||||
Official "specs" are from 115200 to 1200
|
||||
|
@ -7,20 +7,20 @@
|
|||
var STM32_protocol = function() {
|
||||
this.hex; // ref
|
||||
this.verify_hex;
|
||||
|
||||
|
||||
this.receive_buffer;
|
||||
|
||||
|
||||
this.bytes_to_read = 0; // ref
|
||||
this.read_callback; // ref
|
||||
|
||||
|
||||
this.upload_time_start;
|
||||
this.upload_process_alive;
|
||||
|
||||
|
||||
this.status = {
|
||||
ACK: 0x79, // y
|
||||
NACK: 0x1F
|
||||
};
|
||||
|
||||
|
||||
this.command = {
|
||||
get: 0x00, // Gets the version and the allowed commands supported by the current version of the bootloader
|
||||
get_ver_r_protect_s: 0x01, // Gets the bootloader version and the Read Protection status of the Flash memory
|
||||
|
@ -35,7 +35,7 @@ var STM32_protocol = function() {
|
|||
readout_protect: 0x82, // Enables the read protection
|
||||
readout_unprotect: 0x92 // Disables the read protection
|
||||
};
|
||||
|
||||
|
||||
// Erase (x043) and Extended Erase (0x44) are exclusive. A device may support either the Erase command or the Extended Erase command but not both.
|
||||
};
|
||||
|
||||
|
@ -48,14 +48,14 @@ STM32_protocol.prototype.GUI_status = function(string) {
|
|||
STM32_protocol.prototype.connect = function(hex) {
|
||||
var self = this;
|
||||
self.hex = hex;
|
||||
|
||||
|
||||
var selected_port = String($('div#port-picker .port select').val());
|
||||
var baud = parseInt($('div#port-picker #baud').val());
|
||||
|
||||
|
||||
if (selected_port != '0') {
|
||||
// popular choices - 921600, 460800, 256000, 230400, 153600, 128000, 115200, 57600, 38400, 28800, 19200
|
||||
var flashing_bitrate;
|
||||
|
||||
|
||||
switch (GUI.operating_system) {
|
||||
case 'Windows':
|
||||
flashing_bitrate = 921600;
|
||||
|
@ -68,11 +68,11 @@ STM32_protocol.prototype.connect = function(hex) {
|
|||
case 'UNIX':
|
||||
flashing_bitrate = 921600;
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
flashing_bitrate = 115200;
|
||||
}
|
||||
|
||||
|
||||
if (!$('input.updating').is(':checked')) {
|
||||
serial.connect(selected_port, {bitrate: baud}, function(openInfo) {
|
||||
if (openInfo) {
|
||||
|
@ -80,17 +80,17 @@ STM32_protocol.prototype.connect = function(hex) {
|
|||
|
||||
// we are connected, disabling connect button in the UI
|
||||
GUI.connect_lock = true;
|
||||
|
||||
|
||||
var bufferOut = new ArrayBuffer(1);
|
||||
var bufferView = new Uint8Array(bufferOut);
|
||||
|
||||
|
||||
bufferView[0] = 0x52;
|
||||
|
||||
|
||||
serial.send(bufferOut, function() {
|
||||
serial.disconnect(function(result) {
|
||||
if (result) {
|
||||
if (result) {
|
||||
serial.connect(selected_port, {bitrate: flashing_bitrate, parityBit: 'even', stopBits: 'one'}, function(openInfo) {
|
||||
if (openInfo) {
|
||||
if (openInfo) {
|
||||
self.initialize();
|
||||
} else {
|
||||
GUI.log('<span style="color: red">Failed</span> to open serial port');
|
||||
|
@ -107,10 +107,10 @@ STM32_protocol.prototype.connect = function(hex) {
|
|||
});
|
||||
} else {
|
||||
serial.connect(selected_port, {bitrate: flashing_bitrate, parityBit: 'even', stopBits: 'one'}, function(openInfo) {
|
||||
if (openInfo) {
|
||||
if (openInfo) {
|
||||
// we are connected, disabling connect button in the UI
|
||||
GUI.connect_lock = true;
|
||||
|
||||
|
||||
self.initialize();
|
||||
} else {
|
||||
GUI.log('<span style="color: red">Failed</span> to open serial port');
|
||||
|
@ -126,14 +126,14 @@ STM32_protocol.prototype.connect = function(hex) {
|
|||
// initialize certain variables and start timers that oversee the communication
|
||||
STM32_protocol.prototype.initialize = function() {
|
||||
var self = this;
|
||||
|
||||
// reset and set some variables before we start
|
||||
|
||||
// reset and set some variables before we start
|
||||
self.receive_buffer = [];
|
||||
self.verify_hex = [];
|
||||
|
||||
|
||||
self.upload_time_start = microtime();
|
||||
self.upload_process_alive = false;
|
||||
|
||||
|
||||
// reset progress bar to initial state
|
||||
self.progress_bar_e = $('.progress');
|
||||
self.progress_bar_e.val(0);
|
||||
|
@ -142,42 +142,42 @@ STM32_protocol.prototype.initialize = function() {
|
|||
serial.onReceive.addListener(function(info) {
|
||||
self.read(info);
|
||||
});
|
||||
|
||||
|
||||
GUI.interval_add('STM32_timeout', function() {
|
||||
if (self.upload_process_alive) { // process is running
|
||||
self.upload_process_alive = false;
|
||||
} else {
|
||||
console.log('STM32 - timed out, programming failed ...');
|
||||
STM32.GUI_status('STM32 - timed out, programming: <strong style="color: red">FAILED</strong>');
|
||||
|
||||
|
||||
// protocol got stuck, clear timer and disconnect
|
||||
GUI.interval_remove('STM32_timeout');
|
||||
|
||||
|
||||
// exit
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
|
||||
self.upload_procedure(1);
|
||||
};
|
||||
|
||||
// no input parameters
|
||||
// this method should be executed every 1 ms via interval timer
|
||||
STM32_protocol.prototype.read = function(readInfo) {
|
||||
STM32_protocol.prototype.read = function(readInfo) {
|
||||
// routine that fills the buffer
|
||||
var data = new Uint8Array(readInfo.data);
|
||||
|
||||
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
this.receive_buffer.push(data[i]);
|
||||
this.receive_buffer.push(data[i]);
|
||||
}
|
||||
|
||||
|
||||
// routine that fetches data from buffer if statement is true
|
||||
if (this.receive_buffer.length >= this.bytes_to_read && this.bytes_to_read != 0) {
|
||||
var data = this.receive_buffer.slice(0, this.bytes_to_read); // bytes requested
|
||||
this.receive_buffer.splice(0, this.bytes_to_read); // remove read bytes
|
||||
|
||||
|
||||
this.bytes_to_read = 0; // reset trigger
|
||||
|
||||
|
||||
this.read_callback(data);
|
||||
}
|
||||
};
|
||||
|
@ -188,7 +188,7 @@ STM32_protocol.prototype.retrieve = function(n_bytes, callback) {
|
|||
// data that we need are there, process immediately
|
||||
var data = this.receive_buffer.slice(0, n_bytes);
|
||||
this.receive_buffer.splice(0, n_bytes); // remove read bytes
|
||||
|
||||
|
||||
callback(data);
|
||||
} else {
|
||||
// still waiting for data, add callback
|
||||
|
@ -203,38 +203,38 @@ STM32_protocol.prototype.retrieve = function(n_bytes, callback) {
|
|||
STM32_protocol.prototype.send = function(Array, bytes_to_read, callback) {
|
||||
// flip flag
|
||||
this.upload_process_alive = true;
|
||||
|
||||
|
||||
var bufferOut = new ArrayBuffer(Array.length);
|
||||
var bufferView = new Uint8Array(bufferOut);
|
||||
|
||||
|
||||
// set Array values inside bufferView (alternative to for loop)
|
||||
bufferView.set(Array);
|
||||
|
||||
|
||||
// update references
|
||||
this.bytes_to_read = bytes_to_read;
|
||||
this.read_callback = callback;
|
||||
|
||||
|
||||
// empty receive buffer before next command is out
|
||||
this.receive_buffer = [];
|
||||
|
||||
// send over the actual data
|
||||
serial.send(bufferOut, function(writeInfo) {});
|
||||
serial.send(bufferOut, function(writeInfo) {});
|
||||
};
|
||||
|
||||
// val = single byte to be verified
|
||||
// val = single byte to be verified
|
||||
// data = response of n bytes from mcu (array)
|
||||
// result = true/false
|
||||
STM32_protocol.prototype.verify_response = function(val, data) {
|
||||
if (val != data[0]) {
|
||||
console.log('STM32 Communication failed, wrong response, expected: ' + val + ' received: ' + data[0]);
|
||||
STM32.GUI_status('STM32 Communication <span style="color: red">failed</span>, wrong response, expected: ' + val + ' received: ' + data[0]);
|
||||
|
||||
|
||||
// disconnect
|
||||
this.upload_procedure(99);
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
|
@ -242,7 +242,7 @@ STM32_protocol.prototype.verify_response = function(val, data) {
|
|||
// result = true/false
|
||||
STM32_protocol.prototype.verify_chip_signature = function(signature) {
|
||||
var available_flash_size = 0;
|
||||
|
||||
|
||||
switch (signature) {
|
||||
case 0x412: // not tested
|
||||
console.log('Chip recognized as F1 Low-density');
|
||||
|
@ -297,19 +297,19 @@ STM32_protocol.prototype.verify_chip_signature = function(signature) {
|
|||
console.log('Chip recognized as F3 STM32F30xxx, STM32F31xxx');
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (available_flash_size > 0) {
|
||||
if (this.hex.bytes_total < available_flash_size) {
|
||||
return true;
|
||||
} else {
|
||||
console.log('Supplied hex is bigger then flash available on the chip, HEX: ' + this.hex.bytes_total + ' bytes, limit = ' + available_flash_size + ' bytes');
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
console.log('Chip NOT recognized: ' + signature);
|
||||
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
|
@ -323,16 +323,16 @@ STM32_protocol.prototype.verify_flash = function(first_array, second_array) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
console.log('Verification successful, matching: ' + first_array.length + ' bytes');
|
||||
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// step = value depending on current state of upload_procedure
|
||||
STM32_protocol.prototype.upload_procedure = function(step) {
|
||||
var self = this;
|
||||
|
||||
|
||||
switch (step) {
|
||||
case 1:
|
||||
// initialize serial interface on the MCU side, auto baud rate settings
|
||||
|
@ -342,18 +342,18 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
if (reply[0] == 0x7F || reply[0] == self.status.ACK || reply[0] == self.status.NACK) {
|
||||
GUI.interval_remove('stm32_initialize_mcu');
|
||||
console.log('STM32 - Serial interface initialized on the MCU side');
|
||||
|
||||
|
||||
// proceed to next step
|
||||
self.upload_procedure(2);
|
||||
} else {
|
||||
GUI.interval_remove('stm32_initialize_mcu');
|
||||
STM32.GUI_status('STM32 Communication with bootloader <span style="color: red">failed</span>');
|
||||
|
||||
|
||||
// disconnect
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (send_counter++ > 3) {
|
||||
// stop retrying, its too late to get any response from MCU
|
||||
GUI.interval_remove('stm32_initialize_mcu');
|
||||
|
@ -366,7 +366,7 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
if (self.verify_response(self.status.ACK, data)) {
|
||||
self.retrieve(data[1] + 1 + 1, function(data) { // data[1] = number of bytes that will follow [– 1 except current and ACKs]
|
||||
console.log('STM32 - Bootloader version: ' + (parseInt(data[0].toString(16)) / 10).toFixed(1)); // convert dec to hex, hex to dec and add floating point
|
||||
|
||||
|
||||
// proceed to next step
|
||||
self.upload_procedure(3);
|
||||
});
|
||||
|
@ -380,7 +380,7 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
self.retrieve(data[1] + 1 + 1, function(data) { // data[1] = number of bytes that will follow [– 1 (N = 1 for STM32), except for current byte and ACKs]
|
||||
var signature = (data[0] << 8) | data[1];
|
||||
console.log('STM32 - Signature: 0x' + signature.toString(16)); // signature in hex representation
|
||||
|
||||
|
||||
if (self.verify_chip_signature(signature)) {
|
||||
// proceed to next step
|
||||
self.upload_procedure(4);
|
||||
|
@ -396,7 +396,7 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
// erase memory
|
||||
console.log('Executing global chip erase');
|
||||
STM32.GUI_status('Erasing');
|
||||
|
||||
|
||||
self.send([self.command.erase, 0xBC], 1, function(reply) { // 0x43 ^ 0xFF
|
||||
if (self.verify_response(self.status.ACK, reply)) {
|
||||
self.send([0xFF, 0x00], 1, function(reply) {
|
||||
|
@ -404,9 +404,9 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
console.log('Erasing: done');
|
||||
console.log('Writing data ...');
|
||||
STM32.GUI_status('<span style="color: green">Flashing ...</span>');
|
||||
|
||||
|
||||
// proceed to next step
|
||||
self.upload_procedure(5);
|
||||
self.upload_procedure(5);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -417,36 +417,36 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
var blocks = self.hex.data.length - 1;
|
||||
var flashing_block = 0;
|
||||
var address = self.hex.data[flashing_block].address;
|
||||
|
||||
|
||||
var bytes_flashed = 0;
|
||||
var bytes_flashed_total = 0; // used for progress bar
|
||||
|
||||
|
||||
var write = function() {
|
||||
if (bytes_flashed < self.hex.data[flashing_block].bytes) {
|
||||
var bytes_to_write = ((bytes_flashed + 128) <= self.hex.data[flashing_block].bytes) ? 128 : (self.hex.data[flashing_block].bytes - bytes_flashed);
|
||||
|
||||
|
||||
// console.log('STM32 - Writing to: 0x' + address.toString(16) + ', ' + bytes_to_write + ' bytes');
|
||||
|
||||
|
||||
self.send([self.command.write_memory, 0xCE], 1, function(reply) { // 0x31 ^ 0xFF
|
||||
if (self.verify_response(self.status.ACK, reply)) {
|
||||
// address needs to be transmitted as 32 bit integer, we need to bit shift each byte out and then calculate address checksum
|
||||
var address_arr = [(address >> 24), (address >> 16), (address >> 8), address];
|
||||
var address_checksum = address_arr[0] ^ address_arr[1] ^ address_arr[2] ^ address_arr[3];
|
||||
|
||||
|
||||
self.send([address_arr[0], address_arr[1], address_arr[2], address_arr[3], address_checksum], 1, function(reply) { // write start address + checksum
|
||||
if (self.verify_response(self.status.ACK, reply)) {
|
||||
var array_out = new Array(bytes_to_write + 2); // 2 byte overhead [N, ...., checksum]
|
||||
array_out[0] = bytes_to_write - 1; // number of bytes to be written (to write 128 bytes, N must be 127, to write 256 bytes, N must be 255)
|
||||
|
||||
|
||||
var checksum = array_out[0];
|
||||
for (var i = 0; i < bytes_to_write; i++) {
|
||||
array_out[i + 1] = self.hex.data[flashing_block].data[bytes_flashed]; // + 1 because of the first byte offset
|
||||
checksum ^= self.hex.data[flashing_block].data[bytes_flashed];
|
||||
|
||||
|
||||
bytes_flashed++;
|
||||
}
|
||||
array_out[array_out.length - 1] = checksum; // checksum (last byte in the array_out array)
|
||||
|
||||
|
||||
address += bytes_to_write;
|
||||
bytes_flashed_total += bytes_to_write
|
||||
|
||||
|
@ -454,7 +454,7 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
if (self.verify_response(self.status.ACK, reply)) {
|
||||
// update progress bar
|
||||
self.progress_bar_e.val(bytes_flashed_total / (self.hex.bytes_total * 2) * 100);
|
||||
|
||||
|
||||
// flash another page
|
||||
write();
|
||||
}
|
||||
|
@ -467,23 +467,23 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
// move to another block
|
||||
if (flashing_block < blocks) {
|
||||
flashing_block++;
|
||||
|
||||
|
||||
address = self.hex.data[flashing_block].address;
|
||||
bytes_flashed = 0;
|
||||
|
||||
|
||||
write();
|
||||
} else {
|
||||
// all blocks flashed
|
||||
console.log('Writing: done');
|
||||
console.log('Verifying data ...');
|
||||
STM32.GUI_status('<span style="color: green">Verifying ...</span>');
|
||||
|
||||
|
||||
// proceed to next step
|
||||
self.upload_procedure(6);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// start writing
|
||||
write();
|
||||
break;
|
||||
|
@ -492,44 +492,44 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
var blocks = self.hex.data.length - 1;
|
||||
var reading_block = 0;
|
||||
var address = self.hex.data[reading_block].address;
|
||||
|
||||
|
||||
var bytes_verified = 0;
|
||||
var bytes_verified_total = 0; // used for progress bar
|
||||
|
||||
|
||||
// initialize arrays
|
||||
for (var i = 0; i <= blocks; i++) {
|
||||
self.verify_hex.push([]);
|
||||
}
|
||||
|
||||
|
||||
var reading = function() {
|
||||
if (bytes_verified < self.hex.data[reading_block].bytes) {
|
||||
var bytes_to_read = ((bytes_verified + 128) <= self.hex.data[reading_block].bytes) ? 128 : (self.hex.data[reading_block].bytes - bytes_verified);
|
||||
|
||||
|
||||
// console.log('STM32 - Reading from: 0x' + address.toString(16) + ', ' + bytes_to_read + ' bytes');
|
||||
|
||||
|
||||
self.send([self.command.read_memory, 0xEE], 1, function(reply) { // 0x11 ^ 0xFF
|
||||
if (self.verify_response(self.status.ACK, reply)) {
|
||||
var address_arr = [(address >> 24), (address >> 16), (address >> 8), address];
|
||||
var address_checksum = address_arr[0] ^ address_arr[1] ^ address_arr[2] ^ address_arr[3];
|
||||
|
||||
|
||||
self.send([address_arr[0], address_arr[1], address_arr[2], address_arr[3], address_checksum], 1, function(reply) { // read start address + checksum
|
||||
if (self.verify_response(self.status.ACK, reply)) {
|
||||
var bytes_to_read_n = bytes_to_read - 1;
|
||||
|
||||
|
||||
self.send([bytes_to_read_n, (~bytes_to_read_n) & 0xFF], 1, function(reply) { // bytes to be read + checksum XOR(complement of bytes_to_read_n)
|
||||
if (self.verify_response(self.status.ACK, reply)) {
|
||||
self.retrieve(bytes_to_read, function(data) {
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
self.verify_hex[reading_block].push(data[i]);
|
||||
}
|
||||
|
||||
|
||||
address += bytes_to_read;
|
||||
bytes_verified += bytes_to_read;
|
||||
bytes_verified_total += bytes_to_read;
|
||||
|
||||
|
||||
// update progress bar
|
||||
self.progress_bar_e.val((self.hex.bytes_total + bytes_verified_total) / (self.hex.bytes_total * 2) * 100);
|
||||
|
||||
self.progress_bar_e.val((self.hex.bytes_total + bytes_verified_total) / (self.hex.bytes_total * 2) * 100);
|
||||
|
||||
// verify another page
|
||||
reading();
|
||||
});
|
||||
|
@ -543,44 +543,44 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
// move to another block
|
||||
if (reading_block < blocks) {
|
||||
reading_block++;
|
||||
|
||||
|
||||
address = self.hex.data[reading_block].address;
|
||||
bytes_verified = 0;
|
||||
|
||||
|
||||
reading();
|
||||
} else {
|
||||
// all blocks read, verify
|
||||
|
||||
|
||||
var verify = true;
|
||||
for (var i = 0; i <= blocks; i++) {
|
||||
verify = self.verify_flash(self.hex.data[i].data, self.verify_hex[i]);
|
||||
|
||||
|
||||
if (!verify) break;
|
||||
}
|
||||
|
||||
|
||||
if (verify) {
|
||||
console.log('Programming: SUCCESSFUL');
|
||||
STM32.GUI_status('Programming: <strong style="color: green">SUCCESSFUL</strong>');
|
||||
|
||||
|
||||
// update progress bar
|
||||
self.progress_bar_e.addClass('valid');
|
||||
|
||||
|
||||
// proceed to next step
|
||||
self.upload_procedure(7);
|
||||
self.upload_procedure(7);
|
||||
} else {
|
||||
console.log('Programming: FAILED');
|
||||
STM32.GUI_status('Programming: <strong style="color: red">FAILED</strong>');
|
||||
|
||||
|
||||
// update progress bar
|
||||
self.progress_bar_e.addClass('invalid');
|
||||
|
||||
|
||||
// disconnect
|
||||
self.upload_procedure(99);
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// start reading
|
||||
reading();
|
||||
break;
|
||||
|
@ -594,7 +594,7 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
var gt_address = 0x8000000;
|
||||
var address = [(gt_address >> 24), (gt_address >> 16), (gt_address >> 8), gt_address];
|
||||
var address_checksum = address[0] ^ address[1] ^ address[2] ^ address[3];
|
||||
|
||||
|
||||
self.send([address[0], address[1], address[2], address[3], address_checksum], 1, function(reply) {
|
||||
if (self.verify_response(self.status.ACK, reply)) {
|
||||
// disconnect
|
||||
|
@ -607,15 +607,15 @@ STM32_protocol.prototype.upload_procedure = function(step) {
|
|||
case 99:
|
||||
// disconnect
|
||||
GUI.interval_remove('STM32_timeout'); // stop STM32 timeout timer (everything is finished now)
|
||||
|
||||
|
||||
console.log('Script finished after: ' + (microtime() - self.upload_time_start).toFixed(4) + ' seconds');
|
||||
|
||||
|
||||
// close connection
|
||||
serial.disconnect(function(result) {
|
||||
if (result) { // All went as expected
|
||||
} else { // Something went wrong
|
||||
}
|
||||
|
||||
|
||||
// unlocking connect button
|
||||
GUI.connect_lock = false;
|
||||
});
|
||||
|
|
|
@ -3,24 +3,24 @@
|
|||
// if hex file wasn't valid (crc check failed on any of the lines), result will be false
|
||||
function read_hex_file(data) {
|
||||
data = data.split("\n");
|
||||
|
||||
|
||||
// check if there is an empty line in the end of hex file, if there is, remove it
|
||||
if (data[data.length - 1] == "") {
|
||||
data.pop();
|
||||
}
|
||||
|
||||
|
||||
var hexfile_valid = true; // if any of the crc checks failed, this variable flips to false
|
||||
|
||||
|
||||
var result = {
|
||||
data: [],
|
||||
end_of_file: false,
|
||||
bytes_total: 0,
|
||||
start_linear_address: 0
|
||||
};
|
||||
|
||||
|
||||
var extended_linear_address = 0;
|
||||
var next_address = 0;
|
||||
|
||||
|
||||
for (var i = 0; i < data.length && hexfile_valid; i++) {
|
||||
// each byte is represnted by two chars
|
||||
var byte_count = parseInt(data[i].substr(1, 2), 16);
|
||||
|
@ -28,33 +28,33 @@ function read_hex_file(data) {
|
|||
var record_type = parseInt(data[i].substr(7, 2), 16);
|
||||
var content = data[i].substr(9, byte_count * 2); // still in string format
|
||||
var checksum = parseInt(data[i].substr(9 + byte_count * 2, 2), 16); // (this is a 2's complement value)
|
||||
|
||||
|
||||
switch (record_type) {
|
||||
case 0x00: // data record
|
||||
case 0x00: // data record
|
||||
if (address != next_address || next_address == 0) {
|
||||
result.data.push({'address': extended_linear_address + address, 'bytes': 0, 'data': []});
|
||||
}
|
||||
|
||||
|
||||
// store address for next comparison
|
||||
next_address = address + byte_count;
|
||||
|
||||
|
||||
// process data
|
||||
var crc = byte_count + parseInt(data[i].substr(3, 2), 16) + parseInt(data[i].substr(5, 2), 16) + record_type;
|
||||
for (var needle = 0; needle < byte_count * 2; needle += 2) { // * 2 because of 2 hex chars per 1 byte
|
||||
var num = parseInt(content.substr(needle, 2), 16); // get one byte in hex and convert it to decimal
|
||||
var data_block = result.data.length - 1;
|
||||
|
||||
|
||||
result.data[data_block].data.push(num);
|
||||
result.data[data_block].bytes++;
|
||||
|
||||
result.data[data_block].bytes++;
|
||||
|
||||
crc += num;
|
||||
result.bytes_total++;
|
||||
}
|
||||
|
||||
|
||||
// change crc to 2's complement
|
||||
crc = (~crc + 1) & 0xFF;
|
||||
|
||||
// verify
|
||||
|
||||
// verify
|
||||
if (crc != checksum) {
|
||||
hexfile_valid = false;
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ function read_hex_file(data) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (result.end_of_file && hexfile_valid) {
|
||||
postMessage(result);
|
||||
} else {
|
||||
|
@ -98,11 +98,11 @@ function microtime() {
|
|||
|
||||
onmessage = function(event) {
|
||||
var time_parsing_start = microtime(); // track time
|
||||
|
||||
|
||||
read_hex_file(event.data);
|
||||
|
||||
|
||||
console.log('HEX_PARSER - File parsed in: ' + (microtime() - time_parsing_start).toFixed(4) + ' seconds');
|
||||
|
||||
|
||||
// terminate worker
|
||||
close();
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue