mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-24 16:55:24 +03:00
Adding fixes for 3D to the newest version
Merge remote-tracking branch 'upstream/master' Conflicts: tabs/configuration.html
This commit is contained in:
commit
904a55c930
219 changed files with 25961 additions and 4066 deletions
|
@ -48,6 +48,10 @@ var BOARD_DEFINITIONS = [
|
|||
name: "SP Racing F3",
|
||||
identifier: "SRF3",
|
||||
vcp: false
|
||||
}, {
|
||||
name: "MotoLab",
|
||||
identifier: "MOTO",
|
||||
vcp: true
|
||||
}
|
||||
];
|
||||
|
||||
|
@ -71,4 +75,3 @@ BOARD.find_board_definition = function (identifier) {
|
|||
}
|
||||
return DEFAULT_BOARD_DEFINITION;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
var CONFIGURATOR = {
|
||||
'releaseDate': 1446278768375, // new Date().getTime() - Fri Oct 02 2015 20:50:49 GMT+0100 (GMT Daylight Time)
|
||||
'releaseDate': 1447275720339, // new Date().getTime() - Wed Nov 11 2015 21:02:18 GMT+0000 (GMT)
|
||||
|
||||
// all versions are specified and compared using semantic versioning http://semver.org/
|
||||
'apiVersionAccepted': '1.2.0',
|
||||
|
|
31
js/gui.js
31
js/gui.js
|
@ -10,7 +10,6 @@ var GUI_control = function () {
|
|||
this.active_tab;
|
||||
this.tab_switch_in_progress = false;
|
||||
this.operating_system;
|
||||
this.optional_usb_permissions = false; // controlled by usb permissions code
|
||||
this.interval_array = [];
|
||||
this.timeout_array = [];
|
||||
this.defaultAllowedTabsWhenDisconnected = [
|
||||
|
@ -238,5 +237,35 @@ GUI_control.prototype.tab_switch_cleanup = function (callback) {
|
|||
}
|
||||
};
|
||||
|
||||
GUI_control.prototype.content_ready = function (callback) {
|
||||
$('.togglesmall').each(function(index, html) {
|
||||
var switchery = new Switchery(html,
|
||||
{
|
||||
size: 'small',
|
||||
color: '#59aa29',
|
||||
secondaryColor: '#c4c4c4'
|
||||
});
|
||||
|
||||
$(html).removeClass('togglesmall');
|
||||
});
|
||||
|
||||
$('.toggle').each(function(index, html) {
|
||||
var switchery = new Switchery(html,
|
||||
{
|
||||
color: '#59aa29',
|
||||
secondaryColor: '#c4c4c4'
|
||||
});
|
||||
|
||||
$(html).removeClass('toggle');
|
||||
});
|
||||
|
||||
// Build link to in-use CF version documentation
|
||||
var documentationButton = $('div#content #button-documentation');
|
||||
documentationButton.html("Documentation for "+CONFIG.flightControllerVersion);
|
||||
documentationButton.attr("href","https://github.com/cleanflight/cleanflight/tree/v{0}/docs".format(CONFIG.flightControllerVersion));
|
||||
|
||||
if (callback) callback();
|
||||
}
|
||||
|
||||
// initialize object into GUI variable
|
||||
var GUI = new GUI_control();
|
||||
|
|
572
js/libraries/jbox/jBox.css
Executable file
572
js/libraries/jbox/jBox.css
Executable file
|
@ -0,0 +1,572 @@
|
|||
|
||||
/* Global */
|
||||
|
||||
.jBox-wrapper {
|
||||
text-align: left;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.jBox-title,
|
||||
.jBox-content,
|
||||
.jBox-container {
|
||||
position: relative;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.jBox-container {
|
||||
background: #fff;
|
||||
border:1px solid #59aa29;
|
||||
max-width:180px;
|
||||
font-size:11px;
|
||||
line-height:13px;
|
||||
color:#525352;
|
||||
}
|
||||
|
||||
.jBox-content {
|
||||
padding: 4px 5px;
|
||||
overflow: auto;
|
||||
-webkit-transition: opacity .15s;
|
||||
transition: opacity .15s;
|
||||
}
|
||||
|
||||
/* jBox Tooltip */
|
||||
|
||||
.jBox-Tooltip .jBox-container,
|
||||
.jBox-Mouse .jBox-container {
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.jBox-Tooltip .jBox-title,
|
||||
.jBox-Mouse .jBox-title {
|
||||
padding: 8px 10px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.jBox-hasTitle.jBox-Tooltip .jBox-content,
|
||||
.jBox-hasTitle.jBox-Mouse .jBox-content {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
/* Pointer */
|
||||
|
||||
.jBox-pointer {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.jBox-pointer-top { top: 0; }
|
||||
.jBox-pointer-bottom { bottom: 0; }
|
||||
.jBox-pointer-left { left: 0; }
|
||||
.jBox-pointer-right { right: 0; }
|
||||
|
||||
.jBox-pointer-top,
|
||||
.jBox-pointer-bottom {
|
||||
width: 22px;
|
||||
height: 10px;
|
||||
}
|
||||
|
||||
.jBox-pointer-left,
|
||||
.jBox-pointer-right {
|
||||
width: 10px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.jBox-pointer:after {
|
||||
content: '';
|
||||
width: 10px;
|
||||
height: 9px;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
border:1px solid #59aa29;
|
||||
|
||||
}
|
||||
|
||||
.jBox-pointer-top:after {
|
||||
left: 5px;
|
||||
top: 6px;
|
||||
box-shadow: -1px -1px 4px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
.jBox-pointer-right:after {
|
||||
top: 5px;
|
||||
right: 6px;
|
||||
box-shadow: 1px -1px 4px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
.jBox-pointer-bottom:after {
|
||||
left: 5px;
|
||||
bottom: 6px;
|
||||
box-shadow: 1px 1px 4px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
.jBox-pointer-left:after {
|
||||
top: 5px;
|
||||
left: 6px;
|
||||
box-shadow: -1px 1px 4px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
/* jBox Modal & jBox Confirm */
|
||||
|
||||
.jBox-Modal .jBox-container,
|
||||
.jBox-Confirm .jBox-container {
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 3px 15px rgba(0, 0, 0, .4), 0 0 5px rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
.jBox-Modal .jBox-title,
|
||||
.jBox-Confirm .jBox-title {
|
||||
border-radius: 3px 3px 0 0;
|
||||
padding: 10px 15px;
|
||||
background: #f4f5f6;
|
||||
border-bottom: 1px solid #ddd;
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
}
|
||||
|
||||
.jBox-Modal.jBox-closeButton-title .jBox-title,
|
||||
.jBox-Confirm.jBox-closeButton-title .jBox-title {
|
||||
padding-right: 55px;
|
||||
}
|
||||
|
||||
.jBox-Modal.jBox-closeButton-box:before,
|
||||
.jBox-Confirm.jBox-closeButton-box:before {
|
||||
box-shadow: 0 3px 15px rgba(0, 0, 0, .4), 0 0 5px rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
/* jBox Modal */
|
||||
|
||||
.jBox-Modal .jBox-content {
|
||||
padding: 12px 15px;
|
||||
}
|
||||
|
||||
/* jBox Confirm */
|
||||
|
||||
.jBox-Confirm .jBox-content {
|
||||
text-align: center;
|
||||
padding: 45px 35px;
|
||||
}
|
||||
|
||||
.jBox-Confirm-footer {
|
||||
border-top: 1px solid #e2e2e2;
|
||||
background: #fafafa;
|
||||
border-radius: 0 0 3px 3px;
|
||||
text-align: center;
|
||||
padding: 10px 0;
|
||||
}
|
||||
|
||||
.jBox-Confirm-button {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
font-size: 15px;
|
||||
line-height: 30px;
|
||||
height: 30px;
|
||||
border-radius: 3px;
|
||||
padding: 0 20px;
|
||||
-webkit-transition: color .2s, background-color .2s;
|
||||
transition: color .2s, background-color .2s;
|
||||
}
|
||||
|
||||
.jBox-Confirm-button-cancel {
|
||||
text-shadow: 0 1px 1px rgba(255, 255, 255, .6);
|
||||
background: #ddd;
|
||||
color: #999;
|
||||
margin-right: 25px;
|
||||
}
|
||||
|
||||
.jBox-Confirm-button-cancel:hover {
|
||||
background: #ccc;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.jBox-Confirm-button-submit {
|
||||
text-shadow: 0 -1px 1px rgba(0, 0, 0, .2);
|
||||
background: #5fc04c;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.jBox-Confirm-button-submit:hover {
|
||||
background: #53a642;
|
||||
}
|
||||
|
||||
.jBox-Confirm-button-cancel:active,
|
||||
.jBox-Confirm-button-submit:active {
|
||||
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .26);
|
||||
}
|
||||
|
||||
/* jBox Notice */
|
||||
|
||||
.jBox-Notice {
|
||||
-webkit-transition: margin .2s;
|
||||
transition: margin .2s;
|
||||
}
|
||||
|
||||
.jBox-Notice .jBox-container {
|
||||
border-radius: 3px;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, .2);
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 1px #000;
|
||||
background: #333;
|
||||
background-image: linear-gradient(to bottom, #444, #222);
|
||||
}
|
||||
|
||||
.jBox-Notice .jBox-content {
|
||||
border-radius: 3px;
|
||||
padding: 12px 20px;
|
||||
}
|
||||
|
||||
.jBox-Notice .jBox-title {
|
||||
padding: 8px 20px 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.jBox-hasTitle.jBox-Notice .jBox-content {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.jBox-Notice-color .jBox-container {
|
||||
text-shadow: 0 -1px 1px rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.jBox-Notice-gray .jBox-container {
|
||||
color: #666;
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
background: #f4f4f4;
|
||||
background-image: linear-gradient(to bottom, #fafafa, #f0f0f0);
|
||||
}
|
||||
|
||||
.jBox-Notice-red .jBox-container {
|
||||
background: #b02222;
|
||||
background-image: linear-gradient(to bottom, #ee2222, #b02222);
|
||||
}
|
||||
|
||||
.jBox-Notice-green .jBox-container {
|
||||
background: #70a800;
|
||||
background-image: linear-gradient(to bottom, #95cc2a, #70a800);
|
||||
}
|
||||
|
||||
.jBox-Notice-blue .jBox-container {
|
||||
background: #2b91d9;
|
||||
background-image: linear-gradient(to bottom, #5abaff, #2b91d9);
|
||||
}
|
||||
|
||||
.jBox-Notice-yellow .jBox-container {
|
||||
color: #744700;
|
||||
text-shadow: 0 1px 1px rgba(255, 255, 255, .6);
|
||||
background: #ffb11f;
|
||||
background-image: linear-gradient(to bottom, #ffd665, #ffb11f);
|
||||
}
|
||||
|
||||
/* jBox Image */
|
||||
|
||||
.jBox-Image {
|
||||
background: #fff;
|
||||
padding: 8px 8px 45px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.jBox-Image .jBox-content {
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.jBox-image-container {
|
||||
border-radius: 5px;
|
||||
background: #fff center center no-repeat;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.jBox-image-label {
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
background: #fff;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
color: #333;
|
||||
margin-top: -35px;
|
||||
padding: 0 90px 5px 10px;
|
||||
border-radius: 0 0 5px 5px;
|
||||
-webkit-transition: opacity .3s;
|
||||
transition: opacity .3s;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.jBox-image-label.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.jBox-image-pointer-next,
|
||||
.jBox-image-pointer-prev {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 22px;
|
||||
height: 45px;
|
||||
background: no-repeat center center url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9Ijc0LjcgMjI0IDE4LjcgMzIiPg0KPHBhdGggZmlsbD0iIzAwMDAwMCIgZD0iTTkzLDIyNy40TDgwLjQsMjQwTDkzLDI1Mi42YzAuNCwwLjQsMC40LDEuMSwwLDEuNWwtMS42LDEuNmMtMC40LDAuNC0xLDAuNS0xLjUsMEw3NSwyNDAuN2MtMC40LTAuNC0wLjUtMSwwLTEuNWwxNC45LTE0LjljMC40LTAuNCwxLTAuNCwxLjUsMGwxLjYsMS42QzkzLjUsMjI2LjQsOTMuNCwyMjcsOTMsMjI3LjR6Ii8+DQo8L3N2Zz4=);
|
||||
background-size: 11px auto;
|
||||
cursor: pointer;
|
||||
opacity: .6;
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-transition: opacity .2s;
|
||||
transition: opacity .2s;
|
||||
}
|
||||
|
||||
.jBox-image-pointer-next:hover,
|
||||
.jBox-image-pointer-prev:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.jBox-image-pointer-next {
|
||||
right: 8px;
|
||||
-webkit-transform: scaleX(-1);
|
||||
transform: scaleX(-1);
|
||||
}
|
||||
|
||||
.jBox-image-pointer-prev {
|
||||
right: 30px;
|
||||
}
|
||||
|
||||
.jBox-image-open #jBox-overlay {
|
||||
background-color: rgba(0, 0, 0, .86);
|
||||
}
|
||||
|
||||
.jBox-Image.jBox-loading .jBox-container:before {
|
||||
left: auto;
|
||||
top: auto;
|
||||
bottom: -33px;
|
||||
right: 55px;
|
||||
margin-top: -9px;
|
||||
margin-left: -9px;
|
||||
}
|
||||
|
||||
/* Close button */
|
||||
|
||||
.jBox-closeButton {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.jBox-closeButton svg {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 50%;
|
||||
}
|
||||
|
||||
.jBox-closeButton path {
|
||||
-webkit-transition: fill .2s;
|
||||
transition: fill .2s;
|
||||
}
|
||||
|
||||
.jBox-closeButton path {
|
||||
fill: #aaa;
|
||||
}
|
||||
|
||||
.jBox-closeButton:hover path {
|
||||
fill: #888;
|
||||
}
|
||||
|
||||
.jBox-closeButton:active path {
|
||||
fill: #666;
|
||||
}
|
||||
|
||||
/* Close button in overlay */
|
||||
|
||||
#jBox-overlay .jBox-closeButton {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
#jBox-overlay .jBox-closeButton svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
margin-right: -10px;
|
||||
}
|
||||
|
||||
#jBox-overlay .jBox-closeButton path {
|
||||
fill: #d2d4d6;
|
||||
}
|
||||
|
||||
#jBox-overlay .jBox-closeButton:hover path {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
#jBox-overlay .jBox-closeButton:active path {
|
||||
fill: #b2b4b6;
|
||||
}
|
||||
|
||||
/* Close button in title */
|
||||
|
||||
.jBox-closeButton-title .jBox-closeButton {
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
.jBox-closeButton-title .jBox-closeButton svg {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-top: -6px;
|
||||
margin-right: -6px;
|
||||
}
|
||||
|
||||
/* Close button in box */
|
||||
|
||||
.jBox-closeButton-box .jBox-closeButton {
|
||||
top: -8px;
|
||||
right: -10px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: #fff;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.jBox-closeButton-box .jBox-closeButton svg {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
margin-top: -5px;
|
||||
margin-right: -5px;
|
||||
}
|
||||
|
||||
.jBox-hasTitle.jBox-Modal.jBox-closeButton-box .jBox-closeButton {
|
||||
background: #f4f5f6;
|
||||
}
|
||||
|
||||
.jBox-closeButton-box:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -8px;
|
||||
right: -10px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, .3);
|
||||
}
|
||||
|
||||
.jBox-pointerPosition-top.jBox-closeButton-box:before {
|
||||
top: 4px;
|
||||
}
|
||||
|
||||
.jBox-pointerPosition-right.jBox-closeButton-box:before {
|
||||
right: 2px;
|
||||
}
|
||||
|
||||
/* Overlay */
|
||||
|
||||
#jBox-overlay {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #000;
|
||||
background-color: rgba(0, 0, 0, .6);
|
||||
}
|
||||
|
||||
/* Block scrolling */
|
||||
|
||||
body[class^="jBox-blockScroll-"],
|
||||
body[class*=" jBox-blockScroll-"] {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* Draggable */
|
||||
|
||||
.jBox-draggable {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
/* Spinner */
|
||||
|
||||
@keyframes jBoxLoading {
|
||||
to {transform: rotate(360deg);}
|
||||
}
|
||||
|
||||
@-webkit-keyframes jBoxLoading {
|
||||
to {-webkit-transform: rotate(360deg);}
|
||||
}
|
||||
|
||||
.jBox-loading .jBox-content {
|
||||
min-height: 32px;
|
||||
min-width: 38px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.jBox-spinner {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -10px;
|
||||
margin-left: -10px;
|
||||
}
|
||||
|
||||
.jBox-spinner:before {
|
||||
content: 'Loading…';
|
||||
display: block;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
text-align: center;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.jBox-spinner:not(:required):before {
|
||||
content: '';
|
||||
border-radius: 50%;
|
||||
border: 2px solid rgba(0, 0, 0, .3);
|
||||
border-top-color: rgba(0, 0, 0, .6);
|
||||
animation: jBoxLoading .6s linear infinite;
|
||||
-webkit-animation: jBoxLoading .6s linear infinite;
|
||||
}
|
||||
|
||||
/* IE8 fixes */
|
||||
|
||||
.jBox-IE8.jBox-Tooltip .jBox-container,
|
||||
.jBox-IE8.jBox-Mouse .jBox-container {
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
|
||||
.jBox-IE8 .jBox-pointer:after {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jBox-IE8 .jBox-pointer {
|
||||
border: 0;
|
||||
background: no-repeat url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABsAAAAbCAYAAACN1PRVAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAPJJREFUeNq01l0OwyAIAGAlvY+n8ZJ6Gk/EqqkNtf7ApCQ+LM34iuCmRUQzihjj6FH+kjWL8N4/Ph9GHpiTnC9SwDbhLGyvspSScc71KkOa/HpuuRhIK+psE2pjONouCQg7kBSEXUgC2tHo52mTTBpnaEATWlaYK6MrhIAaceWpOcsCrYp6FV4H/90zTWjUQ/gSevVQq0ecHqoOxWpYoO7p5O9ku2fnVtp7QAik2rsK3fnpWfjynJWpbw+1BkghurrYDjiCptg/4AxaYhJwBbEwDsiB2NgM5EIirAdKIDFGQSmU1+NaIPjJYt2I25vxT4ABAMhWvtle2YvmAAAAAElFTkSuQmCC);
|
||||
}
|
||||
|
||||
.jBox-IE8 .jBox-pointer-top { background-position: center top; }
|
||||
.jBox-IE8 .jBox-pointer-bottom { background-position: center bottom; }
|
||||
.jBox-IE8 .jBox-pointer-left { background-position: left center; }
|
||||
.jBox-IE8 .jBox-pointer-right { background-position: right center; }
|
||||
|
||||
.jBox-IE8.jBox-Modal .jBox-container {
|
||||
border: 3px solid #aaa;
|
||||
}
|
||||
|
||||
/* No SVG support fixes */
|
||||
|
||||
.jBox-nosvg .jBox-closeButton:before {
|
||||
font-family: Verdana, sans-serif;
|
||||
content: 'x';
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
color: #888;
|
||||
}
|
2
js/libraries/jbox/jBox.min.js
vendored
Executable file
2
js/libraries/jbox/jBox.min.js
vendored
Executable file
File diff suppressed because one or more lines are too long
46
js/libraries/jbox/themes/ModalBorder.css
Executable file
46
js/libraries/jbox/themes/ModalBorder.css
Executable file
|
@ -0,0 +1,46 @@
|
|||
|
||||
/* Wrapper */
|
||||
|
||||
.jBox-ModalBorder {
|
||||
border-radius: 8px;
|
||||
background: rgba(0, 0, 0, .4);
|
||||
padding: 8px;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, .2);
|
||||
}
|
||||
|
||||
/* Container */
|
||||
|
||||
.jBox-ModalBorder .jBox-container {
|
||||
border-radius: 5px;
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
/* Close button */
|
||||
|
||||
.jBox-ModalBorder.jBox-closeButton-box {
|
||||
border-top-right-radius: 0;
|
||||
}
|
||||
|
||||
.jBox-ModalBorder.jBox-closeButton-box:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jBox-ModalBorder.jBox-hasTitle.jBox-closeButton-box .jBox-closeButton,
|
||||
.jBox-ModalBorder.jBox-closeButton-box .jBox-closeButton {
|
||||
background: rgba(0, 0, 0, .4);
|
||||
border-radius: 0 50% 50% 0;
|
||||
right: -32px;
|
||||
top: -8px;
|
||||
}
|
||||
|
||||
.jBox-ModalBorder.jBox-closeButton-box .jBox-closeButton path {
|
||||
fill: #d2d4d6;
|
||||
}
|
||||
|
||||
.jBox-ModalBorder.jBox-closeButton-box .jBox-closeButton:hover path {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.jBox-ModalBorder.jBox-closeButton-box .jBox-closeButton:active path {
|
||||
fill: #b2b4b6;
|
||||
}
|
45
js/libraries/jbox/themes/NoticeBorder.css
Executable file
45
js/libraries/jbox/themes/NoticeBorder.css
Executable file
|
@ -0,0 +1,45 @@
|
|||
|
||||
/* jBox: Notice */
|
||||
|
||||
.jBox-NoticeBorder .jBox-container {
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.jBox-NoticeBorder .jBox-content,
|
||||
.jBox-NoticeBorder .jBox-title {
|
||||
padding-left: 26px;
|
||||
}
|
||||
|
||||
.jBox-NoticeBorder.jBox-Notice-color .jBox-container {
|
||||
color: #fff;
|
||||
text-shadow: 0 -1px 0 #000;
|
||||
background: rgba(0, 0, 0, .92);
|
||||
}
|
||||
|
||||
.jBox-NoticeBorder.jBox-Notice-color .jBox-container:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 8px;
|
||||
border-radius: 5px 0 0 5px;
|
||||
background-image: linear-gradient(45deg, rgba(255, 255, 255, .5) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .5) 50%, rgba(255, 255, 255, .5) 75%, transparent 75%, transparent);
|
||||
background-size: 18px 18px;
|
||||
}
|
||||
|
||||
.jBox-NoticeBorder.jBox-Notice-red .jBox-container:after {
|
||||
background-color: #ee0000;
|
||||
}
|
||||
|
||||
.jBox-NoticeBorder.jBox-Notice-green .jBox-container:after {
|
||||
background-color: #95cc2a;
|
||||
}
|
||||
|
||||
.jBox-NoticeBorder.jBox-Notice-blue .jBox-container:after {
|
||||
background-color: #4cb4ff;
|
||||
}
|
||||
|
||||
.jBox-NoticeBorder.jBox-Notice-yellow .jBox-container:after {
|
||||
background-color: #ffba00;
|
||||
}
|
33
js/libraries/jbox/themes/TooltipBorder.css
Executable file
33
js/libraries/jbox/themes/TooltipBorder.css
Executable file
|
@ -0,0 +1,33 @@
|
|||
|
||||
/* Container */
|
||||
|
||||
.jBox-TooltipBorder .jBox-container {
|
||||
border-radius: 5px;
|
||||
border: 2px solid #52a2cb;
|
||||
}
|
||||
|
||||
/* Pointer */
|
||||
|
||||
.jBox-TooltipBorder .jBox-pointer:after {
|
||||
border: 2px solid #52a2cb;
|
||||
}
|
||||
|
||||
.jBox-TooltipBorder .jBox-pointer-top,
|
||||
.jBox-TooltipBorder .jBox-pointer-bottom {
|
||||
width: 34px;
|
||||
height: 12px;
|
||||
}
|
||||
|
||||
.jBox-TooltipBorder .jBox-pointer-left,
|
||||
.jBox-TooltipBorder .jBox-pointer-right {
|
||||
width: 12px;
|
||||
height: 34px;
|
||||
}
|
||||
|
||||
/* Close button */
|
||||
|
||||
.jBox-TooltipBorder.jBox-closeButton-box:before {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
background: #52a2cb;
|
||||
}
|
37
js/libraries/jbox/themes/TooltipDark.css
Executable file
37
js/libraries/jbox/themes/TooltipDark.css
Executable file
|
@ -0,0 +1,37 @@
|
|||
|
||||
/* Container */
|
||||
|
||||
.jBox-TooltipDark .jBox-container {
|
||||
border-radius: 3px;
|
||||
background: #222;
|
||||
color: #fff;
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
/* Pointer */
|
||||
|
||||
.jBox-TooltipDark .jBox-pointer:after {
|
||||
background: #222;
|
||||
}
|
||||
|
||||
/* Close button */
|
||||
|
||||
.jBox-TooltipDark .jBox-closeButton {
|
||||
background: #222;
|
||||
}
|
||||
|
||||
.jBox-TooltipDark.jBox-closeButton-box:before {
|
||||
box-shadow: 0 0 6px rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton path {
|
||||
fill: #d2d4d6;
|
||||
}
|
||||
|
||||
.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:hover path {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
.jBox-TooltipDark.jBox-closeButton-box .jBox-closeButton:active path {
|
||||
fill: #b2b4b6;
|
||||
}
|
112
js/libraries/switchery/switchery.css
Normal file
112
js/libraries/switchery/switchery.css
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
*
|
||||
* Main stylesheet for Switchery.
|
||||
* http://abpetkov.github.io/switchery/
|
||||
*
|
||||
*/
|
||||
|
||||
/* Switchery defaults. */
|
||||
|
||||
.switchery {
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 14px;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
width: 45px;
|
||||
z-index:1000;
|
||||
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
box-sizing: content-box;
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
.switchery > small {
|
||||
background: #fff;
|
||||
border-radius: 100%;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
|
||||
height: 14px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 14px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.switcherymid {
|
||||
background-color: #fff;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 20px;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
height: 14px;
|
||||
position: relative;
|
||||
vertical-align: middle;
|
||||
width: 35px;
|
||||
|
||||
-moz-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
box-sizing: content-box;
|
||||
background-clip: content-box;
|
||||
}
|
||||
|
||||
.switcherymid > small {
|
||||
background: #fff;
|
||||
border-radius: 100%;
|
||||
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);
|
||||
height: 14px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
width: 14px;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Switchery sizes. */
|
||||
|
||||
.switchery-small {
|
||||
border: none !important;
|
||||
|
||||
border-radius: 20px;
|
||||
height: 10px;
|
||||
width: 20px;
|
||||
margin-top:-3px;
|
||||
margin-right:3px;
|
||||
}
|
||||
|
||||
.switchery-small > small {
|
||||
height: 10px;
|
||||
width: 10px;
|
||||
}
|
||||
|
||||
.switchery-large {
|
||||
border-radius: 40px;
|
||||
height: 40px;
|
||||
width: 66px;
|
||||
}
|
||||
|
||||
.switchery-large > small {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
|
1955
js/libraries/switchery/switchery.js
Normal file
1955
js/libraries/switchery/switchery.js
Normal file
File diff suppressed because it is too large
Load diff
21
js/msp.js
21
js/msp.js
|
@ -52,7 +52,7 @@ var MSP_codes = {
|
|||
MSP_WP: 118,
|
||||
MSP_BOXIDS: 119,
|
||||
MSP_SERVO_CONFIGURATIONS: 120,
|
||||
MSP_3D: 124,
|
||||
MSP_3D: 124,
|
||||
|
||||
MSP_SET_RAW_RC: 200,
|
||||
MSP_SET_RAW_GPS: 201,
|
||||
|
@ -68,7 +68,7 @@ var MSP_codes = {
|
|||
MSP_SET_HEAD: 211,
|
||||
MSP_SET_SERVO_CONFIGURATION: 212,
|
||||
MSP_SET_MOTOR: 214,
|
||||
MSP_SET_3D: 217,
|
||||
MSP_SET_3D: 217,
|
||||
|
||||
// MSP_BIND: 240,
|
||||
|
||||
|
@ -411,16 +411,16 @@ var MSP = {
|
|||
MISC.vbatmaxcellvoltage = data.getUint8(offset++, 1) / 10; // 10-50
|
||||
MISC.vbatwarningcellvoltage = data.getUint8(offset++, 1) / 10; // 10-50
|
||||
break;
|
||||
case MSP_codes.MSP_3D:
|
||||
var offset = 0;
|
||||
case MSP_codes.MSP_3D:
|
||||
var offset = 0;
|
||||
_3D.deadband3d_low = data.getUint16(offset, 1);
|
||||
offset += 2;
|
||||
_3D.deadband3d_high = data.getUint16(offset, 1);
|
||||
offset += 2;
|
||||
_3D.neutral3d = data.getUint16(offset, 1);
|
||||
offset += 2;
|
||||
_3D.deadband3d_throttle = data.getUint16(offset, 1);
|
||||
break;
|
||||
_3D.deadband3d_high = data.getUint16(offset, 1);
|
||||
offset += 2;
|
||||
_3D.neutral3d = data.getUint16(offset, 1);
|
||||
offset += 2;
|
||||
_3D.deadband3d_throttle = data.getUint16(offset, 1);
|
||||
break;
|
||||
case MSP_codes.MSP_MOTOR_PINS:
|
||||
console.log(data);
|
||||
break;
|
||||
|
@ -1141,6 +1141,7 @@ MSP.crunch = function (code) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MSP_codes.MSP_SET_3D:
|
||||
buffer.push(lowByte(_3D.deadband3d_low));
|
||||
buffer.push(highByte(_3D.deadband3d_low));
|
||||
|
|
|
@ -1,9 +1,14 @@
|
|||
'use strict';
|
||||
|
||||
var usbDevices = {
|
||||
STM32DFU: {'vendorId': 1155, 'productId': 57105}
|
||||
};
|
||||
|
||||
var PortHandler = new function () {
|
||||
this.initial_ports = false;
|
||||
this.port_detected_callbacks = [];
|
||||
this.port_removed_callbacks = [];
|
||||
this.dfu_available = false;
|
||||
};
|
||||
|
||||
PortHandler.initialize = function () {
|
||||
|
@ -131,30 +136,32 @@ PortHandler.check = function () {
|
|||
self.initial_ports = current_ports;
|
||||
}
|
||||
|
||||
if (GUI.optional_usb_permissions) {
|
||||
check_usb_devices();
|
||||
}
|
||||
self.check_usb_devices();
|
||||
|
||||
GUI.updateManualPortVisibility();
|
||||
setTimeout(function () {
|
||||
self.check();
|
||||
}, 250);
|
||||
});
|
||||
};
|
||||
|
||||
function check_usb_devices() {
|
||||
chrome.usb.getDevices(usbDevices.STM32DFU, function (result) {
|
||||
if (result.length) {
|
||||
if (!$("div#port-picker #port [value='DFU']").length) {
|
||||
$('div#port-picker #port').append('<option value="DFU">DFU</option>');
|
||||
$('div#port-picker #port').val('DFU');
|
||||
}
|
||||
} else {
|
||||
if ($("div#port-picker #port [value='DFU']").length) {
|
||||
$("div#port-picker #port [value='DFU']").remove();
|
||||
}
|
||||
PortHandler.check_usb_devices = function (callback) {
|
||||
chrome.usb.getDevices(usbDevices.STM32DFU, function (result) {
|
||||
if (result.length) {
|
||||
if (!$("div#port-picker #port [value='DFU']").length) {
|
||||
$('div#port-picker #port').append($('<option/>', {value: "DFU", text: "DFU", data: {isDFU: true}}));
|
||||
$('div#port-picker #port').val('DFU');
|
||||
}
|
||||
});
|
||||
}
|
||||
self.dfu_available = true;
|
||||
} else {
|
||||
if ($("div#port-picker #port [value='DFU']").length) {
|
||||
$("div#port-picker #port [value='DFU']").remove();
|
||||
}
|
||||
self.dfu_available = false;
|
||||
}
|
||||
|
||||
if(callback) callback(self.dfu_available);
|
||||
});
|
||||
};
|
||||
|
||||
PortHandler.update_port_select = function (ports) {
|
||||
|
|
|
@ -100,14 +100,25 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
|
|||
serial.send(bufferOut, function () {
|
||||
serial.disconnect(function (result) {
|
||||
if (result) {
|
||||
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
|
||||
if (openInfo) {
|
||||
self.initialize();
|
||||
} else {
|
||||
GUI.connect_lock = false;
|
||||
GUI.log('<span style="color: red">Failed</span> to open serial port');
|
||||
}
|
||||
});
|
||||
// delay to allow board to boot in bootloader mode
|
||||
// required to detect if a DFU device appears
|
||||
setTimeout(function() {
|
||||
// refresh device list
|
||||
PortHandler.check_usb_devices(function(dfu_available) {
|
||||
if(dfu_available) {
|
||||
STM32DFU.connect(usbDevices.STM32DFU, hex, options);
|
||||
} else {
|
||||
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
|
||||
if (openInfo) {
|
||||
self.initialize();
|
||||
} else {
|
||||
GUI.connect_lock = false;
|
||||
GUI.log('<span style="color: red">Failed</span> to open serial port');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}, 1000);
|
||||
} else {
|
||||
GUI.connect_lock = false;
|
||||
}
|
||||
|
|
|
@ -61,13 +61,26 @@ var STM32DFU_protocol = function () {
|
|||
dfuUPLOAD_IDLE: 9, // The device is processing an upload operation. Expecting DFU_UPLOAD requests.
|
||||
dfuERROR: 10 // An error has occurred. Awaiting the DFU_CLRSTATUS request.
|
||||
};
|
||||
|
||||
// Assume 2 kB page size (STM32F303)
|
||||
// Cannot read chip ID using DFU protocol and Chrome doesn't provide the interface
|
||||
// description string with flash page size information (at least on Linux anyway)
|
||||
this.page_size = 2048;
|
||||
};
|
||||
|
||||
STM32DFU_protocol.prototype.connect = function (device, hex, callback) {
|
||||
STM32DFU_protocol.prototype.connect = function (device, hex, options, callback) {
|
||||
var self = this;
|
||||
self.hex = hex;
|
||||
self.callback = callback;
|
||||
|
||||
self.options = {
|
||||
erase_chip: false
|
||||
};
|
||||
|
||||
if (options.erase_chip) {
|
||||
self.options.erase_chip = true;
|
||||
}
|
||||
|
||||
// reset and set some variables before we start
|
||||
self.upload_time_start = new Date().getTime();
|
||||
self.verify_hex = [];
|
||||
|
@ -89,12 +102,35 @@ STM32DFU_protocol.prototype.connect = function (device, hex, callback) {
|
|||
});
|
||||
};
|
||||
|
||||
STM32DFU_protocol.prototype.checkChromeError = function() {
|
||||
if (chrome.runtime.lastError) {
|
||||
if(chrome.runtime.lastError.message)
|
||||
console.log(chrome.runtime.lastError.message);
|
||||
else
|
||||
console.log(chrome.runtime.lastError);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
STM32DFU_protocol.prototype.openDevice = function (device) {
|
||||
var self = this;
|
||||
|
||||
chrome.usb.openDevice(device, function (handle) {
|
||||
if(self.checkChromeError()) {
|
||||
console.log('Failed to open USB device!');
|
||||
GUI.log(chrome.i18n.getMessage('usbDeviceOpenFail'));
|
||||
if(GUI.operating_system === 'Linux') {
|
||||
GUI.log(chrome.i18n.getMessage('usbDeviceUdevNotice'));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
self.handle = handle;
|
||||
|
||||
GUI.log(chrome.i18n.getMessage('usbDeviceOpened', handle.handle.toString()));
|
||||
console.log('Device opened with Handle ID: ' + handle.handle);
|
||||
self.claimInterface(0);
|
||||
});
|
||||
|
@ -104,6 +140,12 @@ STM32DFU_protocol.prototype.closeDevice = function () {
|
|||
var self = this;
|
||||
|
||||
chrome.usb.closeDevice(this.handle, function closed() {
|
||||
if(self.checkChromeError()) {
|
||||
console.log('Failed to close USB device!');
|
||||
GUI.log(chrome.i18n.getMessage('usbDeviceCloseFail'));
|
||||
}
|
||||
|
||||
GUI.log(chrome.i18n.getMessage('usbDeviceClosed'));
|
||||
console.log('Device closed with Handle ID: ' + self.handle.handle);
|
||||
|
||||
self.handle = null;
|
||||
|
@ -139,6 +181,8 @@ STM32DFU_protocol.prototype.resetDevice = function (callback) {
|
|||
};
|
||||
|
||||
STM32DFU_protocol.prototype.controlTransfer = function (direction, request, value, _interface, length, data, callback) {
|
||||
var self = this;
|
||||
|
||||
if (direction == 'in') {
|
||||
// data is ignored
|
||||
chrome.usb.controlTransfer(this.handle, {
|
||||
|
@ -150,6 +194,9 @@ STM32DFU_protocol.prototype.controlTransfer = function (direction, request, valu
|
|||
'index': _interface,
|
||||
'length': length
|
||||
}, function (result) {
|
||||
if(self.checkChromeError()) {
|
||||
console.log('USB transfer failed!');
|
||||
}
|
||||
if (result.resultCode) console.log(result.resultCode);
|
||||
|
||||
var buf = new Uint8Array(result.data);
|
||||
|
@ -174,6 +221,9 @@ STM32DFU_protocol.prototype.controlTransfer = function (direction, request, valu
|
|||
'index': _interface,
|
||||
'data': arrayBuf
|
||||
}, function (result) {
|
||||
if(self.checkChromeError()) {
|
||||
console.log('USB transfer failed!');
|
||||
}
|
||||
if (result.resultCode) console.log(result.resultCode);
|
||||
|
||||
callback(result);
|
||||
|
@ -217,7 +267,7 @@ STM32DFU_protocol.prototype.loadAddress = function (address, callback) {
|
|||
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
||||
callback(data);
|
||||
} else {
|
||||
console.log('Failed to execure address load');
|
||||
console.log('Failed to execute address load');
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
});
|
||||
|
@ -256,32 +306,86 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
|||
});
|
||||
break;
|
||||
case 2:
|
||||
// full chip erase
|
||||
console.log('Executing global chip erase');
|
||||
$('span.progressLabel').text('Erasing ...');
|
||||
// erase
|
||||
if (self.options.erase_chip) {
|
||||
// full chip erase
|
||||
console.log('Executing global chip erase');
|
||||
$('span.progressLabel').text('Erasing ...');
|
||||
|
||||
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x41], function () {
|
||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||
if (data[4] == self.state.dfuDNBUSY) { // completely normal
|
||||
var delay = data[1] | (data[2] << 8) | (data[3] << 16);
|
||||
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x41], function () {
|
||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||
if (data[4] == self.state.dfuDNBUSY) { // completely normal
|
||||
var delay = data[1] | (data[2] << 8) | (data[3] << 16);
|
||||
|
||||
setTimeout(function () {
|
||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
||||
self.upload_procedure(4);
|
||||
} else {
|
||||
console.log('Failed to execute global chip erase');
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
});
|
||||
}, delay);
|
||||
} else {
|
||||
console.log('Failed to initiate global chip erase');
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
setTimeout(function () {
|
||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
||||
self.upload_procedure(4);
|
||||
} else {
|
||||
console.log('Failed to execute global chip erase');
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
});
|
||||
}, delay);
|
||||
} else {
|
||||
console.log('Failed to initiate global chip erase');
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// local erase
|
||||
|
||||
var max_address = self.hex.data[self.hex.data.length - 1].address + self.hex.data[self.hex.data.length - 1].bytes - 0x8000000,
|
||||
erase_pages_n = Math.ceil(max_address / self.page_size),
|
||||
page = 0;
|
||||
|
||||
$('span.progressLabel').text('Erasing ...');
|
||||
console.log('Executing local chip erase');
|
||||
console.log('Erasing. page: 0x00 - 0x' + erase_pages_n.toString(16));
|
||||
|
||||
var erase_page = function() {
|
||||
var page_addr = page * self.page_size + 0x8000000;
|
||||
var cmd = [0x41, page_addr & 0xff, (page_addr >> 8) & 0xff, (page_addr >> 16) & 0xff, (page_addr >> 24) & 0xff];
|
||||
|
||||
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, cmd, function () {
|
||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||
if (data[4] == self.state.dfuDNBUSY) { // completely normal
|
||||
var delay = data[1] | (data[2] << 8) | (data[3] << 16);
|
||||
|
||||
setTimeout(function () {
|
||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
||||
// update progress bar
|
||||
self.progress_bar_e.val((page + 1) / erase_pages_n * 100);
|
||||
page++;
|
||||
|
||||
if(page == erase_pages_n) {
|
||||
console.log("Erase: complete");
|
||||
GUI.log(chrome.i18n.getMessage('dfu_erased_kilobytes', (erase_pages_n * self.page_size / 1024).toString()));
|
||||
self.upload_procedure(4);
|
||||
}
|
||||
else
|
||||
erase_page();
|
||||
} else {
|
||||
console.log('Failed to erase page 0x' + self.current_page.toString(16));
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
});
|
||||
}, delay);
|
||||
} else {
|
||||
console.log('Failed to initiate page erase, page 0x' + self.current_page.toString(16));
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// start
|
||||
erase_page();
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// upload
|
||||
// we dont need to clear the state as we are already using DFU_DNLOAD
|
||||
|
@ -296,9 +400,6 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
|||
var bytes_flashed_total = 0; // used for progress bar
|
||||
var wBlockNum = 2; // required by DFU
|
||||
|
||||
// start
|
||||
self.loadAddress(address, write);
|
||||
|
||||
var write = function () {
|
||||
if (bytes_flashed < self.hex.data[flashing_block].bytes) {
|
||||
var bytes_to_write = ((bytes_flashed + 2048) <= self.hex.data[flashing_block].bytes) ? 2048 : (self.hex.data[flashing_block].bytes - bytes_flashed);
|
||||
|
@ -353,6 +454,10 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// start
|
||||
self.loadAddress(address, write);
|
||||
|
||||
break;
|
||||
case 5:
|
||||
// verify
|
||||
|
@ -463,13 +568,13 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
|||
});
|
||||
}
|
||||
|
||||
// start
|
||||
clear_before_leave();
|
||||
break;
|
||||
case 99:
|
||||
// cleanup
|
||||
self.releaseInterface(0);
|
||||
|
||||
GUI.connect_lock = false;
|
||||
|
||||
var timeSpent = new Date().getTime() - self.upload_time_start;
|
||||
|
||||
console.log('Script finished after: ' + (timeSpent / 1000) + ' seconds');
|
||||
|
|
|
@ -3,12 +3,19 @@
|
|||
$(document).ready(function () {
|
||||
|
||||
GUI.updateManualPortVisibility = function(){
|
||||
if ($('div#port-picker #port option:selected').data().isManual) {
|
||||
var selected_port = $('div#port-picker #port option:selected');
|
||||
if (selected_port.data().isManual) {
|
||||
$('#port-override-option').show();
|
||||
}
|
||||
else {
|
||||
$('#port-override-option').hide();
|
||||
}
|
||||
if (selected_port.data().isDFU) {
|
||||
$('select#baud').hide();
|
||||
}
|
||||
else {
|
||||
$('select#baud').show();
|
||||
}
|
||||
};
|
||||
|
||||
GUI.updateManualPortVisibility();
|
||||
|
@ -25,7 +32,7 @@ $(document).ready(function () {
|
|||
GUI.updateManualPortVisibility();
|
||||
});
|
||||
|
||||
$('div#port-picker a.connect').click(function () {
|
||||
$('div.connect_controls a.connect').click(function () {
|
||||
if (GUI.connect_lock != true) { // GUI control overrides the user control
|
||||
|
||||
var clicks = $(this).data('clicks');
|
||||
|
@ -33,15 +40,18 @@ $(document).ready(function () {
|
|||
var selected_port = $('div#port-picker #port option:selected').data().isManual ?
|
||||
$('#port-override').val() :
|
||||
String($('div#port-picker #port').val());
|
||||
|
||||
if (selected_port != '0' && selected_port != 'DFU') {
|
||||
if (selected_port === 'DFU') {
|
||||
GUI.log(chrome.i18n.getMessage('dfu_connect_message'));
|
||||
}
|
||||
else if (selected_port != '0') {
|
||||
if (!clicks) {
|
||||
console.log('Connecting to: ' + selected_port);
|
||||
GUI.connecting_to = selected_port;
|
||||
|
||||
// lock port select & baud while we are connecting / connected
|
||||
$('div#port-picker #port, div#port-picker #baud, div#port-picker #delay').prop('disabled', true);
|
||||
$('div#port-picker a.connect').text(chrome.i18n.getMessage('connecting'));
|
||||
$('div.connect_controls a.connect_state').text(chrome.i18n.getMessage('connecting'));
|
||||
|
||||
|
||||
serial.connect(selected_port, {bitrate: selected_baud}, onOpen);
|
||||
} else {
|
||||
|
@ -69,9 +79,9 @@ $(document).ready(function () {
|
|||
if (!GUI.auto_connect) $('div#port-picker #baud').prop('disabled', false);
|
||||
|
||||
// reset connect / disconnect button
|
||||
$(this).text(chrome.i18n.getMessage('connect'));
|
||||
$(this).removeClass('active');
|
||||
|
||||
$('div.connect_controls a.connect').removeClass('active');
|
||||
$('div.connect_controls a.connect_state').text(chrome.i18n.getMessage('connect'));
|
||||
|
||||
// reset active sensor indicators
|
||||
sensor_status(0);
|
||||
|
||||
|
@ -122,13 +132,22 @@ $(document).ready(function () {
|
|||
}
|
||||
|
||||
chrome.storage.local.set({'auto_connect': GUI.auto_connect});
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
PortHandler.initialize();
|
||||
PortUsage.initialize();
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
function onOpen(openInfo) {
|
||||
if (openInfo) {
|
||||
// update connected_to
|
||||
|
@ -159,7 +178,7 @@ function onOpen(openInfo) {
|
|||
if (!CONFIGURATOR.connectionValid) {
|
||||
GUI.log(chrome.i18n.getMessage('noConfigurationReceived'));
|
||||
|
||||
$('div#port-picker a.connect').click(); // disconnect
|
||||
$('div.connect_controls ').click(); // disconnect
|
||||
}
|
||||
}, 10000);
|
||||
|
||||
|
@ -220,28 +239,31 @@ function onOpen(openInfo) {
|
|||
console.log('Failed to open serial port');
|
||||
GUI.log(chrome.i18n.getMessage('serialPortOpenFail'));
|
||||
|
||||
$('div#port-picker a.connect').text(chrome.i18n.getMessage('connect'));
|
||||
$('div#port-picker a.connect').removeClass('active');
|
||||
$('div#connectbutton a.connect_state').text(chrome.i18n.getMessage('connect'));
|
||||
$('div#connectbutton a.connect').removeClass('active');
|
||||
|
||||
// unlock port select & baud
|
||||
$('div#port-picker #port, div#port-picker #baud, div#port-picker #delay').prop('disabled', false);
|
||||
|
||||
// reset data
|
||||
$('div#port-picker a.connect').data("clicks", false);
|
||||
$('div#connectbutton a.connect').data("clicks", false);
|
||||
}
|
||||
}
|
||||
|
||||
function onConnect() {
|
||||
GUI.timeout_remove('connecting'); // kill connecting timer
|
||||
$('div#port-picker a.connect').text(chrome.i18n.getMessage('disconnect')).addClass('active');
|
||||
$('div#connectbutton a.connect_state').text(chrome.i18n.getMessage('disconnect')).addClass('active');
|
||||
$('div#connectbutton a.connect').addClass('active');
|
||||
$('#tabs ul.mode-disconnected').hide();
|
||||
$('#tabs ul.mode-connected').show();
|
||||
|
||||
if ("CLFL" == CONFIG.flightControllerIdentifier){
|
||||
var documentationButton = $('#button-documentation');
|
||||
documentationButton.show();
|
||||
documentationButton.html("Documentation for "+CONFIG.flightControllerVersion);
|
||||
documentationButton.attr("href","https://github.com/cleanflight/cleanflight/tree/v{0}/docs".format(CONFIG.flightControllerVersion));
|
||||
|
||||
var sensor_state = $('#sensor-status');
|
||||
sensor_state.show();
|
||||
|
||||
var port_picker = $('#portsinput');
|
||||
port_picker.hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -255,8 +277,13 @@ function onClosed(result) {
|
|||
$('#tabs ul.mode-connected').hide();
|
||||
$('#tabs ul.mode-disconnected').show();
|
||||
|
||||
var documentationButton = $('#button-documentation');
|
||||
documentationButton.hide();
|
||||
var port_picker = $('#portsinput');
|
||||
port_picker.show();
|
||||
|
||||
/* */
|
||||
var sensor_state = $('#sensor-status');
|
||||
sensor_state.hide();
|
||||
|
||||
}
|
||||
|
||||
function read_serial(info) {
|
||||
|
@ -285,38 +312,54 @@ function sensor_status(sensors_detected) {
|
|||
|
||||
if (have_sensor(sensors_detected, 'acc')) {
|
||||
$('.accel', e_sensor_status).addClass('on');
|
||||
$('.accicon', e_sensor_status).addClass('active');
|
||||
|
||||
} else {
|
||||
$('.accel', e_sensor_status).removeClass('on');
|
||||
$('.accicon', e_sensor_status).removeClass('active');
|
||||
|
||||
}
|
||||
|
||||
if (have_sensor(sensors_detected, 'gyro')) {
|
||||
$('.gyro', e_sensor_status).addClass('on');
|
||||
$('.gyroicon', e_sensor_status).addClass('active');
|
||||
|
||||
} else {
|
||||
$('.gyro', e_sensor_status).removeClass('on');
|
||||
$('.gyroicon', e_sensor_status).removeClass('active');
|
||||
|
||||
}
|
||||
|
||||
if (have_sensor(sensors_detected, 'baro')) {
|
||||
$('.baro', e_sensor_status).addClass('on');
|
||||
$('.baroicon', e_sensor_status).addClass('active');
|
||||
} else {
|
||||
$('.baro', e_sensor_status).removeClass('on');
|
||||
$('.baroicon', e_sensor_status).removeClass('active');
|
||||
}
|
||||
|
||||
if (have_sensor(sensors_detected, 'mag')) {
|
||||
$('.mag', e_sensor_status).addClass('on');
|
||||
$('.magicon', e_sensor_status).addClass('active');
|
||||
} else {
|
||||
$('.mag', e_sensor_status).removeClass('on');
|
||||
$('.magicon', e_sensor_status).removeClass('active');
|
||||
}
|
||||
|
||||
if (have_sensor(sensors_detected, 'gps')) {
|
||||
$('.gps', e_sensor_status).addClass('on');
|
||||
$('.gpsicon', e_sensor_status).addClass('active');
|
||||
} else {
|
||||
$('.gps', e_sensor_status).removeClass('on');
|
||||
$('.gpsicon', e_sensor_status).removeClass('active');
|
||||
}
|
||||
|
||||
if (have_sensor(sensors_detected, 'sonar')) {
|
||||
$('.sonar', e_sensor_status).addClass('on');
|
||||
$('.sonaricon', e_sensor_status).addClass('active');
|
||||
} else {
|
||||
$('.sonar', e_sensor_status).removeClass('on');
|
||||
$('.sonaricon', e_sensor_status).removeClass('active');
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -360,3 +403,5 @@ function bit_set(num, bit) {
|
|||
function bit_clear(num, bit) {
|
||||
return num & ~(1 << bit);
|
||||
}
|
||||
|
||||
|
||||
|
|
36
js/usb.js
36
js/usb.js
|
@ -1,36 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
var usbDevices = {
|
||||
STM32DFU: {'vendorId': 1155, 'productId': 57105}
|
||||
};
|
||||
var usbPermissions = {permissions: [{'usbDevices': [usbDevices.STM32DFU]}]};
|
||||
|
||||
function check_usb_permissions(callback) {
|
||||
chrome.permissions.contains(usbPermissions, function (result) {
|
||||
if (result) {
|
||||
GUI.optional_usb_permissions = true;
|
||||
} else {
|
||||
console.log('Optional USB permissions: missing');
|
||||
GUI.log(chrome.i18n.getMessage('please_grant_usb_permissions'));
|
||||
|
||||
// display optional usb permissions request box
|
||||
$('div.optional_permissions').show();
|
||||
|
||||
// UI hooks
|
||||
document.getElementById("requestOptionalPermissions").addEventListener('click', function () {
|
||||
chrome.permissions.request(usbPermissions, function (result) {
|
||||
if (result) {
|
||||
GUI.log(chrome.i18n.getMessage('usb_permissions_granted'));
|
||||
$('div.optional_permissions').hide();
|
||||
|
||||
GUI.optional_usb_permissions = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue