Add Race Transponder configuration support.

Also cleans up i18n support for 'features' and adds tooltip support for
them on the configuration tab.
pull/3/head
Dominic Clifton 9 years ago
parent 5c2273bd65
commit 1a58bfcf82

@ -87,6 +87,12 @@
"tabServos": {
"message": "Servos"
},
"tabFailsafe": {
"message": "Failsafe"
},
"tabTransponder": {
"message": "Race Transponder"
},
"tabGPS": {
"message": "GPS"
},
@ -433,6 +439,88 @@
"message": "EEPROM <span style=\"color: #57a929\">saved</span>"
},
"featureRX_PPM": {
"message": "PPM RX input"
},
"featureVBAT": {
"message": "Battery voltage monitoring"
},
"featureINFLIGHT_ACC_CAL": {
"message": "In-flight level calibration"
},
"featureRX_SERIAL": {
"message": "Serial-based receiver (SPEKSAT, SBUS, SUMD)"
},
"featureMOTOR_STOP": {
"message": "Don't spin the motors when armed"
},
"featureSERVO_TILT": {
"message": "Servo gimbal"
},
"featureSOFTSERIAL": {
"message": "Enable CPU based serial ports"
},
"featureSOFTSERIALTip": {
"message": "Configure ports on the Ports tab after enabling."
},
"featureGPS": {
"message": "GPS for navigation and telemetry"
},
"featureGPSTip": {
"message": "Configure port scenario first"
},
"featureFAILSAFE": {
"message": "Apply failsafe settings on RX signal loss"
},
"featureSONAR": {
"message": "Sonar"
},
"featureTELEMETRY": {
"message": "Telemetry output"
},
"featureCURRENT_METER": {
"message": "Battery current monitoring"
},
"feature3D": {
"message": "3D mode (for use with reversible ESCs)"
},
"featureRX_PARALLEL_PWM": {
"message": "PWM RX input (one wire per channel)"
},
"featureRX_MSP": {
"message": "MSP RX input (control via MSP port)"
},
"featureRSSI_ADC": {
"message": "Analog RSSI input"
},
"featureLED_STRIP": {
"message": "Multi-color RGB LED strip support"
},
"featureDISPLAY": {
"message": "OLED Screen Display"
},
"featureONESHOT125": {
"message": "ONESHOT ESC support"
},
"featureONESHOT125Tip": {
"message": "Disconnect flight battery and remove props before enabling."
},
"featureBLACKBOX": {
"message": "Blackbox flight data recorder"
},
"featureBLACKBOXTip": {
"message": "Configure via the BlackBox tab after enabling."
},
"featureCHANNEL_FORWARDING": {
"message": "Forward aux channels to servo outputs"
},
"featureTRANSPONDER": {
"message": "Race Transponder"
},
"featureTRANSPONDERTip": {
"message": "Configure via the Race Transponder tab after enabling."
},
"configurationFeatureEnabled": {
"message": "Enabled"
},
@ -943,6 +1031,33 @@
"message": "EEPROM <span style=\"color: #57a929\">saved</span>"
},
"transponderNotSupported": {
"message": "Your flight controller's firmware does not support transponder functionality."
},
"transponderHelp": {
"message": "Configure your transponder code here. Note: Only valid codes will be recognised by race timing systems. Valid transponder codes can be obtained from <a href=\"http://seriouslypro.com/transponder-codes\" target=\"_blank\">Seriously Pro</a>."
},
"transponderInformation": {
"message": "Transponders systems allow race organizers to time your laps. The transponder is fitted to your aircraft and when your aircraft passes the timing gate the track-side receiver registers your code and records your laptime. When fitting an IR based transponder your should ensure that it points outward from your aircraft towards the track-side receivers and that the light beam is not obstructed by your airframe, battery-straps, cables, propellers, etc."
},
"transponderConfiguration": {
"message": "Configuration"
},
"transponderData": {
"message": "Data"
},
"transponderDataHelp": {
"message": "Hexadecimal digits only, 0-9, A-F"
},
"transponderButtonSave": {
"message": "Save"
},
"transponderDataInvalid": {
"message": "Transponder data is <span style=\"color: red\">invalid</span>"
},
"transponderEepromSaved": {
"message": "EEPROM <span style=\"color: #57a929\">saved</span>"
},
"servosFirmwareUpgradeRequired": {
"message": "Servos requires firmware &gt;= 1.10.0. and target support."

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="595.281px" height="841.891px" viewBox="0 0 595.281 841.891" enable-background="new 0 0 595.281 841.891"
xml:space="preserve">
<g>
<path fill="#818181" d="M127.71,440.9c-7.142,41.59,6.722,84.439,36.549,114.267s72.677,43.69,114.267,36.549
c11.763-2.101,19.745-13.443,18.064-25.206c-0.84-4.621-2.94-8.822-5.881-11.763c-4.621-4.621-11.763-7.142-18.904-6.302
c-27.727,4.621-56.293-4.621-76.458-24.365c-20.165-19.745-28.987-47.892-24.366-76.038c2.1-11.763-5.881-23.105-18.064-25.206
C140.733,420.735,129.811,429.137,127.71,440.9"/>
<path fill="#818181" d="M289.028,652.21c-0.42-5.461-2.521-10.502-6.302-14.283c-4.201-4.201-10.083-6.722-16.804-6.302
c-47.892,2.521-94.942-15.543-128.971-49.151c-34.028-33.607-51.672-81.079-48.731-128.971c0.84-12.183-8.402-22.265-20.585-23.105
c-12.183-0.84-22.265,8.402-23.105,20.585c-3.36,60.494,19.325,119.309,62.175,162.158c42.85,42.851,101.664,65.115,162.158,62.175
C280.626,674.895,289.868,664.392,289.028,652.21"/>
</g>
<g>
<path fill="#818181" d="M480.616,308.596c-10.826,0-19.984,13.633-23.733,32.085h-97.416v32.084h97.416
c3.332,18.451,12.491,32.088,23.733,32.088c13.735,0,24.977-21.659,24.977-48.131C505.592,330.255,494.351,308.596,480.616,308.596
z"/>
<path fill="#818181" d="M297.853,252.445c-29.975,0-55.369,36.899-64.945,88.236h-91.171
c-3.331-18.452-12.491-32.085-23.729-32.085c-13.739,0-24.979,21.658-24.979,48.126c0,26.472,11.24,48.131,24.979,48.131
c10.822,0,19.982-13.637,23.729-32.088h87.426h132.386h4.995C363.631,304.584,334.073,252.445,297.853,252.445z"/>
<rect x="21.007" y="280.52" fill="#818181" width="191.502" height="23.262"/>
<rect x="381.115" y="280.52" fill="#818181" width="191.504" height="23.262"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="595.281px" height="841.891px" viewBox="0 0 595.281 841.891" enable-background="new 0 0 595.281 841.891"
xml:space="preserve">
<g>
<path fill="#FFFFFF" d="M127.71,440.9c-7.142,41.59,6.722,84.439,36.549,114.267s72.677,43.69,114.267,36.549
c11.763-2.101,19.745-13.443,18.064-25.206c-0.84-4.621-2.94-8.822-5.881-11.763c-4.621-4.621-11.763-7.142-18.904-6.302
c-27.727,4.621-56.293-4.621-76.458-24.365c-20.165-19.745-28.987-47.892-24.366-76.038c2.1-11.763-5.881-23.105-18.064-25.206
C140.733,420.735,129.811,429.137,127.71,440.9"/>
<path fill="#FFFFFF" d="M289.028,652.21c-0.42-5.461-2.521-10.502-6.302-14.283c-4.201-4.201-10.083-6.722-16.804-6.302
c-47.892,2.521-94.942-15.543-128.971-49.151c-34.028-33.607-51.672-81.079-48.731-128.971c0.84-12.183-8.402-22.265-20.585-23.105
c-12.183-0.84-22.265,8.402-23.105,20.585c-3.36,60.494,19.325,119.309,62.175,162.158c42.85,42.851,101.664,65.115,162.158,62.175
C280.626,674.895,289.868,664.392,289.028,652.21"/>
</g>
<g>
<path fill="#FFFFFF" d="M480.616,308.596c-10.826,0-19.984,13.633-23.733,32.085h-97.416v32.084h97.416
c3.332,18.451,12.491,32.088,23.733,32.088c13.735,0,24.977-21.659,24.977-48.131C505.592,330.255,494.351,308.596,480.616,308.596
z"/>
<path fill="#FFFFFF" d="M297.853,252.445c-29.975,0-55.369,36.899-64.945,88.236h-91.171
c-3.331-18.452-12.491-32.085-23.729-32.085c-13.739,0-24.979,21.658-24.979,48.126c0,26.472,11.24,48.131,24.979,48.131
c10.822,0,19.982-13.637,23.729-32.088h87.426h132.386h4.995C363.631,304.584,334.073,252.445,297.853,252.445z"/>
<rect x="21.007" y="280.52" fill="#FFFFFF" width="191.502" height="23.262"/>
<rect x="381.115" y="280.52" fill="#FFFFFF" width="191.504" height="23.262"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

@ -29,6 +29,7 @@ var _3D;
var DATAFLASH;
var SDCARD;
var BLACKBOX;
var TRANSPONDER;
var RC_deadband;
var SENSOR_ALIGNMENT;
var RX_CONFIG;
@ -217,6 +218,11 @@ var FC = {
blackboxRateDenom: 1
};
TRANSPONDER = {
supported: false,
data: []
};
RC_deadband = {
deadband: 0,
yaw_deadband: 0,

@ -19,6 +19,7 @@ var GUI_control = function () {
];
this.defaultAllowedTabsWhenConnected = [
'failsafe',
'transponder',
'adjustments',
'auxiliary',
'cli',
@ -275,10 +276,12 @@ GUI_control.prototype.content_ready = function (callback) {
$(elem).removeClass('togglemedium');
});
// Build link to in-use CF version documentation
var documentationButton = $('div#content #button-documentation');
documentationButton.html("Documentation for "+CONFIG.flightControllerVersion);
documentationButton.attr("href","https://github.com/cleanflight/cleanflight/tree/v{0}/docs".format(CONFIG.flightControllerVersion));
if (CONFIGURATOR.connectionValid) {
// Build link to in-use CF version documentation
var documentationButton = $('div#content #button-documentation');
documentationButton.html("Documentation for " + CONFIG.flightControllerVersion);
documentationButton.attr("href","https://github.com/cleanflight/cleanflight/tree/v{0}/docs".format(CONFIG.flightControllerVersion));
}
// loading tooltip
jQuery(document).ready(function($) {

@ -38,6 +38,8 @@ var MSP_codes = {
MSP_SDCARD_SUMMARY: 79,
MSP_BLACKBOX_CONFIG: 80,
MSP_SET_BLACKBOX_CONFIG: 81,
MSP_TRANSPONDER_CONFIG: 82,
MSP_SET_TRANSPONDER_CONFIG: 83,
// Multiwii MSP commands
MSP_IDENT: 100,
@ -932,6 +934,18 @@ var MSP = {
case MSP_codes.MSP_SET_BLACKBOX_CONFIG:
console.log("Blackbox config saved");
break;
case MSP_codes.MSP_TRANSPONDER_CONFIG:
var offset = 0;
TRANSPONDER.supported = (data.getUint8(offset++) & 1) != 0;
TRANSPONDER.data = [];
var bytesRemaining = data.byteLength - offset;
for (var i = 0; i < bytesRemaining; i++) {
TRANSPONDER.data.push(data.getUint8(offset++));
}
break;
case MSP_codes.MSP_SET_TRANSPONDER_CONFIG:
console.log("Transponder config saved");
break;
case MSP_codes.MSP_SET_MODE_RANGE:
console.log('Mode range saved');
break;
@ -1242,6 +1256,12 @@ MSP.crunch = function (code) {
}
break;
case MSP_codes.MSP_SET_TRANSPONDER_CONFIG:
for (var i = 0; i < TRANSPONDER.data.length; i++) {
buffer.push(TRANSPONDER.data[i]);
}
break;
case MSP_codes.MSP_SET_CHANNEL_FORWARDING:
for (var i = 0; i < SERVO_CONFIG.length; i++) {
var out = SERVO_CONFIG[i].indexOfChannelToForward;

@ -784,6 +784,19 @@ li.active .ic_flasher {
background-image: url(images/icons/cf_icon_flasher_white.svg);
}
.ic_transponder {
background-image: url(images/icons/cf_icon_transponder_grey.svg);
}
.ic_transponder:hover {
background-image: url(images/icons/cf_icon_transponder_white.svg);
}
li.active .ic_transponder {
background-image: url(images/icons/cf_icon_transponder_white.svg);
}
/* SPARE Tab-Icons */
.ic_failsafe {
background-image: url(images/icons/cf_icon_failsafe_grey.svg);

@ -26,6 +26,7 @@
<link type="text/css" rel="stylesheet" href="./tabs/adjustments.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/auxiliary.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/failsafe.css" media="all" />
<link type="text/css" rel="stylesheet" href="./tabs/transponder.css" media="all" />
<link type="text/css" rel="stylesheet" href="./css/opensans_webfontkit/fonts.css" media="all" />
<link type="text/css" rel="stylesheet" href="./css/dropdown-lists/css/style_lists.css" media="all" />
<link type="text/css" rel="stylesheet" href="./js/libraries/switchery/switchery.css" media="all" />
@ -78,6 +79,7 @@
<script type="text/javascript" src="./tabs/onboard_logging.js"></script>
<script type="text/javascript" src="./tabs/firmware_flasher.js"></script>
<script type="text/javascript" src="./tabs/failsafe.js"></script>
<script type="text/javascript" src="./tabs/transponder.js"></script>
<title></title>
</head>
<body>
@ -191,7 +193,7 @@
<li class="tab_setup"><a href="#" i18n="tabSetup" class="tabicon ic_setup" title="Setup"></a></li>
<li class="tab_ports"><a href="#" i18n="tabPorts" class="tabicon ic_ports" title="Ports"></a></li>
<li class="tab_configuration"><a href="#" i18n="tabConfiguration" class="tabicon ic_config" title="Configuration"></a></li>
<li class="tab_failsafe"><a href="#" class="tabicon ic_failsafe" title="Failsafe">Failsafe</a></li>
<li class="tab_failsafe"><a href="#" i18n="tabFailsafe" class="tabicon ic_failsafe" title="Failsafe"></a></li>
<li class="tab_pid_tuning"><a href="#" i18n="tabPidTuning" class="tabicon ic_pid" title="PID Tuning"></a></li>
<li class="tab_receiver"><a href="#" i18n="tabReceiver" class="tabicon ic_rx" title="Receiver"></a></li>
<li class="tab_auxiliary"><a href="#" i18n="tabAuxiliary" class="tabicon ic_modes" title="Modes"></a></li>
@ -199,6 +201,7 @@
<li class="tab_servos"><a href="#" i18n="tabServos" class="tabicon ic_servo" title="Servos"></a></li>
<li class="tab_gps"><a href="#" i18n="tabGPS" class="tabicon ic_gps" title="GPS"></a></li>
<li class="tab_motors"><a href="#" i18n="tabMotorTesting" class="tabicon ic_motor" title="Motors"></a></li>
<li class="tab_transponder"><a href="#" i18n="tabTransponder" class="tabicon ic_transponder" title="Transponder"></a></li>
<li class="tab_led_strip"><a href="#" i18n="tabLedStrip" class="tabicon ic_led" title="LED Strip"></a></li>
<li class="tab_sensors"><a href="#" i18n="tabRawSensorData" class="tabicon ic_sensors" title="Sensors"></a></li>
<li class="tab_logging"><a href="#" i18n="tabLogging" class="tabicon ic_log" title="Tethered Logging"></a></li>

@ -136,6 +136,9 @@ $(document).ready(function () {
case 'failsafe':
TABS.failsafe.initialize(content_ready);
break;
case 'transponder':
TABS.transponder.initialize(content_ready);
break;
case 'setup':
TABS.setup.initialize(content_ready);
break;

@ -89,9 +89,7 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
}
function process_html() {
// translate to user-selected language
localize();
var mixer_list_e = $('select.mixerList');
for (var i = 0; i < mixerList.length; i++) {
mixer_list_e.append('<option value="' + (i + 1) + '">' + mixerList[i].name + '</option>');
@ -110,37 +108,37 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
// generate features
var features = [
{bit: 0, group: 'rxMode', mode: 'group', name: 'RX_PPM', description: 'PPM RX input'},
{bit: 1, group: 'batteryVoltage', name: 'VBAT', description: 'Battery voltage monitoring'},
{bit: 2, group: 'other', name: 'INFLIGHT_ACC_CAL', description: 'In-flight level calibration'},
{bit: 3, group: 'rxMode', mode: 'group', name: 'RX_SERIAL', description: 'Serial-based receiver (SPEKSAT, SBUS, SUMD)'},
{bit: 4, group: 'esc', name: 'MOTOR_STOP', description: 'Don\'t spin the motors when armed'},
{bit: 5, group: 'other', name: 'SERVO_TILT', description: 'Servo gimbal'},
{bit: 6, group: 'other', name: 'SOFTSERIAL', description: 'Enable CPU based serial ports'},
{bit: 7, group: 'gps', name: 'GPS', description: 'Configure port scenario first'},
{bit: 8, group: 'rxFailsafe', name: 'FAILSAFE', description: 'Failsafe settings on RX signal loss'},
{bit: 9, group: 'other', name: 'SONAR', description: 'Sonar'},
{bit: 10, group: 'other', name: 'TELEMETRY', description: 'Telemetry output'},
{bit: 11, group: 'batteryCurrent', name: 'CURRENT_METER', description: 'Battery current monitoring'},
{bit: 12, group: 'other', name: '3D', description: '3D mode (for use with reversible ESCs)'},
{bit: 13, group: 'rxMode', mode: 'group', name: 'RX_PARALLEL_PWM', description: 'PWM RX input'},
{bit: 14, group: 'rxMode', mode: 'group', name: 'RX_MSP', description: 'MSP RX input'},
{bit: 15, group: 'rssi', name: 'RSSI_ADC', description: 'Analog RSSI input'},
{bit: 16, group: 'other', name: 'LED_STRIP', description: 'Addressable RGB LED strip support'},
{bit: 17, group: 'other', name: 'DISPLAY', description: 'OLED Screen Display'},
{bit: 18, group: 'esc', name: 'ONESHOT125', description: 'ONESHOT ESC support (disconnect ESCs, remove props)'},
{bit: 19, group: 'other', name: 'BLACKBOX', description: 'Blackbox flight data recorder'}
{bit: 0, group: 'rxMode', mode: 'group', name: 'RX_PPM'},
{bit: 1, group: 'batteryVoltage', name: 'VBAT'},
{bit: 2, group: 'other', name: 'INFLIGHT_ACC_CAL'},
{bit: 3, group: 'rxMode', mode: 'group', name: 'RX_SERIAL'},
{bit: 4, group: 'esc', name: 'MOTOR_STOP'},
{bit: 5, group: 'other', name: 'SERVO_TILT'},
{bit: 6, group: 'other', name: 'SOFTSERIAL', haveTip: true},
{bit: 7, group: 'gps', name: 'GPS', haveTip: true},
{bit: 8, group: 'rxFailsafe', name: 'FAILSAFE'},
{bit: 9, group: 'other', name: 'SONAR'},
{bit: 10, group: 'other', name: 'TELEMETRY'},
{bit: 11, group: 'batteryCurrent', name: 'CURRENT_METER'},
{bit: 12, group: 'other', name: '3D'},
{bit: 13, group: 'rxMode', mode: 'group', name: 'RX_PARALLEL_PWM'},
{bit: 14, group: 'rxMode', mode: 'group', name: 'RX_MSP'},
{bit: 15, group: 'rssi', name: 'RSSI_ADC'},
{bit: 16, group: 'other', name: 'LED_STRIP'},
{bit: 17, group: 'other', name: 'DISPLAY'},
{bit: 18, group: 'esc', name: 'ONESHOT125', haveTip: true},
{bit: 19, group: 'other', name: 'BLACKBOX', haveTip: true}
];
if (semver.gte(CONFIG.apiVersion, "1.12.0")) {
features.push(
{bit: 20, group: 'other', name: 'CHANNEL_FORWARDING', description: 'Forward aux channels to servo outputs'}
{bit: 20, group: 'other', name: 'CHANNEL_FORWARDING'}
);
}
if (semver.gte(CONFIG.apiVersion, "1.15.0")) {
if (semver.gte(CONFIG.apiVersion, "1.16.0")) {
features.push(
{bit: 21, group: 'other', name: 'TRANSPONDER', description: 'Transponder'}
{bit: 21, group: 'other', name: 'TRANSPONDER', haveTip: true}
);
}
@ -159,6 +157,11 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
for (var i = 0; i < features.length; i++) {
var row_e;
var feature_tip_html = '';
if (features[i].haveTip) {
feature_tip_html = '<div class="helpicon cf_tip" i18n_title="feature' + features[i].name + 'Tip"></div>';
}
if (features[i].mode === 'group') {
row_e = $('<tr><td style="width: 15px;"><input style="width: 13px;" class="feature" id="feature-'
+ i
@ -172,9 +175,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
+ i
+ '">'
+ features[i].name
+ '</label></td><td><span>'
+ features[i].description
+ '</td><span>');
+ '</label></td><td><span i18n="feature' + features[i].name + '"></span>'
+ feature_tip_html + '</td></tr>');
radioGroups.push(features[i].group);
} else {
row_e = $('<tr><td><input class="feature toggle"'
@ -187,9 +189,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
+ i
+ '">'
+ features[i].name
+ '</label></td><td><span>'
+ features[i].description
+ '</span></td>');
+ '</label></td><td><span i18n="feature' + features[i].name + '"></span>'
+ feature_tip_html + '</td></tr>');
var feature_e = row_e.find('input.feature');
@ -203,6 +204,9 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
}
});
}
// translate to user-selected language
localize();
for (var i = 0; i < radioGroups.length; i++) {
var group = radioGroups[i];

@ -0,0 +1,75 @@
.tab-transponder .spacer_box {
padding-bottom: 10px;
float: left;
width: calc(100% - 20px);
}
.tab-transponder .text input {
width: 100px;
padding-left: 3px;
height: 20px;
line-height: 20px;
text-align: left;
border: 1px solid silver;
border-radius: 3px;
margin-right: 11px;
font-size: 12px;
font-weight: normal;
}
.tab-transponder .text .disabled {
width: 43px;
padding: 0px 5px;
background-color: #ececec;
}
.tab-transponder .text span {
margin-left: 0px;
}
.tab-transponder input {
float: left;
}
.tab-transponder span {
margin: 0px;
}
.tab-transponder .text
{
margin-bottom: 5px;
clear: left;
padding-bottom: 5px;
border-bottom: 1px solid #ddd;
width: 100%;
float: left;
}
.tab-transponder .text:last-child {
border-bottom: none;
padding-bottom: 0px;
margin-bottom: 0px;
}
.tab-transponder .textspacer {
float: left;
width: 115px;
height: 21px;
}
.tab-transponder .gui_box span {
font-style: normal;
font-family: 'open_sansregular', Arial;
line-height: 19px;
color: #4F4F4F;
font-size: 11px;
}
.require-transponder-supported,
.tab-transponder.transponder-supported .require-transponder-unsupported {
display: none;
}
.tab-transponder.transponder-supported .require-transponder-supported {
display: block;
}

@ -0,0 +1,52 @@
<div class="tab-transponder toolbar_fixed_bottom">
<div class="content_wrapper">
<div class="tab_title" i18n="tabTransponder">Transponder</div>
<div class="cf_doc_version_bt">
<a id="button-documentation" href="https://github.com/cleanflight/cleanflight/releases" target="_blank"></a>
</div>
<div class="require-transponder-unsupported note">
<div class="note_spacer">
<p i18n="transponderNotSupported"></p>
</div>
</div>
<div class="require-transponder-supported">
<div class="note" style="margin-bottom: 20px;">
<div class="note_spacer">
<p i18n="transponderHelp"></p>
</div>
</div>
<div class="gui_box grey">
<div class="gui_box_titlebar">
<div class="spacer_box_title" i18n="transponderConfiguration"></div>
</div>
<div class="spacer_box">
<div class="text transponderData">
<div class="textspacer" >
<input type="text" name="data" spellcheck="false"/>
</div>
<label for="failsafe_feature_new"><span i18n="transponderData"></span>
</label>
<div class="helpicon cf_tip" i18n_title="transponderDataHelp"></div>
</div>
</div>
</div>
<div class="clear-both"></div>
</div>
<div class="note">
<div class="note_spacer">
<p i18n="transponderInformation"></p>
</div>
</div>
</div>
<div class="content_toolbar require-transponder-supported">
<div class="btn save_btn">
<a class="save" href="#" i18n="transponderButtonSave"></a>
</div>
</div>
</div>

@ -0,0 +1,105 @@
'use strict';
TABS.transponder = {
available: false
};
TABS.transponder.initialize = function (callback, scrollPosition) {
var self = this;
if (GUI.active_tab != 'transponder') {
GUI.active_tab = 'transponder';
googleAnalytics.sendAppView('Transponder');
}
// transponder supported added in MSP API Version 1.16.0
TABS.transponder.available = semver.gte(CONFIG.apiVersion, "1.16.0");
if (!TABS.transponder.available) {
load_html();
return;
}
function load_html() {
$('#content').load("./tabs/transponder.html", process_html);
}
// get the transponder data and a flag to see if transponder support is enabled on the FC
MSP.send_message(MSP_codes.MSP_TRANSPONDER_CONFIG, false, false, load_html);
// Convert a hex string to a byte array
function hexToBytes(hex) {
for (var bytes = [], c = 0; c < hex.length; c += 2)
bytes.push(~parseInt(hex.substr(c, 2), 16));
return bytes;
}
function pad(n, width) {
n = n + '';
return n.length >= width ? n : new Array(width - n.length + 1).join('0') + n;
}
// Convert a byte array to a hex string
function bytesToHex(bytes) {
for (var hex = [], i = 0; i < bytes.length; i++) {
hex.push(pad(((~bytes[i]) & 0xFF).toString(16),2));
}
return hex.join("").toUpperCase();
}
function process_html() {
// translate to user-selected language
localize();
$(".tab-transponder")
.toggleClass("transponder-supported", TABS.transponder.available && TRANSPONDER.supported);
if (TABS.transponder.available) {
var data = bytesToHex(TRANSPONDER.data);
$('input[name="data"]').val(data);
$('input[name="data"]').prop('maxLength', data.length);
$('a.save').click(function () {
// gather data that doesn't have automatic change event bound
var dataString = $('input[name="data"]').val();
var expectedLength = TRANSPONDER.data.length;
var hexRegExp = new RegExp('[0-9a-fA-F]{' + (expectedLength * 2) + '}', 'gi');
if (!dataString.match(hexRegExp)) {
GUI.log(chrome.i18n.getMessage('transponderDataInvalid'));
return;
}
TRANSPONDER.data = hexToBytes(dataString);
//
// send data to FC
//
function save_transponder_config() {
MSP.send_message(MSP_codes.MSP_SET_TRANSPONDER_CONFIG, MSP.crunch(MSP_codes.MSP_SET_TRANSPONDER_CONFIG), false, save_to_eeprom);
}
function save_to_eeprom() {
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, function () {
GUI.log(chrome.i18n.getMessage('transponderEepromSaved'));
});
}
save_transponder_config();
});
}
// status data pulled via separate timer with static speed
GUI.interval_add('status_pull', function status_pull() {
MSP.send_message(MSP_codes.MSP_STATUS);
}, 250, true);
GUI.content_ready(callback);
}
};
TABS.transponder.cleanup = function (callback) {
if (callback) callback();
};
Loading…
Cancel
Save