mirror of
https://github.com/iNavFlight/inav-configurator.git
synced 2025-07-20 06:45:11 +03:00
Merge pull request #330 from cleanflight/spracingf3mini-sdcard
Add support for the SPRacingF3Mini (SD Card Blackbox Logging, Race Transponder, VCP)
This commit is contained in:
commit
ace6e32269
24 changed files with 1828 additions and 831 deletions
|
@ -87,6 +87,12 @@
|
||||||
"tabServos": {
|
"tabServos": {
|
||||||
"message": "Servos"
|
"message": "Servos"
|
||||||
},
|
},
|
||||||
|
"tabFailsafe": {
|
||||||
|
"message": "Failsafe"
|
||||||
|
},
|
||||||
|
"tabTransponder": {
|
||||||
|
"message": "Race Transponder"
|
||||||
|
},
|
||||||
"tabGPS": {
|
"tabGPS": {
|
||||||
"message": "GPS"
|
"message": "GPS"
|
||||||
},
|
},
|
||||||
|
@ -103,10 +109,10 @@
|
||||||
"message": "CLI"
|
"message": "CLI"
|
||||||
},
|
},
|
||||||
"tabLogging": {
|
"tabLogging": {
|
||||||
"message": "Logging"
|
"message": "Tethered Logging"
|
||||||
},
|
},
|
||||||
"tabDataflash": {
|
"tabOnboardLogging": {
|
||||||
"message": "Dataflash"
|
"message": "Blackbox"
|
||||||
},
|
},
|
||||||
"tabAdjustments": {
|
"tabAdjustments": {
|
||||||
"message": "Adjustments"
|
"message": "Adjustments"
|
||||||
|
@ -433,6 +439,88 @@
|
||||||
"message": "EEPROM <span style=\"color: #57a929\">saved</span>"
|
"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": {
|
"configurationFeatureEnabled": {
|
||||||
"message": "Enabled"
|
"message": "Enabled"
|
||||||
},
|
},
|
||||||
|
@ -943,6 +1031,33 @@
|
||||||
"message": "EEPROM <span style=\"color: #57a929\">saved</span>"
|
"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": {
|
"servosFirmwareUpgradeRequired": {
|
||||||
"message": "Servos requires firmware >= 1.10.0. and target support."
|
"message": "Servos requires firmware >= 1.10.0. and target support."
|
||||||
|
@ -1100,10 +1215,30 @@
|
||||||
"message": "Automatically loaded previous log file: <strong>$1</strong>"
|
"message": "Automatically loaded previous log file: <strong>$1</strong>"
|
||||||
},
|
},
|
||||||
|
|
||||||
"dataflashNote": {
|
"blackboxNotSupported": {
|
||||||
"message": "Blackbox flight logs can be recorded to your flight controller's onboard dataflash chip."
|
"message": "Your flight controller's firmware does not support Blackbox logging."
|
||||||
},
|
},
|
||||||
"dataflashNotSupportedNote": {
|
"blackboxMaybeSupported": {
|
||||||
|
"message": "Your flight controller's firmware is too old to support this tab, or the Blackbox feature is disabled on the Configuration tab."
|
||||||
|
},
|
||||||
|
"blackboxConfiguration": {
|
||||||
|
"message": "Blackbox configuration"
|
||||||
|
},
|
||||||
|
"blackboxButtonSave": {
|
||||||
|
"message": "Save and reboot"
|
||||||
|
},
|
||||||
|
|
||||||
|
"serialLoggingSupportedNote": {
|
||||||
|
"message": "You can log to an external logging device (such as an OpenLog or compatible clone) by using a serial port. Configure the port on the Ports tab."
|
||||||
|
},
|
||||||
|
"sdcardNote": {
|
||||||
|
"message": "Flight logs can be recorded to your flight controller's onboard SD card slot."
|
||||||
|
},
|
||||||
|
|
||||||
|
"dataflashNote": {
|
||||||
|
"message": "Flight logs can be recorded to your flight controller's onboard dataflash chip."
|
||||||
|
},
|
||||||
|
"dataflashNotPresentNote": {
|
||||||
"message": "Your flight controller does not have a compatible dataflash chip available."
|
"message": "Your flight controller does not have a compatible dataflash chip available."
|
||||||
},
|
},
|
||||||
"dataflashFirmwareUpgradeRequired": {
|
"dataflashFirmwareUpgradeRequired": {
|
||||||
|
|
83
images/icons/cf_icon_sdcard.svg
Normal file
83
images/icons/cf_icon_sdcard.svg
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
width="81.504448mm"
|
||||||
|
height="109.72666mm"
|
||||||
|
viewBox="0 0 288.79529 388.79528"
|
||||||
|
id="svg2"
|
||||||
|
version="1.1"
|
||||||
|
inkscape:version="0.91 r13725"
|
||||||
|
sodipodi:docname="cf_icon_sdcard.svg">
|
||||||
|
<defs
|
||||||
|
id="defs4" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#9e9e9e"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1.979899"
|
||||||
|
inkscape:cx="62.562956"
|
||||||
|
inkscape:cy="45.52524"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer2"
|
||||||
|
showgrid="true"
|
||||||
|
showguides="true"
|
||||||
|
inkscape:guide-bbox="true"
|
||||||
|
fit-margin-top="1.1"
|
||||||
|
fit-margin-left="1.1"
|
||||||
|
fit-margin-right="1.1"
|
||||||
|
fit-margin-bottom="1.1"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1076"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1">
|
||||||
|
<inkscape:grid
|
||||||
|
type="xygrid"
|
||||||
|
id="grid3336"
|
||||||
|
originx="-168.45952"
|
||||||
|
originy="-373.45953" />
|
||||||
|
<sodipodi:guide
|
||||||
|
position="241.54049,446.54052"
|
||||||
|
orientation="0,1"
|
||||||
|
id="guide3343" />
|
||||||
|
</sodipodi:namedview>
|
||||||
|
<metadata
|
||||||
|
id="metadata7">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
<dc:title></dc:title>
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-168.45951,-290.10742)" />
|
||||||
|
<g
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer2"
|
||||||
|
inkscape:label="Layer 2"
|
||||||
|
transform="translate(-168.45951,-290.10742)">
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||||
|
d="m 172.85715,294.50506 240,0 40,50 0,330 -280,0 0,-230 10,0 0,-50 -10,0 z"
|
||||||
|
id="path3341"
|
||||||
|
inkscape:connector-curvature="0" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.5 KiB |
27
images/icons/cf_icon_transponder_grey.svg
Normal file
27
images/icons/cf_icon_transponder_grey.svg
Normal file
|
@ -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 KiB |
27
images/icons/cf_icon_transponder_white.svg
Normal file
27
images/icons/cf_icon_transponder_white.svg
Normal file
|
@ -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 KiB |
|
@ -48,6 +48,10 @@ var BOARD_DEFINITIONS = [
|
||||||
name: "SP Racing F3",
|
name: "SP Racing F3",
|
||||||
identifier: "SRF3",
|
identifier: "SRF3",
|
||||||
vcp: false
|
vcp: false
|
||||||
|
}, {
|
||||||
|
name: "SP Racing F3 Mini",
|
||||||
|
identifier: "SRFM",
|
||||||
|
vcp: true
|
||||||
}, {
|
}, {
|
||||||
name: "MotoLab",
|
name: "MotoLab",
|
||||||
identifier: "MOTO",
|
identifier: "MOTO",
|
||||||
|
|
|
@ -14,200 +14,3 @@ var CONFIGURATOR = {
|
||||||
'cliActive': false,
|
'cliActive': false,
|
||||||
'cliValid': false
|
'cliValid': false
|
||||||
};
|
};
|
||||||
|
|
||||||
var CONFIG = {
|
|
||||||
apiVersion: "0.0.0",
|
|
||||||
flightControllerIdentifier: '',
|
|
||||||
flightControllerVersion: '',
|
|
||||||
version: 0,
|
|
||||||
buildInfo: '',
|
|
||||||
multiType: 0,
|
|
||||||
msp_version: 0, // not specified using semantic versioning
|
|
||||||
capability: 0,
|
|
||||||
cycleTime: 0,
|
|
||||||
i2cError: 0,
|
|
||||||
activeSensors: 0,
|
|
||||||
mode: 0,
|
|
||||||
profile: 0,
|
|
||||||
uid: [0, 0, 0],
|
|
||||||
accelerometerTrims: [0, 0]
|
|
||||||
};
|
|
||||||
|
|
||||||
var BF_CONFIG = {
|
|
||||||
mixerConfiguration: 0,
|
|
||||||
features: 0,
|
|
||||||
serialrx_type: 0,
|
|
||||||
board_align_roll: 0,
|
|
||||||
board_align_pitch: 0,
|
|
||||||
board_align_yaw: 0,
|
|
||||||
currentscale: 0,
|
|
||||||
currentoffset: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var LED_STRIP = [];
|
|
||||||
|
|
||||||
var PID = {
|
|
||||||
controller: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var PID_names = [];
|
|
||||||
var PIDs = new Array(10);
|
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
PIDs[i] = new Array(3);
|
|
||||||
}
|
|
||||||
|
|
||||||
var RC_MAP = [];
|
|
||||||
|
|
||||||
// defaults
|
|
||||||
// roll, pitch, yaw, throttle, aux 1, ... aux n
|
|
||||||
var RC = {
|
|
||||||
active_channels: 0,
|
|
||||||
channels: new Array(32)
|
|
||||||
};
|
|
||||||
|
|
||||||
var RC_tuning = {
|
|
||||||
RC_RATE: 0,
|
|
||||||
RC_EXPO: 0,
|
|
||||||
roll_pitch_rate: 0, // pre 1.7 api only
|
|
||||||
roll_rate: 0,
|
|
||||||
pitch_rate: 0,
|
|
||||||
yaw_rate: 0,
|
|
||||||
dynamic_THR_PID: 0,
|
|
||||||
throttle_MID: 0,
|
|
||||||
throttle_EXPO: 0,
|
|
||||||
dynamic_THR_breakpoint: 0,
|
|
||||||
RC_YAW_EXPO: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var AUX_CONFIG = [];
|
|
||||||
var AUX_CONFIG_IDS = [];
|
|
||||||
|
|
||||||
var MODE_RANGES = [];
|
|
||||||
var ADJUSTMENT_RANGES = [];
|
|
||||||
|
|
||||||
var SERVO_CONFIG = [];
|
|
||||||
var SERVO_RULES = [];
|
|
||||||
|
|
||||||
var SERIAL_CONFIG = {
|
|
||||||
ports: [],
|
|
||||||
|
|
||||||
// pre 1.6 settings
|
|
||||||
mspBaudRate: 0,
|
|
||||||
gpsBaudRate: 0,
|
|
||||||
gpsPassthroughBaudRate: 0,
|
|
||||||
cliBaudRate: 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
var SENSOR_DATA = {
|
|
||||||
gyroscope: [0, 0, 0],
|
|
||||||
accelerometer: [0, 0, 0],
|
|
||||||
magnetometer: [0, 0, 0],
|
|
||||||
altitude: 0,
|
|
||||||
sonar: 0,
|
|
||||||
kinematics: [0.0, 0.0, 0.0],
|
|
||||||
debug: [0, 0, 0, 0]
|
|
||||||
};
|
|
||||||
|
|
||||||
var MOTOR_DATA = new Array(8);
|
|
||||||
var SERVO_DATA = new Array(8);
|
|
||||||
|
|
||||||
var GPS_DATA = {
|
|
||||||
fix: 0,
|
|
||||||
numSat: 0,
|
|
||||||
lat: 0,
|
|
||||||
lon: 0,
|
|
||||||
alt: 0,
|
|
||||||
speed: 0,
|
|
||||||
ground_course: 0,
|
|
||||||
distanceToHome: 0,
|
|
||||||
ditectionToHome: 0,
|
|
||||||
update: 0,
|
|
||||||
|
|
||||||
// baseflight specific gps stuff
|
|
||||||
chn: [],
|
|
||||||
svid: [],
|
|
||||||
quality: [],
|
|
||||||
cno: []
|
|
||||||
};
|
|
||||||
|
|
||||||
var ANALOG = {
|
|
||||||
voltage: 0,
|
|
||||||
mAhdrawn: 0,
|
|
||||||
rssi: 0,
|
|
||||||
amperage: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var ARMING_CONFIG = {
|
|
||||||
auto_disarm_delay: 0,
|
|
||||||
disarm_kill_switch: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var FC_CONFIG = {
|
|
||||||
loopTime: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var MISC = {
|
|
||||||
midrc: 0,
|
|
||||||
minthrottle: 0,
|
|
||||||
maxthrottle: 0,
|
|
||||||
mincommand: 0,
|
|
||||||
failsafe_throttle: 0,
|
|
||||||
gps_type: 0,
|
|
||||||
gps_baudrate: 0,
|
|
||||||
gps_ubx_sbas: 0,
|
|
||||||
multiwiicurrentoutput: 0,
|
|
||||||
rssi_channel: 0,
|
|
||||||
placeholder2: 0,
|
|
||||||
mag_declination: 0, // not checked
|
|
||||||
vbatscale: 0,
|
|
||||||
vbatmincellvoltage: 0,
|
|
||||||
vbatmaxcellvoltage: 0,
|
|
||||||
vbatwarningcellvoltage: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var _3D = {
|
|
||||||
deadband3d_low: 0,
|
|
||||||
deadband3d_high: 0,
|
|
||||||
neutral3d: 0,
|
|
||||||
deadband3d_throttle: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var DATAFLASH = {
|
|
||||||
ready: false,
|
|
||||||
sectors: 0,
|
|
||||||
totalSize: 0,
|
|
||||||
usedSize: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var RC_deadband = {
|
|
||||||
deadband: 0,
|
|
||||||
yaw_deadband: 0,
|
|
||||||
alt_hold_deadband: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var SENSOR_ALIGNMENT = {
|
|
||||||
align_gyro: 0,
|
|
||||||
align_acc: 0,
|
|
||||||
align_mag: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var RX_CONFIG = {
|
|
||||||
serialrx_provider: 0,
|
|
||||||
maxcheck: 0,
|
|
||||||
midrc: 0,
|
|
||||||
mincheck: 0,
|
|
||||||
spektrum_sat_bind: 0,
|
|
||||||
rx_min_usec: 0,
|
|
||||||
rx_max_usec: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var FAILSAFE_CONFIG = {
|
|
||||||
failsafe_delay: 0,
|
|
||||||
failsafe_off_delay: 0,
|
|
||||||
failsafe_throttle: 0,
|
|
||||||
failsafe_kill_switch: 0,
|
|
||||||
failsafe_throttle_low_delay: 0,
|
|
||||||
failsafe_procedure: 0
|
|
||||||
};
|
|
||||||
|
|
||||||
var RXFAIL_CONFIG = [];
|
|
||||||
|
|
259
js/fc.js
Normal file
259
js/fc.js
Normal file
|
@ -0,0 +1,259 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
// define all the global variables that are uses to hold FC state
|
||||||
|
var CONFIG;
|
||||||
|
var BF_CONFIG;
|
||||||
|
var LED_STRIP;
|
||||||
|
var PID;
|
||||||
|
var PID_names;
|
||||||
|
var PIDs;
|
||||||
|
var RC_MAP;
|
||||||
|
var RC;
|
||||||
|
var RC_tuning;
|
||||||
|
var AUX_CONFIG;
|
||||||
|
var AUX_CONFIG_IDS;
|
||||||
|
var MODE_RANGES;
|
||||||
|
var ADJUSTMENT_RANGES;
|
||||||
|
var SERVO_CONFIG;
|
||||||
|
var SERVO_RULES;
|
||||||
|
var SERIAL_CONFIG;
|
||||||
|
var SENSOR_DATA;
|
||||||
|
var MOTOR_DATA;
|
||||||
|
var SERVO_DATA;
|
||||||
|
var GPS_DATA;
|
||||||
|
var ANALOG;
|
||||||
|
var ARMING_CONFIG;
|
||||||
|
var FC_CONFIG;
|
||||||
|
var MISC;
|
||||||
|
var _3D;
|
||||||
|
var DATAFLASH;
|
||||||
|
var SDCARD;
|
||||||
|
var BLACKBOX;
|
||||||
|
var TRANSPONDER;
|
||||||
|
var RC_deadband;
|
||||||
|
var SENSOR_ALIGNMENT;
|
||||||
|
var RX_CONFIG;
|
||||||
|
var FAILSAFE_CONFIG;
|
||||||
|
var RXFAIL_CONFIG;
|
||||||
|
|
||||||
|
var FC = {
|
||||||
|
resetState: function() {
|
||||||
|
CONFIG = {
|
||||||
|
apiVersion: "0.0.0",
|
||||||
|
flightControllerIdentifier: '',
|
||||||
|
flightControllerVersion: '',
|
||||||
|
version: 0,
|
||||||
|
buildInfo: '',
|
||||||
|
multiType: 0,
|
||||||
|
msp_version: 0, // not specified using semantic versioning
|
||||||
|
capability: 0,
|
||||||
|
cycleTime: 0,
|
||||||
|
i2cError: 0,
|
||||||
|
activeSensors: 0,
|
||||||
|
mode: 0,
|
||||||
|
profile: 0,
|
||||||
|
uid: [0, 0, 0],
|
||||||
|
accelerometerTrims: [0, 0]
|
||||||
|
};
|
||||||
|
|
||||||
|
BF_CONFIG = {
|
||||||
|
mixerConfiguration: 0,
|
||||||
|
features: 0,
|
||||||
|
serialrx_type: 0,
|
||||||
|
board_align_roll: 0,
|
||||||
|
board_align_pitch: 0,
|
||||||
|
board_align_yaw: 0,
|
||||||
|
currentscale: 0,
|
||||||
|
currentoffset: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
LED_STRIP = [];
|
||||||
|
|
||||||
|
PID = {
|
||||||
|
controller: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
PID_names = [];
|
||||||
|
PIDs = new Array(10);
|
||||||
|
for (var i = 0; i < 10; i++) {
|
||||||
|
PIDs[i] = new Array(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
RC_MAP = [];
|
||||||
|
|
||||||
|
// defaults
|
||||||
|
// roll, pitch, yaw, throttle, aux 1, ... aux n
|
||||||
|
RC = {
|
||||||
|
active_channels: 0,
|
||||||
|
channels: new Array(32)
|
||||||
|
};
|
||||||
|
|
||||||
|
RC_tuning = {
|
||||||
|
RC_RATE: 0,
|
||||||
|
RC_EXPO: 0,
|
||||||
|
roll_pitch_rate: 0, // pre 1.7 api only
|
||||||
|
roll_rate: 0,
|
||||||
|
pitch_rate: 0,
|
||||||
|
yaw_rate: 0,
|
||||||
|
dynamic_THR_PID: 0,
|
||||||
|
throttle_MID: 0,
|
||||||
|
throttle_EXPO: 0,
|
||||||
|
dynamic_THR_breakpoint: 0,
|
||||||
|
RC_YAW_EXPO: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
AUX_CONFIG = [];
|
||||||
|
AUX_CONFIG_IDS = [];
|
||||||
|
|
||||||
|
MODE_RANGES = [];
|
||||||
|
ADJUSTMENT_RANGES = [];
|
||||||
|
|
||||||
|
SERVO_CONFIG = [];
|
||||||
|
SERVO_RULES = [];
|
||||||
|
|
||||||
|
SERIAL_CONFIG = {
|
||||||
|
ports: [],
|
||||||
|
|
||||||
|
// pre 1.6 settings
|
||||||
|
mspBaudRate: 0,
|
||||||
|
gpsBaudRate: 0,
|
||||||
|
gpsPassthroughBaudRate: 0,
|
||||||
|
cliBaudRate: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
SENSOR_DATA = {
|
||||||
|
gyroscope: [0, 0, 0],
|
||||||
|
accelerometer: [0, 0, 0],
|
||||||
|
magnetometer: [0, 0, 0],
|
||||||
|
altitude: 0,
|
||||||
|
sonar: 0,
|
||||||
|
kinematics: [0.0, 0.0, 0.0],
|
||||||
|
debug: [0, 0, 0, 0]
|
||||||
|
};
|
||||||
|
|
||||||
|
MOTOR_DATA = new Array(8);
|
||||||
|
SERVO_DATA = new Array(8);
|
||||||
|
|
||||||
|
GPS_DATA = {
|
||||||
|
fix: 0,
|
||||||
|
numSat: 0,
|
||||||
|
lat: 0,
|
||||||
|
lon: 0,
|
||||||
|
alt: 0,
|
||||||
|
speed: 0,
|
||||||
|
ground_course: 0,
|
||||||
|
distanceToHome: 0,
|
||||||
|
ditectionToHome: 0,
|
||||||
|
update: 0,
|
||||||
|
|
||||||
|
// baseflight specific gps stuff
|
||||||
|
chn: [],
|
||||||
|
svid: [],
|
||||||
|
quality: [],
|
||||||
|
cno: []
|
||||||
|
};
|
||||||
|
|
||||||
|
ANALOG = {
|
||||||
|
voltage: 0,
|
||||||
|
mAhdrawn: 0,
|
||||||
|
rssi: 0,
|
||||||
|
amperage: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
ARMING_CONFIG = {
|
||||||
|
auto_disarm_delay: 0,
|
||||||
|
disarm_kill_switch: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
FC_CONFIG = {
|
||||||
|
loopTime: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
MISC = {
|
||||||
|
midrc: 0,
|
||||||
|
minthrottle: 0,
|
||||||
|
maxthrottle: 0,
|
||||||
|
mincommand: 0,
|
||||||
|
failsafe_throttle: 0,
|
||||||
|
gps_type: 0,
|
||||||
|
gps_baudrate: 0,
|
||||||
|
gps_ubx_sbas: 0,
|
||||||
|
multiwiicurrentoutput: 0,
|
||||||
|
rssi_channel: 0,
|
||||||
|
placeholder2: 0,
|
||||||
|
mag_declination: 0, // not checked
|
||||||
|
vbatscale: 0,
|
||||||
|
vbatmincellvoltage: 0,
|
||||||
|
vbatmaxcellvoltage: 0,
|
||||||
|
vbatwarningcellvoltage: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
_3D = {
|
||||||
|
deadband3d_low: 0,
|
||||||
|
deadband3d_high: 0,
|
||||||
|
neutral3d: 0,
|
||||||
|
deadband3d_throttle: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
DATAFLASH = {
|
||||||
|
ready: false,
|
||||||
|
supported: false,
|
||||||
|
sectors: 0,
|
||||||
|
totalSize: 0,
|
||||||
|
usedSize: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
SDCARD = {
|
||||||
|
supported: false,
|
||||||
|
state: 0,
|
||||||
|
filesystemLastError: 0,
|
||||||
|
freeSizeKB: 0,
|
||||||
|
totalSizeKB: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
BLACKBOX = {
|
||||||
|
supported: false,
|
||||||
|
blackboxDevice: 0,
|
||||||
|
blackboxRateNum: 1,
|
||||||
|
blackboxRateDenom: 1
|
||||||
|
};
|
||||||
|
|
||||||
|
TRANSPONDER = {
|
||||||
|
supported: false,
|
||||||
|
data: []
|
||||||
|
};
|
||||||
|
|
||||||
|
RC_deadband = {
|
||||||
|
deadband: 0,
|
||||||
|
yaw_deadband: 0,
|
||||||
|
alt_hold_deadband: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
SENSOR_ALIGNMENT = {
|
||||||
|
align_gyro: 0,
|
||||||
|
align_acc: 0,
|
||||||
|
align_mag: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
RX_CONFIG = {
|
||||||
|
serialrx_provider: 0,
|
||||||
|
maxcheck: 0,
|
||||||
|
midrc: 0,
|
||||||
|
mincheck: 0,
|
||||||
|
spektrum_sat_bind: 0,
|
||||||
|
rx_min_usec: 0,
|
||||||
|
rx_max_usec: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
FAILSAFE_CONFIG = {
|
||||||
|
failsafe_delay: 0,
|
||||||
|
failsafe_off_delay: 0,
|
||||||
|
failsafe_throttle: 0,
|
||||||
|
failsafe_kill_switch: 0,
|
||||||
|
failsafe_throttle_low_delay: 0,
|
||||||
|
failsafe_procedure: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
RXFAIL_CONFIG = [];
|
||||||
|
}
|
||||||
|
};
|
13
js/gui.js
13
js/gui.js
|
@ -19,6 +19,7 @@ var GUI_control = function () {
|
||||||
];
|
];
|
||||||
this.defaultAllowedTabsWhenConnected = [
|
this.defaultAllowedTabsWhenConnected = [
|
||||||
'failsafe',
|
'failsafe',
|
||||||
|
'transponder',
|
||||||
'adjustments',
|
'adjustments',
|
||||||
'auxiliary',
|
'auxiliary',
|
||||||
'cli',
|
'cli',
|
||||||
|
@ -26,7 +27,7 @@ var GUI_control = function () {
|
||||||
'gps',
|
'gps',
|
||||||
'led_strip',
|
'led_strip',
|
||||||
'logging',
|
'logging',
|
||||||
'dataflash',
|
'onboard_logging',
|
||||||
'modes',
|
'modes',
|
||||||
'motors',
|
'motors',
|
||||||
'pid_tuning',
|
'pid_tuning',
|
||||||
|
@ -275,10 +276,12 @@ GUI_control.prototype.content_ready = function (callback) {
|
||||||
$(elem).removeClass('togglemedium');
|
$(elem).removeClass('togglemedium');
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build link to in-use CF version documentation
|
if (CONFIGURATOR.connectionValid) {
|
||||||
var documentationButton = $('div#content #button-documentation');
|
// Build link to in-use CF version documentation
|
||||||
documentationButton.html("Documentation for "+CONFIG.flightControllerVersion);
|
var documentationButton = $('div#content #button-documentation');
|
||||||
documentationButton.attr("href","https://github.com/cleanflight/cleanflight/tree/v{0}/docs".format(CONFIG.flightControllerVersion));
|
documentationButton.html("Documentation for " + CONFIG.flightControllerVersion);
|
||||||
|
documentationButton.attr("href","https://github.com/cleanflight/cleanflight/tree/v{0}/docs".format(CONFIG.flightControllerVersion));
|
||||||
|
}
|
||||||
|
|
||||||
// loading tooltip
|
// loading tooltip
|
||||||
jQuery(document).ready(function($) {
|
jQuery(document).ready(function($) {
|
||||||
|
|
68
js/msp.js
68
js/msp.js
|
@ -35,6 +35,11 @@ var MSP_codes = {
|
||||||
MSP_SET_FAILSAFE_CONFIG: 76,
|
MSP_SET_FAILSAFE_CONFIG: 76,
|
||||||
MSP_RXFAIL_CONFIG: 77,
|
MSP_RXFAIL_CONFIG: 77,
|
||||||
MSP_SET_RXFAIL_CONFIG: 78,
|
MSP_SET_RXFAIL_CONFIG: 78,
|
||||||
|
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
|
// Multiwii MSP commands
|
||||||
MSP_IDENT: 100,
|
MSP_IDENT: 100,
|
||||||
|
@ -888,13 +893,17 @@ var MSP = {
|
||||||
break;
|
break;
|
||||||
case MSP_codes.MSP_DATAFLASH_SUMMARY:
|
case MSP_codes.MSP_DATAFLASH_SUMMARY:
|
||||||
if (data.byteLength >= 13) {
|
if (data.byteLength >= 13) {
|
||||||
DATAFLASH.ready = (data.getUint8(0) & 1) != 0;
|
var
|
||||||
|
flags = data.getUint8(0);
|
||||||
|
DATAFLASH.ready = (flags & 1) != 0;
|
||||||
|
DATAFLASH.supported = (flags & 2) != 0 || DATAFLASH.ready;
|
||||||
DATAFLASH.sectors = data.getUint32(1, 1);
|
DATAFLASH.sectors = data.getUint32(1, 1);
|
||||||
DATAFLASH.totalSize = data.getUint32(5, 1);
|
DATAFLASH.totalSize = data.getUint32(5, 1);
|
||||||
DATAFLASH.usedSize = data.getUint32(9, 1);
|
DATAFLASH.usedSize = data.getUint32(9, 1);
|
||||||
} else {
|
} else {
|
||||||
// Firmware version too old to support MSP_DATAFLASH_SUMMARY
|
// Firmware version too old to support MSP_DATAFLASH_SUMMARY
|
||||||
DATAFLASH.ready = false;
|
DATAFLASH.ready = false;
|
||||||
|
DATAFLASH.supported = false;
|
||||||
DATAFLASH.sectors = 0;
|
DATAFLASH.sectors = 0;
|
||||||
DATAFLASH.totalSize = 0;
|
DATAFLASH.totalSize = 0;
|
||||||
DATAFLASH.usedSize = 0;
|
DATAFLASH.usedSize = 0;
|
||||||
|
@ -907,6 +916,36 @@ var MSP = {
|
||||||
case MSP_codes.MSP_DATAFLASH_ERASE:
|
case MSP_codes.MSP_DATAFLASH_ERASE:
|
||||||
console.log("Data flash erase begun...");
|
console.log("Data flash erase begun...");
|
||||||
break;
|
break;
|
||||||
|
case MSP_codes.MSP_SDCARD_SUMMARY:
|
||||||
|
var flags = data.getUint8(0);
|
||||||
|
|
||||||
|
SDCARD.supported = (flags & 0x01) != 0;
|
||||||
|
SDCARD.state = data.getUint8(1);
|
||||||
|
SDCARD.filesystemLastError = data.getUint8(2);
|
||||||
|
SDCARD.freeSizeKB = data.getUint32(3, 1);
|
||||||
|
SDCARD.totalSizeKB = data.getUint32(7, 1);
|
||||||
|
break;
|
||||||
|
case MSP_codes.MSP_BLACKBOX_CONFIG:
|
||||||
|
BLACKBOX.supported = (data.getUint8(0) & 1) != 0;
|
||||||
|
BLACKBOX.blackboxDevice = data.getUint8(1);
|
||||||
|
BLACKBOX.blackboxRateNum = data.getUint8(2);
|
||||||
|
BLACKBOX.blackboxRateDenom = data.getUint8(3);
|
||||||
|
break;
|
||||||
|
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:
|
case MSP_codes.MSP_SET_MODE_RANGE:
|
||||||
console.log('Mode range saved');
|
console.log('Mode range saved');
|
||||||
break;
|
break;
|
||||||
|
@ -1217,6 +1256,12 @@ MSP.crunch = function (code) {
|
||||||
}
|
}
|
||||||
break;
|
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:
|
case MSP_codes.MSP_SET_CHANNEL_FORWARDING:
|
||||||
for (var i = 0; i < SERVO_CONFIG.length; i++) {
|
for (var i = 0; i < SERVO_CONFIG.length; i++) {
|
||||||
var out = SERVO_CONFIG[i].indexOfChannelToForward;
|
var out = SERVO_CONFIG[i].indexOfChannelToForward;
|
||||||
|
@ -1315,6 +1360,19 @@ MSP.setRawRx = function(channels) {
|
||||||
MSP.send_message(MSP_codes.MSP_SET_RAW_RC, buffer, false);
|
MSP.send_message(MSP_codes.MSP_SET_RAW_RC, buffer, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MSP.sendBlackboxConfiguration = function(onDataCallback) {
|
||||||
|
var
|
||||||
|
message = [
|
||||||
|
BLACKBOX.blackboxDevice & 0xFF,
|
||||||
|
BLACKBOX.blackboxRateNum & 0xFF,
|
||||||
|
BLACKBOX.blackboxRateDenom & 0xFF
|
||||||
|
];
|
||||||
|
|
||||||
|
MSP.send_message(MSP_codes.MSP_SET_BLACKBOX_CONFIG, message, false, function(response) {
|
||||||
|
onDataCallback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send a request to read a block of data from the dataflash at the given address and pass that address and a dataview
|
* Send a request to read a block of data from the dataflash at the given address and pass that address and a dataview
|
||||||
* of the returned data to the given callback (or null for the data if an error occured).
|
* of the returned data to the given callback (or null for the data if an error occured).
|
||||||
|
@ -1608,3 +1666,11 @@ MSP.sendRxFailConfig = function(onCompleteCallback) {
|
||||||
MSP.send_message(MSP_codes.MSP_SET_RXFAIL_CONFIG, buffer, false, nextFunction);
|
MSP.send_message(MSP_codes.MSP_SET_RXFAIL_CONFIG, buffer, false, nextFunction);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MSP.SDCARD_STATE_NOT_PRESENT = 0;
|
||||||
|
MSP.SDCARD_STATE_FATAL = 1;
|
||||||
|
MSP.SDCARD_STATE_CARD_INIT = 2;
|
||||||
|
MSP.SDCARD_STATE_FS_INIT = 3;
|
||||||
|
MSP.SDCARD_STATE_READY = 4;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,7 @@ function onOpen(openInfo) {
|
||||||
}
|
}
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
|
FC.resetState();
|
||||||
|
|
||||||
// request configuration data
|
// request configuration data
|
||||||
MSP.send_message(MSP_codes.MSP_API_VERSION, false, false, function () {
|
MSP.send_message(MSP_codes.MSP_API_VERSION, false, false, function () {
|
||||||
|
@ -285,7 +286,6 @@ function onClosed(result) {
|
||||||
|
|
||||||
var dataflash = $('#dataflash_wrapper_global');
|
var dataflash = $('#dataflash_wrapper_global');
|
||||||
dataflash.hide();
|
dataflash.hide();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function read_serial(info) {
|
function read_serial(info) {
|
||||||
|
|
15
main.css
15
main.css
|
@ -784,6 +784,19 @@ li.active .ic_flasher {
|
||||||
background-image: url(images/icons/cf_icon_flasher_white.svg);
|
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 */
|
/* SPARE Tab-Icons */
|
||||||
.ic_failsafe {
|
.ic_failsafe {
|
||||||
background-image: url(images/icons/cf_icon_failsafe_grey.svg);
|
background-image: url(images/icons/cf_icon_failsafe_grey.svg);
|
||||||
|
@ -1416,7 +1429,7 @@ dialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixing padding for all Tabs*/
|
/* fixing padding for all Tabs*/
|
||||||
.tab-setup, .tab-landing, .tab-adjustments, .tab-auxiliary, .tab-cli, .tab-configuration, .tab-failsafe, .tab-dataflash,
|
.tab-setup, .tab-landing, .tab-adjustments, .tab-auxiliary, .tab-cli, .tab-configuration, .tab-failsafe, .tab-onboard_logging,
|
||||||
.tab-firmware_flasher, .tab-gps, .tab-help, .tab-led-strip, .tab-logging, .tab-modes, .tab-motors, .tab-pid_tuning,
|
.tab-firmware_flasher, .tab-gps, .tab-help, .tab-led-strip, .tab-logging, .tab-modes, .tab-motors, .tab-pid_tuning,
|
||||||
.tab-ports, .tab-receiver, .tab-sensors, .tab-servos {
|
.tab-ports, .tab-receiver, .tab-sensors, .tab-servos {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
14
main.html
14
main.html
|
@ -21,11 +21,12 @@
|
||||||
<link type="text/css" rel="stylesheet" href="./tabs/sensors.css" media="all" />
|
<link type="text/css" rel="stylesheet" href="./tabs/sensors.css" media="all" />
|
||||||
<link type="text/css" rel="stylesheet" href="./tabs/cli.css" media="all" />
|
<link type="text/css" rel="stylesheet" href="./tabs/cli.css" media="all" />
|
||||||
<link type="text/css" rel="stylesheet" href="./tabs/logging.css" media="all" />
|
<link type="text/css" rel="stylesheet" href="./tabs/logging.css" media="all" />
|
||||||
<link type="text/css" rel="stylesheet" href="./tabs/dataflash.css" media="all" />
|
<link type="text/css" rel="stylesheet" href="./tabs/onboard_logging.css" media="all" />
|
||||||
<link type="text/css" rel="stylesheet" href="./tabs/firmware_flasher.css" media="all" />
|
<link type="text/css" rel="stylesheet" href="./tabs/firmware_flasher.css" media="all" />
|
||||||
<link type="text/css" rel="stylesheet" href="./tabs/adjustments.css" media="all" />
|
<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/auxiliary.css" media="all" />
|
||||||
<link type="text/css" rel="stylesheet" href="./tabs/failsafe.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/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="./css/dropdown-lists/css/style_lists.css" media="all" />
|
||||||
<link type="text/css" rel="stylesheet" href="./js/libraries/switchery/switchery.css" media="all" />
|
<link type="text/css" rel="stylesheet" href="./js/libraries/switchery/switchery.css" media="all" />
|
||||||
|
@ -51,6 +52,7 @@
|
||||||
<script type="text/javascript" src="./js/request_balancer.js"></script>
|
<script type="text/javascript" src="./js/request_balancer.js"></script>
|
||||||
<script type="text/javascript" src="./js/serial_backend.js"></script>
|
<script type="text/javascript" src="./js/serial_backend.js"></script>
|
||||||
<script type="text/javascript" src="./js/data_storage.js"></script>
|
<script type="text/javascript" src="./js/data_storage.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/fc.js"></script>
|
||||||
<script type="text/javascript" src="./js/msp.js"></script>
|
<script type="text/javascript" src="./js/msp.js"></script>
|
||||||
<script type="text/javascript" src="./js/backup_restore.js"></script>
|
<script type="text/javascript" src="./js/backup_restore.js"></script>
|
||||||
<script type="text/javascript" src="./js/protocols/stm32.js"></script>
|
<script type="text/javascript" src="./js/protocols/stm32.js"></script>
|
||||||
|
@ -74,9 +76,10 @@
|
||||||
<script type="text/javascript" src="./tabs/sensors.js"></script>
|
<script type="text/javascript" src="./tabs/sensors.js"></script>
|
||||||
<script type="text/javascript" src="./tabs/cli.js"></script>
|
<script type="text/javascript" src="./tabs/cli.js"></script>
|
||||||
<script type="text/javascript" src="./tabs/logging.js"></script>
|
<script type="text/javascript" src="./tabs/logging.js"></script>
|
||||||
<script type="text/javascript" src="./tabs/dataflash.js"></script>
|
<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/firmware_flasher.js"></script>
|
||||||
<script type="text/javascript" src="./tabs/failsafe.js"></script>
|
<script type="text/javascript" src="./tabs/failsafe.js"></script>
|
||||||
|
<script type="text/javascript" src="./tabs/transponder.js"></script>
|
||||||
<title></title>
|
<title></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -190,7 +193,7 @@
|
||||||
<li class="tab_setup"><a href="#" i18n="tabSetup" class="tabicon ic_setup" title="Setup"></a></li>
|
<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_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_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_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_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>
|
<li class="tab_auxiliary"><a href="#" i18n="tabAuxiliary" class="tabicon ic_modes" title="Modes"></a></li>
|
||||||
|
@ -198,10 +201,11 @@
|
||||||
<li class="tab_servos"><a href="#" i18n="tabServos" class="tabicon ic_servo" title="Servos"></a></li>
|
<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_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_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_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_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="Logging"></a></li>
|
<li class="tab_logging"><a href="#" i18n="tabLogging" class="tabicon ic_log" title="Tethered Logging"></a></li>
|
||||||
<li class="tab_dataflash"><a href="#" i18n="tabDataflash" class="tabicon ic_data" title="Dataflash"></a></li>
|
<li class="tab_onboard_logging"><a href="#" i18n="tabOnboardLogging" class="tabicon ic_data" title="Onboard Logging"></a></li>
|
||||||
<li class="tab_cli"><a href="#" i18n="tabCLI" class="tabicon ic_cli" title="CLI"></a></li>
|
<li class="tab_cli"><a href="#" i18n="tabCLI" class="tabicon ic_cli" title="CLI"></a></li>
|
||||||
<!-- spare icons
|
<!-- spare icons
|
||||||
<li class=""><a href="#"class="tabicon ic_mission">Mission (spare icon)</a></li>
|
<li class=""><a href="#"class="tabicon ic_mission">Mission (spare icon)</a></li>
|
||||||
|
|
7
main.js
7
main.js
|
@ -136,6 +136,9 @@ $(document).ready(function () {
|
||||||
case 'failsafe':
|
case 'failsafe':
|
||||||
TABS.failsafe.initialize(content_ready);
|
TABS.failsafe.initialize(content_ready);
|
||||||
break;
|
break;
|
||||||
|
case 'transponder':
|
||||||
|
TABS.transponder.initialize(content_ready);
|
||||||
|
break;
|
||||||
case 'setup':
|
case 'setup':
|
||||||
TABS.setup.initialize(content_ready);
|
TABS.setup.initialize(content_ready);
|
||||||
break;
|
break;
|
||||||
|
@ -166,8 +169,8 @@ $(document).ready(function () {
|
||||||
case 'logging':
|
case 'logging':
|
||||||
TABS.logging.initialize(content_ready);
|
TABS.logging.initialize(content_ready);
|
||||||
break;
|
break;
|
||||||
case 'dataflash':
|
case 'onboard_logging':
|
||||||
TABS.dataflash.initialize(content_ready);
|
TABS.onboard_logging.initialize(content_ready);
|
||||||
break;
|
break;
|
||||||
case 'cli':
|
case 'cli':
|
||||||
TABS.cli.initialize(content_ready);
|
TABS.cli.initialize(content_ready);
|
||||||
|
|
|
@ -89,8 +89,6 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function process_html() {
|
function process_html() {
|
||||||
// translate to user-selected language
|
|
||||||
localize();
|
|
||||||
|
|
||||||
var mixer_list_e = $('select.mixerList');
|
var mixer_list_e = $('select.mixerList');
|
||||||
for (var i = 0; i < mixerList.length; i++) {
|
for (var i = 0; i < mixerList.length; i++) {
|
||||||
|
@ -110,31 +108,37 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
|
|
||||||
// generate features
|
// generate features
|
||||||
var features = [
|
var features = [
|
||||||
{bit: 0, group: 'rxMode', mode: 'group', name: 'RX_PPM', description: 'PPM RX input'},
|
{bit: 0, group: 'rxMode', mode: 'group', name: 'RX_PPM'},
|
||||||
{bit: 1, group: 'batteryVoltage', name: 'VBAT', description: 'Battery voltage monitoring'},
|
{bit: 1, group: 'batteryVoltage', name: 'VBAT'},
|
||||||
{bit: 2, group: 'other', name: 'INFLIGHT_ACC_CAL', description: 'In-flight level calibration'},
|
{bit: 2, group: 'other', name: 'INFLIGHT_ACC_CAL'},
|
||||||
{bit: 3, group: 'rxMode', mode: 'group', name: 'RX_SERIAL', description: 'Serial-based receiver (SPEKSAT, SBUS, SUMD)'},
|
{bit: 3, group: 'rxMode', mode: 'group', name: 'RX_SERIAL'},
|
||||||
{bit: 4, group: 'esc', name: 'MOTOR_STOP', description: 'Don\'t spin the motors when armed'},
|
{bit: 4, group: 'esc', name: 'MOTOR_STOP'},
|
||||||
{bit: 5, group: 'other', name: 'SERVO_TILT', description: 'Servo gimbal'},
|
{bit: 5, group: 'other', name: 'SERVO_TILT'},
|
||||||
{bit: 6, group: 'other', name: 'SOFTSERIAL', description: 'Enable CPU based serial ports'},
|
{bit: 6, group: 'other', name: 'SOFTSERIAL', haveTip: true},
|
||||||
{bit: 7, group: 'gps', name: 'GPS', description: 'Configure port scenario first'},
|
{bit: 7, group: 'gps', name: 'GPS', haveTip: true},
|
||||||
{bit: 8, group: 'rxFailsafe', name: 'FAILSAFE', description: 'Failsafe settings on RX signal loss'},
|
{bit: 8, group: 'rxFailsafe', name: 'FAILSAFE'},
|
||||||
{bit: 9, group: 'other', name: 'SONAR', description: 'Sonar'},
|
{bit: 9, group: 'other', name: 'SONAR'},
|
||||||
{bit: 10, group: 'other', name: 'TELEMETRY', description: 'Telemetry output'},
|
{bit: 10, group: 'other', name: 'TELEMETRY'},
|
||||||
{bit: 11, group: 'batteryCurrent', name: 'CURRENT_METER', description: 'Battery current monitoring'},
|
{bit: 11, group: 'batteryCurrent', name: 'CURRENT_METER'},
|
||||||
{bit: 12, group: 'other', name: '3D', description: '3D mode (for use with reversible ESCs)'},
|
{bit: 12, group: 'other', name: '3D'},
|
||||||
{bit: 13, group: 'rxMode', mode: 'group', name: 'RX_PARALLEL_PWM', description: 'PWM RX input'},
|
{bit: 13, group: 'rxMode', mode: 'group', name: 'RX_PARALLEL_PWM'},
|
||||||
{bit: 14, group: 'rxMode', mode: 'group', name: 'RX_MSP', description: 'MSP RX input'},
|
{bit: 14, group: 'rxMode', mode: 'group', name: 'RX_MSP'},
|
||||||
{bit: 15, group: 'rssi', name: 'RSSI_ADC', description: 'Analog RSSI input'},
|
{bit: 15, group: 'rssi', name: 'RSSI_ADC'},
|
||||||
{bit: 16, group: 'other', name: 'LED_STRIP', description: 'Addressable RGB LED strip support'},
|
{bit: 16, group: 'other', name: 'LED_STRIP'},
|
||||||
{bit: 17, group: 'other', name: 'DISPLAY', description: 'OLED Screen Display'},
|
{bit: 17, group: 'other', name: 'DISPLAY'},
|
||||||
{bit: 18, group: 'esc', name: 'ONESHOT125', description: 'ONESHOT ESC support (disconnect ESCs, remove props)'},
|
{bit: 18, group: 'esc', name: 'ONESHOT125', haveTip: true},
|
||||||
{bit: 19, group: 'other', name: 'BLACKBOX', description: 'Blackbox flight data recorder'}
|
{bit: 19, group: 'other', name: 'BLACKBOX', haveTip: true}
|
||||||
];
|
];
|
||||||
|
|
||||||
if (semver.gte(CONFIG.apiVersion, "1.12.0")) {
|
if (semver.gte(CONFIG.apiVersion, "1.12.0")) {
|
||||||
features.push(
|
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.16.0")) {
|
||||||
|
features.push(
|
||||||
|
{bit: 21, group: 'other', name: 'TRANSPONDER', haveTip: true}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,6 +157,11 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
for (var i = 0; i < features.length; i++) {
|
for (var i = 0; i < features.length; i++) {
|
||||||
var row_e;
|
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') {
|
if (features[i].mode === 'group') {
|
||||||
row_e = $('<tr><td style="width: 15px;"><input style="width: 13px;" class="feature" id="feature-'
|
row_e = $('<tr><td style="width: 15px;"><input style="width: 13px;" class="feature" id="feature-'
|
||||||
+ i
|
+ i
|
||||||
|
@ -166,9 +175,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
+ i
|
+ i
|
||||||
+ '">'
|
+ '">'
|
||||||
+ features[i].name
|
+ features[i].name
|
||||||
+ '</label></td><td><span>'
|
+ '</label></td><td><span i18n="feature' + features[i].name + '"></span>'
|
||||||
+ features[i].description
|
+ feature_tip_html + '</td></tr>');
|
||||||
+ '</td><span>');
|
|
||||||
radioGroups.push(features[i].group);
|
radioGroups.push(features[i].group);
|
||||||
} else {
|
} else {
|
||||||
row_e = $('<tr><td><input class="feature toggle"'
|
row_e = $('<tr><td><input class="feature toggle"'
|
||||||
|
@ -181,9 +189,8 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
+ i
|
+ i
|
||||||
+ '">'
|
+ '">'
|
||||||
+ features[i].name
|
+ features[i].name
|
||||||
+ '</label></td><td><span>'
|
+ '</label></td><td><span i18n="feature' + features[i].name + '"></span>'
|
||||||
+ features[i].description
|
+ feature_tip_html + '</td></tr>');
|
||||||
+ '</span></td>');
|
|
||||||
|
|
||||||
var feature_e = row_e.find('input.feature');
|
var feature_e = row_e.find('input.feature');
|
||||||
|
|
||||||
|
@ -198,6 +205,9 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// translate to user-selected language
|
||||||
|
localize();
|
||||||
|
|
||||||
for (var i = 0; i < radioGroups.length; i++) {
|
for (var i = 0; i < radioGroups.length; i++) {
|
||||||
var group = radioGroups[i];
|
var group = radioGroups[i];
|
||||||
var controls_e = $('input[name="' + group + '"].feature');
|
var controls_e = $('input[name="' + group + '"].feature');
|
||||||
|
|
|
@ -1,227 +0,0 @@
|
||||||
.tab-dataflash .info {
|
|
||||||
margin: 0 0 10px 0;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .info .progressLabel {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 26px;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
text-align: center;
|
|
||||||
line-height: 24px;
|
|
||||||
color: white;
|
|
||||||
font-weight: bold;
|
|
||||||
/* text-shadow: 1px 0px 2px rgba(0, 0, 0, 0.9);*/
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .properties {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .dataflash-info {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .dataflash-info dt {
|
|
||||||
float: left;
|
|
||||||
width: 12em;
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .dataflash-info dd {
|
|
||||||
display: block;
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .speed {
|
|
||||||
margin-top: 5px;
|
|
||||||
width: 80px;
|
|
||||||
border: 1px solid silver;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .info {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .info dt {
|
|
||||||
float: left;
|
|
||||||
width: 120px;
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .info dd {
|
|
||||||
display: block;
|
|
||||||
margin-left: 130px;
|
|
||||||
height: 20px;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .buttons {
|
|
||||||
width: calc(100% - 20px);
|
|
||||||
position: absolute;
|
|
||||||
bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .dataflash-progress {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .dataflash-contents {
|
|
||||||
margin-top: 5px;
|
|
||||||
border: 1px solid silver;
|
|
||||||
background-color: #eee;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
flex-wrap: nowrap;
|
|
||||||
justify-content: flex-start;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .dataflash-contents li {
|
|
||||||
height: 26px;
|
|
||||||
position: relative;
|
|
||||||
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.20);
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .dataflash-contents li div {
|
|
||||||
position: absolute;
|
|
||||||
top: 26px;
|
|
||||||
margin-top: 4px;
|
|
||||||
text-align: center;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
width: 100%;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .dataflash-used {
|
|
||||||
background-color: #59AA29;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash progress::-webkit-progress-bar {
|
|
||||||
height: 24px;
|
|
||||||
background-color: #eee;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash progress::-webkit-progress-value {
|
|
||||||
background-color: #bcf;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash dialog {
|
|
||||||
width: 40em;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash dialog .buttons {
|
|
||||||
position: static;
|
|
||||||
margin-top: 2em;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .buttons a {
|
|
||||||
margin-top: 9px;
|
|
||||||
margin-bottom: 0px;
|
|
||||||
margin-right: 10px;
|
|
||||||
background-color: #59aa29;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid #4c8829;
|
|
||||||
color: #fff;
|
|
||||||
float: left;
|
|
||||||
font-family: 'open_sansbold', Arial;
|
|
||||||
font-size: 12px;
|
|
||||||
text-shadow: 0px 1px rgba(0, 0, 0, 0.25);
|
|
||||||
display: block;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all ease 0.2s;
|
|
||||||
padding: 0px;
|
|
||||||
padding-left: 9px;
|
|
||||||
padding-right: 9px;
|
|
||||||
line-height: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .buttons a:hover {
|
|
||||||
background-color: #6ac435;
|
|
||||||
border: 1px solid #4d9324;
|
|
||||||
text-shadow: 0px 1px rgba(0, 0, 0, 0.25);
|
|
||||||
color: #fff;
|
|
||||||
transition: all ease 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .buttons a:active {
|
|
||||||
background-color: #4d9324;
|
|
||||||
transition: all ease 0.0s;
|
|
||||||
box-shadow: inset 0px 1px 5px rgba(0, 0, 0, 0.35);
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash dialog h3 {
|
|
||||||
margin-bottom: 0.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataflash-confirm-erase .dataflash-erase-progress {
|
|
||||||
height: 125px;
|
|
||||||
display: none;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataflash-confirm-erase.erasing .dataflash-erase-progress {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataflash-confirm-erase.erasing h3, .dataflash-confirm-erase.erasing .erase-flash-confirm, .dataflash-confirm-erase.erasing .dataflash-confirm-erase-note
|
|
||||||
{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash progress {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
margin: 1em 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataflash-saving .dataflash-saving-after {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataflash-saving.done .dataflash-saving-before {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dataflash-saving.done .dataflash-saving-after {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.require-dataflash {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash.supported .require-dataflash {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.require-no-dataflash {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash.supported .require-no-dataflash {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-dataflash .spacebottom {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: 1055px) , only screen and (max-device-width: 1055px) {
|
|
||||||
.tab-dataflash table thead tr:first-child {
|
|
||||||
font-size: 12px;
|
|
||||||
height: 22px;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,66 +0,0 @@
|
||||||
<div class="tab-dataflash toolbar_fixed_bottom">
|
|
||||||
<div class="content_wrapper">
|
|
||||||
<div class="tab_title" i18n="tabDataflash"></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-dataflash">
|
|
||||||
<div class="note spacebottom">
|
|
||||||
<div class="note_spacer">
|
|
||||||
<p i18n="dataflashNote"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<dialog class="dataflash-confirm-erase">
|
|
||||||
<h3 i18n="dataflashConfirmEraseTitle"></h3>
|
|
||||||
<div class="dataflash-confirm-erase-note" i18n="dataflashConfirmEraseNote"></div>
|
|
||||||
<div class="dataflash-erase-progress">
|
|
||||||
<div class="data-loading">
|
|
||||||
<p>Erase in progress, please wait...</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="buttons">
|
|
||||||
<a href="#" class="erase-flash-cancel" i18n="dataflashButtonEraseCancel"></a> <a href="#"
|
|
||||||
class="erase-flash-confirm" i18n="dataflashButtonEraseConfirm"></a>
|
|
||||||
</div>
|
|
||||||
</dialog>
|
|
||||||
<dialog class="dataflash-saving">
|
|
||||||
<h3 i18n="dataflashSavingTitle"></h3>
|
|
||||||
<div class="dataflash-saving-before">
|
|
||||||
<div i18n="dataflashSavingNote"></div>
|
|
||||||
<progress value="0" min="0" max="100"></progress>
|
|
||||||
<div class="buttons">
|
|
||||||
<a href="#" class="save-flash-cancel" i18n="dataflashButtonSaveCancel"></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="dataflash-saving-after">
|
|
||||||
<div i18n="dataflashSavingNoteAfter"></div>
|
|
||||||
<div class="buttons">
|
|
||||||
<a href="#" class="save-flash-dismiss" i18n="dataflashButtonSaveDismiss"></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</dialog>
|
|
||||||
<h3>Dataflash contents</h3>
|
|
||||||
<ul class="dataflash-contents">
|
|
||||||
<li class="dataflash-used">
|
|
||||||
<div class="legend">Used space</div>
|
|
||||||
</li>
|
|
||||||
<li class="dataflash-free">
|
|
||||||
<div class="legend">Free space</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="require-no-dataflash note">
|
|
||||||
<div class="note_spacer">
|
|
||||||
<p i18n="require-no-dataflash"></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content_toolbar">
|
|
||||||
<div class="btn erase_btn">
|
|
||||||
<a class="erase-flash" href="#" i18n="dataflashButtonErase"></a>
|
|
||||||
</div>
|
|
||||||
<div class="btn save_btn">
|
|
||||||
<a class="save-flash" href="#" i18n="dataflashButtonSaveFile"></a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -1,288 +0,0 @@
|
||||||
'use strict';
|
|
||||||
|
|
||||||
TABS.dataflash = {
|
|
||||||
available: false
|
|
||||||
};
|
|
||||||
TABS.dataflash.initialize = function (callback) {
|
|
||||||
var
|
|
||||||
self = this,
|
|
||||||
saveCancelled, eraseCancelled;
|
|
||||||
|
|
||||||
if (GUI.active_tab != 'dataflash') {
|
|
||||||
GUI.active_tab = 'dataflash';
|
|
||||||
googleAnalytics.sendAppView('dataflash');
|
|
||||||
}
|
|
||||||
|
|
||||||
var
|
|
||||||
requested_properties = [],
|
|
||||||
samples = 0,
|
|
||||||
requests = 0,
|
|
||||||
log_buffer = [];
|
|
||||||
|
|
||||||
if (CONFIGURATOR.connectionValid) {
|
|
||||||
TABS.dataflash.available = semver.gte(CONFIG.apiVersion, "1.6.0");
|
|
||||||
|
|
||||||
if (!TABS.dataflash.available) {
|
|
||||||
load_html();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MSP.send_message(MSP_codes.MSP_DATAFLASH_SUMMARY, false, false, load_html);
|
|
||||||
}
|
|
||||||
|
|
||||||
function load_html() {
|
|
||||||
$('#content').load("./tabs/dataflash.html", function() {
|
|
||||||
create_html();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function formatFilesize(bytes) {
|
|
||||||
if (bytes < 1024) {
|
|
||||||
return bytes + "B";
|
|
||||||
}
|
|
||||||
|
|
||||||
var kilobytes = bytes / 1024;
|
|
||||||
|
|
||||||
if (kilobytes < 1024) {
|
|
||||||
return Math.round(kilobytes) + "kB";
|
|
||||||
}
|
|
||||||
|
|
||||||
var megabytes = kilobytes / 1024;
|
|
||||||
|
|
||||||
return megabytes.toFixed(1) + "MB";
|
|
||||||
}
|
|
||||||
|
|
||||||
function update_html() {
|
|
||||||
if (DATAFLASH.usedSize > 0) {
|
|
||||||
$(".dataflash-used").css({
|
|
||||||
width: (DATAFLASH.usedSize / DATAFLASH.totalSize * 100) + "%",
|
|
||||||
display: 'block'
|
|
||||||
});
|
|
||||||
|
|
||||||
$(".dataflash-used div").text('Used space ' + formatFilesize(DATAFLASH.usedSize));
|
|
||||||
} else {
|
|
||||||
$(".dataflash-used").css({
|
|
||||||
display: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (DATAFLASH.totalSize - DATAFLASH.usedSize > 0) {
|
|
||||||
$(".dataflash-free").css({
|
|
||||||
width: ((DATAFLASH.totalSize - DATAFLASH.usedSize) / DATAFLASH.totalSize * 100) + "%",
|
|
||||||
display: 'block'
|
|
||||||
});
|
|
||||||
$(".dataflash-free div").text('Free space ' + formatFilesize(DATAFLASH.totalSize - DATAFLASH.usedSize));
|
|
||||||
} else {
|
|
||||||
$(".dataflash-free").css({
|
|
||||||
display: 'none'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$(".btn a.erase-flash, .btn a.save-flash").toggleClass("disabled", DATAFLASH.usedSize == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
function create_html() {
|
|
||||||
|
|
||||||
// translate to user-selected language
|
|
||||||
localize();
|
|
||||||
|
|
||||||
|
|
||||||
if (TABS.dataflash.available) {
|
|
||||||
var supportsDataflash = DATAFLASH.totalSize > 0;
|
|
||||||
|
|
||||||
$(".tab-dataflash").toggleClass("supported", supportsDataflash);
|
|
||||||
|
|
||||||
if (supportsDataflash) {
|
|
||||||
// UI hooks
|
|
||||||
$('.tab-dataflash a.erase-flash').click(ask_to_erase_flash);
|
|
||||||
|
|
||||||
$('.tab-dataflash a.erase-flash-confirm').click(flash_erase);
|
|
||||||
$('.tab-dataflash a.erase-flash-cancel').click(flash_erase_cancel);
|
|
||||||
|
|
||||||
$('.tab-dataflash a.save-flash').click(flash_save_begin);
|
|
||||||
$('.tab-dataflash a.save-flash-cancel').click(flash_save_cancel);
|
|
||||||
$('.tab-dataflash a.save-flash-dismiss').click(dismiss_saving_dialog);
|
|
||||||
|
|
||||||
update_html();
|
|
||||||
} else {
|
|
||||||
$(".tab-dataflash .note_spacer").html(chrome.i18n.getMessage('dataflashNotSupportedNote'));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$(".tab-dataflash").removeClass("supported");
|
|
||||||
$(".tab-dataflash .note").html(chrome.i18n.getMessage('dataflashFirmwareUpgradeRequired'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
GUI.content_ready(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// IO related methods
|
|
||||||
function zeroPad(value, width) {
|
|
||||||
value = "" + value;
|
|
||||||
|
|
||||||
while (value.length < width) {
|
|
||||||
value = "0" + value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
function flash_save_cancel() {
|
|
||||||
saveCancelled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function show_saving_dialog() {
|
|
||||||
$(".dataflash-saving progress").attr("value", 0);
|
|
||||||
saveCancelled = false;
|
|
||||||
$(".dataflash-saving").removeClass("done");
|
|
||||||
|
|
||||||
$(".dataflash-saving")[0].showModal();
|
|
||||||
}
|
|
||||||
|
|
||||||
function dismiss_saving_dialog() {
|
|
||||||
$(".dataflash-saving")[0].close();
|
|
||||||
}
|
|
||||||
|
|
||||||
function mark_saving_dialog_done() {
|
|
||||||
$(".dataflash-saving").addClass("done");
|
|
||||||
}
|
|
||||||
|
|
||||||
function flash_update_summary(onDone) {
|
|
||||||
MSP.send_message(MSP_codes.MSP_DATAFLASH_SUMMARY, false, false, function() {
|
|
||||||
update_html();
|
|
||||||
|
|
||||||
if (onDone) {
|
|
||||||
onDone();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function flash_save_begin() {
|
|
||||||
if (GUI.connected_to) {
|
|
||||||
// Begin by refreshing the occupied size in case it changed while the tab was open
|
|
||||||
flash_update_summary(function() {
|
|
||||||
var
|
|
||||||
maxBytes = DATAFLASH.usedSize;
|
|
||||||
|
|
||||||
prepare_file(function(fileWriter) {
|
|
||||||
var
|
|
||||||
nextAddress = 0;
|
|
||||||
|
|
||||||
show_saving_dialog();
|
|
||||||
|
|
||||||
function onChunkRead(chunkAddress, chunkDataView) {
|
|
||||||
if (chunkDataView != null) {
|
|
||||||
// Did we receive any data?
|
|
||||||
if (chunkDataView.byteLength > 0) {
|
|
||||||
nextAddress += chunkDataView.byteLength;
|
|
||||||
|
|
||||||
$(".dataflash-saving progress").attr("value", nextAddress / maxBytes * 100);
|
|
||||||
|
|
||||||
var
|
|
||||||
blob = new Blob([chunkDataView]);
|
|
||||||
|
|
||||||
fileWriter.onwriteend = function(e) {
|
|
||||||
if (saveCancelled || nextAddress >= maxBytes) {
|
|
||||||
if (saveCancelled) {
|
|
||||||
dismiss_saving_dialog();
|
|
||||||
} else {
|
|
||||||
mark_saving_dialog_done();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
fileWriter.write(blob);
|
|
||||||
} else {
|
|
||||||
// A zero-byte block indicates end-of-file, so we're done
|
|
||||||
mark_saving_dialog_done();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// There was an error with the received block (address didn't match the one we asked for), retry
|
|
||||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch the initial block
|
|
||||||
MSP.dataflashRead(nextAddress, onChunkRead);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepare_file(onComplete) {
|
|
||||||
var
|
|
||||||
date = new Date(),
|
|
||||||
filename = 'blackbox_log_' + date.getFullYear() + '-' + zeroPad(date.getMonth() + 1, 2) + '-'
|
|
||||||
+ zeroPad(date.getDate(), 2) + '_' + zeroPad(date.getHours(), 2) + zeroPad(date.getMinutes(), 2)
|
|
||||||
+ zeroPad(date.getSeconds(), 2);
|
|
||||||
|
|
||||||
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: filename,
|
|
||||||
accepts: [{extensions: ['TXT']}]}, function(fileEntry) {
|
|
||||||
var error = chrome.runtime.lastError;
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
console.error(error.message);
|
|
||||||
|
|
||||||
if (error.message != "User cancelled") {
|
|
||||||
GUI.log(chrome.i18n.getMessage('dataflashFileWriteFailed'));
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// echo/console log path specified
|
|
||||||
chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
|
|
||||||
console.log('Dataflash dump file path: ' + path);
|
|
||||||
});
|
|
||||||
|
|
||||||
fileEntry.createWriter(function (fileWriter) {
|
|
||||||
fileWriter.onerror = function (e) {
|
|
||||||
console.error(e);
|
|
||||||
|
|
||||||
// stop logging if the procedure was/is still running
|
|
||||||
};
|
|
||||||
|
|
||||||
onComplete(fileWriter);
|
|
||||||
}, function (e) {
|
|
||||||
// File is not readable or does not exist!
|
|
||||||
console.error(e);
|
|
||||||
GUI.log(chrome.i18n.getMessage('dataflashFileWriteFailed'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function ask_to_erase_flash() {
|
|
||||||
eraseCancelled = false;
|
|
||||||
$(".dataflash-confirm-erase").removeClass('erasing');
|
|
||||||
|
|
||||||
$(".dataflash-confirm-erase")[0].showModal();
|
|
||||||
}
|
|
||||||
|
|
||||||
function poll_for_erase_completion() {
|
|
||||||
flash_update_summary(function() {
|
|
||||||
if (!eraseCancelled) {
|
|
||||||
if (DATAFLASH.ready) {
|
|
||||||
$(".dataflash-confirm-erase")[0].close();
|
|
||||||
} else {
|
|
||||||
setTimeout(poll_for_erase_completion, 500);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function flash_erase() {
|
|
||||||
$(".dataflash-confirm-erase").addClass('erasing');
|
|
||||||
|
|
||||||
MSP.send_message(MSP_codes.MSP_DATAFLASH_ERASE, false, false, poll_for_erase_completion);
|
|
||||||
}
|
|
||||||
|
|
||||||
function flash_erase_cancel() {
|
|
||||||
eraseCancelled = true;
|
|
||||||
$(".dataflash-confirm-erase")[0].close();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
TABS.dataflash.cleanup = function (callback) {
|
|
||||||
if (callback) callback();
|
|
||||||
};
|
|
|
@ -46,7 +46,7 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
||||||
// Build Grid
|
// Build Grid
|
||||||
var theHTML = [];
|
var theHTML = [];
|
||||||
var theHTMLlength = 0;
|
var theHTMLlength = 0;
|
||||||
for (i=0; i<256; i++) {
|
for (var i = 0; i < 256; i++) {
|
||||||
theHTML[theHTMLlength++] = ('<div class="gPoint"><div class="indicators"><span class="north"></span><span class="south"></span><span class="west"></span><span class="east"></span><span class="up">U</span><span class="down">D</span></div><span class="wire"></span></div>');
|
theHTML[theHTMLlength++] = ('<div class="gPoint"><div class="indicators"><span class="north"></span><span class="south"></span><span class="west"></span><span class="east"></span><span class="up">U</span><span class="down">D</span></div><span class="wire"></span></div>');
|
||||||
}
|
}
|
||||||
$('.mainGrid').html(theHTML.join(''));
|
$('.mainGrid').html(theHTML.join(''));
|
||||||
|
|
298
tabs/onboard_logging.css
Normal file
298
tabs/onboard_logging.css
Normal file
|
@ -0,0 +1,298 @@
|
||||||
|
.tab-onboard_logging .info {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .info .progressLabel {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 26px;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 24px;
|
||||||
|
color: white;
|
||||||
|
font-weight: bold;
|
||||||
|
/* text-shadow: 1px 0px 2px rgba(0, 0, 0, 0.9);*/
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .properties {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .dataflash-info {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .dataflash-info dt {
|
||||||
|
float: left;
|
||||||
|
width: 12em;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .dataflash-info dd {
|
||||||
|
display: block;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .speed {
|
||||||
|
margin-top: 5px;
|
||||||
|
width: 80px;
|
||||||
|
border: 1px solid silver;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .info {
|
||||||
|
margin-top: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .info dt {
|
||||||
|
float: left;
|
||||||
|
width: 120px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .info dd {
|
||||||
|
display: block;
|
||||||
|
margin-left: 130px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .buttons {
|
||||||
|
width: calc(100% - 20px);
|
||||||
|
position: absolute;
|
||||||
|
bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .dataflash-progress {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .dataflash-contents,
|
||||||
|
.tab-onboard_logging .sdcard-contents {
|
||||||
|
margin-top: 15px;
|
||||||
|
margin-bottom:26px;
|
||||||
|
border: 1px solid silver;
|
||||||
|
background-color: #eee;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
justify-content: flex-start;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .dataflash-contents li,
|
||||||
|
.tab-onboard_logging .sdcard-contents li {
|
||||||
|
height: 26px;
|
||||||
|
position: relative;
|
||||||
|
box-shadow: inset 0 0 5px rgba(0, 0, 0, 0.20);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .dataflash-contents li div,
|
||||||
|
.tab-onboard_logging .sdcard-contents li div {
|
||||||
|
position: absolute;
|
||||||
|
top: 26px;
|
||||||
|
margin-top: 4px;
|
||||||
|
text-align: center;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .dataflash-used,
|
||||||
|
.tab-onboard_logging .sdcard-other {
|
||||||
|
background-color: #59AA29;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging progress::-webkit-progress-bar {
|
||||||
|
height: 24px;
|
||||||
|
background-color: #eee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging progress::-webkit-progress-value {
|
||||||
|
background-color: #bcf;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging dialog {
|
||||||
|
width: 40em;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging dialog .buttons {
|
||||||
|
position: static;
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging dialog h3 {
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataflash-confirm-erase .dataflash-erase-progress {
|
||||||
|
height: 125px;
|
||||||
|
display: none;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataflash-confirm-erase.erasing .dataflash-erase-progress {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataflash-confirm-erase.erasing h3, .dataflash-confirm-erase.erasing .erase-flash-confirm, .dataflash-confirm-erase.erasing .dataflash-confirm-erase-note
|
||||||
|
{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging progress {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataflash-saving .dataflash-saving-after {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataflash-saving.done .dataflash-saving-before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dataflash-saving.done .dataflash-saving-after {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.require-dataflash-present,
|
||||||
|
.require-dataflash-supported,
|
||||||
|
.require-sdcard-ready,
|
||||||
|
.require-sdcard-supported,
|
||||||
|
.require-blackbox-supported,
|
||||||
|
.require-blackbox-maybe-supported,
|
||||||
|
.require-blackbox-unsupported,
|
||||||
|
.require-blackbox-config-supported,
|
||||||
|
.tab-onboard_logging.dataflash-present .require-dataflash-not-present,
|
||||||
|
.tab-onboard_logging.dataflash-supported .require-dataflash-unsupported,
|
||||||
|
.tab-onboard_logging.sdcard-supported .require-sdcard-unsupported,
|
||||||
|
.tab-onboard_logging.blackbox-config-supported .require-blackbox-config-unsupported {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging.dataflash-present .require-dataflash-present,
|
||||||
|
.tab-onboard_logging.dataflash-supported .require-dataflash-supported,
|
||||||
|
.tab-onboard_logging.sdcard-ready .require-sdcard-ready,
|
||||||
|
.tab-onboard_logging.sdcard-supported .require-sdcard-supported,
|
||||||
|
.tab-onboard_logging.blackbox-supported .require-blackbox-supported,
|
||||||
|
.tab-onboard_logging.blackbox-maybe-supported .require-blackbox-maybe-supported,
|
||||||
|
.tab-onboard_logging.blackbox-unsupported .require-blackbox-unsupported,
|
||||||
|
.tab-onboard_logging.blackbox-config-supported .require-blackbox-config-supported {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.require-no-dataflash {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging.supported .require-no-dataflash {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width: 1055px) , only screen and (max-device-width: 1055px) {
|
||||||
|
.tab-onboard_logging table thead tr:first-child {
|
||||||
|
font-size: 12px;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .line {
|
||||||
|
clear: left;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging .blackboxRate select,
|
||||||
|
.tab-onboard_logging .blackboxDevice select {
|
||||||
|
float: left;
|
||||||
|
width: 180px;
|
||||||
|
height: 20px;
|
||||||
|
margin: 0 10px 5px 0;
|
||||||
|
border: 1px solid silver;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging .blackboxRate span,
|
||||||
|
.tab-onboard_logging .blackboxDevice span {
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .sdcard {
|
||||||
|
padding:10px;
|
||||||
|
float:left;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging .sdcard-status {
|
||||||
|
padding-top: 4px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging.sdcard-error .sdcard-icon {
|
||||||
|
background-color: #e60000;
|
||||||
|
border: 1px solid #fe0000;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging.sdcard-initializing .sdcard-icon {
|
||||||
|
background-color: #64a5f6;
|
||||||
|
border: 1px solid #68a7ff;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging.sdcard-ready .sdcard-icon {
|
||||||
|
background-color: #56ac1d;
|
||||||
|
border: 1px solid #5bbb1b;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging .sdcard-icon {
|
||||||
|
box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.35);
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
background-image: url(/images/icons/cf_icon_sdcard.svg);
|
||||||
|
background-position: 21px 20px;
|
||||||
|
background-size: 50px 50px;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
|
||||||
|
background-color: #808080;
|
||||||
|
border: 1px solid #888888;
|
||||||
|
|
||||||
|
border-radius: 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-onboard_logging .regular-button {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
margin-right: 10px;
|
||||||
|
background-color: #59aa29;
|
||||||
|
border-radius: 3px;
|
||||||
|
border: 1px solid #4c8829;
|
||||||
|
color: #fff;
|
||||||
|
font-family: 'open_sansbold', Arial;
|
||||||
|
font-size: 12px;
|
||||||
|
text-shadow: 0px 1px rgba(0, 0, 0, 0.25);
|
||||||
|
display: inline-block;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all ease 0.2s;
|
||||||
|
padding: 0px;
|
||||||
|
padding-left: 9px;
|
||||||
|
padding-right: 9px;
|
||||||
|
line-height: 28px;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging .regular-button:hover {
|
||||||
|
background-color: #6ac435;
|
||||||
|
transition: all ease 0.2s;
|
||||||
|
}
|
||||||
|
.tab-onboard_logging .regular-button:active {
|
||||||
|
background-color: #4d9324;
|
||||||
|
transition: all ease 0.0s;
|
||||||
|
box-shadow: inset 0px 1px 5px rgba(0, 0, 0, 0.35);
|
||||||
|
}
|
||||||
|
.tab-onboard_logging .regular-button.disabled {
|
||||||
|
cursor: default;
|
||||||
|
color: #fff;
|
||||||
|
background-color: #AFAFAF;
|
||||||
|
border: 1px solid #AFAFAF;
|
||||||
|
pointer-events: none;
|
||||||
|
text-shadow: none;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
141
tabs/onboard_logging.html
Normal file
141
tabs/onboard_logging.html
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
<div class="tab-onboard_logging toolbar_fixed_bottom">
|
||||||
|
<div class="content_wrapper">
|
||||||
|
<div class="tab_title" i18n="tabOnboardLogging"></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-blackbox-unsupported note">
|
||||||
|
<div class="note_spacer">
|
||||||
|
<p i18n="blackboxNotSupported"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="require-blackbox-maybe-supported note">
|
||||||
|
<div class="note_spacer">
|
||||||
|
<p i18n="blackboxMaybeSupported"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="require-blackbox-supported">
|
||||||
|
<div class="gui_box grey require-blackbox-config-supported">
|
||||||
|
<div class="gui_box_titlebar">
|
||||||
|
<div class="spacer_box_title" i18n="blackboxConfiguration"></div>
|
||||||
|
</div>
|
||||||
|
<div class="spacer_box">
|
||||||
|
<div class="line blackboxDevice">
|
||||||
|
<select name="blackbox_device">
|
||||||
|
</select>
|
||||||
|
<span>Blackbox logging device</span>
|
||||||
|
</div>
|
||||||
|
<div class="line blackboxRate">
|
||||||
|
<select name="blackbox_rate">
|
||||||
|
</select>
|
||||||
|
<span>Portion of flight loop iterations to log (logging rate)</span>
|
||||||
|
</div>
|
||||||
|
<div class="line">
|
||||||
|
<a href="#" class="save-settings regular-button" i18n="blackboxButtonSave"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="gui_box grey">
|
||||||
|
<div class="gui_box_titlebar" align="left">
|
||||||
|
<div class="spacer_box_title">
|
||||||
|
Outboard serial logging device
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="spacer_box">
|
||||||
|
<p i18n="serialLoggingSupportedNote"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="gui_box grey require-dataflash-supported">
|
||||||
|
<div class="gui_box_titlebar" align="left">
|
||||||
|
<div class="spacer_box_title">
|
||||||
|
Onboard dataflash chip
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="spacer_box">
|
||||||
|
<div class="require-dataflash-supported">
|
||||||
|
<p i18n="dataflashNote"></p>
|
||||||
|
|
||||||
|
<dialog class="dataflash-confirm-erase">
|
||||||
|
<h3 i18n="dataflashConfirmEraseTitle"></h3>
|
||||||
|
<div class="dataflash-confirm-erase-note" i18n="dataflashConfirmEraseNote"></div>
|
||||||
|
<div class="dataflash-erase-progress">
|
||||||
|
<div class="data-loading">
|
||||||
|
<p>Erase in progress, please wait...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="#" class="erase-flash-confirm regular-button" i18n="dataflashButtonEraseConfirm"></a>
|
||||||
|
<a href="#" class="erase-flash-cancel regular-button" i18n="dataflashButtonEraseCancel"></a>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
|
<dialog class="dataflash-saving">
|
||||||
|
<h3 i18n="dataflashSavingTitle"></h3>
|
||||||
|
<div class="dataflash-saving-before">
|
||||||
|
<div i18n="dataflashSavingNote"></div>
|
||||||
|
<progress value="0" min="0" max="100"></progress>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="#" class="save-flash-cancel regular-button" i18n="dataflashButtonSaveCancel"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="dataflash-saving-after">
|
||||||
|
<div i18n="dataflashSavingNoteAfter"></div>
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="#" class="save-flash-dismiss regular-button" i18n="dataflashButtonSaveDismiss"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</dialog>
|
||||||
|
|
||||||
|
<ul class="dataflash-contents">
|
||||||
|
<li class="dataflash-used">
|
||||||
|
<div class="legend"></div>
|
||||||
|
</li>
|
||||||
|
<li class="dataflash-free">
|
||||||
|
<div class="legend"></div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<a class="regular-button erase-flash" href="#" i18n="dataflashButtonErase"></a>
|
||||||
|
<a class="regular-button save-flash" href="#" i18n="dataflashButtonSaveFile"></a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="require-dataflash-not-present" i18n="dataflashNotPresentNote"></p>
|
||||||
|
<p class="require-dataflash-unsupported" i18n="dataflashFirmwareUpgradeRequired"></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="require-sdcard-supported">
|
||||||
|
<div class="gui_box grey">
|
||||||
|
<div class="gui_box_titlebar" align="left">
|
||||||
|
<div class="spacer_box_title">
|
||||||
|
Onboard SD card
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="spacer_box">
|
||||||
|
<div class="sdcard">
|
||||||
|
<div class="sdcard-icon"></div>
|
||||||
|
<div class="sdcard-status"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p i18n="sdcardNote"></p>
|
||||||
|
|
||||||
|
<div class="require-sdcard-ready">
|
||||||
|
<ul class="sdcard-contents">
|
||||||
|
<li class="sdcard-other">
|
||||||
|
<div class="legend"></div>
|
||||||
|
</li>
|
||||||
|
<li class="sdcard-free">
|
||||||
|
<div class="legend"></div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
470
tabs/onboard_logging.js
Normal file
470
tabs/onboard_logging.js
Normal file
|
@ -0,0 +1,470 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var
|
||||||
|
sdcardTimer;
|
||||||
|
|
||||||
|
TABS.onboard_logging = {
|
||||||
|
available: false
|
||||||
|
};
|
||||||
|
TABS.onboard_logging.initialize = function (callback) {
|
||||||
|
var
|
||||||
|
self = this,
|
||||||
|
saveCancelled, eraseCancelled;
|
||||||
|
|
||||||
|
if (GUI.active_tab != 'onboard_logging') {
|
||||||
|
GUI.active_tab = 'onboard_logging';
|
||||||
|
googleAnalytics.sendAppView('onboard_logging');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CONFIGURATOR.connectionValid) {
|
||||||
|
// Blackbox was introduced in 1.5.0, dataflash API was introduced in 1.8.0, BLACKBOX/SDCARD MSP APIs in 1.11.0
|
||||||
|
TABS.onboard_logging.available = semver.gte(CONFIG.flightControllerVersion, "1.5.0");
|
||||||
|
|
||||||
|
if (!TABS.onboard_logging.available) {
|
||||||
|
load_html();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
MSP.send_message(MSP_codes.MSP_BF_CONFIG, false, false, function() {
|
||||||
|
if (semver.gte(CONFIG.flightControllerVersion, "1.8.0")) {
|
||||||
|
MSP.send_message(MSP_codes.MSP_DATAFLASH_SUMMARY, false, false, function() {
|
||||||
|
if (semver.gte(CONFIG.flightControllerVersion, "1.11.0")) {
|
||||||
|
MSP.send_message(MSP_codes.MSP_SDCARD_SUMMARY, false, false, function() {
|
||||||
|
MSP.send_message(MSP_codes.MSP_BLACKBOX_CONFIG, false, false, load_html);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
load_html();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
load_html();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function gcd(a, b) {
|
||||||
|
if (b == 0)
|
||||||
|
return a;
|
||||||
|
|
||||||
|
return gcd(b, a % b);
|
||||||
|
}
|
||||||
|
|
||||||
|
function save_to_eeprom() {
|
||||||
|
MSP.send_message(MSP_codes.MSP_EEPROM_WRITE, false, false, reboot);
|
||||||
|
}
|
||||||
|
|
||||||
|
function reboot() {
|
||||||
|
GUI.log(chrome.i18n.getMessage('configurationEepromSaved'));
|
||||||
|
|
||||||
|
GUI.tab_switch_cleanup(function() {
|
||||||
|
MSP.send_message(MSP_codes.MSP_SET_REBOOT, false, false, reinitialize);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function reinitialize() {
|
||||||
|
GUI.log(chrome.i18n.getMessage('deviceRebooting'));
|
||||||
|
|
||||||
|
if (BOARD.find_board_definition(CONFIG.boardIdentifier).vcp) { // VCP-based flight controls may crash old drivers, we catch and reconnect
|
||||||
|
$('a.connect').click();
|
||||||
|
GUI.timeout_add('start_connection',function start_connection() {
|
||||||
|
$('a.connect').click();
|
||||||
|
},2000);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
GUI.timeout_add('waiting_for_bootup', function waiting_for_bootup() {
|
||||||
|
MSP.send_message(MSP_codes.MSP_IDENT, false, false, function () {
|
||||||
|
GUI.log(chrome.i18n.getMessage('deviceReady'));
|
||||||
|
TABS.onboard_logging.initialize(false, $('#content').scrollTop());
|
||||||
|
});
|
||||||
|
},1500); // 1500 ms seems to be just the right amount of delay to prevent data request timeouts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function load_html() {
|
||||||
|
$('#content').load("./tabs/onboard_logging.html", function() {
|
||||||
|
// translate to user-selected language
|
||||||
|
localize();
|
||||||
|
|
||||||
|
var
|
||||||
|
dataflashPresent = DATAFLASH.totalSize > 0,
|
||||||
|
blackboxSupport;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Pre-1.11.0 firmware supported DATAFLASH API (on targets with SPI flash) but not the BLACKBOX config API.
|
||||||
|
*
|
||||||
|
* The best we can do on those targets is check the BLACKBOX feature bit to identify support for Blackbox instead.
|
||||||
|
*/
|
||||||
|
if (BLACKBOX.supported || DATAFLASH.supported
|
||||||
|
|| semver.gte(CONFIG.flightControllerVersion, "1.5.0") && semver.lte(CONFIG.flightControllerVersion, "1.10.0") && bit_check(BF_CONFIG.features, 19)) {
|
||||||
|
blackboxSupport = 'yes';
|
||||||
|
} else if (semver.gte(CONFIG.flightControllerVersion, "1.5.0") && semver.lte(CONFIG.flightControllerVersion, "1.10.0")) {
|
||||||
|
blackboxSupport = 'maybe';
|
||||||
|
} else {
|
||||||
|
blackboxSupport = 'no';
|
||||||
|
}
|
||||||
|
|
||||||
|
$(".tab-onboard_logging")
|
||||||
|
.addClass("serial-supported")
|
||||||
|
.toggleClass("dataflash-supported", DATAFLASH.supported)
|
||||||
|
.toggleClass("dataflash-present", dataflashPresent)
|
||||||
|
.toggleClass("sdcard-supported", SDCARD.supported)
|
||||||
|
.toggleClass("blackbox-config-supported", BLACKBOX.supported)
|
||||||
|
|
||||||
|
.toggleClass("blackbox-supported", blackboxSupport == 'yes')
|
||||||
|
.toggleClass("blackbox-maybe-supported", blackboxSupport == 'maybe')
|
||||||
|
.toggleClass("blackbox-unsupported", blackboxSupport == 'no');
|
||||||
|
|
||||||
|
if (dataflashPresent) {
|
||||||
|
// UI hooks
|
||||||
|
$('.tab-onboard_logging a.erase-flash').click(ask_to_erase_flash);
|
||||||
|
|
||||||
|
$('.tab-onboard_logging a.erase-flash-confirm').click(flash_erase);
|
||||||
|
$('.tab-onboard_logging a.erase-flash-cancel').click(flash_erase_cancel);
|
||||||
|
|
||||||
|
$('.tab-onboard_logging a.save-flash').click(flash_save_begin);
|
||||||
|
$('.tab-onboard_logging a.save-flash-cancel').click(flash_save_cancel);
|
||||||
|
$('.tab-onboard_logging a.save-flash-dismiss').click(dismiss_saving_dialog);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BLACKBOX.supported) {
|
||||||
|
$(".tab-onboard_logging a.save-settings").click(function() {
|
||||||
|
var rate = $(".blackboxRate select").val().split('/');
|
||||||
|
|
||||||
|
BLACKBOX.blackboxRateNum = parseInt(rate[0], 10);
|
||||||
|
BLACKBOX.blackboxRateDenom = parseInt(rate[1], 10);
|
||||||
|
BLACKBOX.blackboxDevice = parseInt($(".blackboxDevice select").val(), 10);
|
||||||
|
|
||||||
|
MSP.sendBlackboxConfiguration(save_to_eeprom);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
populateLoggingRates();
|
||||||
|
populateDevices();
|
||||||
|
|
||||||
|
update_html();
|
||||||
|
|
||||||
|
GUI.content_ready(callback);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateDevices() {
|
||||||
|
var
|
||||||
|
deviceSelect = $(".blackboxDevice select").empty();
|
||||||
|
|
||||||
|
deviceSelect.append('<option value="0">Serial port</option>');
|
||||||
|
if (DATAFLASH.ready) {
|
||||||
|
deviceSelect.append('<option value="1">On-board dataflash chip</option>');
|
||||||
|
}
|
||||||
|
if (SDCARD.supported) {
|
||||||
|
deviceSelect.append('<option value="2">On-board SD card slot</option>');
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceSelect.val(BLACKBOX.blackboxDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateLoggingRates() {
|
||||||
|
var
|
||||||
|
userRateGCD = gcd(BLACKBOX.blackboxRateNum, BLACKBOX.blackboxRateDenom),
|
||||||
|
userRate = {num: BLACKBOX.blackboxRateNum / userRateGCD, denom: BLACKBOX.blackboxRateDenom / userRateGCD};
|
||||||
|
|
||||||
|
// Offer a reasonable choice of logging rates (if people want weird steps they can use CLI)
|
||||||
|
var
|
||||||
|
loggingRates = [
|
||||||
|
{num: 1, denom: 32},
|
||||||
|
{num: 1, denom: 16},
|
||||||
|
{num: 1, denom: 8},
|
||||||
|
{num: 1, denom: 5},
|
||||||
|
{num: 1, denom: 4},
|
||||||
|
{num: 1, denom: 3},
|
||||||
|
{num: 1, denom: 2},
|
||||||
|
{num: 2, denom: 3},
|
||||||
|
{num: 3, denom: 4},
|
||||||
|
{num: 4, denom: 5},
|
||||||
|
{num: 7, denom: 8},
|
||||||
|
{num: 1, denom: 1},
|
||||||
|
],
|
||||||
|
loggingRatesSelect = $(".blackboxRate select");
|
||||||
|
|
||||||
|
var
|
||||||
|
addedCurrentValue = false;
|
||||||
|
|
||||||
|
for (var i = 0; i < loggingRates.length; i++) {
|
||||||
|
if (!addedCurrentValue && userRate.num / userRate.denom <= loggingRates[i].num / loggingRates[i].denom) {
|
||||||
|
if (userRate.num / userRate.denom < loggingRates[i].num / loggingRates[i].denom) {
|
||||||
|
loggingRatesSelect.append('<option value="' + userRate.num + '/' + userRate.denom + '">'
|
||||||
|
+ userRate.num + '/' + userRate.denom + ' (' + Math.round(userRate.num / userRate.denom * 100) + '%)</option>');
|
||||||
|
}
|
||||||
|
addedCurrentValue = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
loggingRatesSelect.append('<option value="' + loggingRates[i].num + '/' + loggingRates[i].denom + '">'
|
||||||
|
+ loggingRates[i].num + '/' + loggingRates[i].denom + ' (' + Math.round(loggingRates[i].num / loggingRates[i].denom * 100) + '%)</option>');
|
||||||
|
|
||||||
|
}
|
||||||
|
loggingRatesSelect.val(userRate.num + '/' + userRate.denom);
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatFilesizeKilobytes(kilobytes) {
|
||||||
|
if (kilobytes < 1024) {
|
||||||
|
return Math.round(kilobytes) + "kB";
|
||||||
|
}
|
||||||
|
|
||||||
|
var
|
||||||
|
megabytes = kilobytes / 1024,
|
||||||
|
gigabytes;
|
||||||
|
|
||||||
|
if (megabytes < 900) {
|
||||||
|
return megabytes.toFixed(1) + "MB";
|
||||||
|
} else {
|
||||||
|
gigabytes = megabytes / 1024;
|
||||||
|
|
||||||
|
return gigabytes.toFixed(1) + "GB";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatFilesizeBytes(bytes) {
|
||||||
|
if (bytes < 1024) {
|
||||||
|
return bytes + "B";
|
||||||
|
}
|
||||||
|
return formatFilesizeKilobytes(bytes / 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_bar_width(bar, value, total, label, valuesAreKilobytes) {
|
||||||
|
if (value > 0) {
|
||||||
|
bar.css({
|
||||||
|
width: (value / total * 100) + "%",
|
||||||
|
display: 'block'
|
||||||
|
});
|
||||||
|
|
||||||
|
$("div", bar).text((label ? label + " " : "") + (valuesAreKilobytes ? formatFilesizeKilobytes(value) : formatFilesizeBytes(value)));
|
||||||
|
} else {
|
||||||
|
bar.css({
|
||||||
|
display: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function update_html() {
|
||||||
|
update_bar_width($(".tab-onboard_logging .dataflash-used"), DATAFLASH.usedSize, DATAFLASH.totalSize, "Used space", false);
|
||||||
|
update_bar_width($(".tab-onboard_logging .dataflash-free"), DATAFLASH.totalSize - DATAFLASH.usedSize, DATAFLASH.totalSize, "Free space", false);
|
||||||
|
|
||||||
|
update_bar_width($(".tab-onboard_logging .sdcard-other"), SDCARD.totalSizeKB - SDCARD.freeSizeKB, SDCARD.totalSizeKB, "Unavailable space", true);
|
||||||
|
update_bar_width($(".tab-onboard_logging .sdcard-free"), SDCARD.freeSizeKB, SDCARD.totalSizeKB, "Free space for logs", true);
|
||||||
|
|
||||||
|
$(".btn a.erase-flash, .btn a.save-flash").toggleClass("disabled", DATAFLASH.usedSize == 0);
|
||||||
|
|
||||||
|
$(".tab-onboard_logging")
|
||||||
|
.toggleClass("sdcard-error", SDCARD.state == MSP.SDCARD_STATE_FATAL)
|
||||||
|
.toggleClass("sdcard-initializing", SDCARD.state == MSP.SDCARD_STATE_CARD_INIT || SDCARD.state == MSP.SDCARD_STATE_FS_INIT)
|
||||||
|
.toggleClass("sdcard-ready", SDCARD.state == MSP.SDCARD_STATE_READY);
|
||||||
|
|
||||||
|
switch (SDCARD.state) {
|
||||||
|
case MSP.SDCARD_STATE_NOT_PRESENT:
|
||||||
|
$(".sdcard-status").text("No card inserted");
|
||||||
|
break;
|
||||||
|
case MSP.SDCARD_STATE_FATAL:
|
||||||
|
$(".sdcard-status").html("Fatal error<br>Reboot to retry");
|
||||||
|
break;
|
||||||
|
case MSP.SDCARD_STATE_READY:
|
||||||
|
$(".sdcard-status").text("Card ready");
|
||||||
|
break;
|
||||||
|
case MSP.SDCARD_STATE_CARD_INIT:
|
||||||
|
$(".sdcard-status").text("Card starting...");
|
||||||
|
break;
|
||||||
|
case MSP.SDCARD_STATE_FS_INIT:
|
||||||
|
$(".sdcard-status").text("Filesystem starting...");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
$(".sdcard-status").text("Unknown state " + SDCARD.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SDCARD.supported && !sdcardTimer) {
|
||||||
|
// Poll for changes in SD card status
|
||||||
|
sdcardTimer = setTimeout(function() {
|
||||||
|
sdcardTimer = false;
|
||||||
|
if (CONFIGURATOR.connectionValid) {
|
||||||
|
MSP.send_message(MSP_codes.MSP_SDCARD_SUMMARY, false, false, function() {
|
||||||
|
update_html();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// IO related methods
|
||||||
|
function zeroPad(value, width) {
|
||||||
|
value = "" + value;
|
||||||
|
|
||||||
|
while (value.length < width) {
|
||||||
|
value = "0" + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function flash_save_cancel() {
|
||||||
|
saveCancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_saving_dialog() {
|
||||||
|
$(".dataflash-saving progress").attr("value", 0);
|
||||||
|
saveCancelled = false;
|
||||||
|
$(".dataflash-saving").removeClass("done");
|
||||||
|
|
||||||
|
$(".dataflash-saving")[0].showModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
function dismiss_saving_dialog() {
|
||||||
|
$(".dataflash-saving")[0].close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mark_saving_dialog_done() {
|
||||||
|
$(".dataflash-saving").addClass("done");
|
||||||
|
}
|
||||||
|
|
||||||
|
function flash_update_summary(onDone) {
|
||||||
|
MSP.send_message(MSP_codes.MSP_DATAFLASH_SUMMARY, false, false, function() {
|
||||||
|
update_html();
|
||||||
|
|
||||||
|
if (onDone) {
|
||||||
|
onDone();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function flash_save_begin() {
|
||||||
|
if (GUI.connected_to) {
|
||||||
|
// Begin by refreshing the occupied size in case it changed while the tab was open
|
||||||
|
flash_update_summary(function() {
|
||||||
|
var
|
||||||
|
maxBytes = DATAFLASH.usedSize;
|
||||||
|
|
||||||
|
prepare_file(function(fileWriter) {
|
||||||
|
var
|
||||||
|
nextAddress = 0;
|
||||||
|
|
||||||
|
show_saving_dialog();
|
||||||
|
|
||||||
|
function onChunkRead(chunkAddress, chunkDataView) {
|
||||||
|
if (chunkDataView != null) {
|
||||||
|
// Did we receive any data?
|
||||||
|
if (chunkDataView.byteLength > 0) {
|
||||||
|
nextAddress += chunkDataView.byteLength;
|
||||||
|
|
||||||
|
$(".dataflash-saving progress").attr("value", nextAddress / maxBytes * 100);
|
||||||
|
|
||||||
|
var
|
||||||
|
blob = new Blob([chunkDataView]);
|
||||||
|
|
||||||
|
fileWriter.onwriteend = function(e) {
|
||||||
|
if (saveCancelled || nextAddress >= maxBytes) {
|
||||||
|
if (saveCancelled) {
|
||||||
|
dismiss_saving_dialog();
|
||||||
|
} else {
|
||||||
|
mark_saving_dialog_done();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fileWriter.write(blob);
|
||||||
|
} else {
|
||||||
|
// A zero-byte block indicates end-of-file, so we're done
|
||||||
|
mark_saving_dialog_done();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// There was an error with the received block (address didn't match the one we asked for), retry
|
||||||
|
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fetch the initial block
|
||||||
|
MSP.dataflashRead(nextAddress, onChunkRead);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepare_file(onComplete) {
|
||||||
|
var
|
||||||
|
date = new Date(),
|
||||||
|
filename = 'blackbox_log_' + date.getFullYear() + '-' + zeroPad(date.getMonth() + 1, 2) + '-'
|
||||||
|
+ zeroPad(date.getDate(), 2) + '_' + zeroPad(date.getHours(), 2) + zeroPad(date.getMinutes(), 2)
|
||||||
|
+ zeroPad(date.getSeconds(), 2);
|
||||||
|
|
||||||
|
chrome.fileSystem.chooseEntry({type: 'saveFile', suggestedName: filename,
|
||||||
|
accepts: [{extensions: ['TXT']}]}, function(fileEntry) {
|
||||||
|
var error = chrome.runtime.lastError;
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
console.error(error.message);
|
||||||
|
|
||||||
|
if (error.message != "User cancelled") {
|
||||||
|
GUI.log(chrome.i18n.getMessage('dataflashFileWriteFailed'));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// echo/console log path specified
|
||||||
|
chrome.fileSystem.getDisplayPath(fileEntry, function(path) {
|
||||||
|
console.log('Dataflash dump file path: ' + path);
|
||||||
|
});
|
||||||
|
|
||||||
|
fileEntry.createWriter(function (fileWriter) {
|
||||||
|
fileWriter.onerror = function (e) {
|
||||||
|
console.error(e);
|
||||||
|
|
||||||
|
// stop logging if the procedure was/is still running
|
||||||
|
};
|
||||||
|
|
||||||
|
onComplete(fileWriter);
|
||||||
|
}, function (e) {
|
||||||
|
// File is not readable or does not exist!
|
||||||
|
console.error(e);
|
||||||
|
GUI.log(chrome.i18n.getMessage('dataflashFileWriteFailed'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function ask_to_erase_flash() {
|
||||||
|
eraseCancelled = false;
|
||||||
|
$(".dataflash-confirm-erase").removeClass('erasing');
|
||||||
|
|
||||||
|
$(".dataflash-confirm-erase")[0].showModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
function poll_for_erase_completion() {
|
||||||
|
flash_update_summary(function() {
|
||||||
|
if (CONFIGURATOR.connectionValid && !eraseCancelled) {
|
||||||
|
if (DATAFLASH.ready) {
|
||||||
|
$(".dataflash-confirm-erase")[0].close();
|
||||||
|
} else {
|
||||||
|
setTimeout(poll_for_erase_completion, 500);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function flash_erase() {
|
||||||
|
$(".dataflash-confirm-erase").addClass('erasing');
|
||||||
|
|
||||||
|
MSP.send_message(MSP_codes.MSP_DATAFLASH_ERASE, false, false, poll_for_erase_completion);
|
||||||
|
}
|
||||||
|
|
||||||
|
function flash_erase_cancel() {
|
||||||
|
eraseCancelled = true;
|
||||||
|
$(".dataflash-confirm-erase")[0].close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TABS.onboard_logging.cleanup = function (callback) {
|
||||||
|
if (sdcardTimer) {
|
||||||
|
clearTimeout(sdcardTimer);
|
||||||
|
sdcardTimer = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
75
tabs/transponder.css
Normal file
75
tabs/transponder.css
Normal file
|
@ -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;
|
||||||
|
}
|
52
tabs/transponder.html
Normal file
52
tabs/transponder.html
Normal file
|
@ -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>
|
105
tabs/transponder.js
Normal file
105
tabs/transponder.js
Normal file
|
@ -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…
Add table
Add a link
Reference in a new issue