mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-16 12:55:19 +03:00
implemented new more powerful port handler
This commit is contained in:
parent
5a195e3b09
commit
844121e4bf
6 changed files with 201 additions and 110 deletions
|
@ -226,7 +226,7 @@ GUI_control.prototype.tab_switch_cleanup = function(callback) {
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'sensors':
|
case 'sensors':
|
||||||
GUI.interval_kill_all(['port-update', 'port_usage']);
|
GUI.interval_kill_all(['port_handler', 'port_usage']);
|
||||||
serial.empty_output_buffer();
|
serial.empty_output_buffer();
|
||||||
|
|
||||||
// sensor data tab uses scrollbars, emptying the content before loading another tab
|
// sensor data tab uses scrollbars, emptying the content before loading another tab
|
||||||
|
|
195
js/port_handler.js
Normal file
195
js/port_handler.js
Normal file
|
@ -0,0 +1,195 @@
|
||||||
|
function port_handler() {
|
||||||
|
this.initial_ports = false;
|
||||||
|
|
||||||
|
this.port_detected_callbacks = [];
|
||||||
|
this.port_removed_callbacks = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
port_handler.prototype.initialize = function() {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
// 250ms refresh interval, fire instantly after creation
|
||||||
|
GUI.interval_add('port_handler', function() {
|
||||||
|
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 - Ports removed: ' + removed_ports);
|
||||||
|
} else {
|
||||||
|
console.log('PortHandler - Port 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) {
|
||||||
|
for (var i = 0; i < removed_ports.length; i++) {
|
||||||
|
if (removed_ports[i] == GUI.connected_to) {
|
||||||
|
$('div#port-picker a.connect').click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.update_port_select(current_ports);
|
||||||
|
|
||||||
|
// trigger callbacks (only after initialization)
|
||||||
|
if (self.initial_ports) {
|
||||||
|
for (var i = 0; i < self.port_removed_callbacks.length; i++) {
|
||||||
|
var obj = self.port_removed_callbacks[i];
|
||||||
|
|
||||||
|
// remove timeout
|
||||||
|
GUI.timeout_remove(obj.name);
|
||||||
|
|
||||||
|
// trigger callback
|
||||||
|
obj.code(removed_ports);
|
||||||
|
}
|
||||||
|
self.port_removed_callbacks = []; // drop references
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
console.log('Last used port wasn\'t saved "yet", auto-select disabled.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!self.initial_ports) {
|
||||||
|
// initialize
|
||||||
|
self.initial_ports = current_ports;
|
||||||
|
} else {
|
||||||
|
for (var i = 0; i < removed_ports.length; i++) {
|
||||||
|
self.initial_ports.splice(self.initial_ports.indexOf(removed_ports[i]), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 - Ports found: ' + new_ports);
|
||||||
|
} else {
|
||||||
|
console.log('PortHandler - Port 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 {
|
||||||
|
$('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
|
||||||
|
if (GUI.active_tab != 'firmware_flasher') {
|
||||||
|
GUI.timeout_add('auto-connect_timeout', function() {
|
||||||
|
$('div#port-picker a.connect').click();
|
||||||
|
}, 50); // small timeout so we won't get any nasty connect errors due to system initializing the bus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// trigger callbacks
|
||||||
|
for (var i = 0; i < self.port_detected_callbacks.length; i++) {
|
||||||
|
var obj = self.port_detected_callbacks[i];
|
||||||
|
|
||||||
|
// remove timeout
|
||||||
|
GUI.timeout_remove(obj.name);
|
||||||
|
|
||||||
|
// trigger callback
|
||||||
|
obj.code(new_ports);
|
||||||
|
}
|
||||||
|
self.port_detected_callbacks = []; // drop references
|
||||||
|
|
||||||
|
self.initial_ports = current_ports;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 250, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
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) {
|
||||||
|
var self = this;
|
||||||
|
var obj = {'name': name, 'code': code, 'timeout': timeout, 'timer': false};
|
||||||
|
|
||||||
|
if (timeout) {
|
||||||
|
obj.timer = GUI.timeout_add(name, function() {
|
||||||
|
console.log('PortHandler - port detected timeout triggered - ' + obj.name);
|
||||||
|
|
||||||
|
// trigger callback
|
||||||
|
code(false);
|
||||||
|
|
||||||
|
// reset callback array
|
||||||
|
self.port_detected_callbacks = [];
|
||||||
|
}, timeout).timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.port_detected_callbacks.push(obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
port_handler.prototype.port_removed = function(name, code, timeout) {
|
||||||
|
var self = this;
|
||||||
|
var obj = {'name': name, 'code': code, 'timeout': timeout, 'timer': false};
|
||||||
|
|
||||||
|
if (timeout) {
|
||||||
|
obj.timer = GUI.timeout_add(name, function() {
|
||||||
|
console.log('PortHandler - port removed timeout triggered - ' + obj.name);
|
||||||
|
|
||||||
|
// trigger callback
|
||||||
|
code(false);
|
||||||
|
|
||||||
|
// reset callback array
|
||||||
|
self.port_removed_callbacks = [];
|
||||||
|
}, timeout).timer;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.port_removed_callbacks.push(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;
|
||||||
|
};
|
||||||
|
|
||||||
|
var PortHandler = new port_handler();
|
|
@ -3,9 +3,6 @@ var CLI_active = false;
|
||||||
var CLI_valid = false;
|
var CLI_valid = false;
|
||||||
|
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
console.log('Scanning for new ports...');
|
|
||||||
update_ports();
|
|
||||||
|
|
||||||
$('div#port-picker a.connect').click(function() {
|
$('div#port-picker a.connect').click(function() {
|
||||||
if (GUI.connect_lock != true) { // GUI control overrides the user control
|
if (GUI.connect_lock != true) { // GUI control overrides the user control
|
||||||
var clicks = $(this).data('clicks');
|
var clicks = $(this).data('clicks');
|
||||||
|
@ -25,7 +22,7 @@ $(document).ready(function() {
|
||||||
serial.connect(selected_port, {bitrate: selected_baud}, onOpen);
|
serial.connect(selected_port, {bitrate: selected_baud}, onOpen);
|
||||||
} else {
|
} else {
|
||||||
// Disable any active "data pulling" timer
|
// Disable any active "data pulling" timer
|
||||||
GUI.interval_kill_all(['port-update']);
|
GUI.interval_kill_all(['port_handler']);
|
||||||
|
|
||||||
GUI.tab_switch_cleanup();
|
GUI.tab_switch_cleanup();
|
||||||
GUI.timeout_remove('connecting');
|
GUI.timeout_remove('connecting');
|
||||||
|
@ -103,6 +100,7 @@ $(document).ready(function() {
|
||||||
chrome.storage.local.set({'auto_connect': GUI.auto_connect}, function() {});
|
chrome.storage.local.set({'auto_connect': GUI.auto_connect}, function() {});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
PortHandler.initialize();
|
||||||
});
|
});
|
||||||
|
|
||||||
function onOpen(openInfo) {
|
function onOpen(openInfo) {
|
||||||
|
@ -199,91 +197,6 @@ function port_usage() {
|
||||||
char_counter = 0;
|
char_counter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function update_ports() {
|
|
||||||
var initial_ports = false;
|
|
||||||
|
|
||||||
GUI.interval_add('port-update', function() {
|
|
||||||
serial.getDevices(function(current_ports) {
|
|
||||||
if (initial_ports.length > current_ports.length || !initial_ports) {
|
|
||||||
// port got removed or initial_ports wasn't initialized yet
|
|
||||||
var removed_ports = array_difference(initial_ports, current_ports);
|
|
||||||
|
|
||||||
if (initial_ports != false) console.log('Port removed: ' + removed_ports);
|
|
||||||
|
|
||||||
// disconnect "UI" if necessary
|
|
||||||
if (GUI.connected_to != false && removed_ports[0] == GUI.connected_to) {
|
|
||||||
$('div#port-picker a.connect').click();
|
|
||||||
}
|
|
||||||
|
|
||||||
// update COM port list
|
|
||||||
update_port_select_menu(current_ports);
|
|
||||||
|
|
||||||
// auto-select last used port (only during initialization)
|
|
||||||
if (!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) {
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
console.log('Last used port wasn\'t saved "yet", auto-select disabled.');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset initial_ports
|
|
||||||
initial_ports = current_ports;
|
|
||||||
}
|
|
||||||
|
|
||||||
var new_ports = array_difference(current_ports, initial_ports);
|
|
||||||
|
|
||||||
if (new_ports.length > 0) {
|
|
||||||
console.log('New port found: ' + new_ports[0]);
|
|
||||||
|
|
||||||
// generate new COM port list
|
|
||||||
update_port_select_menu(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 {
|
|
||||||
$('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
|
|
||||||
if (GUI.active_tab != 'firmware_flasher') {
|
|
||||||
GUI.timeout_add('auto-connect_timeout', function() {
|
|
||||||
$('div#port-picker a.connect').click();
|
|
||||||
}, 50); // small timeout so we won't get any nasty connect errors due to system initializing the bus
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// reset initial_ports
|
|
||||||
initial_ports = current_ports;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, 250, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_port_select_menu(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'}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function sensor_status(sensors_detected) {
|
function sensor_status(sensors_detected) {
|
||||||
// initialize variable (if it wasn't)
|
// initialize variable (if it wasn't)
|
||||||
if (typeof sensor_status.previous_sensors_detected == 'undefined') {
|
if (typeof sensor_status.previous_sensors_detected == 'undefined') {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<script type="text/javascript" src="./js/libraries/google-analytics-bundle.js"></script>
|
<script type="text/javascript" src="./js/libraries/google-analytics-bundle.js"></script>
|
||||||
<script type="text/javascript" src="./js/libraries/flotr2.min.js"></script>
|
<script type="text/javascript" src="./js/libraries/flotr2.min.js"></script>
|
||||||
<script type="text/javascript" src="./js/libraries/jquery-2.1.0.min.js"></script>
|
<script type="text/javascript" src="./js/libraries/jquery-2.1.0.min.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/port_handler.js"></script>
|
||||||
<script type="text/javascript" src="./js/serial.js"></script>
|
<script type="text/javascript" src="./js/serial.js"></script>
|
||||||
<script type="text/javascript" src="./js/gui.js"></script>
|
<script type="text/javascript" src="./js/gui.js"></script>
|
||||||
<script type="text/javascript" src="./js/serial_backend.js"></script>
|
<script type="text/javascript" src="./js/serial_backend.js"></script>
|
||||||
|
|
18
main.js
18
main.js
|
@ -181,24 +181,6 @@ function microtime() {
|
||||||
return now;
|
return now;
|
||||||
}
|
}
|
||||||
|
|
||||||
// accepting single level array with "value" as key
|
|
||||||
function array_difference(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function add_custom_spinners() {
|
function add_custom_spinners() {
|
||||||
var spinner_element = '<div class="spinner"><div class="up"></div><div class="down"></div></div>';
|
var spinner_element = '<div class="spinner"><div class="up"></div><div class="down"></div></div>';
|
||||||
|
|
|
@ -208,7 +208,7 @@ function tab_initialize_sensors() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// timer initialization
|
// timer initialization
|
||||||
GUI.interval_kill_all(['port-update', 'port_usage']);
|
GUI.interval_kill_all(['port_handler', 'port_usage']);
|
||||||
|
|
||||||
// data pulling timers
|
// data pulling timers
|
||||||
GUI.interval_add('status_pull', function() {
|
GUI.interval_add('status_pull', function() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue