Allow saving of LED Strip configuratiion via MSP. Requires firmware
with new MSP_SET_LED_STRIP_CONFIG. Remove some .toUpperCase() duplication since it was only needed for the CLI commands panel. Minor CSS cleanups. Some variable and class renaming to align with firmware code.10.3.x-maintenance
parent
db68d567d3
commit
519de30f6e
|
@ -948,7 +948,9 @@
|
|||
|
||||
"ledStripHelp": {
|
||||
"message": "The flight controller can control colors and effects of individual LEDs on a strip.<br />Configure LEDs on the grid, configure wiring order then attach LEDs on your aircraft according to grid positions."
|
||||
},
|
||||
"ledStripButtonSave": {
|
||||
"message": "Save"
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
69
js/msp.js
69
js/msp.js
|
@ -93,6 +93,9 @@ var MSP = {
|
|||
callbacks: [],
|
||||
packet_error: 0,
|
||||
|
||||
ledDirectionLetters: ['n', 'e', 's', 'w', 'u', 'd'], // in LSB bit order
|
||||
ledFunctionLetters: ['i', 'w', 'f', 'a', 't'], // in LSB bit order
|
||||
|
||||
read: function (readInfo) {
|
||||
var data = new Uint8Array(readInfo.data);
|
||||
|
||||
|
@ -626,10 +629,9 @@ var MSP = {
|
|||
offset += 2;
|
||||
|
||||
var directions = [];
|
||||
var directionLetters = ['n', 'e', 's', 'w', 'u', 'd'];
|
||||
for (var directionLetterIndex = 0; directionLetterIndex < directionLetters.length; directionLetterIndex++) {
|
||||
for (var directionLetterIndex = 0; directionLetterIndex < MSP.ledDirectionLetters.length; directionLetterIndex++) {
|
||||
if (bit_check(directionMask, directionLetterIndex)) {
|
||||
directions.push(directionLetters[directionLetterIndex]);
|
||||
directions.push(MSP.ledDirectionLetters[directionLetterIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -637,10 +639,9 @@ var MSP = {
|
|||
offset += 2;
|
||||
|
||||
var functions = [];
|
||||
var functionLetters = ['i', 'w', 'f', 'a', 't'];
|
||||
for (var functionLetterIndex = 0; functionLetterIndex < functionLetters.length; functionLetterIndex++) {
|
||||
for (var functionLetterIndex = 0; functionLetterIndex < MSP.ledFunctionLetters.length; functionLetterIndex++) {
|
||||
if (bit_check(functionMask, functionLetterIndex)) {
|
||||
functions.push(functionLetters[functionLetterIndex]);
|
||||
functions.push(MSP.ledFunctionLetters[functionLetterIndex]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -655,6 +656,10 @@ var MSP = {
|
|||
}
|
||||
|
||||
break;
|
||||
case MSP_codes.MSP_SET_LED_STRIP_CONFIG:
|
||||
console.log('Led strip config saved');
|
||||
break;
|
||||
|
||||
|
||||
case MSP_codes.MSP_SET_MODE_RANGE:
|
||||
console.log('Mode range saved');
|
||||
|
@ -920,7 +925,7 @@ MSP.crunch = function (code) {
|
|||
buffer.push(specificByte(SERIAL_CONFIG.gpsPassthroughBaudRate, 2));
|
||||
buffer.push(specificByte(SERIAL_CONFIG.gpsPassthroughBaudRate, 3));
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -989,3 +994,53 @@ MSP.sendAdjustmentRanges = function(onCompleteCallback) {
|
|||
}
|
||||
};
|
||||
|
||||
MSP.sendLedStripConfig = function(onCompleteCallback) {
|
||||
|
||||
var nextFunction = send_next_led_strip_config;
|
||||
|
||||
var ledIndex = 0;
|
||||
|
||||
send_next_led_strip_config();
|
||||
|
||||
function send_next_led_strip_config() {
|
||||
|
||||
var led = LED_STRIP[ledIndex];
|
||||
|
||||
var buffer = [];
|
||||
|
||||
buffer.push(ledIndex);
|
||||
|
||||
var directionMask = 0;
|
||||
for (var directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
|
||||
var bitIndex = MSP.ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
||||
if (bitIndex >= 0) {
|
||||
directionMask = bit_set(directionMask, bitIndex);
|
||||
}
|
||||
}
|
||||
buffer.push(specificByte(directionMask, 0));
|
||||
buffer.push(specificByte(directionMask, 1));
|
||||
|
||||
var functionMask = 0;
|
||||
for (var functionLetterIndex = 0; functionLetterIndex < led.functions.length; functionLetterIndex++) {
|
||||
var bitIndex = MSP.ledFunctionLetters.indexOf(led.functions[functionLetterIndex]);
|
||||
if (bitIndex >= 0) {
|
||||
functionMask = bit_set(functionMask, bitIndex);
|
||||
}
|
||||
}
|
||||
buffer.push(specificByte(functionMask, 0));
|
||||
buffer.push(specificByte(functionMask, 1));
|
||||
|
||||
buffer.push(led.x);
|
||||
buffer.push(led.y);
|
||||
|
||||
|
||||
// prepare for next iteration
|
||||
ledIndex++;
|
||||
if (ledIndex == LED_STRIP.length) {
|
||||
nextFunction = onCompleteCallback;
|
||||
}
|
||||
|
||||
MSP.send_message(MSP_codes.MSP_SET_LED_STRIP_CONFIG, buffer, false, nextFunction);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -98,10 +98,7 @@
|
|||
}
|
||||
|
||||
.tab-adjustments > .buttons {
|
||||
width: calc(100% - 20px);
|
||||
|
||||
margin-top: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.tab-adjustments > .buttons a {
|
||||
|
|
|
@ -139,10 +139,7 @@
|
|||
}
|
||||
|
||||
.tab-auxiliary > .buttons {
|
||||
width: calc(100% - 20px);
|
||||
|
||||
margin-top: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.tab-auxiliary > .buttons a {
|
||||
|
|
|
@ -140,13 +140,6 @@
|
|||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.tab-auxiliary > .buttons {
|
||||
width: calc(100% - 20px);
|
||||
|
||||
margin-top: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.tab-configuration .save {
|
||||
display: block;
|
||||
float: right;
|
||||
|
|
|
@ -29,35 +29,35 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tab-led-strip .gPoint.mode-w { /* warning */
|
||||
.tab-led-strip .gPoint.function-w { /* warning */
|
||||
background: red;
|
||||
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.tab-led-strip .gPoint.mode-f { /* flight mode & orientation */
|
||||
.tab-led-strip .gPoint.function-f { /* flight mode & orientation */
|
||||
background: rgb(50, 205, 50);
|
||||
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
|
||||
border-color: rgb(50, 205, 50);
|
||||
}
|
||||
|
||||
.tab-led-strip .gPoint.mode-w.mode-f {
|
||||
.tab-led-strip .gPoint.function-w.function-f {
|
||||
background: linear-gradient(to bottom, #42c949 0%,#d2ff52 52%,#d2ff52 52%,#ff5454 52%,#ba3535 100%);
|
||||
}
|
||||
|
||||
.tab-led-strip .gPoint.mode-i { /* indicator */
|
||||
.tab-led-strip .gPoint.function-i { /* indicator */
|
||||
background: yellow;
|
||||
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
|
||||
border-color: yellow;
|
||||
}
|
||||
|
||||
.tab-led-strip .gPoint.mode-a { /* Armed Mode */
|
||||
.tab-led-strip .gPoint.function-a { /* Armed Mode */
|
||||
background: rgb(52, 155, 255);
|
||||
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
|
||||
border-color: rgb(52, 155, 255);
|
||||
}
|
||||
|
||||
.tab-led-strip .gPoint.mode-t { /* Armed Mode */
|
||||
.tab-led-strip .gPoint.function-t { /* Armed Mode */
|
||||
background: orange;
|
||||
box-shadow: inset 0 0 30px rgba(0, 0, 0, .7);
|
||||
border-color: orange;
|
||||
|
@ -136,18 +136,13 @@
|
|||
width: 32%;
|
||||
}
|
||||
|
||||
.tab-led-strip .modeW.btnOn {background: red;}
|
||||
.tab-led-strip .modeF.btnOn {background: rgb(50, 205, 50);}
|
||||
.tab-led-strip .modeI.btnOn {background: yellow; color: #333;}
|
||||
.tab-led-strip .modeA.btnOn {background: blue;}
|
||||
.tab-led-strip .modeT.btnOn {background: orange;}
|
||||
.tab-led-strip .functions .function-w.btnOn {background: red;}
|
||||
.tab-led-strip .functions .function-f.btnOn {background: rgb(50, 205, 50);}
|
||||
.tab-led-strip .functions .function-i.btnOn {background: yellow; color: #333;}
|
||||
.tab-led-strip .functions .function-a.btnOn {background: blue;}
|
||||
.tab-led-strip .functions .function-t.btnOn {background: orange;}
|
||||
|
||||
.tab-led-strip .dirN.btnOn {background: #FFF; color: #000;}
|
||||
.tab-led-strip .dirE.btnOn {background: #FFF; color: #000;}
|
||||
.tab-led-strip .dirS.btnOn {background: #FFF; color: #000;}
|
||||
.tab-led-strip .dirW.btnOn {background: #FFF; color: #000;}
|
||||
.tab-led-strip .dirU.btnOn {background: #FFF; color: #000;}
|
||||
.tab-led-strip .dirD.btnOn {background: #FFF; color: #000;}
|
||||
.tab-led-strip .directions .btnOn {background: #FFF; color: #000;}
|
||||
|
||||
.tab-led-strip .indicators {
|
||||
position: relative;
|
||||
|
@ -235,24 +230,24 @@
|
|||
outline: none;
|
||||
}
|
||||
|
||||
.tab-led-strip .orientation {
|
||||
.tab-led-strip .directions {
|
||||
width: 130px;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab-led-strip .orientation button {
|
||||
.tab-led-strip .directions button {
|
||||
position: absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.tab-led-strip .orientation .dirN {top: 0; left: 32px;}
|
||||
.tab-led-strip .orientation .dirS {bottom: 0; left: 32px;}
|
||||
.tab-led-strip .orientation .dirE {left: 64px; top: 32px;}
|
||||
.tab-led-strip .orientation .dirW {left: 0; top: 32px;}
|
||||
.tab-led-strip .orientation .dirU {right: 0; top: 15px;}
|
||||
.tab-led-strip .orientation .dirD {right: 0; bottom: 15px;}
|
||||
.tab-led-strip .directions .dir-n {top: 0; left: 32px;}
|
||||
.tab-led-strip .directions .dir-s {bottom: 0; left: 32px;}
|
||||
.tab-led-strip .directions .dir-e {left: 64px; top: 32px;}
|
||||
.tab-led-strip .directions .dir-w {left: 0; top: 32px;}
|
||||
.tab-led-strip .directions .dir-u {right: 0; top: 15px;}
|
||||
.tab-led-strip .directions .dir-d {right: 0; bottom: 15px;}
|
||||
|
||||
.tab-led-strip .wires-remaining {
|
||||
float: right;
|
||||
|
@ -288,4 +283,27 @@
|
|||
position: absolute;
|
||||
z-index: 100;
|
||||
border: 1px dotted white;
|
||||
}
|
||||
|
||||
.tab-led-strip > .buttons {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.tab-led-strip .save {
|
||||
display: block;
|
||||
float: right;
|
||||
|
||||
height: 28px;
|
||||
line-height: 28px;
|
||||
|
||||
padding: 0 15px 0 15px;
|
||||
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
|
||||
border: 1px solid silver;
|
||||
background-color: #ececec;
|
||||
}
|
||||
.tab-led-strip.save:hover {
|
||||
background-color: #dedcdc;
|
||||
}
|
|
@ -8,23 +8,23 @@
|
|||
<div class="wires-remaining"><div></div>Remaining</div>
|
||||
<button class="funcClear">Clear selected</button>
|
||||
|
||||
<div class="section">LED Modes</div>
|
||||
<div class="modes">
|
||||
<button class="modeW w50">Warnings</button>
|
||||
<button class="modeF w50">Flight & Orientation</button><br>
|
||||
<button class="modeI w33">Indicator</button>
|
||||
<button class="modeA w33">Arm State</button>
|
||||
<button class="modeT w33">Thrust</button>
|
||||
<div class="section">LED Functions</div>
|
||||
<div class="functions">
|
||||
<button class="function-w w50">Warnings</button>
|
||||
<button class="function-f w50">Flight & Orientation</button><br>
|
||||
<button class="function-i w33">Indicator</button>
|
||||
<button class="function-a w33">Arm State</button>
|
||||
<button class="function-t w33">Thrust</button>
|
||||
</div>
|
||||
|
||||
<div class="section">LED Orientation</div>
|
||||
<div class="orientation">
|
||||
<button class="dirN">N</button>
|
||||
<button class="dirE">E</button>
|
||||
<button class="dirS">S</button>
|
||||
<button class="dirW">W</button>
|
||||
<button class="dirU">U</button>
|
||||
<button class="dirD">D</button>
|
||||
<div class="directions">
|
||||
<button class="dir-n">N</button>
|
||||
<button class="dir-e">E</button>
|
||||
<button class="dir-s">S</button>
|
||||
<button class="dir-w">W</button>
|
||||
<button class="dir-u">U</button>
|
||||
<button class="dir-d">D</button>
|
||||
</div>
|
||||
|
||||
|
||||
|
@ -43,4 +43,9 @@
|
|||
</div>
|
||||
|
||||
</div>
|
||||
<div class="clear-both"></div>
|
||||
<div class="buttons">
|
||||
<a class="save" href="#" i18n="ledStripButtonSave"></a>
|
||||
</div>
|
||||
|
||||
</div>
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
TABS.led_strip = {
|
||||
wireMode: false,
|
||||
flightModes: ['w', 'f', 'i', 'a', 't'],
|
||||
ledOrientations: ['n', 'e', 's', 'w', 'u', 'd'],
|
||||
functions: ['w', 'f', 'i', 'a', 't'],
|
||||
directions: ['n', 'e', 's', 'w', 'u', 'd'],
|
||||
};
|
||||
|
||||
TABS.led_strip.initialize = function (callback, scrollPosition) {
|
||||
|
@ -71,11 +71,11 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
|||
|
||||
|
||||
// Directional Buttons
|
||||
$('.orientation').on('click', 'button', function() {
|
||||
$('.directions').on('click', 'button', function() {
|
||||
var that = this;
|
||||
if ($('.ui-selected').length > 0) {
|
||||
TABS.led_strip.ledOrientations.forEach(function(letter) {
|
||||
if ($(that).is('.dir' + letter.toUpperCase())) {
|
||||
TABS.led_strip.directions.forEach(function(letter) {
|
||||
if ($(that).is('.dir-' + letter)) {
|
||||
$(that).toggleClass('btnOn');
|
||||
$('.ui-selected').toggleClass('dir-' + letter);
|
||||
}
|
||||
|
@ -87,13 +87,13 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
|||
|
||||
|
||||
// Mode Buttons
|
||||
$('.modes').on('click', 'button', function() {
|
||||
$('.functions').on('click', 'button', function() {
|
||||
var that = this;
|
||||
if ($('.ui-selected').length > 0) {
|
||||
TABS.led_strip.flightModes.forEach(function(letter) {
|
||||
if ($(that).is('.mode' + letter.toUpperCase())) {
|
||||
TABS.led_strip.functions.forEach(function(letter) {
|
||||
if ($(that).is('.function-' + letter)) {
|
||||
$(that).toggleClass('btnOn');
|
||||
$('.ui-selected').toggleClass('mode-' + letter);
|
||||
$('.ui-selected').toggleClass('function-' + letter);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -145,19 +145,19 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
|||
|
||||
var that = this;
|
||||
|
||||
TABS.led_strip.ledOrientations.forEach(function(letter) {
|
||||
TABS.led_strip.directions.forEach(function(letter) {
|
||||
if ($(that).is('.dir-' + letter)) {
|
||||
$('.dir' + letter.toUpperCase()).addClass('btnOn');
|
||||
$('.dir-' + letter).addClass('btnOn');
|
||||
} else {
|
||||
$('.dir' + letter.toUpperCase()).removeClass('btnOn');
|
||||
$('.dir-' + letter).removeClass('btnOn');
|
||||
}
|
||||
});
|
||||
|
||||
TABS.led_strip.flightModes.forEach(function(letter) {
|
||||
if ($(that).is('.mode-' + letter)) {
|
||||
$('.mode' + letter.toUpperCase()).addClass('btnOn');
|
||||
TABS.led_strip.functions.forEach(function(letter) {
|
||||
if ($(that).is('.function-' + letter)) {
|
||||
$('.function-' + letter).addClass('btnOn');
|
||||
} else {
|
||||
$('.mode' + letter.toUpperCase()).removeClass('btnOn');
|
||||
$('.function-' + letter).removeClass('btnOn');
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -191,7 +191,7 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
|||
$(this).find('.wire').html(ledIndex);
|
||||
|
||||
for (var modeIndex = 0; modeIndex < led.functions.length; modeIndex++) {
|
||||
$(this).addClass('mode-' + led.functions[modeIndex]);
|
||||
$(this).addClass('function-' + led.functions[modeIndex]);
|
||||
}
|
||||
|
||||
for (var directionIndex = 0; directionIndex < led.directions.length; directionIndex++) {
|
||||
|
@ -201,6 +201,16 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
|||
});
|
||||
updateBulkCmd();
|
||||
|
||||
$('a.save').click(function () {
|
||||
|
||||
MSP.sendLedStripConfig(save_to_eeprom);
|
||||
|
||||
function save_to_eeprom() {
|
||||
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, reboot);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
if (callback) callback();
|
||||
}
|
||||
|
||||
|
@ -216,38 +226,50 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
|||
|
||||
function updateBulkCmd() {
|
||||
$('.tempOutput').empty();
|
||||
$('.tempOutput').html('# Copy and paste commands below into the CLI' + "\n\n");
|
||||
$('.tempOutput').html('# CLI commands' + "\n\n");
|
||||
var counter = 0;
|
||||
|
||||
var lines = [];
|
||||
var ledStripLength = LED_STRIP.length;
|
||||
|
||||
LED_STRIP = [];
|
||||
|
||||
$('.gPoint').each(function(){
|
||||
if ($(this).is('[class*="mode"]')) {
|
||||
if ($(this).is('[class*="function"]')) {
|
||||
var gridNumber = ($(this).index() + 1);
|
||||
var row = Math.ceil(gridNumber / 16) - 1;
|
||||
var col = gridNumber/16 % 1 * 16 - 1;
|
||||
if (col < 0) {col = 15;}
|
||||
|
||||
var wireNumber = $(this).find('.wire').html();
|
||||
var ledModes = '';
|
||||
var functions = '';
|
||||
var directions = '';
|
||||
var that = this;
|
||||
|
||||
TABS.led_strip.flightModes.forEach(function(letter){
|
||||
if ($(that).is('.mode-' + letter)) {
|
||||
ledModes += letter.toUpperCase();
|
||||
TABS.led_strip.functions.forEach(function(letter){
|
||||
if ($(that).is('.function-' + letter)) {
|
||||
functions += letter;
|
||||
}
|
||||
});
|
||||
|
||||
TABS.led_strip.ledOrientations.forEach(function(letter){
|
||||
TABS.led_strip.directions.forEach(function(letter){
|
||||
if ($(that).is('.dir-' + letter)) {
|
||||
directions += letter.toUpperCase();
|
||||
directions += letter;
|
||||
}
|
||||
});
|
||||
|
||||
if (wireNumber != '') {
|
||||
var line = 'led ' + wireNumber + ' ' + col + ',' + row + ':' + directions + ':' + ledModes;
|
||||
var line = 'led ' + wireNumber + ' ' + col + ',' + row + ':' + directions.toUpperCase() + ':' + functions.toUpperCase();
|
||||
lines[wireNumber] = line;
|
||||
|
||||
var led = {
|
||||
x: col,
|
||||
y: row,
|
||||
directions: directions,
|
||||
functions: functions
|
||||
}
|
||||
|
||||
LED_STRIP[wireNumber] = led;
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
@ -255,9 +277,25 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
|||
|
||||
$('.tempOutput').append(lines.join("\n"));
|
||||
|
||||
var defaultLed = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
directions: '',
|
||||
functions: ''
|
||||
};
|
||||
|
||||
for (var i = 0; i < ledStripLength; i++) {
|
||||
if (LED_STRIP[i]) {
|
||||
continue;
|
||||
}
|
||||
LED_STRIP[i] = defaultLed;
|
||||
}
|
||||
console.log(LED_STRIP);
|
||||
|
||||
var usedWireNumbers = buildUsedWireNumbers();
|
||||
|
||||
var remaining = LED_STRIP.length - usedWireNumbers.length;
|
||||
|
||||
$('.wires-remaining div').html(remaining);
|
||||
}
|
||||
|
||||
|
|
|
@ -38,12 +38,6 @@
|
|||
.tab-ports select {
|
||||
border: 1px solid silver;
|
||||
}
|
||||
.tab-ports > .buttons {
|
||||
width: calc(100% - 20px);
|
||||
|
||||
margin-top: 10px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
.tab-ports .save {
|
||||
display: block;
|
||||
|
|
Loading…
Reference in New Issue