From 519de30f6e057d240fe07f7911604feaf3406d98 Mon Sep 17 00:00:00 2001 From: Dominic Clifton Date: Fri, 16 Jan 2015 00:15:41 +0000 Subject: [PATCH] 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. --- _locales/en/messages.json | 6 ++- js/msp.js | 69 +++++++++++++++++++++++++++--- tabs/adjustments.css | 3 -- tabs/auxiliary.css | 3 -- tabs/configuration.css | 7 --- tabs/led_strip.css | 68 ++++++++++++++++++----------- tabs/led_strip.html | 33 ++++++++------ tabs/led_strip.js | 90 ++++++++++++++++++++++++++++----------- tabs/ports.css | 6 --- 9 files changed, 192 insertions(+), 93 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 913abbb675..e506b15fb0 100755 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -948,7 +948,9 @@ "ledStripHelp": { "message": "The flight controller can control colors and effects of individual LEDs on a strip.
Configure LEDs on the grid, configure wiring order then attach LEDs on your aircraft according to grid positions." + }, + "ledStripButtonSave": { + "message": "Save" } - - + } diff --git a/js/msp.js b/js/msp.js index 226f921125..725004c7a5 100644 --- a/js/msp.js +++ b/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); + } +} + diff --git a/tabs/adjustments.css b/tabs/adjustments.css index 485b54deb2..9f9b2e5531 100644 --- a/tabs/adjustments.css +++ b/tabs/adjustments.css @@ -98,10 +98,7 @@ } .tab-adjustments > .buttons { - width: calc(100% - 20px); - margin-top: 10px; - bottom: 10px; } .tab-adjustments > .buttons a { diff --git a/tabs/auxiliary.css b/tabs/auxiliary.css index 500a2298a3..10d7ab1df3 100644 --- a/tabs/auxiliary.css +++ b/tabs/auxiliary.css @@ -139,10 +139,7 @@ } .tab-auxiliary > .buttons { - width: calc(100% - 20px); - margin-top: 10px; - bottom: 10px; } .tab-auxiliary > .buttons a { diff --git a/tabs/configuration.css b/tabs/configuration.css index 63f15a2e50..b95700d3ab 100644 --- a/tabs/configuration.css +++ b/tabs/configuration.css @@ -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; diff --git a/tabs/led_strip.css b/tabs/led_strip.css index 7594678ad2..3384ee0a8c 100644 --- a/tabs/led_strip.css +++ b/tabs/led_strip.css @@ -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; } \ No newline at end of file diff --git a/tabs/led_strip.html b/tabs/led_strip.html index cd04064efe..b0a70dfd2d 100644 --- a/tabs/led_strip.html +++ b/tabs/led_strip.html @@ -8,23 +8,23 @@
Remaining
-
LED Modes
-
- -
- - - +
LED Functions
+
+ +
+ + +
LED Orientation
-
- - - - - - +
+ + + + + +
@@ -43,4 +43,9 @@
+
+
+ +
+ \ No newline at end of file diff --git a/tabs/led_strip.js b/tabs/led_strip.js index a988899bad..9370eb93fa 100644 --- a/tabs/led_strip.js +++ b/tabs/led_strip.js @@ -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); } diff --git a/tabs/ports.css b/tabs/ports.css index ba3035e33c..b841ce8fa0 100644 --- a/tabs/ports.css +++ b/tabs/ports.css @@ -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;