diff --git a/.gitignore b/.gitignore index 44f647bb5..26c155113 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -/.idea/ /.*project /.settings /.autotools diff --git a/.gitmodules b/.gitmodules index 71ed20c2f..61bd2368d 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,8 @@ [submodule "libopenui"] path = radio/src/thirdparty/libopenui - url = ../libopenui.git + url = https://github.com/opentx/libopenui.git + branch = master +[submodule "libACCESS"] + path = radio/src/thirdparty/libACCESS + url = https://github.com/FrSky-OS/libACCESS.git branch = master diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 000000000..f108063c7 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,5 @@ +*.iml +misc.xml +modules.xml +vcs.xml +workspace.xml diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 000000000..7a7d96690 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +OpenTX \ No newline at end of file diff --git a/.idea/codeStyleSettings.xml b/.idea/codeStyleSettings.xml new file mode 100644 index 000000000..cc9af5006 --- /dev/null +++ b/.idea/codeStyleSettings.xml @@ -0,0 +1,57 @@ + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 000000000..777209761 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,31 @@ + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 000000000..6e6eec114 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/.idea/encodings.xml b/.idea/encodings.xml new file mode 100644 index 000000000..22f558132 --- /dev/null +++ b/.idea/encodings.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 582215347..442466067 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,7 @@ env: # - FLAVOR=SKY9X # - FLAVOR=9XRPRO - FLAVOR=X9LITE + - FLAVOR=X9LITES - FLAVOR=X7 - FLAVOR=T12 - FLAVOR=XLITE @@ -32,6 +33,7 @@ env: # - FLAVOR=X9D # - FLAVOR=X9D+ # - FLAVOR=X9E + - FLAVOR=T16 - FLAVOR=HORUS # - FLAVOR=X10 # - FLAVOR=X12Sr10 diff --git a/CMakeLists.txt b/CMakeLists.txt index baa7bbbe1..fd5ef8ceb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,11 +2,11 @@ project(OpenTX) set(VERSION_MAJOR "2") set(VERSION_MINOR "3") -set(VERSION_REVISION "0") +set(VERSION_REVISION "2") set(VERSION_SUFFIX $ENV{OPENTX_VERSION_SUFFIX}) set(VERSION_FAMILY ${VERSION_MAJOR}.${VERSION_MINOR}) set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_REVISION}${VERSION_SUFFIX}) -set(SDCARD_REVISION "0021") +set(SDCARD_REVISION "0023") set(SDCARD_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}V${SDCARD_REVISION}) cmake_minimum_required(VERSION 2.8) @@ -228,6 +228,11 @@ endif() add_subdirectory(${RADIO_SRC_DIR}) +add_custom_target(tests-radio + COMMAND ${CMAKE_CURRENT_BINARY_DIR}/gtests-radio + DEPENDS gtests-radio + ) + if(Qt5Core_FOUND AND NOT DISABLE_COMPANION) add_subdirectory(${COMPANION_SRC_DIRECTORY}) add_custom_target(gtests DEPENDS gtests-radio gtests-companion) diff --git a/CREDITS.txt b/CREDITS.txt index 68c996281..62e673034 100644 --- a/CREDITS.txt +++ b/CREDITS.txt @@ -27,6 +27,8 @@ Michael Byrne [Companies and projects who have donated to OpenTX] FrSky (monthly) +FlySky (monthly) +JumperRC (monthly) Aloft Hobbies Jonathan Modellismo WsTech @@ -1539,3 +1541,95 @@ Piotr Wysocki Thomas Halenbeck (monthly) Sjoerd Dost Ralph Gustafson +Herbert Feix +Robert Costford +Taavi Tuisk +Carlos Quian +Noah Reinhart +Timothy Fry +Marc Stelzner +NXGRAPHICS +AIR-RC +Nicolas Deshaies +Jean-Francois Delhove +Hugo Daniel Farneti +RC electronic products +Adrian Andrei +Henk van de Kerkhof +Daniel Dubovski +Hans-Georg Böhm +Tiberiu Atudorei +Alessandro Apostoli (Yaapu!) +Kenneth Bonerigo +Frits van Voorst +Steven Dodge +Christian Buchinger +Patrick Blanc +Darrell Carew +Philippe Faure +Marco Lange +Aaron Tygart +Frantisek Vajbar +Mike Perkins +Knut Einar Kristensen +Georgios Papadopoulos +He Liu +Andrias Thomsen +Alain Azais +Alan Stuart +Fernando Rimoldi +James Snodgrass +Diego Mendoza Gonzalez +Dale Wheeler +Nico Wagner +James A Davey +Peter Glassey +Jeff Dillingham +Don Crowe +Nicola Claudio Rossi +Fabien Leroy +Tyler Nelson +Stuart Olson +Reinhard Plietsch +Manuel Spoerri +Paul Pearson +Thierry Laligand +Bruno Mexique +Uwe Jordt +Markus Goelzner +Jean-Claude Etiemble +Wojciech Winiarski +Michael Fleming +Russell G Shanks +Mike Sedgwick +William Goodrich +Marcel Schäfer +Joseph Santa Cruz +Gerald Roedel +James D McKeown +鄭 淳中 +Matthias Wuethrich +Michael Tessler +John Beech +Stefan Möst +Thomas McGraw +Bruno N Russo Jr +Daniel Eikenkötter +Guy Poignonec +Gérard Falaise +Jacques Loubier +Kelly Warner +James Cox +Sidney B Harden +CG Tech Inc. +Richard Gopstein +Francesco Ziche +Jean Paul Duroch +Romane Oughlissi +Alexander Maciol +Udo Kastenholz +Jacek Wielogórski +Siegfried Preißler +Bernard Mohamedaly +John North +Thomas Wormsley diff --git a/LICENSE b/LICENSE index f288702d2..d159169d1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,622 +1,281 @@ GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 + Version 2, June 1991 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to this License. - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. - 13. Use with the GNU Affero General Public License. +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. - 14. Revised Versions of this License. +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. + NO WARRANTY - 15. Disclaimer of Warranty. + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS @@ -628,15 +287,15 @@ free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least +convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) - This program is free software: you can redistribute it and/or modify + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or + the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -644,31 +303,37 @@ the "copyright" line and a pointer to where the full notice is found. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. diff --git a/companion/src/CMakeLists.txt b/companion/src/CMakeLists.txt index 773212f32..f76a7f252 100644 --- a/companion/src/CMakeLists.txt +++ b/companion/src/CMakeLists.txt @@ -347,6 +347,8 @@ elseif(PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) set(FLAVOUR x9d+2019) elseif(PCB STREQUAL X10 AND PCBREV STREQUAL EXPRESS) set(FLAVOUR x10express) +elseif(PCB STREQUAL X10 AND PCBREV STREQUAL T16) + set(FLAVOUR t16) else() string(TOLOWER ${PCB} FLAVOUR) endif() diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc index 2b4b18f71..32ace6a12 100644 --- a/companion/src/companion.qrc +++ b/companion/src/companion.qrc @@ -136,6 +136,14 @@ images/simulator/X9E/right.png images/simulator/X9E/right_enter.png images/simulator/X9E/top.png + images/simulator/X9D2019/bottom.png + images/simulator/X9D2019/left.png + images/simulator/X9D2019/left_exit.png + images/simulator/X9D2019/left_menu.png + images/simulator/X9D2019/left_page.png + images/simulator/X9D2019/right.png + images/simulator/X9D2019/right_enter.png + images/simulator/X9D2019/top.png images/simulator/X9LITE/bottom.png images/simulator/X9LITE/left.png images/simulator/X9LITE/left_exit.png @@ -170,6 +178,17 @@ images/simulator/JumperT12/JumperT12-x.png images/simulator/JumperT12/JumperT12-center.png images/simulator/JumperT12/JumperT12-top.png + images/simulator/JumperT16/left.png + images/simulator/JumperT16/right.png + images/simulator/JumperT16/top.png + images/simulator/JumperT16/bottom.png + images/simulator/JumperT16/left_mdl.png + images/simulator/JumperT16/left_page.png + images/simulator/JumperT16/left_scrnsht.png + images/simulator/JumperT16/left_sys.png + images/simulator/JumperT16/left_tele.png + images/simulator/JumperT16/right_ent.png + images/simulator/JumperT16/right_rtn.png images/wizard/ailerons.png images/wizard/airbrakes.png images/wizard/elevons.png diff --git a/companion/src/datamodels/rawitemdatamodels.cpp b/companion/src/datamodels/rawitemdatamodels.cpp index f1e613d4a..1cba1c180 100644 --- a/companion/src/datamodels/rawitemdatamodels.cpp +++ b/companion/src/datamodels/rawitemdatamodels.cpp @@ -85,6 +85,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett Firmware * fw = getCurrentFirmware(); // Descending switch direction: NOT (!) switches + addItems(SWITCH_TYPE_ACT, -1); addItems(SWITCH_TYPE_SENSOR, -CPN_MAX_SENSORS); addItems(SWITCH_TYPE_TELEMETRY, -1); addItems(SWITCH_TYPE_FLIGHT_MODE, -fw->getCapability(FlightModes)); @@ -107,6 +108,7 @@ RawSwitchItemModel::RawSwitchItemModel(const GeneralSettings * const generalSett addItems(SWITCH_TYPE_SENSOR, CPN_MAX_SENSORS); addItems(SWITCH_TYPE_ON, 1); addItems(SWITCH_TYPE_ONE, 1); + addItems(SWITCH_TYPE_ACT, 1); } void RawSwitchItemModel::setDynamicItemData(QStandardItem * item, const RawSwitch & rsw) const diff --git a/companion/src/firmwares/boards.cpp b/companion/src/firmwares/boards.cpp index 9f375411f..726cae256 100644 --- a/companion/src/firmwares/boards.cpp +++ b/companion/src/firmwares/boards.cpp @@ -75,6 +75,8 @@ uint32_t Boards::getFourCC(Type board) return 0x3378746F; case BOARD_TARANIS_X9LITE: return 0x3C78746F; + case BOARD_TARANIS_X9LITES: + return 0x3E78746F; case BOARD_SKY9X: case BOARD_AR9X: case BOARD_9XRPRO: @@ -87,6 +89,8 @@ uint32_t Boards::getFourCC(Type board) return 0; case BOARD_JUMPER_T12: return 0x3D78746F; + case BOARD_JUMPER_T16: + return 0x3F78746F; case BOARD_UNKNOWN: break; } @@ -113,6 +117,7 @@ int Boards::getEEpromSize(Board::Type board) case BOARD_TARANIS_XLITE: case BOARD_TARANIS_X7: case BOARD_TARANIS_X9LITE: + case BOARD_TARANIS_X9LITES: case BOARD_TARANIS_X9D: case BOARD_TARANIS_X9DP: case BOARD_TARANIS_X9DP_2019: @@ -124,6 +129,7 @@ int Boards::getEEpromSize(Board::Type board) case BOARD_HORUS_X12S: case BOARD_X10: case BOARD_X10_EXPRESS: + case BOARD_JUMPER_T16: return 0; } @@ -149,6 +155,7 @@ int Boards::getFlashSize(Type board) case BOARD_TARANIS_XLITE: case BOARD_TARANIS_X7: case BOARD_TARANIS_X9LITE: + case BOARD_TARANIS_X9LITES: case BOARD_TARANIS_X9D: case BOARD_TARANIS_X9DP: case BOARD_TARANIS_X9DP_2019: @@ -158,6 +165,7 @@ int Boards::getFlashSize(Type board) case BOARD_HORUS_X12S: case BOARD_X10: case BOARD_X10_EXPRESS: + case BOARD_JUMPER_T16: return FSIZE_HORUS; case BOARD_UNKNOWN: return FSIZE_MAX; @@ -273,7 +281,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) return 2; else if (IS_TARANIS_X9E(board)) return 4; - else if (IS_HORUS_X10(board)) + else if (IS_HORUS_X10(board) || IS_JUMPER_T16(board)) return 5; else if (IS_HORUS_X12S(board)) return 3; @@ -289,7 +297,7 @@ int Boards::getCapability(Board::Type board, Board::Capability capability) case Sliders: if (IS_HORUS_X12S(board) || IS_TARANIS_X9E(board)) return 4; - else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board)) + else if (IS_TARANIS_X9D(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board)) return 2; else return 0; @@ -454,7 +462,7 @@ QString Boards::getAnalogInputName(Board::Type board, int index) if (index < DIM(pots)) return pots[index]; } - else if (IS_HORUS_X10(board)) { + else if (IS_HORUS_X10(board) || IS_JUMPER_T16(board)) { const QString pots[] = { "S1", "6P", @@ -505,6 +513,8 @@ QString Boards::getBoardName(Board::Type board) return "Taranis X9E"; case BOARD_TARANIS_X9LITE: return "Taranis X9-Lite"; + case BOARD_TARANIS_X9LITES: + return "Taranis X9-Lite S"; case BOARD_SKY9X: return "Sky9x"; case BOARD_9XRPRO: @@ -516,7 +526,9 @@ QString Boards::getBoardName(Board::Type board) case BOARD_X10: return "Horus X10/X10S"; case BOARD_X10_EXPRESS: - return "Horus X10 Express"; + return "Horus X10/X10S Express"; + case BOARD_JUMPER_T16: + return "Jumper T16"; default: return tr("Unknown"); } diff --git a/companion/src/firmwares/boards.h b/companion/src/firmwares/boards.h index 06a7a0f04..c3cd3ff59 100644 --- a/companion/src/firmwares/boards.h +++ b/companion/src/firmwares/boards.h @@ -50,10 +50,12 @@ namespace Board { BOARD_TARANIS_XLITE, BOARD_TARANIS_XLITES, BOARD_TARANIS_X9LITE, + BOARD_TARANIS_X9LITES, BOARD_JUMPER_T12, + BOARD_JUMPER_T16, }; - constexpr int BOARD_TYPE_MAX = BOARD_JUMPER_T12 ; + constexpr int BOARD_TYPE_MAX = BOARD_JUMPER_T16 ; enum PotType { @@ -222,6 +224,11 @@ inline bool IS_JUMPER_T12(Board::Type board) return board == Board::BOARD_JUMPER_T12; } +inline bool IS_JUMPER_T16(Board::Type board) +{ + return board == Board::BOARD_JUMPER_T16; +} + inline bool IS_TARANIS_XLITE(Board::Type board) { return board == Board::BOARD_TARANIS_XLITE || board == Board::BOARD_TARANIS_XLITES; @@ -239,7 +246,7 @@ inline bool IS_TARANIS_X7(Board::Type board) inline bool IS_TARANIS_X9LITE(Board::Type board) { - return board == Board::BOARD_TARANIS_X9LITE; + return board == Board::BOARD_TARANIS_X9LITE || board == Board::BOARD_TARANIS_X9LITES; } inline bool IS_TARANIS_X9(Board::Type board) @@ -284,7 +291,7 @@ inline bool IS_HORUS_X12S(Board::Type board) inline bool IS_HORUS(Board::Type board) { - return IS_HORUS_X12S(board) || IS_HORUS_X10(board); + return IS_HORUS_X12S(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board); } inline bool IS_HORUS_OR_TARANIS(Board::Type board) @@ -309,7 +316,13 @@ inline bool HAS_LARGE_LCD(Board::Type board) inline bool HAS_EXTERNAL_ANTENNA(Board::Type board) { - return (IS_HORUS(board) && board != Board::BOARD_X10_EXPRESS) || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board)); + return (board == Board::BOARD_X10 || board == Board::BOARD_HORUS_X12S || (IS_TARANIS_XLITE(board) && !IS_TARANIS_XLITES(board))); +} + +inline bool IS_ACCESS_RADIO(Board::Type board, QString &id) +{ + return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == Board::BOARD_TARANIS_X9DP_2019 || board == Board::BOARD_X10_EXPRESS || + (IS_HORUS(board) && id.contains("internalaccess"))); } #endif // _BOARDS_H_ diff --git a/companion/src/firmwares/generalsettings.cpp b/companion/src/firmwares/generalsettings.cpp index 4f8532cd4..22934cf57 100644 --- a/companion/src/firmwares/generalsettings.cpp +++ b/companion/src/firmwares/generalsettings.cpp @@ -88,7 +88,7 @@ GeneralSettings::GeneralSettings() vBatMin = -5; //8,5V vBatMax = -5; //11,5V } - else if (IS_TARANIS_XLITE(board) || IS_HORUS_X10(board)) { + else if (IS_TARANIS_XLITE(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board)) { // Lipo 2S vBatWarn = 66; vBatMin = -23; // 6.7V @@ -267,7 +267,7 @@ void GeneralSettings::setDefaultControlTypes(Board::Type board) sliderConfig[2] = Board::SLIDER_WITH_DETENT; sliderConfig[3] = Board::SLIDER_WITH_DETENT; } - else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board)) { + else if (IS_TARANIS_X9(board) || IS_HORUS_X10(board) || IS_JUMPER_T16(board)) { sliderConfig[0] = Board::SLIDER_WITH_DETENT; sliderConfig[1] = Board::SLIDER_WITH_DETENT; } diff --git a/companion/src/firmwares/generalsettings.h b/companion/src/firmwares/generalsettings.h index f3b415ec4..a111cac1e 100644 --- a/companion/src/firmwares/generalsettings.h +++ b/companion/src/firmwares/generalsettings.h @@ -109,6 +109,7 @@ class GeneralSettings { bool adjustRTC; bool optrexDisplay; unsigned int inactivityTimer; + unsigned int telemetryBaudrate; bool minuteBeep; bool preBeep; bool flashBeep; @@ -140,6 +141,7 @@ class GeneralSettings { unsigned int rotarySteps; unsigned int countryCode; bool jitterFilter; + bool rtcCheckDisable; unsigned int imperial; char ttsLanguage[2+1]; int beepVolume; diff --git a/companion/src/firmwares/moduledata.cpp b/companion/src/firmwares/moduledata.cpp index 50310c5d0..b4457345a 100644 --- a/companion/src/firmwares/moduledata.cpp +++ b/companion/src/firmwares/moduledata.cpp @@ -57,6 +57,30 @@ bool ModuleData::isPxx1Module() const } } +bool ModuleData::supportRxNum() const +{ + switch (protocol) { + case PULSES_PXX_XJT_X16: + case PULSES_PXX_R9M: + case PULSES_PXX_R9M_LITE: + case PULSES_PXX_R9M_LITE_PRO: + case PULSES_MULTIMODULE: + case PULSES_ACCESS_ISRM: + case PULSES_ACCST_ISRM_D16: + case PULSES_ACCESS_R9M: + case PULSES_ACCESS_R9M_LITE: + case PULSES_ACCESS_R9M_LITE_PRO: + case PULSES_XJT_LITE_X16: + case PULSES_XJT_LITE_LR12: + case PULSES_PXX_XJT_LR12: + case PULSES_LP45: + case PULSES_DSM2: + case PULSES_DSMX: + return true; + default: + return false; + } +} QString ModuleData::rfProtocolToString() const { @@ -127,12 +151,12 @@ QString ModuleData::protocolToString(unsigned protocol) "FrSky XJT (D16)", "FrSky XJT (D8)", "FrSky XJT (LR12)", "FrSky DJT", "TBS Crossfire", "DIY Multiprotocol Module", - "FrSky PXX R9M", - "FrSky PXX R9M Lite", - "FrSky PXX R9M Lite Pro", + "FrSky R9M", + "FrSky R9M Lite", + "FrSky R9M Lite Pro", "SBUS output at VBat", "FrSky ACCESS ISRM", "FrSky ACCST ISRM D16", - "FrSky ACCESS R9M", + "FrSky ACCESS R9M 2019", "FrSky ACCESS R9M Lite", "FrSky ACCESS R9M Lite Pro", "FrSky XJT lite (D16)", "FrSky XJT lite (D8)", "FrSky XJT lite (LR12)" diff --git a/companion/src/firmwares/moduledata.h b/companion/src/firmwares/moduledata.h index 5d86c2876..8f3f8cd53 100644 --- a/companion/src/firmwares/moduledata.h +++ b/companion/src/firmwares/moduledata.h @@ -114,7 +114,10 @@ enum MultiModuleRFProtocols { MODULE_SUBTYPE_MULTI_POTENSIC, MODULE_SUBTYPE_MULTI_ZSX, MODULE_SUBTYPE_MULTI_FLYZONE, - MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_FLYZONE + MODULE_SUBTYPE_MULTI_SCANNER, + MODULE_SUBTYPE_MULTI_FRSKYX_RX, + MODULE_SUBTYPE_MULTI_AFHDS2A_RX, + MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_AFHDS2A_RX }; enum TrainerProtocol { @@ -183,6 +186,7 @@ class ModuleData { void convert(RadioDataConversionState & cstate); bool isPxx2Module() const; bool isPxx1Module() const; + bool supportRxNum() const; QString polarityToString() const { return ppm.pulsePol ? tr("Positive") : tr("Negative"); } QString rfProtocolToString() const; QString subTypeToString(int type = -1) const; diff --git a/companion/src/firmwares/multiprotocols.cpp b/companion/src/firmwares/multiprotocols.cpp index 41f2e83c8..73f9ea69f 100644 --- a/companion/src/firmwares/multiprotocols.cpp +++ b/companion/src/firmwares/multiprotocols.cpp @@ -71,6 +71,7 @@ static const QStringList STR_SUBTYPE_REDPINE {"Fast", "Slow"}; static const QStringList STR_SUBTYPE_POTENSIC {"A20 Firefly"}; static const QStringList STR_SUBTYPE_ZSX {"JJRC ZSX-280"}; static const QStringList STR_SUBTYPE_FLYZONE {"FZ-410 TX"}; +static const QStringList STR_SUBTYPE_FRSKYX_RX {"D16 FCC", "D16 LBT"}; static const QStringList NO_SUBTYPE {STR_MULTI_DEFAULT}; @@ -108,7 +109,7 @@ const Multiprotocols multiProtocols { {MODULE_SUBTYPE_MULTI_HITEC, 2, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_BUGS_MINI, 1, false, STR_SUBTYPE_BUGS_MINI, nullptr}, {MODULE_SUBTYPE_MULTI_TRAXXAS, 0, false, STR_SUBTYPE_TRAXXAS, nullptr}, - {MODULE_SUBTYPE_MULTI_E01X, 2, false, STR_SUBTYPE_E01X, nullptr}, + {MODULE_SUBTYPE_MULTI_E01X, 2, false, STR_SUBTYPE_E01X, STR_MULTI_OPTION}, {MODULE_SUBTYPE_MULTI_V911S, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, nullptr}, {MODULE_SUBTYPE_MULTI_KF606, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, @@ -116,6 +117,7 @@ const Multiprotocols multiProtocols { {MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, STR_SUBTYPE_POTENSIC, nullptr}, {MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr}, {MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr}, + {MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE}, {MM_RF_CUSTOM_SELECTED, 7, true, STR_SUBTYPE_CUSTOM, STR_MULTI_OPTION}, // Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff) @@ -158,7 +160,7 @@ QString Multiprotocols::protocolToString(int protocol, bool custom) "Bayang", "ESky", "MT99XX", "MJXQ", "Shenqi", "FY326", "SFHSS", "J6 PRO","FQ777","Assan","Hontai","Open LRS", "FlySky AFHDS2A", "Q2x2", "Walkera", "Q303", "GW008", "DM002", "Cabell", "ESky 150", "H8 3D", "Corona", "CFlie", "Hitec", "Wfly", "Bugs", "Bugs Mini", "Traxxas", "NCC-1701-A", "E01X", "WL Heli V911S", "GD00X", "Volantex V761", - "KFPlan KF606", "Redpine", "Potensic", "ZXS", "FlyZone" + "KFPlan KF606", "Redpine", "Potensic", "ZXS", "FlyZone", "Scanner", "FrSky RX", "FlySky AFHDS2A RX" }); if (protocol == MM_RF_CUSTOM_SELECTED || custom) diff --git a/companion/src/firmwares/opentx/opentxeeprom.cpp b/companion/src/firmwares/opentx/opentxeeprom.cpp index a81457e23..80b56f16f 100644 --- a/companion/src/firmwares/opentx/opentxeeprom.cpp +++ b/companion/src/firmwares/opentx/opentxeeprom.cpp @@ -217,6 +217,10 @@ class SwitchesConversionTable: public ConversionTable { addConversion(RawSwitch(SWITCH_TYPE_SENSOR, i), val++); } } + if (version >= 219) { + addConversion(RawSwitch(SWITCH_TYPE_ACT, -1), -val+offset); + addConversion(RawSwitch(SWITCH_TYPE_ACT, 1), val++); + } } @@ -1914,7 +1918,7 @@ class SensorField: public TransformedField { if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) { _id = sensor.id; _subid = sensor.subid; - _instance = (sensor.instance & 0x1F) | (sensor.rxIdx << 5) | (sensor.moduleIdx << 7); + _instance = sensor.instance == 0 ? 0 : ((sensor.instance - 1) & 0x1F) | (sensor.rxIdx << 5) | (sensor.moduleIdx << 7); _ratio = sensor.ratio; _offset = sensor.offset; } @@ -1942,12 +1946,12 @@ class SensorField: public TransformedField { sensor.id = _id; sensor.subid = _subid; if (model.moduleData[0].isPxx1Module() || model.moduleData[1].isPxx1Module()) { - sensor.instance = (_instance & 0x1F) + (version <= 218 ? -1 : 0); // 5 bits instance + sensor.instance = (_instance & 0x1F) + (version <= 218 ? 0 : 1); // 5 bits instance sensor.rxIdx = 0x03; // 2 bits Rx idx sensor.moduleIdx = 0x01; // 1 bit module idx } else { - sensor.instance = _instance & 0x1F; + sensor.instance = (_instance & 0x1F) + 1; sensor.rxIdx = (_instance >> 5) & 0x03; // 2 bits Rx idx sensor.moduleIdx = (_instance >> 7) & 0x1; // 1 bit module idx } @@ -2048,7 +2052,6 @@ class ModuleUnionField: public UnionField { void beforeExport() override { - module.rfProtocol = module.multi.rfProtocol & 0xf; rfProtExtra = (module.multi.rfProtocol >> 4) & 0x03; } @@ -2089,9 +2092,6 @@ class ModuleUnionField: public UnionField { void beforeExport() override { - if (module.protocol >= PULSES_PXX_XJT_X16 && module.protocol <= PULSES_PXX_XJT_LR12) { - module.subType = module.protocol - PULSES_PXX_XJT_X16; - } } void afterImport() override @@ -2132,9 +2132,6 @@ class ModuleUnionField: public UnionField { void beforeExport() override { - if (module.protocol == PULSES_ACCST_ISRM_D16 || module.protocol == PULSES_ACCESS_ISRM) { - module.subType = module.protocol - PULSES_ACCESS_ISRM; - } for (int i=0; i= PULSES_LP45 && module.protocol <= PULSES_DSMX) { module.rfProtocol = module.protocol - PULSES_LP45; } + else if (module.protocol == PULSES_ACCST_ISRM_D16 || module.protocol == PULSES_ACCESS_ISRM) { + module.subType = module.protocol - PULSES_ACCESS_ISRM; + } + else if (module.protocol >= PULSES_PXX_XJT_X16 && module.protocol <= PULSES_PXX_XJT_LR12) { + module.subType = module.protocol - PULSES_PXX_XJT_X16; + } + else if (module.protocol == PULSES_MULTIMODULE) { + module.rfProtocol = module.multi.rfProtocol & 0xf; + } } void afterImport() override @@ -2361,8 +2367,8 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig internalField.Append(new UnsignedField<8>(this, modelData.rssiSource)); if (IS_TARANIS_X9(board)) { - // TODO TOPBAR - internalField.Append(new SpareBitsField<16>(this)); + internalField.Append(new UnsignedField<8>(this, modelData.frsky.voltsSource)); + internalField.Append(new UnsignedField<8>(this, modelData.frsky.altitudeSource)); } internalField.Append(new BoolField<1>(this, modelData.rssiAlarms.disabled)); @@ -2395,7 +2401,7 @@ OpenTxModelData::OpenTxModelData(ModelData & modelData, Board::Type board, unsig if (version >= 219) { // Trainer PPM settings - internalField.Append(new SpareBitsField<3>(this)); // TODO mode + internalField.Append(new UnsignedField<3>(this, modelData.trainerMode)); internalField.Append(new SpareBitsField<5>(this)); internalField.Append(new UnsignedField<8>(this, modelData.moduleData[2].channelsStart)); internalField.Append(new ConversionField >(this, modelData.moduleData[2].channelsCount, -8)); @@ -2571,7 +2577,8 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type internalField.Append(new SignedField<2>(this, generalData.antennaMode)); else internalField.Append(new SpareBitsField<2>(this)); - internalField.Append(new SpareBitsField<3>(this)); + internalField.Append(new BoolField<1>(this, generalData.rtcCheckDisable)); + internalField.Append(new SpareBitsField<2>(this)); for (int i=0; i<4; i++) { internalField.Append(new SignedField<16>(this, generalData.trainer.calib[i])); @@ -2602,7 +2609,7 @@ OpenTxGeneralData::OpenTxGeneralData(GeneralSettings & generalData, Board::Type } internalField.Append(new UnsignedField<8>(this, generalData.inactivityTimer)); - internalField.Append(new SpareBitsField<3>(this)); // telemetryBaudrate + internalField.Append(new UnsignedField<3>(this, generalData.telemetryBaudrate)); if (IS_HORUS(board)) internalField.Append(new SpareBitsField<3>(this)); else if (IS_TARANIS(board)) diff --git a/companion/src/firmwares/opentx/opentxinterface.cpp b/companion/src/firmwares/opentx/opentxinterface.cpp index 3ba4f2a7a..3b4413a3c 100644 --- a/companion/src/firmwares/opentx/opentxinterface.cpp +++ b/companion/src/firmwares/opentx/opentxinterface.cpp @@ -68,6 +68,8 @@ const char * OpenTxEepromInterface::getName() return "OpenTX for Gruvin9x board / 9X"; case BOARD_JUMPER_T12: return "OpenTX for Jumper T12"; + case BOARD_JUMPER_T16: + return "OpenTX for Jumper T16"; case BOARD_TARANIS_X9D: return "OpenTX for FrSky Taranis X9D"; case BOARD_TARANIS_X9DP: @@ -78,6 +80,8 @@ const char * OpenTxEepromInterface::getName() return "OpenTX for FrSky Taranis X9E"; case BOARD_TARANIS_X7: return "OpenTX for FrSky Taranis X7"; + case BOARD_TARANIS_X9LITES: + return "OpenTX for FrSky Taranis X9-Lite S"; case BOARD_TARANIS_X9LITE: return "OpenTX for FrSky Taranis X9-Lite"; case BOARD_TARANIS_XLITE: @@ -445,7 +449,7 @@ int OpenTxFirmware::getCapability(::Capability capability) else return id.contains("imperial") ? 1 : 0; case ModelImage: - return (board == BOARD_TARANIS_X9D || IS_TARANIS_PLUS(board) || IS_HORUS(board)); + return (board == BOARD_TARANIS_X9D || IS_TARANIS_PLUS(board) || board == BOARD_TARANIS_X9DP_2019 || IS_HORUS(board)); case HasBeeper: return (!IS_ARM(board)); case HasPxxCountry: @@ -768,18 +772,20 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) return true; case PULSES_PXX_XJT_X16: case PULSES_PXX_XJT_LR12: - return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); + return !IS_ACCESS_RADIO(board, id) && board != BOARD_JUMPER_T16; case PULSES_PXX_XJT_D8: - return !(IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || id.contains("eu")); + return !(IS_ACCESS_RADIO(board, id) || id.contains("eu")) && board != BOARD_JUMPER_T16; case PULSES_PPM: return id.contains("internalppm"); case PULSES_ACCESS_ISRM: case PULSES_ACCST_ISRM_D16: - return IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_HORUS(board) && id.contains("internalaccess")); + return IS_ACCESS_RADIO(board, id); + case PULSES_MULTIMODULE: + return id.contains("internalmulti"); default: return false; } - + case 1: switch (proto) { case PULSES_OFF: @@ -797,13 +803,15 @@ bool OpenTxFirmware::isAvailable(PulsesProtocol proto, int port) case PULSES_MULTIMODULE: case PULSES_CROSSFIRE: return true; + case PULSES_ACCESS_R9M: + return IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board) || board == BOARD_TARANIS_X9DP_2019 || board == BOARD_X10_EXPRESS || (IS_HORUS(board) && id.contains("internalaccess")); + case PULSES_PXX_R9M_LITE: case PULSES_ACCESS_R9M_LITE: case PULSES_ACCESS_R9M_LITE_PRO: - return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); case PULSES_XJT_LITE_X16: case PULSES_XJT_LITE_D8: case PULSES_XJT_LITE_LR12: - return (IS_TARANIS_XLITES(board) || IS_TARANIS_X9LITE(board)); + return (IS_TARANIS_XLITE(board) || IS_TARANIS_X9LITE(board)); default: return false; } @@ -1214,7 +1222,7 @@ void registerOpenTxFirmwares() /* FrSky Taranis X9D+ 2019 board */ firmware = new OpenTxFirmware("opentx-x9d+2019", Firmware::tr("FrSky Taranis X9D+ 2019"), BOARD_TARANIS_X9DP_2019); addOpenTxTaranisOptions(firmware); - addPPMInternalModuleHack(firmware); + firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); registerOpenTxFirmware(firmware); /* FrSky Taranis X9D board */ @@ -1238,6 +1246,12 @@ void registerOpenTxFirmwares() firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); registerOpenTxFirmware(firmware); + /* FrSky X9-LiteS board */ + firmware = new OpenTxFirmware("opentx-x9lites", Firmware::tr("FrSky Taranis X9-Lite S"), BOARD_TARANIS_X9LITES); + addOpenTxTaranisOptions(firmware); + firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); + registerOpenTxFirmware(firmware); + /* FrSky X7 board */ firmware = new OpenTxFirmware("opentx-x7", Firmware::tr("FrSky Taranis X7 / X7S"), BOARD_TARANIS_X7); addOpenTxTaranisOptions(firmware); @@ -1262,8 +1276,9 @@ void registerOpenTxFirmwares() registerOpenTxFirmware(firmware); /* FrSky X10 Express board */ - firmware = new OpenTxFirmware("opentx-x10express", Firmware::tr("FrSky Horus X10 Express"), BOARD_X10_EXPRESS); + firmware = new OpenTxFirmware("opentx-x10express", Firmware::tr("FrSky Horus X10 / X10S Express"), BOARD_X10_EXPRESS); addOpenTxFrskyOptions(firmware); + firmware->addOption("autoupdate", Firmware::tr("Support for auto update on boot")); registerOpenTxFirmware(firmware); /* FrSky X12 (Horus) board */ @@ -1283,6 +1298,13 @@ void registerOpenTxFirmwares() addOpenTxFontOptions(firmware); registerOpenTxFirmware(firmware); + /* Jumper T16 board */ + firmware = new OpenTxFirmware("opentx-t16", Firmware::tr("Jumper T16 / T16+"), BOARD_JUMPER_T16); + addOpenTxFrskyOptions(firmware); + firmware->addOption("internalmulti", Firmware::tr("Support for MULTI internal module")); + firmware->addOption("bluetooth", Firmware::tr("Support for bluetooth module")); + registerOpenTxFirmware(firmware); + /* 9XR-Pro */ firmware = new OpenTxFirmware("opentx-9xrpro", Firmware::tr("Turnigy 9XR-PRO"), BOARD_9XRPRO); addOpenTxArm9xOptions(firmware, false); diff --git a/companion/src/firmwares/rawswitch.cpp b/companion/src/firmwares/rawswitch.cpp index 6438d335e..1d91f242a 100644 --- a/companion/src/firmwares/rawswitch.cpp +++ b/companion/src/firmwares/rawswitch.cpp @@ -115,6 +115,9 @@ QString RawSwitch::toString(Board::Type board, const GeneralSettings * const gen case SWITCH_TYPE_ONE: return tr("One"); + case SWITCH_TYPE_ACT: + return tr("Act"); + case SWITCH_TYPE_FLIGHT_MODE: if (modelData) return modelData->flightModeData[index-1].nameToString(index - 1); diff --git a/companion/src/firmwares/rawswitch.h b/companion/src/firmwares/rawswitch.h index 6d0c93700..af49156c0 100644 --- a/companion/src/firmwares/rawswitch.h +++ b/companion/src/firmwares/rawswitch.h @@ -45,6 +45,7 @@ enum RawSwitchType { SWITCH_TYPE_TIMER_MODE, SWITCH_TYPE_TELEMETRY, SWITCH_TYPE_SENSOR, + SWITCH_TYPE_ACT, MAX_SWITCH_TYPE }; diff --git a/companion/src/firmwares/sensordata.cpp b/companion/src/firmwares/sensordata.cpp index a88f3239a..8d677ed50 100644 --- a/companion/src/firmwares/sensordata.cpp +++ b/companion/src/firmwares/sensordata.cpp @@ -92,24 +92,16 @@ QString SensorData::nameToString(int index) const return RadioData::getElementName(tr("TELE"), index + 1, label); } -QString SensorData::getRxOrModName(const ModelData* model) const +QString SensorData::getOrigin(const ModelData * model) const { - if ((type != TELEM_TYPE_CUSTOM) || (!id && !instance)) + if (type != TELEM_TYPE_CUSTOM || !id) return QString(); - const ModuleData& module = model->moduleData[moduleIdx]; - - if (module.isPxx2Module()) { - if (module.access.receivers & (1 << rxIdx)) { - return QString(module.access.receiverName[rxIdx]); - } - - // receiver does not seem to be active + const ModuleData & module = model->moduleData[moduleIdx]; + if (module.isPxx2Module() && rxIdx <= 2 && module.access.receivers & (1 << rxIdx)) { + return QString(module.access.receiverName[rxIdx]); + } + else { return QString(); } - - if (moduleIdx) - return tr("Internal"); - - return tr("External"); } diff --git a/companion/src/firmwares/sensordata.h b/companion/src/firmwares/sensordata.h index 8e95aa7f6..a5cdb4957 100644 --- a/companion/src/firmwares/sensordata.h +++ b/companion/src/firmwares/sensordata.h @@ -148,7 +148,7 @@ class SensorData { void updateUnit(); QString unitString() const; QString nameToString(int index) const; - QString getRxOrModName(const ModelData* model) const; + QString getOrigin(const ModelData* model) const; void clear() { memset(this, 0, sizeof(SensorData)); } }; diff --git a/companion/src/generaledit/hardware.cpp b/companion/src/generaledit/hardware.cpp index 09f109bda..8868e7766 100644 --- a/companion/src/generaledit/hardware.cpp +++ b/companion/src/generaledit/hardware.cpp @@ -200,6 +200,15 @@ HardwarePanel::HardwarePanel(QWidget * parent, GeneralSettings & generalSettings } else { ui->filterEnable->hide(); + ui->filterLabel->hide(); + } + + if (IS_STM32(board)) { + ui->rtcCheckDisable->setChecked(!generalSettings.rtcCheckDisable); + } + else { + ui->rtcCheckDisable->hide(); + ui->rtcCheckLabel->hide(); } disableMouseScrolling(); @@ -217,6 +226,11 @@ void HardwarePanel::on_filterEnable_stateChanged() generalSettings.jitterFilter = !ui->filterEnable->isChecked(); } +void HardwarePanel::on_rtcCheckDisable_stateChanged() +{ + generalSettings.rtcCheckDisable = !ui->rtcCheckDisable->isChecked(); +} + void HardwarePanel::on_PPM_MultiplierDSB_editingFinished() { int val = (int)(ui->PPM_MultiplierDSB->value()*10)-10; diff --git a/companion/src/generaledit/hardware.h b/companion/src/generaledit/hardware.h index 07ba62c40..8101b784c 100644 --- a/companion/src/generaledit/hardware.h +++ b/companion/src/generaledit/hardware.h @@ -49,6 +49,7 @@ class HardwarePanel : public GeneralPanel void on_txCurrentCalibration_editingFinished(); void on_txVoltageCalibration_editingFinished(); void on_filterEnable_stateChanged(); + void on_rtcCheckDisable_stateChanged(); void on_serialPortMode_currentIndexChanged(int index); diff --git a/companion/src/generaledit/hardware.ui b/companion/src/generaledit/hardware.ui index 79bb36a32..45e8e8da6 100644 --- a/companion/src/generaledit/hardware.ui +++ b/companion/src/generaledit/hardware.ui @@ -7,7 +7,7 @@ 0 0 470 - 1585 + 1618 @@ -57,7 +57,7 @@ - + @@ -169,7 +169,7 @@ - + -49 @@ -192,27 +192,7 @@ - - - - RS2 - - - - - - - - 0 - 10 - - - - Qt::Horizontal - - - - + @@ -231,6 +211,26 @@ + + + + + 0 + 10 + + + + Qt::Horizontal + + + + + + + RS2 + + + @@ -267,7 +267,7 @@ - + Current Offset @@ -284,7 +284,7 @@ - + PPM 2 @@ -312,6 +312,9 @@ + + + @@ -322,6 +325,19 @@ + + + + + + + + + + + + + @@ -342,17 +358,14 @@ - - + + - - - @@ -375,16 +388,6 @@ - - - - - - - - - - @@ -434,6 +437,16 @@ + + + + + + + + + + @@ -447,23 +460,6 @@ - - - - 3 - - - - - - - - - - - - - @@ -471,6 +467,13 @@ + + + + 3 + + + @@ -512,7 +515,7 @@ - + 1 @@ -545,6 +548,19 @@ + + + + + + + + + + + + + @@ -562,19 +578,6 @@ - - - - - - - - - - - - - @@ -589,9 +592,6 @@ - - - @@ -599,6 +599,13 @@ + + + + SI + + + @@ -613,10 +620,10 @@ - - + + - SI + SL @@ -627,13 +634,6 @@ - - - - SL - - - @@ -688,7 +688,7 @@ - + @@ -707,7 +707,7 @@ - + PPM 1 @@ -727,14 +727,14 @@ - + PPM 4 - + @@ -766,6 +766,20 @@ + + + + SB + + + + + + + 3 + + + @@ -788,21 +802,7 @@ - - - - SB - - - - - - - 3 - - - - + PPM Multiplier @@ -903,16 +903,6 @@ - - - - Antenna - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - @@ -933,7 +923,17 @@ - + + + + Antenna + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + PPM 3 @@ -1029,6 +1029,26 @@ + + + + 3 + + + + + + + + + + + + + + + + @@ -1058,26 +1078,6 @@ - - - - 3 - - - - - - - - - - - - - - - - @@ -1113,6 +1113,20 @@ + + + + + + + + + + + RTC Batt Check + + + diff --git a/companion/src/helpers.cpp b/companion/src/helpers.cpp index 8ecf55f12..eb594b9b6 100644 --- a/companion/src/helpers.cpp +++ b/companion/src/helpers.cpp @@ -435,6 +435,23 @@ static bool caseInsensitiveLessThan(const QString &s1, const QString &s2) return s1.toLower() < s2.toLower(); } +bool displayT16ImportWarning() +{ + QMessageBox msgBox; + msgBox.setWindowTitle(QObject::tr("WARNING")); + msgBox.setText(QObject::tr("

Importing JumperTX data into OpenTX 2.3 is not supported and dangerous.

\ +

It is unfortunately not possible for us to differentiate JumperTX data from legitimate FrSky X10 data, but You should only continue here if the file you opened comes from a real FrSky X10.

\ +

Do you really want to continue?

")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.addButton(QMessageBox::No); + msgBox.addButton(QMessageBox::Yes); + msgBox.setDefaultButton(QMessageBox::No); + + if (msgBox.exec() == QMessageBox::No) + return false; + return true; +} + void Helpers::populateFileComboBox(QComboBox * b, const QSet & set, const QString & current) { b->clear(); diff --git a/companion/src/helpers.h b/companion/src/helpers.h index 0ce75e7fb..8a7399c56 100644 --- a/companion/src/helpers.h +++ b/companion/src/helpers.h @@ -52,6 +52,8 @@ extern const QColor colors[CPN_MAX_CURVES]; #define TRIM_MODE_NONE 0x1F // 0b11111 +bool displayT16ImportWarning(); + class CompanionIcon: public QIcon { public: CompanionIcon(const QString &baseimage); diff --git a/companion/src/images/simulator/JumperT16/JumperT16.svg b/companion/src/images/simulator/JumperT16/JumperT16.svg new file mode 100644 index 000000000..649a506c4 --- /dev/null +++ b/companion/src/images/simulator/JumperT16/JumperT16.svg @@ -0,0 +1,2594 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + Activated button= black/opacity 40% + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SYS + SYS + RTN + RTN + MDL + MDL + PAGE + PAGE + TELE + TELE + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/companion/src/images/simulator/JumperT16/bottom.png b/companion/src/images/simulator/JumperT16/bottom.png new file mode 100644 index 000000000..8f0d29f7e Binary files /dev/null and b/companion/src/images/simulator/JumperT16/bottom.png differ diff --git a/companion/src/images/simulator/JumperT16/left.png b/companion/src/images/simulator/JumperT16/left.png new file mode 100644 index 000000000..ed8f9e27f Binary files /dev/null and b/companion/src/images/simulator/JumperT16/left.png differ diff --git a/companion/src/images/simulator/JumperT16/left_mdl.png b/companion/src/images/simulator/JumperT16/left_mdl.png new file mode 100644 index 000000000..62f64d6f7 Binary files /dev/null and b/companion/src/images/simulator/JumperT16/left_mdl.png differ diff --git a/companion/src/images/simulator/JumperT16/left_page.png b/companion/src/images/simulator/JumperT16/left_page.png new file mode 100644 index 000000000..d135a3307 Binary files /dev/null and b/companion/src/images/simulator/JumperT16/left_page.png differ diff --git a/companion/src/images/simulator/JumperT16/left_scrnsht.png b/companion/src/images/simulator/JumperT16/left_scrnsht.png new file mode 100644 index 000000000..899f0a9c4 Binary files /dev/null and b/companion/src/images/simulator/JumperT16/left_scrnsht.png differ diff --git a/companion/src/images/simulator/JumperT16/left_sys.png b/companion/src/images/simulator/JumperT16/left_sys.png new file mode 100644 index 000000000..beed21ee5 Binary files /dev/null and b/companion/src/images/simulator/JumperT16/left_sys.png differ diff --git a/companion/src/images/simulator/JumperT16/left_tele.png b/companion/src/images/simulator/JumperT16/left_tele.png new file mode 100644 index 000000000..029506325 Binary files /dev/null and b/companion/src/images/simulator/JumperT16/left_tele.png differ diff --git a/companion/src/images/simulator/JumperT16/right.png b/companion/src/images/simulator/JumperT16/right.png new file mode 100644 index 000000000..290803879 Binary files /dev/null and b/companion/src/images/simulator/JumperT16/right.png differ diff --git a/companion/src/images/simulator/JumperT16/right_ent.png b/companion/src/images/simulator/JumperT16/right_ent.png new file mode 100644 index 000000000..8f4fdc769 Binary files /dev/null and b/companion/src/images/simulator/JumperT16/right_ent.png differ diff --git a/companion/src/images/simulator/JumperT16/right_rtn.png b/companion/src/images/simulator/JumperT16/right_rtn.png new file mode 100644 index 000000000..00114f2a7 Binary files /dev/null and b/companion/src/images/simulator/JumperT16/right_rtn.png differ diff --git a/companion/src/images/simulator/JumperT16/top.png b/companion/src/images/simulator/JumperT16/top.png new file mode 100644 index 000000000..3bc1784ee Binary files /dev/null and b/companion/src/images/simulator/JumperT16/top.png differ diff --git a/companion/src/images/simulator/X9D2019/Readme.md b/companion/src/images/simulator/X9D2019/Readme.md new file mode 100644 index 000000000..75a11a3ad --- /dev/null +++ b/companion/src/images/simulator/X9D2019/Readme.md @@ -0,0 +1,28 @@ + +# "Taranis X9D+ 2019" dark blue skin for the Companion simulator +![X9D+ 2019 Image for Companion](X9DP2019_Companion_image.png "Taranis X9D+ 2019") + +## The different parts of the image + +The image is divided into 4 pieces: top, bottom, left and right. +For the images concerned, there is the version with the activated element and the version without the activated element (such as a button, a rotary encoder, clicking on the rotary encoder). + +| File name | What is this image ? | +|:---------------------|:----------------------------------------------| +| `bottom.png` | central lower band | +| `center_LCD.png` | central LCD 424x128px (useless for simulator) | +| `left.png` | left part with inactive elements | +| `left_exit.png` | left part with the EXIT button activated | +| `left_menu.png` | left part with the MENU button activated | +| `left_page.png` | left part with the PAGE button activated | +| `bottom_scrnshot.png`| central lower band with the SCREENSHOT button activated| +| `right_ent.png` | right part with the ENTER button activated | +| `right.png` | right part with inactive elements | +| `top.png` | central upper band | + +`X9DP2019_Companion_image.png` is the image displayed here. + + +## Software used : +- **Inkscape** : vector drawing software (http://www.inkscape.org/) +- **Gimp** : image editor (http://www.gimp.org/) \ No newline at end of file diff --git a/companion/src/images/simulator/X9D2019/X9DP2019_Companion_image.png b/companion/src/images/simulator/X9D2019/X9DP2019_Companion_image.png new file mode 100644 index 000000000..9f28d54a8 Binary files /dev/null and b/companion/src/images/simulator/X9D2019/X9DP2019_Companion_image.png differ diff --git a/companion/src/images/simulator/X9D2019/bottom.png b/companion/src/images/simulator/X9D2019/bottom.png new file mode 100644 index 000000000..bc812ddb0 Binary files /dev/null and b/companion/src/images/simulator/X9D2019/bottom.png differ diff --git a/companion/src/images/simulator/X9D2019/bottom_scrnshot.png b/companion/src/images/simulator/X9D2019/bottom_scrnshot.png new file mode 100644 index 000000000..b46eaa9ec Binary files /dev/null and b/companion/src/images/simulator/X9D2019/bottom_scrnshot.png differ diff --git a/companion/src/images/simulator/X9D2019/center_LCD.png b/companion/src/images/simulator/X9D2019/center_LCD.png new file mode 100644 index 000000000..3bc62efd0 Binary files /dev/null and b/companion/src/images/simulator/X9D2019/center_LCD.png differ diff --git a/companion/src/images/simulator/X9D2019/left.png b/companion/src/images/simulator/X9D2019/left.png new file mode 100644 index 000000000..113cd1611 Binary files /dev/null and b/companion/src/images/simulator/X9D2019/left.png differ diff --git a/companion/src/images/simulator/X9D2019/left_exit.png b/companion/src/images/simulator/X9D2019/left_exit.png new file mode 100644 index 000000000..4b6376c0f Binary files /dev/null and b/companion/src/images/simulator/X9D2019/left_exit.png differ diff --git a/companion/src/images/simulator/X9D2019/left_menu.png b/companion/src/images/simulator/X9D2019/left_menu.png new file mode 100644 index 000000000..9e2a74ecc Binary files /dev/null and b/companion/src/images/simulator/X9D2019/left_menu.png differ diff --git a/companion/src/images/simulator/X9D2019/left_page.png b/companion/src/images/simulator/X9D2019/left_page.png new file mode 100644 index 000000000..4ad08533f Binary files /dev/null and b/companion/src/images/simulator/X9D2019/left_page.png differ diff --git a/companion/src/images/simulator/X9D2019/right.png b/companion/src/images/simulator/X9D2019/right.png new file mode 100644 index 000000000..a16456573 Binary files /dev/null and b/companion/src/images/simulator/X9D2019/right.png differ diff --git a/companion/src/images/simulator/X9D2019/right_enter.png b/companion/src/images/simulator/X9D2019/right_enter.png new file mode 100644 index 000000000..8f9c5f1cb Binary files /dev/null and b/companion/src/images/simulator/X9D2019/right_enter.png differ diff --git a/companion/src/images/simulator/X9D2019/top.png b/companion/src/images/simulator/X9D2019/top.png new file mode 100644 index 000000000..083fd6e3c Binary files /dev/null and b/companion/src/images/simulator/X9D2019/top.png differ diff --git a/companion/src/images/simulator/X9LITE/Readme.md b/companion/src/images/simulator/X9LITE/Readme.md new file mode 100644 index 000000000..46b4f4f4b --- /dev/null +++ b/companion/src/images/simulator/X9LITE/Readme.md @@ -0,0 +1,29 @@ + +# X9-Lite skin for the Companion simulator +![X9-Lite Image for Companion](X9-Lite_Companion_image.png "X9-Lite") + +## The different parts of the image + +The image is divided into 4 pieces: top, bottom, left and right. +For the images concerned, there is the version with the activated element and the version without the activated element (such as a button, a rotary encoder, clicking on the rotary encoder). + +| File name | What is this image ? | +|:---------------------|:----------------------------------------------| +| `bottom.png` | central lower band | +| `center_LCD.png` | central LCD 256x128px (useless for simulator) | +| `left.png` | left part with inactive elements | +| `left_exit.png` | left part with the EXIT button activated | +| `left_menu.png` | left part with the MENU button activated | +| `left_page.png` | left part with the PAGE button activated | +| `left_scrnshot.png `| left part with the SCREENSHOT button activated| +| `right_ent.png` | right part with the ENT button activated | +| `right_rotcoder.png` | right part with the Rotary Encoder actuated | +| `right.png` | right part with inactive elements | +| `top.png` | central upper band | +`X9-Lite_Companion_image.png` is the image displayed here. + +When turning the rotary encoder, it is possible to make a motion effect by displaying `right_rotcoder.png` and `right.png`. + +## Software used : +- **Inkscape** : vector drawing software (http://www.inkscape.org/) +- **Gimp** : image editor (http://www.gimp.org/) \ No newline at end of file diff --git a/companion/src/images/simulator/X9LITE/X9-Lite_Companion_image.png b/companion/src/images/simulator/X9LITE/X9-Lite_Companion_image.png new file mode 100644 index 000000000..d206c83e1 Binary files /dev/null and b/companion/src/images/simulator/X9LITE/X9-Lite_Companion_image.png differ diff --git a/companion/src/images/simulator/X9LITE/bottom.png b/companion/src/images/simulator/X9LITE/bottom.png index 3f709a449..43f26ab49 100644 Binary files a/companion/src/images/simulator/X9LITE/bottom.png and b/companion/src/images/simulator/X9LITE/bottom.png differ diff --git a/companion/src/images/simulator/X9LITE/center_LCD.png b/companion/src/images/simulator/X9LITE/center_LCD.png new file mode 100644 index 000000000..f3249de16 Binary files /dev/null and b/companion/src/images/simulator/X9LITE/center_LCD.png differ diff --git a/companion/src/images/simulator/X9LITE/left.png b/companion/src/images/simulator/X9LITE/left.png index 4d3376c48..5d784b68c 100644 Binary files a/companion/src/images/simulator/X9LITE/left.png and b/companion/src/images/simulator/X9LITE/left.png differ diff --git a/companion/src/images/simulator/X9LITE/left_exit.png b/companion/src/images/simulator/X9LITE/left_exit.png index 0d7cd5b5b..16a7dfda9 100644 Binary files a/companion/src/images/simulator/X9LITE/left_exit.png and b/companion/src/images/simulator/X9LITE/left_exit.png differ diff --git a/companion/src/images/simulator/X9LITE/left_menu.png b/companion/src/images/simulator/X9LITE/left_menu.png index b97ba1da4..db1cbd768 100644 Binary files a/companion/src/images/simulator/X9LITE/left_menu.png and b/companion/src/images/simulator/X9LITE/left_menu.png differ diff --git a/companion/src/images/simulator/X9LITE/left_page.png b/companion/src/images/simulator/X9LITE/left_page.png index 9fd9d5b8e..bf5b3ce36 100644 Binary files a/companion/src/images/simulator/X9LITE/left_page.png and b/companion/src/images/simulator/X9LITE/left_page.png differ diff --git a/companion/src/images/simulator/X9LITE/left_scrnshot.png b/companion/src/images/simulator/X9LITE/left_scrnshot.png index c01e802de..afd46507e 100644 Binary files a/companion/src/images/simulator/X9LITE/left_scrnshot.png and b/companion/src/images/simulator/X9LITE/left_scrnshot.png differ diff --git a/companion/src/images/simulator/X9LITE/right.png b/companion/src/images/simulator/X9LITE/right.png index 73a2a1e30..fcb8efd75 100644 Binary files a/companion/src/images/simulator/X9LITE/right.png and b/companion/src/images/simulator/X9LITE/right.png differ diff --git a/companion/src/images/simulator/X9LITE/right_ent.png b/companion/src/images/simulator/X9LITE/right_ent.png index 3292fb0e5..1640129f8 100644 Binary files a/companion/src/images/simulator/X9LITE/right_ent.png and b/companion/src/images/simulator/X9LITE/right_ent.png differ diff --git a/companion/src/images/simulator/X9LITE/right_rotary_encoder.png b/companion/src/images/simulator/X9LITE/right_rotary_encoder.png new file mode 100644 index 000000000..3d9f7cf82 Binary files /dev/null and b/companion/src/images/simulator/X9LITE/right_rotary_encoder.png differ diff --git a/companion/src/images/simulator/X9LITE/top.png b/companion/src/images/simulator/X9LITE/top.png index 427ee0911..bd15db2b7 100644 Binary files a/companion/src/images/simulator/X9LITE/top.png and b/companion/src/images/simulator/X9LITE/top.png differ diff --git a/companion/src/mdichild.cpp b/companion/src/mdichild.cpp index 4d0d7dcb8..358f85817 100644 --- a/companion/src/mdichild.cpp +++ b/companion/src/mdichild.cpp @@ -1457,6 +1457,12 @@ bool MdiChild::convertStorage(Board::Type from, Board::Type to, bool newFile) { QMessageBox::StandardButtons btns; QMessageBox::StandardButton dfltBtn; + + if (from == Board::BOARD_X10 && to == Board::BOARD_JUMPER_T16) { + if (displayT16ImportWarning() == false) + return false; + } + QString q = tr("

Currently selected radio type (%1) is not compatible with file %3 (from %2), models and settings need to be converted.

").arg(Boards::getBoardName(to)).arg(Boards::getBoardName(from)).arg(userFriendlyCurrentFile()); if (newFile) { q.append(tr("Do you wish to continue with the conversion?")); diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index 552b31038..dfcc1809e 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -688,7 +688,7 @@ void CustomFunctionsPanel::populateFuncCB(QComboBox *b, unsigned int value) ((i==FuncLogs) && !firmware->getCapability(HasSDLogs)) || ((i==FuncSetTimer1 || i==FuncSetTimer2) && !IS_ARM(firmware->getBoard())) || ((i==FuncSetTimer3) && firmware->getCapability(Timers) < 3) || - ((i==FuncScreenshot) && !IS_TARANIS(firmware->getBoard())) || + ((i==FuncScreenshot) && !IS_HORUS_OR_TARANIS(firmware->getBoard())) || ((i>=FuncRangeCheckInternalModule && i<=FuncBindExternalModule) && (!model || !firmware->getCapability(DangerousFunctions))) || ((i>=FuncAdjustGV1 && i<=FuncAdjustGVLast) && (!model || !firmware->getCapability(Gvars))) ) { diff --git a/companion/src/modeledit/setup.cpp b/companion/src/modeledit/setup.cpp index 4b12115fe..271dcd8b6 100644 --- a/companion/src/modeledit/setup.cpp +++ b/companion/src/modeledit/setup.cpp @@ -217,15 +217,14 @@ ModulePanel::ModulePanel(QWidget * parent, ModelData & model, ModuleData & modul // The protocols available on this board for (unsigned int i=0; iisAvailable((PulsesProtocol) i, moduleIdx)) { - if (IS_TARANIS_XLITE(firmware->getBoard()) && i == PULSES_PXX_R9M) //TODO remove when mini are handled as a different module type - ui->protocol->addItem("FrSky R9M Mini", (QVariant) i); - else - ui->protocol->addItem(ModuleData::protocolToString(i), i); + ui->protocol->addItem(ModuleData::protocolToString(i), i); if (i == module.protocol) ui->protocol->setCurrentIndex(ui->protocol->count()-1); } } for (int i=0; i<=MODULE_SUBTYPE_MULTI_LAST; i++) { + if (i == MODULE_SUBTYPE_MULTI_SCANNER) + continue; ui->multiProtocol->addItem(Multiprotocols::protocolToString(i), i); } @@ -299,8 +298,10 @@ void ModulePanel::setupFailsafes() } } - if (!hasFailsafe) + if (!hasFailsafe) { + lock = false; return; + } int row = 0; int col = 0; @@ -365,6 +366,48 @@ void ModulePanel::setupFailsafes() lock = false; } +int ModulePanel::getMaxChannelCount() +{ + const PulsesProtocol protocol = (PulsesProtocol)module.protocol; + switch (protocol) { + case PULSES_ACCESS_ISRM: + return 24; + case PULSES_PXX_R9M: + case PULSES_ACCESS_R9M: + case PULSES_ACCESS_R9M_LITE: + case PULSES_ACCESS_R9M_LITE_PRO: + case PULSES_ACCST_ISRM_D16: + case PULSES_XJT_LITE_X16: + case PULSES_PXX_XJT_X16: + case PULSES_CROSSFIRE: + case PULSES_SBUS: + return 16; + case PULSES_XJT_LITE_LR12: + case PULSES_PXX_XJT_LR12: + return 12; + case PULSES_PXX_DJT: + case PULSES_XJT_LITE_D8: + case PULSES_PXX_XJT_D8: + case PULSES_PPM: + return 8; + case PULSES_LP45: + case PULSES_DSM2: + case PULSES_DSMX: + return 6; + case PULSES_MULTIMODULE: + if (module.multi.rfProtocol == MODULE_SUBTYPE_MULTI_DSM2) + return 12; + else + return 16; + break; + case PULSES_OFF: + break; + default: + break; + } + return 8; +} + void ModulePanel::update() { const PulsesProtocol protocol = (PulsesProtocol)module.protocol; @@ -463,10 +506,12 @@ void ModulePanel::update() ui->rxNumber->setValue(module.modelId); ui->label_channelsStart->setVisible(mask & MASK_CHANNELS_RANGE); ui->channelsStart->setVisible(mask & MASK_CHANNELS_RANGE); + ui->channelsStart->setMaximum(33 - module.channelsCount); ui->channelsStart->setValue(module.channelsStart+1); ui->label_channelsCount->setVisible(mask & MASK_CHANNELS_RANGE); ui->channelsCount->setVisible(mask & MASK_CHANNELS_RANGE); ui->channelsCount->setEnabled(mask & MASK_CHANNELS_COUNT); + ui->channelsCount->setMaximum(getMaxChannelCount()); ui->channelsCount->setValue(module.channelsCount); ui->channelsCount->setSingleStep(firmware->getCapability(HasPPMStart) ? 1 : 2); @@ -482,7 +527,7 @@ void ModulePanel::update() ui->ppmDelay->setValue(module.ppm.delay); ui->label_ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS); ui->ppmFrameLength->setVisible(mask & MASK_SBUSPPM_FIELDS); - ui->ppmFrameLength->setMinimum(module.channelsCount*(model->extendedLimits ? 2.250 : 2)+3.5); + ui->ppmFrameLength->setMinimum(module.channelsCount * (model->extendedLimits ? 2.250 : 2)+3.5); ui->ppmFrameLength->setMaximum(firmware->getCapability(PPMFrameLength)); ui->ppmFrameLength->setValue(22.5+((double)module.ppm.frameLength)*0.5); @@ -546,7 +591,7 @@ void ModulePanel::update() ui->lowPower->setVisible(mask & MASK_MULTIMODULE); if (mask & MASK_MULTIMODULE) { - ui->multiProtocol->setCurrentIndex(module.multi.rfProtocol); + ui->multiProtocol->setCurrentIndex(ui->multiProtocol->findData(module.multi.rfProtocol)); ui->autoBind->setChecked(module.multi.autoBindMode); ui->lowPower->setChecked(module.multi.lowPowerMode); } @@ -611,11 +656,6 @@ void ModulePanel::update() } } } - - if (mask & MASK_CHANNELS_RANGE) { - ui->channelsStart->setMaximum(33 - ui->channelsCount->value()); - ui->channelsCount->setMaximum(qMin(24, 33-ui->channelsStart->value())); - } } void ModulePanel::on_trainerMode_currentIndexChanged(int index) @@ -631,6 +671,7 @@ void ModulePanel::onProtocolChanged(int index) { if (!lock && module.protocol != ui->protocol->itemData(index).toUInt()) { module.protocol = ui->protocol->itemData(index).toInt(); + module.channelsCount = getMaxChannelCount(); update(); emit modified(); } @@ -717,13 +758,15 @@ void ModulePanel::on_failsafeMode_currentIndexChanged(int value) void ModulePanel::onMultiProtocolChanged(int index) { - if (!lock && module.multi.rfProtocol != (unsigned)index) { + int rfProtocol = ui->multiProtocol->itemData(index).toInt(); + if (!lock && module.multi.rfProtocol != (unsigned)rfProtocol) { lock=true; - module.multi.rfProtocol = (unsigned int) index; + module.multi.rfProtocol = (unsigned int)rfProtocol; unsigned int maxSubTypes = multiProtocols.getProtocol(index).numSubTypes(); if (module.multi.customProto) maxSubTypes=8; module.subType = std::min(module.subType, maxSubTypes -1); + module.channelsCount = getMaxChannelCount(); update(); emit modified(); lock = false; diff --git a/companion/src/modeledit/setup.h b/companion/src/modeledit/setup.h index fc1a57cf7..3edb1efd8 100644 --- a/companion/src/modeledit/setup.h +++ b/companion/src/modeledit/setup.h @@ -71,6 +71,7 @@ class ModulePanel : public ModelPanel void channelsRangeChanged(); private slots: + int getMaxChannelCount(); void setupFailsafes(); void on_trainerMode_currentIndexChanged(int index); void onProtocolChanged(int index); diff --git a/companion/src/modeledit/telemetry.cpp b/companion/src/modeledit/telemetry.cpp index 39a314fa7..68be10638 100644 --- a/companion/src/modeledit/telemetry.cpp +++ b/companion/src/modeledit/telemetry.cpp @@ -653,9 +653,8 @@ void TelemetrySensorPanel::update() ui->id->hide(); ui->instanceLabel->hide(); ui->instance->hide(); - ui->rxLabel->hide(); - ui->moduleLabel->hide(); - ui->rxOrMod->hide(); + ui->originLabel->hide(); + ui->origin->hide(); ui->formula->show(); ui->formula->setCurrentIndex(sensor.formula); isConfigurable = (sensor.formula < SensorData::TELEM_FORMULA_CELL); @@ -679,13 +678,10 @@ void TelemetrySensorPanel::update() ui->id->show(); ui->instanceLabel->show(); ui->instance->show(); - - bool is_pxx2 = model->moduleData[sensor.moduleIdx].isPxx2Module(); - ui->rxLabel->setVisible(is_pxx2); - ui->moduleLabel->setVisible(!is_pxx2); - - ui->rxOrMod->setText(sensor.getRxOrModName(model)); - ui->rxOrMod->show(); + QString origin = sensor.getOrigin(model); + ui->originLabel->setVisible(!origin.isEmpty()); + ui->origin->setVisible(!origin.isEmpty()); + ui->origin->setText(origin); ui->formula->hide(); isConfigurable = sensor.unit < SensorData::UNIT_FIRST_VIRTUAL; @@ -755,7 +751,7 @@ void populateTelemetrySourcesComboBox(AutoComboBox * cb, const ModelData * model const SensorData& sensor = model->sensorData[-i-1]; if (sensor.isAvailable()) { if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) - cb->addItem(QString("-%1 (%2)").arg(sensor.label, sensor.getRxOrModName(model)), i); + cb->addItem(QString("-%1 (%2)").arg(sensor.label, sensor.getOrigin(model)), i); else cb->addItem(QString("-%1").arg(sensor.label), i); } @@ -766,7 +762,7 @@ void populateTelemetrySourcesComboBox(AutoComboBox * cb, const ModelData * model const SensorData& sensor = model->sensorData[i-1]; if (sensor.isAvailable()) { if (sensor.type == SensorData::TELEM_TYPE_CUSTOM) - cb->addItem(QString("%1 (%2)").arg(sensor.label, sensor.getRxOrModName(model)), i); + cb->addItem(QString("%1 (%2)").arg(sensor.label, sensor.getOrigin(model)), i); else cb->addItem(QString("%1").arg(sensor.label), i); } diff --git a/companion/src/modeledit/telemetry_sensor.ui b/companion/src/modeledit/telemetry_sensor.ui index f6007f6d6..7d08243e0 100644 --- a/companion/src/modeledit/telemetry_sensor.ui +++ b/companion/src/modeledit/telemetry_sensor.ui @@ -13,7 +13,7 @@ Form - + 0 @@ -121,21 +121,14 @@
- + Rx - - - Mod. - - - - - + 0 diff --git a/companion/src/modelslist.cpp b/companion/src/modelslist.cpp index b106a2896..2fb5cc329 100644 --- a/companion/src/modelslist.cpp +++ b/companion/src/modelslist.cpp @@ -727,7 +727,7 @@ void TreeModel::refresh() protocol = moduleData.protocol; // These are the only RXs that allow nominating RX # but changing RX or copying models can leave residual configuration which can cause issues // if (protocol == PULSES_PXX_XJT_X16 || protocol == PULSES_PXX_XJT_LR12 || protocol == PULSES_PXX_R9M || protocol == PULSES_DSMX || protocol == PULSES_MULTIMODULE) { - if (protocol != PULSES_OFF && moduleData.modelId > 0) { + if (moduleData.supportRxNum() && moduleData.modelId > 0) { if (!rxs.isEmpty()) { rxs.append(", "); } @@ -751,6 +751,9 @@ void TreeModel::refresh() bool TreeModel::isModelIdUnique(unsigned modelIdx, unsigned module, unsigned protocol) { int cnt = 0; + if (protocol== PULSES_PXX_XJT_D8) + return true; + for (auto const& model: radioData->models) { if (!model.isEmpty()) { const ModuleData& moduleData = model.moduleData[module]; diff --git a/companion/src/radiointerface.cpp b/companion/src/radiointerface.cpp index d83f40c5c..63befdd0c 100644 --- a/companion/src/radiointerface.cpp +++ b/companion/src/radiointerface.cpp @@ -333,6 +333,11 @@ bool readEeprom(const QString & filename, ProgressWidget * progress) QMessageBox::critical(progress, CPN_STR_TTL_ERROR, outputStorage.error()); return false; } + + if (getCurrentBoard() == Board::BOARD_JUMPER_T16 && inputStorage.getBoard() == Board::BOARD_X10) { + if (displayT16ImportWarning() == false) + return false; + } } else { if (IS_ARM(board)) { diff --git a/companion/src/simulation/CMakeLists.txt b/companion/src/simulation/CMakeLists.txt index 5245d48a4..0142241b2 100644 --- a/companion/src/simulation/CMakeLists.txt +++ b/companion/src/simulation/CMakeLists.txt @@ -9,9 +9,11 @@ set(simulation_SRCS simulateduiwidgetX9.cpp simulateduiwidgetXLITE.cpp simulateduiwidgetX9E.cpp + simulateduiwidgetX9D2019.cpp simulateduiwidgetX10.cpp simulateduiwidgetX12.cpp simulateduiwidgetJumperT12.cpp + simulateduiwidgetJumperT16.cpp simulatorinterface.cpp simulatormainwindow.cpp simulatorstartupdialog.cpp @@ -31,9 +33,11 @@ set(simulation_UIS simulateduiwidgetX9.ui simulateduiwidgetXLITE.ui simulateduiwidgetX9E.ui + simulateduiwidgetX9D2019.ui simulateduiwidgetX10.ui simulateduiwidgetX12.ui simulateduiwidgetJumperT12.ui + simulateduiwidgetJumperT16.ui simulatormainwindow.ui simulatorstartupdialog.ui simulatorwidget.ui diff --git a/companion/src/simulation/simulateduiwidget.h b/companion/src/simulation/simulateduiwidget.h index 94ad0e966..d688c641a 100644 --- a/companion/src/simulation/simulateduiwidget.h +++ b/companion/src/simulation/simulateduiwidget.h @@ -108,9 +108,11 @@ namespace Ui { class SimulatedUIWidgetX9; class SimulatedUIWidgetXLITE; class SimulatedUIWidgetX9E; + class SimulatedUIWidgetX9D2019; class SimulatedUIWidgetX10; class SimulatedUIWidgetX12; class SimulatedUIWidgetJumperT12; + class SimulatedUIWidgetJumperT16; } class SimulatedUIWidget9X: public SimulatedUIWidget @@ -189,6 +191,18 @@ class SimulatedUIWidgetX9E: public SimulatedUIWidget Ui::SimulatedUIWidgetX9E * ui; }; +class SimulatedUIWidgetX9D2019: public SimulatedUIWidget +{ + Q_OBJECT + + public: + explicit SimulatedUIWidgetX9D2019(SimulatorInterface * simulator, QWidget * parent = nullptr); + virtual ~SimulatedUIWidgetX9D2019(); + + private: + Ui::SimulatedUIWidgetX9D2019 * ui; +}; + class SimulatedUIWidgetX10: public SimulatedUIWidget { Q_OBJECT @@ -225,4 +239,17 @@ class SimulatedUIWidgetJumperT12: public SimulatedUIWidget Ui::SimulatedUIWidgetJumperT12 * ui; }; +class SimulatedUIWidgetJumperT16: public SimulatedUIWidget +{ + Q_OBJECT + + public: + explicit SimulatedUIWidgetJumperT16(SimulatorInterface * simulator, QWidget * parent = nullptr); + virtual ~SimulatedUIWidgetJumperT16(); + + private: + Ui::SimulatedUIWidgetJumperT16 * ui; +}; + + #endif // SIMULATEDUIWIDGET_H diff --git a/companion/src/simulation/simulateduiwidgetJumperT12.cpp b/companion/src/simulation/simulateduiwidgetJumperT12.cpp index e69f433d3..067108e69 100644 --- a/companion/src/simulation/simulateduiwidgetJumperT12.cpp +++ b/companion/src/simulation/simulateduiwidgetJumperT12.cpp @@ -8,7 +8,6 @@ SimulatedUIWidgetJumperT12::SimulatedUIWidgetJumperT12(SimulatorInterface *simul ui(new Ui::SimulatedUIWidgetJumperT12) { RadioUiAction * act; - QPolygon polygon; ui->setupUi(this); diff --git a/companion/src/simulation/simulateduiwidgetJumperT16.cpp b/companion/src/simulation/simulateduiwidgetJumperT16.cpp new file mode 100644 index 000000000..317fdb24c --- /dev/null +++ b/companion/src/simulation/simulateduiwidgetJumperT16.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +// NOTE: RadioUiAction(NUMBER,...): NUMBER relates to enum EnumKeys in the specific board.h + +#include "simulateduiwidget.h" +#include "ui_simulateduiwidgetJumperT16.h" + +SimulatedUIWidgetJumperT16::SimulatedUIWidgetJumperT16(SimulatorInterface *simulator, QWidget * parent): + SimulatedUIWidget(simulator, parent), + ui(new Ui::SimulatedUIWidgetJumperT16) +{ + RadioUiAction * act; + + ui->setupUi(this); + + // add actions in order of appearance on the help menu + + act = new RadioUiAction(3, QList() << Qt::Key_Up, SIMU_STR_HLP_KEY_UP, SIMU_STR_HLP_ACT_MDL); + addRadioWidget(ui->leftbuttons->addArea(QRect(10, 70, 80, 35), "JumperT16/left_mdl.png", act)); + + act = new RadioUiAction(6, QList() << Qt::Key_Left, SIMU_STR_HLP_KEY_LFT, SIMU_STR_HLP_ACT_SYS); + addRadioWidget(ui->leftbuttons->addArea(QRect(10, 10, 80, 35), "JumperT16/left_sys.png", act)); + + act = new RadioUiAction(5, QList() << Qt::Key_Right, SIMU_STR_HLP_KEY_RGT, SIMU_STR_HLP_ACT_TELE); + addRadioWidget(ui->leftbuttons->addArea(QRect(10, 190, 80, 35), "JumperT16/left_tele.png", act)); + + act = new RadioUiAction(4, QList() << Qt::Key_Down << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, + SIMU_STR_HLP_KEY_DN % "
" % SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_RTN); + addRadioWidget(ui->rightbuttons->addArea(QRect(35, 10, 80, 35), "JumperT16/right_rtn.png", act)); + + act = new RadioUiAction(1, QList() << Qt::Key_PageDown, SIMU_STR_HLP_KEY_PGDN, SIMU_STR_HLP_ACT_PGDN); + addRadioWidget(ui->leftbuttons->addArea(QRect(10, 131, 80, 35), "JumperT16/left_page.png", act)); + + m_scrollUpAction = new RadioUiAction(-1, QList() << Qt::Key_Minus, SIMU_STR_HLP_KEY_MIN % "|" % SIMU_STR_HLP_MOUSE_UP, SIMU_STR_HLP_ACT_ROT_LFT); + m_scrollDnAction = new RadioUiAction(-1, QList() << Qt::Key_Plus << Qt::Key_Equal, SIMU_STR_HLP_KEY_PLS % "|" % SIMU_STR_HLP_MOUSE_DN, SIMU_STR_HLP_ACT_ROT_RGT); + connectScrollActions(); + + m_mouseMidClickAction = new RadioUiAction(2, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN); + addRadioWidget(ui->rightbuttons->addArea(QRect(45, 70, 100, 160), "JumperT16/right_ent.png", m_mouseMidClickAction)); + + addRadioWidget(ui->leftbuttons->addArea(QRect(10, 252, 30, 30), "JumperT16/left_scrnsht.png", m_screenshotAction)); + + m_backlightColors << QColor(47, 123, 227); + + setLcd(ui->lcd); +} + +SimulatedUIWidgetJumperT16::~SimulatedUIWidgetJumperT16() +{ + delete ui; +} diff --git a/companion/src/simulation/simulateduiwidgetJumperT16.ui b/companion/src/simulation/simulateduiwidgetJumperT16.ui new file mode 100644 index 000000000..02085d7e7 --- /dev/null +++ b/companion/src/simulation/simulateduiwidgetJumperT16.ui @@ -0,0 +1,197 @@ + + + SimulatedUIWidgetJumperT16 + + + + 0 + 0 + 825 + 292 + + + + + 0 + 0 + + + + + 825 + 292 + + + + + 825 + 292 + + + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 174 + 292 + + + + + 174 + 292 + + + + background:url(:/images/simulator/JumperT16/right.png) + + + + + + + + 0 + 0 + + + + + 480 + 272 + + + + + 480 + 272 + + + + + 5 + + + + + + + + + 0 + 0 + + + + + 174 + 292 + + + + + 174 + 292 + + + + true + + + background:url(:/images/simulator/JumperT16/left.png); + + + + + + + + 0 + 0 + + + + + 480 + 10 + + + + + 480 + 10 + + + + + 5 + + + + background:url(:/images/simulator/JumperT16/top.png) + + + + + + + + 0 + 0 + + + + + 480 + 10 + + + + + 480 + 10 + + + + + 5 + false + + + + background:url(:/images/simulator/JumperT16/bottom.png) + + + + + + + + LcdWidget + QWidget +
lcdwidget.h
+ 1 +
+ + ButtonsWidget + QWidget +
buttonswidget.h
+ 1 +
+
+ + +
diff --git a/companion/src/simulation/simulateduiwidgetX9D2019.cpp b/companion/src/simulation/simulateduiwidgetX9D2019.cpp new file mode 100644 index 000000000..828a946b8 --- /dev/null +++ b/companion/src/simulation/simulateduiwidgetX9D2019.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +// NOTE: RadioUiAction(NUMBER,...): NUMBER relates to enum EnumKeys in the specific board.h + +#include "simulateduiwidget.h" +#include "ui_simulateduiwidgetX9D2019.h" + +SimulatedUIWidgetX9D2019::SimulatedUIWidgetX9D2019(SimulatorInterface *simulator, QWidget * parent): + SimulatedUIWidget(simulator, parent), + ui(new Ui::SimulatedUIWidgetX9D2019) +{ + RadioUiAction * act; + + ui->setupUi(this); + + // add actions in order of appearance on the help menu + + QPoint ctr(70, 100); + + act = new RadioUiAction(0, QList() << Qt::Key_Up << Qt::Key_PageUp, SIMU_STR_HLP_KEYS_GO_UP, SIMU_STR_HLP_ACT_MENU); + addRadioWidget(ui->leftbuttons->addArea(QRect(25, 40, 80, 35), "X9D2019/left_menu.png", act)); + + act = new RadioUiAction(3, QList() << Qt::Key_Down << Qt::Key_PageDown, SIMU_STR_HLP_KEYS_GO_DN, SIMU_STR_HLP_ACT_PAGE); + addRadioWidget(ui->leftbuttons->addArea(QRect(25, 85, 80, 35), "X9D2019/left_page.png", act)); + + act = new RadioUiAction(1, QList() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT); + addRadioWidget(ui->leftbuttons->addArea(QRect(25, 140, 80, 35), "X9D2019/left_exit.png", act)); + + m_scrollUpAction = addRadioAction(new RadioUiAction(-1, QList() << Qt::Key_Minus << Qt::Key_Left, SIMU_STR_HLP_KEYS_GO_LFT, SIMU_STR_HLP_ACT_ROT_LFT)); + m_scrollDnAction = addRadioAction(new RadioUiAction(-1, QList() << Qt::Key_Plus << Qt::Key_Equal << Qt::Key_Right, SIMU_STR_HLP_KEYS_GO_RGT, SIMU_STR_HLP_ACT_ROT_RGT)); + connectScrollActions(); + + m_mouseMidClickAction = new RadioUiAction(2, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN); + addRadioWidget(ui->rightbuttons->addArea(QRect(40, 30, 80, 130), "X9D2019/right_enter.png", m_mouseMidClickAction)); + + addRadioWidget(ui->leftbuttons->addArea(QRect(10, 170, 30, 30), "X9D2019/left_scrnshot.png", m_screenshotAction)); + + m_backlightColors << QColor(47, 123, 227); // Taranis Blue + m_backlightColors << QColor(166,247,159); + m_backlightColors << QColor(247,159,166); + m_backlightColors << QColor(255,195,151); + m_backlightColors << QColor(247,242,159); + + setLcd(ui->lcd); + + QString css = "#radioUiWidget {" + "background-color: qlineargradient(spread:pad, x1:1, y1:0.9, x2:0, y2:0," + "stop:0 rgba(255, 255, 255, 255)," + "stop:0.35 rgba(250, 250, 250, 255), stop:0.5 rgba(242, 241, 241, 255)," + "stop:0.61 rgba(241, 241, 241, 255), stop:1.0 rgba(251, 251, 251, 255));" + "}"; + + QTimer * tim = new QTimer(this); + tim->setSingleShot(true); + connect(tim, &QTimer::timeout, [this, css]() { + emit customStyleRequest(css); + }); + tim->start(100); +} + +SimulatedUIWidgetX9D2019::~SimulatedUIWidgetX9D2019() +{ + delete ui; +} + diff --git a/companion/src/simulation/simulateduiwidgetX9D2019.ui b/companion/src/simulation/simulateduiwidgetX9D2019.ui new file mode 100644 index 000000000..4333f50ca --- /dev/null +++ b/companion/src/simulation/simulateduiwidgetX9D2019.ui @@ -0,0 +1,166 @@ + + + SimulatedUIWidgetX9D2019 + + + + 0 + 0 + 756 + 258 + + + + + 0 + 0 + + + + + 756 + 258 + + + + + 756 + 258 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + 166 + 258 + + + + true + + + background:url(:/images/simulator/X9D2019/left.png); + + + + + + + + 0 + 0 + + + + + 424 + 50 + + + + background:url(:/images/simulator/X9D2019/top.png) + + + + + + + + 0 + 0 + + + + + 166 + 258 + + + + background:url(:/images/simulator/X9D2019/right.png) + + + + + + + + 0 + 0 + + + + + 424 + 128 + + + + + 424 + 128 + + + + + + + + + 0 + 0 + + + + + 424 + 80 + + + + background:url(:/images/simulator/X9D2019/bottom.png) + + + + + + + + LcdWidget + QWidget +
lcdwidget.h
+ 1 +
+ + ButtonsWidget + QWidget +
buttonswidget.h
+ 1 +
+
+ + +
diff --git a/companion/src/simulation/simulateduiwidgetX9LITE.cpp b/companion/src/simulation/simulateduiwidgetX9LITE.cpp index 640945bcf..6941a308d 100644 --- a/companion/src/simulation/simulateduiwidgetX9LITE.cpp +++ b/companion/src/simulation/simulateduiwidgetX9LITE.cpp @@ -8,24 +8,21 @@ SimulatedUIWidgetX9LITE::SimulatedUIWidgetX9LITE(SimulatorInterface *simulator, ui(new Ui::SimulatedUIWidgetX9LITE) { RadioUiAction * act; - QPolygon polygon; ui->setupUi(this); // add actions in order of appearance on the help menu QPoint ctr(70, 91); - polygon << polyArc(ctr.x(), ctr.y(), 50, -90, 90) << polyArc(ctr.x(), ctr.y(), 22, -90, 90); + act = new RadioUiAction(0, QList() << Qt::Key_PageUp << Qt::Key_Up, SIMU_STR_HLP_KEYS_GO_UP, SIMU_STR_HLP_ACT_MENU_ICN); - addRadioWidget(ui->leftbuttons->addArea(polyArc(ctr.x(), ctr.y(), 20), "X9LITE/left_menu.png", act)); + addRadioWidget(ui->leftbuttons->addArea(QRect(80, 20, 40, 35), "X9LITE/left_menu.png", act)); act = new RadioUiAction(3, QList() << Qt::Key_PageDown << Qt::Key_Down, SIMU_STR_HLP_KEYS_GO_DN, SIMU_STR_HLP_ACT_PAGE); - addRadioWidget(ui->leftbuttons->addArea(polygon, "X9LITE/left_page.png", act)); + addRadioWidget(ui->leftbuttons->addArea(QRect(80, 65, 40, 35), "X9LITE/left_page.png", act)); - polygon.clear(); - polygon << polyArc(ctr.x(), ctr.y(), 50, 90, 270) << polyArc(ctr.x(), ctr.y(), 22, 90, 270); act = new RadioUiAction(1, QList() << Qt::Key_Delete << Qt::Key_Escape << Qt::Key_Backspace, SIMU_STR_HLP_KEYS_EXIT, SIMU_STR_HLP_ACT_EXIT); - addRadioWidget(ui->leftbuttons->addArea(polygon, "X9LITE/left_exit.png", act)); + addRadioWidget(ui->leftbuttons->addArea(QRect(80, 130, 40, 35), "X9LITE/left_exit.png", act)); m_scrollUpAction = new RadioUiAction(-1, QList() << Qt::Key_Minus << Qt::Key_Equal << Qt::Key_Left, SIMU_STR_HLP_KEYS_GO_LFT, SIMU_STR_HLP_ACT_ROT_LFT); m_scrollDnAction = new RadioUiAction(-1, QList() << Qt::Key_Plus << Qt::Key_Right, SIMU_STR_HLP_KEYS_GO_RGT, SIMU_STR_HLP_ACT_ROT_RGT); @@ -34,7 +31,7 @@ SimulatedUIWidgetX9LITE::SimulatedUIWidgetX9LITE(SimulatorInterface *simulator, m_mouseMidClickAction = new RadioUiAction(2, QList() << Qt::Key_Enter << Qt::Key_Return, SIMU_STR_HLP_KEYS_ACTIVATE, SIMU_STR_HLP_ACT_ROT_DN); addRadioWidget(ui->rightbuttons->addArea(polyArc(88, 92, 33), "X9LITE/right_ent.png", m_mouseMidClickAction)); - addRadioWidget(ui->leftbuttons->addArea(QRect(9, 154, 30, 30), "X9LITE/left_scrnshot.png", m_screenshotAction)); + addRadioWidget(ui->leftbuttons->addArea(QRect(30, 154, 30, 30), "X9LITE/left_scrnshot.png", m_screenshotAction)); m_backlightColors << QColor(215, 243, 255); // X9LITE Blue m_backlightColors << QColor(166,247,159); @@ -45,10 +42,10 @@ SimulatedUIWidgetX9LITE::SimulatedUIWidgetX9LITE(SimulatorInterface *simulator, setLcd(ui->lcd); QString css = "#radioUiWidget {" - "background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1," - "stop:0 rgba(255, 255, 255, 255)," - "stop:0.757062 rgba(241, 238, 238, 255)," - "stop:1 rgba(247, 245, 245, 255));" + "background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1," + "stop:0 rgba(255, 255, 255, 255)," + "stop:0.757062 rgba(241, 238, 238, 255)," + "stop:1 rgba(247, 245, 245, 255));" "}"; QTimer * tim = new QTimer(this); diff --git a/companion/src/simulation/simulateduiwidgetX9LITE.ui b/companion/src/simulation/simulateduiwidgetX9LITE.ui index 94dbaa08b..4432f8ae3 100644 --- a/companion/src/simulation/simulateduiwidgetX9LITE.ui +++ b/companion/src/simulation/simulateduiwidgetX9LITE.ui @@ -6,7 +6,7 @@ 0 0 - 570 + 650 208
@@ -18,14 +18,14 @@ - 570 - 208 + 603 + 235 - 570 - 208 + 603 + 240 @@ -60,14 +60,14 @@ - 157 - 186 + 173 + 210 - 157 - 186 + 173 + 210 @@ -85,14 +85,14 @@ - 256 - 128 + 602 + 129 - 424 - 128 + 602 + 129 @@ -110,14 +110,14 @@ - 157 - 186 + 174 + 210 - 157 - 186 + 174 + 210 @@ -135,14 +135,14 @@ - 256 - 48 + 258 + 35 - 256 - 48 + 258 + 35 @@ -160,14 +160,14 @@ - 256 - 10 + 258 + 46 - 256 - 10 + 258 + 46 diff --git a/companion/src/simulation/simulatorstartupdialog.cpp b/companion/src/simulation/simulatorstartupdialog.cpp index 07766b7da..57272bf99 100644 --- a/companion/src/simulation/simulatorstartupdialog.cpp +++ b/companion/src/simulation/simulatorstartupdialog.cpp @@ -86,7 +86,7 @@ void SimulatorStartupDialog::changeEvent(QEvent *e) // FIXME : need a better way to check for this bool SimulatorStartupDialog::usesCategorizedStorage(const QString & name) { - return name.contains(QRegExp("(x12|x10|horus)", Qt::CaseInsensitive)); + return name.contains(QRegExp("(x12|x10|horus|t16)", Qt::CaseInsensitive)); } bool SimulatorStartupDialog::usesCategorizedStorage() diff --git a/companion/src/simulation/simulatorwidget.cpp b/companion/src/simulation/simulatorwidget.cpp index 4858d7135..c96cd480e 100644 --- a/companion/src/simulation/simulatorwidget.cpp +++ b/companion/src/simulation/simulatorwidget.cpp @@ -60,6 +60,7 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato switch(m_board) { case Board::BOARD_TARANIS_X9LITE: + case Board::BOARD_TARANIS_X9LITES: radioUiWidget = new SimulatedUIWidgetX9LITE(simulator, this); break; case Board::BOARD_TARANIS_X7: @@ -67,9 +68,11 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato break; case Board::BOARD_TARANIS_X9D: case Board::BOARD_TARANIS_X9DP: - case Board::BOARD_TARANIS_X9DP_2019: radioUiWidget = new SimulatedUIWidgetX9(simulator, this); break; + case Board::BOARD_TARANIS_X9DP_2019: + radioUiWidget = new SimulatedUIWidgetX9D2019(simulator, this); + break; case Board::BOARD_TARANIS_XLITE: case Board::BOARD_TARANIS_XLITES: radioUiWidget = new SimulatedUIWidgetXLITE(simulator, this); @@ -86,7 +89,10 @@ SimulatorWidget::SimulatorWidget(QWidget * parent, SimulatorInterface * simulato break; case Board::BOARD_JUMPER_T12: radioUiWidget = new SimulatedUIWidgetJumperT12(simulator, this); - break; + break; + case Board::BOARD_JUMPER_T16: + radioUiWidget = new SimulatedUIWidgetJumperT16(simulator, this); + break; default: radioUiWidget = new SimulatedUIWidget9X(simulator, this); break; diff --git a/companion/src/tests/conversions.cpp b/companion/src/tests/conversions.cpp index bee7b9520..611c2a3f1 100644 --- a/companion/src/tests/conversions.cpp +++ b/companion/src/tests/conversions.cpp @@ -42,7 +42,7 @@ TEST(Conversions, ConversionX9DPFrom22) EXPECT_STREQ("Thr", model.inputNames[0]); EXPECT_STREQ("Tes", model.sensorData[0].label); EXPECT_EQ(10, model.sensorData[0].id); - EXPECT_EQ(9, model.sensorData[0].instance); + EXPECT_EQ(10, model.sensorData[0].instance); EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,0).toValue(), model.logicalSw[0].val1); } @@ -77,7 +77,7 @@ TEST(Conversions, ConversionX9DPFrom23) EXPECT_STREQ("Rud", model1.inputNames[0]); EXPECT_STREQ("Tes", model1.sensorData[0].label); EXPECT_EQ(10, model1.sensorData[0].id); - EXPECT_EQ(10, model1.sensorData[0].instance); + EXPECT_EQ(11, model1.sensorData[0].instance); EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,0).toValue(), model1.logicalSw[0].val1); const ModelData & model2 = radioData.models[1]; @@ -96,7 +96,7 @@ TEST(Conversions, ConversionX9DPFrom23) EXPECT_STREQ("Rud", model2.inputNames[0]); EXPECT_STREQ("Tes", model2.sensorData[0].label); EXPECT_EQ(10, model2.sensorData[0].id); - EXPECT_EQ(10, model2.sensorData[0].instance); + EXPECT_EQ(11, model2.sensorData[0].instance); EXPECT_EQ(RawSource(SOURCE_TYPE_TELEMETRY,0).toValue(), model2.logicalSw[0].val1); } @@ -130,7 +130,7 @@ TEST(Conversions, ConversionX7From22) EXPECT_STREQ("Tes", model.sensorData[0].label); EXPECT_EQ(10, model.sensorData[0].id); - EXPECT_EQ(9, model.sensorData[0].instance); + EXPECT_EQ(10, model.sensorData[0].instance); EXPECT_EQ(900, model.limitData[0].max); // -100 EXPECT_EQ(10, model.flightModeData[0].gvars[0]); @@ -178,7 +178,7 @@ TEST(Conversions, ConversionXLiteFrom22) EXPECT_STREQ("Tes", model.sensorData[0].label); EXPECT_EQ(10, model.sensorData[0].id); - EXPECT_EQ(8, model.sensorData[0].instance); + EXPECT_EQ(9, model.sensorData[0].instance); EXPECT_EQ(900, model.limitData[0].max); // -100 EXPECT_EQ(LS_FN_VPOS, model.logicalSw[0].func); @@ -284,7 +284,7 @@ TEST(Conversions, ConversionX10From22) EXPECT_STREQ("Rud", model.inputNames[0]); EXPECT_STREQ("Tes", model.sensorData[0].label); EXPECT_EQ(10, model.sensorData[0].id); - EXPECT_EQ(9, model.sensorData[0].instance); + EXPECT_EQ(10, model.sensorData[0].instance); EXPECT_EQ(5 + 2 + 3, model.thrTraceSrc); // CH3 } @@ -360,6 +360,6 @@ TEST(Conversions, ConversionX12SFrom22) EXPECT_STREQ("Rud", model.inputNames[0]); EXPECT_STREQ("Tes", model.sensorData[0].label); EXPECT_EQ(10, model.sensorData[0].id); - EXPECT_EQ(9, model.sensorData[0].instance); + EXPECT_EQ(10, model.sensorData[0].instance); EXPECT_EQ(5 + 2 + 3, model.thrTraceSrc); // CH3 } diff --git a/companion/src/translations/companion_cs.ts b/companion/src/translations/companion_cs.ts index ed4e492d8..c144d4f38 100644 --- a/companion/src/translations/companion_cs.ts +++ b/companion/src/translations/companion_cs.ts @@ -68,17 +68,17 @@ Could not save Application Settings to file "%1" - + Nelze uložit nastavení aplikace do souboru "%1" because the file could not be saved (check access permissions). - + protože soubor nemůže být uložen (zkontrolujte přístupová práva) for unknown reasons. - + z neznámého důvodu. @@ -86,7 +86,7 @@ Show this message again at next startup? - Chcete zobrazit toto upozornění i příště ? + Zobrazit toto upozornění i při příštím spuštění? @@ -710,7 +710,7 @@ Mode 4: Release channel - + Kanál vydání @@ -785,7 +785,7 @@ Mode 4: Append version number to FW file name - Přidat číslo verze do názvu souboru staženého firmwaru + Přidat číslo verze do názvu souboru staženého firmwaru @@ -797,7 +797,7 @@ Mode 4: Offer to write FW to Tx after download - Po stažení firmwaru nabídnout okamžité zapsání do rádia + Po stažení firmwaru nabídnout okamžité zapsání do rádia @@ -1057,7 +1057,7 @@ Mode 4: most recently used files - + naposledny použité soubory @@ -1069,7 +1069,7 @@ Mode 4: Startup Settings - + Nastavení zapnutí @@ -1081,7 +1081,7 @@ Mode 4: Remember - + Zapamatovat @@ -1093,7 +1093,7 @@ Mode 4: Output Logs Folder - + Výstupní složka pro záznamy @@ -1141,7 +1141,7 @@ Mode 4: Just create the model - Jen vytvořit model + Pouze vytvořit model @@ -1153,7 +1153,7 @@ Mode 4: Debug Output Logging - + Záznam pro režim ladění @@ -1177,7 +1177,7 @@ Mode 4: Application (Companion/Simulator) - + Použití (Companion/Simulátor) @@ -1201,7 +1201,7 @@ Mode 4: Radio Firmware (in Simulator) - + Firmware vysílače (v simulátoru) @@ -1273,7 +1273,7 @@ Mode 4: Screenshot capture folder - + Složka pro snímky obrazovky @@ -1285,7 +1285,7 @@ Mode 4: Joystick - + Joystick @@ -1336,7 +1336,7 @@ Mode 4: Select your snapshot folder - Vyberat složku pro snímky obrazovky simulátoru + Vybrat složku pro snímky obrazovky simulátoru @@ -1378,7 +1378,7 @@ Mode 4: Select a folder for application logs - + Vybrat složku pro záznamy aplikace @@ -1388,7 +1388,7 @@ Mode 4: Select the folder replicating your SD structure - Vyberat složku která představuje obsah SD karty rádia + Vybrat složku, která představuje obsah SD karty rádia @@ -1431,30 +1431,31 @@ Mode 4: Error reading %1: %2 - + Chyba čtení %1: %2 Cannot save EEPROM - + Nelze uložit do EEPROM Cannot open file %1: %2. - + Nelze otevřít soubor %1: +%2 Error writing file %1: %2. - Chyba při zápisu souboru %1: + Chyba při zápisu souboru %1: %2. Invalid binary EEPROM file %1 - + Neplatný binární EEPROM soubor %1 @@ -1462,22 +1463,22 @@ Mode 4: Left Horizontal - Levá horizontální + Levá horizontální Left Vertical - Levá vertikální + Levá vertikální Right Vertical - Pravá vertikální + Pravá vertikální Right Horizontal - Pravá horizontální + Pravá horizontální @@ -1493,27 +1494,27 @@ Mode 4: Unknown - Neznámý + Neznámý Rud - Směrovka + Směrovka Ele - Výškovka + Výškovka Thr - Plyn + Plyn Ail - Křidélka + Křidélka @@ -1521,17 +1522,17 @@ Mode 4: Negative span - Negativní + Záporný rozsah Mid value - Střed + Střední hodnota Positive span - Pozitivní + Kladný rozsah @@ -1539,22 +1540,22 @@ Mode 4: Can't extract RADIO/radio.bin - + Nelze rozbalit RADIO/radio.bin Can't extract RADIO/models.txt - + Nelze rozbalit RADIO/models.txt Can't extract %1 - + Nelze rozbalit %1 Error loading models - + Chyba při načítání modelů @@ -1567,17 +1568,17 @@ Mode 4: Min - + Min Max - + Max Subtrim - + Subtrim @@ -2553,27 +2554,27 @@ Thomasi Hustererovi (th9x) a také Erazovi Ravivovi(er9x a eePe) Play Track - Hrát stopu + Přehrát stopu Play Both - Přehrát pár + Přehrát oboje Play Value - Přehrát hodnotu + Přehrát hodnotu Play Script - Spustit skript + Spustit skript SD Logs - SD logy + SD záznamy @@ -2583,27 +2584,27 @@ Thomasi Hustererovi (th9x) a také Erazovi Ravivovi(er9x a eePe) Backlight - Podsvětlení + Podsvětlení Screenshot - Snímek LCD + Snímek obrazovky Background Music - Hudba na pozadí + Hudba na pozadí Background Music Pause - Hudba na pozadí -pozastavit + Hudba na pozadí -pozastavit Adjust %1 - + Upravit %1 diff --git a/companion/src/translations/companion_de.ts b/companion/src/translations/companion_de.ts index e5485ebfb..63d302d40 100644 --- a/companion/src/translations/companion_de.ts +++ b/companion/src/translations/companion_de.ts @@ -11,22 +11,22 @@ Yes, controlled by a single channel - Ja, mit einem Kanal + Ja, über einen Kanal gesteuert Yes, controlled by two channels - Ja, mit 2 Kanälen + Ja, über zwei Kanäle gesteuert <br>First Aileron Channel: - <br> Erster, rechter Querruder Kanal: + <br> Erster Querruderkanal: Second Aileron Channel: - Zweiter, linker Querruder Kanal: + Zweiter Querruderkanal: @@ -39,22 +39,22 @@ Yes, controlled by a single channel - Ja, mit 1 Servo + Ja, über einen Kanal gesteuert Yes, controlled by two channels - Ja, mit 2 Servos + Ja, über zwei Kanäle gesteuert <br>First Airbrake Channel: - <br> Erster, rechter Airbrake Kanal: + <br> Erster Störklappenkanal: Second Airbrake Channel: - Zweiter, linker Airbrake Kanal: + Zweiter Störklappenkanal: @@ -63,22 +63,26 @@ Application Settings have been saved to %1 - + Die Anwendungseinstellungen wurden unter +%1 +gespeichert Could not save Application Settings to file "%1" - + Die Anwendungseinstellungen konnten nicht unter +%1 +gespeichert werden because the file could not be saved (check access permissions). - + , da auf die Datei nicht zugegriffen werden konnte (Überprüfen Sie die Zugriffsrechte). for unknown reasons. - + . Der Grund hierfür ist unbekannt. @@ -86,7 +90,7 @@ Show this message again at next startup? - Diese Nachricht beim nächsten Starten wieder anzeigen? + Diese Nachricht beim nächsten Starten erneut anzeigen? @@ -2067,7 +2071,7 @@ If you have a settings backup file, you may import that instead. OK, I understand. - OK verstanden. + OK, verstanden. @@ -2104,7 +2108,7 @@ If you have a settings backup file, you may import that instead. OpenTX Blacklist - + OpenTX Blacklist @@ -2259,7 +2263,7 @@ If you have a settings backup file, you may import that instead. Curve type - Kurven Typ + Kurventyp @@ -2295,7 +2299,7 @@ If you have a settings backup file, you may import that instead. Point size - + Punktgröße @@ -2367,7 +2371,7 @@ If you have a settings backup file, you may import that instead. Side - Seite + Bereich @@ -2403,7 +2407,7 @@ If you have a settings backup file, you may import that instead. Curve name - Kurven Name + Kurvenname @@ -2413,7 +2417,7 @@ If you have a settings backup file, you may import that instead. Popup menu available - Menü verfügbar + Popoup-Menü verfügbar @@ -2453,22 +2457,22 @@ If you have a settings backup file, you may import that instead. Clear - Löschen + Zurücksetzen Clear all curves - Lösche alle Kurven + Alle Kurven zurücksetzen Are you sure you want to reset curve %1? - Die Kurve %1 wirklich löschen? + Die Kurve %1 wirklich zurücksetzen? Are you sure you want to reset all curves? - Wirklich alle Kurven löschen? + Wirklich alle Kurven zurücksetzen? @@ -2478,7 +2482,7 @@ If you have a settings backup file, you may import that instead. Not enough free points in EEPROM to store the curve. - Nicht genug freie Stützstellen im EEPROM um die Kurve zu speichern. + Es sind nicht genügend freie Stützstellen im EEPROM vorhanden, um diese Kurve zu abzuspeichern. @@ -2606,37 +2610,37 @@ If you have a settings backup file, you may import that instead. Adjust %1 - + Verstelle %1 SetFailsafe Int. Module - + SetFailsafe Int. Modul SetFailsafe Ext. Module - + SetFailsafe Ext. Modul RangeCheck Int. Module - + RangeCheck Int. Modul RangeCheck Ext. Module - + RangeCheck Ext. Modul Bind Int. Module - + Binden Int. Modul Bind Ext. Module - + Binden Ext. Modul @@ -2688,12 +2692,12 @@ If you have a settings backup file, you may import that instead. <font color=red><b>Inconsistent parameter</b></font> - + <font color=red><b>Widersprüchliche Parameter</b></font> Value - Wert + Wert @@ -2703,7 +2707,7 @@ If you have a settings backup file, you may import that instead. repeat(%1s) - + wiederholen(%1s) @@ -2713,7 +2717,7 @@ If you have a settings backup file, you may import that instead. CFN - + CFN @@ -2741,7 +2745,7 @@ If you have a settings backup file, you may import that instead. Popup menu available - Menü verfügbar + Popup-Menü verfügbar @@ -2761,13 +2765,13 @@ If you have a settings backup file, you may import that instead. Error occurred while trying to play sound, possibly the file is already opened. (Err: %1 [%2]) - + Beim Abspielen der Audio-Datei kam es zu einem Fehler, möglicherweise ist sie bereits geöffnet. (Err: %1 [%2]) Unable to find or open sound file: %1 - + Diese Audio-Datei %1 konnte nicht gefunden bzw. geöffnet werden: @@ -2862,7 +2866,7 @@ If you have a settings backup file, you may import that instead. Load FW - Lade FW + Bild aus Firmware-File @@ -2882,7 +2886,7 @@ If you have a settings backup file, you may import that instead. Load Pict - Lade Bild + Bild direkt @@ -2902,7 +2906,7 @@ If you have a settings backup file, you may import that instead. Load Profile - Lade Profil + Bild aus Profil @@ -3003,7 +3007,7 @@ If you have a settings backup file, you may import that instead. Can not load embedded image from firmware file %1. - + Die Bilddatei konnte nicht aus dem Firmware-File %1 geladen werden. @@ -3018,17 +3022,17 @@ If you have a settings backup file, you may import that instead. Cannot load the image file %1. - + Die Bilddatei %1 konnte nicht geladen werden. Cannot load profile image %1. - + Die Bilddatei %1 konnte nicht aus dem Profil geladen werden. Cannot load the library image %1. - + Die Bilddatei %1 konnte nicht aus der Bibliothek geladen werden. @@ -3038,27 +3042,27 @@ If you have a settings backup file, you may import that instead. The image was saved to the file %1 - + Das Bild wurde als %1 gespeichert Image Refresh Error - + Fehler beim Aktualisieren des Bildes Failed to refresh image from file %1 - + Das Aktualisieren des Bildes durch die Datei %1 ist fehlgeschlagen File Save Error - Datei speichern fehlerhaft + Fehler beim Speichern der Datei Failed to write image to %1 - + Das Speichern des Bildes in die Datei %1 ist fehlgeschlagen @@ -3360,17 +3364,17 @@ To <b>remove a remembered entry</b> from the filter list, first cho Downloading: - Herunterladen: + Herunterladen: Unable to save the file %1: %2. - Kann Datei %1:%2 nicht abspeichern. + Die Datei %1 konnte nicht abgespeichert werden:%2. Download failed: %1. - Herunterladen fehlgeschlagen: %1. + Herunterladen fehlgeschlagen: %1. @@ -3477,12 +3481,12 @@ To <b>remove a remembered entry</b> from the filter list, first cho <br>First Elevon Channel: - <br>Erster Rechter Höhenruder Kanal: + <br>Erster Elevon-Kanal: Second Elevon Channel: - Zweiter Linker Höhenruder Kanal: + Zweiter Elevon-Kanal: @@ -3658,7 +3662,7 @@ To <b>remove a remembered entry</b> from the filter list, first cho Include Trim - Trimmung einschliessen + Trimmung einschließen @@ -3777,7 +3781,7 @@ If blank then the input is considered to be "ON" all the time. Popup menu available - Menü verfügbar + Popup-Menü verfügbar @@ -4481,7 +4485,7 @@ Blank means include all. ?, *, and [...] wildcards accepted. Unknown - Unbekannt + Unbekannt @@ -4494,22 +4498,22 @@ Blank means include all. ?, *, and [...] wildcards accepted. Yes, controlled by a single channel - Ja mit einem Kanal + Ja, über einen Kanal gesteuert Yes, controlled by two channels - Ja, mit 2 Kanälen + Ja, über zwei Kanäle gesteuert <br>First Flap Channel: - <br> Erster, rechter Flap Kanal: + <br> Erster Wölbklappenkanal: Second Flap Channel: - Zweiter, linker Flap Kanal: + Zweiter Wölbklappenkanal: @@ -4998,7 +5002,7 @@ Blank means include all. ?, *, and [...] wildcards accepted. Executable %1 not found - + Die ausführbare Datei %1 wurde nicht gefunden @@ -5058,13 +5062,14 @@ Bitte dazu eine passende Firmware zum Programmieren auswählen. You are currently using: %1 - Sie verwenden gerade: + +Sie verwenden gerade: %1 Your radio does not seem connected to USB or the driver is not initialized!!!. - + Der Sender scheint entweder nicht per USB angeschlossen zu sein, oder der entsprechende Treiber wurde nicht installiert. @@ -5171,32 +5176,32 @@ You are currently using: Popup enabled - Anzeige im Popupfenster freigeben + Anzeige im Popup-Fenster freigeben Popup menu available - Menü verfügbar + Popup-Menü verfügbar Trim disabled - Trim ausgeschaltet + Trimmung deaktivieren Own Trim - Eigene Trim + Eigene Trimmung Use Trim from Flight mode %1 - Trim von Flugphase %1 + Trimmung von Flugphase %1 Use Trim from Flight mode %1 + Own Trim as an offset - Trim von Flugphase %1 + Eigene Trim als Offset + Trimmung von Flugphase %1 + Eigene Trimmung als Offset @@ -5256,12 +5261,12 @@ You are currently using: (%1) - (%1) + (%1) (default) - (normal) + (normal) @@ -5269,7 +5274,7 @@ You are currently using: Has Flybar - Has Flybar + Mit Flybar @@ -7703,7 +7708,7 @@ Warnung stummer Betrieb - Wird angezeigt, wenn der Piepser komplett ausgeschalte Keys + Sticks - Taste+Knüppel + Tasten+ Knüppel @@ -7758,12 +7763,12 @@ Warnung stummer Betrieb - Wird angezeigt, wenn der Piepser komplett ausgeschalte Portuguese - Portogiesisch + Portugiesisch Russian - + Russisch @@ -7788,7 +7793,7 @@ Warnung stummer Betrieb - Wird angezeigt, wenn der Piepser komplett ausgeschalte Rot Enc B - Drehgebeer B + Drehgeber B @@ -7810,8 +7815,8 @@ Warnung stummer Betrieb - Wird angezeigt, wenn der Piepser komplett ausgeschalte If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. Are you sure ? - Wenn man FAI auswählt gibt es nur noch RSSI und RxBat als Sensorwerte -Diese Funktion kann dann im Sender nicht mehr abgewählt werden + Wenn Sie FAI auswählen, stehen nur noch RSSI und RxBat als Sensorwerte zur Verfügung. +Diese Funktion kann im Sender nicht mehr abgewählt werden. Sind Sie sicher? @@ -8177,7 +8182,7 @@ Sind Sie sicher? Antenna - Antenne + Antenne @@ -8187,7 +8192,7 @@ Sind Sie sicher? S5 - S5 + S5 @@ -8696,22 +8701,22 @@ Sind Sie sicher? Throttle Channel: - Gas Kanal: + Gas-Kanal: Yaw Channel: - Yaw (Heck) Kanal: + Yaw-Kanal: Pitch Channel: - Pitch Kanal: + Pitch-Kanal: Roll Channel: - Roll Kanal: + Roll-Kanal: @@ -9453,12 +9458,12 @@ Die Spalten für Höhe "GAlt" und für Geschwindigkeit "GSpd" The OpenTX Companion project was originally forked from <a href='%1'>eePe</a> - + Das OpenTX Companion Project ist ein Fork von <a href='%1'>eePe</a> Copyright OpenTX Team - + Copyright OpenTX Team @@ -9498,7 +9503,7 @@ Die Spalten für Höhe "GAlt" und für Geschwindigkeit "GSpd" Diskimage (*.dmg) - + Diskimage (*.dmg) @@ -10763,7 +10768,7 @@ Sollen die Änderungen gespeichert werden? Include Trim - Trimmung einschliessen + Trimmung einschließen @@ -10981,7 +10986,17 @@ p, li { white-space: pre-wrap; } <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If Delay is not zero the actuation of the mix will be delayed by the specified amount of seconds.</p> <p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">If Slow is not zero then the speed of the mix will be set by the value specified -&gt; the value states the number of seconds it takes to transit from -100 to 100.</p></body></html> - + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;"> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600; text-decoration: underline;">Verzögerung und Verlangsamung</span></p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-weight:600; text-decoration: underline;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Diese Werte beeinflussen die Verzögerung und die Geschwindigkeit des Ausgangs des Mixers</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Wenn die Verzögerung nicht 0 ist, wird die Ausführung um diesen Wert in Sekunden verzögert.</p> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"></p> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;">Wenn die Verlangsamung nicht 0 ist, wird der Ausgang des Mixers um den gegebenen Wert verlangsamt -&gt; Der Wert stellt die Zeit in Sekunden dar, die der Ausgangswert des Mischers benötigt, um sich von -100 auf 100 zu ändern.</p></body></html> @@ -10994,7 +11009,9 @@ p, li { white-space: pre-wrap; } Mixer warning. Setting this value will cause a beep to be emmitted when this value is active. - + Ich bin mir nicht sicher ob der + Mixerwarnung. +Diese Einstellung sorgt dafür, dass ein Piepton abgespielt wird, sobald dieser Mixer aktiviert wird. @@ -11091,7 +11108,7 @@ If blank then the mix is considered to be "ON" all the time. Include DR/Expo - DR/Expo einschliessen + DR/Expo einschließen @@ -11115,7 +11132,8 @@ If blank then the mix is considered to be "ON" all the time. Slow - Langsam + Man könnte auch Hemmung sagen + Verlangsamung @@ -11333,12 +11351,12 @@ If blank then the mix is considered to be "ON" all the time. Model: - Model: + Modell: Throttle Source - GasTimer Quelle + Gas-Quelle @@ -11811,7 +11829,7 @@ If blank then the mix is considered to be "ON" all the time. Trim idle only - Nur Leerlauftrimm + Nur Leerlauftrimmung @@ -12212,7 +12230,7 @@ If blank then the mix is considered to be "ON" all the time. Plane - Flugmodell + Flächenmodell @@ -12227,12 +12245,12 @@ If blank then the mix is considered to be "ON" all the time. Model Name: - Model Name: + Modellname: Model Type: - Model Typ: + Modelltyp: @@ -13424,22 +13442,22 @@ If blank then the mix is considered to be "ON" all the time. Throttle Channel: - Gas Kanal: + Gas-Kanal: Yaw Channel: - Yaw (Heck) Kanal: + Yaw-Kanal: Pitch Channel: - Pitch Kanal: + Pitch-Kanal: Roll Channel: - Roll Kanal: + Roll-Kanal: @@ -13452,7 +13470,7 @@ If blank then the mix is considered to be "ON" all the time. ... plus %1 errors - ...plus %1 Fehler + ... plus %1 Fehler @@ -13470,17 +13488,17 @@ If blank then the mix is considered to be "ON" all the time. Throttle Cut - Gas Freigabe Schalter + Gas-Freigabeschalter Throttle Timer - Gas Timer starten + Gas-Timer starten Flight Timer - Flug Timer starten + Flug-Timer starten @@ -13550,7 +13568,7 @@ If blank then the mix is considered to be "ON" all the time. Style - + Style @@ -13809,7 +13827,7 @@ If blank then the mix is considered to be "ON" all the time. <html><head/><body><p>No Radio was found!</p><p>Make sure that you hold the lower trim buttons towards the center while you turn it on.</p><p>Then connect the USB wire.</p><p><span style=" font-family:'arial,sans-serif'; font-size:13px; font-style:italic; color:#222222; background-color:#ffffff;">Note: if you have a Taranis that has not had the firmware upgraded to 2.0 then this version of Companion will not work.</span></p></body></html> - + <html><head/><body><p>Es wurde kein Sender gefunden!</p><p>Stellen Sie sicher, dass Sie während des Einschaltens, die unteren Trimmer zur Mitte hin gedrückt halten</p><p>Stecken Sie danach das USB-Kabel ein.</p><p><span style=" font-family:'arial,sans-serif'; font-size:13px; font-style:italic; color:#222222; background-color:#ffffff;">Hinweis: Sollten Sie eine Taranis besitzen, die noch nicht auf die Version 2.0 upgegraded wurde, wird sie mit dieser Version von Companion nicht funktionieren.</span></p></body></html> @@ -14129,12 +14147,12 @@ r Trm5 - + Trm5 Trm6 - + Trm6 @@ -14144,7 +14162,7 @@ r TrmV - + TrmV @@ -14470,102 +14488,102 @@ r ↑ - + ↑ ↓ - + ↓ - - + - ! - + ! RudTrim Left - SeiteTrim links + Seitenruder-Trimmer links RudTrim Right - SeiteTrim rechts + Seiteruder-Trimmer rechts EleTrim Down - HöheTrim ab + Höheruder-Trimmer runter EleTrim Up - HöheTrim auf + Höheruder-Trimmer hoch ThrTrim Down - GasTrim ab + Gas-Trimmer runter ThrTrim Up - GasTrim auf + Gas-Trimmer hoch AilTrim Left - QuerTrim links + Querruder-Trimmer links AilTrim Right - QuerTrim rechts + Querruder-Trimmer rechts Trim 5 Down - Trim5 ab + Trimmer 5 runter Trim 5 Up - Trim5 auf + Trimmer 5 hoch Trim 6 Down - Trim6 ab + Trimmer 6 runter Trim 6 Up - Trim6 auf + Trimmer 6 hoch TrmH Left - TrimH links + Trimmer H links TrmH Right - TrimH rechts + Trimmer H rechts TrmV Down - TrimV ab + Trimmer V runter TrmV Up - TrimV auf + Trimmer V hoch @@ -14680,7 +14698,7 @@ r <br>Rudder Channel: - <br> Seite Kanal: + <br> Seitenruderkanal: @@ -14696,7 +14714,8 @@ r Error opening file %1 in write mode: %2. - + Fehler beim Öffnen der Datei %1 im Schreibmodus: +%2. @@ -14755,7 +14774,7 @@ r °F - + °F @@ -14775,7 +14794,7 @@ r mW - + mW @@ -14800,7 +14819,7 @@ r Rad - + rad @@ -14825,12 +14844,12 @@ r Internal - Interne + Interne External - + Externe @@ -14893,7 +14912,8 @@ r Throttle Trim Idle Only - Gas Leerlauftrim + Hier bin ich mir nicht sicher + Gas-Leerlaufstrimmung @@ -14920,9 +14940,10 @@ r If this is checked the throttle will be reversed. Idle will be forward, trim will also be reversed and the throttle warning will be reversed as well. - Vollgas hinten? -Wenn das angewählt wird, dann ist Leerlauf vorne. Auch die Gas-Leerlauftrimmung und die Gasstellungs-Warung wird -umgedreht und ist dann vorne. + Umgekehrte Gas-Funktion +Wenn angewählt, befindet sich der Leerlauf vorne. Die Gas-Leerlaufstrimmung sowie die Gasstellungs-Warnung werden dadurch +ebenfalls umgekehrt. + @@ -15079,7 +15100,7 @@ umgedreht und ist dann vorne. Throttle Source - GasTimer Quelle + Gas-Timer-Quelle @@ -15091,7 +15112,7 @@ umgedreht und ist dann vorne. Trim Step - Trim Auflösung + Trimmschritte @@ -15103,7 +15124,7 @@ umgedreht und ist dann vorne. Trims Display - Trimmwerte anzeigen + Trimmungswerte anzeigen @@ -15211,7 +15232,7 @@ umgedreht und ist dann vorne. Extended Trims - Erw. Trim 25%--> 100% + Erw. Trimmung 25% --> 100% @@ -15223,7 +15244,7 @@ umgedreht und ist dann vorne. Throttle Warning - Gas Warnung + Gas-Warnung @@ -15266,7 +15287,7 @@ umgedreht und ist dann vorne. Elevator Channel: - Höhe Kanal: + Höheruderkanal: @@ -16672,47 +16693,47 @@ Error: %2 Style sheet data read from '%1' - + Die Stylesheet-Daten wurden aus der Datei %1 eingelesen Style sheet data unable to be read from '%1' - + Die Stylesheet-Daten konnten nicht aus der Datei %1 eingelesen werden Cannot create folder '%1' - + Der Ordner %1 konnte nicht erstellt werden Cannot open file for writing '%1': Error: %2 - + Die Datei %1 konnte nicht zum schreiben geöffnet werden. Fehler: %2 Cannot write to file '%1': Error: %2 - + In die Datei %1 konnte nicht geschrieben werden. Fehler: %2 Cannot flush buffer for file '%1': Error: %2 - + Der Pufferinhalt konnte nicht in die Datei %1 übernommen werden: Fehler %2 Style sheet written to '%1' - + Die Stylesheet-Daten wurde in der Datei %1 geschrieben Custom style sheet deleted: '%1' - + Das benutzerdefinierte Stylesheet %1 wurde gelöscht Unable to delete custom style sheet: '%1' - + Das benutzerdefinierte Stylesheet %1 konnte nicht gelöscht werden @@ -16880,22 +16901,22 @@ Too many errors, giving up. Elevator and Rudder - Höhe und Seite + Höhen- und Seiteruder Only Elevator - Nur Höhe + Nur Höheruder V-tail - V Leitwerk + V-Leitwerk Tail Type: - Leitwerk Typ: + Leitwerkstyp: @@ -17228,7 +17249,7 @@ Too many errors, giving up. Source - Quelle + Quelle @@ -17252,7 +17273,7 @@ Too many errors, giving up. Altitude source - Höhe Quelle + Höhenquelle @@ -17264,7 +17285,7 @@ Too many errors, giving up. Volts source - Spannung Quelle + Spannungsquelle @@ -17288,7 +17309,7 @@ Too many errors, giving up. mAh - mAh + mAh @@ -17300,7 +17321,7 @@ Too many errors, giving up. A - A + A @@ -19204,7 +19225,7 @@ Timestamp Meters - Meter + m @@ -19432,7 +19453,7 @@ hh:mm:ss Amps - Ampere + A @@ -19484,7 +19505,7 @@ hh:mm:ss Volts - Volt + V @@ -19554,7 +19575,7 @@ hh:mm:ss Degrees - Grad + ° @@ -19681,7 +19702,7 @@ hh:mm:ss <br>Throttle Channel: - <br>Gas Kanal: + <br>Gaskanal: @@ -20254,19 +20275,19 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. RX # - + RX # Models Translators do NOT use accent for this, this is the default category name on Horus. - Modelle + Modelle Model %1 Translators: do NOT use accents here, this is a default model name. - + Modell %1 @@ -20274,12 +20295,12 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. First Tail Channel: - Erster rechter Leitwerk Kanal: + Erster Leitwerkskanal: Second Tail Channel: - Zweiter, linker Leitwerk Kanal: + Zweiter Leitwerkskanal: @@ -20343,12 +20364,12 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Model Wizard - Modell Wizard + Modell-Wizard Model Type - Model Type + Modelltyp @@ -20358,7 +20379,7 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Throttle - Gas + Antrieb @@ -20368,7 +20389,7 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Wing Type - Flächen Typ + Flächentyp @@ -20388,12 +20409,12 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Flaps - Landeklappen + Wölbklappen Has your model got flaps? - Hat das Modell Landeklappen? + Hat das Modell Wölbklappen? @@ -20465,12 +20486,12 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Which type of swash control is installed in your helicopter? - Welchen Typ an Taumelscheibe hat der Heli? + Welche Art von Taumelscheibe ist verbaut? Tail Gyro - Heck Kreisel + Heckkreisel @@ -20485,7 +20506,7 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Has your helicopter got a flybar? - + Hat der Hubschrauber eine Flybar? @@ -20502,7 +20523,7 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Multirotor - MultiCopter + Multikopter @@ -20522,12 +20543,12 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Save Changes - Speichere die Kanäle + Änderungen speichern Manually check the direction of each control surface and reverse any channels that make controls move in the wrong direction. Remove the propeller/propellers before you try to control your model for the first time.<br>Please note that continuing removes all old model settings! - + Überprüfe, ob alle Steuerflächen sich in die richtige Richtung bewegen und invertiere diese gegebenenfalls. Entferne den oder die Propeller bevor du das Modell zum ersten mal steuerst.<br>Bitte beachte, dass das Fortfahren alle alten Einstellungen überschreibt! @@ -20537,7 +20558,7 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Select the receiver channel that is connected to your ESC or throttle servo.<br><br>Throttle - Spektrum: CH1, Futaba: CH3 - + Wähle den Empfängerkanal, an den der ESC oder der Gasservo angeschlossen ist.<br><br>Gas - Spektrum: CH1, Futaba: CH3 @@ -20552,12 +20573,12 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. This wizard assumes that your flaps are controlled by a switch. If your flaps are controlled by a potentiometer you can change that manually later. - + Der Wizard geht davon aus, dass die Wölbklappen durch einen Schalter gesteuert werden. Sollen die Wölbklappen durch ein Poti gesteuert werden, kann dies später noch geändert werden. Air brakes are used to reduce the speed of advanced sail planes.<br>They are very uncommon on other types of planes. - + Störklappen werden eingesetzt um den Widerstand zu erhöhen und damit den Gleitwinkel bei Seglern zu verschlechtern.<br>Für ander Arten von Flugzeugen sind sie eher ungewöhnlich. @@ -20567,23 +20588,23 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Select the receiver channel that is connected to your rudder.<br><br>Rudder - Spektrum: CH4, Futaba: CH4 - + Wähle den Empfängerkanal, an den das Seitenruderservo angeschlossen ist.<br><br>Seitenruder - Spektrum: CH4, Futaba: CH4 Select the tail type of your plane. - Wählen Sie den Leitwerkstyp Ihres Flugzeugs. + Wähle den Leitwerkstyp des Flugzeugs. Select the Rudder and Elevator channels.<br><br>Rudder - Spektrum: CH4, Futaba: CH4<br>Elevator - Spektrum: CH3, Futaba: CH2 - + Wähle den Empfängerkanal, an den Seiten- und das Höhenruderservo angeschlossen ist.<br><br>Seitenruder - Spektrum: CH4, Futaba: CH4<br>Höhenruder - Spektrum: CH3, Futaba: CH2 Select the Elevator channel.<br><br>Elevator - Spektrum: CH3, Futaba: CH2 - Wählen Sie den Kanal für das Höhenleitwerk.<br><br>Höhenleitwerk - Spektrum: CH3, Futaba: CH2 + Wähle den Kanal für das Höhenleitwerk.<br><br>Höhenleitwerk - Spektrum: CH3, Futaba: CH2 @@ -20599,12 +20620,12 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Select the control channels for your multirotor.<br><br>Throttle - Spektrum: CH1, Futaba: CH3<br>Yaw - Spektrum: CH4, Futaba: CH4<br>Pitch - Spektrum: CH3, Futaba: CH2<br>Roll - Spektrum: CH2, Futaba: CH1 - + Wähle die Steuerkanäle für deinen Multikopter.<br><br>Throttle - Spektrum: CH1, Futaba: CH3<br>Yaw - Spektrum: CH4, Futaba: CH4<br>Pitch - Spektrum: CH3, Futaba: CH2<br>Roll - Spektrum: CH2, Futaba: CH1 There is no help available for the current page. - + Für diese Seite steht keine Hilfe zur Verfügung. @@ -20617,7 +20638,7 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Plane - Flugmodell + Flächenmodell @@ -20632,17 +20653,17 @@ CTRL + scroll or PAGE UP/DOWN keys to change time in larger steps. Model Name: - Model Name: + Modelname: Model Type: - Model Typ: + Modelltyp: Options: - Optionen: + Optionen: diff --git a/companion/src/translations/companion_fr.ts b/companion/src/translations/companion_fr.ts index ec238e663..355c77914 100644 --- a/companion/src/translations/companion_fr.ts +++ b/companion/src/translations/companion_fr.ts @@ -94,97 +94,41 @@ AppPreferencesDialog - - - - - - - Edit Settings - Éditer les réglages + Éditer les paramètres - - - - - - - Radio Profile Profil de radio - - - - - - - Default Channel Order Ordre des voies par défaut - - - - - - - Build Options Options de compilation - - - - - - - Menu Language Langue des menus - - - - - - - Default Stick Mode Mode par défaut - - - - - - - Select Image Sélectionner une image - - - - - - - Mode selection: Mode 1: @@ -226,417 +170,172 @@ Manche Droit: Profondeur, Direction - - - - - - - Mode 1 (RUD ELE THR AIL) Mode 1 (DIR PROF GAZ AIL) - - - - - - - Mode 2 (RUD THR ELE AIL) Mode 2 (DIR GAZ PROF AIL) - - - - - - - Mode 3 (AIL ELE THR RUD) Mode 3 (AIL PROF GAZ DIR) - - - - - - - Mode 4 (AIL THR ELE RUD) Mode 4 (AIL GAZ PROF DIR) - - - - - - - Splash Screen Ecran d'accueil - - - - - - - - - - - - - - The profile specific folder, if set, will override general Backup folder - Dossier de sauvegarde spécifique au profil courant, si défini remplace le réglage de l'application + Dossier de sauvegarde spécifique au profil courant, si défini remplace le paramètre de l'application - - - - - - - Backup folder Dossier de sauvegarde - - - - - - - If set it will override the application general setting - Si défini, remplace le réglage de l'application pour ce profil + Si défini, remplace le paramètre de l'application pour ce profil - - - - - - - if set, will override general backup enable - Si défini, remplace le réglage de l'application pour ce profil + Si défini, remplace le paramètre de l'application pour ce profil - - - - - - - <html><head/><body><p>Channel order</p><p><br/></p><p>Defines the order of the default mixes created on a new model.</p></body></html> <html><head/><body><p>Ordre des voies</p><p><br/></p><p>Détermine l'ordre des mixages par défaut sur un nouveau modèle.</p></body></html> - - - - - - - R E T A D P G A - - - - - - - R E A T D P A G - - - - - - - R T E A D G P A - - - - - - - R T A E D G A P - - - - - - - R A E T D A P G - - - - - - - R A T E D A G P - - - - - - - E R T A P D G A - - - - - - - E R A T P D A G - - - - - - - E T R A P G D A - - - - - - - E T A R P G A D - - - - - - - E A R T P A D G - - - - - - - E A T R P A G D - - - - - - - T R E A G D P A - - - - - - - T R A E G D A P - - - - - - - T E R A G P D A - - - - - - - T E A R G P A D - - - - - - - T A R E G A D P - - - - - - - T A E R G A P D - - - - - - - A R E T A D P G - - - - - - - A R T E A D G P - - - - - - - A E R T A P D G - - - - - - - A E T R A P G D - - - - - - - A T R E A G D P - - - - - - - A T E R A G P D @@ -647,680 +346,272 @@ Manche Droit: Profondeur, Direction - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Select Folder Sélectionner dossier - - - - - - - Select Executable Sélectionner exécutable - - - - Release channel Canal de version - - - - Releases (stable) - Officielle (stable) + Officiel (stable) - - - - Release candidates (testing) Candidate (test) - - - - Nightly builds (unstable) Nighlty (instable) - - - - - - - Simulator Volume Gain Gain de volume du simulateur - - - - - - - Profile Name Nom du profil - - - - - - - Clear Image Effacer l'image - - - - - - - Append version number to FW file name Ajouter le numéro de version au nom du fichier téléchargé - - - - - - - Offer to write FW to Tx after download Proposer de transférer le firmware à la radio après téléchargement - - - - - - - Radio Type Type de radio - - - - - - - Other Settings - Autres réglages + Autres paramètres - - - - - - - General Settings Paramètres généraux - - - - - - - SD Structure path Chemin de la structure de la carte SD - - - - - - - Application Settings - Réglages de l'application + Paramètres de l'application - - - - - - - Show splash screen when Companion starts Afficher l'écran d'accueil au lancement de Companion - - - - - - - Automatic check for Companion updates Vérifier la présence de mises à jour de Companion automatiquement - - - - - - - - - - - - - - Enable automatic backup before writing firmware - Sauvegarder les réglages et modèles automatiquement lors des transferts + Sauvegarder les paramètres et modèles automatiquement lors des transferts - - - - - - - Automatic check for OpenTX firmware updates Vérifier la présence de mises à jour de firmware automatiquement - - - - - - - Splash Screen Library Bibliothèque d'écrans d'accueil - - - - - - - Google Earth Executable Exécutable Google Earth - - - - - - - Only show user splash images Ne montrer que les images de l'utilisateur - - - - - - - Show user and companion splash images Montrer les images de Companion et de l'utilisateur - - - - - - - User Splash Screens Ecrans d'accueil personnalisés - - - - - - - Automatic Backup Folder Dossier de sauvegardes automatiques - - - - - - - Simulator Settings Paramètres du simulateur - - - - - - - Simulator BackLight Rétroéclairage du simulateur - - - - - - - Enable Actif - - - - - - - Action on New Model Action par défaut "Ajout Modèle" - - - - - - - Use model wizard Assistant - - - - - - - Open model editor Éditer modèle - - - - - - - Just create the model Créer modèle - - - - - - - <html><head/><body><p>This option maintains the behaviour from older OpenTx versions where empty model slots are preserved when a model is deleted or moved. </p><p>When this option is de-selected, the other models may be re-arranged to fill the gap left by the removed model.</p></body></html> <html><head/><body><p><b><u>/!\</u> Uniquement pour les radios sans catégories <u>/!\</u></b></p><p>Cette option maintient le comportement des anciennes versions d’OpenTx où les emplacements des modèles vides sont conservés lorsqu'un modèle est supprimé ou déplacé.</p><p>Lorsque cette option est désélectionnée, les autres modèles peuvent être réarrangés pour combler l'écart laissé par le modèle supprimé.</p></body></html> - - - - - - - most recently used files fichiers récemment utilisés - - - - - - - Startup Settings Paramètres de démarrage - - - - - - - Remember Mémoriser - - - - - - - Output Logs Folder Dossier des logs sauvegardés - - - - - - - Remove empty model slots when deleting models (only applies for radios w/out categories) Supprimer les emplacements vides lors de la suppression de modèles - - - - - - - Debug Output Logging Log les messages de debug - - - - - - - <html><head/><body><p>Keep a log of all debugging messages generated by the desktop Companion/Simulator applications. An OpenTX developer may request this to help diagnose an issue.</p></body></html> <html><head/><body><p>Garder un log de tous les messages de débogage générés par les applications Companion/Simulateur. Un développeur OpenTX peut demander ce log afin d'aider à diagnostiquer un problème.</p></body></html> - - - - - - - Application (Companion/Simulator) Application (Companion/Simulateur) - - - - - - - <html><head/><body><p>Keep a log of all messages generated by the radio firmware when running in Simulator. This is the same information one would also see in the Simulator <span style=" font-style:italic;">Debug Output</span> window.</p></body></html> <html><head/><body><p>Conserver un log de tous les messages générés par le firmware radio lors de l'exécution du Simulateur. C'est la même information visible depuis le Simulateur dans la <span style=" font-style:italic;">Fenêtre de débogage</span>.</p></body></html> - - - - - - - Radio Firmware (in Simulator) Firmware radio (Simulateur) - - - - - - - Blue Bleu - - - - - - - Green Vert - - - - - - - Red Rouge - - - - - - - Orange Orange - - - - - - - Yellow Jaune - - - - - - - Screenshot capture folder Dossier des captures d'écran - - - - - - - Joystick - - - - - - - Calibrate Calibrer - - - - - - - Only capture to clipboard Capturer dans le presse-papiers uniquement - - - - - - - Remember simulator switch values Mémoriser les positions des inters du simulateur @@ -1358,12 +649,12 @@ Manche Droit: Profondeur, Direction AVAILABLE: Radio settings of unknown age - DISPONIBLE: Réglages enregistrés à une date inconnue + DISPONIBLE: Paramètres enregistrés à une date inconnue AVAILABLE: Radio settings stored %1 - DISPONIBLE: Réglages enregistrés le %1 + DISPONIBLE: Paramètres enregistrés le %1 @@ -1374,7 +665,7 @@ Manche Droit: Profondeur, Direction Select your Models and Settings backup folder - Sélectionner le dossier dans lequel une sauvegarde des réglages et modèles sera placée automatiquement lors de chaque opération + Sélectionner le dossier dans lequel une sauvegarde des paramètres et modèles sera placée automatiquement lors de chaque opération @@ -1401,31 +692,6 @@ Manche Droit: Profondeur, Direction Images (%1) Images (%1) - - - - - Use releases (stable) - - - - - Use release candidates (testing) - - - - - - - Use nightly builds (unstable) - - - - - - Use releases and release candidates (testing) - - BinEepromFormat @@ -1462,58 +728,58 @@ Manche Droit: Profondeur, Direction Boards - + Left Horizontal Gauche Horizontal - + Left Vertical Gauche Vertical - + Right Vertical Droit Vertical - + Right Horizontal Droit Horizontal - + Aux. 1 - + Aux. 2 - - + + Unknown Inconnu - + Rud Dir - + Ele Prf - + Thr Gaz - + Ail @@ -1646,85 +912,36 @@ Manche Droit: Profondeur, Direction ChecklistDialog - - - - - - - Edit Checklist Éditer Checklist - - - - - - - Line nn, Col nn Ligne nn, Col nn - - - - - - - &Import... &Importer... - - - - - - - &Cancel &Annuler - - - - - - - &OK - - - - - - - Please note, the maximum width displayable is radio model limited. Also, renaming the model will break the link to this checklist file. Veuillez noter que la largeur maximale affichable est limitée suivant le modèle de radio. Notez aussi que renommer le modèle va casser le lien vers ce fichier "Checklist". - - - - - - - File: unknown Fichier: inconnu @@ -1813,7 +1030,7 @@ Manche Droit: Profondeur, Direction Application Settings - Réglages de l'application + Paramètres de l'application @@ -1823,7 +1040,7 @@ Manche Droit: Profondeur, Direction Radio and Models settings - Réglages Radio et Modèles + Paramètres Radio et Modèles @@ -1841,37 +1058,37 @@ Manche Droit: Profondeur, Direction <p> Le type de radio sélectionnée dans le profil n'existe pas. Utilisez plutôt le type par défaut. </p> <p><b>Veuillez mettre à jour les paramètres de votre profil!</b></p> - + Select or create a file for exported Settings: Sélectionnez ou créez un fichier pour les paramètres exportés: - + Press the 'Retry' button to choose another file. Appuyez sur le bouton 'Réessayer' pour choisir un autre fichier. - + Simulator for this firmware is not yet available Le simulateur n'est pas encore disponible pour ce firmware - + Uknown error during Simulator startup. Erreur inconnue pendant le démarrage du simulateur. - + Simulator Error Erreur Simulateur - + Data Load Error Erreur de chargement des données - + Error occurred while starting simulator. Une erreur s'est produite lors du démarrage du simulateur. @@ -1978,73 +1195,31 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import CompareDialog - - - - - - - Compare Models Comparer les modèles - - - - - - - To compare models, drag and drop them anywhere in this window. Pour comparer les modèles, faites un glisser/déposer n'importe où dans cette fenêtre. - - - - - - - Close Fermer - - - - - - - Style - - - - - - - Print Imprimer - - - - - - - Print to file Imprimer vers un fichier @@ -2201,213 +1376,87 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import Curves - - - - - - - Fixed X X fixe - - - - - - - Custom X X configurable - - - - - - - Lines Linéaire - - - - - - - Smooth Adoucie - - - - - - - - - - - - - - Curve type Type de courbe - - - - - - - Curve Creator Créateur de courbe - - - - - - - Y at X=0 Y pour X=0 - - - - - - - Point size Taille point - - - - - - - Y at X=100 Y pour X=100 - - - - - - - Both Les 2 - - - - - - - x>0 - - - - - - - x<0 - - - - - - - Apply Appliquer - - - - - - - Side Côté - - - - - - - Y at X=-100 Y pour X=-100 - - - - - - - Coefficient - - - - - - - Curve name Nom de la courbe @@ -2821,133 +1870,42 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import CustomizeSplashDialog - - - - - - - Transmitter Splash Screen Editor Éditeur d'écran d'accueil - - - - - - - - - - - - - - Invert Inverser - - - - - - - - - - - - - - Load FW Ouvrir le firmware - - - - - - - - - - - - - - Load Pict Ouvrir l'image - - - - - - - - - - - - - - Load Profile Charger le profil - - - - - - - - - - - - - - Save Sauvegarder - - - - - - - - - - - - - - Open Splash Library Ouvrir la bibliothèque des écrans d'accueil @@ -2956,34 +1914,6 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import - - - - - - - - - - - - - - - - - - - - - - - - - - - - ... @@ -3099,48 +2029,48 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import Erreur de conversion du champ %1 - + Switch Interrupteur - + Switch L'interrupteur - + cannot be exported on this board! n'est pas supporté sur cette carte ! - + Source - + Source %1 cannot be exported on this board! La source %1 n'est pas supportée sur cette plateforme ! - + OpenTX only accepts %1 points in all curves OpenTX n'accepte que %1 points au maximum entre toutes les courbes - + OpenTx only accepts %1 points in all curves OpenTX n'accepte que %1 points au maximum entre toutes les courbes - + OpenTX on this board doesn't accept this function OpenTX ne supporte pas cette fonction sur cette carte - + OpenTX doesn't accept this radio protocol OpenTX ne supporte pas ce protocole radio @@ -3149,57 +2079,21 @@ Si vous avez un fichier de sauvegarde des paramètres, vous pouvez l'import DebugOutput - - - - - - - - - Debug Output Sortie débogage - - - - - - - - - <html><head/><body><p>Enable or disable the filter. If the button won't stay enabled, it is likely there is a syntax error in the Regular Expression entered.</p></body></html> <html><head/><body><p>Activer ou désactiver le filtre. Si le bouton ne reste pas actif, c'est qu'il y a probablement une erreur dans la <i>Regular Expression</i>.</p></body></html> - - - - - - - - - Filter: Filtre: - - - - - - - - - <html><head/><body><p>Enter filter text here. Click the help/info button for details about using the filter. </p><p> To <b>remove a remembered entry</b> from the filter list, first choose it, and then press <code>Shift-Delete</code> (or <code>Shift-Backspace</code>) key combination.</p></body></html> <html><head/><body><p>Entrer le filtre ici. Cliquer sur le bouton d'aide/info pour plus de détails sur l'utilisation du filtre. </p><p> @@ -3207,141 +2101,51 @@ Pour <b>retirer un filtre de l'historique</b>, sélectionnez-le - - - - - - - - - Buffer: Tampon: - - - - - - - - - Number of lines to keep in display. Nombre de lignes du tampon. - - - - - - - - - Filter &Help Filtre &Aide - - - - - - - - - Show information about using the filter. Affiche les informations concernant l'usage du filtre. - - - - - - - - - Word &Wrap Renvoi &Ligne - - - - - - - - - Toggle word wrapping on/off. Retour automatique à la ligne on/off. - - - - - - - - - &Clear &Effacer - - - - - - - - - Clear the output window of all text. Effacer tout le texte dans la fenêtre de sortie. - - - - - - - - - Enable &Filter Activer &Filtre - - - - - - - - - Turn the filter on/off. Basculer le filtre on/off. @@ -3360,13 +2164,6 @@ Pour <b>retirer un filtre de l'historique</b>, sélectionnez-le DownloadDialog - - - - - - - Downloading: Téléchargement: @@ -3513,37 +2310,16 @@ Vérifier la sélection (M64/M128) ExpoDialog - - - - - - - Weight Ratio - - - - - - - Flight modes Phases de vol - - - - - - - Input name Nom de l'entrée @@ -3551,111 +2327,41 @@ Vérifier la sélection (M64/M128) - - - - - - - - - - - - - - - - - - - - - GV VG - - - - - - - Switch Interrupteur - - - - - - - Curve applied to the source. Courbe appliquée à la source. - - - - - - - Source - - - - - - - Line name Nom de la ligne - - - - - - - Stick Side Direction - - - - - - - Source for the mixer. La voie maître du mixage. - - - - - - - Switch used to enable the line. If blank then the input is considered to be "ON" all the time. Interrupteur utilisé pour activer la ligne. @@ -3663,121 +2369,51 @@ Si vide, la ligne est toujours active. - - - - - - - Scale Echelle - - - - - - - Include Trim Inclure Trim - - - - - - - No Non - - - - - - - Yes Oui - - - - - - - Curve Courbe - - - - - - - Offset Décalage - - - - - - - The source for the mixer La voie maître du mixage - - - - - - - NEG Négative - - - - - - - POS Positive - - - - - - - ALL Les 2 @@ -3903,37 +2539,37 @@ Si vide, la ligne est toujours active. Source Folder: - Dosssier Source: + Dosssier "Local": Destination Folder: - Dossier Destination: + Dossier "Radio": %1%2 Both directions, to destination folder first - %1%2 Bidirectionnel, en commençant par le dossier Destination + %1%2 Bidirectionnel, en commençant par "Radio" %1%2 Both directions, to source folder first - %1%2 Bidirectionnel, en commençant par le dossier Source + %1%2 Bidirectionnel, en commençant par "Local" %1 Only from source folder to destination folder - %1 Uniquement du dossier Source vers le dossier Destination + %1 Uniquement de "Local" vers "Radio" %1 Only from destination folder to source folder - %1 Uniquement du dossier Destination vers le dossier Source + %1 Uniquement de "Radio" vers "Local" How to handle overwriting files which already exist in the destination folder. - Comment gérer l'écrasement des fichiers qui existent déjà dans le dossier Destination. + Comment gérer l'écrasement des fichiers qui existent déjà dans le dossier de destination. @@ -4155,268 +2791,286 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Source folder not found. - Dossier Source non trouvé. + Dosssier "Local" non trouvé. Destination folder not found. - Dossier Destination non trouvé. + Dosssier "Radio" non trouvé. Source and destination folders are the same. - Les dossiers Source et Destination sont les mêmes. + Les dossiers "Local" et "Radio" sont les mêmes. Firmware - + Channel values displayed in us Positions de voies affichées en µs - + No OverrideCH functions available Désactive la fonction spéciale "Remplacer VOIExx" - + Possibility to enable FAI MODE (no telemetry) at field Possibilité d'activer le mode FAI (télémétrie désactivée) sur le terrain - + FAI MODE (no telemetry) always enabled Mode FAI (télémétrie toujours désactivée) - + Removes D8 FrSky protocol support which is not legal for use in the EU on radios sold after Jan 1st, 2015 Masque le protocole D8. Légalement obligatoire sur les radios Européennes importées après le 1er janvier 2015 - - + + Disable HELI menu and cyclic mix support Supprimer le menu HELICO et les mixages cycliques - - + + Disable Global variables Supprimer le support des variables globales - - + + Enable Lua custom scripts screen Activer l'écran des scripts Lua personnalisés - + Support for PPM internal module hack Support du remplacement du module interne par un module PPM - + Use alternative SQT5 font Utiliser la police alternative SQT5 - + Disable RAS (SWR) Désactiver le RAS (SWR). Utile uniquement pour les X9D+ avec un RAS/SWR non fonctionnel - + Pots use in menus navigation Support de la navigation dans les menus avec les POTS - + FrSky Taranis X9D+ - + FrSky Taranis X9D+ 2019 - + FrSky Taranis X9D - + Haptic module installed Module vibreur installé - + FrSky Taranis X9E - + Confirmation before radio shutdown Confirmation avant l'arrêt de la radio - + Horus gimbals installed (Hall sensors) Manches Horus à effet HALL installés - + FrSky Taranis X9-Lite - - + + + + + Support for auto update on boot Prise en charge de la mise à jour automatique au démarrage - + + FrSky Taranis X9-Lite S + + + + FrSky Taranis X7 / X7S - + FrSky Taranis X-Lite S/PRO - + FrSky Taranis X-Lite - + FrSky Horus X10 / X10S - - + + Support for ACCESS internal module replacement Prise en charge du module de remplacement interne ACCESS - - FrSky Horus X10 Express - - - - + FrSky Horus X12S - + Use ONLY with first DEV pcb version Exclusivement pour les Horus DEV - + Jumper T12 - + Enable non certified R9M firmwares Activer les firmwares R9M non certifiés - + + Jumper T16 / T16+ + + + + + Support for MULTI internal module + Prise en charge du module MULTI interne + + + Turnigy 9XR-PRO - + Enable HELI menu and cyclic mix support Activer le menu hélico et les mixages CCPM - + Global variables Variables globales - + Enable non certified firmwares Activer les firmwares non certifiés - + In model setup menus automatically set source by moving the control Sélectionner les sources des mixeurs en bougeant le contrôle désiré - + In model setup menus automatically set switch by moving the control Sélectionner les interrupteurs en bougeant le contrôle désiré - + No graphical check boxes and sliders Pas de cases à cocher et de curseurs graphiques - + Battery graph Graphique de la batterie - + Don't use bold font for highlighting active items Ne pas mettre les lignes actives en gras - + + FrSky Horus X10 / X10S Express + + + + Turnigy 9XR with m128 chip Turnigy 9XR avec une puce m128 - + Turnigy 9XR - + 9X with stock board 9X avec carte mère d'origine - + Enable resetting values by pressing up and down at the same time Permet la remise à zéro des valeurs en pressant haut-bas en même temps, valeur min avec gauche/bas, valeur max avec haut/droite, inversion avec gauche/droite - + 9X with stock board and m128 chip Carte 9x avec un chip m128 - + 9X with AR9X board 9X avec carte AR9X - + 9X with Sky9x board 9X avec carte Sky9x - + 9X with Gruvin9x board 9X avec carte Gruvin9x - + DIY MEGA2560 radio Radio DIY à base de MEGA2560 @@ -4425,73 +3079,31 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont FirmwarePreferencesDialog - - - - - - - Downloads Téléchargements - - - - - - - Check for updates Vérifier les mises à jour - - - - - - - Firmware - - - - - - - Download firmware Télécharger firmware - - - - - - - Download SD contents Télécharger carte SD - - - - - - - Latest Download Dernière version téléchargée @@ -4533,158 +3145,67 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont FlashEEpromDialog - - - - - - - Write Models and Settings to Radio - Transférer les réglages et modèles vers la radio + Transférer les paramètres et modèles vers la radio - - - - - - - Load... Parcourir... - - - - - - - Current Profile Profil courant - - - - - - - Allows Companion to write to older version of the firmware - Permet à Companion de transférer des réglages à une ancienne version de firmware + Permet à Companion de transférer des paramètres à une ancienne version de firmware - - - - - - - Check Firmware compatibility Vérifier la compatibilité du firmware - - - - - - - <html><head/><body><p>Saves a dated copy of your eeprom to the backup folder you specified in the Companion settings before writing the current model to the radio.</p></body></html> <html><head/><body><p>Enregistre une copie datée de votre eeprom actuelle dans le dossier de sauvegarde avant de transférer les modèles à la radio.</p></body></html> - - - - - - - Backup before Write - Sauvegarder les réglages actuels avant d'écrire + Sauvegarder les paramètres actuels avant d'écrire - - - - - - - <html><head/><body><p>Modify calibration parameters using settings from current profile</p></body></html> <html><head/><body><p>Charger l'étalonnage du profil courant</p></body></html> - - - - - - - Patch calibration setting from profile Patcher l'étalonnage du profil courant - - - - - - - <html><head/><body><p>Modify HW parameters using settings from current profile</p></body></html> <html><head/><body><p>Charger les paramètres hardware du profil courant</p></body></html> - - - - - - - Patch HW settings from profile Patcher les paramètres hardware du profil courant - - - - - - - Cancel Annuler - - - - - - - Write to TX Transférer @@ -4701,12 +3222,12 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Wrong radio calibration data in profile, Settings not patched - Données de calibration incorrectes dans le profil, les réglages ne seront pas transférés + Données de calibration incorrectes dans le profil, les paramètres ne seront pas transférés Wrong radio setting data in profile, Settings not patched - Données de configuration incorrectes dans le profil, les réglages ne seront pas transférés + Données de configuration incorrectes dans le profil, les paramètres ne seront pas transférés @@ -4735,176 +3256,78 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Cannot check Models and Settings compatibility! Continue anyway? - Impossible de vérifier la compatibilité des réglages et modèles ! Continuer quand même ? + Impossible de vérifier la compatibilité des paramètres et modèles ! Continuer quand même ? FlashFirmwareDialog - - - - - - - Flash Firmware Programmer le firmware - - - - - - - Load... Parcourir... - - - - - - - Date & Time Date et heure - - - - - - - Variant Variante - - - - - - - Version - - - - - - - Use profile start screen Utiliser l'écran d'accueil du profil - - - - - - - Use firmware start screen Utiliser l'écran d'accueil du firmware - - - - - - - Use library start screen Utiliser un écran d'accueil de la bibliothèque - - - - - - - Use another start screen Utiliser un autre écran d'accueil - - - - - - - Allows Companion to write to older version of the firmware - Permet à Companion de transférer des réglages à une ancienne version de firmware + Permet à Companion de transférer des paramètres à une ancienne version de firmware - - - - - - - Check Hardware compatibility Vérifier la compatibilité du hardware - - - - - - - Backup and restore Models and Settings - Sauvegarder et restaurer les réglages et modèles + Sauvegarder et restaurer les paramètres et modèles - - - - - - - Cancel Annuler - - - - - - - Write to TX Transférer @@ -4992,7 +3415,7 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Cannot convert Models and Settings for use with this firmware, original data will be used - Impossible de convertir les réglages et modèles pour ce firmware, les données originales vont être utilisées + Impossible de convertir les paramètres et modèles pour ce firmware, les données originales vont être utilisées @@ -5002,7 +3425,7 @@ Blanc signifie "inclure tous".Les métacaractères ?, * et [...] sont Could not restore Models and Settings to Radio. The models and settings data file can be found at: %1 - Impossible de restaurer les réglages et modèles sur la radio. Le fichier peut être récupéré ici: %1 + Impossible de restaurer les paramètres et modèles sur la radio. Le fichier peut être récupéré ici: %1 @@ -5104,49 +3527,21 @@ Vous utilisez actuellement: FlightMode - - - - - - - Fade In Fondu en entrée - - - - - - - Fade Out Fondu en sortie - - - - - - - Name Nom - - - - - - - Switch Interrupteur @@ -5336,25 +3731,11 @@ Vous utilisez actuellement: FusesDialog - - - - - - - Fuses Fusibles - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5384,25 +3765,11 @@ p, li { white-space: pre-wrap; } - - - - - - - Read Fuses Lire Fusibles - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5437,13 +3804,6 @@ p, li { white-space: pre-wrap; } - - - - - - - Reset Fuses EEPROM - PROTECT Réinitialiser Fusibles @@ -5451,13 +3811,6 @@ PROTECTION EEPROM - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5490,13 +3843,6 @@ p, li { white-space: pre-wrap; } - - - - - - - Reset Fuses EEPROM - DELETE Réinitialiser Fusibles @@ -5504,13 +3850,6 @@ EFFACEMENT EEPROM - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -5592,25 +3931,11 @@ p, li { white-space: pre-wrap; } - - - - - - - Radio settings - Réglages Radio + Paramètres Radio - - - - - - - General settings used throught the transmitter. These will be relevant for all models in the same EEPROM. Paramètres généraux de l'émetteur. @@ -5623,27 +3948,13 @@ Communs à tous les modèles d'une même EEPROM. - - - - - - - Store calib. and hw settings in selected profile - Sauver étalonnage et réglages hw dans profil + Sauver étalonnage et paramètres hw dans profil - - - - - - - Retrieve calib. and hw settings from profile - Lire étalonnage et réglages hw du profil + Lire étalonnage et paramètres hw du profil @@ -5698,309 +4009,127 @@ Communs à tous les modèles d'une même EEPROM. GeneralSetup - - - - - - - Form Formulaire - - - - - - - Readonly Unlock Débloquage lecture seule - - - - - - - SC - - - - - - - SE - - - - - - - SA - - - - - - - SF - - - - - - - SH - - - - - - - SD - - - - - - - SB - - - - - - - SG - - - - - - - Timeshift from UTC Décalage horaire (UTC) - - - - - - - Voice Language Langue des voix - - - - - - - Country Code Zone géographique RF - - - - - - - Stick reverse Inversion des manches - - - - - - - FAI Mode Mode FAI - - - - - - - Adjust RTC Ajuster l'heure par GPS - - - - - - - Vario pitch at max Tonalité du vario au max - - - - - - - - - - - - - - Hz - - - - - - - Speaker Volume Volume haut-parleur - - - - - - - Backlight Switch Inter de rétroéclairage - - - - - - - Sound Mode Mode Son - - - - - - - Color 1 Couleur 1 - - - - - - - Color 2 Couleur 2 - - - - - - - Speaker Pitch (spkr only) Tonalité (HP uniquement) - - - - - - - If this value is not 0, any keypress will turn on the backlight and turn it off after the specified number of seconds. Si cette valeur est différente de 0, l'appui sur une touche de navigation déclenche le rétroéclairage qui s'éteint après la durée spécifiée (en secondes). @@ -6008,209 +4137,82 @@ Communs à tous les modèles d'une même EEPROM. - - - - - - - - - - - - - - - sec - - - - - - - Backlight color Couleur du rétroéclairage - - - - - - - Beeper Bipeur - - - - - - - Speaker Haut-parleur - - - - - - - BeeperVoice Bipeur/Voix - - - - - - - SpeakerVoice Haut-parleur/Voix - - - - - - - Beep volume Volume des bips - - - - - - - Wav volume Volume des fichiers audio - - - - - - - Vario volume Volume du variomètre - - - - - - - Background volume Volume de la musique d'ambiance - - - - - - - - - - - - - - ms - - - - - - - Backlight Auto OFF after Arrêt rétroéclairage après - - - - - - - Backlight flash on alarm Clignotement rétroécl. alarmes - - - - - - - Vario pitch at zero Tonalité du vario à 0 - - - - - - - Vario repeat at zero Répétition du vario à 0 - - - - - - - This is the switch selectrion for turning on the backlight (if installed). @@ -6219,20 +4221,6 @@ Communs à tous les modèles d'une même EEPROM. - - - - - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -6248,97 +4236,41 @@ p, li { white-space: pre-wrap; } - - - - - - - Backlight Brightness Luminosité du rétroéclairage - - - - - - - RotEnc Navigation Navigation sélecteur rotatif - - - - - - - Automatically adjust the radio's clock if a GPS is connected to telemetry. Régle automatique l'heure de la radio si un GPS est présent. - - - - - - - America Amérique - - - - - - - Japan Japon - - - - - - - Europe - - - - - - - Backlight OFF Brightness Luminosité écran éteint - - - - - - - Mode selection: Mode 1: @@ -6380,824 +4312,336 @@ Mode 4: - - - - - - - Mode 1 (RUD ELE THR AIL) Mode 1 (DIR PRF GAZ AIL) - - - - - - - Mode 2 (RUD THR ELE AIL) Mode 2 (DIR GAZ PRF AIL) - - - - - - - Mode 3 (AIL ELE THR RUD) Mode 3 (AIL PRF GAZ DIR) - - - - - - - Mode 4 (AIL THR ELE RUD) Mode 4 (AIL GAZ PRF DIR) - - - - - - - <html><head/><body><p>Channel order</p><p><br/></p><p>Defines the order of the default mixes created on a new model.</p></body></html> <html><head/><body><p>Ordre des voies</p><p><br/></p><p>Détermine l'ordre des mixages par défaut sur un nouveau modèle.</p></body></html> - - - - - - - If you enable FAI, only RSSI and RxBt sensors will keep working. This function cannot be disabled by the radio. Si vous activez l'option FAI, seuls les capteurs RSSI et BtRx vont fonctionner. Cette fonction ne peut pas être désactivée sur la radio. - - - - Owner Registration ID Enregistrement ID du propriétaire - - - - aaaaaaAA - - - - - - - R E T A D P G A - - - - - - - R E A T D P A G - - - - - - - R T E A D G P A - - - - - - - R T A E D G A P - - - - - - - R A E T D A P G - - - - - - - R A T E D A G P - - - - - - - E R T A P D G A - - - - - - - E R A T P D A G - - - - - - - E T R A P G D A - - - - - - - E T A R P G A D - - - - - - - E A R T P A D G - - - - - - - E A T R P A G D - - - - - - - T R E A G D P A - - - - - - - T R A E G D A P - - - - - - - T E R A G P D A - - - - - - - T E A R G P A D - - - - - - - T A R E G A D P - - - - - - - T A E R G A P D - - - - - - - A R E T A D P G - - - - - - - A R T E A D G P - - - - - - - A E R T A P D G - - - - - - - A E T R A P G D - - - - - - - A T R E A G D P - - - - - - - A T E R A G P D - - - - Power Off Delay Délai mise hors tension - - - - - - - USB Mode Mode USB - - - - - - - Jack Mode Mode Jack - - - - - - - Audio - - - - - - - Trainer Écolage - - - - - - - - - - - - - - Ask on Connect Demander à la connexion - - - - - - - Joystick (HID) - - - - - - - USB Mass Storage Stockage USB (SD) - - - - - - - USB Serial (CDC) Port série USB (Debug) - - - - - - - Stick Mode Mode - - - - - - - Metric Métrique - - - - - - - Imperial Impérial - - - - - - - Default Channel Order Ordre des voies par défaut - - - - - - - GPS Coordinates Coordonnées GPS - - - - - - - Min - - - - - - - - - - - - - - v - - - - - - - Max - - - - - - - RSSI Poweroff Warning Vérifier RSSI à l'extinction - - - - - - - DMS - - - - - - - Inactivity Timer Alerte d'inactivité - - - - - - - Show Splash Screen on Startup Afficher l'écran de démarrage - - - - - - - Contrast Contraste - - - - - - - Battery Meter Range Plage de l'indicateur de batterie - - - - - - - Haptic Strength Puissance vibreur - - - - - - - LCD Display Type Type de LCD - - - - - - - "No Sound" Warning Alerte "son coupé" - - - - - - - Battery Warning Alerte batterie - - - - - - - Haptic Length Durée vibreur - - - - - - - MAVLink Baud Rate Baudrate Mavlink - - - - - - - - - - - - - - Quiet Mode silencieux - - - - - - - Only Alarms Seulement les alarmes - - - - - - - - - - - - - - No Keys Touches silencieuses - - - - - - - - - - - - - - All Tous - - - - - - - Battery warning voltage. This is the threashhold where the battery warning sounds. @@ -7209,271 +4653,113 @@ Plage de valeurs: 5v...10v - - - - - - - Standard - - - - - - - Optrex - - - - - - - If not zero will sound beeps if the transmitter has been left without inputs for the specified number of minutes. Si différent de 0, émission d'un bip sonore régulier si aucune action n'a été effectuée sur l'émetteur depuis le temps spécifié (en minutes). Réinitialisation en agissant sur n'importe lequel des manches / touches de navigation. - - - - - - - min - - - - Power On Delay Délai mise sous tension - - - - - - - - - - - - - - Show splash screen on startup Affiche l'écran d'accueil au démarrage - - - - - - - --- - - - - - - - 2s - - - - - - - 3s - - - - - - - 4s - - - - - - - 6s - - - - - - - 8s - - - - - - - 10s - - - - - - - 15s - - - - - - - 4800 Baud - - - - - - - 9600 Baud - - - - - - - 14400 Baud - - - - - - - 19200 Baud - - - - - - - 38400 Baud - - - - - - - 57600 Baud - - - - - - - 76800 Baud - - - - - - - 115200 Baud @@ -7481,27 +4767,6 @@ Réinitialisation en agissant sur n'importe lequel des manches / touches de - - - - - - - - - - - - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -7528,196 +4793,70 @@ p, li { white-space: pre-wrap; } - - - - - - - - - - - - - - X-Short Très court - - - - - - - - - - - - - - Short Court - - - - - - - - - - - - - - Normal - - - - - - - - - - - - - - Long - - - - - - - - - - - - - - X-Long Très long - - - - - - - Low EEPROM Warning Avertissement EEPROM faible - - - - - - - NMEA - - - - - - - Play Delay (switch mid position) Délai position centrale inters - - - - - - - Measurement Units Unités de mesure - - - - - - - Haptic Mode Mode du vibreur - - - - - - - Beeper Length Durée des bips - - - - - - - Beeper Mode - Réglage des bips + Paramètre des bips - - - - - - - Beeper volume 0 - Quiet. No beeps at all. @@ -7735,26 +4874,9 @@ Extra long : bips extra longs. - - - - - - - Alarms Only Seulement les Alarmes - - - Power On Speed - - - - - Power Off Speed - - GeneralSetupPanel @@ -7910,595 +5032,256 @@ Cette fonction ne peut pas être désactivée sur la radio. Hardware - - - - - - - Form Formulaire - - - - - - - - + SQ - - - - - - - SR - - - - - - - LS2 - - - - - - - - + SP - - - - - - - SO - - - - - - - S4 - - - - - - - RS - - - - - - - - + SB - - - - - - - PPM 2 - - - - + Antenna Antenne - - - - - - - - + OFF Eteint - - - - - - - - + S-Port Mirror Recopie S. Port - - - - - - - - + Telemetry Télémetrie - - - - - - - - + SBUS Trainer Écolage SBUS - - - - - - - - + Debug Débogage - - - - - - + + RTC Batt Check + Vérif Batterie RTC + + + S5 - - - - - - - Rud Dir - - - - - - - PPM 3 - - - - - - - - + S1 - - - - - - - - + S2 - - - - - - - - + S3 - - - - - - - PPM 1 - - - - - - - - + Serial Port Port série - - - - - - - - + v - - - - - - - PPM Multiplier Coeff. multiplicateur PPM - - - - - - - Current Offset Correction courant - - - - - - - PPM 4 - - - - - - - - + SA - - - - - - - Ele Prf - - - - - - - Ail Ail - - - - - - - Thr Gaz - - - - - - - SC - - - - - - - - + LS - - - - - - - SD - - - - - - - - + Battery Offset Correction tension - - - - - - - SE - - - - - - - - + SF - - - - - - - - + SG - - - - - - - SH - - - - - - - - + SI - - - - - - - - + SJ - - - - - - - SK - - - - - - - - + SL - - - - - - - SM - - - - - - - SN - - - - - - - - + RS2 - - - - - - - Bluetooth - - - - - - - ADC Filter Filtre ADC - - - - - - - Device Name: Nom de l'appareil: @@ -8597,169 +5380,71 @@ Cette fonction ne peut pas être désactivée sur la radio. Heli - - - - - - - Invert Elevator Profondeur - - - - - - - Invert Aileron Aileron - - - - - - - Invert Collective Pas collectif - - - - - - - Invert Inversion - - - - - - - Off Aucun - - - - - - - 120 - - - - - - - 120X - - - - - - - 140 - - - - - - - 90 - - - - - - - Long. cyc Cyc. longitudinal - - - - - - - Lateral cyc Cyc. latéral - - - - - - - Collective Source du pas collectif - - - - - - - Swash Type Type de plateau cyclique - - - - - - - Swash Ring Limite cyclique @@ -9152,109 +5837,46 @@ Cette fonction ne peut pas être désactivée sur la radio. LogsDialog - - - - - - - Companion Log Viewer Visualiseur de Log - - - - - - - Filename Nom de fichier - - - - - - - Open LogFile Ouvrir fichier de Log - - - - - - - Zoom - - - - - - - Save session CSV Sauvegarder la session CSV - - - - - - - X - - - - - - - Y - - - - - - - Reset Remise à zéro - - - - - - - Fly sessions Sessions de vol @@ -9452,7 +6074,7 @@ Les colonnes contenant l'altitude "GAlt" et la vitesse "GSpd Show fuses dialog - Afficher les réglages des fusibles + Afficher les paramètres des fusibles @@ -9591,18 +6213,18 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Write Models and Settings To Radio - Transférer les réglages et modèles vers la radio + Transférer les paramètres et modèles vers la radio Write Models and Settings to Radio - Transférer les réglages et modèles vers la radio + Transférer les paramètres et modèles vers la radio Read Models and Settings from Radio - Lire les réglages et modèles depuis la radio + Lire les paramètres et modèles depuis la radio @@ -9652,7 +6274,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Save a complete backup file of all settings and model data in the Radio - Créer une copie de sauvegarde de tous les réglages et modèles de la radio + Créer une copie de sauvegarde de tous les paramètres et modèles de la radio @@ -9724,7 +6346,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Open Models and Settings file - Ouvrir un fichier de réglages et modèles + Ouvrir un fichier de paramètres et modèles @@ -9735,7 +6357,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Read Models and Settings From Radio - Lire les réglages et modèles depuis la radio + Lire les paramètres et modèles depuis la radio @@ -9775,7 +6397,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Models and Settings read - Lecture des modèles et réglages + Lecture des modèles et paramètres @@ -9790,12 +6412,12 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Local Folder - Dossier local + Dossier "Local" Radio Folder - Dossier Radio + Dossier "Radio" @@ -9826,13 +6448,13 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Create a new Models and Settings file - Créer un nouveau fichier de réglages et modèles + Créer un nouveau fichier de paramètres et modèles Save Models and Settings file - Enregistrer le fichier de réglages et modèles + Enregistrer le fichier de paramètres et modèles @@ -9852,7 +6474,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Close Models and Settings file - Fermer le fichier de réglages et modèles + Fermer le fichier de paramètres et modèles @@ -9867,7 +6489,7 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Create a new Radio Settings Profile - Créer un nouveau profil de réglages et modèles + Créer un nouveau profil de paramètres et modèles @@ -9877,12 +6499,12 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b Duplicate current Radio Settings Profile - Dupliquer les réglages radio du profil actuel + Dupliquer les paramètres radio du profil actuel Delete the current Radio Settings Profile - Supprimer les réglages radio du profil actuel + Supprimer les paramètres radio du profil actuel @@ -9923,17 +6545,17 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b No Companion release candidates are currently being served for this version, please switch release channel - Aucune version "candidate" de Companion n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal officiel + Aucune version "candidate" de Companion n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal "officiel" No nightly Companion builds are currently being served for this version, please switch release channel - Aucune version "nightly" de Companion n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal officiel + Aucune version "nightly" de Companion n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal "officiel" No Companion release builds are currently being served for this version, please switch release channel - Aucune version "officielle" de Companion n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal officiel + Aucune version "officielle" de Companion n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal "candidate" ou "nightly" @@ -9943,17 +6565,17 @@ Nous recommandons de lire attentivement les notes de version à l'aide du b No firmware release candidates are currently being served for this version, please switch release channel - Aucun firmware "candidate" n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal officiel + Aucun firmware "candidate" n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal "officiel" No firmware nightly builds are currently being served for this version, please switch release channel - Aucun firmware "nightly" n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal officiel + Aucun firmware "nightly" n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal "officiel" No firmware release builds are currently being served for this version, please switch release channel - Aucun firmware "officiel" n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal officiel + Aucun firmware "officiel" n'est actuellement disponible sur ce serveur, veuillez commuter sur le canal "candidate" ou "nightly" @@ -10041,22 +6663,22 @@ Do you wish to continue? Export Application Settings.. - Exporter les réglages de l'application... + Exporter Préférences Application... Save all the current %1 and Simulator settings (including radio profiles) to a file. - Enregistrez tous les réglages actuels %1 et du simulateur (y compris les profils radio) dans un fichier. + Enregistrez tous les paramètres actuels %1 et du simulateur (y compris les profils radio) dans un fichier. Import Application Settings.. - Importer les réglages de l'application... + Importer les paramètres de l'application... Load %1 and Simulator settings from a prevously exported settings file. - Charger les réglages %1 et les réglages de Simulation depuis un fichier précédemment exporté. + Charger les paramètres %1 et les paramètres de Simulation depuis un fichier précédemment exporté. @@ -10191,17 +6813,17 @@ Do you wish to continue? Please save or close all modified files before importing settings - Veuillez sauvegarder ou fermer tous les fichiers modifiés avant d'importer les réglages + Veuillez sauvegarder ou fermer tous les fichiers modifiés avant d'importer les paramètres <html><p>%1 and Simulator settings can be imported (restored) from a previosly saved export (backup) file. This will replace current settings with any settings found in the file.</p><p>An automatic backup of the current settings will be attempted. But if the current settings are useful then it is recommended that you make a manual backup first.</p><p>For best results when importing settings, <b>close any other %1 windows you may have open, and make sure the standalone Simulator application is not running.</p><p>Do you wish to continue?</p></html> - <html><p>%1 et les réglages du simulateur peuvent être importés (restaurés) à partir d’un fichier d’exportation (sauvegarde) préalablement sauvegardé. Ceci remplacera les réglages actuels par tous les réglages trouvés dans le fichier.</p><p>Une sauvegarde automatique des réglages actuels sera tentée. Mais si les réglages actuels sont utiles, il est recommandé de commencer par une sauvegarde manuelle.</p><p>Pour obtenir de meilleurs résultats lors de l'importation des réglages,<b> fermez les autres fenêtres %1 que vous avez éventuellement ouvertes et assurez-vous que l'application autonome Simulator n'est pas en cours d'exécution. </p><p>Souhaitez-vous continuer? </p></html> + <html><p>%1 et les paramètres du simulateur peuvent être importés (restaurés) à partir d’un fichier d’exportation (sauvegarde) préalablement sauvegardé. Ceci remplacera les paramètres actuels par tous les paramètres trouvés dans le fichier.</p><p>Une sauvegarde automatique des paramètres actuels sera tentée. Mais si les paramètres actuels sont utiles, il est recommandé de commencer par une sauvegarde manuelle.</p><p>Pour obtenir de meilleurs résultats lors de l'importation des paramètres,<b> fermez les autres fenêtres %1 que vous avez éventuellement ouvertes et assurez-vous que l'application autonome Simulator n'est pas en cours d'exécution. </p><p>Souhaitez-vous continuer? </p></html> Confirm Settings Import - Confirmer les réglages d'importation + Confirmer les paramètres d'importation @@ -10221,17 +6843,17 @@ Do you wish to continue? The settings could not be imported. - Les réglages n'ont pas pu être importés. + Les paramètres n'ont pas pu être importés. <html><p>New settings have been imported from:<br> %1.</p><p>%2 will now re-initialize.</p><p>Note that you may need to close and restart %2 before some settings like language and icon theme take effect.</p> - <html><p>Les nouveaux réglages ont été importés depuis:<br> %1. </p><p>%2 sera maintenant réinitialisé.</p><p>Notez que vous devrez peut-être fermer et redémarrer %2 avant que certains réglages tels que la langue et le thème d’icône prennent effet.</p> + <html><p>Les nouveaux paramètres ont été importés depuis:<br> %1. </p><p>%2 sera maintenant réinitialisé.</p><p>Notez que vous devrez peut-être fermer et redémarrer %2 avant que certains paramètres tels que la langue et le thème d’icône prennent effet.</p> <p>The previous settings were backed up to:<br> %1</p> - <p>Les réglages précédents ont été sauvegardés sous:<br> %1 </p> + <p>Les paramètres précédents ont été sauvegardés sous:<br> %1 </p> @@ -10266,7 +6888,7 @@ Do you wish to continue? Edit Settings - Éditer les réglages + Éditer les préférences @@ -10349,7 +6971,7 @@ Do you wish to continue? Settings - Réglages + Paramètres @@ -10370,7 +6992,7 @@ Do you wish to continue? MdiChild - + Unable to find file %1! Fichier %1 introuvable ! @@ -10489,17 +7111,17 @@ Do you wish to continue? Edit Radio Settings - Éditer réglages radio + Éditer paramètres radio Copy Radio Settings - Copier les réglages radio + Copier les paramètres radio Paste Radio Settings - Coller les réglages radio + Coller les paramètres radio @@ -10635,37 +7257,37 @@ Do you wish to continue? Impossible de dupliquer le modèle, aucun emplacement libre n’est disponible. - + Do you wish to continue with the conversion? Souhaitez-vous vraiment lancer la conversion ? - + Choose <i>Apply</i> to convert the file, or <i>Close</i> to close it without conversion. Choisissez <i>Appliquer</i> pour convertir le fichier ou <i>Annuler</i> pour le fermer sans conversion. - + <b>The conversion generated some important messages, please review them below.</b> <b>La conversion a généré des messages importants, veuillez les consulter ci-dessous.</b> - + Companion :: Conversion Result for %1 Companion :: Résultat de conversion de %1 - + Unable to find Horus radio SD card! Impossible de trouver la carte SD de la Horus ! - + Models and Settings written - Modèle et réglages écrit + Modèle et paramètres écrit - + Cannot write temporary file! Ecriture de fichier temporaire impossible ! @@ -10675,14 +7297,14 @@ Do you wish to continue? Édition du modèle %1 : - + Error reading file %1: %2. Fichier %1 corrompu: %2. - + Error opening file %1: %2. Erreur à l'ouverture du fichier %1: @@ -10721,17 +7343,17 @@ Do you wish to continue? Nlle categorie - + <p><b>Currently selected radio type (%1) is not compatible with file %3 (from %2), models and settings need to be converted.</b></p> <p><b>Le type de radio actuellement sélectionné (%1) n'est pas compatible avec le fichier %3 (à partir de %2), les modèles et les paramètres doivent être convertis.</b></p> - + Open backup Models and Settings file - Ouvrir la sauvegarde de réglages et modèles + Ouvrir la sauvegarde de paramètres et modèles - + Invalid binary backup File %1 Fichier de sauvegarde %1 invalide @@ -10760,97 +7382,41 @@ Enregistrer les changements ? MixerDialog - - - - - - - Up Haut - - - - - - - ADD += Ajouter - - - - - - - OFF - - - - - - - Down Bas - - - - - - - Slow Ralenti - - - - - - - Delay Délai - - - - - - - Curve Courbe - - - - - - - Multiplexer This determines how mixer values are added. @@ -10868,13 +7434,6 @@ Spécifie comment les valeurs de mixage sont interprétées. - - - - - - - The curve used by the mix Courbe utilisée par le mixage @@ -10882,63 +7441,21 @@ Spécifie comment les valeurs de mixage sont interprétées. - - - - - - - - - - - - - - - - - - - - - GV VG - - - - - - - Yes Oui - - - - - - - No Non - - - - - - - Mixer warning. Setting this value will cause a beep to be emmitted when this value is active. Alerte de mixage. @@ -10946,59 +7463,26 @@ Si activée, signale par des bips que le mixage est actif. - - - - - - - 1 Beep 1 Bip - - - - - - - 2 Beep 2 Bips - - - - - - - 3 Beep 3 Bips - - - - - - - Multiplex Multiplexage - - - - - Dialog Dialogue @@ -11007,34 +7491,6 @@ Si activée, signale par des bips que le mixage est actif. - - - - - - - - - - - - - - - - - - - - - - - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } @@ -11060,61 +7516,26 @@ p, li { white-space: pre-wrap; } - - - - - - - Offset Décalage - - - - - - - Source Source - - - - - - - Switch Interrupteur - - - - - - - Weight Ratio - - - - - - - REPLACE := Remplacer @@ -11123,58 +7544,16 @@ p, li { white-space: pre-wrap; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - The source for the mixer La source du mixage - - - - - - - MULTIPLY *= Multiplier - - - - - - - Switch used by the mix. If blank then the mix is considered to be "ON" all the time. Interrupteur utilisé par le mixage. @@ -11182,25 +7561,11 @@ Mixage actif par défaut si non-renseigné. - - - - - - - Warning Avertissement - - - - - - - Name Nom @@ -11231,46 +7596,19 @@ Mixage actif par défaut si non-renseigné. - - - - - - - Include Trim Inclure Trim - - - - - - - Flight modes Phases de vol - - - - - - - Include DR/Expo Inclure DR/Expo - - - - FullScreenDialog - - MixersListWidget @@ -11444,20 +7782,13 @@ Mixage actif par défaut si non-renseigné. ModelEdit - - - - - - - Simulate Simulation Heli - Réglages hélico + Paramètres hélico @@ -11486,11 +7817,6 @@ Mixage actif par défaut si non-renseigné. - - - - - Dialog Dialogue @@ -11514,12 +7840,6 @@ Mixage actif par défaut si non-renseigné. Telemetry Télémesure - - - - FullScreenDialog - - ModelPrinter @@ -12338,288 +8658,123 @@ Mixage actif par défaut si non-renseigné. Module - - - - - - - Failsafe Mode Mode Failsafe - - - - - - - Start 1ère voie - - - - - - - PPM delay Impulsion - - - - - - - Negative Négative - - - - - - - Positive - - - - - - - Polarity Polarité - - - - - - - Trainer Mode Mode écolage - - - - - - - PPM Frame Length Longueur de trame PPM - - - - - - - CH VOIE - - - - - - - Antenna Antenne - - - - - - - Option value - - - - - - - us µs - - - - - - - Master/Jack Maître/Jack - - - - - - - Slave/Jack Elève/Jack - - - - - - - Master/SBUS Module Maître/SBUS module - - - - - - - Master/CPPM Module Maître/CPPM Module - - - - - - - Master/SBUS in battery compartment Maître/SBUS dans compartiment batterie - - - - - - - RF Output Power Puissance RF - - - - - - - Sub Type Sous-Type - - - - - - - Show values in: Afficher les valeurs en: - - - - - - - % abbreviation for percent - - - - - - - μs abbreviation for microseconds - - - - - - - ms - - - - Receiver 1 Récepteur 1 @@ -12627,351 +8782,192 @@ Mixage actif par défaut si non-renseigné. - - - - - - - - - - - - X - - - - Receiver 2 Récepteur 2 - - - - Receiver 3 Récepteur 3 - - - - - - - WARNING: changing RF Output Power needs RE-BIND ATTENTION: RE-BIND nécessaire pour tout changement de puissance RF - - - - - - - Channels Nb de voies - - - - - - - Not set Non défini - - - - - - - Hold Maintien - - - - - - - Custom Prédéfini - - - - - - - No Pulses Pas d'impulsions - - - - - - - Receiver Récepteur - - - - - - - WARNING: Requires non-certified firmware! ATTENTION: Nécessite un firmware non certifié! - - - - Registration ID ID d'enregistrement - - - - - - - Failsafe Positions Positions Failsafe - - - - - - - Protocol Protocole - - - - - - - Multi Radio Protocol Protocole Multi - - - - - - - Receiver No. Récepteur No. - - - - - - - Output type Type de sortie - - - - - - - Open Drain - - - - - - - Push Pull - - - - - - - Bind on startup Bind au démarage - - - - - - - Low Power Puissance Réduite - - - - - - Internal - Interne - - - - - - - Ext. + Int. - - ModuleData - + Positive - + Negative Négative - + Trainer Port Port écolage - + Internal Radio System Module HF interne - + External Radio Module Module HF externe - + Extra Radio System Module HF supplémentaire - + Radio System Module HF - + 10mW - 16CH 10mW - 16 VOIES - - + + 100mW - 16CH 100mW - 16 VOIES - + 500mW - 16CH 500mW - 16 VOIES - + Auto <= 1W - 16CH Auto <= 1W - 16 VOIES - - + + 25mW - 8CH 25mW - 8 VOIES - - + + 25mW - 16CH 25mW - 16 VOIES - + 200mW - 16CH (no telemetry) 200mW - 16 VOIES (pas de télémétrie) - + 500mW - 16CH (no telemetry) 500mW - 16 VOIES (pas de télémétrie) - + 100mW - 16CH (no telemetry) 100mW - 16 VOIES (pas de télémétrie) @@ -12979,37 +8975,37 @@ Mixage actif par défaut si non-renseigné. ModulePanel - + Value Valeur - + Hold Maintien - + No Pulse Pas d'impulsion - + Ask Demander - + Internal Interne - + Internal + External Interne + Externe - + External Externe @@ -13511,7 +9507,7 @@ Mixage actif par défaut si non-renseigné. DÉFAUT - + Custom - proto %1) Personnaliser - proto %1) @@ -13542,22 +9538,22 @@ Mixage actif par défaut si non-renseigné. OpenTxEepromInterface - + Unknown error Erreur inconnue - + ... plus %1 errors ... plus %1 erreurs - + Cannot write radio settings Impossible d'écrire les paramètres de la radio - + Cannot write model %1 Impossible d'écrire le modèle %1 @@ -13628,49 +9624,21 @@ Mixage actif par défaut si non-renseigné. PrintDialog - - - - - - - Close Fermer - - - - - - - Style - - - - - - - Print Imprimer - - - - - - - Print to file Imprimer vers un fichier @@ -13694,25 +9662,11 @@ Mixage actif par défaut si non-renseigné. ProgressDialog - - - - - - - Flash Firmware Flasher le firmware - - - - - - - Close Fermer @@ -13727,17 +9681,23 @@ Mixage actif par défaut si non-renseigné. ProgressWidget - - - - - - - Show Details Voir les détails + + QObject + + + WARNING + ATTENTION + + + + <p>Importing JumperTX data into OpenTX 2.3 is <b>not supported and dangerous.</b></p> <p>It is unfortunately not possible for us to differentiate JumperTX data from legitimate FrSky X10 data, but <b>You should only continue here if the file you opened comes from a real FrSky X10.</b></p> <p>Do you really want to continue?</p> + <p>L'importation de données JumperTX dans OpenTX 2.3 est <b> non prise en charge et dangereuse.</b></p> <p>Il n'est malheureusement pas possible pour nous de différencier les données JumperTX des données légitimes FrSky X10, donc <b>Vous devez continuer uniquement si le fichier que vous avez ouvert provient d’une véritable radio FrSky X10.</b></p> <p>Voulez-vous vraiment continuer?</p> + + RadioData @@ -13887,37 +9847,16 @@ Mixage actif par défaut si non-renseigné. RadioNotFoundDialog - - - - - - - No Radio Found Radio non détectée - - - - - - - <html><head/><body><p>No Radio was found!</p><p>Make sure that you hold the lower trim buttons towards the center while you turn it on.</p><p>Then connect the USB wire.</p><p><span style=" font-family:'arial,sans-serif'; font-size:13px; font-style:italic; color:#222222; background-color:#ffffff;">Note: if you have a Taranis that has not had the firmware upgraded to 2.0 then this version of Companion will not work.</span></p></body></html> - <html><head/><body><p>Aucune radio détectée !</p><p>Veuillez vous assurer de maintenir les 2 trims horizontaux vers l'intérieur lors de la mise sous tension de la radio.</p><p>Ensuite connecter le câble USB.</p><p><span style=" font-family:'arial,sans-serif'; font-size:13px; font-style:italic; color:#222222; background-color:#ffffff;">Note: Cette version de Companion ne doit être utilisée pour éditer des réglages que si la version du firmware de la radio est au moins 2.0.</span></p></body></html> + <html><head/><body><p>Aucune radio détectée !</p><p>Veuillez vous assurer de maintenir les 2 trims horizontaux vers l'intérieur lors de la mise sous tension de la radio.</p><p>Ensuite connecter le câble USB.</p><p><span style=" font-family:'arial,sans-serif'; font-size:13px; font-style:italic; color:#222222; background-color:#ffffff;">Note: Cette version de Companion ne doit être utilisée pour éditer des paramètres que si la version du firmware de la radio est au moins 2.0.</span></p></body></html> - - - - - - - OK @@ -13926,99 +9865,36 @@ Mixage actif par défaut si non-renseigné. RadioOutputsWidget - - - - - - - - - Form Formulaire - - - - - - - - - View: Vue: - - - - - - - - - Logical Switches Inters Logiques - - - - - - - - - Global Variables Variables Globales - - - - - - - - - Channel Outputs Sorties Voies - - - - - - - - - Mix Outputs Sorties Mixages - - - - - - - - - L o g @@ -14029,15 +9905,6 @@ L - - - - - - - - - G l o @@ -14049,15 +9916,6 @@ G - - - - - - - - - C h a @@ -14073,15 +9931,6 @@ E - - - - - - - - - M i x @@ -14097,12 +9946,12 @@ E FM%1 - PV%1 + PV%1 GV%1 - VG%1 + VG%1 @@ -14694,7 +10543,7 @@ E - + ??? @@ -14704,17 +10553,22 @@ E Un - + + Act + + + + ---- - + Telemetry Télémétrie - + SW @@ -14911,400 +10765,166 @@ E TELE - - - Internal - Interne - - - - External - Externe - Setup - - - - - - - Center beep Bip de centrage - - - - - - - OFF - - - - - - - Model Image Image du modèle - - - - - - - Exponential Exponentiel - - - - - - - Throttle Trim Idle Only Trim ralenti uniquement - - - - - - - Timer 3 Chrono 3 - - - - - - - Extra Fine Extra fin - - - - - - - Fine Fin - - - - - - - Medium Moyen - - - - - - - Coarse Grossier - - - - - - - Display Checklist Afficher la checklist - - - - - - - Timer 2 Chrono 2 - - - - - - - Timer 1 Chrono 1 - - - - - - - Never Jamais - - - - - - - On change Au changement - - - - - - - Always Toujours - - - - - - - Global Functions Fonctions globales - - - - - - - Edit Checklist... Éditer Checklist... - - - - - - - Throttle Source Source des gaz - - - - - - - Trim Step Pas des trims - - - - - - - Trims Display Affichage des trims - - - - - - - Warnings Avertissements - - - - - - - Top LCD Timer Chrono LCD supérieur - - - - - - - Switch Warnings Positions des interrupteurs - - - - - - - Pot Warnings Positions des potentiomètres - - - - - - - Manual Manuel - - - - - - - Auto - - - - - - - Model Modèle - - - - - - - Extended Limits Débattements étendus - - - - - - - Extended Trims Trims étendus - - - - - - - Throttle Warning Alerte gaz - - - - - - - Reverse throttle operation. If this is checked the throttle will be reversed. Idle will be forward, trim will also be reversed and the throttle warning will be reversed as well. @@ -15316,13 +10936,6 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo - - - - - - - Reverse Throttle Gaz inversés @@ -15330,22 +10943,22 @@ Si cette option est cochée, la voie des gaz est inversée: le ralenti est &apo SetupPanel - + Timer %1 Chrono %1 - + THR GAZ - + Profile Settings - Réglages du profil + Paramètres du profil - + SD structure path not specified or invalid Chemin de la structure SD non spécifié ou invalide @@ -15695,421 +11308,151 @@ Profil ID: [%1]; Radio ID: [%2] SimulatorMainWindow - - - - - - - - - OpenTx Simulator Simulateur OpenTX - - - - - - - - - View Vue - - - - - - - - - Radio Window Fenêtre radio - - - - - - - - - Reload... Recharger... - - - - - - - - - Tools Outils - - - - - - - - - Toolbar Barre d'outils - - - - - - - - - Reload Lua Scripts Recharger le script Lua - - - - - - - - - Reload the Lua environment on the simulated radio. Recharger l'environnement Lua dans le simulateur. - - - - - - - - - F7 - - - - - - - - - Reload Radio Data Recharger les données radio - - - - - - - - - Reload all radio data without restarting the simulator. Recharger les données radio sans redémarrer le simulateur. - - - - - - - - - F9 - - - - - - - - - Key Mapping Raccourcis clavier - - - - - - - - - Show keyboard maping reference. Afficher les raccourcis clavier. - - - - - - - - - F1 - - - - - - - - - Joystick Settings Paramètres Joystick - - - - - - - - - Open joystick configuration settings dialog. Ouvrir la boite de dialogue de la configuration du Joystick. - - - - - - - - - F3 - - - - - - - - - LCD Screenshot Capture LCD - - - - - - - - - Save a screenshot of the current simulated LCD screen. Enregistrez une capture de l'écran LCD actuellement simulé. - - - - - - - - - F8 - - - - - - - - - Dock In Main Window Ancrer dans la fenêtre principale - - - - - - - - - Show the radio in the main window or as a separate "floating" window. Afficher la radio dans la fenêtre principale ou comme une fenêtre "flottante" séparée. - - - - - - - - - Menu Bar Barre de menus - - - - - - - - - Show or hide the top menu bar. Afficher ou masquer la barre de menus. - - - - - - - - - Alt+M - - - - - - - - - Constrain Width Contraindre la largeur - - - - - - - - - Set radio widget width to be a fixed size. Défini la largeur du widget radio comme étant une taille fixe. - - - - - - - - - Constrain Height Contraindre la hauteur - - - - - - - - - Set radio widget height to be a fixed size. Défini la hauteur du widget radio comme étant une taille fixe. @@ -16190,57 +11533,21 @@ Profil ID: [%1]; Radio ID: [%2] SimulatorStartupDialog - - - - - - - - - OpenTX Simulator - Startup Options Simulateur OpenTX - Options de démarrage - - - - - - - - - Simulator Startup Options: Options de démarrage: - - - - - - - - - Radio Profile: Profil Radio: - - - - - - - - - Existing radio profiles are shown here.<br /> Create or edit profiles using the Companion application. Les profils existants sont affichés ici.<br /> @@ -16248,29 +11555,11 @@ Créer ou éditer les profils avec l'application Companion. - - - - - - - - - Radio Type: Type de Radio: - - - - - - - - - Existing radio simulators are shown here.<br /> The radio type specified in the selected profile is used by default. Les simulateurs radios existants sont affichés ici.<br /> @@ -16278,71 +11567,26 @@ Le type de radio choisi par défaut est celui défini dans le profil selectionn - - - - - - - - - Data Source: Source Données: - - - - - - - - - Data File: Fichier Données: - - - - - - - - - Data Folder: Dossier Données: - - - - - - - - - SD Image Path: Dossier Image SD: - - - - - - - - - Radio data (.bin/.eeprom/.otx) image file to use. A new file with a default image will be created if necessary.<br /> <b>NOTE</b>: any existing EEPROM data incompatible with the selected radio type may be overwritten! Fichier de données utilisé (.bin/.eeprom/.otx).Un nouveau fichier avec une nouvelle image sera créé si nécessaire.<br /> @@ -16350,15 +11594,6 @@ Le type de radio choisi par défaut est celui défini dans le profil selectionn - - - - - - - - - Select data file... Choisir le fichier de données... @@ -16366,47 +11601,11 @@ Le type de radio choisi par défaut est celui défini dans le profil selectionn - - - - - - - - - - - - - - - - - - - - - - - - - - - ... - - - - - - - - - Directory containing RADIO and MODELS folders to use.<br /> New folder(s) with default radio/model will be created here if necessary. Chemin contenant les dossiers RADIO et MODELS à utiliser.<br /> @@ -16414,29 +11613,11 @@ Un (ou plusieurs) dossier peut être créé ici si nécessaire. - - - - - - - - - Select data folder... Sélectionner le dossier de données... - - - - - - - - - Directory containing the SD card image to use.<br/> The default is configured in the chosen Radio Profile. Dossier contenant l'image de la carte SD.<br/> @@ -16444,71 +11625,26 @@ La valeur par défaut est configurée dans le profil radio sélectionné. - - - - - - - - - Select SD card image folder... Choisir le dossier contenant l'image de la carte SD... - - - - - - - - - Select which of the data sources (File/Folder/SD Card) you would like to start the simulator with. Choisir la source (Fichier/Dossier/Image SD) du type de donnée utilisé par le simulateur. - - - - - - - - - File Fichier - - - - - - - - - Folder Dossier - - - - - - - - - SD Path Image SD @@ -16537,15 +11673,6 @@ La valeur par défaut est configurée dans le profil radio sélectionné.SimulatorWidget
- - - - - - - - - Companion Simulator Simulateur Companion @@ -16555,62 +11682,62 @@ La valeur par défaut est configurée dans le profil radio sélectionné.Simulateur Radio (%1) - + Could not determine startup data source. Impossible de déterminer les données source. - + Could not load data, possibly wrong format. Impossible de charger les données, mauvais format. - + Data Load Error Erreur de lecture des données - + Invalid startup data provided. Plese specify a proper file/path. Données de démarrage fournies non valides. Veuillez spécifier un fichier/chemin approprié. - + Simulator Startup Error Erreur de démarrage du simulateur - + Error saving data: could open file for writing: '%1' Erreur de sauvegarde des données: impossible d'écrire le fichier '%1' - + Error saving data: could not get data from simulator interface. Erreur de sauvegarde des données: impossible de récupérer les données depuis l'interface de simulation. - + An unexpected error occurred while attempting to save radio data to file '%1'. Une erreur inattendue s'est produite lors de l'enregistrement des données radio dans le fichier '%1'. - + Data Save Error Erreur de sauvegarde des données - + Cannot open joystick, joystick disabled Impossible d'accéder au Joystick, Joystick désactivé - + Radio firmware error: %1 Erreur firmware radio: %1 - + - Flight Mode %1 (#%2) - Phase de Vol %1 (#%2) @@ -16633,20 +11760,6 @@ La valeur par défaut est configurée dans le profil radio sélectionné. - - - - - - - - - - - - - - ... @@ -16686,13 +11799,6 @@ La valeur par défaut est configurée dans le profil radio sélectionné.StyleEditDialog
- - - - - - - @@ -16701,49 +11807,21 @@ La valeur par défaut est configurée dans le profil radio sélectionné. - - - - - - - &Reset to default - &Réglages par défaut + &Paramètres par défaut - - - - - - - &Cancel &Annuler - - - - - - - &OK - - - - - - - This feature does not validate your changes and assumes you are familiar with CSS syntax for QT. Cet éditeur ne vérifie/valide pas vos modifications. Vous devez connaitre la syntaxe CSS pour QT. @@ -17009,475 +12087,190 @@ Trop d'erreurs, abandon. Telemetry - - - - - - - A1 - - - - - - - A2 - - - - - - - RSSI - - - - - - - Alarm 1 Alarme 1 - - - - - - - - - - - - - - ---- ---- - - - - - - - - - - - - - - Yellow Jaune - - - - - - - - - - - - - - Orange Orange - - - - - - - - - - - - - - Red Rouge - - - - - - - Alarm 2 Alarme 2 - - - - - - - Serial Protocol Protocole Série - - - - - - - Volt source Source de mesure de tension - - - - - - - Current source Source de mesure de courant - - - - - - - Protocol Protocole - - - - - - - None Aucun - - - - - - - FrSky Sensor Hub Sensor Hub FrSky - - - - - - - Blades Pales - - - - - - - Sink Max Chute max - - - - - - - Climb Max Montée max - - - - - - - Sink Min Chute min - - - - - - - Climb Min Montée min - - - - - - - Center Silent Neutre silencieux - - - - - - - Vario source Source vario - - - - - - - Vario limits Limites vario - - - - - - - Disable telemetry audio warnings Désactiver les avertissements audio de la télémétrie - - - - - Source - - - - - - - Altimetry Altitude - - - - - - - Altitude source Source de l'altitude - - - - - - - Volts source Source de la tension - - - - - - - Top Bar Barre de titre de l'écran d'accueil - - - - - - - mAh - - - - - - - A - - - - - - - Various Divers - - - - - - - Sensors Capteurs - - - - - - - Disable multi sensor handling Désactiver la gestion des capteurs multiples - - - - - - - mAh count Valeur enregistrée - - - - - - - FAS Offset Décalage FAS - - - - - - - Persistent mAh Mémorisation des mAh @@ -17486,289 +12279,107 @@ Trop d'erreurs, abandon. TelemetryAnalog - - - - - - - Unit Unité - - - - - - - Max Value Valeur Max - - - - - - - Alarm 1 Alarme 1 - - - - - - - - - - - - - - ---- - - - - - - - - - - - - - - Yellow Jaune - - - - - - - - - - - - - - Orange - - - - - - - - - - - - - - Red Rouge - - - - - - - - - - - - - - < - - - - - - - - - - - - - - > - - - - - - - Alarm 2 Alarme 2 - - - - - - - Offset Décalage - - - - - - - Volts (V) Tension (V) - - - - - - - Amps (A) Courant (A) - - - - - - - Speed (m/s or ft/s) Vitesse (m/s ou ft/s) - - - - - - - Raw (-) Chiffres bruts (-) - - - - - - - Speed (km/h or miles/h) Vitesse (km/h ou miles/h) - - - - - - - Meters (m or ft) Distance (m ou ft) - - - - - - - Temp (°) Température (°) - - - - - - - Fuel (%) Carburant (%) - - - - - - - mAmps (mA) Courant (mA) @@ -17782,13 +12393,6 @@ Trop d'erreurs, abandon. TelemetryCustomScreen - - - - - - - Custom Screen Type Type d'écran personnalisé @@ -17814,49 +12418,21 @@ Trop d'erreurs, abandon. - - - - - - - Min - - - - - - - Source - - - - - - - Gauge Jauge - - - - - - - Max @@ -17864,104 +12440,104 @@ Trop d'erreurs, abandon. TelemetryPanel - + FrSky S.PORT - + FrSky D - + FrSky D (cable) FrSky D (câble) - + Telemetry screen %1 Ecran de télémesure %1 - + Source - + Low Alarm Alarme basse - + Critical Alarm Alarme critique - + Winged Shadow How High - + Winged Shadow How High (not supported) Winged Shadow How High (non supporté) - + Alti Alt - + Alti+ Alt+ - + VSpeed Vitesse verticale - - - + + + A1 - - - + + + A2 - - + + A3 - - + + A4 - - + + FAS - + Cells Velm - + --- @@ -17970,711 +12546,278 @@ Trop d'erreurs, abandon. TelemetrySensor - - - - - - - Form Formulaire - - - - - - - Custom Prédéfini - - - - - - - Calculated Calculé - - - - - - - Id - - - - - - - Instance - - - - Rx - - - - - - Mod. - - - - - - - - - - - + Add Addition - - - - - - - - + Average Moyenne - - - - - - - - + Min - - - - - - - - + Max - - - - - - - - + Multiply Multiplication - - - - - - - - + Totalize Totalisation - - - - - - - - + Cell Element LiPo - - - - - - - - + Consumption Consommation - - - - - - - - + Dist Distance - - - - - - - - + Cells Sensor : Capteur d'éléments: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + --- - - - - - - - - + GPS Sensor : Capteur GPS: - - - - - - - - + Alt. Sensor : Capteur d'altitude: - - - - - - - - + Sensor : Capteur: - - - - - - - - + V - - - - - - - - + A - - - - - - - - + mA - - - - - - - - + kt - - - - - - - - + m/s - - - - - - - - + ft/s - - - - - - - - + km/h - - - - - - - - + mph - - - - - - - - + m - - - - - - - - + ft - - - - - - - - + °C - - - - - - - - + °F - - - - - - - - + % - - - - - - - - + mAh - - - - - - - - + W - - - - - - - - + mW - - - - - - - - + dBm - - - - - - - - + g - - - - - - - - + ° - - - - - - - - + Rad - - - - - - - - + mL - - - - - - - - + US fl.Oz. - - - - - - - - + Raw (-) Chiffres bruts (-) - - - - - - - - + RPM Tours/minute - - - - - - - - + Precision Précision - - - - - - - - + Ratio - - - - - - - - + Blades Pales - - - - - - - - + Offset Décalage - - - - - - - - + Multiplier Multiplicateur - - - - - - - - + Auto Offset Offset auto - - - - - - - - + Filter Filtre - - - - - - - - + Persistent Persistant - - - - - - - - + Positive - - - - - - - - + Logs @@ -18706,281 +12849,101 @@ Trop d'erreurs, abandon. TelemetrySimulator - - - - - - - - - Telemetry Simulator Simulateur de télémesure - - - - - - - - - VFAS - - - - - - - - - RSSI - - - - - - - - - Simulate Simuler - - - - - - - - - Replay SD Log File Rejouer le fichier de Log SD - - - - - - - - - Replay rate Vitesse - - - - - - - - - |> - - - - - - - - - <| - - - - - - - - - > - - - - - - - - - <- - - - - - - - - - X - - - - - - - - - 1/5x - - - - - - - - - 5x - - - - - - - - - No Log File Currently Loaded Pas de fichier de Log chargé - - - - - - - - - Setting RSSI to zero simulates telemetry and radio link loss. Régler le RSSI à zéro simule la perte de liaison radio et de télémétrie. - - - - - - - - - Set RSSI to zero when paused. Régler le RSSI à zéro lors d'une pause. - - - - - - - - - Stop sending telemetry data when the Telemetry Simulator window is hidden. Arrêtez d'envoyer des données de télémétrie lorsque la case est cochée. - - - - - - - - - Pause simulation when hidden. Pause la simulation. - - - - - - - - - Load Charger - - - - - - - - - Row # Timestamp Ligne # @@ -18988,15 +12951,6 @@ Horodatage - - - - - - - - - RxBt @@ -19004,33 +12958,6 @@ Horodatage - - - - - - - - - - - - - - - - - - - - - - - - - - - V / ratio @@ -19048,420 +12975,105 @@ Horodatage - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <html><head/><body><p><br/></p></body></html> - - - - - - - - - - - - - - - - - - Volts - - - - - - - - - Db dB - - - - - - - - - Curr Courant - - - - - - - - - Amps - - - - - - - - - Cels Elément - - - - - - - - - A1 - - - - - - - - - A2 - - - - - - - - - ASpd - - - - - - - - - - - - - - - - - - km/h - - - - - - - - - A3 - - - - - - - - - GAlt - - - - - - - - - - - - - - - - - - Meters Mètres - - - - - - - - - A4 - - - - - - - - - GSpd - - - - - - - - - Tmp1 - - - - - - - - - RAS - - - - - - - - - Hdg - - - - - - - - - Lat,Lon (dec.deg.) - - - - - - - - - dd-MM-yyyy hh:mm:ss jj-MM-aaaa @@ -19469,123 +13081,42 @@ hh:mm:ss - - - - - - - - - Degrees - - - - - - - - - Tmp2 - - - - - - - - - - - - - - - - - - °C - - - - - - - - - Date - - - - - - - - - GPS - - - - - - - - - Fuel Carburant - - - - - - - - - % - - - - - - - - - AccX @@ -19593,169 +13124,52 @@ hh:mm:ss - - - - - - - - - - - - - - - - - - - - - - - - - - - G - - - - - - - - - Fuel Qty Qté Carburant - - - - - - - - - ml - - - - - - - - - AccY - - - - - - - - - VSpd Vitesse Verticale - - - - - - - - - m/s - - - - - - - - - AccZ - - - - - - - - - Alt Altitude - - - - - - - - - - - - - - - - - - RPM - - - - - - - - - When enabled, sends any non-blank values as simulated telemetry data. Transmet les valeurs non vides au simulateur. @@ -19797,25 +13211,11 @@ hh:mm:ss Timer - - - - - - - Countdown Compte à rebours - - - - - - - Minute Call Annonces minutes @@ -19900,61 +13300,26 @@ Utilisez CTRL + le défilement de la souris ou les touches PAGE HAUT/PAGE BAS po Trainer - - - - - - - Form Formulaire - - - - - - - Mode - - - - - - - Input Entrée - - - - - - - Weight Ratio - - - - - - - Rud Dir @@ -19967,62 +13332,6 @@ Utilisez CTRL + le défilement de la souris ou les touches PAGE HAUT/PAGE BAS po - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Beeper volume 0 - Quiet. No beeps at all. @@ -20043,34 +13352,6 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - Off @@ -20079,34 +13360,6 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - += (Sum) += (Additionner) @@ -20115,34 +13368,6 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - := (Replace) := (Remplacer) @@ -20151,34 +13376,6 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - chn1 VOIE1 @@ -20187,34 +13384,6 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - chn2 VOIE2 @@ -20223,34 +13392,6 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - chn3 VOIE3 @@ -20259,70 +13400,21 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - chn4 VOIE4 - - - - - - - Ele Prf - - - - - - - Thr Gaz - - - - - - - Ail @@ -20331,15 +13423,6 @@ Extra long : bips extra longs. TrainerSimulator - - - - - - - - - Trainer simulator Simulateur d'écolage @@ -20637,7 +13720,7 @@ Extra long : bips extra longs. Manually check the direction of each control surface and reverse any channels that make controls move in the wrong direction. Remove the propeller/propellers before you try to control your model for the first time.<br>Please note that continuing removes all old model settings! - Vérifiez manuellement le sens de chaque commande, et inversez les voies de celles qui répondent dans le mauvais sens. Attention à bien enlever les hélices du modèle avant de l'alimenter la première fois !<br>Veuillez noter que tous les réglages existants du modèle courant seront écrasés ! + Vérifiez manuellement le sens de chaque commande, et inversez les voies de celles qui répondent dans le mauvais sens. Attention à bien enlever les hélices du modèle avant de l'alimenter la première fois !<br>Veuillez noter que tous les paramètres existants du modèle courant seront écrasés ! @@ -20765,32 +13848,11 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - Port - - - - - - - List all available programmers. Lister tous les programmateurs supportés. @@ -20799,47 +13861,12 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - - - - - - - - The location of the AVRDUDE executable. The location of the AVRDUDE.EXE executable. Chemin d'accès de l'exécutable AVRDUDE. - - - - - - - DFU-Util Location Chemin de DFU-UTIL @@ -20847,39 +13874,11 @@ Extra long : bips extra longs. - - - - - - - - - - - - - - - - - - - - - Use this button to browse and look for the AVRDUDE executable file. Utiliser ce bouton pour parcourir à la recherche du fichier exécutable AVRDUDE.EXE. - - - - - - - Programmer used for communicating with the controller. Please consult the programmer's documentation and the AVRDUDE documentation to select the appropriate programmer. Programmateur utilisé pour la communication avec le contrôleur. @@ -20887,13 +13886,6 @@ Consulter la documentation du programmateur utilisé et celle d'AVRDUDE pou - - - - - - - Communication port to the programmer. Port de communication pour le programmateur. @@ -20901,73 +13893,31 @@ Consulter la documentation du programmateur utilisé et celle d'AVRDUDE pou - - - - - - - MCU Processeur - - - - - - - at91sam3s8-9xr - - - - - - - Alternate device Dispositif alternatif - - - - - - - Use advanced controls Utiliser les contrôles avancés - - - - - - - Extra Arguments Paramètres supplémentaires - - - - - - - Show Help Aide @@ -20975,27 +13925,6 @@ Consulter la documentation du programmateur utilisé et celle d'AVRDUDE pou - - - - - - - - - - - - - - - - - - - - - Browse... Parcourir... @@ -21033,33 +13962,12 @@ Consulter la documentation du programmateur utilisé et celle d'AVRDUDE pou - - - - - - - List Available Affiche Liste - - - - - - - - - - - - - - Extra arguments used in AVRDUDE. This can be used for providing extra information to AVRDUDE. @@ -21071,37 +13979,16 @@ A n'utiliser qu'en connaissance de cause: il n'y a pas de contrô - - - - - - - AVRDUDE Location Emplacement d'AVRDUDE - - - - - - - Show AVRDUDE help Affiche l'aide d'AVRDUDE - - - - - - - Programmer Configuration Configuration AVRDUDE / SAM-BA Configuration du programmateur @@ -21109,20 +13996,6 @@ A n'utiliser qu'en connaissance de cause: il n'y a pas de contrô - - - - - - - - - - - - - - Extra arguments that will be passed to AVRDUDE on every call Paramètres complémentaires passés à chaque appel d'AVRDUDE @@ -21133,65 +14006,23 @@ A n'utiliser qu'en connaissance de cause: il n'y a pas de contrô - - - - - - - Location of AVRDUDE executable Chemin d'accès de l'exécutable AVRDUDE - - - - - - - Programmer Programmateur - - - - - - - - - - - - - - CPU of your TX CPU de l'émetteur - - - - - - - - - - - - - - CPU present on your 9x radio Should be m64 for stock radios m2560 for v4.1 boards @@ -21199,57 +14030,22 @@ m2560 for v4.1 boards - - - - - - - SAM-BA Location Emplacement de SAM-BA - - - - - - - - - - - - - - Location of sam-ba executable Emplacement de l'exécutable SAM-BA - - - - - - - ARM MCU Processeur ARM - - - - - - - sam-ba serial port Port série de SAM-BA @@ -21258,197 +14054,71 @@ m2560 for v4.1 boards joystickDialog - - - - - - - - - Configure Joystick Configuration du Joystick - - - - - - - - - Ch2 VOIE2 - - - - - - - - - Ch1 VOIE1 - - - - - - - - - Ch4 VOIE4 - - - - - - - - - Ch6 VOIE6 - - - - - - - - - Ch3 VOIE3 - - - - - - - - - Ch5 VOIE5 - - - - - - - - - Ch7 VOIE7 - - - - - - - - - Ch8 VOIE8 - - - - - - - - - Instructions - - - - - - - - - Enable Actif - - - - - - - - - Cancel Annuler - - - - - - - - - Back Précédent - - - - - - - - - Start Démarrer @@ -21459,15 +14129,6 @@ m2560 for v4.1 boards - - - - - - - - - Ok OK diff --git a/launchpad/common/rules b/launchpad/common/rules index 67b06466b..cf96b0fda 100755 --- a/launchpad/common/rules +++ b/launchpad/common/rules @@ -27,6 +27,7 @@ build: cd $(BUILDDIR); cmake $(COMMON_OPTIONS) $(STM32_OPTIONS) -DPCB=X9E ../ ; make libsimulator cd $(BUILDDIR); cmake $(COMMON_OPTIONS) $(STM32_OPTIONS) -DPCB=X12S ../ ; make libsimulator cd $(BUILDDIR); cmake $(COMMON_OPTIONS) $(STM32_OPTIONS) -DPCB=JUMPERT12 ../ ; make libsimulator + cd $(BUILDDIR); cmake $(COMMON_OPTIONS) $(STM32_OPTIONS) -DPCB=JUMPERT16 ../ ; make libsimulator make -C $(BUILDDIR) companion22 simulator22 diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua index 7ac2014b7..3b40fa82b 100644 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua @@ -91,7 +91,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT then selectDevice(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectDevice(-1) end diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua index e6d8e54fe..18b72623c 100644 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/CROSSFIRE/device.lua @@ -455,15 +455,15 @@ local function runDevicePage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT then + if event == EVT_VIRTUAL_INC then incrField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_DEC then incrField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky GaSuite.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky GaSuite.lua index 7613742ef..e0497f00f 100755 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky GaSuite.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky GaSuite.lua @@ -332,15 +332,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -500,7 +500,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_VIRTUAL_PREVIOUS_PAGE then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua index 1310fe95d..15c94c4e6 100644 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SBEC.lua @@ -221,15 +221,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SxR.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SxR.lua index 31c41a7f3..7bbf9a13d 100755 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SxR.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/FrSky SxR.lua @@ -44,8 +44,8 @@ local configFields = { { "Mounting type", COMBO, 0x81, nil, { "Horz", "Horz rev.", "Vert", "Vert rev." } }, } -local wingBitmapsFile = { "bmp/plane.bmp", "bmp/delta.bmp", "bmp/vtail.bmp" } -local mountBitmapsFile = { "bmp/horz.bmp", "bmp/horz-r.bmp", "bmp/vert.bmp", "bmp/vert-r.bmp" } +local wingBitmapsFile = { "/SCRIPTS/TOOLS/bmp/plane.bmp", "/SCRIPTS/TOOLS/bmp/delta.bmp", "/SCRIPTS/TOOLS/bmp/vtail.bmp" } +local mountBitmapsFile = { "/SCRIPTS/TOOLS/bmp/horz.bmp", "/SCRIPTS/TOOLS/bmp/horz-r.bmp", "/SCRIPTS/TOOLS/bmp/vert.bmp", "/SCRIPTS/TOOLS/bmp/vert-r.bmp" } local settingsFields = { {"SxR functions", COMBO, 0x9C, nil, { "Disable", "Enable" } }, @@ -268,15 +268,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -332,8 +332,8 @@ local function init() if LCD_W == 480 then margin = 10 spacing = 20 - wingBitmapsFile = { "img/plane_b.png", "img/delta_b.png", "img/planev_b.png" } - mountBitmapsFile = { "img/up.png", "img/down.png", "img/vert.png", "img/vert-r.png" } + wingBitmapsFile = { "/SCRIPTS/TOOLS/img/plane_b.png", "/SCRIPTS/TOOLS/img/delta_b.png", "/SCRIPTS/TOOLS/img/planev_b.png" } + mountBitmapsFile = { "/SCRIPTS/TOOLS/img/up.png", "/SCRIPTS/TOOLS/img/down.png", "/SCRIPTS/TOOLS/img/vert.png", "/SCRIPTS/TOOLS/img/vert-r.png" } end pages = { runConfigPage, @@ -348,7 +348,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_VIRTUAL_PREVIOUS_PAGE then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/horus/SCRIPTS/TOOLS/crossfire.lua b/radio/sdcard/horus/SCRIPTS/TOOLS/crossfire.lua index de0ec06dc..0f9b1a20f 100644 --- a/radio/sdcard/horus/SCRIPTS/TOOLS/crossfire.lua +++ b/radio/sdcard/horus/SCRIPTS/TOOLS/crossfire.lua @@ -30,7 +30,7 @@ local function run(event) return 2 end - chdir("CROSSFIRE") + chdir("/SCRIPTS/TOOLS/CROSSFIRE") return "crossfire.lua" end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/back.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/back.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/back.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/back.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/delta_b.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/delta_b.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/delta_b.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/delta_b.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/done.bmp b/radio/sdcard/horus/SCRIPTS/TOOLS/img/done.bmp similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/done.bmp rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/done.bmp diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/down.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/down.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/down.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/down.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/forward.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/forward.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/forward.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/forward.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/left.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/left.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/left.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/left.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/plane_b.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/plane_b.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/plane_b.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/plane_b.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/planev_b.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/planev_b.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/planev_b.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/planev_b.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/planev_s.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/planev_s.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/planev_s.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/planev_s.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/right.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/right.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/right.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/right.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/up.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/up.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/up.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/up.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/vert-r.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/vert-r.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/vert-r.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/vert-r.png diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/vert.png b/radio/sdcard/horus/SCRIPTS/TOOLS/img/vert.png similarity index 100% rename from radio/sdcard/taranis-x7/SCRIPTS/TOOLS/img/vert.png rename to radio/sdcard/horus/SCRIPTS/TOOLS/img/vert.png diff --git a/radio/sdcard/horus/THEMES/Darkblue/t16.bmp b/radio/sdcard/horus/THEMES/Darkblue/t16.bmp new file mode 100755 index 000000000..ac0d16cf6 Binary files /dev/null and b/radio/sdcard/horus/THEMES/Darkblue/t16.bmp differ diff --git a/radio/sdcard/horus/THEMES/Default/t16.bmp b/radio/sdcard/horus/THEMES/Default/t16.bmp new file mode 100755 index 000000000..ac0d16cf6 Binary files /dev/null and b/radio/sdcard/horus/THEMES/Default/t16.bmp differ diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua index f68c4db3d..70c125b69 100644 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua @@ -90,7 +90,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT then selectDevice(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectDevice(-1) end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/device.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/device.lua index 289df386b..8ccdbf285 100644 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/device.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/CROSSFIRE/device.lua @@ -452,13 +452,13 @@ local function runDevicePage(event) elseif edit then if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then incrField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_PREV or event == EVT_VIRTUAL_PREV_REPT then incrField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky GaSuite.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky GaSuite.lua index 7613742ef..e0497f00f 100755 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky GaSuite.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky GaSuite.lua @@ -332,15 +332,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -500,7 +500,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_VIRTUAL_PREVIOUS_PAGE then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua index 1310fe95d..15c94c4e6 100644 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SBEC.lua @@ -221,15 +221,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SxR.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SxR.lua index 31c41a7f3..7bbf9a13d 100755 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SxR.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/FrSky SxR.lua @@ -44,8 +44,8 @@ local configFields = { { "Mounting type", COMBO, 0x81, nil, { "Horz", "Horz rev.", "Vert", "Vert rev." } }, } -local wingBitmapsFile = { "bmp/plane.bmp", "bmp/delta.bmp", "bmp/vtail.bmp" } -local mountBitmapsFile = { "bmp/horz.bmp", "bmp/horz-r.bmp", "bmp/vert.bmp", "bmp/vert-r.bmp" } +local wingBitmapsFile = { "/SCRIPTS/TOOLS/bmp/plane.bmp", "/SCRIPTS/TOOLS/bmp/delta.bmp", "/SCRIPTS/TOOLS/bmp/vtail.bmp" } +local mountBitmapsFile = { "/SCRIPTS/TOOLS/bmp/horz.bmp", "/SCRIPTS/TOOLS/bmp/horz-r.bmp", "/SCRIPTS/TOOLS/bmp/vert.bmp", "/SCRIPTS/TOOLS/bmp/vert-r.bmp" } local settingsFields = { {"SxR functions", COMBO, 0x9C, nil, { "Disable", "Enable" } }, @@ -268,15 +268,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -332,8 +332,8 @@ local function init() if LCD_W == 480 then margin = 10 spacing = 20 - wingBitmapsFile = { "img/plane_b.png", "img/delta_b.png", "img/planev_b.png" } - mountBitmapsFile = { "img/up.png", "img/down.png", "img/vert.png", "img/vert-r.png" } + wingBitmapsFile = { "/SCRIPTS/TOOLS/img/plane_b.png", "/SCRIPTS/TOOLS/img/delta_b.png", "/SCRIPTS/TOOLS/img/planev_b.png" } + mountBitmapsFile = { "/SCRIPTS/TOOLS/img/up.png", "/SCRIPTS/TOOLS/img/down.png", "/SCRIPTS/TOOLS/img/vert.png", "/SCRIPTS/TOOLS/img/vert-r.png" } end pages = { runConfigPage, @@ -348,7 +348,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_VIRTUAL_PREVIOUS_PAGE then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/crossfire.lua b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/crossfire.lua index 62ca776d7..debf9056d 100644 --- a/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/crossfire.lua +++ b/radio/sdcard/taranis-x7/SCRIPTS/TOOLS/crossfire.lua @@ -30,7 +30,7 @@ local function run(event) return 2 end - chdir("CROSSFIRE") + chdir("/SCRIPTS/TOOLS/CROSSFIRE") return "crossfire.lua" end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua index f68c4db3d..70c125b69 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/crossfire.lua @@ -90,7 +90,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT then selectDevice(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectDevice(-1) end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/device.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/device.lua index 6f733469a..58416af36 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/device.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/CROSSFIRE/device.lua @@ -450,15 +450,15 @@ local function runDevicePage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then incrField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then incrField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky GaSuite.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky GaSuite.lua index 7613742ef..e0497f00f 100755 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky GaSuite.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky GaSuite.lua @@ -332,15 +332,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -500,7 +500,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_VIRTUAL_PREVIOUS_PAGE then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua index 1310fe95d..15c94c4e6 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SBEC.lua @@ -221,15 +221,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SxR.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SxR.lua index 31c41a7f3..7bbf9a13d 100755 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SxR.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/FrSky SxR.lua @@ -44,8 +44,8 @@ local configFields = { { "Mounting type", COMBO, 0x81, nil, { "Horz", "Horz rev.", "Vert", "Vert rev." } }, } -local wingBitmapsFile = { "bmp/plane.bmp", "bmp/delta.bmp", "bmp/vtail.bmp" } -local mountBitmapsFile = { "bmp/horz.bmp", "bmp/horz-r.bmp", "bmp/vert.bmp", "bmp/vert-r.bmp" } +local wingBitmapsFile = { "/SCRIPTS/TOOLS/bmp/plane.bmp", "/SCRIPTS/TOOLS/bmp/delta.bmp", "/SCRIPTS/TOOLS/bmp/vtail.bmp" } +local mountBitmapsFile = { "/SCRIPTS/TOOLS/bmp/horz.bmp", "/SCRIPTS/TOOLS/bmp/horz-r.bmp", "/SCRIPTS/TOOLS/bmp/vert.bmp", "/SCRIPTS/TOOLS/bmp/vert-r.bmp" } local settingsFields = { {"SxR functions", COMBO, 0x9C, nil, { "Disable", "Enable" } }, @@ -268,15 +268,15 @@ local function runFieldsPage(event) end end elseif edit then - if event == EVT_VIRTUAL_NEXT or event == EVT_VIRTUAL_NEXT_REPT then + if event == EVT_VIRTUAL_INC or event == EVT_VIRTUAL_INC_REPT then addField(1) - elseif event == EVT_VIRTUAL_PREVIOUS or event == EVT_VIRTUAL_PREVIOUS_REPT then + elseif event == EVT_VIRTUAL_DEC or event == EVT_VIRTUAL_DEC_REPT then addField(-1) end else if event == EVT_VIRTUAL_NEXT then selectField(1) - elseif event == EVT_VIRTUAL_PREVIOUS then + elseif event == EVT_VIRTUAL_PREV then selectField(-1) end end @@ -332,8 +332,8 @@ local function init() if LCD_W == 480 then margin = 10 spacing = 20 - wingBitmapsFile = { "img/plane_b.png", "img/delta_b.png", "img/planev_b.png" } - mountBitmapsFile = { "img/up.png", "img/down.png", "img/vert.png", "img/vert-r.png" } + wingBitmapsFile = { "/SCRIPTS/TOOLS/img/plane_b.png", "/SCRIPTS/TOOLS/img/delta_b.png", "/SCRIPTS/TOOLS/img/planev_b.png" } + mountBitmapsFile = { "/SCRIPTS/TOOLS/img/up.png", "/SCRIPTS/TOOLS/img/down.png", "/SCRIPTS/TOOLS/img/vert.png", "/SCRIPTS/TOOLS/img/vert-r.png" } end pages = { runConfigPage, @@ -348,7 +348,7 @@ local function run(event) return 2 elseif event == EVT_VIRTUAL_NEXT_PAGE then selectPage(1) - elseif event == EVT_VIRTUAL_PREVIOUS_PAGE then + elseif event == EVT_VIRTUAL_PREV_PAGE then killEvents(event); selectPage(-1) end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/crossfire.lua b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/crossfire.lua index de0ec06dc..0f9b1a20f 100644 --- a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/crossfire.lua +++ b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/crossfire.lua @@ -30,7 +30,7 @@ local function run(event) return 2 end - chdir("CROSSFIRE") + chdir("/SCRIPTS/TOOLS/CROSSFIRE") return "crossfire.lua" end diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/back.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/back.png deleted file mode 100755 index 2cf3cd699..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/back.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/delta_b.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/delta_b.png deleted file mode 100755 index 80c0302f9..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/delta_b.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/done.bmp b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/done.bmp deleted file mode 100755 index 9ac501398..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/done.bmp and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/down.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/down.png deleted file mode 100755 index 8eac8039a..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/down.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/forward.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/forward.png deleted file mode 100755 index de09680b7..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/forward.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/left.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/left.png deleted file mode 100755 index 658c9916b..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/left.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/plane_b.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/plane_b.png deleted file mode 100755 index 37abedc3a..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/plane_b.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/planev_b.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/planev_b.png deleted file mode 100755 index 4e33f660b..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/planev_b.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/planev_s.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/planev_s.png deleted file mode 100755 index 48283a290..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/planev_s.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/right.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/right.png deleted file mode 100755 index 01d555394..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/right.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/up.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/up.png deleted file mode 100755 index f033aba55..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/up.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/vert-r.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/vert-r.png deleted file mode 100755 index 7bfc9450c..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/vert-r.png and /dev/null differ diff --git a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/vert.png b/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/vert.png deleted file mode 100755 index de09680b7..000000000 Binary files a/radio/sdcard/taranis-x9/SCRIPTS/TOOLS/img/vert.png and /dev/null differ diff --git a/radio/src/CMakeLists.txt b/radio/src/CMakeLists.txt index 275c95988..90e9d578d 100644 --- a/radio/src/CMakeLists.txt +++ b/radio/src/CMakeLists.txt @@ -1,7 +1,7 @@ include(CMakeForceCompiler) include(Bitmaps) -set(PCB_TYPES X9LITE X7 XLITE XLITES X9D X9D+ X9E X10 X12S SKY9X 9XRPRO AR9X NV14) +set(PCB_TYPES X9LITE X9LITES X7 XLITE XLITES X9D X9D+ X9E X10 X12S SKY9X 9XRPRO AR9X NV14) set(RADIO_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU NL CN) set(TTS_LANGUAGES CZ DE EN ES FR IT PT SK SE PL HU NL RU) @@ -84,7 +84,7 @@ if(PCB STREQUAL X12S OR PCB STREQUAL X10) include(targets/horus/CMakeLists.txt) elseif(PCB STREQUAL NV14) include(targets/nv14/CMakeLists.txt) -elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL X9LITE OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES) +elseif(PCB STREQUAL X9E OR PCB STREQUAL X9D+ OR PCB STREQUAL X9D OR PCB STREQUAL X7 OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES) include(targets/taranis/CMakeLists.txt) elseif(PCB STREQUAL SKY9X OR PCB STREQUAL 9XRPRO OR PCB STREQUAL AR9X) include(targets/sky9x/CMakeLists.txt) @@ -333,6 +333,10 @@ if(MODULE_PROTOCOL_D8) add_definitions(-DMODULE_PROTOCOL_D8) endif() +if(JUMPER_RELEASE) + add_definitions(-DJUMPER_RELEASE) +endif() + if(FRSKY_RELEASE) add_definitions(-DFRSKY_RELEASE) set(POPUP_LEVEL 3) @@ -461,6 +465,10 @@ if(NOT MSVC) # these are in addition to CMAKE_CXX_FLAGS set(CMAKE_EXE_LINKER_FLAGS "-lm -T${RADIO_SRC_DIR}/${LINKER_SCRIPT} -Wl,-Map=firmware.map,--cref,--no-warn-mismatch,--gc-sections") + if(ACCESS_LIB) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--whole-archive ${RADIO_SRC_DIRECTORY}/${THIRDPARTY_DIR}/libACCESS/libAccess.a -Wl,--no-whole-archive") + endif() + if(SEMIHOSTING) add_definitions(-DSEMIHOSTING) set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --specs=rdimon.specs") @@ -478,7 +486,7 @@ if(NOT MSVC) set(SRC ${SRC} bin_allocator.cpp) endif() - if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR PCB STREQUAL X9D OR PCB STREQUAL X9D+ OR PCB STREQUAL X9E OR PCB STREQUAL X9LITE OR PCB STREQUAL X7 OR PCB STREQUAL X3 OR PCB STREQUAL X10 OR PCB STREQUAL X12S) + if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR PCB STREQUAL X9D OR PCB STREQUAL X9D+ OR PCB STREQUAL X9E OR PCB STREQUAL X9LITE OR PCB STREQUAL X7 OR PCB STREQUAL X3 OR PCB STREQUAL X9LITES OR PCB STREQUAL X10 OR PCB STREQUAL X12S) add_subdirectory(targets/common/arm/stm32/bootloader) include_directories(${CMAKE_CURRENT_BINARY_DIR}/targets/common/arm/stm32/bootloader) set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} bootloader) diff --git a/radio/src/audio.cpp b/radio/src/audio.cpp index 7403d52b9..9d451c01f 100644 --- a/radio/src/audio.cpp +++ b/radio/src/audio.cpp @@ -755,7 +755,7 @@ void AudioQueue::wakeup() DEBUG_TIMER_STOP(debugTimerAudioConsume); AudioBuffer * buffer; - while ((buffer = buffersFifo.getEmptyBuffer()) != 0) { + while ((buffer = buffersFifo.getEmptyBuffer()) != nullptr) { int result; unsigned int fade = 0; int size = 0; diff --git a/radio/src/bluetooth.cpp b/radio/src/bluetooth.cpp index 9de8bc403..40af04537 100644 --- a/radio/src/bluetooth.cpp +++ b/radio/src/bluetooth.cpp @@ -73,7 +73,7 @@ char * Bluetooth::readline(bool error_reset) { uint8_t byte; - while (1) { + while (true) { if (!btRxFifo.pop(byte)) { #if defined(PCBX9E) // X9E BT module can get unresponsive @@ -280,7 +280,7 @@ void Bluetooth::receiveTrainer() { uint8_t byte; - while (1) { + while (true) { if (!btRxFifo.pop(byte)) { return; } @@ -451,9 +451,11 @@ void Bluetooth::wakeup() ++reusableBuffer.moduleSetup.bt.devicesCount; } } - /* else if (state == BLUETOOTH_STATE_DISCOVER_START && !strcmp(line, "OK+DISCE")) { +#if defined(PCBHORUS) + else if (state == BLUETOOTH_STATE_DISCOVER_START && !strcmp(line, "OK+DISCE")) { state = BLUETOOTH_STATE_DISCOVER_END; - } */ + } +#endif else if (state == BLUETOOTH_STATE_CLEAR_REQUESTED) { char command[] = "AT+CLEAR"; writeString(command); diff --git a/radio/src/dataconstants.h b/radio/src/dataconstants.h index 16d459b06..0ebf0cd3a 100644 --- a/radio/src/dataconstants.h +++ b/radio/src/dataconstants.h @@ -197,6 +197,7 @@ enum TrainerMode { TRAINER_MODE_MASTER_BLUETOOTH, TRAINER_MODE_SLAVE_BLUETOOTH, #endif + TRAINER_MODE_MULTI, }; #elif defined(PCBSKY9X) enum ModuleIndex { @@ -206,22 +207,32 @@ enum TrainerMode { }; #endif -#if defined(BLUETOOTH) +#if defined(MULTIMODULE) + #define TRAINER_MODE_MAX() TRAINER_MODE_MULTI +#elif defined(BLUETOOTH) #define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE_BLUETOOTH +#elif defined(RADIO_T16) + #define TRAINER_MODE_MAX() TRAINER_MODE_SLAVE #elif defined(PCBX7) || defined(PCBXLITE) #define TRAINER_MODE_MAX() TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE #else #define TRAINER_MODE_MAX() HAS_WIRELESS_TRAINER_HARDWARE() ? TRAINER_MODE_MASTER_BATTERY_COMPARTMENT : TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE #endif -#if defined(PCBFRSKY) || defined(PCBNV14) +#if defined(HARDWARE_INTERNAL_MODULE) #define IS_INTERNAL_MODULE_ENABLED() (g_model.moduleData[INTERNAL_MODULE].type != MODULE_TYPE_NONE) -#elif defined(PCBSKY9X) +#else #define IS_INTERNAL_MODULE_ENABLED() (false) #endif #define IS_EXTERNAL_MODULE_ENABLED() (g_model.moduleData[EXTERNAL_MODULE].type != MODULE_TYPE_NONE) +#if defined(HARDWARE_INTERNAL_MODULE) + #define IS_MODULE_ENABLED(moduleIdx) (moduleIdx==INTERNAL_MODULE ? IS_INTERNAL_MODULE_ENABLED() : moduleIdx==EXTERNAL_MODULE ? IS_EXTERNAL_MODULE_ENABLED() : false) +#else + #define IS_MODULE_ENABLED(moduleIdx) (moduleIdx==EXTERNAL_MODULE ? IS_EXTERNAL_MODULE_ENABLED() : false) +#endif + enum UartModes { #if defined(CLI) || defined(DEBUG) UART_MODE_DEBUG, @@ -256,6 +267,7 @@ enum TelemetryProtocol PROTOCOL_TELEMETRY_CROSSFIRE, PROTOCOL_TELEMETRY_SPEKTRUM, PROTOCOL_TELEMETRY_FLYSKY_IBUS, + PROTOCOL_TELEMETRY_HITEC, PROTOCOL_TELEMETRY_MULTIMODULE, PROTOCOL_TELEMETRY_LAST=PROTOCOL_TELEMETRY_MULTIMODULE, PROTOCOL_TELEMETRY_LUA @@ -334,17 +346,17 @@ enum TelemetryUnit { enum TelemetryScreenType { TELEMETRY_SCREEN_TYPE_NONE, TELEMETRY_SCREEN_TYPE_VALUES, - TELEMETRY_SCREEN_TYPE_GAUGES, -#if defined(LUA) + TELEMETRY_SCREEN_TYPE_BARS, TELEMETRY_SCREEN_TYPE_SCRIPT, +#if defined(LUA) TELEMETRY_SCREEN_TYPE_MAX = TELEMETRY_SCREEN_TYPE_SCRIPT #else - TELEMETRY_SCREEN_TYPE_MAX = TELEMETRY_SCREEN_TYPE_GAUGES + TELEMETRY_SCREEN_TYPE_MAX = TELEMETRY_SCREEN_TYPE_BARS #endif }; #define MAX_TELEMETRY_SCREENS 4 #define TELEMETRY_SCREEN_TYPE(screenIndex) TelemetryScreenType((g_model.screensType >> (2*(screenIndex))) & 0x03) -#define IS_BARS_SCREEN(screenIndex) (TELEMETRY_SCREEN_TYPE(screenIndex) == TELEMETRY_SCREEN_TYPE_GAUGES) +#define IS_BARS_SCREEN(screenIndex) (TELEMETRY_SCREEN_TYPE(screenIndex) == TELEMETRY_SCREEN_TYPE_BARS) constexpr int16_t FAILSAFE_CHANNEL_HOLD = 2000; constexpr int16_t FAILSAFE_CHANNEL_NOPULSE = 2001; @@ -795,7 +807,7 @@ static_assert(MIXSRC_FIRST_LOGICAL_SWITCH == MIXSRC_FIRST_SWITCH + STORAGE_NUM_S #define MIXSRC_FIRST (MIXSRC_NONE + 1) #define MIXSRC_LAST MIXSRC_LAST_CH -#define MIXSRC_LAST_SWITCH (MIXSRC_FIRST_SWITCH + NUM_SWITCHES - 1) +#define MIXSRC_LAST_SWITCH (MIXSRC_FIRST_SWITCH + STORAGE_NUM_SWITCHES - 1) #define INPUTSRC_FIRST MIXSRC_Rud #define INPUTSRC_LAST MIXSRC_LAST_TELEM diff --git a/radio/src/datastructs.h b/radio/src/datastructs.h index 4009139db..18b3aeec3 100644 --- a/radio/src/datastructs.h +++ b/radio/src/datastructs.h @@ -698,7 +698,7 @@ PACK(struct TrainerData { swarnstate_t switchUnlockStates; \ swconfig_t switchConfig; \ char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME]; \ - char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME]; \ + char anaNames[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS][LEN_ANA_NAME]; \ BLUETOOTH_FIELDS #elif defined(PCBSKY9X) #define EXTRA_GENERAL_FIELDS \ @@ -711,7 +711,7 @@ PACK(struct TrainerData { uint8_t sticksGain; \ uint8_t rotarySteps; \ char switchNames[STORAGE_NUM_SWITCHES][LEN_SWITCH_NAME]; \ - char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME]; + char anaNames[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS][LEN_ANA_NAME]; #else #define EXTRA_GENERAL_FIELDS #endif @@ -743,7 +743,8 @@ PACK(struct RadioData { NOBACKUP(int8_t txVoltageCalibration); uint8_t backlightMode:3; int8_t antennaMode:2; - int8_t spare1:3; + uint8_t disableRtcWarning:1; + int8_t spare1:2; NOBACKUP(TrainerData trainer); NOBACKUP(uint8_t view); // index of view in main screen NOBACKUP(BUZZER_FIELD); /* 2bits */ diff --git a/radio/src/fifo.h b/radio/src/fifo.h index 35daef7ef..9aff60f57 100644 --- a/radio/src/fifo.h +++ b/radio/src/fifo.h @@ -77,11 +77,6 @@ class Fifo return (next == ridx); } - void flush() - { - while (!isEmpty()); - } - uint32_t size() const { return (N + widx - ridx) & (N - 1); diff --git a/radio/src/functions.cpp b/radio/src/functions.cpp index 3bb18805c..59df7764f 100644 --- a/radio/src/functions.cpp +++ b/radio/src/functions.cpp @@ -165,11 +165,13 @@ void evalFunctions(const CustomFunctionData * functions, CustomFunctionsContext case FUNC_TRAINER: { - uint8_t mask = 0x0f; - if (CFN_CH_INDEX(cfn) > 0) { - mask = (1<<(CFN_CH_INDEX(cfn)-1)); - } - newActiveFunctions |= mask; + uint8_t param = CFN_CH_INDEX(cfn); + if (param == 0) + newActiveFunctions |= 0x0F; + else if (param <= NUM_STICKS) + newActiveFunctions |= (1 << (param-1)); + else if (param == NUM_STICKS + 1) + newActiveFunctions |= (1 << FUNCTION_TRAINER_CHANNELS); break; } diff --git a/radio/src/gui/128x64/gui.h b/radio/src/gui/128x64/gui.h index 11e526412..c972d8ec4 100644 --- a/radio/src/gui/128x64/gui.h +++ b/radio/src/gui/128x64/gui.h @@ -244,7 +244,6 @@ void readModelNotes(); #define IS_ROTARY_EVENT(evt) (EVT_KEY_MASK(evt) >= 0x0e) void repeatLastCursorMove(event_t event); #define REPEAT_LAST_CURSOR_MOVE() { if (EVT_KEY_MASK(event) >= 0x0e) putEvent(event); else repeatLastCursorMove(event); } - #define MOVE_CURSOR_FROM_HERE() if (menuHorizontalPosition > 0) REPEAT_LAST_CURSOR_MOVE() #else #define IS_ROTARY_LEFT(evt) (0) #define IS_ROTARY_RIGHT(evt) (0) @@ -253,7 +252,6 @@ void readModelNotes(); #define IS_ROTARY_EVENT(evt) (0) void repeatLastCursorMove(event_t event); #define REPEAT_LAST_CURSOR_MOVE() repeatLastCursorMove(event) - #define MOVE_CURSOR_FROM_HERE() if (menuHorizontalPosition > 0) REPEAT_LAST_CURSOR_MOVE() #endif // TODO enum diff --git a/radio/src/gui/128x64/lcd.cpp b/radio/src/gui/128x64/lcd.cpp index 8b4241e68..31038f07f 100644 --- a/radio/src/gui/128x64/lcd.cpp +++ b/radio/src/gui/128x64/lcd.cpp @@ -777,10 +777,12 @@ void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att) } } -void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags) +void drawSwitch(coord_t x, coord_t y, swsrc_t idx, LcdFlags flags, bool autoBold) { char s[8]; getSwitchPositionName(s, idx); + if (autoBold && idx != SWSRC_NONE && getSwitch(idx)) + flags |= BOLD; lcdDrawText(x, y, s, flags); } diff --git a/radio/src/gui/128x64/lcd.h b/radio/src/gui/128x64/lcd.h index 9d0993676..1161e78d5 100644 --- a/radio/src/gui/128x64/lcd.h +++ b/radio/src/gui/128x64/lcd.h @@ -119,7 +119,7 @@ void lcdDraw8bitsNumber(coord_t x, coord_t y, int8_t val); void drawModelName(coord_t x, coord_t y, char * name, uint8_t id, LcdFlags att); #if !defined(BOOT) // TODO not here ... -void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags att=0); +void drawSwitch(coord_t x, coord_t y, swsrc_t swtch, LcdFlags att=0, bool autoBold = true); void drawSource(coord_t x, coord_t y, mixsrc_t idx, LcdFlags att=0); #endif void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); diff --git a/radio/src/gui/128x64/menus.h b/radio/src/gui/128x64/menus.h index 4f1428a6f..ccde94cc9 100644 --- a/radio/src/gui/128x64/menus.h +++ b/radio/src/gui/128x64/menus.h @@ -52,7 +52,7 @@ enum MenuRadioIndexes { MENU_RADIO_SETUP, CASE_SDCARD(MENU_RADIO_SD_MANAGER) -#if defined(LUA) || defined(PXX2) +#if defined(LUA) || defined(PXX2) || defined(MULTIMODULE) MENU_RADIO_TOOLS, #endif MENU_RADIO_SPECIAL_FUNCTIONS, @@ -78,7 +78,7 @@ void menuRadioCalibration(event_t event); static const MenuHandlerFunc menuTabGeneral[MENU_RADIO_PAGES_COUNT] = { menuRadioSetup, CASE_SDCARD(menuRadioSdManager) -#if defined(LUA) || defined(PXX2) +#if defined(LUA) || defined(PXX2) || defined(MULTIMODULE) menuRadioTools, #endif menuRadioSpecialFunctions, diff --git a/radio/src/gui/128x64/model_display.cpp b/radio/src/gui/128x64/model_display.cpp index b9fe1b662..f138593e0 100644 --- a/radio/src/gui/128x64/model_display.cpp +++ b/radio/src/gui/128x64/model_display.cpp @@ -52,21 +52,44 @@ enum MenuModelDisplayItems { #endif #define DISPLAY_COL3 (17*FW+2) -#if defined(LUA) - #define SCREEN_TYPE_ROWS 1 - #define DISPLAY_LINE_ROWS(x) ((TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE || TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_SCRIPT) ? HIDDEN_ROW : (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_GAUGES ? (uint8_t)2 : (uint8_t)1)) -#else - #define SCREEN_TYPE_ROWS 0 - #define DISPLAY_LINE_ROWS(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_GAUGES ? (uint8_t)2 : (uint8_t)1)) -#endif - -#define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x) -#define TELEMETRY_CURRENT_SCREEN(k) (k < ITEM_DISPLAY_SCREEN_LABEL2 ? 0 : (k < ITEM_DISPLAY_SCREEN_LABEL3 ? 1 : (k < ITEM_DISPLAY_SCREEN_LABEL4 ? 2 : 3))) - -#if defined(LUA) -void onTelemetryScriptFileSelectionMenu(const char *result) +inline uint8_t SCREEN_TYPE_COLUMNS(uint8_t screenIndex) { - int screenIndex = TELEMETRY_CURRENT_SCREEN(menuVerticalPosition - HEADER_LINE); + if (TELEMETRY_SCREEN_TYPE(screenIndex) == TELEMETRY_SCREEN_TYPE_SCRIPT) + return 1; + else + return 0; +} + +inline uint8_t SCREEN_LINE_COLUMNS(uint8_t screenIndex, uint8_t lineIndex) +{ + switch (TELEMETRY_SCREEN_TYPE(screenIndex)) { + case TELEMETRY_SCREEN_TYPE_VALUES: + return 1; + case TELEMETRY_SCREEN_TYPE_BARS: + return g_model.screens[screenIndex].bars[lineIndex].source ? 2 : 0; + default: + return HIDDEN_ROW; + } +} + +#define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_COLUMNS(x), SCREEN_LINE_COLUMNS(x, 0), SCREEN_LINE_COLUMNS(x, 1), SCREEN_LINE_COLUMNS(x, 2), SCREEN_LINE_COLUMNS(x, 3) + +inline uint8_t DISPLAY_CURRENT_SCREEN(uint8_t line) +{ + if (line < ITEM_DISPLAY_SCREEN_LABEL2) + return 0; + else if (line < ITEM_DISPLAY_SCREEN_LABEL3) + return 1; + else if (line < ITEM_DISPLAY_SCREEN_LABEL4) + return 2; + else + return 3; +} + +#if defined(LUA) +void onTelemetryScriptFileSelectionMenu(const char * result) +{ + int screenIndex = DISPLAY_CURRENT_SCREEN(menuVerticalPosition - HEADER_LINE); if (result == STR_UPDATE_LIST) { if (!sdListFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.screens[screenIndex].script.file), NULL)) { @@ -82,7 +105,6 @@ void onTelemetryScriptFileSelectionMenu(const char *result) } #endif - int skipHiddenLines(int noRows, const uint8_t * mstate_tab, int row) { for(int i=0; i0) { switch (menuHorizontalPosition) { case 0: diff --git a/radio/src/gui/128x64/model_input_edit.cpp b/radio/src/gui/128x64/model_input_edit.cpp index 6a45d7e10..4f718a674 100644 --- a/radio/src/gui/128x64/model_input_edit.cpp +++ b/radio/src/gui/128x64/model_input_edit.cpp @@ -102,7 +102,7 @@ void menuModelExpoOne(event_t event) case EXPO_FIELD_SOURCE: lcdDrawTextAlignedLeft(y, STR_SOURCE); drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, RIGHT|STREXPANDED|attr); - if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); + if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailableInInputs); break; case EXPO_FIELD_SCALE: diff --git a/radio/src/gui/128x64/model_setup.cpp b/radio/src/gui/128x64/model_setup.cpp index 1f7f212d5..e1d9d26a9 100644 --- a/radio/src/gui/128x64/model_setup.cpp +++ b/radio/src/gui/128x64/model_setup.cpp @@ -179,9 +179,6 @@ enum MenuModelSetupItems { #define SW_WARN_ROWS uint8_t(NAVIGATION_LINE_BY_LINE|(getSwitchWarningsCount()-1)), uint8_t(getSwitchWarningsCount() > MAX_SWITCH_PER_LINE ? TITLE_ROW : HIDDEN_ROW) #endif -#define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW) -#define IF_EXTERNAL_MODULE_ON(x) (IS_EXTERNAL_MODULE_ENABLED()? (uint8_t)(x) : HIDDEN_ROW) - #if defined(INTERNAL_MODULE_PXX1) #define INTERNAL_MODULE_TYPE_ROWS ((isModuleXJT(INTERNAL_MODULE) || isModulePXX2(INTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0) // Module type + RF protocols #else @@ -194,8 +191,6 @@ enum MenuModelSetupItems { #define OUTPUT_TYPE_ROW #endif -#define PORT_CHANNELS_ROWS(x) (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 0) - inline uint8_t EXTERNAL_MODULE_TYPE_ROW() { if (isModuleXJT(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE)) @@ -213,7 +208,7 @@ inline uint8_t EXTERNAL_MODULE_TYPE_ROW() #define TIMER_ROWS 1, 0, 1, 0, 0, 0 #if defined(PCBSKY9X) - #define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2, + #define EXTRA_MODULE_ROWS LABEL(ExtraModule), 1, 2, #else #define EXTRA_MODULE_ROWS #endif @@ -286,7 +281,7 @@ void onBluetoothConnectMenu(const char * result) #define INTERNAL_MODULE_ROWS \ LABEL(InternalModule), \ INTERNAL_MODULE_TYPE_ROWS, \ - INTERNAL_MODULE_CHANNELS_ROWS, \ + MODULE_CHANNELS_ROWS(INTERNAL_MODULE), \ IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(isModuleRxNumAvailable(INTERNAL_MODULE) ? (uint8_t)2 : (uint8_t)1)), \ IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), /* RxNum */ \ EXTERNAL_ANTENNA_ROW \ @@ -337,13 +332,13 @@ void menuModelSetup(event_t event) LABEL(ExternalModule), EXTERNAL_MODULE_TYPE_ROW(), MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) - EXTERNAL_MODULE_POWER_ROW, - MULTIMODULE_STATUS_ROWS - EXTERNAL_MODULE_CHANNELS_ROWS, - IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS), // line reused for PPM: PPM settings + MODULE_POWER_ROW(EXTERNAL_MODULE), + MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) + MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), + IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // line reused for PPM: PPM settings IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum - IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, EXTERNAL_MODULE_OPTION_ROW), - MULTIMODULE_MODULE_ROWS + IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)), + MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE) FAILSAFE_ROWS(EXTERNAL_MODULE), IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options @@ -354,18 +349,46 @@ void menuModelSetup(event_t event) TRAINER_ROWS }); #else - MENU_TAB({ HEADER_LINE_COLUMNS 0, TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, 0, 0, 0, LABEL(PreflightCheck), 0, 0, NUM_SWITCHES-1, NUM_STICKS+NUM_POTS+NUM_SLIDERS-1, 0, + MENU_TAB({ + HEADER_LINE_COLUMNS + 0, + TIMER_ROWS, + TIMER_ROWS, + TIMER_ROWS, + 0, // Extended limits + 1, // Extended trims + 0, // Show trims + 0, // Trims step + 0, // Throttle reverse + 0, // Throttle trace source + 0, // Throttle trim + + LABEL(PreflightCheck), + 0, // Checklist + 0, // Throttle warning + NUM_SWITCHES-1, // Switch warning + + NUM_STICKS+NUM_POTS+NUM_SLIDERS-1, // Center beeps + 0, // Global functions + LABEL(ExternalModule), - EXTERNAL_MODULE_TYPE_ROW(), - MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) - MULTIMODULE_STATUS_ROWS - EXTERNAL_MODULE_CHANNELS_ROWS, - EXTERNAL_MODULE_BIND_ROWS, - OUTPUT_TYPE_ROW - EXTERNAL_MODULE_OPTION_ROW, - MULTIMODULE_MODULE_ROWS - EXTERNAL_MODULE_POWER_ROW, - FAILSAFE_ROWS(EXTERNAL_MODULE), + EXTERNAL_MODULE_TYPE_ROW(), + MULTIMODULE_SUBTYPE_ROWS(EXTERNAL_MODULE) + MODULE_POWER_ROW(EXTERNAL_MODULE), + MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) + MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), + IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), // line reused for PPM: PPM settings + OUTPUT_TYPE_ROW + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum + IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)), + MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE) + FAILSAFE_ROWS(EXTERNAL_MODULE), + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons + IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 1 + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 2 + IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // Receiver 3 + EXTRA_MODULE_ROWS TRAINER_ROWS }); @@ -377,6 +400,8 @@ void menuModelSetup(event_t event) if (event == EVT_ENTRY || event == EVT_ENTRY_UP) { memclear(&reusableBuffer.moduleSetup, sizeof(reusableBuffer.moduleSetup)); reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; + reusableBuffer.moduleSetup.previousType = g_model.moduleData[EXTERNAL_MODULE].type; + reusableBuffer.moduleSetup.newType = g_model.moduleData[EXTERNAL_MODULE].type; #if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA) reusableBuffer.moduleSetup.antennaMode = g_model.moduleData[INTERNAL_MODULE].pxx.antennaMode; #endif @@ -621,7 +646,7 @@ void menuModelSetup(event_t event) } int current = 0; - for (int i = 0; i < switchWarningsCount; i++) { + for (int i = 0; i < NUM_SWITCHES; i++) { if (SWITCH_WARNING_ALLOWED(i)) { div_t qr = div(current, MAX_SWITCH_PER_LINE); if (!READ_ONLY() && event==EVT_KEY_BREAK(KEY_ENTER) && attr && l_posHorz == current && old_posHorz >= 0) { @@ -837,7 +862,7 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE: lcdDrawTextAlignedLeft(y, INDENT TR_MODE); - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, reusableBuffer.moduleSetup.newType, menuHorizontalPosition==0 ? attr : 0); if (isModuleXJT(EXTERNAL_MODULE)) lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_XJT_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); else if (isModuleDSM2(EXTERNAL_MODULE)) @@ -853,17 +878,25 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_MULTI_PROTOCOLS, multi_rfProto, menuHorizontalPosition==1 ? attr : 0); } #endif + if (attr && menuHorizontalPosition == 0) { + if (s_editMode > 0) { + g_model.moduleData[EXTERNAL_MODULE].type = MODULE_TYPE_NONE; + } + else if (reusableBuffer.moduleSetup.newType != reusableBuffer.moduleSetup.previousType) { + g_model.moduleData[EXTERNAL_MODULE].type = reusableBuffer.moduleSetup.newType; + reusableBuffer.moduleSetup.previousType = reusableBuffer.moduleSetup.newType; + setModuleType(EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].type); + } + else if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE) { + g_model.moduleData[EXTERNAL_MODULE].type = reusableBuffer.moduleSetup.newType; + } + } if (attr) { if (s_editMode > 0) { switch (menuHorizontalPosition) { case 0: - { - uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable); - if (checkIncDec_Ret) { - setModuleType(EXTERNAL_MODULE, moduleType); - } - } - break; + reusableBuffer.moduleSetup.newType = checkIncDec(event, reusableBuffer.moduleSetup.newType, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable); + break; case 1: if (isModuleDSM2(EXTERNAL_MODULE)) { @@ -886,7 +919,7 @@ void menuModelSetup(event_t event) #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MODULE_SUBTYPE_MULTI_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); - CHECK_INCDEC_MODELVAR(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST); + CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST, isMultiProtocolSelectable); if (checkIncDec_Ret) { g_model.moduleData[EXTERNAL_MODULE].multi.customProto = (multiRfProto == MODULE_SUBTYPE_MULTI_CUSTOM); if (!g_model.moduleData[EXTERNAL_MODULE].multi.customProto) @@ -1020,7 +1053,7 @@ void menuModelSetup(event_t event) } if (bluetooth.state == BLUETOOTH_STATE_DISCOVER_START && reusableBuffer.moduleSetup.bt.devicesCount > 0) { - popupMenuItemsCount = min(reusableBuffer.moduleSetup.bt.devicesCount, 6); + popupMenuItemsCount = min(reusableBuffer.moduleSetup.bt.devicesCount, MAX_BLUETOOTH_DISTANT_ADDR); for (uint8_t i=0; i= 0) { - lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CH, menuHorizontalPosition==0 ? attr : 0); - lcdDrawNumber(lcdLastRightPos, y, moduleData.channelsStart+1, LEFT | (menuHorizontalPosition==0 ? attr : 0)); - lcdDrawChar(lcdLastRightPos, y, '-'); - lcdDrawNumber(lcdLastRightPos + FW+1, y, moduleData.channelsStart+sentModuleChannels(moduleIdx), LEFT | (menuHorizontalPosition==1 ? attr : 0)); - const char * delay = getModuleDelay(moduleIdx); - if (delay) - lcdDrawText(lcdLastRightPos+4, y, delay, SMLSIZE); - if (attr && s_editMode > 0) { - switch (menuHorizontalPosition) { - case 0: - CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); - break; - case 1: - CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); - if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) { - setDefaultPpmFrameLength(moduleIdx); - } - break; - } + lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CH, menuHorizontalPosition==0 ? attr : 0); + lcdDrawNumber(lcdLastRightPos, y, moduleData.channelsStart+1, LEFT | (menuHorizontalPosition==0 ? attr : 0)); + lcdDrawChar(lcdLastRightPos, y, '-'); + lcdDrawNumber(lcdLastRightPos + FW+1, y, moduleData.channelsStart+sentModuleChannels(moduleIdx), LEFT | (menuHorizontalPosition==1 ? attr : 0)); + const char * delay = getModuleDelay(moduleIdx); + if (delay) + lcdDrawText(lcdLastRightPos+4, y, delay, SMLSIZE); + if (attr && s_editMode > 0) { + switch (menuHorizontalPosition) { + case 0: + CHECK_INCDEC_MODELVAR_ZERO(event, moduleData.channelsStart, 32-8-moduleData.channelsCount); + break; + case 1: + CHECK_INCDEC_MODELVAR_CHECK(event, moduleData.channelsCount, -4, min(maxModuleChannels_M8(moduleIdx), 32-8-moduleData.channelsStart), moduleData.type == MODULE_TYPE_ISRM_PXX2 ? isPxx2IsrmChannelsCountAllowed : nullptr); + if (checkIncDec_Ret && moduleData.type == MODULE_TYPE_PPM) { + setDefaultPpmFrameLength(moduleIdx); + } + break; } } break; @@ -1193,12 +1224,10 @@ void menuModelSetup(event_t event) #if defined(PCBSKY9X) case ITEM_MODEL_SETUP_EXTRA_MODULE_BIND: #endif -#if defined(PCBTARANIS) #if defined(HARDWARE_INTERNAL_MODULE) case ITEM_MODEL_SETUP_INTERNAL_MODULE_NOT_ACCESS_BIND: #endif case ITEM_MODEL_SETUP_EXTERNAL_MODULE_NOT_ACCESS_BIND: -#endif { uint8_t moduleIdx = CURRENT_MODULE_EDITED(k); ModuleData & moduleData = g_model.moduleData[moduleIdx]; @@ -1274,8 +1303,8 @@ void menuModelSetup(event_t event) lcdDrawText(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0); uint8_t newFlag = 0; #if defined(MULTIMODULE) - if (multiBindStatus == MULTI_BIND_FINISHED) { - multiBindStatus = MULTI_NORMAL_OPERATION; + if (getMultiBindStatus(moduleIdx) == MULTI_BIND_FINISHED) { + setMultiBindStatus(moduleIdx, MULTI_NORMAL_OPERATION); s_editMode = 0; } #endif @@ -1286,7 +1315,7 @@ void menuModelSetup(event_t event) if (isModuleR9MNonAccess(moduleIdx) || isModuleD16(moduleIdx)) { #if defined(PCBXLITE) if (EVT_KEY_MASK(event) == KEY_ENTER) { -#elif defined(PCBSKY9X) || defined(PCBAR9X) +#elif defined(NAVIGATION_9X) if (event == EVT_KEY_FIRST(KEY_ENTER)) { #else if (event == EVT_KEY_BREAK(KEY_ENTER)) { @@ -1325,7 +1354,7 @@ void menuModelSetup(event_t event) #if defined(MULTIMODULE) if (newFlag == MODULE_MODE_BIND) { - multiBindStatus = MULTI_BIND_INITIATED; + setMultiBindStatus(moduleIdx, MULTI_BIND_INITIATED); } #endif @@ -1431,6 +1460,11 @@ void menuModelSetup(event_t event) } else { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127); + if (pdef->optionsstr == STR_MULTI_RFTUNE) { + lcdDrawText(MODEL_SETUP_2ND_COLUMN + 23, y, "RSSI(", LEFT); + lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); + lcdDrawText(lcdLastRightPos, y, ")", LEFT); + } } } } @@ -1469,7 +1503,7 @@ void menuModelSetup(event_t event) lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_R9M_FCC_POWER_VALUES, module.pxx.power, LEFT | attr); if (attr) { CHECK_INCDEC_MODELVAR_ZERO(event, module.pxx.power, R9M_FCC_POWER_MAX); - if (s_editMode == 0 && reusableBuffer.moduleSetup.r9mPower != module.pxx.power) { + if (s_editMode == 0 && reusableBuffer.moduleSetup.r9mPower != module.pxx.power && module.channelsCount > maxModuleChannels_M8(moduleIdx)) { module.channelsStart = 0; module.channelsCount = maxModuleChannels_M8(moduleIdx); } @@ -1486,7 +1520,8 @@ void menuModelSetup(event_t event) CHECK_INCDEC_MODELVAR_ZERO(event, module.pxx.power, R9M_LITE_LBT_POWER_MAX); if (s_editMode == 0 && reusableBuffer.moduleSetup.r9mPower != module.pxx.power) { module.channelsStart = 0; - module.channelsCount = maxModuleChannels_M8(moduleIdx); + if (module.channelsCount > maxModuleChannels_M8(moduleIdx)) + module.channelsCount = maxModuleChannels_M8(moduleIdx); if (reusableBuffer.moduleSetup.r9mPower + module.pxx.power < 5) { // switching between mode 2 and 3 does not require rebind POPUP_WARNING(STR_REBIND); } @@ -1502,7 +1537,8 @@ void menuModelSetup(event_t event) CHECK_INCDEC_MODELVAR_ZERO(event, module.pxx.power, R9M_LBT_POWER_MAX); if (s_editMode == 0 && reusableBuffer.moduleSetup.r9mPower != module.pxx.power) { module.channelsStart = 0; - module.channelsCount = maxModuleChannels_M8(moduleIdx); + if (module.channelsCount > maxModuleChannels_M8(moduleIdx)) + module.channelsCount = maxModuleChannels_M8(moduleIdx); if (reusableBuffer.moduleSetup.r9mPower + module.pxx.power < 5) { //switching between mode 2 and 3 does not require rebind POPUP_WARNING(STR_REBIND); } @@ -1533,7 +1569,7 @@ void menuModelSetup(event_t event) lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS); char statusText[64]; - multiModuleStatus.getStatusString(statusText); + getMultiModuleStatus(EXTERNAL_MODULE).getStatusString(statusText); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); break; } @@ -1542,7 +1578,7 @@ void menuModelSetup(event_t event) lcdDrawTextAlignedLeft(y, STR_MODULE_SYNC); char statusText[64]; - multiSyncStatus.getRefreshString(statusText); + getMultiSyncStatus(EXTERNAL_MODULE).getRefreshString(statusText); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); break; } diff --git a/radio/src/gui/128x64/model_special_functions.cpp b/radio/src/gui/128x64/model_special_functions.cpp index b4f4646a3..a0472d681 100644 --- a/radio/src/gui/128x64/model_special_functions.cpp +++ b/radio/src/gui/128x64/model_special_functions.cpp @@ -222,8 +222,12 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF else #endif if (func == FUNC_TRAINER) { - maxParam = 4; - drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); + maxParam = NUM_STICKS + 1; + uint8_t param = CFN_CH_INDEX(cfn); + if (param == NUM_STICKS + 1) + lcdDrawText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, "Chans", attr); + else + drawSource(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, CFN_CH_INDEX(cfn) == 0 ? 0 : MIXSRC_Rud + CFN_CH_INDEX(cfn) - 1, attr); } #if defined(GVARS) else if (func == FUNC_ADJUST_GVAR) { diff --git a/radio/src/gui/128x64/model_telemetry_sensor.cpp b/radio/src/gui/128x64/model_telemetry_sensor.cpp index d80cd0080..264fe6f4c 100644 --- a/radio/src/gui/128x64/model_telemetry_sensor.cpp +++ b/radio/src/gui/128x64/model_telemetry_sensor.cpp @@ -104,7 +104,7 @@ void menuModelSensor(event_t event) if (sensor->type == TELEM_TYPE_CUSTOM) { lcdDrawTextAlignedLeft(y, STR_ID); lcdDrawHexNumber(SENSOR_2ND_COLUMN, y, sensor->id, LEFT|(menuHorizontalPosition==0 ? attr : 0)); - lcdDrawHexChar(SENSOR_3RD_COLUMN, y, sensor->instance & 0x1f, LEFT|(menuHorizontalPosition==1 ? attr : 0)); + lcdDrawHexChar(SENSOR_3RD_COLUMN, y, (sensor->instance & 0x1F) + 1, LEFT|(menuHorizontalPosition==1 ? attr : 0)); if (attr && s_editMode > 0) { switch (menuHorizontalPosition) { case 0: diff --git a/radio/src/gui/128x64/radio_diagkeys.cpp b/radio/src/gui/128x64/radio_diagkeys.cpp index bd8668c82..a5840754a 100644 --- a/radio/src/gui/128x64/radio_diagkeys.cpp +++ b/radio/src/gui/128x64/radio_diagkeys.cpp @@ -64,7 +64,7 @@ void menuRadioDiagKeys(event_t event) #else if (i < NUM_SWITCHES) { if (SWITCH_EXISTS(i)) { - y = MENU_HEADER_HEIGHT + 1 + FH*i; + y = (NUM_SWITCHES > 6 ? 0 : MENU_HEADER_HEIGHT) + FH*i; getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i); getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3)); drawSwitch(8*FW+4, y, sw, 0); diff --git a/radio/src/gui/128x64/radio_setup.cpp b/radio/src/gui/128x64/radio_setup.cpp index 9d4c10c9e..e8a3cd25b 100644 --- a/radio/src/gui/128x64/radio_setup.cpp +++ b/radio/src/gui/128x64/radio_setup.cpp @@ -663,7 +663,6 @@ void menuRadioSetup(event_t event) resumePulses(); waitKeysReleased(); } - MOVE_CURSOR_FROM_HERE(); break; } } diff --git a/radio/src/gui/128x64/view_main.cpp b/radio/src/gui/128x64/view_main.cpp index 5e37e3691..0fdfa9b43 100644 --- a/radio/src/gui/128x64/view_main.cpp +++ b/radio/src/gui/128x64/view_main.cpp @@ -180,11 +180,31 @@ void displayTrims(uint8_t phase) void drawTimerWithMode(coord_t x, coord_t y, uint8_t index) { const TimerData & timer = g_model.timers[index]; + if (timer.mode) { const TimerState & timerState = timersStates[index]; const uint8_t negative = (timerState.val<0 ? BLINK | INVERS : 0); - LcdFlags att = RIGHT | DBLSIZE | negative; - drawTimer(x, y, timerState.val, att, att); + LcdFlags att = RIGHT | DBLSIZE; + if (timerState.val < 60 * 60) { // display MM:SS + div_t qr = div(abs(timerState.val), 60); + lcdDrawNumber(x - 5, y, qr.rem, att | LEADING0 | negative, 2); + lcdDrawText(lcdLastLeftPos, y, ":", att|BLINK | negative); + lcdDrawNumber(lcdLastLeftPos, y, qr.quot, att | negative); + if (negative) + lcdDrawText(lcdLastLeftPos, y, "-", att | negative); + } + else if (timerState.val < (99 * 60 * 60) + (59 * 60)) { // display HHhMM + div_t qr = div(abs(timerState.val) / 60, 60); + lcdDrawNumber(x - 5, y, qr.rem, att | LEADING0, 2); + lcdDrawText(lcdLastLeftPos, y, "h", att); + lcdDrawNumber(lcdLastLeftPos, y, qr.quot, att); + if (negative) + lcdDrawText(lcdLastLeftPos, y, "-", att); + } + else { //display HHHH for crazy large persistent timers + lcdDrawText(x - 5, y, "h", att); + lcdDrawNumber(lcdLastLeftPos, y, timerState.val / 3600, att); + } uint8_t xLabel = (negative ? x-56 : x-49); uint8_t len = zlen(timer.name, LEN_TIMER_NAME); if (len > 0) @@ -295,6 +315,36 @@ void onMainViewMenu(const char *result) } } +void drawSmallSwitch(coord_t x, coord_t y, int width, unsigned int index) +{ + if (SWITCH_EXISTS(index)) { + int val = getValue(MIXSRC_FIRST_SWITCH+index); + + if (val >= 0) { + lcdDrawSolidHorizontalLine(x, y, width); + lcdDrawSolidHorizontalLine(x, y+2, width); + y += 4; + if (val > 0) { + lcdDrawSolidHorizontalLine(x, y, width); + lcdDrawSolidHorizontalLine(x, y+2, width); + y += 4; + } + } + + lcdDrawChar(width==5 ? x+1 : x, y, 'A'+index, SMLSIZE); + y += 7; + + if (val <= 0) { + lcdDrawSolidHorizontalLine(x, y, width); + lcdDrawSolidHorizontalLine(x, y+2, width); + if (val < 0) { + lcdDrawSolidHorizontalLine(x, y+4, width); + lcdDrawSolidHorizontalLine(x, y+6, width); + } + } + } +} + void menuMainView(event_t event) { uint8_t view = g_eeGeneral.view; @@ -470,14 +520,26 @@ void menuMainView(event_t event) doMainScreenGraphics(); // Switches -#if defined(PCBX9LITE) +#if defined(PCBX9LITES) + static const uint8_t x[NUM_SWITCHES-2] = {2*FW-2, 2*FW-2, 17*FW+1, 2*FW-2, 17*FW+1}; + static const uint8_t y[NUM_SWITCHES-2] = {4*FH+1, 5*FH+1, 5*FH+1, 6*FH+1, 6*FH+1}; + for (int i=0; i 0) REPEAT_LAST_CURSOR_MOVE() - -#define MENU_FIRST_LINE_EDIT (menuTab ? (MAXCOL((uint16_t)0) >= HIDDEN_ROW ? (MAXCOL((uint16_t)1) >= HIDDEN_ROW ? 2 : 1) : 0) : 0) #define POS_HORZ_INIT(posVert) ((COLATTR(posVert) & NAVIGATION_LINE_BY_LINE) ? -1 : 0) #define EDIT_MODE_INIT 0 // TODO enum diff --git a/radio/src/gui/212x64/lcd.cpp b/radio/src/gui/212x64/lcd.cpp index f948c1523..3b09fee9b 100644 --- a/radio/src/gui/212x64/lcd.cpp +++ b/radio/src/gui/212x64/lcd.cpp @@ -689,10 +689,12 @@ void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att) } } -void drawSwitch(coord_t x, coord_t y, int32_t idx, LcdFlags flags) +void drawSwitch(coord_t x, coord_t y, int32_t idx, LcdFlags flags, bool autoBold) { char s[8]; getSwitchPositionName(s, idx); + if (autoBold && idx != SWSRC_NONE && getSwitch(idx)) + flags |= BOLD; lcdDrawText(x, y, s, flags); } diff --git a/radio/src/gui/212x64/lcd.h b/radio/src/gui/212x64/lcd.h index dc6fc22c4..82c6a1339 100644 --- a/radio/src/gui/212x64/lcd.h +++ b/radio/src/gui/212x64/lcd.h @@ -117,7 +117,7 @@ void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode, uint8_t len void lcdDrawNumber(coord_t x, coord_t y, int32_t val, LcdFlags mode=0); void drawModelName(coord_t x, coord_t y, char *name, uint8_t id, LcdFlags att); -void drawSwitch(coord_t x, coord_t y, int32_t swtch, LcdFlags att=0); +void drawSwitch(coord_t x, coord_t y, int32_t swtch, LcdFlags att=0, bool autoBold = true); void drawStickName(coord_t x, coord_t y, uint8_t idx, LcdFlags att=0); void drawSource(coord_t x, coord_t y, uint32_t idx, LcdFlags att=0); void drawCurveName(coord_t x, coord_t y, int8_t idx, LcdFlags att=0); diff --git a/radio/src/gui/212x64/menus.h b/radio/src/gui/212x64/menus.h index cbbd43fd1..24da83e0f 100644 --- a/radio/src/gui/212x64/menus.h +++ b/radio/src/gui/212x64/menus.h @@ -54,7 +54,7 @@ void menuTraceBuffer(event_t event); enum MenuRadioIndexes { MENU_RADIO_SETUP, MENU_RADIO_SD_MANAGER, -#if defined(LUA) || defined(PXX2) +#if defined(LUA) || defined(PXX2) || defined(MULTIMODULE) MENU_RADIO_TOOLS, #endif MENU_RADIO_SPECIAL_FUNCTIONS, diff --git a/radio/src/gui/212x64/model_display.cpp b/radio/src/gui/212x64/model_display.cpp index 857f9a7de..0e1da16d5 100644 --- a/radio/src/gui/212x64/model_display.cpp +++ b/radio/src/gui/212x64/model_display.cpp @@ -51,21 +51,44 @@ enum MenuModelDisplayItems { #define DISPLAY_COL2 (16*FW) #define DISPLAY_COL3 (28*FW+2) -#if defined(LUA) - #define SCREEN_TYPE_ROWS 1 - #define DISPLAY_LINE_ROWS(x) ((TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE || TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_SCRIPT) ? HIDDEN_ROW : (uint8_t)2) -#else - #define SCREEN_TYPE_ROWS 0 - #define DISPLAY_LINE_ROWS(x) (TELEMETRY_SCREEN_TYPE(x) == TELEMETRY_SCREEN_TYPE_NONE ? HIDDEN_ROW : (uint8_t)2) -#endif -#define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_ROWS, DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x), DISPLAY_LINE_ROWS(x) +inline uint8_t SCREEN_TYPE_COLUMNS(uint8_t screenIndex) +{ + if (TELEMETRY_SCREEN_TYPE(screenIndex) == TELEMETRY_SCREEN_TYPE_SCRIPT) + return 1; + else + return 0; +} -#define TELEMETRY_CURRENT_SCREEN(k) (k < ITEM_DISPLAY_SCREEN_LABEL2 ? 0 : (k < ITEM_DISPLAY_SCREEN_LABEL3 ? 1 : (k < ITEM_DISPLAY_SCREEN_LABEL4 ? 2 : 3))) +inline uint8_t SCREEN_LINE_COLUMNS(uint8_t screenIndex, uint8_t lineIndex) +{ + switch (TELEMETRY_SCREEN_TYPE(screenIndex)) { + case TELEMETRY_SCREEN_TYPE_VALUES: + return 2; + case TELEMETRY_SCREEN_TYPE_BARS: + return g_model.screens[screenIndex].bars[lineIndex].source ? 2 : 0; + default: + return HIDDEN_ROW; + } +} + +#define TELEMETRY_SCREEN_ROWS(x) SCREEN_TYPE_COLUMNS(x), SCREEN_LINE_COLUMNS(x, 0), SCREEN_LINE_COLUMNS(x, 1), SCREEN_LINE_COLUMNS(x, 2), SCREEN_LINE_COLUMNS(x, 3) + +inline uint8_t DISPLAY_CURRENT_SCREEN(uint8_t line) +{ + if (line < ITEM_DISPLAY_SCREEN_LABEL2) + return 0; + else if (line < ITEM_DISPLAY_SCREEN_LABEL3) + return 1; + else if (line < ITEM_DISPLAY_SCREEN_LABEL4) + return 2; + else + return 3; +} #if defined(LUA) void onTelemetryScriptFileSelectionMenu(const char *result) { - int screenIndex = TELEMETRY_CURRENT_SCREEN(menuVerticalPosition); + int screenIndex = DISPLAY_CURRENT_SCREEN(menuVerticalPosition); if (result == STR_UPDATE_LIST) { if (!sdListFiles(SCRIPTS_TELEM_PATH, SCRIPTS_EXT, sizeof(g_model.screens[screenIndex].script.file), NULL)) { @@ -122,7 +145,7 @@ void menuModelDisplay(event_t event) case ITEM_DISPLAY_SCREEN_LABEL3: case ITEM_DISPLAY_SCREEN_LABEL4: { - uint8_t screenIndex = TELEMETRY_CURRENT_SCREEN(k); + uint8_t screenIndex = DISPLAY_CURRENT_SCREEN(k); drawStringWithIndex(0*FW, y, STR_SCREEN, screenIndex+1); TelemetryScreenType oldScreenType = TELEMETRY_SCREEN_TYPE(screenIndex); TelemetryScreenType newScreenType = (TelemetryScreenType)editChoice(DISPLAY_COL2, y, "", STR_VTELEMSCREENTYPE, oldScreenType, 0, TELEMETRY_SCREEN_TYPE_MAX, (menuHorizontalPosition==0 ? attr : 0), event); @@ -151,9 +174,6 @@ void menuModelDisplay(event_t event) } } } - else if (attr) { - MOVE_CURSOR_FROM_HERE(); - } #endif break; } @@ -195,7 +215,7 @@ void menuModelDisplay(event_t event) if (IS_BARS_SCREEN(screenIndex)) { FrSkyBarData & bar = g_model.screens[screenIndex].bars[lineIndex]; - drawSource(DISPLAY_COL1, y, bar.source, menuHorizontalPosition==0 ? attr : 0); + drawSource(DISPLAY_COL1, y, bar.source, menuHorizontalPosition == 0 ? attr : 0); int16_t barMax, barMin; LcdFlags lf = LEFT; getMixSrcRange(bar.source, barMin, barMax, &lf); @@ -209,9 +229,6 @@ void menuModelDisplay(event_t event) drawSourceCustomValue(DISPLAY_COL3, y, bar.source, bar.barMax, (menuHorizontalPosition==2 ? attr : 0) | lf); } } - else if (attr) { - MOVE_CURSOR_FROM_HERE(); - } if (attr && s_editMode>0) { switch (menuHorizontalPosition) { case 0: diff --git a/radio/src/gui/212x64/model_input_edit.cpp b/radio/src/gui/212x64/model_input_edit.cpp index f99e31cd4..dc5e6085b 100644 --- a/radio/src/gui/212x64/model_input_edit.cpp +++ b/radio/src/gui/212x64/model_input_edit.cpp @@ -109,7 +109,7 @@ void menuModelExpoOne(event_t event) case EXPO_FIELD_SOURCE: lcdDrawTextAlignedLeft(y, STR_SOURCE); drawSource(EXPO_ONE_2ND_COLUMN, y, ed->srcRaw, STREXPANDED|attr); - if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isInputSourceAvailable); + if (attr) ed->srcRaw = checkIncDec(event, ed->srcRaw, INPUTSRC_FIRST, INPUTSRC_LAST, EE_MODEL|INCDEC_SOURCE|NO_INCDEC_MARKS, isSourceAvailableInInputs); break; case EXPO_FIELD_SCALE: diff --git a/radio/src/gui/212x64/model_setup.cpp b/radio/src/gui/212x64/model_setup.cpp index b5b148bf6..d25a54fc7 100644 --- a/radio/src/gui/212x64/model_setup.cpp +++ b/radio/src/gui/212x64/model_setup.cpp @@ -230,8 +230,6 @@ void editTimerCountdown(int timerIdx, coord_t y, LcdFlags attr, event_t event) #define INTERNAL_MODULE_TYPE_ROWS (0) // Module type + RF protocols #endif -#define PORT_CHANNELS_ROWS(x) (x==INTERNAL_MODULE ? INTERNAL_MODULE_CHANNELS_ROWS : (x==EXTERNAL_MODULE ? EXTERNAL_MODULE_CHANNELS_ROWS : 1)) - #define TRAINER_CHANNELS_ROW (IS_SLAVE_TRAINER() ? (uint8_t)1 : HIDDEN_ROW) #define TRAINER_PPM_PARAMS_ROW (g_model.trainerData.mode == TRAINER_MODE_SLAVE ? (uint8_t)2 : HIDDEN_ROW) #define TRAINER_BLUETOOTH_M_ROW ((bluetooth.distantAddr[0] == '\0' || bluetooth.state == BLUETOOTH_STATE_CONNECTED) ? (uint8_t)0 : (uint8_t)1) @@ -352,7 +350,7 @@ void menuModelSetup(event_t event) LABEL(InternalModule), INTERNAL_MODULE_TYPE_ROWS, - INTERNAL_MODULE_CHANNELS_ROWS, + MODULE_CHANNELS_ROWS(INTERNAL_MODULE), IF_NOT_ACCESS_MODULE_RF(INTERNAL_MODULE, IF_INTERNAL_MODULE_ON(isModuleFailsafeAvailable(INTERNAL_MODULE) ? (uint8_t)2 : (uint8_t)1)), IF_ACCESS_MODULE_RF(INTERNAL_MODULE, 0), // RxNum for ACCESS IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), // Failsafe @@ -364,13 +362,13 @@ void menuModelSetup(event_t event) LABEL(ExternalModule), EXTERNAL_MODULE_TYPE_ROW(), - MULTIMODULE_STATUS_ROWS - EXTERNAL_MODULE_CHANNELS_ROWS, - IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, EXTERNAL_MODULE_BIND_ROWS), + MULTIMODULE_STATUS_ROWS(EXTERNAL_MODULE) + MODULE_CHANNELS_ROWS(EXTERNAL_MODULE), + IF_NOT_ACCESS_MODULE_RF(EXTERNAL_MODULE, MODULE_BIND_ROWS(EXTERNAL_MODULE)), IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 0), // RxNum for ACCESS - IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, EXTERNAL_MODULE_OPTION_ROW), - MULTIMODULE_MODULE_ROWS - EXTERNAL_MODULE_POWER_ROW, + IF_NOT_PXX2_MODULE(EXTERNAL_MODULE, MODULE_OPTION_ROW(EXTERNAL_MODULE)), + MULTIMODULE_MODULE_ROWS(EXTERNAL_MODULE) + MODULE_POWER_ROW(EXTERNAL_MODULE), FAILSAFE_ROWS(EXTERNAL_MODULE), IF_ACCESS_MODULE_RF(EXTERNAL_MODULE, 1), // Range check and Register buttons IF_PXX2_MODULE(EXTERNAL_MODULE, 0), // Module options @@ -387,6 +385,8 @@ void menuModelSetup(event_t event) if (event == EVT_ENTRY || event == EVT_ENTRY_UP) { memclear(&reusableBuffer.moduleSetup, sizeof(reusableBuffer.moduleSetup)); reusableBuffer.moduleSetup.r9mPower = g_model.moduleData[EXTERNAL_MODULE].pxx.power; + reusableBuffer.moduleSetup.previousType = g_model.moduleData[EXTERNAL_MODULE].type; + reusableBuffer.moduleSetup.newType = g_model.moduleData[EXTERNAL_MODULE].type; } #if (defined(DSM2) || defined(PXX)) @@ -776,7 +776,7 @@ void menuModelSetup(event_t event) } } else if (isModulePXX2(INTERNAL_MODULE)) { - g_model.moduleData[INTERNAL_MODULE].subType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_ISRM_PXX2_ACCST_LR12, EE_MODEL, isRfProtocolAvailable); + g_model.moduleData[INTERNAL_MODULE].subType = checkIncDec(event, g_model.moduleData[INTERNAL_MODULE].subType, 0, MODULE_SUBTYPE_ISRM_PXX2_ACCST_D16, EE_MODEL, isRfProtocolAvailable); } } #else @@ -786,7 +786,7 @@ void menuModelSetup(event_t event) } lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_ISRM_RF_PROTOCOLS, index, attr); if (attr) { - index = checkIncDec(event, index, 0, 3, EE_MODEL); + index = checkIncDec(event, index, 0, MODULE_SUBTYPE_ISRM_PXX2_ACCST_D16 + 1 /* because of --- */, EE_MODEL); if (checkIncDec_Ret) { memclear(&g_model.moduleData[INTERNAL_MODULE], sizeof(ModuleData)); if (index > 0) { @@ -806,7 +806,7 @@ void menuModelSetup(event_t event) case ITEM_MODEL_SETUP_EXTERNAL_MODULE_TYPE: lcdDrawTextAlignedLeft(y, INDENT TR_MODE); - lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, g_model.moduleData[EXTERNAL_MODULE].type, menuHorizontalPosition==0 ? attr : 0); + lcdDrawTextAtIndex(MODEL_SETUP_2ND_COLUMN, y, STR_EXTERNAL_MODULE_PROTOCOLS, reusableBuffer.moduleSetup.newType, menuHorizontalPosition==0 ? attr : 0); if (isModuleXJT(EXTERNAL_MODULE)) lcdDrawTextAtIndex(lcdNextPos + 3, y, STR_XJT_ACCST_RF_PROTOCOLS, 1+g_model.moduleData[EXTERNAL_MODULE].subType, menuHorizontalPosition==1 ? attr : 0); else if (isModuleDSM2(EXTERNAL_MODULE)) @@ -832,17 +832,25 @@ void menuModelSetup(event_t event) } } #endif + if (attr && menuHorizontalPosition == 0) { + if (s_editMode > 0) { + g_model.moduleData[EXTERNAL_MODULE].type = MODULE_TYPE_NONE; + } + else if (reusableBuffer.moduleSetup.newType != reusableBuffer.moduleSetup.previousType) { + g_model.moduleData[EXTERNAL_MODULE].type = reusableBuffer.moduleSetup.newType; + reusableBuffer.moduleSetup.previousType = reusableBuffer.moduleSetup.newType; + setModuleType(EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].type); + } + else if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_NONE) { + g_model.moduleData[EXTERNAL_MODULE].type = reusableBuffer.moduleSetup.newType; + } + } if (attr) { if (s_editMode > 0) { switch (menuHorizontalPosition) { case 0: - { - uint8_t moduleType = checkIncDec(event, g_model.moduleData[EXTERNAL_MODULE].type, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable); - if (checkIncDec_Ret) { - setModuleType(EXTERNAL_MODULE, moduleType); - } + reusableBuffer.moduleSetup.newType = checkIncDec(event, reusableBuffer.moduleSetup.newType, MODULE_TYPE_NONE, MODULE_TYPE_MAX, EE_MODEL, isExternalModuleAvailable); break; - } case 1: if (isModuleDSM2(EXTERNAL_MODULE)) { @@ -851,7 +859,7 @@ void menuModelSetup(event_t event) #if defined(MULTIMODULE) else if (isModuleMultimodule(EXTERNAL_MODULE)) { int multiRfProto = g_model.moduleData[EXTERNAL_MODULE].multi.customProto == 1 ? MODULE_SUBTYPE_MULTI_CUSTOM : g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false); - CHECK_INCDEC_MODELVAR(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST); + CHECK_INCDEC_MODELVAR_CHECK(event, multiRfProto, MODULE_SUBTYPE_MULTI_FIRST, MODULE_SUBTYPE_MULTI_LAST, isMultiProtocolSelectable); if (checkIncDec_Ret) { g_model.moduleData[EXTERNAL_MODULE].multi.customProto = (multiRfProto == MODULE_SUBTYPE_MULTI_CUSTOM); if (!g_model.moduleData[EXTERNAL_MODULE].multi.customProto) @@ -976,7 +984,7 @@ void menuModelSetup(event_t event) } if (bluetooth.state == BLUETOOTH_STATE_DISCOVER_START && reusableBuffer.moduleSetup.bt.devicesCount > 0) { - popupMenuItemsCount = min(reusableBuffer.moduleSetup.bt.devicesCount, 6); + popupMenuItemsCount = min(reusableBuffer.moduleSetup.bt.devicesCount, MAX_BLUETOOTH_DISTANT_ADDR); for (uint8_t i=0; i= 0) { + if ((int8_t)MODULE_CHANNELS_ROWS(moduleIdx) >= 0) { lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, STR_CH, menuHorizontalPosition==0 ? attr : 0); lcdDrawNumber(lcdLastRightPos, y, moduleData.channelsStart+1, LEFT | (menuHorizontalPosition==0 ? attr : 0)); lcdDrawChar(lcdLastRightPos, y, '-'); @@ -1144,8 +1152,8 @@ void menuModelSetup(event_t event) lcdDrawText(MODEL_SETUP_2ND_COLUMN+MODEL_SETUP_RANGE_OFS+xOffsetBind, y, STR_MODULE_RANGE, l_posHorz==2 ? attr : 0); uint8_t newFlag = 0; #if defined(MULTIMODULE) - if (multiBindStatus == MULTI_BIND_FINISHED) { - multiBindStatus = MULTI_NORMAL_OPERATION; + if (getMultiBindStatus(moduleIdx) == MULTI_BIND_FINISHED) { + setMultiBindStatus(moduleIdx, MULTI_NORMAL_OPERATION); s_editMode = 0; } #endif @@ -1178,7 +1186,7 @@ void menuModelSetup(event_t event) moduleState[moduleIdx].mode = newFlag; #if defined(MULTIMODULE) if (newFlag == MODULE_MODE_BIND) - multiBindStatus = MULTI_BIND_INITIATED; + setMultiBindStatus(moduleIdx, MULTI_BIND_INITIATED); #endif } } @@ -1253,6 +1261,11 @@ void menuModelSetup(event_t event) } else { CHECK_INCDEC_MODELVAR(event, g_model.moduleData[moduleIdx].multi.optionValue, -128, 127); + if (pdef->optionsstr == STR_MULTI_RFTUNE) { + lcdDrawText(MODEL_SETUP_3RD_COLUMN+22, y, "RSSI(", LEFT); + lcdDrawNumber(lcdLastRightPos, y, TELEMETRY_RSSI(), LEFT); + lcdDrawText(lcdLastRightPos, y, ")", LEFT); + } } } } @@ -1314,7 +1327,7 @@ void menuModelSetup(event_t event) { lcdDrawTextAlignedLeft(y, STR_MODULE_STATUS); char statusText[64]; - multiModuleStatus.getStatusString(statusText); + getMultiModuleStatus(EXTERNAL_MODULE).getStatusString(statusText); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); break; } @@ -1323,7 +1336,7 @@ void menuModelSetup(event_t event) { lcdDrawTextAlignedLeft(y, STR_MODULE_SYNC); char statusText[64]; - multiSyncStatus.getRefreshString(statusText); + getMultiSyncStatus(EXTERNAL_MODULE).getRefreshString(statusText); lcdDrawText(MODEL_SETUP_2ND_COLUMN, y, statusText); break; } diff --git a/radio/src/gui/212x64/model_special_functions.cpp b/radio/src/gui/212x64/model_special_functions.cpp index 653e83783..eb1bcb58d 100644 --- a/radio/src/gui/212x64/model_special_functions.cpp +++ b/radio/src/gui/212x64/model_special_functions.cpp @@ -214,8 +214,12 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF else #endif if (func == FUNC_TRAINER) { - maxParam = NUM_STICKS; - drawSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); + maxParam = NUM_STICKS + 1; + uint8_t param = CFN_CH_INDEX(cfn); + if (param == NUM_STICKS + 1) + lcdDrawText(lcdNextPos, y, "Chans", attr); + else + drawSource(lcdNextPos, y, CFN_CH_INDEX(cfn)==0 ? 0 : MIXSRC_Rud+CFN_CH_INDEX(cfn)-1, attr); } #if defined(GVARS) else if (func == FUNC_ADJUST_GVAR) { diff --git a/radio/src/gui/212x64/model_telemetry_sensor.cpp b/radio/src/gui/212x64/model_telemetry_sensor.cpp index ac490c6d0..df1ced3bb 100644 --- a/radio/src/gui/212x64/model_telemetry_sensor.cpp +++ b/radio/src/gui/212x64/model_telemetry_sensor.cpp @@ -114,7 +114,7 @@ void menuModelSensor(event_t event) if (sensor->type == TELEM_TYPE_CUSTOM) { lcdDrawTextAlignedLeft(y, STR_ID); lcdDrawHexNumber(SENSOR_2ND_COLUMN, y, sensor->id, LEFT|(menuHorizontalPosition==0 ? attr : 0)); - lcdDrawNumber(SENSOR_3RD_COLUMN, y, sensor->instance, LEFT|(menuHorizontalPosition==1 ? attr : 0)); + lcdDrawNumber(SENSOR_3RD_COLUMN, y, (sensor->instance & 0x1F) + 1, LEFT|(menuHorizontalPosition==1 ? attr : 0)); if (attr) { switch (menuHorizontalPosition) { case 0: diff --git a/radio/src/gui/212x64/view_main.cpp b/radio/src/gui/212x64/view_main.cpp index 8119f0dcf..cf4192164 100644 --- a/radio/src/gui/212x64/view_main.cpp +++ b/radio/src/gui/212x64/view_main.cpp @@ -165,19 +165,21 @@ void displayTrims(uint8_t phase) void drawSliders() { - for (uint8_t i=NUM_STICKS; i=SLIDER1 ? LCD_H/2+1 : 1); #endif lcdDrawSolidVerticalLine(x, y, LCD_H/2-2); lcdDrawSolidVerticalLine(x+1, y, LCD_H/2-2); - y += LCD_H/2-4; + y += LCD_H / 2 - 4; y -= ((calibratedAnalogs[i]+RESX)*(LCD_H/2-4)/(RESX*2)); // calculate once per loop lcdDrawSolidVerticalLine(x-1, y, 2); lcdDrawSolidVerticalLine(x+2, y, 2); @@ -530,7 +532,7 @@ void menuMainView(event_t event) if (SWITCH_EXISTS(i)) { getvalue_t val = getValue(MIXSRC_FIRST_SWITCH+i); getvalue_t sw = ((val < 0) ? 3*i+1 : ((val == 0) ? 3*i+2 : 3*i+3)); - drawSwitch((g_model.view == VIEW_INPUTS) ? (index<4 ? 8*FW+1 : 23*FW+2) : (index<4 ? 3*FW+1 : 8*FW-2), (index%4)*FH+3*FH, sw, 0); + drawSwitch((g_model.view == VIEW_INPUTS) ? (index<4 ? 8*FW+1 : 23*FW+2) : (index<4 ? 3*FW+1 : 8*FW-2), (index%4)*FH+3*FH, sw, 0, false); index++; } } diff --git a/radio/src/gui/colorlcd/model_setup.cpp b/radio/src/gui/colorlcd/model_setup.cpp index f65da7bab..1ce182afc 100644 --- a/radio/src/gui/colorlcd/model_setup.cpp +++ b/radio/src/gui/colorlcd/model_setup.cpp @@ -573,17 +573,18 @@ class ModuleWindow : public FormGroup { // Multimodule status new StaticText(this, grid.getLabelSlot(true), STR_MODULE_STATUS); - char statusText[64]; - multiModuleStatus.getStatusString(statusText); + char statusText[64] = {}; + #warning "multimodule adaptations needed" + // multiModuleStatus.getStatusString(statusText); new StaticText(this, grid.getFieldSlot(), statusText); // Multimodule sync - if(multiSyncStatus.isValid()) { + /*if (multiSyncStatus.isValid()) { grid.nextLine(); new StaticText(this, grid.getLabelSlot(true), STR_MODULE_SYNC); multiSyncStatus.getRefreshString(statusText); new StaticText(this, grid.getFieldSlot(), statusText); - } + }*/ // Multi optional feature row const uint8_t multi_proto = g_model.moduleData[moduleIdx].getMultiProtocol(true); diff --git a/radio/src/gui/common/stdlcd/CMakeLists.txt b/radio/src/gui/common/stdlcd/CMakeLists.txt index c558676a6..aaedd18ba 100644 --- a/radio/src/gui/common/stdlcd/CMakeLists.txt +++ b/radio/src/gui/common/stdlcd/CMakeLists.txt @@ -22,7 +22,7 @@ set(GUI_SRC model_curve_edit.cpp ) -if(PXX2 OR LUA) +if(PXX2 OR LUA OR MULTIMODULE) set(GUI_SRC ${GUI_SRC} ../common/stdlcd/radio_tools.cpp) endif() @@ -40,8 +40,14 @@ endif() if(PXX2) set(GUI_SRC ${GUI_SRC} - ../common/stdlcd/radio_spectrum_analyser.cpp ../common/stdlcd/radio_power_meter.cpp ) endif() +if(PXX2 OR MULTIMODULE) + set(GUI_SRC + ${GUI_SRC} + ../common/stdlcd/radio_spectrum_analyser.cpp + ) +endif() + diff --git a/radio/src/gui/common/stdlcd/draw_functions.cpp b/radio/src/gui/common/stdlcd/draw_functions.cpp index 63467dc20..906e61c62 100644 --- a/radio/src/gui/common/stdlcd/draw_functions.cpp +++ b/radio/src/gui/common/stdlcd/draw_functions.cpp @@ -25,7 +25,7 @@ void drawStringWithIndex(coord_t x, coord_t y, const char * str, uint8_t idx, Lc { if (flags & RIGHT) { lcdDrawNumber(x, y, idx, flags); - lcdDrawText(x-FWNUM, y, str, flags & ~LEADING0); + lcdDrawText(lcdNextPos, y, str, flags & ~LEADING0); } else { lcdDrawText(x, y, str, flags & ~LEADING0); diff --git a/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp b/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp index 84cc284fd..24091dcd7 100644 --- a/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp +++ b/radio/src/gui/common/stdlcd/model_setup_pxx1.cpp @@ -26,16 +26,10 @@ void onBindMenu(const char * result) if (result == STR_BINDING_1_8_TELEM_ON) { g_model.moduleData[moduleIdx].pxx.receiverTelemetryOff = false; g_model.moduleData[moduleIdx].pxx.receiverHigherChannels = false; - if (isModuleR9MLiteNonPro(moduleIdx) && isModuleR9M_LBT(moduleIdx)) { - g_model.moduleData[moduleIdx].pxx.power = R9M_LITE_LBT_POWER_25_8CH; - } } else if (result == STR_BINDING_1_8_TELEM_OFF) { g_model.moduleData[moduleIdx].pxx.receiverTelemetryOff = true; g_model.moduleData[moduleIdx].pxx.receiverHigherChannels = false; - if (isModuleR9MLiteNonPro(moduleIdx) && isModuleR9M_LBT(moduleIdx)) { - g_model.moduleData[moduleIdx].pxx.power = R9M_LITE_LBT_POWER_100_16CH_NOTELEM; - } } else if (result == STR_BINDING_9_16_TELEM_ON) { g_model.moduleData[moduleIdx].pxx.receiverTelemetryOff = false; diff --git a/radio/src/gui/common/stdlcd/radio_hardware.cpp b/radio/src/gui/common/stdlcd/radio_hardware.cpp index e3a02fbc1..ccf69f105 100644 --- a/radio/src/gui/common/stdlcd/radio_hardware.cpp +++ b/radio/src/gui/common/stdlcd/radio_hardware.cpp @@ -35,7 +35,7 @@ enum { void menuRadioHardware(event_t event) { - MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX+1, {0, 0, (uint8_t)-1, 0, 0, 0, CASE_BLUETOOTH(0)}); + MENU(STR_HARDWARE, menuTabGeneral, MENU_RADIO_HARDWARE, ITEM_RADIO_HARDWARE_MAX+1, {0, 0, 0, 0, 0, 0, CASE_BLUETOOTH(0)}); uint8_t sub = menuVerticalPosition - 1; @@ -52,6 +52,10 @@ void menuRadioHardware(event_t event) case ITEM_RADIO_HARDWARE_STICKS_GAINS_LABELS: lcdDrawTextAlignedLeft(y, "Sticks"); + lcdDrawText(LCD_W, y, BUTTON(TR_CALIBRATION), attr| RIGHT); + if (attr && event == EVT_KEY_FIRST(KEY_ENTER)) { + pushMenu(menuRadioCalibration); + } break; case ITEM_RADIO_HARDWARE_STICK_LV_GAIN: @@ -99,7 +103,7 @@ enum { #if defined(HARDWARE_POT2) ITEM_RADIO_HARDWARE_POT2, #endif -#if defined(HARDWARE_POT3) +#if defined(HARDWARE_POT3) || defined(PCBX9D) // TODO #if defined(STORAGE_POT3) ITEM_RADIO_HARDWARE_POT3, #endif #if defined(HARDWARE_POT4) @@ -151,6 +155,7 @@ enum { #if defined(STM32) ITEM_RADIO_HARDWARE_RTC_BATTERY, + ITEM_RADIO_HARDWARE_RTC_CHECK, #endif #if defined(TX_CAPACITY_MEASUREMENT) @@ -193,6 +198,8 @@ enum { #define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 #elif (NUM_POTS + NUM_SLIDERS) == 3 #define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 +#elif defined(PCBX9D) // TODO defined(STORAGE_POT3) && !defined(STORAGE_POT3) + #define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, HIDDEN_ROW, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 #elif (NUM_POTS + NUM_SLIDERS) == 4 #define POTS_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 #elif (NUM_POTS + NUM_SLIDERS) == 5 @@ -209,6 +216,8 @@ enum { #define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 #elif NUM_SWITCHES == 8 #define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 +#elif NUM_SWITCHES == 7 + #define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 #elif NUM_SWITCHES == 6 #define SWITCHES_ROWS NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1, NAVIGATION_LINE_BY_LINE|1 #elif NUM_SWITCHES == 5 @@ -222,7 +231,7 @@ enum { #elif defined(PCBX9E) #define BLUETOOTH_ROWS 0, uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : READONLY_ROW), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : READONLY_ROW), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : 0), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : 0), #else - #define BLUETOOTH_ROWS uint8_t(IS_BLUETOOTH_CHIP_PRESENT() ? 0 : HIDDEN_ROW), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_TELEMETRY ? -1 : HIDDEN_ROW), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : -1), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : -1), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : 0), + #define BLUETOOTH_ROWS uint8_t(IS_BLUETOOTH_CHIP_PRESENT() ? 0 : HIDDEN_ROW), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_TELEMETRY ? READONLY_ROW : HIDDEN_ROW), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : READONLY_ROW), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : READONLY_ROW), uint8_t(g_eeGeneral.bluetoothMode == BLUETOOTH_OFF ? HIDDEN_ROW : 0), #endif #if defined(INTERNAL_MODULE_PXX1) && defined(EXTERNAL_ANTENNA) @@ -255,7 +264,7 @@ void onHardwareAntennaSwitchConfirm(const char * result) #endif #if defined(STM32) - #define RTC_ROW READONLY_ROW, + #define RTC_ROW READONLY_ROW, 0, #else #define RTC_ROW #endif @@ -471,7 +480,7 @@ void menuRadioHardware(event_t event) { int index = k - ITEM_RADIO_HARDWARE_SA; int config = SWITCH_CONFIG(index); - lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, MIXSRC_FIRST_SWITCH-MIXSRC_Rud+index+1, menuHorizontalPosition < 0 ? attr : 0); + lcdDrawTextAtIndex(INDENT_WIDTH, y, STR_VSRCRAW, MIXSRC_FIRST_SWITCH - MIXSRC_Rud + index + 1, menuHorizontalPosition < 0 ? attr : 0); if (ZEXIST(g_eeGeneral.switchNames[index]) || (attr && s_editMode > 0 && menuHorizontalPosition == 0)) editName(HW_SETTINGS_COLUMN1, y, g_eeGeneral.switchNames[index], LEN_SWITCH_NAME, event, menuHorizontalPosition == 0 ? attr : 0); else @@ -510,6 +519,10 @@ void menuRadioHardware(event_t event) lcdDrawTextAlignedLeft(y, STR_RTC_BATT); putsVolts(HW_SETTINGS_COLUMN2, y, getRTCBatteryVoltage(), PREC2|LEFT); break; + + case ITEM_RADIO_HARDWARE_RTC_CHECK: + g_eeGeneral.disableRtcWarning = 1 - editCheckBox(1 - g_eeGeneral.disableRtcWarning, HW_SETTINGS_COLUMN2, y, STR_RTC_CHECK, attr, event); + break; #endif #if defined(TX_CAPACITY_MEASUREMENT) @@ -552,17 +565,17 @@ void menuRadioHardware(event_t event) break; case ITEM_RADIO_HARDWARE_BLUETOOTH_PAIRING_CODE: - lcdDrawTextAlignedLeft(y, STR_BLUETOOTH_PIN_CODE); + lcdDrawText(INDENT_WIDTH, y, STR_BLUETOOTH_PIN_CODE); lcdDrawText(HW_SETTINGS_COLUMN2, y, "000000"); break; case ITEM_RADIO_HARDWARE_BLUETOOTH_LOCAL_ADDR: - lcdDrawTextAlignedLeft(y, STR_BLUETOOTH_LOCAL_ADDR); + lcdDrawText(INDENT_WIDTH, y, STR_BLUETOOTH_LOCAL_ADDR); lcdDrawText(HW_SETTINGS_COLUMN2, y, bluetooth.localAddr[0] == '\0' ? "---" : bluetooth.localAddr); break; case ITEM_RADIO_HARDWARE_BLUETOOTH_DISTANT_ADDR: - lcdDrawTextAlignedLeft(y, STR_BLUETOOTH_DIST_ADDR); + lcdDrawText(INDENT_WIDTH, y, STR_BLUETOOTH_DIST_ADDR); lcdDrawText(HW_SETTINGS_COLUMN2, y, bluetooth.distantAddr[0] == '\0' ? "---" : bluetooth.distantAddr); break; @@ -602,7 +615,7 @@ void menuRadioHardware(event_t event) break; case ITEM_RADIO_HARDWARE_RAS: -#if defined(PCBX9LITE) +#if defined(PCBX9LITE) && !defined(PCBX9LITES) lcdDrawTextAlignedLeft(y, "Ext. RAS"); lcdNextPos = HW_SETTINGS_COLUMN2; #else @@ -632,7 +645,10 @@ void menuRadioHardware(event_t event) break; case ITEM_RADIO_BACKUP_EEPROM: - lcdDrawText(LCD_W / 2, y, BUTTON(STR_EEBACKUP), attr | CENTERED); + if (LCD_W < 212) + lcdDrawText(LCD_W / 2, y, BUTTON(STR_EEBACKUP), attr | CENTERED); + else + lcdDrawText(HW_SETTINGS_COLUMN2, y, BUTTON(STR_EEBACKUP), attr); if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = EDIT_SELECT_FIELD; eepromBackup(); @@ -640,7 +656,10 @@ void menuRadioHardware(event_t event) break; case ITEM_RADIO_FACTORY_RESET: - lcdDrawText(LCD_W / 2, y, BUTTON(STR_FACTORYRESET), attr | CENTERED); + if (LCD_W < 212) + lcdDrawText(LCD_W / 2, y, BUTTON(STR_FACTORYRESET), attr | CENTERED); + else + lcdDrawText(HW_SETTINGS_COLUMN2, y, BUTTON(STR_FACTORYRESET), attr); if (attr && event == EVT_KEY_BREAK(KEY_ENTER)) { s_editMode = EDIT_SELECT_FIELD; POPUP_CONFIRMATION(STR_CONFIRMRESET, onFactoryResetConfirm); diff --git a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp index 6316638d2..eaf640636 100644 --- a/radio/src/gui/common/stdlcd/radio_sdmanager.cpp +++ b/radio/src/gui/common/stdlcd/radio_sdmanager.cpp @@ -20,6 +20,7 @@ #include "opentx.h" #include "io/frsky_firmware_update.h" +#include "io/multi_firmware_update.h" #include "libopenui/src/libopenui_file.h" #define NODE_TYPE(fname) fname[SD_SCREEN_FILE_LENGTH+1] @@ -220,6 +221,18 @@ void onSdManagerMenu(const char * result) FrskyDeviceFirmwareUpdate device(SPORT_MODULE); device.flashFirmware(lfn, drawProgressScreen); } +#if defined(MULTIMODULE) +#if defined(INTERNAL_MODULE_MULTI) + else if (result == STR_FLASH_INTERNAL_MULTI) { + getSelectionFullPath(lfn); + multiFlashFirmware(INTERNAL_MODULE, lfn); + } +#endif + else if (result == STR_FLASH_EXTERNAL_MULTI) { + getSelectionFullPath(lfn); + multiFlashFirmware(EXTERNAL_MODULE, lfn); + } +#endif #if defined(BLUETOOTH) else if (result == STR_FLASH_BLUETOOTH_MODULE) { getSelectionFullPath(lfn); @@ -341,6 +354,9 @@ void menuRadioSdManager(event_t _event) break; } #endif + TCHAR lfn[_MAX_LFN + 1]; + getSelectionFullPath(lfn); + if (SD_CARD_PRESENT() && s_editMode <= 0) { killEvents(_event); int index = menuVerticalPosition - HEADER_LINE - menuVerticalOffset; @@ -365,10 +381,19 @@ void menuRadioSdManager(event_t _event) POPUP_MENU_ADD_ITEM(STR_EXECUTE_FILE); } #endif +#if defined(MULTIMODULE) && !defined(DISABLE_MULTI_UPDATE) + if (!READ_ONLY() && !strcasecmp(ext, MULTI_FIRMWARE_EXT)) { + MultiFirmwareInformation information; + if (information.readMultiFirmwareInformation(line) == nullptr) { +#if defined(INTERNAL_MODULE_MULTI) + POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MULTI); +#endif + POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MULTI); + } + } +#endif #if defined(PCBTARANIS) - else if (!READ_ONLY() && !strcasecmp(ext, FIRMWARE_EXT)) { - TCHAR lfn[FF_MAX_LFN + 1]; - getSelectionFullPath(lfn); + if (!READ_ONLY() && !strcasecmp(ext, FIRMWARE_EXT)) { if (isBootloader(lfn)) { POPUP_MENU_ADD_ITEM(STR_FLASH_BOOTLOADER); } @@ -379,15 +404,19 @@ void menuRadioSdManager(event_t _event) POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE); POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE); } - else if (!READ_ONLY() && !strcasecmp(ext, UPDATE_FIRMWARE_EXT)) { + else if (!READ_ONLY() && !strcasecmp(ext, FRSKY_FIRMWARE_EXT)) { FrSkyFirmwareInformation information; - if (readFirmwareInformation(line, information) == nullptr) { + if (readFrSkyFirmwareInformation(line, information) == nullptr) { if (information.productFamily == FIRMWARE_FAMILY_INTERNAL_MODULE) POPUP_MENU_ADD_ITEM(STR_FLASH_INTERNAL_MODULE); if (information.productFamily == FIRMWARE_FAMILY_EXTERNAL_MODULE) POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE); - if (HAS_SPORT_UPDATE_CONNECTOR() && (information.productFamily == FIRMWARE_FAMILY_RECEIVER || information.productFamily == FIRMWARE_FAMILY_SENSOR)) - POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_DEVICE); + if (information.productFamily == FIRMWARE_FAMILY_RECEIVER || information.productFamily == FIRMWARE_FAMILY_SENSOR) { + if (HAS_SPORT_UPDATE_CONNECTOR()) + POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_DEVICE); + else + POPUP_MENU_ADD_ITEM(STR_FLASH_EXTERNAL_MODULE); + } #if defined(PXX2) if (information.productFamily == FIRMWARE_FAMILY_RECEIVER) POPUP_MENU_ADD_ITEM(STR_FLASH_RECEIVER_OTA); diff --git a/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp b/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp index a122dd7ba..ab96c52d5 100644 --- a/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp +++ b/radio/src/gui/common/stdlcd/radio_spectrum_analyser.cpp @@ -25,12 +25,19 @@ extern uint8_t g_moduleIdx; enum SpectrumFields { SPECTRUM_FREQUENCY, SPECTRUM_SPAN, + SPECTRUM_TRACK, SPECTRUM_FIELDS_MAX }; +#define SPECTRUM_ROW (isModuleMultimodule(g_moduleIdx) ? READONLY_ROW : (uint8_t)0) + void menuRadioSpectrumAnalyser(event_t event) { - SUBMENU(STR_MENU_SPECTRUM_ANALYSER, 1, {1}); + SUBMENU(STR_MENU_SPECTRUM_ANALYSER, SPECTRUM_FIELDS_MAX, { + SPECTRUM_ROW, //Freq + SPECTRUM_ROW, //Span + 0 //Tracker + }); if (menuEvent) { lcdDrawCenteredText(LCD_H/2, STR_STOPPING); @@ -62,7 +69,10 @@ void menuRadioSpectrumAnalyser(event_t event) reusableBuffer.spectrumAnalyser.freqMax = 930; } else { - reusableBuffer.spectrumAnalyser.spanDefault = 40; // 40MHz + if (isModuleMultimodule(g_moduleIdx)) + reusableBuffer.spectrumAnalyser.spanDefault = 80; // 80MHz + else + reusableBuffer.spectrumAnalyser.spanDefault = 40; // 40MHz reusableBuffer.spectrumAnalyser.spanMax = 80; reusableBuffer.spectrumAnalyser.freqDefault = 2440; // 2440MHz reusableBuffer.spectrumAnalyser.freqMin = 2400; @@ -71,20 +81,22 @@ void menuRadioSpectrumAnalyser(event_t event) reusableBuffer.spectrumAnalyser.span = reusableBuffer.spectrumAnalyser.spanDefault * 1000000; reusableBuffer.spectrumAnalyser.freq = reusableBuffer.spectrumAnalyser.freqDefault * 1000000; + reusableBuffer.spectrumAnalyser.track = reusableBuffer.spectrumAnalyser.freq; reusableBuffer.spectrumAnalyser.step = reusableBuffer.spectrumAnalyser.span / LCD_W; reusableBuffer.spectrumAnalyser.dirty = true; moduleState[g_moduleIdx].mode = MODULE_MODE_SPECTRUM_ANALYSER; } for (uint8_t i=0; i0 ? INVERS|BLINK : INVERS) : 0); + uint8_t sub = menuVerticalPosition; + LcdFlags attr = (sub==i ? (s_editMode>0 ? BLINK|INVERS : INVERS) : 0); switch (i) { case SPECTRUM_FREQUENCY: { uint16_t frequency = reusableBuffer.spectrumAnalyser.freq / 1000000; - lcdDrawText(1, 10, "F:", 0); - lcdDrawNumber(lcdLastRightPos + 2, 10, frequency, attr); - lcdDrawText(lcdLastRightPos + 2, 10, "MHz", 0); + lcdDrawText(1, 10, "F:", SMLSIZE); + lcdDrawNumber(lcdLastRightPos + 1, 10, frequency, attr|SMLSIZE); + lcdDrawText(lcdLastRightPos + 1, 10, "MHz", SMLSIZE); if (attr) { reusableBuffer.spectrumAnalyser.freq = uint32_t(checkIncDec(event, frequency, reusableBuffer.spectrumAnalyser.freqMin, reusableBuffer.spectrumAnalyser.freqMax, 0)) * 1000000; if (checkIncDec_Ret) { @@ -94,11 +106,11 @@ void menuRadioSpectrumAnalyser(event_t event) break; } - case SPECTRUM_SPAN: + case SPECTRUM_SPAN: { uint8_t span = reusableBuffer.spectrumAnalyser.span / 1000000; - lcdDrawText(lcdLastRightPos + 5, 10, "S:", 0); - lcdDrawNumber(lcdLastRightPos + 2, 10, reusableBuffer.spectrumAnalyser.span/1000000, attr); - lcdDrawText(lcdLastRightPos + 2, 10, "MHz", 0); + lcdDrawText(lcdLastRightPos + 2, 10, "S:", SMLSIZE); + lcdDrawNumber(lcdLastRightPos + 1, 10, reusableBuffer.spectrumAnalyser.span / 1000000, attr | SMLSIZE); + lcdDrawText(lcdLastRightPos + 1, 10, "MHz", SMLSIZE); if (attr) { reusableBuffer.spectrumAnalyser.span = checkIncDec(event, span, 1, reusableBuffer.spectrumAnalyser.spanMax, 0) * 1000000; if (checkIncDec_Ret) { @@ -107,21 +119,42 @@ void menuRadioSpectrumAnalyser(event_t event) } } break; + } + + case SPECTRUM_TRACK: { + uint16_t track = reusableBuffer.spectrumAnalyser.track / 1000000; + lcdDrawText(lcdNextPos + 2, 10, "T:", SMLSIZE); + lcdDrawNumber(lcdNextPos + 1, 10, reusableBuffer.spectrumAnalyser.track / 1000000, attr | SMLSIZE); + lcdDrawText(lcdNextPos + 1, 10, "MHz", SMLSIZE); + if (attr) { + reusableBuffer.spectrumAnalyser.track = uint32_t( + checkIncDec(event, track, (reusableBuffer.spectrumAnalyser.freq - reusableBuffer.spectrumAnalyser.span / 2) / 1000000, + (reusableBuffer.spectrumAnalyser.freq + reusableBuffer.spectrumAnalyser.span / 2) / 1000000, 0)) * 1000000; + if (checkIncDec_Ret) { + reusableBuffer.spectrumAnalyser.dirty = true; + } + } + break; + } } } - uint8_t peak_y = 1; - uint8_t peak_x = 0; + // Signal bar for (uint8_t i=0; i(reusableBuffer.spectrumAnalyser.bars[i] >> 1, LCD_H); - if (h > peak_y) { - peak_x = i; - peak_y = h; - } lcdDrawSolidVerticalLine(i, LCD_H - h, h); } - int8_t y = max(FH, LCD_H - peak_y - FH); - lcdDrawNumber(min(100, peak_x), y, ((reusableBuffer.spectrumAnalyser.freq - reusableBuffer.spectrumAnalyser.span / 2) + peak_x * (reusableBuffer.spectrumAnalyser.span / LCD_W)) / 1000000, TINSIZE); - lcdDrawText(lcdLastRightPos, y, "M", TINSIZE); -} + // Signal max + for (uint8_t i=0; i(reusableBuffer.spectrumAnalyser.max[i] >> 1, LCD_H); + lcdDrawPoint(i, LCD_H - h); + if (reusableBuffer.spectrumAnalyser.max[i] > 1) + reusableBuffer.spectrumAnalyser.max[i] -= 1; + } + + // Draw Tracker + int offset = reusableBuffer.spectrumAnalyser.track - (reusableBuffer.spectrumAnalyser.freq - reusableBuffer.spectrumAnalyser.span / 2); + int x = offset / reusableBuffer.spectrumAnalyser.step; + lcdDrawVerticalLine(x, 10+FH+1, LCD_H, SOLID); +} \ No newline at end of file diff --git a/radio/src/gui/common/stdlcd/radio_tools.cpp b/radio/src/gui/common/stdlcd/radio_tools.cpp index 08a9af336..b5e411b24 100644 --- a/radio/src/gui/common/stdlcd/radio_tools.cpp +++ b/radio/src/gui/common/stdlcd/radio_tools.cpp @@ -46,15 +46,13 @@ void addRadioModuleTool(uint8_t index, const char * label, void (* tool)(event_t } } -#define TOOL_NAME_MAXLEN 16 - #if defined(LUA) void addRadioScriptTool(uint8_t index, const char * path) { - char toolName[TOOL_NAME_MAXLEN + 1]; + char toolName[RADIO_TOOL_NAME_MAXLEN + 1]; if (!readToolName(toolName, path)) { - strAppendFilename(toolName, getBasename(path), TOOL_NAME_MAXLEN); + strAppendFilename(toolName, getBasename(path), RADIO_TOOL_NAME_MAXLEN); } if (addRadioTool(index, toolName)) { @@ -84,17 +82,21 @@ void menuRadioTools(event_t event) uint8_t index = 0; -#if defined(PXX2) - if (isPXX2ModuleOptionAvailable(reusableBuffer.radioTools.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) +#if defined(INTERNAL_MODULE_PXX2) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); - if (isPXX2ModuleOptionAvailable(reusableBuffer.radioTools.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[INTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) addRadioModuleTool(index++, STR_POWER_METER_INT, menuRadioPowerMeter, INTERNAL_MODULE); - - if (isPXX2ModuleOptionAvailable(reusableBuffer.radioTools.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER)) +#elif defined(INTERNAL_MODULE_MULTI) + addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_INT, menuRadioSpectrumAnalyser, INTERNAL_MODULE); +#endif +#if defined(PXX2)|| defined(MULTIMODULE) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_SPECTRUM_ANALYSER) || isModuleMultimodule(EXTERNAL_MODULE)) addRadioModuleTool(index++, STR_SPECTRUM_ANALYSER_EXT, menuRadioSpectrumAnalyser, EXTERNAL_MODULE); - - if (isPXX2ModuleOptionAvailable(reusableBuffer.radioTools.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) +#endif +#if defined(PXX2) + if (isPXX2ModuleOptionAvailable(reusableBuffer.hardwareAndSettings.modules[EXTERNAL_MODULE].information.modelID, MODULE_OPTION_POWER_METER)) addRadioModuleTool(index++, STR_POWER_METER_EXT, menuRadioPowerMeter, EXTERNAL_MODULE); #endif diff --git a/radio/src/gui/common/stdlcd/radio_trainer.cpp b/radio/src/gui/common/stdlcd/radio_trainer.cpp index a4d6f5e56..58c338a8d 100644 --- a/radio/src/gui/common/stdlcd/radio_trainer.cpp +++ b/radio/src/gui/common/stdlcd/radio_trainer.cpp @@ -88,10 +88,13 @@ void menuRadioTrainer(event_t event) lcdDrawText(0*FW, MENU_HEADER_HEIGHT+1+6*FH, STR_CAL, attr); for (uint8_t i=0; i<4; i++) { uint8_t x = (i*TRAINER_CALIB_COLUMN_WIDTH + 16) * FW/2; + int32_t chVal = ppmInput[i] - g_eeGeneral.trainer.calib[i]; + chVal *= g_eeGeneral.trainer.mix[i].studWeight * 10; + chVal /= 512; #if defined (PPM_UNIT_PERCENT_PREC1) - lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])*2, PREC1|RIGHT); + lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, chVal, PREC1|RIGHT); #else - lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, (ppmInput[i]-g_eeGeneral.trainer.calib[i])/5, RIGHT); + lcdDrawNumber(x, MENU_HEADER_HEIGHT+1+6*FH, chVal / 10, RIGHT); #endif } diff --git a/radio/src/gui/gui_common.cpp b/radio/src/gui/gui_common.cpp index aaeb23dec..bec40cfaf 100644 --- a/radio/src/gui/gui_common.cpp +++ b/radio/src/gui/gui_common.cpp @@ -251,22 +251,17 @@ bool isSourceAvailableInCustomSwitches(int source) return result; } -bool isInputSourceAvailable(int source) +bool isSourceAvailableInInputs(int source) { if (source >= MIXSRC_FIRST_POT && source <= MIXSRC_LAST_POT) return IS_POT_SLIDER_AVAILABLE(POT1+source - MIXSRC_FIRST_POT); -#if defined(GYRO) - if (source >= MIXSRC_GYRO1 && source <= MIXSRC_GYRO2) - return true; -#endif - #if defined(PCBX10) if (source >= MIXSRC_MOUSE1 && source <= MIXSRC_MOUSE2) return false; #endif - if (source >= MIXSRC_Rud && source < MIXSRC_MAX) + if (source >= MIXSRC_Rud && source <= MIXSRC_MAX) return true; if (source >= MIXSRC_FIRST_TRIM && source <= MIXSRC_LAST_TRIM) @@ -537,6 +532,15 @@ bool isPxx2IsrmChannelsCountAllowed(int channels) } #endif +bool isTrainerUsingModuleBay() +{ +#if defined(PCBTARANIS) + if (TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE <= g_model.trainerData.mode && g_model.trainerData.mode <= TRAINER_MODE_MASTER_BATTERY_COMPARTMENT) + return true; +#endif + return false; +} + bool isModuleUsingSport(uint8_t moduleBay, uint8_t moduleType) { switch (moduleType) { @@ -573,6 +577,13 @@ bool isInternalModuleAvailable(int moduleType) return true; #endif +#if defined(INTERNAL_MODULE_MULTI) + if (moduleType == MODULE_TYPE_MULTIMODULE) + return true; + else + return false; +#endif + if (moduleType == MODULE_TYPE_XJT_PXX1) { #if defined(PXX1) && defined(INTERNAL_MODULE_PXX1) return !isModuleUsingSport(EXTERNAL_MODULE, g_model.moduleData[EXTERNAL_MODULE].type); @@ -590,13 +601,20 @@ bool isInternalModuleAvailable(int moduleType) return true; #endif } - + return false; +} +#else +bool isInternalModuleAvailable(int moduleType) +{ return false; } #endif bool isExternalModuleAvailable(int moduleType) { + if (moduleType == MODULE_TYPE_R9M_LITE_PRO_PXX1) + return false; + #if !defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) if (isModuleTypeR9MLite(moduleType) || moduleType == MODULE_TYPE_XJT_LITE_PXX2) return false; @@ -647,7 +665,7 @@ bool isExternalModuleAvailable(int moduleType) #endif #if defined(HARDWARE_INTERNAL_MODULE) - if (isModuleUsingSport(EXTERNAL_MODULE, moduleType) && isModuleUsingSport(INTERNAL_MODULE, g_model.moduleData[INTERNAL_MODULE].type)) + if ((isModuleUsingSport(EXTERNAL_MODULE, moduleType) || isTrainerUsingModuleBay()) && isModuleUsingSport(INTERNAL_MODULE, g_model.moduleData[INTERNAL_MODULE].type)) return false; #endif @@ -720,6 +738,9 @@ bool isTrainerModeAvailable(int mode) #if defined(PCBTARANIS) && !defined(TRAINER_BATTERY_COMPARTMENT) if (mode == TRAINER_MODE_MASTER_BATTERY_COMPARTMENT) return false; +#elif defined(PCBTARANIS) + if (mode == TRAINER_MODE_MASTER_BATTERY_COMPARTMENT) + return g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER; #endif #if defined(PCBX9E) @@ -815,6 +836,7 @@ const char STR_SUBTYPE_REDPINE[] = "\004""Fast""Slow"; const char STR_SUBTYPE_POTENSIC[] = "\003""A20"; const char STR_SUBTYPE_ZSX[] = "\007""280JJRC"; const char STR_SUBTYPE_FLYZONE[] = "\005""FZ410"; +const char STR_SUBTYPE_FRSKYX_RX[] = "\003""FCC""LBT"; const mm_protocol_definition multi_protocols[] = { @@ -848,7 +870,7 @@ const mm_protocol_definition multi_protocols[] = { {MODULE_SUBTYPE_MULTI_HITEC, 2, false, STR_SUBTYPE_HITEC, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_BUGS_MINI, 1, false, STR_SUBTYPE_BUGS_MINI, nullptr}, {MODULE_SUBTYPE_MULTI_TRAXXAS, 0, false, STR_SUBTYPE_TRAXXAS, nullptr}, - {MODULE_SUBTYPE_MULTI_E01X, 2, false, STR_SUBTYPE_E01X, nullptr}, + {MODULE_SUBTYPE_MULTI_E01X, 2, false, STR_SUBTYPE_E01X, STR_MULTI_OPTION}, {MODULE_SUBTYPE_MULTI_V911S, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_GD00X, 1, false, STR_SUBTYPE_GD00X, STR_MULTI_RFTUNE}, {MODULE_SUBTYPE_MULTI_KF606, 0, false, NO_SUBTYPE, STR_MULTI_RFTUNE}, @@ -856,6 +878,7 @@ const mm_protocol_definition multi_protocols[] = { {MODULE_SUBTYPE_MULTI_POTENSIC, 0, false, STR_SUBTYPE_POTENSIC, nullptr}, {MODULE_SUBTYPE_MULTI_ZSX, 0, false, STR_SUBTYPE_ZSX, nullptr}, {MODULE_SUBTYPE_MULTI_FLYZONE, 0, false, STR_SUBTYPE_FLYZONE, nullptr}, + {MODULE_SUBTYPE_MULTI_FRSKYX_RX, 1, false, STR_SUBTYPE_FRSKYX_RX, STR_MULTI_RFTUNE}, {MM_RF_CUSTOM_SELECTED, 7, true, NO_SUBTYPE, STR_MULTI_OPTION}, // Sentinel and default for protocols not listed above (MM_RF_CUSTOM is 0xff) diff --git a/radio/src/gui/gui_common.h b/radio/src/gui/gui_common.h index 5b99a5dc8..7845fe8d6 100644 --- a/radio/src/gui/gui_common.h +++ b/radio/src/gui/gui_common.h @@ -39,6 +39,21 @@ #define CASE_EVT_ROTARY_RIGHT #endif +#if defined(NAVIGATION_X7) || defined(NAVIGATION_X9D) || defined(NAVIGATION_HORUS) +inline uint8_t MENU_FIRST_LINE_EDIT(const uint8_t * horTab, uint8_t horTabMax) +{ + if (horTab) { + uint8_t result = 0; + while (result < horTabMax && horTab[result] >= HIDDEN_ROW) + ++result; + return result; + } + else { + return 0; + } +} +#endif + #if defined(LIBOPENUI) typedef std::function IsValueAvailable; #else @@ -59,7 +74,7 @@ int getFirstAvailable(int min, int max, IsValueAvailable isValueAvailable); bool isTrimModeAvailable(int mode); bool isInputAvailable(int input); -bool isInputSourceAvailable(int source); +bool isSourceAvailableInInputs(int source); bool isThrottleSourceAvailable(int source); bool isLogicalSwitchFunctionAvailable(int function); bool isLogicalSwitchAvailable(int index); @@ -77,6 +92,7 @@ bool isSwitchAvailableInTimers(int swtch); bool isR9MModeAvailable(int mode); bool isPxx2IsrmChannelsCountAllowed(int channels); bool isModuleUsingSport(uint8_t moduleBay, uint8_t moduleType); +bool isTrainerUsingModuleBay(); bool isExternalModuleAvailable(int moduleType); bool isInternalModuleAvailable(int moduleType); bool isRfProtocolAvailable(int protocol); @@ -124,9 +140,31 @@ void drawSourceValue(coord_t x, coord_t y, source_t channel, LcdFlags flags=0); void drawCurve(coord_t offset=0); // model_setup Defines that are used in all uis in the same way -#define INTERNAL_MODULE_CHANNELS_ROWS IF_INTERNAL_MODULE_ON((uint8_t)1) -#define EXTERNAL_MODULE_CHANNELS_ROWS IF_EXTERNAL_MODULE_ON((isModuleDSM2(EXTERNAL_MODULE) || isModuleCrossfire(EXTERNAL_MODULE) || isModuleSBUS(EXTERNAL_MODULE) || (isModuleMultimodule(EXTERNAL_MODULE) && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) != MODULE_SUBTYPE_MULTI_DSM2)) ? (uint8_t)0 : (uint8_t)1) -#define EXTERNAL_MODULE_BIND_ROWS (isModuleXJTD8(EXTERNAL_MODULE) || isModuleSBUS(EXTERNAL_MODULE)) ? (uint8_t)1 : (isModulePPM(EXTERNAL_MODULE) || isModulePXX1(EXTERNAL_MODULE) || isModulePXX2(EXTERNAL_MODULE) || isModuleDSM2(EXTERNAL_MODULE) || isModuleMultimodule(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW +#define IF_INTERNAL_MODULE_ON(x) (IS_INTERNAL_MODULE_ENABLED() ? (uint8_t)(x) : HIDDEN_ROW) +#define IF_MODULE_ON(moduleIndex, x) (IS_MODULE_ENABLED(moduleIndex) ? (uint8_t)(x) : HIDDEN_ROW) + +inline uint8_t MODULE_BIND_ROWS(int moduleIdx) +{ + if (isModuleXJTD8(moduleIdx) || isModuleSBUS(moduleIdx)) + return 1; + + if (isModulePPM(moduleIdx) || isModulePXX1(moduleIdx) || isModulePXX2(moduleIdx) || isModuleDSM2(moduleIdx) || isModuleMultimodule(moduleIdx)) + return 2; + else + return HIDDEN_ROW; +} + +inline uint8_t MODULE_CHANNELS_ROWS(int moduleIdx) +{ + if (!IS_MODULE_ENABLED(moduleIdx)) + return HIDDEN_ROW; + + if (isModuleDSM2(moduleIdx) || isModuleCrossfire(moduleIdx) || isModuleSBUS(moduleIdx) || (isModuleMultimodule(moduleIdx) && g_model.moduleData[moduleIdx].getMultiProtocol(true) != MODULE_SUBTYPE_MULTI_DSM2)) + return 0; + else + return 1; +} + #if defined(MULTIMODULE) // When using packed, the pointer in here end up not being aligned, which clang and gcc complain about @@ -139,9 +177,15 @@ struct mm_protocol_definition { const char *optionsstr; }; const mm_protocol_definition *getMultiProtocolDefinition (uint8_t protocol); -#define MULTIMODULE_STATUS_ROWS isModuleMultimodule(EXTERNAL_MODULE) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(EXTERNAL_MODULE) && multiSyncStatus.isValid()) ? TITLE_ROW : HIDDEN_ROW, -#define MULTIMODULE_MODULE_ROWS isModuleMultimodule(EXTERNAL_MODULE) ? (uint8_t) 0 : HIDDEN_ROW, -#define MULTIMODULE_MODE_ROWS(x) (g_model.moduleData[x].multi.customProto) ? (uint8_t) 3 :MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[x].getMultiProtocol(true)) ? (uint8_t)2 : (uint8_t)1 +#define MULTIMODULE_STATUS_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? TITLE_ROW : HIDDEN_ROW, (isModuleMultimodule(moduleIdx) && getMultiSyncStatus(moduleIdx).isValid()) ? TITLE_ROW : HIDDEN_ROW, +#define MULTIMODULE_MODULE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? (uint8_t) 0 : HIDDEN_ROW, +#define MULTIMODULE_MODE_ROWS(moduleIdx) (g_model.moduleData[moduleIdx].multi.customProto) ? (uint8_t) 3 :MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t)2 : (uint8_t)1 + +inline bool isMultiProtocolSelectable(int protocol) +{ + return protocol != MODULE_SUBTYPE_MULTI_SCANNER; +} + inline bool MULTIMODULE_HAS_SUBTYPE(uint8_t moduleIdx) { return getMultiProtocolDefinition(moduleIdx)->maxSubtype > 0; @@ -154,21 +198,21 @@ inline uint8_t MULTIMODULE_RFPROTO_COLUMNS(uint8_t moduleIdx) return (g_model.moduleData[moduleIdx].multi.customProto ? (uint8_t) 2 : MULTIMODULE_HAS_SUBTYPE(g_model.moduleData[moduleIdx].getMultiProtocol(true)) ? (uint8_t) 1 : 0); #endif } -#define MULTIMODULE_SUBTYPE_ROWS(x) isModuleMultimodule(x) ? MULTIMODULE_RFPROTO_COLUMNS(x) : HIDDEN_ROW, -#define MULTIMODULE_HASOPTIONS(x) (getMultiProtocolDefinition(x)->optionsstr != nullptr) -#define MULTIMODULE_OPTIONS_ROW (isModuleMultimodule(EXTERNAL_MODULE) && MULTIMODULE_HASOPTIONS(g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true))) ? (uint8_t) 0: HIDDEN_ROW +#define MULTIMODULE_SUBTYPE_ROWS(moduleIdx) isModuleMultimodule(moduleIdx) ? MULTIMODULE_RFPROTO_COLUMNS(moduleIdx) : HIDDEN_ROW, +#define MULTIMODULE_HASOPTIONS(moduleIdx) (getMultiProtocolDefinition(moduleIdx)->optionsstr != nullptr) +#define MULTIMODULE_OPTIONS_ROW(moduleIdx) (isModuleMultimodule(moduleIdx) && MULTIMODULE_HASOPTIONS(g_model.moduleData[moduleIdx].getMultiProtocol(true))) ? (uint8_t) 0: HIDDEN_ROW #else -#define MULTIMODULE_STATUS_ROWS -#define MULTIMODULE_MODULE_ROWS -#define MULTIMODULE_SUBTYPE_ROWS(x) -#define MULTIMODULE_MODE_ROWS(x) (uint8_t)0 -#define MULTIMODULE_OPTIONS_ROW HIDDEN_ROW +#define MULTIMODULE_STATUS_ROWS(moduleIdx) +#define MULTIMODULE_MODULE_ROWS(moduleIdx) +#define MULTIMODULE_SUBTYPE_ROWS(moduleIdx) +#define MULTIMODULE_MODE_ROWS(moduleIdx) (uint8_t)0 +#define MULTIMODULE_OPTIONS_ROW(moduleIdx) HIDDEN_ROW #endif -#define FAILSAFE_ROWS(x) isModuleFailsafeAvailable(x) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW -#define EXTERNAL_MODULE_OPTION_ROW (isModuleR9MNonAccess(EXTERNAL_MODULE) || isModuleSBUS(EXTERNAL_MODULE) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW) -#define EXTERNAL_MODULE_POWER_ROW (isModuleMultimodule(EXTERNAL_MODULE) || isModuleR9MNonAccess(EXTERNAL_MODULE)) ? (isModuleR9MLiteNonPro(EXTERNAL_MODULE) ? (isModuleR9M_FCC_VARIANT(EXTERNAL_MODULE) ? READONLY_ROW : (uint8_t)0) : (uint8_t)0) : HIDDEN_ROW +#define FAILSAFE_ROWS(moduleIdx) isModuleFailsafeAvailable(moduleIdx) ? (g_model.moduleData[moduleIdx].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW +#define MODULE_OPTION_ROW(moduleIdx) (isModuleR9MNonAccess(moduleIdx) || isModuleSBUS(moduleIdx) ? TITLE_ROW : MULTIMODULE_OPTIONS_ROW(moduleIdx)) +#define MODULE_POWER_ROW(moduleIdx) (isModuleMultimodule(moduleIdx) || isModuleR9MNonAccess(moduleIdx)) ? (isModuleR9MLiteNonPro(moduleIdx) ? (isModuleR9M_FCC_VARIANT(moduleIdx) ? READONLY_ROW : (uint8_t)0) : (uint8_t)0) : HIDDEN_ROW void editStickHardwareSettings(coord_t x, coord_t y, int idx, event_t event, LcdFlags flags); diff --git a/radio/src/gui/navigation/navigation_horus.cpp b/radio/src/gui/navigation/navigation_horus.cpp index 494f1ee49..b8729c8a3 100644 --- a/radio/src/gui/navigation/navigation_horus.cpp +++ b/radio/src/gui/navigation/navigation_horus.cpp @@ -353,7 +353,7 @@ bool check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t switch (event) { case EVT_ENTRY: s_editMode = EDIT_MODE_INIT; - menuVerticalPosition = MENU_FIRST_LINE_EDIT; + menuVerticalPosition = MENU_FIRST_LINE_EDIT(horTab, horTabMax); menuHorizontalPosition = POS_HORZ_INIT(menuVerticalPosition); break; @@ -390,7 +390,7 @@ bool check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t AUDIO_KEY_PRESS(); } else { - uint8_t posVertInit = MENU_FIRST_LINE_EDIT; + uint8_t posVertInit = MENU_FIRST_LINE_EDIT(horTab, horTabMax); if (menuVerticalOffset != 0 || menuVerticalPosition != posVertInit) { menuVerticalOffset = 0; menuVerticalPosition = posVertInit; @@ -435,7 +435,7 @@ bool check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t break; } do { - INC(menuVerticalPosition, MENU_FIRST_LINE_EDIT, rowcount-1); + INC(menuVerticalPosition, MENU_FIRST_LINE_EDIT(horTab, horTabMax), rowcount-1); } while (CURSOR_NOT_ALLOWED_IN_ROW(menuVerticalPosition)); menuHorizontalPosition = POS_HORZ_INIT(menuVerticalPosition); break; @@ -454,7 +454,7 @@ bool check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t break; } do { - DEC(menuVerticalPosition, MENU_FIRST_LINE_EDIT, rowcount-1); + DEC(menuVerticalPosition, MENU_FIRST_LINE_EDIT(horTab, horTabMax), rowcount-1); } while (CURSOR_NOT_ALLOWED_IN_ROW(menuVerticalPosition)); if (COLATTR(menuVerticalPosition) & NAVIGATION_LINE_BY_LINE) menuHorizontalPosition = -1; @@ -465,7 +465,7 @@ bool check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t linesCount = rowcount; - if (menuVerticalPosition <= MENU_FIRST_LINE_EDIT) { + if (menuVerticalPosition <= MENU_FIRST_LINE_EDIT(horTab, horTabMax)) { menuVerticalOffset = 0; if (horTab) { linesCount = 0; diff --git a/radio/src/gui/navigation/navigation_x7.cpp b/radio/src/gui/navigation/navigation_x7.cpp index d4b2b1f1b..bc835a375 100644 --- a/radio/src/gui/navigation/navigation_x7.cpp +++ b/radio/src/gui/navigation/navigation_x7.cpp @@ -205,7 +205,6 @@ tmr10ms_t menuEntryTime; #define MAXCOL_RAW(row) (horTab ? *(horTab+min(row, (vertpos_t)horTabMax)) : (const uint8_t)0) #define MAXCOL(row) (MAXCOL_RAW(row) >= HIDDEN_ROW ? MAXCOL_RAW(row) : (const uint8_t)(MAXCOL_RAW(row) & (~NAVIGATION_LINE_BY_LINE))) #define COLATTR(row) (MAXCOL_RAW(row) == (uint8_t)-1 ? (const uint8_t)0 : (const uint8_t)(MAXCOL_RAW(row) & NAVIGATION_LINE_BY_LINE)) -#define MENU_FIRST_LINE_EDIT (menuTab ? (MAXCOL((uint16_t)0) >= HIDDEN_ROW ? (MAXCOL((uint16_t)1) >= HIDDEN_ROW ? 2 : 1) : 0) : 0) #define POS_HORZ_INIT(posVert) ((COLATTR(posVert) & NAVIGATION_LINE_BY_LINE) ? -1 : 0) void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t menuTabSize, const uint8_t * horTab, uint8_t horTabMax, vertpos_t rowcount) @@ -251,7 +250,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t case EVT_ENTRY: menuEntryTime = get_tmr10ms(); s_editMode = EDIT_MODE_INIT; - l_posVert = MENU_FIRST_LINE_EDIT; + l_posVert = MENU_FIRST_LINE_EDIT(horTab, horTabMax); l_posHorz = POS_HORZ_INIT(l_posVert); break; @@ -291,7 +290,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t AUDIO_KEY_PRESS(); } else { - uint8_t posVertInit = MENU_FIRST_LINE_EDIT; + uint8_t posVertInit = MENU_FIRST_LINE_EDIT(horTab, horTabMax); if (menuVerticalOffset != 0 || l_posVert != posVertInit) { menuVerticalOffset = 0; l_posVert = posVertInit; @@ -327,7 +326,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t } do { - INC(l_posVert, MENU_FIRST_LINE_EDIT, rowcount-1); + INC(l_posVert, MENU_FIRST_LINE_EDIT(horTab, horTabMax), rowcount-1); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); s_editMode = 0; // if we go down, we must be in this mode @@ -356,7 +355,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc * menuTab, uint8_t } do { - DEC(l_posVert, MENU_FIRST_LINE_EDIT, rowcount-1); + DEC(l_posVert, MENU_FIRST_LINE_EDIT(horTab, horTabMax), rowcount-1); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); s_editMode = 0; // if we go up, we must be in this mode diff --git a/radio/src/gui/navigation/navigation_x9d.cpp b/radio/src/gui/navigation/navigation_x9d.cpp index 0018ad063..a5d6fc332 100644 --- a/radio/src/gui/navigation/navigation_x9d.cpp +++ b/radio/src/gui/navigation/navigation_x9d.cpp @@ -360,7 +360,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t case EVT_ENTRY: menuEntryTime = get_tmr10ms(); s_editMode = EDIT_MODE_INIT; - l_posVert = MENU_FIRST_LINE_EDIT; + l_posVert = MENU_FIRST_LINE_EDIT(horTab, horTabMax); l_posHorz = POS_HORZ_INIT(l_posVert); SET_SCROLLBAR_X(LCD_W-1); break; @@ -373,7 +373,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t break; case EVT_KEY_BREAK(KEY_ENTER): - if (s_editMode > 1) + if (s_editMode > 1) break; if (menuHorizontalPosition < 0 && maxcol > 0 && READ_ONLY_UNLOCKED()) { l_posHorz = 0; @@ -402,7 +402,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t AUDIO_KEY_PRESS(); } else { - uint8_t posVertInit = MENU_FIRST_LINE_EDIT; + uint8_t posVertInit = MENU_FIRST_LINE_EDIT(horTab, horTabMax); if (menuVerticalOffset != 0 || l_posVert != posVertInit) { menuVerticalOffset = 0; l_posVert = posVertInit; @@ -438,7 +438,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t } do { - INC(l_posVert, MENU_FIRST_LINE_EDIT, rowcount-1); + INC(l_posVert, MENU_FIRST_LINE_EDIT(horTab, horTabMax), rowcount-1); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); s_editMode = 0; // if we go down, we must be in this mode @@ -467,7 +467,7 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t } do { - DEC(l_posVert, MENU_FIRST_LINE_EDIT, rowcount-1); + DEC(l_posVert, MENU_FIRST_LINE_EDIT(horTab, horTabMax), rowcount-1); } while (CURSOR_NOT_ALLOWED_IN_ROW(l_posVert)); s_editMode = 0; // if we go up, we must be in this mode @@ -545,4 +545,3 @@ void check(event_t event, uint8_t curr, const MenuHandlerFunc *menuTab, uint8_t menuHorizontalPosition = l_posHorz; } - diff --git a/radio/src/io/frsky_firmware_update.cpp b/radio/src/io/frsky_firmware_update.cpp index 94166e34a..c6a810a50 100644 --- a/radio/src/io/frsky_firmware_update.cpp +++ b/radio/src/io/frsky_firmware_update.cpp @@ -34,7 +34,7 @@ #define PRIM_END_DOWNLOAD 0x83 #define PRIM_DATA_CRC_ERR 0x84 -const char * readFirmwareInformation(const char * filename, FrSkyFirmwareInformation & data) +const char * readFrSkyFirmwareInformation(const char * filename, FrSkyFirmwareInformation & data) { FIL file; UINT count; @@ -306,7 +306,7 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P } const char * ext = getFileExtension(filename); - if (ext && !strcasecmp(ext, UPDATE_FIRMWARE_EXT)) { + if (ext && !strcasecmp(ext, FRSKY_FIRMWARE_EXT)) { if (f_read(&file, &information, sizeof(FrSkyFirmwareInformation), &count) != FR_OK || count != sizeof(FrSkyFirmwareInformation)) { f_close(&file); return "Format error"; @@ -322,7 +322,7 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P if (module == INTERNAL_MODULE && information.productId == FIRMWARE_ID_XJT) { INTERNAL_MODULE_ON(); RTOS_WAIT_MS(1); - intmoduleSerialStart(38400, true); + intmoduleSerialStart(38400, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b); GPIO_SetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); result = uploadFileToHorusXJT(filename, &file, progressHandler); GPIO_ResetBits(INTMODULE_BOOTCMD_GPIO, INTMODULE_BOOTCMD_GPIO_PIN); @@ -337,7 +337,7 @@ const char * FrskyDeviceFirmwareUpdate::doFlashFirmware(const char * filename, P // this ifdef can be removed if we use .frsk instead of .frk // theorically it should be possible to use an ISRM module in an XLite case INTERNAL_MODULE: - intmoduleSerialStart(57600, true); + intmoduleSerialStart(57600, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b); break; #endif diff --git a/radio/src/io/frsky_firmware_update.h b/radio/src/io/frsky_firmware_update.h index 872c948bc..eb9fb1a32 100644 --- a/radio/src/io/frsky_firmware_update.h +++ b/radio/src/io/frsky_firmware_update.h @@ -54,7 +54,7 @@ PACK(struct FrSkyFirmwareInformation { uint16_t crc; }); -const char * readFirmwareInformation(const char * filename, FrSkyFirmwareInformation & data); +const char * readFrSkyFirmwareInformation(const char * filename, FrSkyFirmwareInformation & data); class FrskyDeviceFirmwareUpdate { enum State { diff --git a/radio/src/io/multi_firmware_update.cpp b/radio/src/io/multi_firmware_update.cpp new file mode 100644 index 000000000..22a3b42fb --- /dev/null +++ b/radio/src/io/multi_firmware_update.cpp @@ -0,0 +1,564 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#if !defined(DISABLE_MULTI_UPDATE) +#include "opentx.h" +#include "multi_firmware_update.h" +#include "stk500.h" +#include "debug.h" + +#define UPDATE_MULTI_EXT_BIN ".bin" + +class MultiFirmwareUpdateDriver +{ + public: + MultiFirmwareUpdateDriver() {} + const char* flashFirmware(FIL* file, const char* label) const; + + protected: + virtual void init() const = 0; + virtual bool getByte(uint8_t& byte) const = 0; + virtual void sendByte(uint8_t byte) const = 0; + virtual void clear() const = 0; + virtual void deinit() const {} + + private: + bool getRxByte(uint8_t& byte) const; + bool checkRxByte(uint8_t byte) const; + const char * waitForInitialSync() const; + const char * getDeviceSignature(uint8_t* signature) const; + const char * loadAddress(uint32_t offset) const; + const char * progPage(uint8_t* buffer, uint16_t size) const; + void leaveProgMode() const; +}; + +#if defined(INTERNAL_MODULE_MULTI) + +class MultiInternalUpdateDriver: public MultiFirmwareUpdateDriver +{ + public: + MultiInternalUpdateDriver() {} + + protected: + void init() const override + { + INTERNAL_MODULE_ON(); + intmoduleSerialStart(57600, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b); + } + + bool getByte(uint8_t& byte) const override + { + return intmoduleFifo.pop(byte); + } + + void sendByte(uint8_t byte) const override + { + intmoduleSendByte(byte); + } + + void clear() const override + { + intmoduleFifo.clear(); + } + + void deinit() const override + { + clear(); + } +}; + +static const MultiInternalUpdateDriver multiInternalUpdateDriver; + +#endif + +class MultiExternalSoftSerialUpdateDriver: public MultiFirmwareUpdateDriver +{ + public: + MultiExternalSoftSerialUpdateDriver() {} + + protected: + void init() const override + { +#if !defined(EXTMODULE_USART) + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Pin = EXTMODULE_TX_GPIO_PIN; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_Init(EXTMODULE_TX_GPIO, &GPIO_InitStructure); +#endif + + EXTERNAL_MODULE_ON(); + telemetryPortInvertedInit(57600); + } + + bool getByte(uint8_t& byte) const override + { + return telemetryGetByte(&byte); + } + + void sendByte(uint8_t byte) const override + { + extmoduleSendInvertedByte(byte); + } + + void clear() const override + { + telemetryClearFifo(); + } + + void deinit() const override + { + telemetryPortInvertedInit(0); + clear(); + } +}; + +static const MultiExternalSoftSerialUpdateDriver multiExternalSoftSerialUpdateDriver; + +bool MultiFirmwareUpdateDriver::getRxByte(uint8_t& byte) const +{ + uint16_t time; + + time = getTmr2MHz() ; + while ( (uint16_t) (getTmr2MHz() - time) < 25000 ) { // 12.5mS + + if (getByte(byte)) { +#if defined(DEBUG_EXT_MODULE_FLASH) + TRACE("[RX] 0x%X", byte); +#endif + return true; + } + } + + byte = 0; + return false; +} + +bool MultiFirmwareUpdateDriver::checkRxByte(uint8_t byte) const +{ + uint8_t rxchar; + return getRxByte(rxchar) ? rxchar == byte : false; +} + +const char * MultiFirmwareUpdateDriver::waitForInitialSync() const +{ + uint8_t byte; + int retries = 1000; + + clear(); + do { + // Send sync request + sendByte(STK_GET_SYNC); + sendByte(CRC_EOP); + + getRxByte(byte); + wdt_reset(); + + } while((byte != STK_INSYNC) && --retries); + + if (!retries) { + return "NoSync"; + } + + if (byte != STK_INSYNC) { + return "NoSync"; + } + + if (!checkRxByte(STK_OK)) { + return "NoSync"; + } + + return nullptr; +} + +const char * MultiFirmwareUpdateDriver::getDeviceSignature(uint8_t* signature) const +{ + // Read signature + sendByte(STK_READ_SIGN); + sendByte(CRC_EOP); + + if (!checkRxByte(STK_INSYNC)) + return "NoSync"; + + for (uint8_t i=0; i<4; i++) { + if (!getRxByte(signature[i])) { + return "NoSignature"; + } + } + + return nullptr; +} + +const char * MultiFirmwareUpdateDriver::loadAddress(uint32_t offset) const +{ + sendByte(STK_LOAD_ADDRESS); + sendByte(offset & 0xFF); // low byte + sendByte(offset >> 8); // high byte + sendByte(CRC_EOP); + + if (!checkRxByte(STK_INSYNC) || !checkRxByte(STK_OK)) { + return "NoSync"; + } + + return nullptr; +} + +const char * MultiFirmwareUpdateDriver::progPage(uint8_t* buffer, uint16_t size) const +{ + sendByte(STK_PROG_PAGE); + + // page size + sendByte(size >> 8); + sendByte(size & 0xFF); + + // flash/eeprom flag + sendByte(0); + + for (uint16_t i=0; i < size; i++) { + sendByte(buffer[i]); + } + sendByte(CRC_EOP); + + if (!checkRxByte(STK_INSYNC)) + return "NoSync"; + + uint8_t byte; + uint8_t retries = 4; + do { + getRxByte(byte); + wdt_reset(); + } while(!byte && --retries); + + if (!retries || (byte != STK_OK)) + return "NoPageSync"; + + return nullptr; +} + +void MultiFirmwareUpdateDriver::leaveProgMode() const +{ + sendByte(STK_LEAVE_PROGMODE); + sendByte(CRC_EOP); + + // eat last sync byte + checkRxByte(STK_INSYNC); + deinit(); +} + +const char * MultiFirmwareUpdateDriver::flashFirmware(FIL* file, const char* label) const +{ + const char* result = nullptr; + init(); + + /* wait 500ms for power on */ + watchdogSuspend(500); + RTOS_WAIT_MS(500); + + result = waitForInitialSync(); + if (result) { + leaveProgMode(); + return result; + } + + unsigned char signature[4]; // 3 bytes signature + STK_OK + result = getDeviceSignature(signature); + if (result) { + leaveProgMode(); + return result; + } + + uint8_t buffer[256]; + uint16_t pageSize = 128; + uint32_t writeOffset = 0; + + if (signature[0] != 0x1E) { + leaveProgMode(); + return "Wrong signature"; + } + + if (signature[1] == 0x55 && signature[2] == 0xAA) { + pageSize = 256; + writeOffset = 0x1000; // start offset (word address) + } + + while (!f_eof(file)) { + +#if defined(COLORLCD) +#warning "TODO drawProgressScreen" +#else + drawProgressScreen(label, STR_WRITING, file->fptr, file->obj.objsize); +#endif + + UINT count=0; + memclear(buffer, pageSize); + if (f_read(file, buffer, pageSize, &count) != FR_OK) { + result = "Error reading file"; + break; + } + + if (!count) + break; + + clear(); + + result = loadAddress(writeOffset); + if (result) { + break; + } + + result = progPage(buffer, pageSize); + if (result) { + break; + } + + writeOffset += pageSize / 2; + } + + if (f_eof(file)) { +#if defined(COLORLCD) +#warning "TODO drawProgressScreen" +#else + drawProgressScreen(label, STR_WRITING, file->fptr, file->obj.objsize); +#endif + } + + leaveProgMode(); + return result; +} + +// example : multi-stm-bcsid-01020176 +#define MULTI_SIGN_SIZE 24 +#define MULTI_SIGN_BOOTLOADER_SUPPORT_OFFSET 10 +#define MULTI_SIGN_BOOTLOADER_CHECK_OFFSET 11 +#define MULTI_SIGN_TELEM_TYPE_OFFSET 12 +#define MULTI_SIGN_TELEM_INVERSION_OFFSET 13 +#define MULTI_SIGN_VERSION_OFFSET 15 + +const char * MultiFirmwareInformation::readV1Signature(const char * buffer) +{ + if (!memcmp(buffer, "multi-stm", 9)) + boardType = FIRMWARE_MULTI_STM; + else if (!memcmp(buffer, "multi-avr", 9)) + boardType = FIRMWARE_MULTI_AVR; + else if (!memcmp(buffer, "multi-orx", 9)) + boardType = FIRMWARE_MULTI_ORX; + else + return "Wrong format"; + + if(buffer[MULTI_SIGN_BOOTLOADER_SUPPORT_OFFSET] == 'b') + optibootSupport = true; + else + optibootSupport = false; + + if(buffer[MULTI_SIGN_BOOTLOADER_CHECK_OFFSET] == 'c') + bootloaderCheck = true; + else + bootloaderCheck = false; + + if(buffer[MULTI_SIGN_TELEM_TYPE_OFFSET] == 't') + telemetryType = FIRMWARE_MULTI_TELEM_MULTI_STATUS; + else if (buffer[MULTI_SIGN_TELEM_TYPE_OFFSET] == 's') + telemetryType = FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY; + else + telemetryType = FIRMWARE_MULTI_TELEM_NONE; + + if(buffer[MULTI_SIGN_TELEM_INVERSION_OFFSET] == 'i') + telemetryInversion = true; + else + telemetryInversion = false; + + return nullptr; +} + +const char * MultiFirmwareInformation::readV2Signature(const char * buffer) +{ + // new format + uint32_t options = 0; + const char * beg = buffer + 7; + const char * cursor = beg; + + while (cursor - beg < 8) { + options <<= 4; + if (*cursor >= '0' && *cursor <= '9') + options |= *cursor - '0'; + else if (*cursor >= 'a' && *cursor <= 'f') + options |= *cursor - 'a' + 10; + else if (*cursor >= 'A' && *cursor <= 'F') + options |= *cursor - 'A' + 10; + else + break; // should be '-' + cursor++; + } + + if (cursor - beg < 8) + return "Invalid signature"; + + boardType = options & 0x3; + optibootSupport = options & 0x80 ? true : false; + telemetryInversion = options & 0x200 ? true : false; + bootloaderCheck = options & 0x100 ? true : false; + + telemetryType = FIRMWARE_MULTI_TELEM_NONE; + if (options & 0x400) + telemetryType = FIRMWARE_MULTI_TELEM_MULTI_STATUS; + if (options & 0x800) + telemetryType = FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY; + + return nullptr; +} + +const char * MultiFirmwareInformation::readMultiFirmwareInformation(const char * filename) +{ + FIL file; + if (f_open(&file, filename, FA_READ) != FR_OK) + return "Error opening file"; + + const char * err = readMultiFirmwareInformation(&file); + f_close(&file); + + return err; +} + +const char * MultiFirmwareInformation::readMultiFirmwareInformation(FIL * file) +{ + char buffer[MULTI_SIGN_SIZE]; + UINT count; + + if (f_size(file) < MULTI_SIGN_SIZE) + return "File too small"; + + f_lseek(file, f_size(file) - MULTI_SIGN_SIZE); + if (f_read(file, buffer, MULTI_SIGN_SIZE, &count) != FR_OK || count != MULTI_SIGN_SIZE) { + return "Error reading file"; + } + + if (!memcmp(buffer, "multi-x", 7)) { + return readV2Signature(buffer); + } + + return readV1Signature(buffer); +} + +bool multiFlashFirmware(uint8_t moduleIdx, const char * filename) +{ + FIL file; + + if (f_open(&file, filename, FA_READ) != FR_OK) { + POPUP_WARNING("Not a valid file"); + return false; + } + + MultiFirmwareInformation firmwareFile; + if (firmwareFile.readMultiFirmwareInformation(&file)) { + f_close(&file); + POPUP_WARNING("Not a valid file"); + return false; + } + f_lseek(&file, 0); + + if (moduleIdx == EXTERNAL_MODULE) { + if (!firmwareFile.isMultiExternalFirmware()) { + f_close(&file); + POPUP_WARNING(STR_NEEDS_FILE); + SET_WARNING_INFO(STR_EXT_MULTI_SPEC, strlen(STR_EXT_MULTI_SPEC), 0); + return false; + } + } + else { + if (!firmwareFile.isMultiInternalFirmware()) { + f_close(&file); + POPUP_WARNING(STR_NEEDS_FILE); + SET_WARNING_INFO(STR_INT_MULTI_SPEC, strlen(STR_INT_MULTI_SPEC), 0); + return false; + } + } + + const MultiFirmwareUpdateDriver* driver = &multiExternalSoftSerialUpdateDriver; +#if defined(INTERNAL_MODULE_MULTI) + if (moduleIdx == INTERNAL_MODULE) + driver = &multiInternalUpdateDriver; +#endif + + pausePulses(); + +#if defined(INTERNAL_MODULE_MULTI) + uint8_t intPwr = IS_INTERNAL_MODULE_ON(); + INTERNAL_MODULE_OFF(); +#endif + + uint8_t extPwr = IS_EXTERNAL_MODULE_ON(); + EXTERNAL_MODULE_OFF(); + + SPORT_UPDATE_POWER_OFF(); + +#if defined(COLORLCD) +#warning "TODO drawProgressScreen" +#else + drawProgressScreen(getBasename(filename), STR_DEVICE_RESET, 0, 0); +#endif + + /* wait 2s off */ + watchdogSuspend(2000); + RTOS_WAIT_MS(2000); + + const char * result = driver->flashFirmware(&file, getBasename(filename)); + f_close(&file); + + AUDIO_PLAY(AU_SPECIAL_SOUND_BEEP1 ); + BACKLIGHT_ENABLE(); + + if (result) { + POPUP_WARNING(STR_FIRMWARE_UPDATE_ERROR); + SET_WARNING_INFO(result, strlen(result), 0); + } + else { + POPUP_INFORMATION(STR_FIRMWARE_UPDATE_SUCCESS); + } + + INTERNAL_MODULE_OFF(); + EXTERNAL_MODULE_OFF(); + SPORT_UPDATE_POWER_OFF(); + + /* wait 2s off */ + watchdogSuspend(2000); + RTOS_WAIT_MS(2000); + + // reset telemetry protocol + telemetryInit(255); + +#if defined(INTERNAL_MODULE_MULTI) + if (intPwr) { + INTERNAL_MODULE_ON(); + setupPulsesInternalModule(); + } +#endif + + if (extPwr) { + EXTERNAL_MODULE_ON(); + setupPulsesExternalModule(); + } + + resumePulses(); + + return result == nullptr; +} +#endif diff --git a/radio/src/io/multi_firmware_update.h b/radio/src/io/multi_firmware_update.h new file mode 100644 index 000000000..6713d5cfb --- /dev/null +++ b/radio/src/io/multi_firmware_update.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef OPENTX_MULTI_FIRMWARE_H +#define OPENTX_MULTI_FIRMWARE_H + +#include "ff.h" + +/* Signature format is multi-[board type]-[bootloader support][check for bootloader][multi telemetry type][telemetry inversion][debug]-[firmware version] + Where: + [board type] is avr, stm, or orx + [bootloader support] b for optiboot (AVR) / USB (STM) or u (unsupported) + [check for bootloader] is c (CHECK_FOR_BOOTLOADER) or u (undefined) + [telemetry type] is t (MULTI_TELEMETRY), s (MULTI_STATUS), or u (undefined) for neither + [telemetry inversion] is i (INVERT_TELEMETRY) or u (undefined) + [firmware version] is the version padded to two bytes per segment, without seperators e.g. 01020176 + + For example: REM multi-stm-bcsid-01020176 +*/ + +class MultiFirmwareInformation { + public: + enum MultiFirmwareBoardType { + FIRMWARE_MULTI_AVR = 0, + FIRMWARE_MULTI_STM, + FIRMWARE_MULTI_ORX, + }; + + enum MultiFirmwareTelemetryType { + FIRMWARE_MULTI_TELEM_NONE = 0, + FIRMWARE_MULTI_TELEM_MULTI_STATUS, // erSkyTX + FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY, // OpenTX + }; + + bool isMultiStmFirmware() const + { + return boardType == FIRMWARE_MULTI_STM; + } + + bool isMultiAvrFirmware() const + { + return boardType == FIRMWARE_MULTI_AVR; + } + + bool isMultiOrxFirmware() const + { + return boardType == FIRMWARE_MULTI_ORX; + } + + bool isMultiWithBootloaderFirmware() const + { + return optibootSupport; + } + + bool isMultiInternalFirmware() const + { + return (boardType == FIRMWARE_MULTI_STM && telemetryInversion == false && optibootSupport == true && bootloaderCheck == true && telemetryType == FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY); + } + + bool isMultiExternalFirmware() const + { + return (boardType == FIRMWARE_MULTI_STM && telemetryInversion == true && optibootSupport == true && bootloaderCheck == true && telemetryType == FIRMWARE_MULTI_TELEM_MULTI_TELEMETRY); + } + + const char * readMultiFirmwareInformation(const char * filename); + const char * readMultiFirmwareInformation(FIL * file); + + private: + uint8_t boardType; + uint8_t optibootSupport; + uint8_t bootloaderCheck; + uint8_t telemetryType; + uint8_t telemetryInversion; + uint8_t firmwareVersionMajor; + uint8_t firmwareVersionMinor; + uint8_t firmwareVersionRevision; + uint8_t firmwareVersionSubRevision; + + const char * readV1Signature(const char * buffer); + const char * readV2Signature(const char * buffer); +}; + +bool multiFlashFirmware(uint8_t module, const char * filename); + +#endif //OPENTX_MULTI_FIRMWARE_H diff --git a/radio/src/io/stk500.h b/radio/src/io/stk500.h new file mode 100644 index 000000000..ca0dd91df --- /dev/null +++ b/radio/src/io/stk500.h @@ -0,0 +1,39 @@ +/* STK500 constants list, from AVRDUDE */ +#define STK_OK 0x10 +#define STK_FAILED 0x11 // Not used +#define STK_UNKNOWN 0x12 // Not used +#define STK_NODEVICE 0x13 // Not used +#define STK_INSYNC 0x14 // ' ' +#define STK_NOSYNC 0x15 // Not used +#define ADC_CHANNEL_ERROR 0x16 // Not used +#define ADC_MEASURE_OK 0x17 // Not used +#define PWM_CHANNEL_ERROR 0x18 // Not used +#define PWM_ADJUST_OK 0x19 // Not used +#define CRC_EOP 0x20 // 'SPACE' +#define STK_GET_SYNC 0x30 // '0' +#define STK_GET_SIGN_ON 0x31 // '1' +#define STK_SET_PARAMETER 0x40 // '@' +#define STK_GET_PARAMETER 0x41 // 'A' +#define STK_SET_DEVICE 0x42 // 'B' +#define STK_SET_DEVICE_EXT 0x45 // 'E' +#define STK_ENTER_PROGMODE 0x50 // 'P' +#define STK_LEAVE_PROGMODE 0x51 // 'Q' +#define STK_CHIP_ERASE 0x52 // 'R' +#define STK_CHECK_AUTOINC 0x53 // 'S' +#define STK_LOAD_ADDRESS 0x55 // 'U' +#define STK_UNIVERSAL 0x56 // 'V' +#define STK_PROG_FLASH 0x60 // '`' +#define STK_PROG_DATA 0x61 // 'a' +#define STK_PROG_FUSE 0x62 // 'b' +#define STK_PROG_LOCK 0x63 // 'c' +#define STK_PROG_PAGE 0x64 // 'd' +#define STK_PROG_FUSE_EXT 0x65 // 'e' +#define STK_READ_FLASH 0x70 // 'p' +#define STK_READ_DATA 0x71 // 'q' +#define STK_READ_FUSE 0x72 // 'r' +#define STK_READ_LOCK 0x73 // 's' +#define STK_READ_PAGE 0x74 // 't' +#define STK_READ_SIGN 0x75 // 'u' +#define STK_READ_OSCCAL 0x76 // 'v' +#define STK_READ_FUSE_EXT 0x77 // 'w' +#define STK_READ_OSCCAL_EXT 0x78 // 'x' diff --git a/radio/src/lua/CMakeLists.txt b/radio/src/lua/CMakeLists.txt index 9c4f41897..b2abeb7fb 100644 --- a/radio/src/lua/CMakeLists.txt +++ b/radio/src/lua/CMakeLists.txt @@ -17,6 +17,7 @@ set(LUA_INCLUDES if(PYTHONINTERP_FOUND) add_lua_export_target(x9lite ${LUA_INCLUDES} -DPCBTARANIS -DPCBX9LITE -DPCBX9) + add_lua_export_target(x9lites ${LUA_INCLUDES} -DPCBTARANIS -DPCBX9LITES -DPCBX9LITE -DPCBX9) add_lua_export_target(x7 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_X7) add_lua_export_target(xlite ${LUA_INCLUDES} -DPCBTARANIS -DPCBXLITE) add_lua_export_target(xlites ${LUA_INCLUDES} -DPCBTARANIS -DPCBXLITES -DPCBXLITE -DGYRO) @@ -25,4 +26,5 @@ if(PYTHONINTERP_FOUND) add_lua_export_target(x10 ${LUA_INCLUDES} -DPCBHORUS -DPCBX10) add_lua_export_target(x12s ${LUA_INCLUDES} -DPCBHORUS -DPCBX12S) add_lua_export_target(t12 ${LUA_INCLUDES} -DPCBTARANIS -DPCBX7 -DRADIO_T12) + add_lua_export_target(t16 ${LUA_INCLUDES} -DPCBHORUS -DPCBX10 -DRADIO_T16) endif() diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index dd5d5bf30..e1cfd4999 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -27,6 +27,8 @@ #if defined(PCBX12S) #include "lua/lua_exports_x12s.inc" // this line must be after lua headers +#elif defined(RADIO_T16) + #include "lua/lua_exports_t16.inc" #elif defined(PCBX10) #include "lua/lua_exports_x10.inc" #elif defined(PCBX9E) @@ -35,6 +37,8 @@ #include "lua/lua_exports_x7.inc" #elif defined(RADIO_T12) #include "lua/lua_exports_t12.inc" +#elif defined(PCBX9LITES) + #include "lua/lua_exports_x9lites.inc" #elif defined(PCBX9LITE) #include "lua/lua_exports_x9lite.inc" #elif defined(PCBXLITES) @@ -54,10 +58,10 @@ #define FIND_FIELD_DESC 0x01 #define KEY_EVENTS(xxx, yyy) \ - { "EVT_"#xxx"_FIRST", EVT_KEY_FIRST(yyy) }, \ - { "EVT_"#xxx"_BREAK", EVT_KEY_BREAK(yyy) }, \ - { "EVT_"#xxx"_LONG", EVT_KEY_LONG(yyy) }, \ - { "EVT_"#xxx"_REPT", EVT_KEY_REPT(yyy) } + { "EVT_"#xxx"_FIRST", EVT_KEY_FIRST(yyy) }, \ + { "EVT_"#xxx"_BREAK", EVT_KEY_BREAK(yyy) }, \ + { "EVT_"#xxx"_LONG", EVT_KEY_LONG(yyy) }, \ + { "EVT_"#xxx"_REPT", EVT_KEY_REPT(yyy) } /*luadoc @function getVersion() @@ -484,13 +488,7 @@ static int luaSportTelemetryPush(lua_State * L) outputTelemetryBuffer.pushSportPacketWithBytestuffing(packet); #if defined(PXX2) uint8_t destination = (IS_INTERNAL_MODULE_ON() ? INTERNAL_MODULE : EXTERNAL_MODULE); - - if (isModulePXX2(destination)) { - outputTelemetryBuffer.setDestination(destination << 2); - } - else { - outputTelemetryBuffer.setDestination(TELEMETRY_ENDPOINT_SPORT); - } + outputTelemetryBuffer.setDestination(isModulePXX2(destination) ? (destination << 2) : TELEMETRY_ENDPOINT_SPORT); #else outputTelemetryBuffer.setDestination(TELEMETRY_ENDPOINT_SPORT); #endif @@ -1379,7 +1377,7 @@ static int luaChdir(lua_State * L) @function loadScript(file [, mode], [,env]) Load a Lua script file. This is similar to Lua's own [loadfile()](https://www.lua.org/manual/5.2/manual.html#pdf-loadfile) -API method, but it uses OpenTx's optional pre-compilation feature to save memory and time during load. +API method, but it uses OpenTx's optional pre-compilation feature to save memory and time during load. Return values are same as from Lua API loadfile() method: If the script was loaded w/out errors then the loaded script (or "chunk") is returned as a function. Otherwise, returns nil plus the error message. @@ -1675,53 +1673,61 @@ const luaR_value_entry opentxConstants[] = { { "FIXEDWIDTH", FIXEDWIDTH }, #endif -// Virtual Page Next/Previous -#if defined(KEYS_GPIO_REG_PGUP) && defined(KEYS_GPIO_REG_PGDN) - { "EVT_VIRTUAL_PREVIOUS_PAGE", EVT_KEY_FIRST(KEY_PGUP) }, - { "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_FIRST(KEY_PGDN) }, -#elif defined(KEYS_GPIO_REG_PGDN) - { "EVT_VIRTUAL_PREVIOUS_PAGE", EVT_KEY_LONG(KEY_PGDN) }, - { "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_BREAK(KEY_PGDN) }, -#elif defined(KEYS_GPIO_REG_UP) && defined(KEYS_GPIO_REG_DOWN) - { "EVT_VIRTUAL_PREVIOUS_PAGE", EVT_KEY_LONG(KEY_UP) }, - { "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_LONG(KEY_DOWN) }, -#elif defined(KEYS_GPIO_REG_PAGE) - { "EVT_VIRTUAL_PREVIOUS_PAGE", EVT_KEY_LONG(KEY_PAGE) }, - { "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_BREAK(KEY_PAGE) }, +// Virtual events +#if defined(ROTARY_ENCODER_NAVIGATION) + { "EVT_VIRTUAL_PREV", EVT_ROTARY_LEFT }, + { "EVT_VIRTUAL_NEXT", EVT_ROTARY_RIGHT }, + { "EVT_VIRTUAL_DEC", EVT_ROTARY_LEFT }, + { "EVT_VIRTUAL_INC", EVT_ROTARY_RIGHT }, +#elif defined(PCBX9D) || defined(PCBX9DP) // key reverted between field nav and value change + { "EVT_VIRTUAL_PREV", EVT_KEY_FIRST(KEY_PLUS) }, + { "EVT_VIRTUAL_PREV_REPT", EVT_KEY_REPT(KEY_PLUS) }, + { "EVT_VIRTUAL_NEXT", EVT_KEY_FIRST(KEY_MINUS) }, + { "EVT_VIRTUAL_NEXT_REPT", EVT_KEY_REPT(KEY_MINUS) }, + { "EVT_VIRTUAL_DEC", EVT_KEY_FIRST(KEY_MINUS) }, + { "EVT_VIRTUAL_DEC_REPT", EVT_KEY_REPT(KEY_MINUS) }, + { "EVT_VIRTUAL_INC", EVT_KEY_FIRST(KEY_PLUS) }, + { "EVT_VIRTUAL_INC_REPT", EVT_KEY_REPT(KEY_PLUS) }, +#else + { "EVT_VIRTUAL_PREV", EVT_KEY_FIRST(KEY_UP) }, + { "EVT_VIRTUAL_PREV_REPT", EVT_KEY_REPT(KEY_UP) }, + { "EVT_VIRTUAL_NEXT", EVT_KEY_FIRST(KEY_DOWN) }, + { "EVT_VIRTUAL_NEXT_REPT", EVT_KEY_REPT(KEY_DOWN) }, + { "EVT_VIRTUAL_DEC", EVT_KEY_FIRST(KEY_DOWN) }, + { "EVT_VIRTUAL_DEC_REPT", EVT_KEY_REPT(KEY_DOWN) }, + { "EVT_VIRTUAL_INC", EVT_KEY_FIRST(KEY_UP) }, + { "EVT_VIRTUAL_INC_REPT", EVT_KEY_REPT(KEY_UP) }, #endif -// Virtual exit - { "EVT_VIRTUAL_EXIT", EVT_KEY_BREAK(KEY_EXIT) }, - -// Virtual enter -#if defined(KEYS_GPIO_REG_ENTER) +#if defined(NAVIGATION_9X) || defined(NAVIGATION_XLITE) + { "EVT_VIRTUAL_PREV_PAGE", EVT_KEY_LONG(KEY_LEFT) }, + { "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_BREAK(KEY_LEFT) }, + { "EVT_VIRTUAL_MENU", EVT_KEY_BREAK(KEY_RIGHT) }, + { "EVT_VIRTUAL_MENU_LONG", EVT_KEY_LONG(KEY_RIGHT) }, { "EVT_VIRTUAL_ENTER", EVT_KEY_BREAK(KEY_ENTER) }, { "EVT_VIRTUAL_ENTER_LONG", EVT_KEY_LONG(KEY_ENTER) }, -#endif - -// Virtual menu -#if defined(KEYS_GPIO_REG_MENU) + { "EVT_VIRTUAL_EXIT", EVT_KEY_BREAK(KEY_EXIT) }, +#elif defined(NAVIGATION_X7) || defined(NAVIGATION_X9D) + { "EVT_VIRTUAL_PREV_PAGE", EVT_KEY_LONG(KEY_PAGE) }, + { "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_BREAK(KEY_PAGE) }, { "EVT_VIRTUAL_MENU", EVT_KEY_BREAK(KEY_MENU) }, { "EVT_VIRTUAL_MENU_LONG", EVT_KEY_LONG(KEY_MENU) }, -#elif defined(KEYS_GPIO_REG_SHIFT) - { "EVT_VIRTUAL_MENU", EVT_KEY_BREAK(KEY_SHIFT) }, - { "EVT_VIRTUAL_MENU_LONG", EVT_KEY_LONG(KEY_SHIFT) }, + { "EVT_VIRTUAL_ENTER", EVT_KEY_BREAK(KEY_ENTER) }, + { "EVT_VIRTUAL_ENTER_LONG", EVT_KEY_LONG(KEY_ENTER) }, + { "EVT_VIRTUAL_EXIT", EVT_KEY_BREAK(KEY_EXIT) }, +#elif defined(NAVIGATION_HORUS) +#if defined(KEYS_GPIO_REG_PGUP) + { "EVT_VIRTUAL_PREV_PAGE", EVT_KEY_BREAK(KEY_PGUP) }, + { "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_BREAK(KEY_PGDN) }, +#else + { "EVT_VIRTUAL_PREV_PAGE", EVT_KEY_LONG(KEY_PGDN) }, + { "EVT_VIRTUAL_NEXT_PAGE", EVT_KEY_BREAK(KEY_PGDN) }, #endif - -// Virtual generic plus-next-right minus-previous-left -#if defined(ROTARY_ENCODER_NAVIGATION) - { "EVT_VIRTUAL_NEXT", EVT_ROTARY_RIGHT}, - { "EVT_VIRTUAL_PREVIOUS", EVT_ROTARY_LEFT }, -#elif defined(KEYS_GPIO_REG_RIGHT) && defined(KEYS_GPIO_REG_LEFT) - { "EVT_VIRTUAL_NEXT", EVT_KEY_FIRST(KEY_RIGHT) }, - { "EVT_VIRTUAL_NEXT_REPT", EVT_KEY_REPT(KEY_RIGHT) }, - { "EVT_VIRTUAL_PREVIOUS", EVT_KEY_FIRST(KEY_LEFT) }, - { "EVT_VIRTUAL_PREVIOUS_REPT", EVT_KEY_REPT(KEY_LEFT) }, -#elif defined(KEYS_GPIO_REG_PLUS) && defined(KEYS_GPIO_REG_MINUS) - { "EVT_VIRTUAL_NEXT", EVT_KEY_FIRST(KEY_PLUS) }, - { "EVT_VIRTUAL_NEXT_REPT", EVT_KEY_REPT(KEY_PLUS) }, - { "EVT_VIRTUAL_PREVIOUS", EVT_KEY_FIRST(KEY_MINUS) }, - { "EVT_VIRTUAL_PREVIOUS_REPT", EVT_KEY_REPT(KEY_MINUS) }, + { "EVT_VIRTUAL_MENU", EVT_KEY_BREAK(KEY_MODEL) }, + { "EVT_VIRTUAL_MENU_LONG", EVT_KEY_LONG(KEY_MODEL) }, + { "EVT_VIRTUAL_ENTER", EVT_KEY_BREAK(KEY_ENTER) }, + { "EVT_VIRTUAL_ENTER_LONG", EVT_KEY_LONG(KEY_ENTER) }, + { "EVT_VIRTUAL_EXIT", EVT_KEY_BREAK(KEY_EXIT) }, #endif #if defined(KEYS_GPIO_REG_EXIT) diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index 6bf3658d8..65bb79879 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -1151,11 +1151,11 @@ bool readToolName(char * toolName, const char * filename) return false; uint8_t len = end - start; - if (len > TOOL_NAME_MAXLEN) + if (len > RADIO_TOOL_NAME_MAXLEN) return false; strncpy(toolName, start, len); - memclear(toolName + len, TOOL_NAME_MAXLEN + 1 - len); + memclear(toolName + len, RADIO_TOOL_NAME_MAXLEN + 1 - len); return true; } diff --git a/radio/src/lua/lua_api.h b/radio/src/lua/lua_api.h index 007e7b8f1..71a1cef01 100644 --- a/radio/src/lua/lua_api.h +++ b/radio/src/lua/lua_api.h @@ -171,7 +171,12 @@ void registerBitmapClass(lua_State * L); void luaSetInstructionsLimit(lua_State* L, int count); int luaLoadScriptFileToState(lua_State * L, const char * filename, const char * mode); -#define TOOL_NAME_MAXLEN 16 +#if LCD_W > 350 + #define RADIO_TOOL_NAME_MAXLEN 40 +#else + #define RADIO_TOOL_NAME_MAXLEN 16 +#endif + bool readToolName(char * toolName, const char * filename); bool isRadioScriptTool(const char * filename); diff --git a/radio/src/main.cpp b/radio/src/main.cpp index 827dece1d..0a8711643 100644 --- a/radio/src/main.cpp +++ b/radio/src/main.cpp @@ -515,11 +515,9 @@ void perMain() #endif #if defined(STM32) - bool sdcardPresent = SD_CARD_PRESENT(); - if (sdcardPresent && !globalData.sdcardPresent) { + if (SD_CARD_PRESENT() && !sdMounted()) { sdMount(); } - globalData.sdcardPresent = sdcardPresent; #endif #if !defined(EEPROM) diff --git a/radio/src/mixer.cpp b/radio/src/mixer.cpp index 11c19c9ee..48869b577 100644 --- a/radio/src/mixer.cpp +++ b/radio/src/mixer.cpp @@ -155,6 +155,8 @@ void applyExpos(int16_t * anas, uint8_t mode, uint8_t ovwrIdx, int16_t ovwrValue continue; if (ed->flightModes & (1<srcRaw >= MIXSRC_FIRST_TRAINER && ed->srcRaw <= MIXSRC_LAST_TRAINER && !IS_TRAINER_INPUT_VALID()) + continue; if (getSwitch(ed->swtch)) { int32_t v; if (ed->srcRaw == ovwrIdx) { @@ -218,6 +220,17 @@ void applyExpos(int16_t * anas, uint8_t mode, uint8_t ovwrIdx, int16_t ovwrValue // rescaled from -262144 to 262144 int16_t applyLimits(uint8_t channel, int32_t value) { +#if defined(OVERRIDE_CHANNEL_FUNCTION) + if (safetyCh[channel] != OVERRIDE_CHANNEL_UNDEFINED) { + // safety channel available for channel check + return calc100toRESX(safetyCh[channel]); + } +#endif + + if (isFunctionActive(FUNCTION_TRAINER_CHANNELS) && IS_TRAINER_INPUT_VALID()) { + return ppmInput[channel]; + } + LimitData * lim = limitAddress(channel); if (lim->curve) { @@ -271,17 +284,12 @@ int16_t applyLimits(uint8_t channel, int32_t value) ofs += tmp; // ofs can to added directly because already recalculated, } - if (ofs > lim_p) ofs = lim_p; - if (ofs < lim_n) ofs = lim_n; - - if (lim->revert) ofs = -ofs; // finally do the reverse. - -#if defined(OVERRIDE_CHANNEL_FUNCTION) - if (safetyCh[channel] != OVERRIDE_CHANNEL_UNDEFINED) { - // safety channel available for channel check - ofs = calc100toRESX(safetyCh[channel]); - } -#endif + if (ofs > lim_p) + ofs = lim_p; + if (ofs < lim_n) + ofs = lim_n; + if (lim->revert) + ofs = -ofs; // finally do the reverse. return ofs; } @@ -307,7 +315,7 @@ getvalue_t getValue(mixsrc_t i) } #endif - else if (i <= MIXSRC_LAST_POT+NUM_MOUSE_ANALOGS) { + else if (i <= MIXSRC_LAST_POT + NUM_MOUSE_ANALOGS) { return calibratedAnalogs[i - MIXSRC_Rud]; } @@ -338,8 +346,8 @@ getvalue_t getValue(mixsrc_t i) // TODO : find a better define #if defined(PCBFRSKY) || defined(PCBFLYSKY) - else if ((i >= MIXSRC_FIRST_SWITCH) && (i <= MIXSRC_LAST_SWITCH)) { - mixsrc_t sw = i-MIXSRC_FIRST_SWITCH; + else if (i >= MIXSRC_FIRST_SWITCH && i <= MIXSRC_LAST_SWITCH) { + mixsrc_t sw = i - MIXSRC_FIRST_SWITCH; if (SWITCH_EXISTS(sw)) { return (switchState(3*sw) ? -1024 : (IS_CONFIG_3POS(sw) && switchState(3*sw+1) ? 0 : 1024)); } @@ -417,7 +425,7 @@ void evalInputs(uint8_t mode) { BeepANACenter anaCenter = 0; - for (uint8_t i=0; i [-1024..1024] uint8_t ch = (i < NUM_STICKS ? CONVERT_MODE(i) : i); int16_t v = anaIn(i); @@ -462,12 +470,12 @@ void evalInputs(uint8_t mode) v = 0; } - if (mode <= e_perout_mode_inactive_flight_mode && isFunctionActive(FUNCTION_TRAINER+ch) && IS_TRAINER_INPUT_VALID()) { + if (mode <= e_perout_mode_inactive_flight_mode && isFunctionActive(FUNCTION_TRAINER_STICK1+ch) && IS_TRAINER_INPUT_VALID()) { // trainer mode TrainerMix* td = &g_eeGeneral.trainer.mix[ch]; if (td->mode) { uint8_t chStud = td->srcChn; - int32_t vStud = (ppmInput[chStud]- g_eeGeneral.trainer.calib[chStud]); + int32_t vStud = (ppmInput[chStud] - g_eeGeneral.trainer.calib[chStud]); vStud *= td->studWeight; vStud /= 50; switch (td->mode) { @@ -721,7 +729,7 @@ void evalFlightModeMixes(uint8_t mode, uint8_t tick10ms) } if (mode==e_perout_mode_normal && (!mixCondition || mixEnabled || swOn[i].delay)) { - if (md->mixWarn) + if (md->mixWarn) lv_mixWarning |= 1 << (md->mixWarn - 1); swOn[i].activeMix = true; } diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index 4141f6987..0d664729c 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -38,7 +38,7 @@ #define HAS_WIRELESS_TRAINER_HARDWARE() (g_eeGeneral.auxSerialMode==UART_MODE_SBUS_TRAINER) #elif defined(PCBTARANIS) #define IS_TRAINER_EXTERNAL_MODULE() (g_model.trainerData.mode == TRAINER_MODE_MASTER_SBUS_EXTERNAL_MODULE || g_model.trainerData.mode == TRAINER_MODE_MASTER_CPPM_EXTERNAL_MODULE) - #define HAS_WIRELESS_TRAINER_HARDWARE() (g_eeGeneral.auxSerialMode==UART_MODE_SBUS_TRAINER) + #define HAS_WIRELESS_TRAINER_HARDWARE() (g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) #else #define IS_TRAINER_EXTERNAL_MODULE() false #endif diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index 7b9083566..6c87d6d5c 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -849,6 +849,21 @@ void checkSDVersion() } #endif +#if defined(MULTIMODULE) +void checkMultiLowPower() +{ + if (isModuleMultimodule(EXTERNAL_MODULE) && g_model.moduleData[EXTERNAL_MODULE].multi.lowPowerMode) { + ALERT("MULTI", STR_WARN_MULTI_LOWPOWER, AU_ERROR); + return; + } +#if defined(INTERNAL_MODULE_MULTI) + if (isModuleMultimodule(INTERNAL_MODULE) && g_model.moduleData[INTERNAL_MODULE].multi.lowPowerMode) { + ALERT("MULTI", STR_WARN_MULTI_LOWPOWER, AU_ERROR); + } +#endif +} +#endif + #if defined(STM32) static void checkRTCBattery() { @@ -865,6 +880,12 @@ static void checkRTCBattery() void checkFailsafe() { for (int i=0; i= MODULE_MODE_BEEP_FIRST || multiModuleStatus.isBinding()) { + if (moduleState[i].mode >= MODULE_MODE_BEEP_FIRST || getMultiModuleStatus(i).isBinding()) { #else if (moduleState[i].mode >= MODULE_MODE_BEEP_FIRST) { #endif @@ -1881,8 +1907,6 @@ void opentxInit() } #if defined(SDCARD) - globalData.sdcardPresent = SD_CARD_PRESENT(); - // SDCARD related stuff, only done if not unexpectedShutdown if (!globalData.unexpectedShutdown) { sdInit(); @@ -1891,7 +1915,7 @@ void opentxInit() sportStopSendByteLoop(); if (f_stat(AUTOUPDATE_FILENAME, nullptr) == FR_OK) { FrSkyFirmwareInformation information; - if (readFirmwareInformation(AUTOUPDATE_FILENAME, information) == nullptr) { + if (readFrSkyFirmwareInformation(AUTOUPDATE_FILENAME, information) == nullptr) { #if defined(BLUETOOTH) if (information.productFamily == FIRMWARE_FAMILY_BLUETOOTH_CHIP) { if (bluetooth.flashFirmware(AUTOUPDATE_FILENAME) == nullptr) diff --git a/radio/src/opentx.h b/radio/src/opentx.h index 7614473a2..411b483ee 100644 --- a/radio/src/opentx.h +++ b/radio/src/opentx.h @@ -561,6 +561,8 @@ bool setTrimValue(uint8_t phase, uint8_t idx, int trim); #if defined(PCBSKY9X) #define ROTARY_ENCODER_GRANULARITY (2 << g_eeGeneral.rotarySteps) +#elif defined(RADIO_T16) + #define ROTARY_ENCODER_GRANULARITY (1) #else #define ROTARY_ENCODER_GRANULARITY (2) #endif @@ -584,9 +586,8 @@ void flightReset(uint8_t check=true); PACK(struct GlobalData { uint8_t unexpectedShutdown:1; - uint8_t sdcardPresent:1; uint8_t externalAntennaEnabled: 1; - uint8_t spare:5; + uint8_t spare:6; }); extern GlobalData globalData; @@ -887,8 +888,9 @@ uint8_t lswFamily(uint8_t func); int16_t lswTimerValue(delayval_t val); enum FunctionsActive { - FUNCTION_TRAINER, - FUNCTION_INSTANT_TRIM = FUNCTION_TRAINER+4, + FUNCTION_TRAINER_STICK1, + FUNCTION_TRAINER_CHANNELS = FUNCTION_TRAINER_STICK1 + NUM_STICKS, + FUNCTION_INSTANT_TRIM, FUNCTION_VARIO, FUNCTION_BACKLIGHT, #if defined(SDCARD) @@ -1085,6 +1087,8 @@ union ReusableBuffer char msg[64]; uint8_t r9mPower; int8_t antennaMode; + uint8_t previousType; + uint8_t newType; BindInformation bindInformation; struct { union { @@ -1169,12 +1173,11 @@ union ReusableBuffer struct { uint8_t bars[LCD_W]; -#if defined(COLORLCD) uint8_t max[LCD_W]; -#endif uint32_t freq; uint32_t span; uint32_t step; + uint32_t track; uint8_t spanDefault; uint8_t spanMax; uint16_t freqDefault; @@ -1383,4 +1386,9 @@ inline bool isAsteriskDisplayed() #include "module.h" +#if defined(ACCESS_LIB) +// TODO should be inside module.h +#include "thirdparty/libACCESS/libAccess.h" +#endif + #endif // _OPENTX_H_ diff --git a/radio/src/options.h b/radio/src/options.h index 1038af319..e7ddb0caf 100644 --- a/radio/src/options.h +++ b/radio/src/options.h @@ -56,6 +56,9 @@ static const char * options[] = { #if defined(INTERNAL_MODULE_PPM) "internalppm", #endif +#if defined(INTERNAL_MODULE_MULTI) + "internalmulti", +#endif #if defined(MULTIMODULE) "multimodule", #endif diff --git a/radio/src/pulses/modules_constants.h b/radio/src/pulses/modules_constants.h index b640f0611..cd173ff83 100644 --- a/radio/src/pulses/modules_constants.h +++ b/radio/src/pulses/modules_constants.h @@ -33,7 +33,7 @@ enum ModuleType { MODULE_TYPE_R9M_PXX2, MODULE_TYPE_R9M_LITE_PXX1, MODULE_TYPE_R9M_LITE_PXX2, - MODULE_TYPE_R9M_LITE_PRO_PXX1, + MODULE_TYPE_R9M_LITE_PRO_PXX1, // Doesn't exist MODULE_TYPE_R9M_LITE_PRO_PXX2, MODULE_TYPE_SBUS, MODULE_TYPE_XJT_LITE_PXX2, @@ -154,7 +154,10 @@ enum ModuleSubtypeMulti { MODULE_SUBTYPE_MULTI_POTENSIC, MODULE_SUBTYPE_MULTI_ZSX, MODULE_SUBTYPE_MULTI_FLYZONE, - MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_FLYZONE + MODULE_SUBTYPE_MULTI_SCANNER, + MODULE_SUBTYPE_MULTI_FRSKYX_RX, + MODULE_SUBTYPE_MULTI_AFHDS2A_RX, + MODULE_SUBTYPE_MULTI_LAST = MODULE_SUBTYPE_MULTI_AFHDS2A_RX }; enum MMDSM2Subtypes { diff --git a/radio/src/pulses/modules_helpers.h b/radio/src/pulses/modules_helpers.h index 098de5984..a5240b1ea 100644 --- a/radio/src/pulses/modules_helpers.h +++ b/radio/src/pulses/modules_helpers.h @@ -139,9 +139,13 @@ inline bool isModuleTypePPM(uint8_t type) return type == MODULE_TYPE_PPM; } -inline bool isModulePPM(uint8_t idx) +inline bool isModulePPM(uint8_t moduleIdx) { - return isModuleTypePPM(g_model.moduleData[idx].type); +#if defined(PCBSKY9X) + if (moduleIdx == EXTRA_MODULE) + return true; +#endif + return isModuleTypePPM(g_model.moduleData[moduleIdx].type); } inline bool isModuleTypeR9MNonAccess(uint8_t type) @@ -389,22 +393,24 @@ inline bool isModuleModelIndexAvailable(uint8_t idx) return false; } -inline bool isModuleFailsafeAvailable(uint8_t idx) +inline bool isModuleFailsafeAvailable(uint8_t moduleIdx) { #if defined(PXX2) - if (isModuleISRM(idx)) + if (isModuleISRM(moduleIdx)) return true; #endif - if (isModuleXJT(idx)) - return g_model.moduleData[idx].subType == MODULE_SUBTYPE_PXX1_ACCST_D16; + if (isModuleXJT(moduleIdx)) + return g_model.moduleData[moduleIdx].subType == MODULE_SUBTYPE_PXX1_ACCST_D16; #if defined(MULTIMODULE) - if (isModuleMultimodule(idx)) - return multiModuleStatus.isValid() && multiModuleStatus.supportsFailsafe(); + if (isModuleMultimodule(moduleIdx)){ + MultiModuleStatus& status = getMultiModuleStatus(moduleIdx); + return status.isValid() && status.supportsFailsafe(); + } #endif - if (isModuleR9M(idx)) + if (isModuleR9M(moduleIdx)) return true; return false; diff --git a/radio/src/pulses/multi.cpp b/radio/src/pulses/multi.cpp index babfc4bb1..7c686546f 100644 --- a/radio/src/pulses/multi.cpp +++ b/radio/src/pulses/multi.cpp @@ -31,27 +31,38 @@ #define MULTI_CHANS 16 #define MULTI_CHAN_BITS 11 -static void sendFrameProtocolHeader(uint8_t port, bool failsafe); +static void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe); -void sendChannels(uint8_t port); +void sendChannels(uint8_t moduleIdx); -static void sendSetupFrame() +static void sendMulti(uint8_t moduleIdx, uint8_t b) +{ +#if defined(HARDWARE_INTERNAL_MODULE) + if (moduleIdx == INTERNAL_MODULE) { + intmodulePulsesData.multi.sendByte(b); + } + else +#endif + sendByteSbus(b); +} + +static void sendSetupFrame(uint8_t moduleIdx) { // Old multi firmware will mark config messsages as invalid frame and throw them away - sendByteSbus('M'); - sendByteSbus('P'); - sendByteSbus(0x80); // Module Configuration - sendByteSbus(1); // 1 byte data + sendMulti(moduleIdx, 'M'); + sendMulti(moduleIdx, 'P'); + sendMulti(moduleIdx, 0x80); // Module Configuration + sendMulti(moduleIdx, 1); // 1 byte data uint8_t config = 0x01 | 0x02; // inversion + multi_telemetry #if !defined(PPM_PIN_SERIAL) // TODO why PPM_PIN_SERIAL would change MULTI protocol? config |= 0x04; // input synchronsisation #endif - sendByteSbus(config); + sendMulti(moduleIdx, config); } -static void sendFailsafeChannels(uint8_t port) +static void sendFailsafeChannels(uint8_t moduleIdx) { uint32_t bits = 0; uint8_t bitsavailable = 0; @@ -59,67 +70,73 @@ static void sendFailsafeChannels(uint8_t port) for (int i = 0; i < MULTI_CHANS; i++) { int16_t failsafeValue = g_model.failsafeChannels[i]; int pulseValue; - if (g_model.moduleData[port].failsafeMode == FAILSAFE_HOLD) - failsafeValue = FAILSAFE_CHANNEL_HOLD; - if (g_model.moduleData[port].failsafeMode == FAILSAFE_NOPULSES) - failsafeValue = FAILSAFE_CHANNEL_NOPULSE; - - if (failsafeValue == FAILSAFE_CHANNEL_HOLD) { - pulseValue = 0; - } - else if (failsafeValue == FAILSAFE_CHANNEL_NOPULSE) { + if (g_model.moduleData[moduleIdx].failsafeMode == FAILSAFE_HOLD) { pulseValue = 2047; } + else if (g_model.moduleData[moduleIdx].failsafeMode == FAILSAFE_NOPULSES) { + pulseValue = 0; + } else { - failsafeValue += 2 * PPM_CH_CENTER(g_model.moduleData[port].channelsStart + i) - 2 * PPM_CENTER; + failsafeValue += 2 * PPM_CH_CENTER(g_model.moduleData[moduleIdx].channelsStart + i) - 2 * PPM_CENTER; pulseValue = limit(1, (failsafeValue * 800 / 1000) + 1024, 2047); } bits |= pulseValue << bitsavailable; bitsavailable += MULTI_CHAN_BITS; while (bitsavailable >= 8) { - sendByteSbus((uint8_t) (bits & 0xff)); + sendMulti(moduleIdx, (uint8_t) (bits & 0xff)); bits >>= 8; bitsavailable -= 8; } } } -void setupPulsesMultimodule() +void setupPulsesMulti(uint8_t moduleIdx) { - static int counter = 0; + static int counter[2] = {0,0}; //TODO + // Every 1000 cycles (=9s) send a config packet that configures the multimodule (inversion, telemetry type) + counter[moduleIdx]++; + if (counter[moduleIdx] % 1000 == 500) { + sendSetupFrame(moduleIdx); + } + else if (counter[moduleIdx] % 1000 == 0 && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[moduleIdx].failsafeMode != FAILSAFE_RECEIVER) { + sendFrameProtocolHeader(moduleIdx, true); + sendFailsafeChannels(moduleIdx); + } + else { + // Normal Frame + sendFrameProtocolHeader(moduleIdx, false); + sendChannels(moduleIdx); + } +} + +void setupPulsesMultiExternalModule() +{ #if defined(PPM_PIN_SERIAL) extmodulePulsesData.dsm2.serialByte = 0 ; extmodulePulsesData.dsm2.serialBitCount = 0 ; #else - extmodulePulsesData.dsm2.rest = multiSyncStatus.getAdjustedRefreshRate(); + extmodulePulsesData.dsm2.rest = getMultiSyncStatus(EXTERNAL_MODULE).getAdjustedRefreshRate(); extmodulePulsesData.dsm2.index = 0; #endif extmodulePulsesData.dsm2.ptr = extmodulePulsesData.dsm2.pulses; - // Every 1000 cycles (=9s) send a config packet that configures the multimodule (inversion, telemetry type) - counter++; - if (counter % 1000 == 500) { - sendSetupFrame(); - } - else if (counter % 1000 == 0 && g_model.moduleData[EXTERNAL_MODULE].failsafeMode != FAILSAFE_NOT_SET && g_model.moduleData[EXTERNAL_MODULE].failsafeMode != FAILSAFE_RECEIVER) { - sendFrameProtocolHeader(EXTERNAL_MODULE, true); - sendFailsafeChannels(EXTERNAL_MODULE); - } - else { - // Normal Frame - sendFrameProtocolHeader(EXTERNAL_MODULE, false); - sendChannels(EXTERNAL_MODULE); - } - + setupPulsesMulti(EXTERNAL_MODULE); putDsm2Flush(); } +#if defined(INTERNAL_MODULE_MULTI) +void setupPulsesMultiInternalModule() +{ + intmodulePulsesData.multi.initFrame(); + setupPulsesMulti(INTERNAL_MODULE); +} +#endif -void sendChannels(uint8_t port) +void sendChannels(uint8_t moduleIdx) { uint32_t bits = 0; uint8_t bitsavailable = 0; @@ -128,7 +145,7 @@ void sendChannels(uint8_t port) // Range for pulses (channelsOutputs) is [-1024:+1024] for [-100%;100%] // Multi uses [204;1843] as [-100%;100%] for (int i = 0; i < MULTI_CHANS; i++) { - int channel = g_model.moduleData[port].channelsStart + i; + int channel = g_model.moduleData[moduleIdx].channelsStart + i; int value = channelOutputs[channel] + 2 * PPM_CH_CENTER(channel) - 2 * PPM_CENTER; // Scale to 80% @@ -138,36 +155,45 @@ void sendChannels(uint8_t port) bits |= value << bitsavailable; bitsavailable += MULTI_CHAN_BITS; while (bitsavailable >= 8) { - sendByteSbus((uint8_t) (bits & 0xff)); + sendMulti(moduleIdx, (uint8_t) (bits & 0xff)); bits >>= 8; bitsavailable -= 8; } } } -void sendFrameProtocolHeader(uint8_t port, bool failsafe) +void sendFrameProtocolHeader(uint8_t moduleIdx, bool failsafe) {// byte 1+2, protocol information // Our enumeration starts at 0 - int type = g_model.moduleData[port].getMultiProtocol(false) + 1; - int subtype = g_model.moduleData[port].subType; - int8_t optionValue = g_model.moduleData[port].multi.optionValue; + int type = g_model.moduleData[moduleIdx].getMultiProtocol(false) + 1; + int subtype = g_model.moduleData[moduleIdx].subType; + int8_t optionValue = g_model.moduleData[moduleIdx].multi.optionValue; uint8_t protoByte = 0; - if (moduleState[port].mode == MODULE_MODE_BIND) + + if (moduleState[moduleIdx].mode == MODULE_MODE_SPECTRUM_ANALYSER) { + sendMulti(moduleIdx, (uint8_t) 0x54); // Header byte + sendMulti(moduleIdx, (uint8_t) 54); // Spectrum custom protocol + sendMulti(moduleIdx, (uint8_t) 0); + sendMulti(moduleIdx, (uint8_t) 0); + return; + } + + if (moduleState[moduleIdx].mode == MODULE_MODE_BIND) protoByte |= MULTI_SEND_BIND; - else if (moduleState[port].mode == MODULE_MODE_RANGECHECK) + else if (moduleState[moduleIdx].mode == MODULE_MODE_RANGECHECK) protoByte |= MULTI_SEND_RANGECHECK; // rfProtocol - if (g_model.moduleData[port].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) { + if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2) { // Autobinding should always be done in DSMX 11ms - if (g_model.moduleData[port].multi.autoBindMode && moduleState[port].mode == MODULE_MODE_BIND) + if (g_model.moduleData[moduleIdx].multi.autoBindMode && moduleState[moduleIdx].mode == MODULE_MODE_BIND) subtype = MM_RF_DSM2_SUBTYPE_AUTO; // Multi module in DSM mode wants the number of channels to be used as option value - optionValue = sentModuleChannels(EXTERNAL_MODULE); + optionValue = sentModuleChannels(moduleIdx); } @@ -180,7 +206,7 @@ void sendFrameProtocolHeader(uint8_t port, bool failsafe) if (type >= 25) type = type + 1; - if (g_model.moduleData[port].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_FRSKY) { + if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_FRSKY) { if (subtype == MM_RF_FRSKY_SUBTYPE_D8) { //D8 type = 3; @@ -204,12 +230,12 @@ void sendFrameProtocolHeader(uint8_t port, bool failsafe) // Set the highest bit of option byte in AFHDS2A protocol to instruct MULTI to passthrough telemetry bytes instead // of sending Frsky D telemetry - if (g_model.moduleData[port].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) + if (g_model.moduleData[moduleIdx].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) optionValue = optionValue | 0x80; // For custom protocol send unmodified type byte - if (g_model.moduleData[port].getMultiProtocol(true) == MM_RF_CUSTOM_SELECTED) - type = g_model.moduleData[port].getMultiProtocol(false); + if (g_model.moduleData[moduleIdx].getMultiProtocol(true) == MM_RF_CUSTOM_SELECTED) + type = g_model.moduleData[moduleIdx].getMultiProtocol(false); uint8_t headerByte = 0x54; @@ -218,24 +244,24 @@ void sendFrameProtocolHeader(uint8_t port, bool failsafe) // header, byte 0, 0x55 for proto 0-31 0x54 for 32-63 if (type <= 31) - sendByteSbus(headerByte+1); + sendMulti(moduleIdx, headerByte+1); else - sendByteSbus(headerByte); + sendMulti(moduleIdx, headerByte); // protocol byte protoByte |= (type & 0x1f); - if (g_model.moduleData[port].getMultiProtocol(true) != MODULE_SUBTYPE_MULTI_DSM2) - protoByte |= (g_model.moduleData[port].multi.autoBindMode << 6); + if (g_model.moduleData[moduleIdx].getMultiProtocol(true) != MODULE_SUBTYPE_MULTI_DSM2) + protoByte |= (g_model.moduleData[moduleIdx].multi.autoBindMode << 6); - sendByteSbus(protoByte); + sendMulti(moduleIdx, protoByte); // byte 2, subtype, powermode, model id - sendByteSbus((uint8_t) ((g_model.header.modelId[port] & 0x0f) + sendMulti(moduleIdx, (uint8_t) ((g_model.header.modelId[moduleIdx] & 0x0f) | ((subtype & 0x7) << 4) - | (g_model.moduleData[port].multi.lowPowerMode << 7)) + | (g_model.moduleData[moduleIdx].multi.lowPowerMode << 7)) ); // byte 3 - sendByteSbus((uint8_t) optionValue); + sendMulti(moduleIdx, (uint8_t) optionValue); } diff --git a/radio/src/pulses/multi.h b/radio/src/pulses/multi.h new file mode 100644 index 000000000..d3f088b7d --- /dev/null +++ b/radio/src/pulses/multi.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _MULTI_PULSES_H_ +#define _MULTI_PULSES_H_ + +#include "pulses_common.h" + +class UartMultiPulses: public DataBuffer +{ + public: + void initFrame() + { + initBuffer(); + } + + void sendByte(uint8_t b) + { + if (getSize() < 64) + *ptr++ = b; + } +}; + +#endif diff --git a/radio/src/pulses/pulses.cpp b/radio/src/pulses/pulses.cpp index cec72d8a0..63b43943f 100755 --- a/radio/src/pulses/pulses.cpp +++ b/radio/src/pulses/pulses.cpp @@ -269,7 +269,7 @@ void setupPulsesExternalModule(uint8_t protocol) #if defined(MULTIMODULE) case PROTOCOL_CHANNELS_MULTIMODULE: - setupPulsesMultimodule(); + setupPulsesMultiExternalModule(); scheduleNextMixerCalculation(EXTERNAL_MODULE, MULTIMODULE_PERIOD); break; #endif @@ -287,7 +287,7 @@ void setupPulsesExternalModule(uint8_t protocol) } #if defined(HARDWARE_INTERNAL_MODULE) -void enablePulsesInternalModule(uint8_t protocol) +static void enablePulsesInternalModule(uint8_t protocol) { // start new protocol hardware here @@ -306,23 +306,30 @@ void enablePulsesInternalModule(uint8_t protocol) #if defined(PXX2) case PROTOCOL_CHANNELS_PXX2_HIGHSPEED: - intmoduleSerialStart(PXX2_HIGHSPEED_BAUDRATE, true); + intmoduleSerialStart(PXX2_HIGHSPEED_BAUDRATE, true, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b); break; #endif +#if defined(INTERNAL_MODULE_MULTI) + case PROTOCOL_CHANNELS_MULTIMODULE: + intmodulePulsesData.multi.initFrame(); + intmoduleSerialStart(MULTIMODULE_BAUDRATE, true, USART_Parity_Even, USART_StopBits_2, USART_WordLength_9b); + intmoduleTimerStart(MULTIMODULE_PERIOD); + break; +#endif default: break; } } -void setupPulsesInternalModule(uint8_t protocol) +bool setupPulsesInternalModule(uint8_t protocol) { switch (protocol) { #if defined(HARDWARE_INTERNAL_MODULE) && defined(PXX1) && !defined(INTMODULE_USART) case PROTOCOL_CHANNELS_PXX1_PULSES: intmodulePulsesData.pxx.setupFrame(INTERNAL_MODULE); scheduleNextMixerCalculation(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD); - break; + return true; #endif #if defined(PXX1) && defined(INTMODULE_USART) @@ -331,12 +338,13 @@ void setupPulsesInternalModule(uint8_t protocol) #if !defined(INTMODULE_HEARTBEAT) scheduleNextMixerCalculation(INTERNAL_MODULE, INTMODULE_PXX1_SERIAL_PERIOD); #endif - break; + return true; #endif #if defined(PXX2) case PROTOCOL_CHANNELS_PXX2_HIGHSPEED: - intmodulePulsesData.pxx2.setupFrame(INTERNAL_MODULE); + { + bool result = intmodulePulsesData.pxx2.setupFrame(INTERNAL_MODULE); if (moduleState[INTERNAL_MODULE].mode == MODULE_MODE_SPECTRUM_ANALYSER || moduleState[INTERNAL_MODULE].mode == MODULE_MODE_POWER_METER) { scheduleNextMixerCalculation(INTERNAL_MODULE, PXX2_TOOLS_PERIOD); } @@ -345,18 +353,26 @@ void setupPulsesInternalModule(uint8_t protocol) scheduleNextMixerCalculation(INTERNAL_MODULE, PXX2_PERIOD); } #endif - break; + return result; + } #endif #if defined(PCBTARANIS) && defined(INTERNAL_MODULE_PPM) case PROTOCOL_CHANNELS_PPM: setupPulsesPPMInternalModule(); scheduleNextMixerCalculation(INTERNAL_MODULE, PPM_PERIOD(INTERNAL_MODULE)); - break; + return true; +#endif + +#if defined(INTERNAL_MODULE_MULTI) + case PROTOCOL_CHANNELS_MULTIMODULE: + setupPulsesMultiInternalModule(); + scheduleNextMixerCalculation(INTERNAL_MODULE, MULTIMODULE_PERIOD); + return true; #endif default: - break; + return true; } } @@ -373,8 +389,7 @@ bool setupPulsesInternalModule() return false; } else { - setupPulsesInternalModule(protocol); - return true; + return setupPulsesInternalModule(protocol); } } #endif diff --git a/radio/src/pulses/pulses.h b/radio/src/pulses/pulses.h index 6ad42799b..51929a336 100644 --- a/radio/src/pulses/pulses.h +++ b/radio/src/pulses/pulses.h @@ -24,8 +24,9 @@ #include "definitions.h" #include "dataconstants.h" #include "pulses_common.h" -#include "pulses/pxx1.h" -#include "pulses/pxx2.h" +#include "pxx1.h" +#include "pxx2.h" +#include "multi.h" #include "modules_helpers.h" #include "ff.h" @@ -46,6 +47,12 @@ #define IS_DSM2_PROTOCOL(protocol) (0) #endif +#if defined(DSM2_SERIAL) + #define IS_DSM2_SERIAL_PROTOCOL(protocol) (IS_DSM2_PROTOCOL(protocol)) +#else + #define IS_DSM2_SERIAL_PROTOCOL(protocol) (0) +#endif + #if defined(MULTIMODULE) #define IS_MULTIMODULE_PROTOCOL(protocol) (protocol==PROTOCOL_CHANNELS_MULTIMODULE) #if !defined(DSM2) @@ -73,6 +80,7 @@ enum ModuleSettingsMode MODULE_MODE_SHARE, MODULE_MODE_RANGECHECK, MODULE_MODE_RESET, + MODULE_MODE_AUTHENTICATION, MODULE_MODE_OTA_UPDATE, }; @@ -152,7 +160,8 @@ PACK(struct ModuleState { uint8_t paused:1; uint8_t spare:7; uint16_t counter; - union { + union + { ModuleInformation * moduleInformation; ModuleSettings * moduleSettings; ReceiverSettings * receiverSettings; @@ -170,12 +179,14 @@ PACK(struct ModuleState { moduleInformation->maximum = last; mode = MODULE_MODE_GET_HARDWARE_INFO; } + void readModuleSettings(ModuleSettings * destination) { moduleSettings = destination; moduleSettings->state = PXX2_SETTINGS_READ; mode = MODULE_MODE_MODULE_SETTINGS; } + void writeModuleSettings(ModuleSettings * source) { moduleSettings = source; @@ -183,12 +194,14 @@ PACK(struct ModuleState { moduleSettings->timeout = 0; mode = MODULE_MODE_MODULE_SETTINGS; } + void readReceiverSettings(ReceiverSettings * destination) { receiverSettings = destination; receiverSettings->state = PXX2_SETTINGS_READ; mode = MODULE_MODE_RECEIVER_SETTINGS; } + void writeReceiverSettings(ReceiverSettings * source) { receiverSettings = source; @@ -243,17 +256,21 @@ PACK(struct CrossfirePulsesData { union InternalModulePulsesData { #if defined(PXX1) - #if defined(INTMODULE_USART) - UartPxx1Pulses pxx_uart; - #else - PwmPxx1Pulses pxx; - #endif +#if defined(INTMODULE_USART) + UartPxx1Pulses pxx_uart; +#else + PwmPxx1Pulses pxx; +#endif #endif #if defined(PXX2) Pxx2Pulses pxx2; #endif +#if defined(MULTIMODULE) //&& defined(INTMODULE_USART) + UartMultiPulses multi; +#endif + #if defined(INTERNAL_MODULE_PPM) PpmPulsesData ppm; #endif @@ -261,14 +278,14 @@ union InternalModulePulsesData { union ExternalModulePulsesData { #if defined(PXX1) - #if defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) - UartPxx1Pulses pxx_uart; - #endif - #if defined(PPM_PIN_SERIAL) - SerialPxx1Pulses pxx; - #else - PwmPxx1Pulses pxx; - #endif +#if defined(HARDWARE_EXTERNAL_MODULE_SIZE_SML) + UartPxx1Pulses pxx_uart; +#endif +#if defined(PPM_PIN_SERIAL) + SerialPxx1Pulses pxx; +#else + PwmPxx1Pulses pxx; +#endif #endif #if defined(PXX2) @@ -300,11 +317,14 @@ union TrainerPulsesData { extern TrainerPulsesData trainerPulsesData; +#if defined(HARDWARE_INTERNAL_MODULE) bool setupPulsesInternalModule(); +#endif bool setupPulsesExternalModule(); void setupPulsesDSM2(); void setupPulsesCrossfire(); -void setupPulsesMultimodule(); +void setupPulsesMultiExternalModule(); +void setupPulsesMultiInternalModule(); void setupPulsesSbus(); void setupPulsesPPMInternalModule(); void setupPulsesPPMExternalModule(); @@ -416,4 +436,4 @@ inline bool isModuleInBeepMode() return false; } -#endif // _PULSES_H_ +#endif // _PULSES_H_ \ No newline at end of file diff --git a/radio/src/pulses/pxx2.cpp b/radio/src/pulses/pxx2.cpp index 07b32f21f..44f70e8f0 100644 --- a/radio/src/pulses/pxx2.cpp +++ b/radio/src/pulses/pxx2.cpp @@ -360,10 +360,31 @@ void Pxx2Pulses::sendOtaUpdate(uint8_t module, const char * rxName, uint32_t add extmoduleSendNextFrame(); } -void Pxx2Pulses::setupFrame(uint8_t module) +void Pxx2Pulses::setupAuthenticationFrame(uint8_t module, uint8_t mode, const uint8_t * outputMessage) +{ + initFrame(); + + addFrameType(PXX2_TYPE_C_MODULE, PXX2_TYPE_ID_AUTHENTICATION); + + Pxx2Transport::addByte(mode); + if (outputMessage) { + for (uint8_t i = 0; i < 16; i++) { + Pxx2Transport::addByte(outputMessage[i]); + } + } + + endFrame(); +} + +bool Pxx2Pulses::setupFrame(uint8_t module) { if (moduleState[module].mode == MODULE_MODE_OTA_UPDATE) - return; + return false; + + if (moduleState[module].mode == MODULE_MODE_AUTHENTICATION) { + moduleState[module].mode = MODULE_MODE_NORMAL; + return false; + } initFrame(); @@ -416,6 +437,8 @@ void Pxx2Pulses::setupFrame(uint8_t module) } endFrame(); + + return true; } bool Pxx2OtaUpdate::waitStep(uint8_t step, uint8_t timeout) @@ -472,7 +495,7 @@ const char * Pxx2OtaUpdate::doFlashFirmware(const char * filename, ProgressHandl uint32_t size; const char * ext = getFileExtension(filename); - if (ext && !strcasecmp(ext, UPDATE_FIRMWARE_EXT)) { + if (ext && !strcasecmp(ext, FRSKY_FIRMWARE_EXT)) { FrSkyFirmwareInformation * information = (FrSkyFirmwareInformation *) buffer; if (f_read(&file, buffer, sizeof(FrSkyFirmwareInformation), &count) != FR_OK || count != sizeof(FrSkyFirmwareInformation)) { f_close(&file); diff --git a/radio/src/pulses/pxx2.h b/radio/src/pulses/pxx2.h index 9b08e1235..d76b07246 100644 --- a/radio/src/pulses/pxx2.h +++ b/radio/src/pulses/pxx2.h @@ -26,16 +26,17 @@ #include "popups.h" #include "./pxx.h" -#define PXX2_TYPE_C_MODULE 0x01 - #define PXX2_TYPE_ID_REGISTER 0x01 - #define PXX2_TYPE_ID_BIND 0x02 - #define PXX2_TYPE_ID_CHANNELS 0x03 - #define PXX2_TYPE_ID_TX_SETTINGS 0x04 - #define PXX2_TYPE_ID_RX_SETTINGS 0x05 - #define PXX2_TYPE_ID_HW_INFO 0x06 - #define PXX2_TYPE_ID_SHARE 0x07 - #define PXX2_TYPE_ID_RESET 0x08 - #define PXX2_TYPE_ID_TELEMETRY 0xFE +#define PXX2_TYPE_C_MODULE 0x01 + #define PXX2_TYPE_ID_REGISTER 0x01 + #define PXX2_TYPE_ID_BIND 0x02 + #define PXX2_TYPE_ID_CHANNELS 0x03 + #define PXX2_TYPE_ID_TX_SETTINGS 0x04 + #define PXX2_TYPE_ID_RX_SETTINGS 0x05 + #define PXX2_TYPE_ID_HW_INFO 0x06 + #define PXX2_TYPE_ID_SHARE 0x07 + #define PXX2_TYPE_ID_RESET 0x08 + #define PXX2_TYPE_ID_AUTHENTICATION 0x09 + #define PXX2_TYPE_ID_TELEMETRY 0xFE #define PXX2_TYPE_C_POWER_METER 0x02 #define PXX2_TYPE_ID_POWER_METER 0x01 @@ -65,6 +66,8 @@ #define SPECTRUM_ANALYSER_POWER_FLOOR -120 /*dBm*/ #endif +#define PXX2_AUTH_REFUSED_FLAG 0xA5 + enum PXX2ModuleModelID { PXX2_MODULE_NONE, PXX2_MODULE_XJT, @@ -76,7 +79,10 @@ enum PXX2ModuleModelID { PXX2_MODULE_R9M_LITE_PRO, PXX2_MODULE_ISRM_N, PXX2_MODULE_ISRM_S_X9, - PXX2_MODULE_ISRM_S_X10 + PXX2_MODULE_ISRM_S_X10E, + PXX2_MODULE_XJT_LITE, + PXX2_MODULE_ISRM_S_X10S, + PXX2_MODULE_ISRM_S_X9LITE, }; static const char * const PXX2ModulesNames[] = { @@ -90,7 +96,10 @@ static const char * const PXX2ModulesNames[] = { "R9MLite-PRO", "ISRM-N", "ISRM-S-X9", - "ISRM-S-X10", + "ISRM-S-X10E", + "XJT Lite", + "ISRM-S-X10S", + "ISRM-S-X9Lite" }; inline const char * getPXX2ModuleName(uint8_t modelId) @@ -129,7 +138,10 @@ static const uint8_t PXX2ModuleOptions[] = { 0b00000110, // R9MLite-PRO 0b00000100, // ISRM-N 0b00000100, // ISRM-S-X9 - 0b00000101, // ISRM-S-X10 + 0b00000101, // ISRM-S-X10E + 0b00000001, // XJT_LITE + 0b00000101, // ISRM-S-X10S + 0b00000101, // ISRM-S-X9LITE }; inline uint8_t getPXX2ModuleOptions(uint8_t modelId) @@ -333,7 +345,8 @@ class Pxx2Pulses: public Pxx2Transport { friend class Pxx2OtaUpdate; public: - void setupFrame(uint8_t module); + bool setupFrame(uint8_t module); + void setupAuthenticationFrame(uint8_t module, uint8_t mode, const uint8_t * outputMessage); protected: void setupHardwareInfoFrame(uint8_t module); diff --git a/radio/src/sdcard.h b/radio/src/sdcard.h index 6ebbd5bd0..d4b54ca47 100644 --- a/radio/src/sdcard.h +++ b/radio/src/sdcard.h @@ -70,7 +70,8 @@ const char RADIO_SETTINGS_PATH[] = RADIO_PATH "/radio.bin"; #define FIRMWARE_EXT ".bin" #define EEPROM_EXT ".bin" #define SPORT_FIRMWARE_EXT ".frk" -#define UPDATE_FIRMWARE_EXT ".frsk" +#define FRSKY_FIRMWARE_EXT ".frsk" +#define MULTI_FIRMWARE_EXT ".bin" #if defined(COLORLCD) #define BITMAPS_EXT BMP_EXT JPG_EXT PNG_EXT @@ -122,6 +123,8 @@ const char * getBasename(const char * path); #if defined(PCBX12S) #define OTX_FOURCC 0x3478746F // otx for X12S +#elif defined(RADIO_T16) + #define OTX_FOURCC 0x3F78746F // otx for Jumper T16 #elif defined(PCBX10) #define OTX_FOURCC 0x3778746F // otx for X10 #elif defined(PCBX9E) @@ -132,6 +135,8 @@ const char * getBasename(const char * path); #define OTX_FOURCC 0x3978746F // otx for Taranis X-Lite #elif defined(RADIO_X7) #define OTX_FOURCC 0x3678746F // otx for Taranis X7 +#elif defined(PCBX9LITES) + #define OTX_FOURCC 0x3E78746F // otx for Taranis X9-Lite #elif defined(PCBX9LITE) #define OTX_FOURCC 0x3C78746F // otx for Taranis X9-Lite #elif defined(PCBX9D) || defined(PCBX9DP) diff --git a/radio/src/simu.cpp b/radio/src/simu.cpp index 84f02f7fa..3d273406d 100644 --- a/radio/src/simu.cpp +++ b/radio/src/simu.cpp @@ -119,7 +119,7 @@ OpenTxSim::OpenTxSim(FXApp* a): sliders[i]->setValue(0); } - for(int i=0; isetValue(0); @@ -131,6 +131,7 @@ OpenTxSim::OpenTxSim(FXApp* a): continue; } #endif + knobs[i]->setRange(-1024, 1024); } @@ -160,7 +161,7 @@ OpenTxSim::~OpenTxSim() delete sliders[2]; delete sliders[3]; - for(int i=0; isliders[chan]->getValue(); - else if (chanknobs[chan-NUM_STICKS]->getValue(); + else if (chan < NUM_STICKS + NUM_POTS + NUM_SLIDERS) + return opentxSim->knobs[chan - NUM_STICKS]->getValue(); #if defined(PCBTARANIS) else if (chan == TX_RTC_VOLTAGE) return 800; // 2.34V diff --git a/radio/src/stamp.cpp b/radio/src/stamp.cpp index 91d880472..5eb738db1 100644 --- a/radio/src/stamp.cpp +++ b/radio/src/stamp.cpp @@ -28,15 +28,23 @@ #define TAB "\037\033" +#if defined(FRSKY_RELEASE) +#define DISPLAY_VERSION "FrSky" +#elif defined(JUMPER_RELEASE) +#define DISPLAY_VERSION "JumperRC" +#else +#define DISPLAY_VERSION VERSION +#endif + #if defined(COLORLCD) - const char vers_stamp[] = "opentx-" FLAVOUR "-" VERSION " (" GIT_STR ")"; + const char vers_stamp[] = "opentx-" FLAVOUR "-" DISPLAY_VERSION " (" GIT_STR ")"; const char date_stamp[] = DATE; const char time_stamp[] = TIME; const char eeprom_stamp[] = EEPROM_STR; #elif defined(BOARD_NAME) - const char vers_stamp[] = "FW" TAB ": opentx-" BOARD_NAME "\036VERS" TAB ": " VERSION " (" GIT_STR ")" "\036DATE" TAB ": " DATE " " TIME "\036EEPR" TAB ": " EEPROM_STR; + const char vers_stamp[] = "FW" TAB ": opentx-" BOARD_NAME "\036VERS" TAB ": " DISPLAY_VERSION " (" GIT_STR ")" "\036DATE" TAB ": " DATE " " TIME "\036EEPR" TAB ": " EEPROM_STR; #else - const char vers_stamp[] = "FW" TAB ": opentx-" FLAVOUR "\036VERS" TAB ": " VERSION " (" GIT_STR ")" "\036DATE" TAB ": " DATE " " TIME "\036EEPR" TAB ": " EEPROM_STR; + const char vers_stamp[] = "FW" TAB ": opentx-" FLAVOUR "\036VERS" TAB ": " DISPLAY_VERSION " (" GIT_STR ")" "\036DATE" TAB ": " DATE " " TIME "\036EEPR" TAB ": " EEPROM_STR; #endif /** @@ -45,8 +53,8 @@ */ #if defined(STM32) && !defined(SIMU) -__SECTION_USED(".fwversiondata") const char firmware_version[] = "opentx-" FLAVOUR "-" VERSION " (" GIT_STR ")"; -__SECTION_USED(".bootversiondata") const char boot_version[] = "opentx-" FLAVOUR "-" VERSION " (" GIT_STR ")"; +__SECTION_USED(".fwversiondata") const char firmware_version[] = "opentx-" FLAVOUR "-" DISPLAY_VERSION " (" GIT_STR ")"; +__SECTION_USED(".bootversiondata") const char boot_version[] = "opentx-" FLAVOUR "-" DISPLAY_VERSION " (" GIT_STR ")"; /** * Tries to find opentx version in the first 1024 byte of either firmware/bootloader (the one not running) or the buffer diff --git a/radio/src/storage/conversions/conversions_216_218.cpp b/radio/src/storage/conversions/conversions_216_218.cpp index 041b88fb5..b39a623db 100644 --- a/radio/src/storage/conversions/conversions_216_218.cpp +++ b/radio/src/storage/conversions/conversions_216_218.cpp @@ -1226,7 +1226,7 @@ void convertModelData_217_to_218(ModelData &model) } } } - else if (((oldModel.frsky.screensType >> (2*i)) & 0x03) == TELEMETRY_SCREEN_TYPE_GAUGES) { + else if (((oldModel.frsky.screensType >> (2*i)) & 0x03) == TELEMETRY_SCREEN_TYPE_BARS) { for (int j = 0; j < 4; j++) { newModel.frsky.screens[i].bars[j].source = convertSource_217_to_218(oldModel.frsky.screens[i].bars[j].source); } diff --git a/radio/src/storage/conversions/conversions_218_219.cpp b/radio/src/storage/conversions/conversions_218_219.cpp index 8e020443c..e66d27d87 100644 --- a/radio/src/storage/conversions/conversions_218_219.cpp +++ b/radio/src/storage/conversions/conversions_218_219.cpp @@ -124,9 +124,11 @@ void convertModelData_218_to_219(ModelData &model) memclear(&newModel.header.bitmap[10], 4); memcpy(newModel.timers, oldModel.timers, offsetof(ModelData_v218, mixData) - offsetof(ModelData_v218, timers)); +#if defined(BLUETOOTH) // trainer battery compartment removed if (newModel.trainerData.mode >= TRAINER_MODE_MASTER_BLUETOOTH) newModel.trainerData.mode -= 1; +#endif #endif memclear(newModel.mixData, sizeof(ModelData_v219) - offsetof(ModelData_v219, mixData)); @@ -290,7 +292,7 @@ void convertModelData_218_to_219(ModelData &model) for (uint8_t i=0; i 0 && (isModuleTypePXX1(oldModel.moduleData[0].type) || isModuleTypePXX1(oldModel.moduleData[1].type))) newModel.telemetrySensors[i].instance = 0xE0 + (oldModel.telemetrySensors[i].instance & 0x1F) - 1; else newModel.telemetrySensors[i].instance = oldModel.telemetrySensors[i].instance; @@ -353,7 +355,7 @@ void convertModelData_218_to_219(ModelData &model) } } } - else if (screenType == TELEMETRY_SCREEN_TYPE_GAUGES) { + else if (screenType == TELEMETRY_SCREEN_TYPE_BARS) { for (int j = 0; j < 4; j++) { newModel.screens[i].bars[j].source = convertSource_218_to_219(oldModel.frsky.screens[i].bars[j].source); } diff --git a/radio/src/storage/conversions/datastructs_218.h b/radio/src/storage/conversions/datastructs_218.h index e79ecdafe..a3bb72907 100644 --- a/radio/src/storage/conversions/datastructs_218.h +++ b/radio/src/storage/conversions/datastructs_218.h @@ -504,7 +504,7 @@ PACK(struct ModelData_v218 { swarnstate218_t switchUnlockStates; \ swconfig218_t switchConfig; \ char switchNames[NUM_SWITCHES_218][LEN_SWITCH_NAME_218]; \ - char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME_218]; \ + char anaNames[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS][LEN_ANA_NAME_218]; \ BLUETOOTH_FIELDS_218 #elif defined(PCBSKY9X) #define EXTRA_GENERAL_FIELDS_218 \ @@ -517,7 +517,7 @@ PACK(struct ModelData_v218 { uint8_t sticksGain; \ uint8_t rotarySteps; \ char switchNames[NUM_SWITCHES_218][LEN_SWITCH_NAME_218]; \ - char anaNames[NUM_STICKS+NUM_POTS+NUM_SLIDERS][LEN_ANA_NAME_218]; + char anaNames[NUM_STICKS+STORAGE_NUM_POTS+STORAGE_NUM_SLIDERS][LEN_ANA_NAME_218]; #else #define EXTRA_GENERAL_FIELDS_218 EXTRA_GENERAL_FIELDS_GENERAL_218 #endif diff --git a/radio/src/switches.cpp b/radio/src/switches.cpp index 1a4d2d232..def912319 100644 --- a/radio/src/switches.cpp +++ b/radio/src/switches.cpp @@ -33,7 +33,6 @@ #define SWITCH_WARNING_LIST_Y 4*FH+4 #endif - enum LogicalSwitchContextState { SWITCH_START, SWITCH_DELAY, @@ -131,7 +130,12 @@ void getSwitchesPosition(bool startup) CHECK_3POS(1, SW_SB); CHECK_3POS(2, SW_SC); -#if defined(PCBX9LITE) +#if defined(PCBX9LITES) + CHECK_2POS(SW_SD); + CHECK_2POS(SW_SE); + CHECK_2POS(SW_SF); + CHECK_2POS(SW_SG); +#elif defined(PCBX9LITE) CHECK_2POS(SW_SD); CHECK_2POS(SW_SE); #elif defined(PCBXLITES) @@ -154,6 +158,15 @@ void getSwitchesPosition(bool startup) CHECK_2POS(SW_SH); #endif +#if defined(PCBX9DP) && PCBREV >= 2019 + CHECK_2POS(SW_SI); +#endif + +#if defined(PCBHORUS) || defined(PCBX7) + CHECK_2POS(SW_SI); + CHECK_2POS(SW_SJ); +#endif + #if defined(PCBX9E) CHECK_3POS(6, SW_SI); CHECK_3POS(7, SW_SJ); diff --git a/radio/src/targets/common/arm/CMakeLists.txt b/radio/src/targets/common/arm/CMakeLists.txt index 39638d2e3..b2d9108ef 100644 --- a/radio/src/targets/common/arm/CMakeLists.txt +++ b/radio/src/targets/common/arm/CMakeLists.txt @@ -147,7 +147,7 @@ endif() if(MULTIMODULE) add_definitions(-DMULTIMODULE) - set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp telemetry/multi.cpp) + set(SRC ${SRC} pulses/multi.cpp telemetry/spektrum.cpp telemetry/flysky_ibus.cpp telemetry/hitec.cpp telemetry/multi.cpp io/multi_firmware_update.cpp) endif() if(CROSSFIRE) diff --git a/radio/src/targets/common/arm/stm32/adc_driver.cpp b/radio/src/targets/common/arm/stm32/adc_driver.cpp index 36d0e5a60..2a690972b 100644 --- a/radio/src/targets/common/arm/stm32/adc_driver.cpp +++ b/radio/src/targets/common/arm/stm32/adc_driver.cpp @@ -22,8 +22,10 @@ #if defined(SIMU) // not needed +#elif defined(RADIO_T16) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,1, -1,1, -1,1}; #elif defined(PCBX10) - const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, 1,1, 1, -1}; + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,1,-1, 1,1, 1, -1}; #elif defined(PCBX9E) #if defined(HORUS_STICKS) const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, -1,-1,-1,1, -1,1,-1, -1,-1,-1}; @@ -36,14 +38,14 @@ 9 /*TX_VOLTAGE*/, 10 /*TX_VBAT*/ }; #elif defined(PCBX9DP) const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,-1, 1,1, 1, 1}; +#elif defined(PCBX9D) + const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,0, 1,1, 1, 1}; #elif defined(PCBX7) const int8_t adcDirection[NUM_ANALOGS] = {-1,1,-1,1, 1,1, 1, 1}; #elif defined(PCBX9LITE) const int8_t adcDirection[NUM_ANALOGS] = {-1,1,-1,1, 1,1, 1}; #elif defined(PCBXLITE) const int8_t adcDirection[NUM_ANALOGS] = {1,-1,-1,1, -1,1, 1, 1}; -#else - const int8_t adcDirection[NUM_ANALOGS] = {1,-1,1,-1, 1,1,0, 1,1, 1, 1}; #endif #if NUM_PWMSTICKS > 0 diff --git a/radio/src/targets/common/arm/stm32/audio_dac_driver.cpp b/radio/src/targets/common/arm/stm32/audio_dac_driver.cpp index fd1e83183..d050382a2 100644 --- a/radio/src/targets/common/arm/stm32/audio_dac_driver.cpp +++ b/radio/src/targets/common/arm/stm32/audio_dac_driver.cpp @@ -90,13 +90,18 @@ void dacInit() void audioConsumeCurrentBuffer() { - if (nextBuffer == 0) { - + if (!nextBuffer) { nextBuffer = audioQueue.buffersFifo.getNextFilledBuffer(); if (nextBuffer) { #if defined(AUDIO_MUTE_GPIO_PIN) - // un-mute - GPIO_ResetBits(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); + // if muted + if (GPIO_ReadOutputDataBit(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN)) { + // ..un-mute + GPIO_ResetBits(AUDIO_MUTE_GPIO, AUDIO_MUTE_GPIO_PIN); +#if defined(AUDIO_UNMUTE_DELAY) + RTOS_WAIT_MS(AUDIO_UNMUTE_DELAY); +#endif + } #endif AUDIO_DMA_Stream->CR &= ~DMA_SxCR_EN ; // Disable DMA channel AUDIO_DMA->HIFCR = DMA_HIFCR_CTCIF5 | DMA_HIFCR_CHTIF5 | DMA_HIFCR_CTEIF5 | DMA_HIFCR_CDMEIF5 | DMA_HIFCR_CFEIF5 ; // Write ones to clear bits diff --git a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp index c93b6f644..f9598bb27 100644 --- a/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/aux_serial_driver.cpp @@ -206,4 +206,4 @@ extern "C" void AUX_SERIAL_USART_IRQHandler(void) } } #endif -} \ No newline at end of file +} diff --git a/radio/src/targets/common/arm/stm32/bluetooth_driver.cpp b/radio/src/targets/common/arm/stm32/bluetooth_driver.cpp index 2a9e0848b..1d861e1d6 100644 --- a/radio/src/targets/common/arm/stm32/bluetooth_driver.cpp +++ b/radio/src/targets/common/arm/stm32/bluetooth_driver.cpp @@ -20,6 +20,7 @@ #include "opentx.h" +#if !defined(BOOT) Fifo btTxFifo; Fifo btRxFifo; @@ -42,6 +43,7 @@ enum BluetoothWriteState }; volatile uint8_t bluetoothWriteState = BLUETOOTH_WRITE_IDLE; +#endif void bluetoothInit(uint32_t baudrate, bool enable) { @@ -65,6 +67,7 @@ void bluetoothInit(uint32_t baudrate, bool enable) GPIO_Init(BT_BCTS_GPIO, &GPIO_InitStructure); #endif +#if !defined(BOOT) GPIO_PinAFConfig(BT_USART_GPIO, BT_TX_GPIO_PinSource, BT_GPIO_AF); GPIO_PinAFConfig(BT_USART_GPIO, BT_RX_GPIO_PinSource, BT_GPIO_AF); @@ -90,17 +93,17 @@ void bluetoothInit(uint32_t baudrate, bool enable) bluetoothWriteState = BLUETOOTH_WRITE_IDLE; - if (enable) { - GPIO_ResetBits(BT_EN_GPIO, BT_EN_GPIO_PIN); - } - else { - GPIO_SetBits(BT_EN_GPIO, BT_EN_GPIO_PIN); - } - btRxFifo.clear(); btTxFifo.clear(); +#endif + + if (enable) + GPIO_ResetBits(BT_EN_GPIO, BT_EN_GPIO_PIN); + else + GPIO_SetBits(BT_EN_GPIO, BT_EN_GPIO_PIN); } +#if !defined(BOOT) void bluetoothDisable() { GPIO_SetBits(BT_EN_GPIO, BT_EN_GPIO_PIN); // close bluetooth (recent modules will go to bootloader mode) @@ -165,3 +168,4 @@ uint8_t bluetoothIsWriting(void) { return bluetoothWriteState != BLUETOOTH_WRITE_IDLE; } +#endif // !BOOT diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index 36eefc6cd..1fb90fd21 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -85,13 +85,20 @@ set(BOOTLOADER_SRC bin_files.cpp ) -if(PCB STREQUAL X12S OR PCB STREQUAL X10 OR PCB STREQUAL X9E OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR (PCB STREQUAL X7 AND NOT (PCBREV STREQUAL T12)) OR PCB STREQUAL X9LITE) +if(PCB STREQUAL X12S OR PCB STREQUAL X10 OR PCB STREQUAL X9E OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR (PCB STREQUAL X7 AND NOT (PCBREV STREQUAL T12)) OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES) set(BOOTLOADER_SRC ${BOOTLOADER_SRC} ../../../../../targets/common/arm/stm32/rotary_encoder_driver.cpp ) endif() +if(PCB STREQUAL X7 OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES) + set(BOOTLOADER_SRC + ${BOOTLOADER_SRC} + ../../../../../targets/common/arm/stm32/bluetooth_driver.cpp + ) +endif() + if(NOT (PCB STREQUAL X10 OR PCB STREQUAL X12S)) set(BOOTLOADER_SRC ${BOOTLOADER_SRC} @@ -116,7 +123,6 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14) ${BOOTLOADER_SRC} ../../../../../${STM32LIB_DIR}/STM32F4xx_StdPeriph_Driver/src/stm32f4xx_usart.c ../../../../../serial.cpp - ../aux_serial_driver.cpp ) endif() endif() @@ -133,7 +139,7 @@ set(CMAKE_EXE_LINKER_FLAGS "-mcpu=${MCU} -mthumb -nostartfiles -lm -T${RADIO_SRC set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --specs=nano.specs") add_executable(bootloader ${BOOTLOADER_SRC}) -add_dependencies(bootloader ${BITMAPS_TARGET} translations) +add_dependencies(bootloader ${BITMAPS_TARGET}) add_custom_command( TARGET bootloader POST_BUILD diff --git a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp index e5adcd545..a0878eb05 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/boot.cpp +++ b/radio/src/targets/common/arm/stm32/bootloader/boot.cpp @@ -245,6 +245,11 @@ int main() backlightInit(); backlightEnable(); +#if defined(PCBX7) || defined(PCBXLITE) + // we shutdown the bluetooth module now to be sure it will be detected on firmware start + bluetoothInit(BLUETOOTH_DEFAULT_BAUDRATE, false); +#endif + #if defined(PCBTARANIS) i2cInit(); #endif diff --git a/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp b/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp index 926c05c63..70ce2b394 100644 --- a/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp +++ b/radio/src/targets/common/arm/stm32/heartbeat_driver.cpp @@ -83,5 +83,8 @@ void check_intmodule_heartbeat() extern "C" void INTMODULE_HEARTBEAT_EXTI_IRQHandler() { check_intmodule_heartbeat(); + #if defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT) + check_telemetry_exti(); + #endif } #endif diff --git a/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp b/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp index 8102b5eee..e2f01f586 100755 --- a/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp +++ b/radio/src/targets/common/arm/stm32/intmodule_serial_driver.cpp @@ -39,14 +39,20 @@ void intmoduleStop() USART_DeInit(INTMODULE_USART); GPIO_ResetBits(INTMODULE_GPIO, INTMODULE_TX_GPIO_PIN | INTMODULE_RX_GPIO_PIN); + +#if defined(INTERNAL_MODULE_MULTI) + // stop pulses timer + INTMODULE_TIMER->DIER &= ~TIM_DIER_CC2IE; + INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; +#endif } void intmodulePxx1SerialStart() { - intmoduleSerialStart(INTMODULE_PXX1_SERIAL_BAUDRATE, false); + intmoduleSerialStart(INTMODULE_PXX1_SERIAL_BAUDRATE, false, USART_Parity_No, USART_StopBits_1, USART_WordLength_8b); } -void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable) +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength) { INTERNAL_MODULE_ON(); @@ -71,9 +77,9 @@ void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable) USART_DeInit(INTMODULE_USART); USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate = baudrate; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; + USART_InitStructure.USART_Parity = parity; + USART_InitStructure.USART_StopBits = stopBits; + USART_InitStructure.USART_WordLength = wordLength; USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; USART_Init(INTMODULE_USART, &USART_InitStructure); @@ -87,6 +93,28 @@ void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable) } } +#if defined(INTERNAL_MODULE_MULTI) +void intmoduleTimerStart(uint32_t periodMs) +{ + // Timer + INTMODULE_TIMER->CR1 &= ~TIM_CR1_CEN; + INTMODULE_TIMER->PSC = INTMODULE_TIMER_FREQ / 2000000 - 1; // 0.5uS (2Mhz) + INTMODULE_TIMER->ARR = periodMs * 2000; + INTMODULE_TIMER->CCR2 = (periodMs - 1) * 2000; + INTMODULE_TIMER->CCER = TIM_CCER_CC3E; + INTMODULE_TIMER->CCMR2 = 0; + INTMODULE_TIMER->EGR = 1; // Restart + + INTMODULE_TIMER->CCMR2 = TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_0; // Toggle CC1 o/p + INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // Clear flag + INTMODULE_TIMER->DIER |= TIM_DIER_CC2IE; // Enable this interrupt + INTMODULE_TIMER->CR1 |= TIM_CR1_CEN; + + NVIC_EnableIRQ(INTMODULE_TIMER_IRQn); + NVIC_SetPriority(INTMODULE_TIMER_IRQn, 7); +} +#endif + #define USART_FLAG_ERRORS (USART_FLAG_ORE | USART_FLAG_NE | USART_FLAG_FE | USART_FLAG_PE) extern "C" void INTMODULE_USART_IRQHandler(void) { @@ -98,7 +126,6 @@ extern "C" void INTMODULE_USART_IRQHandler(void) intmoduleFifo.errors++; } else { - hardwareOptions.pxx2Enabled = true; intmoduleFifo.push(data); } status = INTMODULE_USART->SR; @@ -152,5 +179,20 @@ void intmoduleSendNextFrame() intmoduleSendBuffer(intmodulePulsesData.pxx_uart.getData(), intmodulePulsesData.pxx_uart.getSize()); break; #endif + +#if defined(INTERNAL_MODULE_MULTI) + case PROTOCOL_CHANNELS_MULTIMODULE: + intmoduleSendBuffer(intmodulePulsesData.multi.getData(), intmodulePulsesData.multi.getSize()); + break; +#endif } } + +#if defined(INTERNAL_MODULE_MULTI) +extern "C" void INTMODULE_TIMER_IRQHandler() +{ + INTMODULE_TIMER->SR &= ~TIM_SR_CC2IF; // clear flag + setupPulsesInternalModule(); + intmoduleSendNextFrame(); +} +#endif diff --git a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp index fc028d3b5..f43090f04 100644 --- a/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp +++ b/radio/src/targets/common/arm/stm32/rotary_encoder_driver.cpp @@ -71,6 +71,27 @@ void rotaryEncoderInit() void rotaryEncoderCheck() { +#if defined(RADIO_T16) + static uint8_t state = 0; + uint8_t pins = ROTARY_ENCODER_POSITION(); + + if (pins != (state & 0x03) && !(readKeys() & (1 << KEY_ENTER))) { + if ((pins & 0x01) ^ ((pins & 0x02) >> 1)) { + if ((state & 0x03) == 3) + ++rotencValue; + else + --rotencValue; + } + else + { + if ((state & 0x03) == 3) + --rotencValue; + else if ((state & 0x03) == 0) + ++rotencValue; + } + state &= ~0x03 ; + state |= pins ; +#else uint8_t newPosition = ROTARY_ENCODER_POSITION(); if (newPosition != rotencPosition && !(readKeys() & (1 << KEY_ENTER))) { if ((rotencPosition & 0x01) ^ ((newPosition & 0x02) >> 1)) { @@ -80,10 +101,12 @@ void rotaryEncoderCheck() ++rotencValue; } rotencPosition = newPosition; +#endif #if !defined(BOOT) if (g_eeGeneral.backlightMode & e_backlight_mode_keys) { backlightOn(); } + inactivity.counter = 0; #endif } } @@ -110,6 +133,10 @@ extern "C" void ROTARY_ENCODER_EXTI_IRQHandler1(void) #if !defined(BOOT) && defined(INTMODULE_HEARTBEAT_REUSE_INTERRUPT_ROTARY_ENCODER) check_intmodule_heartbeat(); #endif + +#if !defined(BOOT) && defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER) + check_telemetry_exti(); +#endif } #if defined(ROTARY_ENCODER_EXTI_IRQn2) @@ -127,4 +154,4 @@ extern "C" void ROTARY_ENCODER_TIMER_IRQHandler(void) ROTARY_ENCODER_TIMER->SR &= ~TIM_SR_UIF; ROTARY_ENCODER_TIMER->CR1 = 0; rotaryEncoderCheck(); -} \ No newline at end of file +} diff --git a/radio/src/targets/horus/CMakeLists.txt b/radio/src/targets/horus/CMakeLists.txt index a98da9d62..3364b4996 100644 --- a/radio/src/targets/horus/CMakeLists.txt +++ b/radio/src/targets/horus/CMakeLists.txt @@ -2,6 +2,7 @@ option(DISK_CACHE "Enable SD card disk cache" ON) option(UNEXPECTED_SHUTDOWN "Enable the Unexpected Shutdown screen" ON) option(PXX1 "PXX1 protocol support" ON) option(PXX2 "PXX2 protocol support" OFF) +option(MULTIMODULE "DIY Multiprotocol TX Module (https://github.com/pascallanger/DIY-Multiprotocol-TX-Module)" ON) set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(CPU_TYPE STM32F4) @@ -41,19 +42,30 @@ if (PCB STREQUAL X10) set(FONTS_TARGET x10_fonts) set(LCD_DRIVER lcd_driver.cpp) set(LUA_EXPORT lua_export_x10) + set(INTERNAL_GPS OFF) if (PCBREV STREQUAL EXPRESS) set(FLAVOUR x10express) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" OFF) option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON) + set(BLUETOOTH ON) + add_definitions(-DHARDWARE_POWER_MANAGEMENT_UNIT) + elseif (PCBREV STREQUAL T16) + set(FLAVOUR t16) + set(LUA_EXPORT lua_export_t16) + add_definitions(-DRADIO_T16) + option(INTERNAL_MODULE_MULTI "Support for MULTI internal module" OFF) + option(BLUETOOTH "Support for bluetooth module" OFF) else() set(FLAVOUR x10) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) + set(BLUETOOTH ON) endif() elseif (PCB STREQUAL X12S) option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) set(FLAVOUR x12s) + set(BLUETOOTH ON) set(PCBREV "13" CACHE STRING "PCB Revision") if(${PCBREV} GREATER 10) option(INTERNAL_GPS "Internal GPS installed" YES) @@ -92,12 +104,23 @@ if(NOT UNEXPECTED_SHUTDOWN) endif() if(INTERNAL_MODULE_PXX1) + add_definitions(-DHARDWARE_INTERNAL_MODULE) add_definitions(-DINTERNAL_MODULE_PXX1) endif() if(INTERNAL_MODULE_PXX2) set(PXX2 ON) + add_definitions(-DHARDWARE_INTERNAL_MODULE) add_definitions(-DINTERNAL_MODULE_PXX2) + if (NOT PCBREV STREQUAL EXPRESS) + set(ACCESS_LIB ON) + add_definitions(-DACCESS_LIB) + endif() +endif() + +if(INTERNAL_MODULE_MULTI) + add_definitions(-DHARDWARE_INTERNAL_MODULE) + add_definitions(-DINTERNAL_MODULE_MULTI) endif() if(DISK_CACHE) @@ -120,10 +143,15 @@ set(TARGET_SRC trainer_driver.cpp ../common/arm/stm32/timers_driver.cpp ../common/arm/stm32/intmodule_serial_driver.cpp - ../common/arm/stm32/bluetooth_driver.cpp ../common/arm/stm32/rotary_encoder_driver.cpp ) +if(BLUETOOTH) + add_definitions(-DBLUETOOTH) + set(TARGET_SRC ${TARGET_SRC} ../common/arm/stm32/bluetooth_driver.cpp) + set(SRC ${SRC} bluetooth.cpp) +endif() + set(FIRMWARE_TARGET_SRC ${FIRMWARE_TARGET_SRC} ${LCD_DRIVER} @@ -137,12 +165,10 @@ set(FIRMWARE_TARGET_SRC ../common/arm/loadboot.cpp ) -add_definitions(-DBLUETOOTH) - set(SRC ${SRC} - bluetooth.cpp io/frsky_firmware_update.cpp + io/multi_firmware_update.cpp ) set(STM32LIB_SRC @@ -160,4 +186,3 @@ if(PYTHONINTERP_FOUND) DEPENDS ${RADIO_DIRECTORY}/src/datastructs.h ${RADIO_DIRECTORY}/util/generate_datacopy.py ) endif() - diff --git a/radio/src/targets/horus/audio_spi_driver.cpp b/radio/src/targets/horus/audio_spi_driver.cpp index dc05ef06d..32ef0f906 100644 --- a/radio/src/targets/horus/audio_spi_driver.cpp +++ b/radio/src/targets/horus/audio_spi_driver.cpp @@ -374,7 +374,7 @@ void audioInit() audioHardReset(); audioSoftReset(); audioSpiSetSpeed(SPI_SPEED_8); - delay_01us(10000); // 1ms + delay_ms(1); // 1ms audioSendRiffHeader(); } diff --git a/radio/src/targets/horus/board.cpp b/radio/src/targets/horus/board.cpp index 40900a099..fd93f15ee 100644 --- a/radio/src/targets/horus/board.cpp +++ b/radio/src/targets/horus/board.cpp @@ -49,7 +49,7 @@ void watchdogInit(unsigned int duration) extern "C" void initialise_monitor_handles(); #endif -#if defined(PCBX10) +#if defined(PCBX10) && !defined(RADIO_T16) void sportUpdateInit() { GPIO_InitTypeDef GPIO_InitStructure; @@ -120,6 +120,7 @@ void boardInit() HAPTIC_RCC_APB2Periph | INTMODULE_RCC_APB2Periph | EXTMODULE_RCC_APB2Periph | + TELEMETRY_RCC_APB2Periph | BT_RCC_APB2Periph | BACKLIGHT_RCC_APB2Periph, ENABLE); @@ -171,8 +172,8 @@ void boardInit() DBGMCU_APB1PeriphConfig(DBGMCU_IWDG_STOP|DBGMCU_TIM1_STOP|DBGMCU_TIM2_STOP|DBGMCU_TIM3_STOP|DBGMCU_TIM4_STOP|DBGMCU_TIM5_STOP|DBGMCU_TIM6_STOP|DBGMCU_TIM7_STOP|DBGMCU_TIM8_STOP|DBGMCU_TIM9_STOP|DBGMCU_TIM10_STOP|DBGMCU_TIM11_STOP|DBGMCU_TIM12_STOP|DBGMCU_TIM13_STOP|DBGMCU_TIM14_STOP, ENABLE); #endif -#if defined(PCBX10) ledInit(); +#if defined(PCBX10) && !defined(RADIO_T16) sportUpdateInit(); #endif diff --git a/radio/src/targets/horus/board.h b/radio/src/targets/horus/board.h index 13717068a..1ac470fa3 100644 --- a/radio/src/targets/horus/board.h +++ b/radio/src/targets/horus/board.h @@ -59,7 +59,7 @@ extern uint16_t sessionTimer; #define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) -#if defined(PCBX10) +#if defined(PCBX10) && !defined(RADIO_T16) #define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_SET) #else #define TRAINER_CONNECTED() (GPIO_ReadInputDataBit(TRAINER_DETECT_GPIO, TRAINER_DETECT_GPIO_PIN) == Bit_RESET) @@ -173,7 +173,10 @@ void SDRAM_Init(); void init_intmodule_heartbeat(); void check_intmodule_heartbeat(); -void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable); +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength); +#if defined(INTERNAL_MODULE_MULTI) +void intmoduleTimerStart(uint32_t periodMs); +#endif void intmoduleSendByte(uint8_t byte); void intmoduleSendBuffer(const uint8_t * data, uint8_t size); void intmoduleSendNextFrame(); @@ -182,6 +185,7 @@ void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inver void extmoduleInvertedSerialStart(uint32_t baudrate); void extmoduleSendBuffer(const uint8_t * data, uint8_t size); void extmoduleSendNextFrame(); +void extmoduleSendInvertedByte(uint8_t byte); // Trainer driver void init_trainer_ppm(); @@ -507,6 +511,8 @@ void backlightEnable(uint8_t dutyCycle = 0); #define BACKLIGHT_LEVEL_MAX 100 #if defined(PCBX12S) #define BACKLIGHT_LEVEL_MIN 5 +#elif defined(RADIO_T16) +#define BACKLIGHT_LEVEL_MIN 1 #else #define BACKLIGHT_LEVEL_MIN 46 #endif @@ -521,6 +527,10 @@ void usbJoystickUpdate(); #define USB_NAME "FrSky Horus" #define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */ #define USB_PRODUCT 'H', 'o', 'r', 'u', 's', ' ', ' ', ' ' /* 8 Bytes */ +#elif defined(RADIO_T16) + #define USB_NAME "Jumper T16" + #define USB_MANUFACTURER 'J', 'u', 'm', 'p', 'e', 'r', ' ', ' ' /* 8 bytes */ + #define USB_PRODUCT 'T', '1', '6', ' ', ' ', ' ', ' ', ' ' /* 8 Bytes */ #elif defined(PCBX10) #define USB_NAME "FrSky X10" #define USB_MANUFACTURER 'F', 'r', 'S', 'k', 'y', ' ', ' ', ' ' /* 8 bytes */ @@ -554,12 +564,15 @@ void telemetryPortSetDirectionInput(); void telemetryPortSetDirectionOutput(); void sportSendByte(uint8_t byte); void sportSendBuffer(const uint8_t * buffer, uint32_t count); -uint8_t telemetryGetByte(uint8_t * byte); +bool telemetryGetByte(uint8_t * byte); void telemetryClearFifo(); extern uint32_t telemetryErrors; +// soft-serial +void telemetryPortInvertedInit(uint32_t baudrate); + // Sport update driver -#if defined(PCBX10) +#if defined(PCBX10) && !defined(RADIO_T16) void sportUpdatePowerOn(); void sportUpdatePowerOff(); #define SPORT_UPDATE_POWER_ON() sportUpdatePowerOn() @@ -582,7 +595,7 @@ uint8_t gpsGetByte(uint8_t * byte); extern uint8_t gpsTraceEnabled; #endif void gpsSendByte(uint8_t byte); -#if defined(PCBX12S) +#if defined(INTERNAL_GPS) #define PILOTPOS_MIN_HDOP 500 #endif @@ -605,6 +618,7 @@ void bluetoothDisable(); extern DMAFifo<512> telemetryFifo; typedef DMAFifo<32> AuxSerialRxFifo; extern AuxSerialRxFifo auxSerialRxFifo; +extern volatile uint32_t externalModulePort; #endif #endif // _BOARD_H_ diff --git a/radio/src/targets/horus/extmodule_driver.cpp b/radio/src/targets/horus/extmodule_driver.cpp index 5c628edf1..0da9e46a5 100644 --- a/radio/src/targets/horus/extmodule_driver.cpp +++ b/radio/src/targets/horus/extmodule_driver.cpp @@ -350,6 +350,38 @@ void extmoduleSendNextFrame() } } +void extmoduleSendInvertedByte(uint8_t byte) +{ + uint16_t time; + uint32_t i; + + __disable_irq(); + time = getTmr2MHz(); + GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); + while ((uint16_t) (getTmr2MHz() - time) < 34) { + // wait + } + time += 34; + for (i = 0 ; i < 8 ; i += 1) { + if (byte & 1) { + GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); + } + else { + GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); + } + byte >>= 1 ; + while ((uint16_t) (getTmr2MHz() - time) < 35) { + // wait + } + time += 35 ; + } + GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); + __enable_irq() ; // No need to wait for the stop bit to complete + while ((uint16_t) (getTmr2MHz() - time) < 34) { + // wait + } +} + extern "C" void EXTMODULE_TIMER_DMA_IRQHandler() { if (!DMA_GetITStatus(EXTMODULE_TIMER_DMA_STREAM, EXTMODULE_TIMER_DMA_FLAG_TC)) diff --git a/radio/src/targets/horus/hal.h b/radio/src/targets/horus/hal.h index 10e169665..e7afa6ddb 100644 --- a/radio/src/targets/horus/hal.h +++ b/radio/src/targets/horus/hal.h @@ -183,10 +183,17 @@ #define TRIMS_GPIO_PIN_RVU GPIO_Pin_12 // PJ.12 #define TRIMS_GPIO_REG_RHR GPIOD->IDR #define TRIMS_GPIO_PIN_RHR GPIO_Pin_7 // PD.07 - #define TRIMS_GPIO_REG_LSU GPIOJ->IDR - #define TRIMS_GPIO_PIN_LSU GPIO_Pin_8 // PJ.08 - #define TRIMS_GPIO_REG_LSD GPIOD->IDR - #define TRIMS_GPIO_PIN_LSD GPIO_Pin_13 // PD.13 + #if defined(RADIO_T16) + #define TRIMS_GPIO_REG_LSU GPIOD->IDR + #define TRIMS_GPIO_PIN_LSU GPIO_Pin_13 // PD.13 + #define TRIMS_GPIO_REG_LSD GPIOJ->IDR + #define TRIMS_GPIO_PIN_LSD GPIO_Pin_8 // PJ.08 + #else + #define TRIMS_GPIO_REG_LSU GPIOJ->IDR + #define TRIMS_GPIO_PIN_LSU GPIO_Pin_8 // PJ.08 + #define TRIMS_GPIO_REG_LSD GPIOD->IDR + #define TRIMS_GPIO_PIN_LSD GPIO_Pin_13 // PD.13 + #endif #define TRIMS_GPIO_REG_RSU GPIOB->IDR #define TRIMS_GPIO_PIN_RSU GPIO_Pin_14 // PB.14 #define TRIMS_GPIO_REG_RSD GPIOB->IDR @@ -195,23 +202,22 @@ // Index of all keys #if defined(PCBX12S) - #define KEYS_GPIOB_PINS (SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_C_L | TRIMS_GPIO_PIN_LSD | TRIMS_GPIO_PIN_LSU) - #define KEYS_GPIOC_PINS (KEYS_GPIO_PIN_PGUP | KEYS_GPIO_PIN_ENTER | KEYS_GPIO_PIN_RIGHT | TRIMS_GPIO_PIN_RHL) - #define KEYS_GPIOD_PINS (SWITCHES_GPIO_PIN_C_H | TRIMS_GPIO_PIN_LHL | TRIMS_GPIO_PIN_LHR | TRIMS_GPIO_PIN_RSU) - #define KEYS_GPIOE_PINS (SWITCHES_GPIO_PIN_E_L) + #define KEYS_GPIOB_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15) + #define KEYS_GPIOC_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_13) + #define KEYS_GPIOD_PINS (GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_11 | GPIO_Pin_13) + #define KEYS_GPIOE_PINS (GPIO_Pin_3) #define KEYS_GPIOG_PINS (KEYS_GPIO_PIN_UP | SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L | SWITCHES_GPIO_PIN_H | TRIMS_GPIO_PIN_RVD) - #define KEYS_GPIOH_PINS (SWITCHES_GPIO_PIN_A_H | SWITCHES_GPIO_PIN_B_H | SWITCHES_GPIO_PIN_E_H | SWITCHES_GPIO_PIN_F | ROTARY_ENCODER_GPIO_PIN_A | ROTARY_ENCODER_GPIO_PIN_B) - #define KEYS_GPIOI_PINS (KEYS_GPIO_PIN_PGDN | KEYS_GPIO_PIN_LEFT | KEYS_GPIO_PIN_DOWN | SWITCHES_GPIO_PIN_A_L | TRIMS_GPIO_PIN_RHR) + #define KEYS_GPIOH_PINS (GPIO_Pin_9 | GPIO_Pin_12 | SWITCHES_GPIO_PIN_E_H | SWITCHES_GPIO_PIN_F | ROTARY_ENCODER_GPIO_PIN_A | ROTARY_ENCODER_GPIO_PIN_B) + #define KEYS_GPIOI_PINS (KEYS_GPIO_PIN_PGDN | KEYS_GPIO_PIN_LEFT | KEYS_GPIO_PIN_DOWN | SWITCHES_GPIO_PIN_A_L | GPIO_Pin_4) #define KEYS_GPIOJ_PINS (SWITCHES_GPIO_PIN_D_H | TRIMS_GPIO_PIN_RVU | TRIMS_GPIO_PIN_LVD | TRIMS_GPIO_PIN_LVU | TRIMS_GPIO_PIN_RSD) #elif defined(PCBX10) - #define KEYS_GPIOB_PINS (SWITCHES_GPIO_PIN_B_L | SWITCHES_GPIO_PIN_C_L | TRIMS_GPIO_PIN_RSU | TRIMS_GPIO_PIN_RSD | TRIMS_GPIO_PIN_LHL | TRIMS_GPIO_PIN_LHR) - #define KEYS_GPIOC_PINS (TRIMS_GPIO_PIN_LHL) - #define KEYS_GPIOD_PINS (SWITCHES_GPIO_PIN_C_H | TRIMS_GPIO_PIN_RHL | TRIMS_GPIO_PIN_RHR | TRIMS_GPIO_PIN_LSD) - #define KEYS_GPIOE_PINS (SWITCHES_GPIO_PIN_E_L) + #define KEYS_GPIOB_PINS (GPIO_Pin_12 | GPIO_Pin_15 | GPIO_Pin_14 | GPIO_Pin_13 | GPIO_Pin_8 | GPIO_Pin_9) + #define KEYS_GPIOD_PINS (GPIO_Pin_11 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_13) + #define KEYS_GPIOE_PINS (GPIO_Pin_3) #define KEYS_GPIOG_PINS (SWITCHES_GPIO_PIN_D_L | SWITCHES_GPIO_PIN_G_H | SWITCHES_GPIO_PIN_G_L | SWITCHES_GPIO_PIN_H | TRIMS_GPIO_PIN_LVD) #define KEYS_GPIOH_PINS (GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15) #define KEYS_GPIOI_PINS (GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_11 | GPIO_Pin_15) - #define KEYS_GPIOJ_PINS (SWITCHES_GPIO_PIN_D_H | TRIMS_GPIO_PIN_LVU | TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU | TRIMS_GPIO_PIN_LSU) + #define KEYS_GPIOJ_PINS (SWITCHES_GPIO_PIN_D_H | TRIMS_GPIO_PIN_LVU | TRIMS_GPIO_PIN_RVD | TRIMS_GPIO_PIN_RVU | GPIO_Pin_8) #endif // ADC @@ -282,8 +288,12 @@ #define ADC_DMA_Stream DMA2_Stream0 #define ADC_SET_DMA_FLAGS() ADC_DMA->LIFCR = (DMA_LIFCR_CTCIF0 | DMA_LIFCR_CHTIF0 | DMA_LIFCR_CTEIF0 | DMA_LIFCR_CDMEIF0 | DMA_LIFCR_CFEIF0) #define ADC_TRANSFER_COMPLETE() (ADC_DMA->LISR & DMA_LISR_TCIF0) +#if defined(RADIO_T16) + #define ADC_VREF_PREC2 300 +#else #define ADC_VREF_PREC2 250 #endif +#endif // Power #define PWR_RCC_AHB1Periph RCC_AHB1Periph_GPIOJ @@ -294,7 +304,7 @@ // S.Port update connector #define SPORT_MAX_BAUDRATE 250000 // < 400000 -#if defined(PCBX10) +#if defined(PCBX10) && !defined(RADIO_T16) #define SPORT_UPDATE_RCC_AHB1Periph RCC_AHB1Periph_GPIOH #define SPORT_UPDATE_PWR_GPIO GPIOH #define SPORT_UPDATE_PWR_GPIO_PIN GPIO_Pin_13 // PH.13 @@ -355,6 +365,7 @@ // Telemetry #define TELEMETRY_RCC_AHB1Periph (RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_DMA1) #define TELEMETRY_RCC_APB1Periph RCC_APB1Periph_USART2 +#define TELEMETRY_RCC_APB2Periph RCC_APB2Periph_TIM10 #define TELEMETRY_DIR_GPIO GPIOD #define TELEMETRY_DIR_GPIO_PIN GPIO_Pin_4 // PD.04 #define TELEMETRY_GPIO GPIOD @@ -364,6 +375,15 @@ #define TELEMETRY_GPIO_PinSource_RX GPIO_PinSource6 #define TELEMETRY_GPIO_AF GPIO_AF_USART2 #define TELEMETRY_USART USART2 +#define TELEMETRY_EXTI_PortSource EXTI_PortSourceGPIOD +#define TELEMETRY_EXTI_PinSource EXTI_PinSource6 +#define TELEMETRY_EXTI_LINE EXTI_Line6 +#define TELEMETRY_EXTI_IRQn EXTI9_5_IRQn +#define TELEMETRY_EXTI_IRQHandler EXTI9_5_IRQHandler +#define TELEMETRY_EXTI_TRIGGER EXTI_Trigger_Rising +#define TELEMETRY_TIMER TIM11 +#define TELEMETRY_TIMER_IRQn TIM1_TRG_COM_TIM11_IRQn +#define TELEMETRY_TIMER_IRQHandler TIM1_TRG_COM_TIM11_IRQHandler #if defined(PCBX12S) #define TELEMETRY_DMA_Stream_RX DMA1_Stream5 #define TELEMETRY_DMA_Channel_RX DMA_Channel_4 @@ -526,6 +546,10 @@ #define AUDIO_DMA DMA1 #endif +#if defined(RADIO_T16) + #define AUDIO_UNMUTE_DELAY 150 +#endif + // I2C Bus #define I2C_RCC_AHB1Periph RCC_AHB1Periph_GPIOB #define I2C_RCC_APB1Periph RCC_APB1Periph_I2C1 @@ -564,9 +588,9 @@ #define HAPTIC_TIMER_COMPARE_VALUE HAPTIC_GPIO_TIMER->CCR2 #endif -// Internal Module -#define HARDWARE_INTERNAL_MODULE +#if !defined(RADIO_T16) #define EXTERNAL_ANTENNA +#endif #define INTMODULE_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_DMA2) #define INTMODULE_PWR_GPIO GPIOA #define INTMODULE_PWR_GPIO_PIN GPIO_Pin_8 // PA.08 diff --git a/radio/src/targets/horus/keys_driver.cpp b/radio/src/targets/horus/keys_driver.cpp index 1a04427a4..52d862ad1 100644 --- a/radio/src/targets/horus/keys_driver.cpp +++ b/radio/src/targets/horus/keys_driver.cpp @@ -207,8 +207,10 @@ void keysInit() GPIO_InitStructure.GPIO_Pin = KEYS_GPIOB_PINS; GPIO_Init(GPIOB, &GPIO_InitStructure); +#if defined(KEYS_GPIOC_PINS) GPIO_InitStructure.GPIO_Pin = KEYS_GPIOC_PINS; GPIO_Init(GPIOC, &GPIO_InitStructure); +#endif GPIO_InitStructure.GPIO_Pin = KEYS_GPIOD_PINS; GPIO_Init(GPIOD, &GPIO_InitStructure); diff --git a/radio/src/targets/horus/telemetry_driver.cpp b/radio/src/targets/horus/telemetry_driver.cpp index 8b782f759..fe143cfe2 100644 --- a/radio/src/targets/horus/telemetry_driver.cpp +++ b/radio/src/targets/horus/telemetry_driver.cpp @@ -28,6 +28,17 @@ DMAFifo telemetryDMAFifo __DMA (TELEMETRY_DMA_Stream_RX); uint8_t telemetryFifoMode; #endif +static void telemetryInitDirPin() +{ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN; + GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure); + GPIO_ResetBits(TELEMETRY_DIR_GPIO, TELEMETRY_DIR_GPIO_PIN); +} + void telemetryPortInit(uint32_t baudrate, uint8_t mode) { if (baudrate == 0) { @@ -55,11 +66,7 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure); - GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure); - GPIO_ResetBits(TELEMETRY_DIR_GPIO, TELEMETRY_DIR_GPIO_PIN); + telemetryInitDirPin(); USART_InitStructure.USART_BaudRate = baudrate; if (mode & TELEMETRY_SERIAL_8E2) { @@ -126,6 +133,95 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) #endif } +// soft serial vars +static uint8_t rxBitCount; +static uint8_t rxByte; + +void telemetryPortInvertedInit(uint32_t baudrate) +{ + if (baudrate == 0) { + NVIC_DisableIRQ(TELEMETRY_EXTI_IRQn); + NVIC_DisableIRQ(TELEMETRY_TIMER_IRQn); + + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_StructInit(&EXTI_InitStructure); + EXTI_InitStructure.EXTI_Line = TELEMETRY_EXTI_LINE; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = TELEMETRY_EXTI_TRIGGER; + EXTI_InitStructure.EXTI_LineCmd = DISABLE; + EXTI_Init(&EXTI_InitStructure); + return; + } + + rxBitCount = 0; + + // configure bit sample timer + RCC->APB2ENR |= RCC_APB2ENR_TIM11EN; + TELEMETRY_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS + TELEMETRY_TIMER->CCER = 0; + TELEMETRY_TIMER->CCMR1 = 0; + TELEMETRY_TIMER->CR1 = TIM_CR1_CEN; + TELEMETRY_TIMER->DIER = TIM_DIER_UIE; + + NVIC_SetPriority(TELEMETRY_TIMER_IRQn, 0); + NVIC_EnableIRQ(TELEMETRY_TIMER_IRQn); + + // init TELEMETRY_RX_GPIO_PIN + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_InitStructure.GPIO_Pin = TELEMETRY_RX_GPIO_PIN; + GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure); + + telemetryInitDirPin(); + + // Connect EXTI line to TELEMETRY RX pin + SYSCFG_EXTILineConfig(TELEMETRY_EXTI_PortSource, TELEMETRY_EXTI_PinSource); + + // Configure EXTI for raising edge (start bit) + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_StructInit(&EXTI_InitStructure); + EXTI_InitStructure.EXTI_Line = TELEMETRY_EXTI_LINE; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = TELEMETRY_EXTI_TRIGGER; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + NVIC_SetPriority(TELEMETRY_EXTI_IRQn, 0); + NVIC_EnableIRQ(TELEMETRY_EXTI_IRQn); +} + +void telemetryPortInvertedRxBit() +{ + if (rxBitCount < 8) { + if (rxBitCount == 0) { + TELEMETRY_TIMER->ARR = 34; + rxByte = 0; + } + else { + rxByte >>= 1; + } + + if (GPIO_ReadInputDataBit(TELEMETRY_GPIO, TELEMETRY_RX_GPIO_PIN) == Bit_RESET) + rxByte |= 0x80; + + ++rxBitCount; + } + else if (rxBitCount == 8) { + + telemetryNoDMAFifo.push(rxByte); + rxBitCount = 0; + + // disable timer + TELEMETRY_TIMER->CR1 &= ~TIM_CR1_CEN; + + // re-enable start bit interrupt + EXTI->IMR |= EXTI_IMR_MR6; + } +} + void telemetryPortSetDirectionOutput() { TELEMETRY_DIR_GPIO->BSRRL = TELEMETRY_DIR_GPIO_PIN; // output enable @@ -253,8 +349,31 @@ extern "C" void TELEMETRY_USART_IRQHandler(void) } } +extern "C" void TELEMETRY_EXTI_IRQHandler(void) +{ + if (EXTI_GetITStatus(TELEMETRY_EXTI_LINE) != RESET) { + + if (rxBitCount == 0) { + + TELEMETRY_TIMER->ARR = 48; // 1,5 cycle from start at 57600bps + TELEMETRY_TIMER->CR1 |= TIM_CR1_CEN; + + // disable start bit interrupt + EXTI->IMR &= ~EXTI_IMR_MR6; + } + + EXTI_ClearITPendingBit(TELEMETRY_EXTI_LINE); + } +} + +extern "C" void TELEMETRY_TIMER_IRQHandler() +{ + TELEMETRY_TIMER->SR &= ~TIM_SR_UIF; + telemetryPortInvertedRxBit(); +} + // TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp -uint8_t telemetryGetByte(uint8_t * byte) +bool telemetryGetByte(uint8_t * byte) { #if defined(PCBX12S) if (telemetryFifoMode & TELEMETRY_SERIAL_WITHOUT_DMA) diff --git a/radio/src/targets/horus/x12s_adc_driver.cpp b/radio/src/targets/horus/x12s_adc_driver.cpp index 932f752a0..2833c4620 100644 --- a/radio/src/targets/horus/x12s_adc_driver.cpp +++ b/radio/src/targets/horus/x12s_adc_driver.cpp @@ -139,7 +139,7 @@ void adcInit() uint16_t getRTCBatteryVoltage() { - return (rtcBatteryVoltage * ADC_VREF_PREC2) / 2048; + return (rtcBatteryVoltage * 2 * ADC_VREF_PREC2) / 2048; } const uint16_t adcCommands[MOUSE1+2] = diff --git a/radio/src/targets/nv14/board.h b/radio/src/targets/nv14/board.h index 077c9bb40..a39c7e591 100644 --- a/radio/src/targets/nv14/board.h +++ b/radio/src/targets/nv14/board.h @@ -145,12 +145,13 @@ void SDRAM_Init(); void init_intmodule_heartbeat(); void check_intmodule_heartbeat(); -void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable); +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength); void intmoduleSendBuffer(const uint8_t * data, uint8_t size); void intmoduleSendNextFrame(); void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inverted); void extmoduleSendNextFrame(); +void extmoduleSendInvertedByte(uint8_t byte); // Trainer driver void init_trainer_ppm(); @@ -452,6 +453,9 @@ void telemetryClearFifo(); void sportSendByte(uint8_t byte); extern uint32_t telemetryErrors; +// soft-serial +void telemetryPortInvertedInit(uint32_t baudrate); + // Sport update driver #define SPORT_UPDATE_POWER_ON() #define SPORT_UPDATE_POWER_OFF() diff --git a/radio/src/targets/nv14/telemetry_driver.cpp b/radio/src/targets/nv14/telemetry_driver.cpp index 1629d8d69..2e440380c 100644 --- a/radio/src/targets/nv14/telemetry_driver.cpp +++ b/radio/src/targets/nv14/telemetry_driver.cpp @@ -89,6 +89,16 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) NVIC_EnableIRQ(TELEMETRY_USART_IRQn); } +void telemetryPortInvertedInit(uint32_t baudrate) +{ +#warning "TODO telemetryPortInvertedInit"; +} + +void extmoduleSendInvertedByte(uint8_t byte) +{ +#warning "TODO extmoduleSendInvertedByte"; +} + void telemetryPortSetDirectionOutput() { TELEMETRY_DIR_OUTPUT(); diff --git a/radio/src/targets/simu/opentxsimulator.cpp b/radio/src/targets/simu/opentxsimulator.cpp index 3c528e743..b9463ac8f 100644 --- a/radio/src/targets/simu/opentxsimulator.cpp +++ b/radio/src/targets/simu/opentxsimulator.cpp @@ -607,6 +607,8 @@ class OpenTxSimulatorFactory: public SimulatorFactory return Board::BOARD_X10; #elif defined(PCBX7) return Board::BOARD_TARANIS_X7; +#elif defined(PCBX9LITES) + return Board::BOARD_TARANIS_X9LITES; #elif defined(PCBX9LITE) return Board::BOARD_TARANIS_X9LITE; #elif defined(PCBTARANIS) diff --git a/radio/src/targets/sky9x/CMakeLists.txt b/radio/src/targets/sky9x/CMakeLists.txt index f1081e5b1..cb207e10a 100644 --- a/radio/src/targets/sky9x/CMakeLists.txt +++ b/radio/src/targets/sky9x/CMakeLists.txt @@ -10,6 +10,7 @@ set(TARGET_DIR sky9x) set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} 9x_bitmaps) set(PPM_LIMITS_SYMETRICAL YES) set(PXX1 YES) +add_definitions(-DDISABLE_MULTI_UPDATE) if(PCB STREQUAL 9XRPRO) add_definitions(-Dat91sam3s8 -DREVX) diff --git a/radio/src/targets/taranis/CMakeLists.txt b/radio/src/targets/taranis/CMakeLists.txt index 08ff86af8..57ca6962e 100644 --- a/radio/src/targets/taranis/CMakeLists.txt +++ b/radio/src/targets/taranis/CMakeLists.txt @@ -1,14 +1,15 @@ option(SHUTDOWN_CONFIRMATION "Shutdown confirmation" OFF) option(LCD_DUAL_BUFFER "Dual LCD Buffer" OFF) -option(INTERNAL_MODULE_PPM "Support for PPM internal module hack" OFF) -option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module replacement" OFF) option(PXX1 "PXX1 protocol support" ON) option(PXX2 "PXX2 protocol support" OFF) +option(INTERNAL_MODULE_PPM "Support for PPM internal module" OFF) option(AUTOUPDATE "Auto update internal chips from SD" OFF) add_definitions(-DPCBFRSKY) if(PCB STREQUAL X9E) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(STICKS "STANDARD" CACHE STRING "Sticks type (STANDARD/HORUS)") set(CPU_TYPE STM32F4) @@ -51,6 +52,8 @@ elseif(PCB STREQUAL X9D+) set(PCBREV 2014 CACHE STRING "PCB Revision") add_definitions(-DPCBREV=${PCBREV}) if (${PCBREV} STREQUAL 2019) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" OFF) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON) set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(CPU_TYPE STM32F4) set(CPU_TYPE_FULL STM32F407xE) # for size report @@ -66,6 +69,8 @@ elseif(PCB STREQUAL X9D+) set(PXX_FREQUENCY "HIGH") set(FLAVOUR x9d+2019) else() + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) set(CPU_TYPE STM32F2) set(CPU_TYPE_FULL STM32F205xE) # for size report set(LINKER_SCRIPT targets/taranis/stm32f2_flash.ld) @@ -74,6 +79,8 @@ elseif(PCB STREQUAL X9D+) set(FLAVOUR x9d+) endif() elseif(PCB STREQUAL X9D) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) set(CPU_TYPE STM32F2) set(CPU_TYPE_FULL STM32F205xE) # for size report set(LINKER_SCRIPT targets/taranis/stm32f2_flash.ld) @@ -103,6 +110,8 @@ elseif(PCB STREQUAL X7) add_definitions(-DRADIO_T12) add_definitions(-DEEPROM_VARIANT=0x4001) else() + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) set(LUA_EXPORT lua_export_x7) set(FLAVOUR x7) set(NAVIGATION_TYPE x7) @@ -118,6 +127,8 @@ elseif(PCB STREQUAL X7) set(GVAR_SCREEN model_gvars.cpp) set(STATUS_LEDS YES) elseif(PCB STREQUAL X9LITE) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" OFF) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON) set(PXX_FREQUENCY "HIGH") set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(CPU_TYPE STM32F2) @@ -138,7 +149,32 @@ elseif(PCB STREQUAL X9LITE) set(LCD_DRIVER lcd_driver_spi.cpp) set(GVAR_SCREEN model_gvars.cpp) set(STATUS_LEDS YES) +elseif(PCB STREQUAL X9LITES) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" OFF) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON) + set(PXX_FREQUENCY "HIGH") + set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") + set(CPU_TYPE STM32F2) + set(CPU_TYPE_FULL STM32F205xE) # for size report + set(LINKER_SCRIPT targets/taranis/stm32f2_flash.ld) + set(HAPTIC YES) + set(LUA_EXPORT lua_export_x9lites) + set(FLAVOUR x9lites) + add_definitions(-DBOARD_NAME="x9lites") + add_definitions(-DPCBX9LITES -DPCBX9LITE -DPCBX9 -DSOFTWARE_VOLUME -DHARDWARE_POWER_MANAGEMENT_UNIT) + add_definitions(-DEEPROM_VARIANT=0x0800) + add_definitions(-DPWR_BUTTON_${PWR_BUTTON}) + set(PXX2 ON) + set(GUI_DIR 128x64) + set(NAVIGATION_TYPE x7) + set(BITMAPS_TARGET 9x_bitmaps) + set(FONTS_TARGET 9x_fonts_1bit) + set(LCD_DRIVER lcd_driver_spi.cpp) + set(GVAR_SCREEN model_gvars.cpp) + set(STATUS_LEDS YES) elseif(PCB STREQUAL XLITE) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" ON) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" OFF) set(PXX_FREQUENCY "HIGH" CACHE STRING "PXX frequency (LOW / HIGH)") # always use HIGH except on some prototype boards set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(CPU_TYPE STM32F2) @@ -159,6 +195,8 @@ elseif(PCB STREQUAL XLITE) set(GVAR_SCREEN model_gvars.cpp) set(STATUS_LEDS YES) elseif(PCB STREQUAL XLITES) + option(INTERNAL_MODULE_PXX1 "Support for PXX1 internal module" OFF) + option(INTERNAL_MODULE_PXX2 "Support for PXX2 internal module" ON) set(PXX_FREQUENCY "HIGH") set(PWR_BUTTON "PRESS" CACHE STRING "Pwr button type (PRESS/SWITCH)") set(CPU_TYPE STM32F2) @@ -192,7 +230,7 @@ if(PCB STREQUAL XLITES) ) endif() -if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR PCB STREQUAL X9LITE OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)) +if(PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)) add_definitions(-DINTERNAL_MODULE_SERIAL) if(PXX_FREQUENCY STREQUAL HIGH) add_definitions(-DPXX_FREQUENCY_HIGH) @@ -208,14 +246,14 @@ elseif(NOT (PCB STREQUAL X7 AND PCBREV STREQUAL T12)) ) endif() -if(PCB STREQUAL X9E OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR (PCB STREQUAL X7 AND NOT (PCBREV STREQUAL T12)) OR PCB STREQUAL X9LITE) +if(PCB STREQUAL X9E OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR (PCB STREQUAL X7 AND NOT (PCBREV STREQUAL T12)) OR PCB STREQUAL X9LITE OR PCB STREQUAL X9LITES) set(TARGET_SRC ${TARGET_SRC} ../common/arm/stm32/rotary_encoder_driver.cpp ) endif() -if(PCB STREQUAL X9E OR PCB STREQUAL X7 OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019)) +if(PCB STREQUAL X9E OR PCB STREQUAL X7 OR PCB STREQUAL XLITE OR PCB STREQUAL XLITES OR (PCB STREQUAL X9D+ AND PCBREV STREQUAL 2019) OR PCB STREQUAL X9LITES) add_definitions(-DBLUETOOTH) set(TARGET_SRC ${TARGET_SRC} @@ -247,6 +285,7 @@ add_definitions(-DAUDIO -DVOICE -DRTCLOCK) set(SRC ${SRC} io/frsky_firmware_update.cpp + io/multi_firmware_update.cpp ) set(GUI_SRC @@ -303,12 +342,20 @@ if(LCD_DUAL_BUFFER) add_definitions(-DLCD_DUAL_BUFFER) endif() -if(INTERNAL_MODULE_PPM) - add_definitions(-DINTERNAL_MODULE_PPM) -endif() - if(INTERNAL_MODULE_PXX1) + add_definitions(-DHARDWARE_INTERNAL_MODULE) add_definitions(-DINTERNAL_MODULE_PXX1) endif() +if(INTERNAL_MODULE_PXX2) + set(PXX2 ON) + add_definitions(-DHARDWARE_INTERNAL_MODULE) + add_definitions(-DINTERNAL_MODULE_PXX2) +endif() + +if(INTERNAL_MODULE_PPM) + add_definitions(-DHARDWARE_INTERNAL_MODULE) + add_definitions(-DINTERNAL_MODULE_PPM) +endif() + set(RADIO_DEPENDENCIES ${RADIO_DEPENDENCIES} ${BITMAPS_TARGET}) diff --git a/radio/src/targets/taranis/board.h b/radio/src/targets/taranis/board.h index a604672bc..1dca15031 100644 --- a/radio/src/targets/taranis/board.h +++ b/radio/src/targets/taranis/board.h @@ -121,7 +121,7 @@ uint32_t isBootloaderStart(const uint8_t * buffer); #define IS_INTERNAL_MODULE_ON() (GPIO_ReadInputDataBit(INTMODULE_PWR_GPIO, INTMODULE_PWR_GPIO_PIN) == Bit_SET) #endif -void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable); +void intmoduleSerialStart(uint32_t baudrate, uint8_t rxEnable, uint16_t parity, uint16_t stopBits, uint16_t wordLength); void intmoduleSendByte(uint8_t byte); void intmoduleSendBuffer(const uint8_t * data, uint8_t size); void intmoduleSendNextFrame(); @@ -130,6 +130,7 @@ void extmoduleSerialStart(uint32_t baudrate, uint32_t period_half_us, bool inver void extmoduleInvertedSerialStart(uint32_t baudrate); void extmoduleSendBuffer(const uint8_t * data, uint8_t size); void extmoduleSendNextFrame(); +void extmoduleSendInvertedByte(uint8_t byte); // Trainer driver #define SLAVE_MODE() (g_model.trainerData.mode == TRAINER_MODE_SLAVE) @@ -191,6 +192,8 @@ void check_intmodule_heartbeat(); #define check_intmodule_heartbeat() #endif +void check_telemetry_exti(); + // SBUS int sbusGetByte(uint8_t * byte); @@ -307,17 +310,17 @@ enum EnumSwitchesPositions SW_SD0, SW_SD1, SW_SD2, -#if defined(PCBX9) || defined(PCBXLITES) +#if defined(PCBX9) || defined(PCBXLITES) || defined(PCBX9LITES) SW_SE0, SW_SE1, SW_SE2, #endif -#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || defined(PCBX7) || defined(PCBXLITES) +#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || defined(PCBX7) || defined(PCBXLITES) || defined(PCBX9LITES) SW_SF0, SW_SF1, SW_SF2, #endif -#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) +#if defined(PCBX9D) || defined(PCBX9DP) || defined(PCBX9E) || defined(PCBX9LITES) SW_SG0, SW_SG1, SW_SG2, @@ -395,6 +398,11 @@ enum EnumSwitchesPositions #define STORAGE_NUM_SWITCHES NUM_SWITCHES #define DEFAULT_SWITCH_CONFIG (SWITCH_TOGGLE << 10) + (SWITCH_2POS << 8) + (SWITCH_3POS << 6) + (SWITCH_3POS << 4) + (SWITCH_3POS << 2) + (SWITCH_3POS << 0) #define DEFAULT_POTS_CONFIG (POT_WITHOUT_DETENT << 0) + (POT_WITH_DETENT << 2); // S1 = pot without detent, S2 = pot with detent +#elif defined(PCBX9LITES) + #define NUM_SWITCHES 7 + #define STORAGE_NUM_SWITCHES NUM_SWITCHES + #define DEFAULT_SWITCH_CONFIG (SWITCH_TOGGLE << 12) + (SWITCH_TOGGLE << 10) + (SWITCH_TOGGLE << 8) + (SWITCH_2POS << 6) + (SWITCH_3POS << 4) + (SWITCH_3POS << 2) + (SWITCH_3POS << 0); + #define DEFAULT_POTS_CONFIG (POT_WITH_DETENT << 0); // S1 = pot with detent #elif defined(PCBX9LITE) #define NUM_SWITCHES 5 #define STORAGE_NUM_SWITCHES NUM_SWITCHES @@ -492,14 +500,19 @@ enum Analogs { #define NUM_SLIDERS 4 #define STORAGE_NUM_POTS 4 #define STORAGE_NUM_SLIDERS 4 -#else +#elif defined(PCBX9DP) #define NUM_POTS 3 #define NUM_SLIDERS 2 #define STORAGE_NUM_POTS 3 #define STORAGE_NUM_SLIDERS 2 +#else + #define NUM_POTS 3 // TODO X9D has only 2 pots + #define NUM_SLIDERS 2 + #define STORAGE_NUM_POTS 3 + #define STORAGE_NUM_SLIDERS 2 #endif -#define NUM_XPOTS NUM_POTS +#define NUM_XPOTS STORAGE_NUM_POTS #define NUM_TRIMS 4 #define NUM_MOUSE_ANALOGS 0 #define STORAGE_NUM_MOUSE_ANALOGS 0 @@ -665,10 +678,13 @@ void sportSendByte(uint8_t byte); void sportSendByteLoop(uint8_t byte); void sportStopSendByteLoop(); void sportSendBuffer(const uint8_t * buffer, uint32_t count); -uint8_t telemetryGetByte(uint8_t * byte); +bool telemetryGetByte(uint8_t * byte); void telemetryClearFifo(); extern uint32_t telemetryErrors; +// soft-serial +void telemetryPortInvertedInit(uint32_t baudrate); + // PCBREV driver #if defined(PCBX7) #define IS_PCBREV_40() (GPIO_ReadInputDataBit(PCBREV_GPIO, PCBREV_GPIO_PIN) == Bit_SET) @@ -766,7 +782,9 @@ void bluetoothInit(uint32_t baudrate, bool enable); void bluetoothWriteWakeup(); uint8_t bluetoothIsWriting(); void bluetoothDisable(); -#if defined(PCBX9LITE) +#if defined(PCBX9LITES) + #define IS_BLUETOOTH_CHIP_PRESENT() (true) +#elif defined(PCBX9LITE) #define IS_BLUETOOTH_CHIP_PRESENT() (false) #elif (defined(PCBX7) || defined(PCBXLITE)) && !defined(SIMU) extern volatile uint8_t btChipPresent; diff --git a/radio/src/targets/taranis/extmodule_driver.cpp b/radio/src/targets/taranis/extmodule_driver.cpp index 3ab23f3e9..19bd04525 100644 --- a/radio/src/targets/taranis/extmodule_driver.cpp +++ b/radio/src/targets/taranis/extmodule_driver.cpp @@ -309,6 +309,38 @@ void extmoduleSendNextFrame() } } +void extmoduleSendInvertedByte(uint8_t byte) +{ + uint16_t time; + uint32_t i; + + __disable_irq(); + time = getTmr2MHz(); + GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); + while ((uint16_t) (getTmr2MHz() - time) < 34) { + // wait + } + time += 34; + for (i = 0 ; i < 8 ; i += 1) { + if (byte & 1) { + GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); + } + else { + GPIO_SetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); + } + byte >>= 1 ; + while ((uint16_t) (getTmr2MHz() - time) < 35) { + // wait + } + time += 35 ; + } + GPIO_ResetBits(EXTMODULE_TX_GPIO, EXTMODULE_TX_GPIO_PIN); + __enable_irq() ; // No need to wait for the stop bit to complete + while ((uint16_t) (getTmr2MHz() - time) < 34) { + // wait + } +} + extern "C" void EXTMODULE_TIMER_DMA_STREAM_IRQHandler() { if (!DMA_GetITStatus(EXTMODULE_TIMER_DMA_STREAM, EXTMODULE_TIMER_DMA_FLAG_TC)) diff --git a/radio/src/targets/taranis/hal.h b/radio/src/targets/taranis/hal.h index 99acd429b..53cc66618 100644 --- a/radio/src/targets/taranis/hal.h +++ b/radio/src/targets/taranis/hal.h @@ -448,6 +448,11 @@ #elif defined(PCBXLITE) // no SWF but we want to remain compatible with XLiteS #define STORAGE_SWITCH_F +#elif defined(PCBX9LITES) + #define STORAGE_SWITCH_F + #define HARDWARE_SWITCH_F + #define SWITCHES_GPIO_REG_F GPIOC->IDR + #define SWITCHES_GPIO_PIN_F GPIO_Pin_3 // PC.03 #elif defined(PCBX9LITE) // no SWF #elif defined(PCBX7) @@ -469,6 +474,11 @@ #define SWITCHES_GPIO_PIN_G_H GPIO_Pin_3 // PF.03 #define SWITCHES_GPIO_REG_G_L GPIOF->IDR #define SWITCHES_GPIO_PIN_G_L GPIO_Pin_4 // PF.04 +#elif defined(PCBX9LITES) + #define STORAGE_SWITCH_G + #define HARDWARE_SWITCH_G + #define SWITCHES_GPIO_REG_G GPIOC->IDR + #define SWITCHES_GPIO_PIN_G GPIO_Pin_2 // PC.02 #elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITE) // no SWG #else @@ -521,8 +531,8 @@ #define HARDWARE_SWITCH_J #define SWITCHES_GPIO_REG_I GPIOC->IDR #define SWITCHES_GPIO_PIN_I GPIO_Pin_13 // PC.13 - #define SWITCHES_GPIO_REG_J GPIOC->IDR - #define SWITCHES_GPIO_PIN_J GPIO_Pin_10 // PC.10 + #define SWITCHES_GPIO_REG_J GPIOD->IDR + #define SWITCHES_GPIO_PIN_J GPIO_Pin_10 // PD.10 #endif #if defined(PCBX9E) @@ -632,9 +642,16 @@ #elif defined(RADIO_X7) #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE) #define KEYS_GPIOA_PINS GPIO_Pin_5 - #define KEYS_GPIOC_PINS (GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_10 | GPIO_Pin_13) - #define KEYS_GPIOD_PINS (GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15) + #define KEYS_GPIOC_PINS (GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_13) + #define KEYS_GPIOD_PINS (GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_14 | GPIO_Pin_15) #define KEYS_GPIOE_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15) +#elif defined(PCBX9LITES) + #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE) + #define KEYS_GPIOA_PINS (GPIO_Pin_5) + #define KEYS_GPIOB_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5) + #define KEYS_GPIOC_PINS (GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_13) + #define KEYS_GPIOD_PINS (GPIO_Pin_8 | GPIO_Pin_9) + #define KEYS_GPIOE_PINS (GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14) #elif defined(PCBX9LITE) #define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE) #define KEYS_GPIOA_PINS (GPIO_Pin_5) @@ -891,6 +908,14 @@ #define LED_RED_GPIO_PIN GPIO_Pin_5 // PC.05 #define LED_BLUE_GPIO GPIOB #define LED_BLUE_GPIO_PIN GPIO_Pin_1 // PB.01 +#elif defined(PCBX9LITES) + #define STATUS_LEDS + #define GPIO_LED_GPIO_ON GPIO_SetBits + #define GPIO_LED_GPIO_OFF GPIO_ResetBits + #define LED_RED_GPIO GPIOE + #define LED_RED_GPIO_PIN GPIO_Pin_5 // PE.05 + #define LED_BLUE_GPIO GPIOE + #define LED_BLUE_GPIO_PIN GPIO_Pin_6 // PE.06 #elif defined(PCBX9LITE) #define STATUS_LEDS #define GPIO_LED_GPIO_ON GPIO_SetBits @@ -904,17 +929,9 @@ #endif // Internal Module -#if !defined(RADIO_T12) - #define HARDWARE_INTERNAL_MODULE -#endif #if defined(PCBXLITE) #define EXTERNAL_ANTENNA #endif -#if defined(PCBXLITES) || defined(PCBX9LITE) || (defined(PCBX9DP) && PCBREV >= 2019) - #define INTERNAL_MODULE_PXX2 -#else - #define INTERNAL_MODULE_PXX1 -#endif #if defined(PCBXLITE) || defined(PCBX9LITE) #define INTMODULE_RCC_APB1Periph 0 #define INTMODULE_RCC_APB2Periph RCC_APB2Periph_USART1 @@ -1267,6 +1284,23 @@ #define TELEMETRY_DMA_TX_FLAG_TC DMA_IT_TCIF6 #define TELEMETRY_USART_IRQHandler USART2_IRQHandler #define TELEMETRY_USART_IRQn USART2_IRQn +#define TELEMETRY_EXTI_PortSource EXTI_PortSourceGPIOD +#define TELEMETRY_EXTI_PinSource EXTI_PinSource6 +#define TELEMETRY_EXTI_LINE EXTI_Line6 +#define TELEMETRY_EXTI_IRQn EXTI9_5_IRQn +#define TELEMETRY_EXTI_TRIGGER EXTI_Trigger_Rising + +#if defined(RADIO_X7) + #define TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER +#elif defined(PCBXLITE) || defined(PCBX9LITE) || (defined(PCBX9DP) && PCBREV >= 2019) + #define TELEMETRY_EXTI_IRQHandler EXTI9_5_IRQHandler +#else + #define TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT +#endif + +#define TELEMETRY_TIMER TIM11 +#define TELEMETRY_TIMER_IRQn TIM1_TRG_COM_TIM11_IRQn +#define TELEMETRY_TIMER_IRQHandler TIM1_TRG_COM_TIM11_IRQHandler // PCBREV #if defined(PCBX7) @@ -1788,7 +1822,7 @@ #define BT_TX_GPIO_PinSource GPIO_PinSource14 #define BT_RX_GPIO_PinSource GPIO_PinSource9 #define BT_USART_IRQHandler USART6_IRQHandler -#elif defined(PCBX7) || defined(PCBXLITE) || (defined(PCBX9DP) && PCBREV >= 2019) +#elif defined(PCBX7) || defined(PCBXLITE) || defined(PCBX9LITES) || (defined(PCBX9DP) && PCBREV >= 2019) #define STORAGE_BLUETOOTH #define BT_RCC_APB1Periph RCC_APB1Periph_USART3 #define BT_RCC_APB2Periph 0 @@ -1800,6 +1834,10 @@ #define BT_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE) // RCC_AHB1Periph_DMA1 #define BT_EN_GPIO GPIOE #define BT_EN_GPIO_PIN GPIO_Pin_15 // PE.15 + #elif defined(PCBX9LITES) + #define BT_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOD) // RCC_AHB1Periph_DMA1 + #define BT_EN_GPIO GPIOD + #define BT_EN_GPIO_PIN GPIO_Pin_14 // PD.14 #else #define BT_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOE) // RCC_AHB1Periph_DMA1 #define BT_EN_GPIO GPIOE diff --git a/radio/src/targets/taranis/intmodule_pulses_driver.cpp b/radio/src/targets/taranis/intmodule_pulses_driver.cpp index 8e16f19d7..e71768eac 100644 --- a/radio/src/targets/taranis/intmodule_pulses_driver.cpp +++ b/radio/src/targets/taranis/intmodule_pulses_driver.cpp @@ -19,6 +19,7 @@ */ #include "opentx.h" +#include "pulses/pulses.h" void intmoduleStop() { diff --git a/radio/src/targets/taranis/keys_driver.cpp b/radio/src/targets/taranis/keys_driver.cpp index 144d7e97e..acfcb822e 100644 --- a/radio/src/targets/taranis/keys_driver.cpp +++ b/radio/src/targets/taranis/keys_driver.cpp @@ -179,7 +179,12 @@ uint32_t switchState(uint8_t index) ADD_3POS_CASE(B, 1); ADD_3POS_CASE(C, 2); -#if defined(PCBX9LITE) +#if defined(PCBX9LITES) + ADD_2POS_CASE(D); + ADD_2POS_CASE(E); + ADD_2POS_CASE(F); + ADD_2POS_CASE(G); +#elif defined(PCBX9LITE) ADD_2POS_CASE(D); ADD_2POS_CASE(E); #elif defined(PCBXLITES) @@ -194,6 +199,8 @@ uint32_t switchState(uint8_t index) ADD_3POS_CASE(D, 3); ADD_2POS_CASE(F); ADD_2POS_CASE(H); + ADD_2POS_CASE(I); + ADD_2POS_CASE(J); #else ADD_3POS_CASE(D, 3); ADD_3POS_CASE(E, 4); diff --git a/radio/src/targets/taranis/telemetry_driver.cpp b/radio/src/targets/taranis/telemetry_driver.cpp index ec6da0c86..3c9618f03 100644 --- a/radio/src/targets/taranis/telemetry_driver.cpp +++ b/radio/src/targets/taranis/telemetry_driver.cpp @@ -23,6 +23,17 @@ Fifo telemetryFifo; uint32_t telemetryErrors = 0; +static void telemetryInitDirPin() +{ + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; + GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN; + GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure); + TELEMETRY_DIR_INPUT(); +} + void telemetryPortInit(uint32_t baudrate, uint8_t mode) { if (baudrate == 0) { @@ -48,11 +59,7 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure); - GPIO_InitStructure.GPIO_Pin = TELEMETRY_DIR_GPIO_PIN; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(TELEMETRY_DIR_GPIO, &GPIO_InitStructure); - TELEMETRY_DIR_INPUT(); + telemetryInitDirPin(); USART_DeInit(TELEMETRY_USART); USART_InitTypeDef USART_InitStructure; @@ -77,6 +84,110 @@ void telemetryPortInit(uint32_t baudrate, uint8_t mode) NVIC_EnableIRQ(TELEMETRY_USART_IRQn); } +// soft serial vars +static uint8_t rxBitCount; +static uint8_t rxByte; + +//TODO: +// - only 57600 supported for now +// - handle other bitrates as well? +// +void telemetryPortInvertedInit(uint32_t baudrate) +{ + if (baudrate == 0) { + + //TODO: + // - handle conflict with HEARTBEAT disabled for trainer input... + // - probably need to stop trainer input/output and restore after this is closed +#if !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER) && !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT) + NVIC_DisableIRQ(TELEMETRY_EXTI_IRQn); +#endif + NVIC_DisableIRQ(TELEMETRY_TIMER_IRQn); + + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_StructInit(&EXTI_InitStructure); + EXTI_InitStructure.EXTI_Line = TELEMETRY_EXTI_LINE; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = TELEMETRY_EXTI_TRIGGER; + EXTI_InitStructure.EXTI_LineCmd = DISABLE; + EXTI_Init(&EXTI_InitStructure); + return; + } + + rxBitCount = 0; + + // configure bit sample timer + RCC->APB2ENR |= RCC_APB2ENR_TIM11EN; + TELEMETRY_TIMER->PSC = (PERI2_FREQUENCY * TIMER_MULT_APB2) / 2000000 - 1; // 0.5uS + TELEMETRY_TIMER->CCER = 0; + TELEMETRY_TIMER->CCMR1 = 0; + TELEMETRY_TIMER->CR1 = TIM_CR1_CEN; + TELEMETRY_TIMER->DIER = TIM_DIER_UIE; + + NVIC_SetPriority(TELEMETRY_TIMER_IRQn, 0); + NVIC_EnableIRQ(TELEMETRY_TIMER_IRQn); + + // init TELEMETRY_RX_GPIO_PIN + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN; + GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; + GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; + GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; + GPIO_InitStructure.GPIO_Pin = TELEMETRY_RX_GPIO_PIN; + GPIO_Init(TELEMETRY_GPIO, &GPIO_InitStructure); + + telemetryInitDirPin(); + + // Connect EXTI line to TELEMETRY RX pin + SYSCFG_EXTILineConfig(TELEMETRY_EXTI_PortSource, TELEMETRY_EXTI_PinSource); + + // Configure EXTI for raising edge (start bit) + EXTI_InitTypeDef EXTI_InitStructure; + EXTI_StructInit(&EXTI_InitStructure); + EXTI_InitStructure.EXTI_Line = TELEMETRY_EXTI_LINE; + EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; + EXTI_InitStructure.EXTI_Trigger = TELEMETRY_EXTI_TRIGGER; + EXTI_InitStructure.EXTI_LineCmd = ENABLE; + EXTI_Init(&EXTI_InitStructure); + + //TODO: + // - handle conflict with HEARTBEAT disabled for trainer input... + // - probably need to stop trainer input/output and restore after this is closed +#if !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_ROTARY_ENCODER) && !defined(TELEMETRY_EXTI_REUSE_INTERRUPT_INTMODULE_HEARTBEAT) + NVIC_SetPriority(TELEMETRY_EXTI_IRQn, 0); + NVIC_EnableIRQ(TELEMETRY_EXTI_IRQn); +#endif +} + +void telemetryPortInvertedRxBit() +{ + if (rxBitCount < 8) { + if (rxBitCount == 0) { + TELEMETRY_TIMER->ARR = 34; + rxByte = 0; + } + else { + rxByte >>= 1; + } + + if (GPIO_ReadInputDataBit(TELEMETRY_GPIO, TELEMETRY_RX_GPIO_PIN) == Bit_RESET) + rxByte |= 0x80; + + ++rxBitCount; + } + else if (rxBitCount == 8) { + + telemetryFifo.push(rxByte); + rxBitCount = 0; + + // disable timer + TELEMETRY_TIMER->CR1 &= ~TIM_CR1_CEN; + + // re-enable start bit interrupt + EXTI->IMR |= EXTI_IMR_MR6; + } +} + void telemetryPortSetDirectionOutput() { TELEMETRY_DIR_OUTPUT(); @@ -217,8 +328,38 @@ extern "C" void TELEMETRY_USART_IRQHandler(void) } } +void check_telemetry_exti() +{ + if (EXTI_GetITStatus(TELEMETRY_EXTI_LINE) != RESET) { + + if (rxBitCount == 0) { + + TELEMETRY_TIMER->ARR = 48; // 1,5 cycle from start at 57600bps + TELEMETRY_TIMER->CR1 |= TIM_CR1_CEN; + + // disable start bit interrupt + EXTI->IMR &= ~EXTI_IMR_MR6; + } + + EXTI_ClearITPendingBit(TELEMETRY_EXTI_LINE); + } +} + +#if defined(TELEMETRY_EXTI_IRQHandler) +extern "C" void TELEMETRY_EXTI_IRQHandler(void) +{ + check_telemetry_exti(); +} +#endif + +extern "C" void TELEMETRY_TIMER_IRQHandler() +{ + TELEMETRY_TIMER->SR &= ~TIM_SR_UIF; + telemetryPortInvertedRxBit(); +} + // TODO we should have telemetry in an higher layer, functions above should move to a sport_driver.cpp -uint8_t telemetryGetByte(uint8_t * byte) +bool telemetryGetByte(uint8_t * byte) { #if defined(AUX_SERIAL) if (telemetryProtocol == PROTOCOL_TELEMETRY_FRSKY_D_SECONDARY) { diff --git a/radio/src/telemetry/flysky_ibus.cpp b/radio/src/telemetry/flysky_ibus.cpp index d4b00c995..9074daa21 100644 --- a/radio/src/telemetry/flysky_ibus.cpp +++ b/radio/src/telemetry/flysky_ibus.cpp @@ -16,148 +16,281 @@ #include "opentx.h" /* - * Telemetry format from goebish/Deviation/flysky_afhds2a_a7105.c - * - * format from RX: - * AA | TXID | RXID | sensor id | sensor # | value 16 bit big endian | sensor id ...... - * max 7 sensors per packet - * * TXID + RXID are already skipped in MULTI module to save memory+transmission time, format from Multi is: - * AA | TX_RSSI | sensor ... - * - * OpenTX Mapping - * - * instance = sensor id - * - * Additional sensors from https://github.com/cleanflight/cleanflight/blob/master/src/main/telemetry/ibus.c - * + * AA or AC | TX_RSSI | sensor ... */ -#define FLYSKY_TELEMETRY_LENGTH (2+7*4) +#define FLYSKY_TELEMETRY_LENGTH (2+7*4) // Should it be 2+7*6??? +#define ALT_PRECISION 15 +#define R_DIV_G_MUL_10_Q15 (uint64_t)9591506 +#define INV_LOG2_E_Q1DOT31 (uint64_t)0x58b90bfc // Inverse log base 2 of e +#define PRESSURE_MASK 0x7FFFF -struct FlySkySensor { +struct FlySkySensor +{ const uint16_t id; - const char *name; + const char * name; const TelemetryUnit unit; const uint8_t precision; }; -#define TX_RSSI_ID 300 // Pseudo id outside 1 byte range of FlySky sensors -#define FS_ID_TEMP 0x01 -#define FS_ID_SNR 0xfa -#define FS_ID_NOISE 0xfb -#define FS_ID_RSSI 0xfc +// telemetry sensors ID +enum +{ + AFHDS2A_ID_VOLTAGE = 0x00, // Internal Voltage + AFHDS2A_ID_TEMPERATURE = 0x01, // Temperature + AFHDS2A_ID_MOT = 0x02, // RPM + AFHDS2A_ID_EXTV = 0x03, // External Voltage + AFHDS2A_ID_CELL_VOLTAGE = 0x04, // Avg Cell voltage + AFHDS2A_ID_BAT_CURR = 0x05, // battery current A * 100 + AFHDS2A_ID_FUEL = 0x06, // remaining battery percentage / mah drawn otherwise or fuel level no unit! + AFHDS2A_ID_RPM = 0x07, // throttle value / battery capacity + AFHDS2A_ID_CMP_HEAD = 0x08, // Heading 0..360 deg, 0=north 2bytes + AFHDS2A_ID_CLIMB_RATE = 0x09, // 2 bytes m/s *100 signed + AFHDS2A_ID_COG = 0x0A, // 2 bytes Course over ground(NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. unknown max uint + AFHDS2A_ID_GPS_STATUS = 0x0B, // 2 bytes + AFHDS2A_ID_ACC_X = 0x0C, // 2 bytes m/s *100 signed + AFHDS2A_ID_ACC_Y = 0x0D, // 2 bytes m/s *100 signed + AFHDS2A_ID_ACC_Z = 0x0E, // 2 bytes m/s *100 signed + AFHDS2A_ID_ROLL = 0x0F, // 2 bytes deg *100 signed + AFHDS2A_ID_PITCH = 0x10, // 2 bytes deg *100 signed + AFHDS2A_ID_YAW = 0x11, // 2 bytes deg *100 signed + AFHDS2A_ID_VERTICAL_SPEED = 0x12, // 2 bytes m/s *100 signed + AFHDS2A_ID_GROUND_SPEED = 0x13, // 2 bytes m/s *100 different unit than build-in sensor + AFHDS2A_ID_GPS_DIST = 0x14, // 2 bytes distance from home m unsigned + AFHDS2A_ID_ARMED = 0x15, // 2 bytes + AFHDS2A_ID_FLIGHT_MODE = 0x16, // 2 bytes -const FlySkySensor flySkySensors[] = { + AFHDS2A_ID_PRES = 0x41, // Pressure + AFHDS2A_ID_ODO1 = 0x7C, // Odometer1 + AFHDS2A_ID_ODO2 = 0x7D, // Odometer2 + AFHDS2A_ID_SPE = 0x7E, // Speed 2 bytes km/h + AFHDS2A_ID_TX_V = 0x7F, // TX Voltage - // RX Voltage (remapped, really 0x0) - {0x100, ZSTR_A1, UNIT_VOLTS, 2}, - // Temperature - {FS_ID_TEMP, ZSTR_TEMP1, UNIT_CELSIUS, 1}, - // RPM - {0x02, ZSTR_RPM, UNIT_RAW, 0}, - // External voltage - {0x03, ZSTR_A3, UNIT_VOLTS, 2}, - // RX SNR - {FS_ID_SNR, ZSTR_RX_SNR, UNIT_DB, 0}, - // RX Noise - {FS_ID_NOISE, ZSTR_RX_NOISE, UNIT_DB, 0}, - // RX RSSI (0xfc) - {FS_ID_RSSI, ZSTR_RSSI, UNIT_DB, 0}, - // RX error rate - {0xfe, ZSTR_RX_QUALITY, UNIT_RAW, 0}, - // 0xff is an unused sensor slot - // Pseudo sensor for TRSSI - {TX_RSSI_ID, ZSTR_TX_RSSI, UNIT_RAW, 0}, - // sentinel - {0x00, NULL, UNIT_RAW, 0}, + AFHDS2A_ID_GPS_LAT = 0x80, // 4bytes signed WGS84 in degrees * 1E7 + AFHDS2A_ID_GPS_LON = 0x81, // 4bytes signed WGS84 in degrees * 1E7 + AFHDS2A_ID_GPS_ALT = 0x82, // 4bytes signed!!! GPS alt m*100 + AFHDS2A_ID_ALT = 0x83, // 4bytes signed!!! Alt m*100 + AFHDS2A_ID_S84 = 0x84, + AFHDS2A_ID_S85 = 0x85, + AFHDS2A_ID_S86 = 0x86, + AFHDS2A_ID_S87 = 0x87, + AFHDS2A_ID_S88 = 0x88, + AFHDS2A_ID_S89 = 0x89, + AFHDS2A_ID_S8a = 0x8A, + + AFHDS2A_ID_ALT_FLYSKY = 0xF9, // Altitude 2 bytes signed in m - used in FlySky native TX - SIGNED value + AFHDS2A_ID_RX_SNR = 0xFA, // SNR + AFHDS2A_ID_RX_NOISE = 0xFB, // Noise + AFHDS2A_ID_RX_RSSI = 0xFC, // RSSI + AFHDS2A_ID_RX_ERR_RATE = 0xFE, // Error rate + AFHDS2A_ID_END = 0xFF, + + // AC type telemetry with multiple values in one packet + AFHDS2A_ID_GPS_FULL = 0xFD, + AFHDS2A_ID_VOLT_FULL = 0xF0, + AFHDS2A_ID_ACC_FULL = 0xEF, + TX_RSSI_ID = 0x200, // Pseudo id outside 1 byte range of FlySky sensors }; -static void processFlySkySensor(const uint8_t *packet) +const FlySkySensor flySkySensors[] = { + {AFHDS2A_ID_VOLTAGE | 0x100, ZSTR_A1, UNIT_VOLTS, 2}, // RX Voltage (remapped, really 0x0) + {AFHDS2A_ID_TEMPERATURE, ZSTR_TEMP1, UNIT_CELSIUS, 1}, // Temperature + {AFHDS2A_ID_MOT, ZSTR_RPM, UNIT_RAW, 0}, // RPM + {AFHDS2A_ID_EXTV, ZSTR_A3, UNIT_VOLTS, 2}, // External voltage + {AFHDS2A_ID_CELL_VOLTAGE, ZSTR_CELLS, UNIT_VOLTS, 2}, // Avg Cell voltage + {AFHDS2A_ID_BAT_CURR, ZSTR_CURR, UNIT_AMPS, 2}, // battery current A * 100 + {AFHDS2A_ID_FUEL, ZSTR_CAPACITY, UNIT_RAW, 0}, // remaining battery percentage / mah drawn otherwise or fuel level no unit! + {AFHDS2A_ID_RPM, ZSTR_RPM, UNIT_RAW, 0}, // throttle value / battery capacity + {AFHDS2A_ID_CMP_HEAD, ZSTR_HDG, UNIT_DEGREE, 0}, // Heading 0..360 deg, 0=north 2bytes + {AFHDS2A_ID_CLIMB_RATE, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 2}, // 2 bytes m/s *100 + {AFHDS2A_ID_COG, ZSTR_HDG, UNIT_DEGREE, 2}, // 2 bytes Course over ground(NOT heading, but direction of movement) in degrees * 100, 0.0..359.99 degrees. unknown max uint + {AFHDS2A_ID_GPS_STATUS, ZSTR_SATELLITES, UNIT_RAW, 0}, // 2 bytes + {AFHDS2A_ID_ACC_X, ZSTR_ACCX, UNIT_METERS_PER_SECOND, 2}, // 2 bytes m/s *100 signed + {AFHDS2A_ID_ACC_Y, ZSTR_ACCY, UNIT_METERS_PER_SECOND, 2}, // 2 bytes m/s *100 signed + {AFHDS2A_ID_ACC_Z, ZSTR_ACCZ, UNIT_METERS_PER_SECOND, 2}, // 2 bytes m/s *100 signed + {AFHDS2A_ID_ROLL, ZSTR_ROLL, UNIT_DEGREE, 2}, // 2 bytes deg *100 signed + {AFHDS2A_ID_PITCH, ZSTR_PITCH, UNIT_DEGREE, 2}, // 2 bytes deg *100 signed + {AFHDS2A_ID_YAW, ZSTR_YAW, UNIT_DEGREE, 2}, // 2 bytes deg *100 signed + {AFHDS2A_ID_VERTICAL_SPEED, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 2}, // 2 bytes m/s *100 + {AFHDS2A_ID_GROUND_SPEED, ZSTR_GSPD, UNIT_METERS_PER_SECOND, 2}, // 2 bytes m/s *100 different unit than build-in sensor + {AFHDS2A_ID_GPS_DIST, ZSTR_DIST, UNIT_METERS, 0}, // 2 bytes dist from home m unsigned + {AFHDS2A_ID_ARMED, ZSTR_ARM, UNIT_RAW, 0}, // 2 bytes + {AFHDS2A_ID_FLIGHT_MODE, ZSTR_FLIGHT_MODE, UNIT_RAW, 0}, // 2 bytes index + {AFHDS2A_ID_PRES, ZSTR_PRES, UNIT_RAW, 2}, // 4 bytes In fact Temperature + Pressure -> Altitude + {AFHDS2A_ID_PRES | 0x100, ZSTR_TEMP2, UNIT_CELSIUS, 1}, // 2 bytes Temperature + {AFHDS2A_ID_ODO1, ZSTR_ODO1, UNIT_METERS, 2}, // 2 bytes Odometer1 -- some magic with 330 needed + {AFHDS2A_ID_ODO2, ZSTR_ODO2, UNIT_METERS, 2}, // 2 bytes Odometer2 -- some magic with 330 needed + {AFHDS2A_ID_SPE, ZSTR_ASPD, UNIT_KMH, 2}, // 2 bytes Speed km/h -- some magic with 330 needed + {AFHDS2A_ID_TX_V, ZSTR_TXV, UNIT_VOLTS, 2}, // TX Voltage + {AFHDS2A_ID_GPS_LAT, ZSTR_GPS, UNIT_RAW, 7}, // 4 bytes signed WGS84 in degrees * 1E7 + {AFHDS2A_ID_GPS_LON, ZSTR_GPS, UNIT_RAW, 7}, // 4 bytes signed WGS84 in degrees * 1E7 + {AFHDS2A_ID_GPS_ALT, ZSTR_GPSALT, UNIT_METERS, 2}, // 4 bytes signed GPS alt m*100 + {AFHDS2A_ID_ALT, ZSTR_ALT, UNIT_METERS, 2}, // 4 bytes signed Alt m*100 + + {AFHDS2A_ID_RX_SNR, ZSTR_RX_SNR, UNIT_DB, 0}, // RX SNR + {AFHDS2A_ID_RX_NOISE, ZSTR_RX_NOISE, UNIT_DB, 0}, // RX Noise + {AFHDS2A_ID_RX_RSSI, ZSTR_RSSI, UNIT_DB, 0}, // RX RSSI (0xfc) + {AFHDS2A_ID_RX_ERR_RATE, ZSTR_RX_QUALITY, UNIT_RAW, 0}, // RX error rate + {TX_RSSI_ID, ZSTR_TX_RSSI, UNIT_RAW, 0}, // Pseudo sensor for TRSSI + + {0x00, NULL, UNIT_RAW, 0}, // sentinel +}; + +int32_t getALT(uint32_t value); + +static void processFlySkySensor(const uint8_t * packet, uint8_t type) { + uint8_t buffer[8]; uint16_t id = packet[0]; const uint8_t instance = packet[1]; - int32_t value = (packet[3] << 8) + packet[2]; + int32_t value; - if (id == 0xff) { - // No sensor + //Load most likely value + if (type == 0xAA) + value = (packet[3] << 8) | packet[2]; + else + value = (packet[6] << 24) | (packet[5] << 16) | (packet[4] << 8) | packet[3]; + + if (id == 0) id = 0x100; // Some part of OpenTX does not like sensor with id and instance 0, remap to 0x100 + + if (id == AFHDS2A_ID_RX_NOISE || id == AFHDS2A_ID_RX_RSSI) { + value = -value; + } + else if (id == AFHDS2A_ID_RX_ERR_RATE) { + value = 100 - value; + telemetryData.rssi.set(value); + if (value > 0) telemetryStreaming = TELEMETRY_TIMEOUT10ms; + } + else if (id == AFHDS2A_ID_PRES && value) { + // Extract temperature to a new sensor + setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, id | 0x100, 0, instance, ((value >> 19) - 400), UNIT_CELSIUS, 1); + // Extract alt to a new sensor + setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, AFHDS2A_ID_ALT, 0, instance, getALT(value), UNIT_METERS, 2); + value &= PRESSURE_MASK; + } + else if ((id >= AFHDS2A_ID_ACC_X && id <= AFHDS2A_ID_VERTICAL_SPEED) || id == AFHDS2A_ID_CLIMB_RATE || id == AFHDS2A_ID_ALT_FLYSKY) { + value = (int16_t) value; // Signed value + } + else if (id == AFHDS2A_ID_GPS_STATUS) { + value = value >> 8; + } + else if (id == AFHDS2A_ID_GPS_FULL) { + //(AC FRAME)[ID][inst][size][fix][sats][LAT]x4[LON]x4[ALT]x4 + setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, AFHDS2A_ID_GPS_STATUS, 0, instance, packet[4], UNIT_RAW, 0); + for (uint8_t sensorID = AFHDS2A_ID_GPS_LAT; sensorID <= AFHDS2A_ID_GPS_ALT; sensorID++) { + int index = 5 + (sensorID - AFHDS2A_ID_GPS_LAT) * 4; + buffer[0] = sensorID; + buffer[1] = instance; + buffer[2] = 4; + memcpy(buffer + 3, packet + index, 4); + processFlySkySensor(buffer, 0xAC); + } return; } - - if (id == 0) { - // Some part of OpenTX does not like sensor with id and instance 0, remap to 0x100 - id = 0x100; - } - - if (id == FS_ID_SNR) { - telemetryData.rssi.set(value); - } - - for (const FlySkySensor * sensor = flySkySensors; sensor->id; sensor++) { - // Extract value, skip header - if (sensor->id == id) { - // The Noise and Signal sensors that are specified in dB send the absolute value - if (id == FS_ID_NOISE || id == FS_ID_RSSI) - value = -value; - else if (id == FS_ID_TEMP) - // Temperature sensors have 40 degree offset - value -= 400; - else if (sensor->unit == UNIT_VOLTS) - // Voltage types are signed 16bit integers - value = (int16_t)value; - setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, id, 0, instance, value, sensor->unit, sensor->precision); - return; + else if (id == AFHDS2A_ID_VOLT_FULL) { + //(AC FRAME)[ID][inst][size][ACC_X]x2[ACC_Y]x2[ACC_Z]x2[ROLL]x2[PITCH]x2[YAW]x2 + for (uint8_t sensorID = AFHDS2A_ID_EXTV; sensorID <= AFHDS2A_ID_RPM; sensorID++) { + int index = 3 + (sensorID - AFHDS2A_ID_EXTV) * 2; + buffer[0] = sensorID; + buffer[1] = instance; + buffer[2] = packet[index]; + buffer[3] = packet[index + 1]; + processFlySkySensor(buffer, 0xAA); } + return; } + else if (id == AFHDS2A_ID_ACC_FULL) { + //(AC FRAME)[ID][inst][size] + for (uint8_t sensorID = AFHDS2A_ID_ACC_X; sensorID <= AFHDS2A_ID_YAW; sensorID++) { + int index = 3 + (sensorID - AFHDS2A_ID_ACC_X) * 2; + buffer[0] = sensorID; + buffer[1] = instance; + buffer[2] = packet[index]; + buffer[3] = packet[index + 1]; + processFlySkySensor(buffer, 0xAA); + } + return; + } + for (const FlySkySensor * sensor = flySkySensors; sensor->id; sensor++) { + if (sensor->id != id) continue; + if (sensor->unit == UNIT_CELSIUS) value -= 400; // Temperature sensors have 40 degree offset + else if (sensor->unit == UNIT_VOLTS) value = (uint16_t) value; // Voltage types are unsigned 16bit integers + setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, id, 0, instance, value, sensor->unit, sensor->precision); + return; + } + //unknown setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, id, 0, instance, value, UNIT_RAW, 0); } -void processFlySkyPacket(const uint8_t *packet) +void processFlySkyPacket(const uint8_t * packet) { // Set TX RSSI Value, reverse MULTIs scaling setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, TX_RSSI_ID, 0, 0, packet[0], UNIT_RAW, 0); - for (int sensor = 0; sensor < 7; sensor++) { - int index = 1 + (4 * sensor); - processFlySkySensor(packet+index); + const uint8_t * buffer = packet + 1; + int sesnor = 0; + while (sesnor++ < 7) { + if (*buffer == AFHDS2A_ID_END) break; + processFlySkySensor(buffer, 0xAA); + buffer += 4; } - telemetryStreaming = TELEMETRY_TIMEOUT10ms; } -void processFlySkyTelemetryData(uint8_t data) +void processFlySkyPacketAC(const uint8_t * packet) { - if (telemetryRxBufferCount == 0 && data != 0xAA) { + // Set TX RSSI Value, reverse MULTIs scaling + setTelemetryValue(PROTOCOL_TELEMETRY_FLYSKY_IBUS, TX_RSSI_ID, 0, 0, packet[0], UNIT_RAW, 0); + const uint8_t * buffer = packet + 1; + while (buffer - packet < 26) //28 + 1(multi TX rssi) - 3(ac header) + { + if (*buffer == AFHDS2A_ID_END) break; + uint8_t size = buffer[2]; + processFlySkySensor(buffer, 0xAC); + buffer += size + 3; + } +} + +void processFlySkyTelemetryData(uint8_t data, uint8_t * rxBuffer, uint8_t &rxBufferCount) +{ + if (rxBufferCount == 0) + return; + + if (data == 0xAA || data == 0xAC) { + TRACE("[IBUS] Packet 0x%02X", data); + } + else { TRACE("[IBUS] invalid start byte 0x%02X", data); + rxBufferCount = 0; return; } - if (telemetryRxBufferCount < TELEMETRY_RX_PACKET_SIZE) { - telemetryRxBuffer[telemetryRxBufferCount++] = data; + if (rxBufferCount < TELEMETRY_RX_PACKET_SIZE) { + rxBuffer[rxBufferCount++] = data; } else { - TRACE("[IBUS] array size %d error", telemetryRxBufferCount); - telemetryRxBufferCount = 0; + TRACE("[IBUS] array size %d error", rxBufferCount); + rxBufferCount = 0; } - - if (telemetryRxBufferCount >= FLYSKY_TELEMETRY_LENGTH) { + if (rxBufferCount >= FLYSKY_TELEMETRY_LENGTH) { // debug print the content of the packets #if 0 - debugPrintf("[IBUS] Packet 0x%02X rssi 0x%02X: ", - telemetryRxBuffer[0], telemetryRxBuffer[1]); + debugPrintf(", rssi 0x%02X: ", rxBuffer[1]); for (int i=0; i<7; i++) { - debugPrintf("[%02X %02X %02X%02X] ", telemetryRxBuffer[i*4+2], telemetryRxBuffer[i*4 + 3], - telemetryRxBuffer[i*4 + 4], telemetryRxBuffer[i*4 + 5]); + debugPrintf("[%02X %02X %02X%02X] ", rxBuffer[i*4+2], rxBuffer[i*4 + 3], + rxBuffer[i*4 + 4], rxBuffer[i*4 + 5]); } debugPrintf("\r\n"); #endif - processFlySkyPacket(telemetryRxBuffer+1); - telemetryRxBufferCount = 0; + if (data == 0xAA) processFlySkyPacket(rxBuffer + 1); + else if (data == 0xAC) processFlySkyPacketAC(rxBuffer + 1); + rxBufferCount = 0; } } -const FlySkySensor *getFlySkySensor(uint16_t id) +const FlySkySensor * getFlySkySensor(uint16_t id) { for (const FlySkySensor * sensor = flySkySensors; sensor->id; sensor++) { if (id == sensor->id) @@ -173,7 +306,7 @@ void flySkySetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance) telemetrySensor.subId = subId; telemetrySensor.instance = instance; - const FlySkySensor *sensor = getFlySkySensor(id); + const FlySkySensor * sensor = getFlySkySensor(id); if (sensor) { TelemetryUnit unit = sensor->unit; uint8_t prec = min(2, sensor->precision); @@ -190,3 +323,71 @@ void flySkySetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance) storageDirty(EE_MODEL); } + +uint16_t ibusTempToK(int16_t tempertureIbus) +{ + return (uint16_t) (tempertureIbus - 400) + 2731; +} + +int32_t log2fix(uint32_t x) +{ + int32_t b = 1U << (ALT_PRECISION - 1); + int32_t y = 0; + while (x < 1U << ALT_PRECISION) { + x <<= 1; + y -= 1U << ALT_PRECISION; + } + + while (x >= 2U << ALT_PRECISION) { + x >>= 1; + y += 1U << ALT_PRECISION; + } + + uint64_t z = x; + for (size_t i = 0; i < ALT_PRECISION; i++) { + z = (z * z) >> ALT_PRECISION; + if (z >= 2U << ALT_PRECISION) { + z >>= 1; + y += b; + } + b >>= 1; + } + return y; +} + +int32_t getALT(uint32_t value) +{ + uint32_t pressurePa = value & PRESSURE_MASK; + if (pressurePa == 0) return 0; + uint16_t temperatureK = ibusTempToK((uint16_t) (value >> 19)); + static uint32_t initPressure = 0; + static uint16_t initTemperature = 0; + if (initPressure <= 0) // use current pressure for ground altitude -> 0 + { + initPressure = pressurePa; + initTemperature = temperatureK; + } + int temperature = (initTemperature + temperatureK) >> 1; //div 2 + bool tempNegative = temperature < 0; + if (tempNegative) temperature = temperature * -1; + uint64_t helper = R_DIV_G_MUL_10_Q15; + helper = helper * (uint64_t) temperature; + helper = helper >> ALT_PRECISION; + + uint32_t po_to_p = (uint32_t)(initPressure << (ALT_PRECISION - 1)); + po_to_p = po_to_p / pressurePa; + //shift missing bit + po_to_p = po_to_p << 1; + if (po_to_p == 0) return 0; + uint64_t t = log2fix(po_to_p) * INV_LOG2_E_Q1DOT31; + int32_t ln = t >> 31; + + bool neg = ln < 0; + if (neg) ln = ln * -1; + helper = helper * (uint64_t) ln; + helper = helper >> ALT_PRECISION; + int result = (int) helper; + + if (neg ^ tempNegative) result = result * -1; + return result; +} \ No newline at end of file diff --git a/radio/src/telemetry/flysky_ibus.h b/radio/src/telemetry/flysky_ibus.h index 71726d64c..bfb0db640 100644 --- a/radio/src/telemetry/flysky_ibus.h +++ b/radio/src/telemetry/flysky_ibus.h @@ -21,11 +21,14 @@ #ifndef _FLYSKY_IBUS_H #define _FLYSKY_IBUS_H -void processFlySkyTelemetryData(uint8_t data); +void processFlySkyTelemetryData(uint8_t data, uint8_t * rxBuffer, uint8_t &rxBufferCount); + void flySkySetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance); // Used by multi protocol -void processFlySkyPacket(const uint8_t *packet); +void processFlySkyPacket(const uint8_t * packet); + +void processFlySkyPacketAC(const uint8_t * packet); #endif diff --git a/radio/src/telemetry/frsky_pxx2.cpp b/radio/src/telemetry/frsky_pxx2.cpp index 200728aad..776de975e 100644 --- a/radio/src/telemetry/frsky_pxx2.cpp +++ b/radio/src/telemetry/frsky_pxx2.cpp @@ -39,6 +39,8 @@ class Pxx2Telemetry static void processPowerMeterFrame(uint8_t module, uint8_t * frame); + static void processAuthenticationFrame(uint8_t module, uint8_t * frame); + public: }; @@ -221,6 +223,29 @@ void processTelemetryFrame(uint8_t module, uint8_t * frame) } } +#if defined(ACCESS_LIB) +void processAuthenticationFrame(uint8_t module, uint8_t * frame) +{ + uint8_t cryptoType = frame[3]; + uint8_t messageDigest[16] = {0}; + + if (frame[0] == 4 && PXX2_AUTH_REFUSED_FLAG == frame[4]) { + POPUP_INFORMATION(STR_AUTH_FAILURE); + return; + } + + if (INTERNAL_MODULE == module && accessCRL(cryptoType, frame+4, messageDigest)) { + moduleState[module].mode = MODULE_MODE_AUTHENTICATION; + Pxx2Pulses & pxx2 = intmodulePulsesData.pxx2; + pxx2.setupAuthenticationFrame(module, cryptoType, (const uint8_t *)messageDigest); + intmoduleSendBuffer(pxx2.getData(), pxx2.getSize()); + // we remain in AUTHENTICATION mode to avoid a CHANNELS frame is sent at the end of the mixing process + } +} +#else +#define processAuthenticationFrame(module, frame) +#endif + void processSpectrumAnalyserFrame(uint8_t module, uint8_t * frame) { if (moduleState[module].mode != MODULE_MODE_SPECTRUM_ANALYSER) { @@ -313,6 +338,10 @@ void processModuleFrame(uint8_t module, uint8_t *frame) processTelemetryFrame(module, frame); break; + case PXX2_TYPE_ID_AUTHENTICATION: + processAuthenticationFrame(module, frame); + break; + case PXX2_TYPE_ID_RESET: processResetFrame(module, frame); break; diff --git a/radio/src/telemetry/hitec.cpp b/radio/src/telemetry/hitec.cpp new file mode 100644 index 000000000..93a0f6a37 --- /dev/null +++ b/radio/src/telemetry/hitec.cpp @@ -0,0 +1,433 @@ +/* + * Copyright (C) OpenTX + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include "opentx.h" + +/* Full telemetry +packet[0] = TX RSSI value +packet[1] = TX LQI value +packet[2] = frame number +packet[3-7] telemetry data + +The frame number takes the following values: 0x00, 0x11, 0x12, ..., 0x1C. The frames can be present or not, they also do not have to follow each others. +Here is a description of the telemetry data for each frame number: +- frame 0x00 +data byte 0 -> 0x00 unknown +data byte 1 -> 0x00 unknown +data byte 2 -> 0x00 unknown +data byte 3 -> RX Batt Volt_H +data byte 4 -> RX Batt Volt_L => RX Batt=(Volt_H*256+Volt_L)/28 +- frame 0x11 +data byte 0 -> 0xAF start of frame +data byte 1 -> 0x00 unknown +data byte 2 -> 0x2D station type 0x2D=standard station nitro or electric, 0xAC=advanced station +data byte 3 -> RX Batt Volt_H +data byte 4 -> RX Batt Volt_L => RX Batt=(Volt_H*256+Volt_L)/28 +- frame 0x12 +data byte 0 -> Lat_sec_H GPS : latitude second +data byte 1 -> Lat_sec_L signed int : 1/100 of second +data byte 2 -> Lat_deg_min_H GPS : latitude degree.minute +data byte 3 -> Lat_deg_min_L signed int : +=North, - = south +data byte 4 -> Time_second GPS Time +- frame 0x13 +data byte 0 -> GPS Longitude second +data byte 1 -> signed int : 1/100 of second +data byte 2 -> GPS Longitude degree.minute +data byte 3 -> signed int : +=Est, - = west +data byte 4 -> Temp2 Temperature2=Temp2-40°C +- frame 0x14 +data byte 0 -> Speed_H +data byte 1 -> Speed_L GPS Speed=Speed_H*256+Speed_L km/h +data byte 2 -> Alti_sea_H +data byte 3 -> Alti_sea_L GPS Altitude=Alti_sea_H*256+Alti_sea_L m +data byte 4 -> Temp1 Temperature1=Temp1-40°C +- frame 0x15 +data byte 0 -> FUEL +data byte 1 -> RPM1_L +data byte 2 -> RPM1_H RPM1=RPM1_H*256+RPM1_L +data byte 3 -> RPM2_L +data byte 4 -> RPM2_H RPM2=RPM2_H*256+RPM2_L +- frame 0x16 +data byte 0 -> Date_year GPS Date +data byte 1 -> Date_month +data byte 2 -> Date_day +data byte 3 -> Time_hour GPS Time +data byte 4 -> Time_min +- frame 0x17 +data byte 0 -> COURSEH +data byte 1 -> COURSEL GPS heading = COURSEH*256+COURSEL in degrees +data byte 2 -> Count GPS satellites +data byte 3 -> Temp3 Temperature3=Temp2-40°C +data byte 4 -> Temp4 Temperature4=Temp3-40°C +- frame 0x18 +data byte 0 -> Volt_L Volt=(Volt_H*256+Volt_L)/10 V +data byte 1 -> Volt_H +data byte 2 -> AMP_L +data byte 3 -> AMP_H Amp=(AMP1_*256+AMP_L -180)/14 in signed A +- frame 0x19 Servo sensor +data byte 0 -> AMP_Servo1 Amp=AMP_Servo1/10 in A +data byte 1 -> AMP_Servo2 Amp=AMP_Servo2/10 in A +data byte 2 -> AMP_Servo3 Amp=AMP_Servo3/10 in A +data byte 3 -> AMP_Servo4 Amp=AMP_Servo4/10 in A +- frame 0x1A +data byte 2 -> ASpeed_H Air speed=ASpeed_H*256+ASpeed_L km/h +data byte 3 -> ASpeed_L +- frame 0x1B Variometer sensor +data byte 0 -> Alti1H +data byte 1 -> Alti1L Altitude unfiltered +data byte 2 -> Alti2H +data byte 3 -> Alti2L Altitude filtered +- frame 0x1C Unknown +- frame 0x22 Unknown +*/ + +#define HITEC_TELEMETRY_LENGTH 8 + +struct HitecSensor +{ + const uint16_t id; + const char * name; + const TelemetryUnit unit; + const uint8_t precision; +}; + +// telemetry frames +enum +{ + HITEC_FRAME_00 = 0x00, + HITEC_FRAME_11 = 0x11, + HITEC_FRAME_12 = 0x12, + HITEC_FRAME_13 = 0x13, + HITEC_FRAME_14 = 0x14, + HITEC_FRAME_15 = 0x15, + HITEC_FRAME_16 = 0x16, + HITEC_FRAME_17 = 0x17, + HITEC_FRAME_18 = 0x18, + HITEC_FRAME_19 = 0x19, + HITEC_FRAME_1A = 0x1A, + HITEC_FRAME_1B = 0x1B, + HITEC_FRAME_1C = 0x1C, + HITEC_FRAME_22 = 0x22, +}; + +// telemetry sensors ID +enum +{ + HITEC_ID_RX_VOLTAGE = 0x0003, // RX_Batt Voltage + HITEC_ID_GPS_LAT_LONG = 0x1200, // GPS latitude longitude + HITEC_ID_TEMP2 = 0x1304, // Temperature sensor 2 + HITEC_ID_GPS_SPEED = 0x1400, // GPS speed + HITEC_ID_GPS_ALTITUDE = 0x1402, // GPS altitude sea level + HITEC_ID_TEMP1 = 0x1404, // Temperature sensor 1 + HITEC_ID_FUEL = 0x1500, // Fuel + HITEC_ID_RPM1 = 0x1501, // RPM1 + HITEC_ID_RPM2 = 0x1503, // RPM2 + HITEC_ID_GPS_DATETIME = 0x1600, // GPS date time + HITEC_ID_GPS_HEADING = 0x1700, // GPS heading + HITEC_ID_GPS_COUNT = 0x1702, // GPS count + HITEC_ID_TEMP3 = 0x1703, // Temperature sensor 3 + HITEC_ID_TEMP4 = 0x1704, // Temperature sensor 4 + HITEC_ID_VOLTAGE = 0x1800, // Voltage sensor + HITEC_ID_AMP = 0x1802, // Amp sensor + HITEC_ID_C50 = 0x1803, // Amp sensor C50 + HITEC_ID_C200 = 0x1804, // Amp sensor C200 + HITEC_ID_AMP_S1 = 0x1900, // Amp servo 1 sensor + HITEC_ID_AMP_S2 = 0x1901, // Amp servo 2 sensor + HITEC_ID_AMP_S3 = 0x1902, // Amp servo 3 sensor + HITEC_ID_AMP_S4 = 0x1903, // Amp servo 4 sensor + HITEC_ID_AIR_SPEED = 0x1A02, // Air speed + HITEC_ID_VARIO = 0x1B00, // Vario + HITEC_ID_ALT = 0x1B02, // Vario + TX_RSSI_ID = 0xFF00, // Pseudo id outside 1 byte range of Hitec sensors + TX_LQI_ID = 0xFF01, // Pseudo id outside 1 byte range of Hitec sensors +}; + +const HitecSensor hitecSensors[] = { + //frame 00 + {HITEC_ID_RX_VOLTAGE, ZSTR_BATT, UNIT_VOLTS, 2}, // RX_Batt Voltage + //frame 11 + //frame 12 + {HITEC_ID_GPS_LAT_LONG, ZSTR_GPS, UNIT_GPS, 0}, // GPS position + //frame 13 + {HITEC_ID_TEMP2, ZSTR_TEMP2, UNIT_CELSIUS, 0}, // Temperature sensor 2 + //frame 14 + {HITEC_ID_GPS_SPEED, ZSTR_GSPD, UNIT_KMH, 0}, // GPS speed + {HITEC_ID_GPS_ALTITUDE, ZSTR_GPSALT, UNIT_METERS, 0}, // GPS altitude sea level + {HITEC_ID_TEMP1, ZSTR_TEMP1, UNIT_CELSIUS, 0}, // Temperature sensor 1 + //frame 15 + {HITEC_ID_FUEL, ZSTR_FUEL, UNIT_PERCENT, 0}, // Fuel + {HITEC_ID_RPM1, ZSTR_RPM, UNIT_RPMS, 0}, // RPM1 + {HITEC_ID_RPM2, ZSTR_RPM2, UNIT_RPMS, 0}, // RPM2 + //frame 16 + {HITEC_ID_GPS_DATETIME, ZSTR_GPS, UNIT_DATETIME, 0}, // GPS date time + //frame 17 + {HITEC_ID_GPS_HEADING, ZSTR_HDG, UNIT_DEGREE, 0}, // GPS Heading + {HITEC_ID_GPS_COUNT, ZSTR_SATELLITES, UNIT_RAW, 0}, // GPS count + {HITEC_ID_TEMP3, ZSTR_TEMP3, UNIT_CELSIUS, 0}, // Temperature sensor 3 + {HITEC_ID_TEMP4, ZSTR_TEMP4, UNIT_CELSIUS, 0}, // Temperature sensor 4 + //frame 18 + {HITEC_ID_VOLTAGE, ZSTR_A1, UNIT_VOLTS, 1}, // Voltage sensor + {HITEC_ID_AMP, ZSTR_CURR, UNIT_AMPS, 0}, // Amp sensor + {HITEC_ID_C50, ZSTR_C50, UNIT_AMPS, 1}, // Amp sensor C50 + {HITEC_ID_C200, ZSTR_C200, UNIT_AMPS, 0}, // Amp sensor C200 + //frame 19 + {HITEC_ID_AMP_S1, ZSTR_CURR_SERVO1, UNIT_AMPS, 1}, // Amp sensor + {HITEC_ID_AMP_S2, ZSTR_CURR_SERVO2, UNIT_AMPS, 1}, // Amp sensor + {HITEC_ID_AMP_S3, ZSTR_CURR_SERVO3, UNIT_AMPS, 1}, // Amp sensor + {HITEC_ID_AMP_S4, ZSTR_CURR_SERVO4, UNIT_AMPS, 1}, // Amp sensor + //frame 1A + {HITEC_ID_AIR_SPEED, ZSTR_ASPD, UNIT_KMH, 0}, // Air speed + //frame 1B + {HITEC_ID_VARIO, ZSTR_VSPD, UNIT_METERS_PER_SECOND, 1}, // Vario + {HITEC_ID_ALT, ZSTR_ALT, UNIT_METERS, 1}, // Altitude + + {TX_RSSI_ID, ZSTR_TX_RSSI, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hitec sensors + {TX_LQI_ID, ZSTR_TX_QUALITY, UNIT_RAW, 0}, // Pseudo id outside 1 byte range of Hitec sensors// Pseudo sensor for TLQI + {0x00, NULL, UNIT_RAW, 0}, // sentinel +}; + +const HitecSensor * getHitecSensor(uint16_t id) +{ + for (const HitecSensor * sensor = hitecSensors; sensor->id; sensor++) { + if (id == sensor->id) + return sensor; + } + return nullptr; +} + +void processHitecPacket(const uint8_t * packet) +{ + static uint16_t rssi = 0, lqi = 0; + // Set TX RSSI Value, reverse MULTIs scaling + rssi = ((packet[0] * 10) + (rssi * 90)) / 100; // quick filtering + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, TX_RSSI_ID, 0, 0, rssi >> 1, UNIT_RAW, 0); + telemetryData.rssi.set(rssi >> 1); + if (packet[0] > 0) telemetryStreaming = TELEMETRY_TIMEOUT10ms; + // Set TX LQI Value, reverse MULTIs scaling + lqi = ((packet[1] * 10) + (lqi * 90)) / 100; // quick filtering + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, TX_LQI_ID, 0, 0, lqi, UNIT_RAW, 0); + + const HitecSensor * sensor; + int32_t value, deg, min, sec, alt, amp; + static uint8_t second = 0; + static int32_t last_alt = 0; + static uint16_t last_ms = 0; + uint16_t current_ms; + + switch (packet[2]) { + case HITEC_FRAME_00: + value = (((packet[6] << 8) | packet[7]) * 100) / 28; + sensor = getHitecSensor(HITEC_ID_RX_VOLTAGE); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_RX_VOLTAGE, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_11: + value = (((packet[6] << 8) | packet[7]) * 100) / 28; + sensor = getHitecSensor(HITEC_ID_RX_VOLTAGE); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_RX_VOLTAGE, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_12: + //value=(packet[5]<<24)|(packet[6]<<16)|(packet[3]<<8)|packet[4]; + min = (int16_t) ((packet[5] << 8) | packet[6]); + deg = min / 100; + min = min - deg * 100; + sec = (int16_t) ((packet[3] << 8) | packet[4]); + value = deg * 1000000 + (min * 150000 + sec * 25) / 9; + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_GPS_LAT_LONG, 0, 0, value, UNIT_GPS_LATITUDE, 0); + second = packet[7]; + return; + case HITEC_FRAME_13: + //value=(packet[5]<<24)|(packet[6]<<16)|(packet[3]<<8)|packet[4]; + min = (int16_t) ((packet[5] << 8) | packet[6]); + deg = min / 100; + min = min - deg * 100; + sec = (int16_t) ((packet[3] << 8) | packet[4]); + value = deg * 1000000 + (min * 150000 + sec * 25) / 9; + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_GPS_LAT_LONG, 0, 0, value, UNIT_GPS_LONGITUDE, 0); + value = packet[7] - 40; + sensor = getHitecSensor(HITEC_ID_TEMP2); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_TEMP2, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_14: + value = (packet[3] << 8) | packet[4]; + sensor = getHitecSensor(HITEC_ID_GPS_SPEED); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_GPS_SPEED, 0, 0, value, sensor->unit, sensor->precision); + value = (packet[5] << 8) | packet[6]; + sensor = getHitecSensor(HITEC_ID_GPS_ALTITUDE); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_GPS_ALTITUDE, 0, 0, value, sensor->unit, sensor->precision); + value = packet[7] - 40; + sensor = getHitecSensor(HITEC_ID_TEMP1); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_TEMP1, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_15: + value = packet[3] * 25; + if (value > 100) value = 100; + sensor = getHitecSensor(HITEC_ID_FUEL); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_FUEL, 0, 0, value, sensor->unit, sensor->precision); + value = (packet[5] << 8) | packet[4]; + sensor = getHitecSensor(HITEC_ID_RPM1); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_RPM1, 0, 0, value, sensor->unit, sensor->precision); + value = (packet[7] << 8) | packet[6]; + sensor = getHitecSensor(HITEC_ID_RPM2); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_RPM2, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_16: + sensor = getHitecSensor(HITEC_ID_GPS_DATETIME); + value = (packet[3] << 24) | (packet[4] << 16) | (packet[5] << 8) | 0x01; + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_GPS_DATETIME, 0, 0, value, sensor->unit, sensor->precision); + value = (packet[6] << 24) | (packet[7] << 16) | (second << 8); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_GPS_DATETIME, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_17: + value = (packet[3] << 8) | packet[4]; + if (value <= 359) { // Filter strange values received time to time + sensor = getHitecSensor(HITEC_ID_GPS_HEADING); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_GPS_HEADING, 0, 0, value, sensor->unit, sensor->precision); + } + value = packet[5]; + sensor = getHitecSensor(HITEC_ID_GPS_COUNT); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_GPS_COUNT, 0, 0, value, sensor->unit, sensor->precision); + value = packet[6] - 40; + sensor = getHitecSensor(HITEC_ID_TEMP3); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_TEMP3, 0, 0, value, sensor->unit, sensor->precision); + value = packet[7] - 40; + sensor = getHitecSensor(HITEC_ID_TEMP4); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_TEMP4, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_18: + value = (packet[4] << 8) | packet[3]; + if (value) value += 2; // Measured voltage seems to be 0.2V lower than real + sensor = getHitecSensor(HITEC_ID_VOLTAGE); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_VOLTAGE, 0, 0, value, sensor->unit, sensor->precision); + //I'm adding below 3 amp sensors but there is only one really since I don't know how to really calculate them + value = (int16_t) ((packet[6] << 8) | packet[5]); + sensor = getHitecSensor(HITEC_ID_AMP); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_AMP, 0, 0, value, sensor->unit, sensor->precision); + amp = ((value + 114.875) * 1.441) + 0.5; + sensor = getHitecSensor(HITEC_ID_C50); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_C50, 0, 0, amp, sensor->unit, sensor->precision); + amp = value * 3 + 165; + sensor = getHitecSensor(HITEC_ID_C200); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_C200, 0, 0, amp, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_19: + value = packet[3]; + sensor = getHitecSensor(HITEC_ID_AMP_S1); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_AMP_S1, 0, 0, value, sensor->unit, sensor->precision); + value = packet[4]; + sensor = getHitecSensor(HITEC_ID_AMP_S2); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_AMP_S2, 0, 0, value, sensor->unit, sensor->precision); + value = packet[5]; + sensor = getHitecSensor(HITEC_ID_AMP_S3); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_AMP_S3, 0, 0, value, sensor->unit, sensor->precision); + value = packet[6]; + sensor = getHitecSensor(HITEC_ID_AMP_S4); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_AMP_S4, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_1A: + value = (packet[5] << 8) | packet[6]; + sensor = getHitecSensor(HITEC_ID_AIR_SPEED); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_AIR_SPEED, 0, 0, value, sensor->unit, sensor->precision); + return; + case HITEC_FRAME_1B: + alt = (int16_t) ((packet[3] << 8) | packet[4]); + sensor = getHitecSensor(HITEC_ID_ALT); + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_ALT, 0, 0, alt, sensor->unit, sensor->precision); + current_ms = RTOS_GET_MS(); + sensor = getHitecSensor(HITEC_ID_VARIO); + value = (alt - last_alt) * 100; + if ((current_ms - last_ms) < 1000) + value /= (int32_t) (current_ms - last_ms); + else + value = 0; + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, HITEC_ID_VARIO, 0, 0, value, sensor->unit, sensor->precision); + last_alt = alt; + last_ms = current_ms; + return; + case HITEC_FRAME_1C: + case HITEC_FRAME_22: + return; + } + //unknown + value = (packet[6] << 24) | (packet[5] << 16) | (packet[4] << 8) | packet[3]; + setTelemetryValue(PROTOCOL_TELEMETRY_HITEC, packet[2], 0, 0, value, UNIT_RAW, 0); +} + +void processHitecTelemetryData(uint8_t data, uint8_t * rxBuffer, uint8_t &rxBufferCount) +{ + if (rxBufferCount == 0) + return; + + if (data != 0xAA) { + TRACE("[HITEC] invalid start byte 0x%02X", data); + rxBufferCount = 0; + return; + } + + if (rxBuffer[3] == HITEC_FRAME_00 || (rxBuffer[3] >= HITEC_FRAME_11 && rxBuffer[3] <= HITEC_FRAME_1C) || rxBuffer[3] == HITEC_FRAME_22) { + TRACE("[HITEC] Frame 0x%02X", rxBuffer[3]); + } + else { + TRACE("[HITEC] wrong frame 0x%02X", rxBuffer[3]); + rxBufferCount = 0; + return; + } + + if (rxBufferCount < TELEMETRY_RX_PACKET_SIZE) { + rxBuffer[rxBufferCount++] = data; + } + else { + TRACE("[HITEC] array size %d error", rxBufferCount); + rxBufferCount = 0; + return; + } + + if (rxBufferCount >= HITEC_TELEMETRY_LENGTH) { + // debug print the content of the packets +#if 0 + debugPrintf(" rssi 0x%02X lqi 0x%02X: ", + rxBuffer[1], rxBuffer[2]); + for (int i=0; i<5; i++) { + debugPrintf("%02X ", rxBuffer[4+i]); + } + debugPrintf("\r\n"); +#endif + processHitecPacket(rxBuffer + 1); + rxBufferCount = 0; + } +} + +void hitecSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance) +{ + TelemetrySensor &telemetrySensor = g_model.telemetrySensors[index]; + telemetrySensor.id = id; + telemetrySensor.subId = subId; + telemetrySensor.instance = instance; + + const HitecSensor * sensor = getHitecSensor(id); + if (sensor) { + TelemetryUnit unit = sensor->unit; + uint8_t prec = min(2, sensor->precision); + telemetrySensor.init(sensor->name, unit, prec); + if (unit == UNIT_RPMS) { + telemetrySensor.custom.ratio = 1; + telemetrySensor.custom.offset = 1; + } + } + else { + telemetrySensor.init(id); + } + + storageDirty(EE_MODEL); +} diff --git a/radio/src/telemetry/hitec.h b/radio/src/telemetry/hitec.h new file mode 100644 index 000000000..d4c851f4c --- /dev/null +++ b/radio/src/telemetry/hitec.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) OpenTX + * + * Based on code named + * th9x - http://code.google.com/p/th9x + * er9x - http://code.google.com/p/er9x + * gruvin9x - http://code.google.com/p/gruvin9x + * + * License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef _HITEC_H +#define _HITEC_H + +void processHitecTelemetryData(uint8_t data, uint8_t* rxBuffer, uint8_t& rxBufferCount); +void hitecSetDefault(int index, uint16_t id, uint8_t subId, uint8_t instance); + +// Used by multi protocol +void processHitecPacket(const uint8_t *packet); + +#endif diff --git a/radio/src/telemetry/multi.cpp b/radio/src/telemetry/multi.cpp index 3717a6a24..5ae925fc4 100644 --- a/radio/src/telemetry/multi.cpp +++ b/radio/src/telemetry/multi.cpp @@ -21,24 +21,29 @@ #include "telemetry.h" #include "multi.h" -MultiModuleStatus multiModuleStatus; -MultiModuleSyncStatus multiSyncStatus; -uint8_t multiBindStatus = MULTI_NORMAL_OPERATION; +#define MULTI_CHAN_BITS 11 +extern uint8_t g_moduleIdx; -enum MultiPacketTypes : uint8_t { +enum MultiPacketTypes : uint8_t +{ MultiStatus = 1, - FrSkySportTelemtry, + FrSkySportTelemetry, FrSkyHubTelemetry, SpektrumTelemetry, DSMBindPacket, FlyskyIBusTelemetry, ConfigCommand, InputSync, - FrskySportPolling + FrskySportPolling, + HitecTelemetry, + SpectrumScannerPacket, + FlyskyIBusTelemetryAC, + MultiRxChannels }; -enum MultiBufferState : uint8_t { +enum MultiBufferState : uint8_t +{ NoProtocolDetected, MultiFirstByteReceived, ReceivingMultiProtocol, @@ -48,71 +53,248 @@ enum MultiBufferState : uint8_t { FrskyTelemetryFallbackFirstByte, FrskyTelemetryFallbackNextBytes, FlyskyTelemetryFallback, + HitecTelemetryFallback, MultiStatusOrFrskyData }; -MultiBufferState guessProtocol() + +#if defined(INTERNAL_MODULE_MULTI) + +static MultiModuleStatus multiModuleStatus[NUM_MODULES] = {MultiModuleStatus(), MultiModuleStatus()}; +static MultiModuleSyncStatus multiSyncStatus[NUM_MODULES] = {MultiModuleSyncStatus(), MultiModuleSyncStatus()}; +static uint8_t multiBindStatus[NUM_MODULES] = {MULTI_NORMAL_OPERATION, MULTI_NORMAL_OPERATION}; + +static MultiBufferState multiTelemetryBufferState[NUM_MODULES]; + +MultiModuleStatus &getMultiModuleStatus(uint8_t module) { - if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_DSM2) + return multiModuleStatus[module]; +} + +MultiModuleSyncStatus &getMultiSyncStatus(uint8_t module) +{ + return multiSyncStatus[module]; +} + +uint8_t getMultiBindStatus(uint8_t module) +{ + return multiBindStatus[module]; +} + +void setMultiBindStatus(uint8_t module, uint8_t bindStatus) +{ + multiBindStatus[module] = bindStatus; +} + +MultiBufferState getMultiTelemetryBufferState(uint8_t module) +{ + return multiTelemetryBufferState[module]; +} + +void setMultiTelemetryBufferState(uint8_t module, MultiBufferState state) +{ + multiTelemetryBufferState[module] = state; +} + +// Use additional telemetry buffer +uint8_t intTelemetryRxBuffer[TELEMETRY_RX_PACKET_SIZE]; +uint8_t intTelemetryRxBufferCount; + +#else // !INTERNAL_MODULE_MULTI + +static MultiModuleStatus multiModuleStatus; +static MultiModuleSyncStatus multiSyncStatus; +static uint8_t multiBindStatus = MULTI_NORMAL_OPERATION; + +static MultiBufferState multiTelemetryBufferState; + +MultiModuleStatus& getMultiModuleStatus(uint8_t) +{ + return multiModuleStatus; +} + +MultiModuleSyncStatus& getMultiSyncStatus(uint8_t) +{ + return multiSyncStatus; +} + +uint8_t getMultiBindStatus(uint8_t) +{ + return multiBindStatus; +} + +void setMultiBindStatus(uint8_t, uint8_t bindStatus) +{ + multiBindStatus = bindStatus; +} + +MultiBufferState getMultiTelemetryBufferState(uint8_t) +{ + return multiTelemetryBufferState; +} + +void setMultiTelemetryBufferState(uint8_t, MultiBufferState state) +{ + multiTelemetryBufferState = state; +} + +#endif // INTERNAL_MODULE_MULTI + + +static MultiBufferState guessProtocol(uint8_t module) +{ + uint32_t moduleIdx = EXTERNAL_MODULE; +#if defined(INTERNAL_MODULE_MULTI) + if (isModuleMultimodule(INTERNAL_MODULE)) { + moduleIdx = INTERNAL_MODULE; + } +#endif + + if (g_model.moduleData[moduleIdx].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_DSM2) return SpektrumTelemetryFallback; - else if (g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) + else if (g_model.moduleData[module].getMultiProtocol(false) == MODULE_SUBTYPE_MULTI_FS_AFHDS2A) return FlyskyTelemetryFallback; else return FrskyTelemetryFallback; } -static void processMultiStatusPacket(const uint8_t *data) +static void processMultiScannerPacket(const uint8_t *data) { - // At least two status packets without bind flag - bool wasBinding = (multiModuleStatus.isBinding()); + uint8_t cur_channel = data[0]; + if (moduleState[g_moduleIdx].mode == MODULE_MODE_SPECTRUM_ANALYSER) { + for (uint8_t channel = 0; channel <5; channel++) { + uint8_t power = max(0,(data[channel+1] - 34) >> 1); // remove everything below -120dB - multiModuleStatus.flags = data[0]; - multiModuleStatus.major = data[1]; - multiModuleStatus.minor = data[2]; - multiModuleStatus.revision = data[3]; - multiModuleStatus.patch = data[4]; - multiModuleStatus.lastUpdate = get_tmr10ms(); - - if (wasBinding && !multiModuleStatus.isBinding() && multiBindStatus == MULTI_BIND_INITIATED) - multiBindStatus = MULTI_BIND_FINISHED; +#if LCD_W == 480 + coord_t x = cur_channel*2; + if (x < LCD_W) { + reusableBuffer.spectrumAnalyser.bars[x] = power; + reusableBuffer.spectrumAnalyser.bars[x+1] = power; + if (power > reusableBuffer.spectrumAnalyser.max[x]) { + reusableBuffer.spectrumAnalyser.max[x] = power; + reusableBuffer.spectrumAnalyser.max[x+1] = power; + } +#elif LCD_W == 212 + coord_t x = cur_channel; + if (x <= LCD_W) { + reusableBuffer.spectrumAnalyser.bars[x] = power; + if (power > reusableBuffer.spectrumAnalyser.max[x]) { + reusableBuffer.spectrumAnalyser.max[x] = power; + } +#else + coord_t x = cur_channel/2 + 1; + if (x <= LCD_W) { + reusableBuffer.spectrumAnalyser.bars[x] = power; + if (power > reusableBuffer.spectrumAnalyser.max[x]) { + reusableBuffer.spectrumAnalyser.max[x] = power; + } +#endif + } + if (++cur_channel > MULTI_SCANNER_MAX_CHANNEL) + cur_channel = 0; + } + } } -static void processMultiSyncPacket(const uint8_t *data) +static void processMultiStatusPacket(const uint8_t * data, uint8_t module) { - multiSyncStatus.lastUpdate = get_tmr10ms(); - multiSyncStatus.interval = data[4]; - multiSyncStatus.target = data[5]; + MultiModuleStatus &status = getMultiModuleStatus(module); + + // At least two status packets without bind flag + bool wasBinding = status.isBinding(); + + status.flags = data[0]; + status.major = data[1]; + status.minor = data[2]; + status.revision = data[3]; + status.patch = data[4]; + status.lastUpdate = get_tmr10ms(); + + if (getMultiModuleStatus(module).requiresFailsafeCheck) { + getMultiModuleStatus(module).requiresFailsafeCheck = false; + if (getMultiModuleStatus(module).supportsFailsafe() && g_model.moduleData[module].failsafeMode == FAILSAFE_NOT_SET) + POPUP_WARNING(STR_NO_FAILSAFE); + } + + if (wasBinding && !status.isBinding() && getMultiBindStatus(module) == MULTI_BIND_INITIATED) + setMultiBindStatus(module, MULTI_BIND_FINISHED); +} + +static void processMultiSyncPacket(const uint8_t * data, uint8_t module) +{ + MultiModuleSyncStatus &status = getMultiSyncStatus(module); + + status.lastUpdate = get_tmr10ms(); + status.interval = data[4]; + status.target = data[5]; #if !defined(PPM_PIN_SERIAL) - auto oldlag = multiSyncStatus.inputLag; + auto oldlag = status.inputLag; (void) oldlag; #endif - multiSyncStatus.calcAdjustedRefreshRate(data[0] << 8 | data[1], data[2] << 8 | data[3]); + status.calcAdjustedRefreshRate(data[0] << 8 | data[1], data[2] << 8 | data[3]); #if !defined(PPM_PIN_SERIAL) - TRACE("MP ADJ: rest: %d, lag %04d, diff: %04d target: %d, interval: %d, Refresh: %d, intAdjRefresh: %d, adjRefresh %d\r\n", extmodulePulsesData.dsm2.rest, - multiSyncStatus.inputLag, oldlag-multiSyncStatus.inputLag, multiSyncStatus.target, multiSyncStatus.interval, multiSyncStatus.refreshRate, multiSyncStatus.adjustedRefreshRate/50, - multiSyncStatus.getAdjustedRefreshRate()); + TRACE("MP ADJ: rest: %d, lag %04d, diff: %04d target: %d, interval: %d, Refresh: %d, intAdjRefresh: %d, adjRefresh %d\r\n", + module == EXTERNAL_MODULE ? extmodulePulsesData.dsm2.rest : 0, + status.inputLag, oldlag - status.inputLag, status.target, status.interval, status.refreshRate, status.adjustedRefreshRate / 50, + status.getAdjustedRefreshRate()); #endif } +#if defined(PCBTARANIS) || defined(PCBHORUS) +static void processMultiRxChannels(const uint8_t * data, uint8_t len) +{ + if (g_model.trainerData.mode != TRAINER_MODE_MULTI) + return; -static void processMultiTelemetryPaket(const uint8_t *packet) + //uint8_t pps = data[0]; + //uint8_t rssi = data[1]; + int ch = max(data[2], (uint8_t)0); + int maxCh = min(ch + data[3], MAX_TRAINER_CHANNELS); + + uint32_t bits = 0; + uint8_t bitsavailable = 0; + uint8_t byteIdx = 4; + + while (ch < maxCh) { + while (bitsavailable < MULTI_CHAN_BITS && byteIdx < len) { + bits |= (uint32_t)(data[byteIdx++]) << (uint32_t)bitsavailable; + bitsavailable += 8; + } + + int value = bits & ((1 << MULTI_CHAN_BITS) - 1); + bitsavailable -= MULTI_CHAN_BITS; + bits >>= MULTI_CHAN_BITS; + + ppmInput[ch] = (value - 1024) * 500 / 800; + ch++; + + if (byteIdx >= len) + break; + } + + if (ch == maxCh) + ppmInputValidityTimer = PPM_IN_VALID_TIMEOUT; +} +#endif + +static void processMultiTelemetryPaket(const uint8_t * packet, uint8_t module) { uint8_t type = packet[0]; uint8_t len = packet[1]; - const uint8_t *data = packet + 2; + const uint8_t * data = packet + 2; // Switch type switch (type) { case MultiStatus: if (len >= 5) - processMultiStatusPacket(data); + processMultiStatusPacket(data, module); break; case DSMBindPacket: if (len >= 10) - processDSMBindPacket(data); + processDSMBindPacket(module, data); break; case SpektrumTelemetry: @@ -131,6 +313,20 @@ static void processMultiTelemetryPaket(const uint8_t *packet) TRACE("[MP] Received IBUS telemetry len %d < 28", len); break; + case FlyskyIBusTelemetryAC: + if (len >= 28) + processFlySkyPacketAC(data); + else + TRACE("[MP] Received IBUS telemetry AC len %d < 28", len); + break; + + case HitecTelemetry: + if (len >= 8) + processHitecPacket(data); + else + TRACE("[MP] Received Hitec telemetry len %d < 8", len); + break; + case FrSkyHubTelemetry: if (len >= 4) frskyDProcessPacket(data); @@ -138,7 +334,7 @@ static void processMultiTelemetryPaket(const uint8_t *packet) TRACE("[MP] Received Frsky HUB telemetry len %d < 4", len); break; - case FrSkySportTelemtry: + case FrSkySportTelemetry: if (len >= 4) sportProcessTelemetryPacket(data); else @@ -147,7 +343,7 @@ static void processMultiTelemetryPaket(const uint8_t *packet) case InputSync: if (len >= 6) - processMultiSyncPacket(data); + processMultiSyncPacket(data, module); else TRACE("[MP] Received input sync len %d < 6", len); break; @@ -164,6 +360,21 @@ static void processMultiTelemetryPaket(const uint8_t *packet) } break; #endif + case SpectrumScannerPacket: + if (len == 6) + processMultiScannerPacket(data); + else + TRACE("[MP] Received spectrum scanner len %d != 6", len); + break; + +#if defined(PCBTARANIS) || defined(PCBHORUS) + case MultiRxChannels: + if (len >= 4) + processMultiRxChannels(data, len); + else + TRACE("[MP] Received RX channels len %d < 4", len); + break; +#endif default: TRACE("[MP] Unkown multi packet type 0x%02X, len %d", type, len); @@ -173,7 +384,7 @@ static void processMultiTelemetryPaket(const uint8_t *packet) // sprintf does not work AVR ARM // use a small helper function -static void appendInt(char *buf, uint32_t val) +static void appendInt(char * buf, uint32_t val) { while (*buf) buf++; @@ -193,8 +404,8 @@ void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uin uint16_t targetRefreshRate = (uint16_t) (newRefreshRate * ((MIN_REFRESH_RATE / (newRefreshRate - 1)) + 1)); // Overflow, reverse sample - if (lagDifference < -targetRefreshRate/2) - lagDifference= -lagDifference; + if (lagDifference < -targetRefreshRate / 2) + lagDifference = -lagDifference; // Reset adjusted refresh if rate has changed @@ -205,7 +416,7 @@ void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uin adjustedRefreshRate /= 2; // Our refresh rate in ps - adjustedRefreshRate*=1000; + adjustedRefreshRate *= 1000; return; } @@ -213,16 +424,16 @@ void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uin int numsamples = interval * 10000 / targetRefreshRate; // Convert lagDifference to ps - lagDifference=lagDifference*1000; + lagDifference = lagDifference * 1000; // Calculate the time we intentionally were late/early - if (inputLag > target*10 +30) - lagDifference += numsamples*500; - else if (inputLag < target*10 - 30) - lagDifference -= numsamples*500; + if (inputLag > target * 10 + 30) + lagDifference += numsamples * 500; + else if (inputLag < target * 10 - 30) + lagDifference -= numsamples * 500; // Caculate the time in ps each frame is to slow (positive), fast(negative) - int perframeps = lagDifference*10/ numsamples; + int perframeps = lagDifference * 10 / numsamples; if (perframeps > 20000) perframeps = 20000; @@ -230,20 +441,21 @@ void MultiModuleSyncStatus::calcAdjustedRefreshRate(uint16_t newRefreshRate, uin if (perframeps < -20000) perframeps = -20000; - adjustedRefreshRate =(adjustedRefreshRate + perframeps); + adjustedRefreshRate = (adjustedRefreshRate + perframeps); // Safeguards - if (adjustedRefreshRate < 6*1000*1000) - adjustedRefreshRate = 6*1000*1000; - if (adjustedRefreshRate > 30*1000*1000) - adjustedRefreshRate = 30*1000*1000; + if (adjustedRefreshRate < 6 * 1000 * 1000) + adjustedRefreshRate = 6 * 1000 * 1000; + if (adjustedRefreshRate > 30 * 1000 * 1000) + adjustedRefreshRate = 30 * 1000 * 1000; inputLag = newInputLag; } static uint8_t counter; -uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate() { +uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate() +{ if (!isValid() || refreshRate == 0) return 18000; @@ -251,9 +463,9 @@ uint16_t MultiModuleSyncStatus::getAdjustedRefreshRate() { counter = (uint8_t) (counter + 1 % 10); uint16_t rate = (uint16_t) ((adjustedRefreshRate + counter * 50) / 500); // Check how far off we are from our target, positive means we are too slow, negative we are too fast - if (inputLag > target*10 +30) - return (uint16_t) (rate - 1); - else if (inputLag < target*10 - 30) + if (inputLag > target * 10 + 30) + return (uint16_t) (rate - 1); + else if (inputLag < target * 10 - 30) return (uint16_t) (rate + 1); else return rate; @@ -265,17 +477,16 @@ static void prependSpaces(char * buf, int val) while (*buf) buf++; - int k=10000; - while(val/k==0 && k > 0) - { - *buf=' '; + int k = 10000; + while (val / k == 0 && k > 0) { + *buf = ' '; buf++; - k/= 10; + k /= 10; } - *buf='\0'; + *buf = '\0'; } -void MultiModuleSyncStatus::getRefreshString(char *statusText) +void MultiModuleSyncStatus::getRefreshString(char * statusText) { if (!isValid()) { return; @@ -285,20 +496,22 @@ void MultiModuleSyncStatus::getRefreshString(char *statusText) prependSpaces(statusText, inputLag); appendInt(statusText, inputLag); strcat(statusText, "ns R "); - prependSpaces(statusText, adjustedRefreshRate/1000); + prependSpaces(statusText, adjustedRefreshRate / 1000); appendInt(statusText, (uint32_t) (adjustedRefreshRate / 1000)); strcat(statusText, "ns"); } -void MultiModuleStatus::getStatusString(char *statusText) +void MultiModuleStatus::getStatusString(char * statusText) { if (!isValid()) { #if defined(PCBFRSKY) - if (IS_INTERNAL_MODULE_ENABLED()) +#if !defined(INTERNAL_MODULE_MULTI) + if (isSportLineUsedByInternalModule()) strcpy(statusText, STR_DISABLE_INTERNAL); else #endif - strcpy(statusText, STR_MODULE_NO_TELEMETRY); +#endif + strcpy(statusText, STR_MODULE_NO_TELEMETRY); return; } if (!protocolValid()) { @@ -313,7 +526,7 @@ void MultiModuleStatus::getStatusString(char *statusText) strcpy(statusText, STR_MODULE_NO_INPUT); return; } - else if(isWaitingforBind()) { + else if (isWaitingforBind()) { strcpy(statusText, STR_MODULE_WAITFORBIND); return; } @@ -333,50 +546,71 @@ void MultiModuleStatus::getStatusString(char *statusText) strcat(statusText, STR_MODULE_BINDING); } - -static MultiBufferState multiTelemetryBufferState; - -static void processMultiTelemetryByte(const uint8_t data) +static uint8_t * getRxBuffer(uint8_t moduleIdx) { - if (telemetryRxBufferCount < TELEMETRY_RX_PACKET_SIZE) { - telemetryRxBuffer[telemetryRxBufferCount++] = data; +#if defined(INTERNAL_MODULE_MULTI) + if (moduleIdx == INTERNAL_MODULE) + return intTelemetryRxBuffer; +#endif + return telemetryRxBuffer; +} + +static uint8_t &getRxBufferCount(uint8_t moduleIdx) +{ +#if defined(INTERNAL_MODULE_MULTI) + if (moduleIdx == INTERNAL_MODULE) + return intTelemetryRxBufferCount; +#endif + return telemetryRxBufferCount; +} + +static void processMultiTelemetryByte(const uint8_t data, uint8_t module) +{ + uint8_t * rxBuffer = getRxBuffer(module); + uint8_t &rxBufferCount = getRxBufferCount(module); + + if (rxBufferCount < TELEMETRY_RX_PACKET_SIZE) { + rxBuffer[rxBufferCount++] = data; } else { - TRACE("[MP] array size %d error", telemetryRxBufferCount); - multiTelemetryBufferState = NoProtocolDetected; + TRACE("[MP] array size %d error", rxBufferCount); + setMultiTelemetryBufferState(module, NoProtocolDetected); } // Length field does not count the header - if (telemetryRxBufferCount >= 2 && telemetryRxBuffer[1] == telemetryRxBufferCount - 2) { + if (rxBufferCount >= 2 && rxBuffer[1] == rxBufferCount - 2) { // debug print the content of the packet #if 0 debugPrintf("[MP] Packet type %02X len 0x%02X: ", - telemetryRxBuffer[0], telemetryRxBuffer[1]); - for (int i=0; i<(telemetryRxBufferCount+3)/4; i++) { - debugPrintf("[%02X%02X %02X%02X] ", telemetryRxBuffer[i*4+2], telemetryRxBuffer[i*4 + 3], - telemetryRxBuffer[i*4 + 4], telemetryRxBuffer[i*4 + 5]); + rxBuffer[0], rxBuffer[1]); + for (int i=0; i<(rxBufferCount+3)/4; i++) { + debugPrintf("[%02X%02X %02X%02X] ", rxBuffer[i*4+2], rxBuffer[i*4 + 3], + rxBuffer[i*4 + 4], rxBuffer[i*4 + 5]); } debugPrintf("\r\n"); #endif // Packet is complete, process it - processMultiTelemetryPaket(telemetryRxBuffer); - multiTelemetryBufferState = NoProtocolDetected; + processMultiTelemetryPaket(rxBuffer, module); + setMultiTelemetryBufferState(module, NoProtocolDetected); } } -void processMultiTelemetryData(const uint8_t data) +void processMultiTelemetryData(uint8_t data, uint8_t module) { - // debugPrintf("State: %d, byte received %02X, buflen: %d\r\n", multiTelemetryBufferState, data, telemetryRxBufferCount); - switch (multiTelemetryBufferState) { + uint8_t * rxBuffer = getRxBuffer(module); + uint8_t &rxBufferCount = getRxBufferCount(module); + + //debugPrintf("State: %d, byte received %02X, buflen: %d\r\n", multiTelemetryBufferState, data, rxBufferCount); + switch (getMultiTelemetryBufferState(module)) { case NoProtocolDetected: if (data == 'M') { - multiTelemetryBufferState = MultiFirstByteReceived; + setMultiTelemetryBufferState(module, MultiFirstByteReceived); } else if (data == 0xAA || data == 0x7e) { - multiTelemetryBufferState = guessProtocol(); + setMultiTelemetryBufferState(module, guessProtocol(module)); // Process the first byte by the protocol - processMultiTelemetryData(data); + processMultiTelemetryData(data, module); } else { TRACE("[MP] invalid start byte 0x%02X", data); @@ -384,91 +618,92 @@ void processMultiTelemetryData(const uint8_t data) break; case FrskyTelemetryFallback: - multiTelemetryBufferState = FrskyTelemetryFallbackFirstByte; + setMultiTelemetryBufferState(module, FrskyTelemetryFallbackFirstByte); processFrskyTelemetryData(data); break; case FrskyTelemetryFallbackFirstByte: if (data == 'M') { - multiTelemetryBufferState = MultiStatusOrFrskyData; + setMultiTelemetryBufferState(module, MultiStatusOrFrskyData); } else { processFrskyTelemetryData(data); if (data != 0x7e) - multiTelemetryBufferState = FrskyTelemetryFallbackNextBytes; + setMultiTelemetryBufferState(module, FrskyTelemetryFallbackNextBytes); } break; case FrskyTelemetryFallbackNextBytes: processFrskyTelemetryData(data); - if (data == 0x7e) + if (data == 0x7e) { // end of packet or start of new packet - multiTelemetryBufferState = FrskyTelemetryFallbackFirstByte; + setMultiTelemetryBufferState(module, FrskyTelemetryFallbackFirstByte); + } break; case FlyskyTelemetryFallback: - processFlySkyTelemetryData(data); - if (telemetryRxBufferCount == 0) - multiTelemetryBufferState = NoProtocolDetected; + processFlySkyTelemetryData(data, rxBuffer, rxBufferCount); + if (rxBufferCount == 0) { + setMultiTelemetryBufferState(module, NoProtocolDetected); + } break; case SpektrumTelemetryFallback: - processSpektrumTelemetryData(data); - if (telemetryRxBufferCount == 0) - multiTelemetryBufferState = NoProtocolDetected; + processSpektrumTelemetryData(module, data, rxBuffer, rxBufferCount); + if (rxBufferCount == 0) { + setMultiTelemetryBufferState(module, NoProtocolDetected); + } break; case MultiFirstByteReceived: - telemetryRxBufferCount = 0; + rxBufferCount = 0; if (data == 'P') { - multiTelemetryBufferState = ReceivingMultiProtocol; + setMultiTelemetryBufferState(module, ReceivingMultiProtocol); } else if (data >= 5 && data <= 10) { // Protocol indented for er9x/ersky9, accept only 5-10 as packet length to have // a bit of validation - multiTelemetryBufferState = ReceivingMultiStatus; - processMultiTelemetryData(data); + setMultiTelemetryBufferState(module, ReceivingMultiStatus); + processMultiTelemetryData(data, module); } else { TRACE("[MP] invalid second byte 0x%02X", data); - multiTelemetryBufferState = NoProtocolDetected; + setMultiTelemetryBufferState(module, NoProtocolDetected); } break; case ReceivingMultiProtocol: - processMultiTelemetryByte(data); + processMultiTelemetryByte(data, module); break; case MultiStatusOrFrskyData: // Check len byte if it makes sense for multi if (data >= 5 && data <= 10) { - multiTelemetryBufferState = ReceivingMultiStatus; - telemetryRxBufferCount = 0; + setMultiTelemetryBufferState(module, ReceivingMultiStatus); + rxBufferCount = 0; } else { - multiTelemetryBufferState = FrskyTelemetryFallbackNextBytes; - processMultiTelemetryData('M'); + setMultiTelemetryBufferState(module, FrskyTelemetryFallbackNextBytes); + processMultiTelemetryData('M', module); } - processMultiTelemetryData(data); + processMultiTelemetryData(data, module); break; case ReceivingMultiStatus: - telemetryRxBuffer[telemetryRxBufferCount++] = data; - if (telemetryRxBufferCount > 5 && telemetryRxBuffer[0] == telemetryRxBufferCount-1) { - processMultiStatusPacket(telemetryRxBuffer+1); - telemetryRxBufferCount = 0; - multiTelemetryBufferState = NoProtocolDetected; + rxBuffer[rxBufferCount++] = data; + if (rxBufferCount > 5 && rxBuffer[0] == rxBufferCount - 1) { + processMultiStatusPacket(rxBuffer + 1, module); + rxBufferCount = 0; + setMultiTelemetryBufferState(module, NoProtocolDetected); } - if (telemetryRxBufferCount > 10) { + if (rxBufferCount > 10) { // too long ignore - TRACE("Overlong multi status packet detected ignoring, wanted %d", telemetryRxBuffer[0]); - telemetryRxBufferCount =0; - multiTelemetryBufferState = NoProtocolDetected; + TRACE("Overlong multi status packet detected ignoring, wanted %d", rxBuffer[0]); + rxBufferCount = 0; + setMultiTelemetryBufferState(module, NoProtocolDetected); } - - + break; } - } diff --git a/radio/src/telemetry/multi.h b/radio/src/telemetry/multi.h index 1b439ea24..83f3de6fb 100644 --- a/radio/src/telemetry/multi.h +++ b/radio/src/telemetry/multi.h @@ -80,11 +80,16 @@ Type 0x06 Flysky AFHDS2 telemetry data data[0] = RSSI value data[1-28] telemetry data +Type 0x0B Spectrum Scanner telemetry data + length: 6 + data[0] = start channel (2400 + x*0.333 Mhz) + data[1-5] power levels + */ +void processMultiTelemetryData(uint8_t data, uint8_t module); - -void processMultiTelemetryData(uint8_t data); +#define MULTI_SCANNER_MAX_CHANNEL 249 // This should be put into the Module definition if other modules gain this functionality struct MultiModuleSyncStatus { @@ -107,7 +112,7 @@ struct MultiModuleSyncStatus { }; -extern MultiModuleSyncStatus multiSyncStatus; +MultiModuleSyncStatus& getMultiSyncStatus(uint8_t module); struct MultiModuleStatus { @@ -118,26 +123,29 @@ struct MultiModuleStatus { uint8_t patch; uint8_t flags; + uint8_t requiresFailsafeCheck; tmr10ms_t lastUpdate; void getStatusString(char* statusText); - inline bool isValid() { return (bool)(get_tmr10ms() - lastUpdate < 200); } - inline bool supportsFailsafe() { return (bool) (flags & 0x20); } - inline bool isWaitingforBind() { return (bool) (flags & 0x10); } - inline bool isBinding() { return (bool) (flags & 0x08); } - inline bool protocolValid() { return (bool) (flags & 0x04); } - inline bool serialMode() { return (bool) (flags & 0x02); } - inline bool inputDetected() { return (bool) (flags & 0x01); } + inline bool isValid() const { return (bool)(get_tmr10ms() - lastUpdate < 200); } + inline bool supportsFailsafe() const { return (bool) (flags & 0x20); } + inline bool isWaitingforBind() const { return (bool) (flags & 0x10); } + inline bool isBinding() const { return (bool) (flags & 0x08); } + inline bool protocolValid() const { return (bool) (flags & 0x04); } + inline bool serialMode() const { return (bool) (flags & 0x02); } + inline bool inputDetected() const { return (bool) (flags & 0x01); } }; -extern MultiModuleStatus multiModuleStatus; +MultiModuleStatus& getMultiModuleStatus(uint8_t module); + enum MultiBindStatus : uint8_t { MULTI_NORMAL_OPERATION, MULTI_BIND_INITIATED, MULTI_BIND_FINISHED, }; -extern uint8_t multiBindStatus; +uint8_t getMultiBindStatus(uint8_t module); +void setMultiBindStatus(uint8_t module, uint8_t bindStatus); #endif //OPENTX_MULTI_H diff --git a/radio/src/telemetry/spektrum.cpp b/radio/src/telemetry/spektrum.cpp index 41b27b88c..ae5435845 100644 --- a/radio/src/telemetry/spektrum.cpp +++ b/radio/src/telemetry/spektrum.cpp @@ -370,28 +370,27 @@ void processSpektrumPacket(const uint8_t *packet) LemonRX+Sat+tele 0xb2 07 1 */ -void processDSMBindPacket(const uint8_t *packet) +void processDSMBindPacket(uint8_t module, const uint8_t *packet) { uint32_t debugval; - if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2 - && g_model.moduleData[EXTERNAL_MODULE].multi.autoBindMode) { + if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2 + && g_model.moduleData[module].multi.autoBindMode) { int channels = packet[5]; // Only sets channel etc when in DSM multi mode - g_model.moduleData[EXTERNAL_MODULE].channelsCount = channels - 8; + g_model.moduleData[module].channelsCount = channels - 8; // bool use11ms = (packet[8] & 0x10) ; if (packet[6] >= 0xb2) - g_model.moduleData[EXTERNAL_MODULE].subType = MM_RF_DSM2_SUBTYPE_DSMX_11; + g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSMX_11; else if (packet[6] >= 0xa2) - g_model.moduleData[EXTERNAL_MODULE].subType = MM_RF_DSM2_SUBTYPE_DSMX_22; + g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSMX_22; else if (packet[6] >= 0x12) - g_model.moduleData[EXTERNAL_MODULE].subType = MM_RF_DSM2_SUBTYPE_DSM2_11; + g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSM2_11; else - g_model.moduleData[EXTERNAL_MODULE].subType = MM_RF_DSM2_SUBTYPE_DSM2_22; + g_model.moduleData[module].subType = MM_RF_DSM2_SUBTYPE_DSM2_22; storageDirty(EE_MODEL); - } debugval = packet[7] << 24 | packet[6] << 16 | packet[5] << 8 | packet[4]; @@ -400,45 +399,45 @@ void processDSMBindPacket(const uint8_t *packet) setTelemetryValue(PROTOCOL_TELEMETRY_SPEKTRUM, (I2C_PSEUDO_TX << 8) + 4, 0, 0, debugval, UNIT_RAW, 0); /* Finally stop binding as the rx just told us that it is bound */ - if (g_model.moduleData[EXTERNAL_MODULE].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[EXTERNAL_MODULE].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2 && moduleState[EXTERNAL_MODULE].mode == MODULE_MODE_BIND) { - multiBindStatus=MULTI_BIND_FINISHED; + if (g_model.moduleData[module].type == MODULE_TYPE_MULTIMODULE && g_model.moduleData[module].getMultiProtocol(true) == MODULE_SUBTYPE_MULTI_DSM2 && moduleState[module].mode == MODULE_MODE_BIND) { + setMultiBindStatus(module, MULTI_BIND_FINISHED); } } -void processSpektrumTelemetryData(uint8_t data) +void processSpektrumTelemetryData(uint8_t module, uint8_t data, uint8_t* rxBuffer, uint8_t& rxBufferCount) { - if (telemetryRxBufferCount == 0 && data != 0xAA) { + if (rxBufferCount == 0 && data != 0xAA) { TRACE("[SPK] invalid start byte 0x%02X", data); return; } - if (telemetryRxBufferCount < TELEMETRY_RX_PACKET_SIZE) { - telemetryRxBuffer[telemetryRxBufferCount++] = data; + if (rxBufferCount < TELEMETRY_RX_PACKET_SIZE) { + rxBuffer[rxBufferCount++] = data; } else { - TRACE("[SPK] array size %d error", telemetryRxBufferCount); - telemetryRxBufferCount = 0; + TRACE("[SPK] array size %d error", rxBufferCount); + rxBufferCount = 0; } - if (telemetryRxBuffer[1] == 0x80 && telemetryRxBufferCount >= DSM_BIND_PACKET_LENGTH) { - processDSMBindPacket(telemetryRxBuffer+2); - telemetryRxBufferCount = 0; + if (rxBuffer[1] == 0x80 && rxBufferCount >= DSM_BIND_PACKET_LENGTH) { + processDSMBindPacket(module, rxBuffer+2); + rxBufferCount = 0; return; } - if (telemetryRxBufferCount >= SPEKTRUM_TELEMETRY_LENGTH) { + if (rxBufferCount >= SPEKTRUM_TELEMETRY_LENGTH) { // Debug print content of Telemetry to console #if 0 debugPrintf("[SPK] Packet 0x%02X rssi 0x%02X: ic2 0x%02x, %02x: ", - telemetryRxBuffer[0], telemetryRxBuffer[1], telemetryRxBuffer[2], telemetryRxBuffer[3]); + rxBuffer[0], rxBuffer[1], rxBuffer[2], rxBuffer[3]); for (int i=4; i * luaInputTelemetryFifo; #endif -#if defined(PCBTARANIS) || defined(PCBHORUS) -inline bool isSportLineUsedByInternalModule() -{ - return g_model.moduleData[INTERNAL_MODULE].type == MODULE_TYPE_XJT_PXX1; -} -#else -inline bool isSportLineUsedByInternalModule() -{ - return false; -} -#endif - void processPXX2Frame(uint8_t module, uint8_t *frame); #endif // _TELEMETRY_H_ diff --git a/radio/src/telemetry/telemetry_sensors.cpp b/radio/src/telemetry/telemetry_sensors.cpp index 8475eac54..868396536 100644 --- a/radio/src/telemetry/telemetry_sensors.cpp +++ b/radio/src/telemetry/telemetry_sensors.cpp @@ -527,6 +527,9 @@ int setTelemetryValue(TelemetryProtocol protocol, uint16_t id, uint8_t subId, ui case PROTOCOL_TELEMETRY_FLYSKY_IBUS: flySkySetDefault(index,id, subId, instance); break; + case PROTOCOL_TELEMETRY_HITEC: + hitecSetDefault(index, id, subId, instance); + break; #endif #if defined(LUA) case PROTOCOL_TELEMETRY_LUA: @@ -599,10 +602,10 @@ const UnitConversionRule unitConversionTable[] = { { UNIT_KMH, UNIT_FEET_PER_SECOND, 911, 1000}, // 1 km/h = 0.911344415 feet per second { UNIT_MILLILITERS, UNIT_FLOZ, 100, 2957}, - + { UNIT_RADIANS, UNIT_DEGREE, 10000, 175}, // 1 rad = 57.29578 deg { UNIT_DEGREE, UNIT_RADIANS, 175, 10000}, // 1 deg = ‪0,0174533‬ rad - + { 0, 0, 0, 0} // termination }; diff --git a/radio/src/tests/lcd.cpp b/radio/src/tests/lcd.cpp index 8375c6f63..5bce5d535 100644 --- a/radio/src/tests/lcd.cpp +++ b/radio/src/tests/lcd.cpp @@ -259,7 +259,7 @@ TEST(Lcd, Dblsize) TEST(Lcd, DrawSwitch) { lcdClear(); - drawSwitch(0, 10, SWSRC_SA0, 0); + drawSwitch(0, 10, SWSRC_SA0, 0, false); drawSwitch(30, 10, SWSRC_SA0, SMLSIZE); // drawSwitch(60, 10, SWSRC_SA0, MIDSIZE); missing arrows in this font drawSwitch(90, 10, SWSRC_SA0, DBLSIZE); diff --git a/radio/src/thirdparty/libACCESS b/radio/src/thirdparty/libACCESS new file mode 160000 index 000000000..79a6921d2 --- /dev/null +++ b/radio/src/thirdparty/libACCESS @@ -0,0 +1 @@ +Subproject commit 79a6921d2386236a44e87554195bf41dc412b445 diff --git a/radio/src/trainer.cpp b/radio/src/trainer.cpp index 86b4dee66..d9e3f4a10 100644 --- a/radio/src/trainer.cpp +++ b/radio/src/trainer.cpp @@ -115,15 +115,14 @@ void checkTrainerSettings() #if defined(TRAINER_BATTERY_COMPARTMENT) case TRAINER_MODE_MASTER_BATTERY_COMPARTMENT: - if (g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) { + if (g_eeGeneral.auxSerialMode == UART_MODE_SBUS_TRAINER) auxSerialSbusInit(); - break; - } - // no break + else + init_trainer_capture(); + break; #endif - default: - // master is default + case TRAINER_MODE_MASTER_TRAINER_JACK: init_trainer_capture(); break; } diff --git a/radio/src/trainer.h b/radio/src/trainer.h index 6f5549cc7..e3c67acac 100644 --- a/radio/src/trainer.h +++ b/radio/src/trainer.h @@ -35,6 +35,7 @@ extern uint8_t currentTrainerMode; void checkTrainerSignalWarning(); void checkTrainerSettings(); +void forceResetTrainerSettings(); // Needs to be inlined to avoid slow function calls in ISR routines inline void captureTrainerPulses(uint16_t capture) diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index af26a58a8..f0508ed75 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -359,6 +359,7 @@ const char STR_SWITCHWARN[] = TR_SWITCHWARN; const char STR_FAILSAFEWARN[] = TR_FAILSAFEWARN; const char STR_WRONG_SDCARDVERSION[] = TR_WRONG_SDCARDVERSION; const char STR_WARN_RTC_BATTERY_LOW[] = TR_WARN_RTC_BATTERY_LOW; +const char STR_WARN_MULTI_LOWPOWER[] = TR_WARN_MULTI_LOWPOWER; const char STR_BATTERY[] = TR_BATTERY; const char STR_WRONG_PCBREV[] = TR_WRONG_PCBREV; const char STR_EMERGENCY_MODE[] = TR_EMERGENCY_MODE; @@ -423,7 +424,9 @@ const char STR_PATH_TOO_LONG[] = TR_PATH_TOO_LONG; const char STR_VIEW_TEXT[] = TR_VIEW_TEXT; const char STR_FLASH_BOOTLOADER[] = TR_FLASH_BOOTLOADER; const char STR_FLASH_INTERNAL_MODULE[] = TR_FLASH_INTERNAL_MODULE; +const char STR_FLASH_INTERNAL_MULTI[] = TR_FLASH_INTERNAL_MULTI; const char STR_FLASH_EXTERNAL_MODULE[] = TR_FLASH_EXTERNAL_MODULE; +const char STR_FLASH_EXTERNAL_MULTI[] = TR_FLASH_EXTERNAL_MULTI; const char STR_FIRMWARE_UPDATE_ERROR[] = TR_FIRMWARE_UPDATE_ERROR; const char STR_FIRMWARE_UPDATE_SUCCESS[] = TR_FIRMWARE_UPDATE_SUCCESS; const char STR_WRITING[] = TR_WRITING; @@ -578,6 +581,7 @@ const char STR_MENU_DISPLAY[] = TR_MENU_DISPLAY; const char STR_MENU_OTHER[] = TR_MENU_OTHER; const char STR_MENU_INVERT[] = TR_MENU_INVERT; const char STR_JITTER_FILTER[] = TR_JITTER_FILTER; +const char STR_RTC_CHECK[] = TR_RTC_CHECK; const char STR_EXIT[] = TR_EXIT; const char STR_MODULE_RANGE[] = TR_MODULE_RANGE; const char STR_RECEIVER_OPTIONS[] = TR_RECEIVER_OPTIONS; @@ -681,6 +685,9 @@ const char STR_PROTOCOL_INVALID[] = TR_PROTOCOL_INVALID; const char STR_MODULE_STATUS[] = TR_MODULE_STATUS; const char STR_MODULE_SYNC[] = TR_MODULE_SYNC; const char STR_MULTI_SERVOFREQ[] = TR_MULTI_SERVOFREQ; +const char STR_NEEDS_FILE[] = TR_NEEDS_FILE; +const char STR_EXT_MULTI_SPEC[] = TR_EXT_MULTI_SPEC; +const char STR_INT_MULTI_SPEC[] = TR_INT_MULTI_SPEC; #endif #if LCD_W < 212 @@ -771,3 +778,5 @@ const char STR_ABOUT_PARENTS_1[] = TR_ABOUT_PARENTS_1; const char STR_ABOUT_PARENTS_2[] = TR_ABOUT_PARENTS_2; const char STR_ABOUT_PARENTS_3[] = TR_ABOUT_PARENTS_3; const char STR_ABOUT_PARENTS_4[] = TR_ABOUT_PARENTS_4; + +const char STR_AUTH_FAILURE[] = TR_AUTH_FAILURE; diff --git a/radio/src/translations.h b/radio/src/translations.h index 86e6c45bb..37ccce3d0 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -550,6 +550,9 @@ extern const char STR_WAITING_FOR_TX[]; #define STR_UPDATE_LIST STR_DELAYDOWN #endif +extern const char STR_NEEDS_FILE[]; +extern const char STR_EXT_MULTI_SPEC[]; +extern const char STR_INT_MULTI_SPEC[]; extern const char STR_CAT_NOT_EMPTY[]; extern const char STR_WARNING[]; extern const char STR_STORAGE_WARNING[]; @@ -562,6 +565,7 @@ extern const char STR_NIGHTLY_WARNING[]; extern const char STR_NIGHTLY_NOTSAFE[]; extern const char STR_WRONG_SDCARDVERSION[]; extern const char STR_WARN_RTC_BATTERY_LOW[]; +extern const char STR_WARN_MULTI_LOWPOWER[]; extern const char STR_BATTERY[]; extern const char STR_WRONG_PCBREV[]; extern const char STR_EMERGENCY_MODE[]; @@ -635,7 +639,9 @@ extern const char STR_FLASH_BLUETOOTH_MODULE[]; extern const char STR_FLASH_POWER_MANAGEMENT_UNIT[]; extern const char STR_CURRENT_VERSION[]; extern const char STR_FLASH_INTERNAL_MODULE[]; +extern const char STR_FLASH_INTERNAL_MULTI[]; extern const char STR_FLASH_EXTERNAL_MODULE[]; +extern const char STR_FLASH_EXTERNAL_MULTI[]; extern const char STR_FIRMWARE_UPDATE_ERROR[]; extern const char STR_FIRMWARE_UPDATE_SUCCESS[]; extern const char STR_WRITING[]; @@ -866,6 +872,7 @@ extern const char STR_MENU_DISPLAY[]; extern const char STR_MENU_OTHER[]; extern const char STR_MENU_INVERT[]; extern const char STR_JITTER_FILTER[]; +extern const char STR_RTC_CHECK[]; #if MENUS_LOCK == 1 extern const char STR_UNLOCKED[]; @@ -919,6 +926,8 @@ extern const char STR_ABOUT_PARENTS_2[]; extern const char STR_ABOUT_PARENTS_3[]; extern const char STR_ABOUT_PARENTS_4[]; +extern const char STR_AUTH_FAILURE[]; + #define CHR_HOUR TR_CHR_HOUR #define CHR_INPUT TR_CHR_INPUT diff --git a/radio/src/translations/cz.h.txt b/radio/src/translations/cz.h.txt index d9c98e7f0..b0f6dca53 100644 --- a/radio/src/translations/cz.h.txt +++ b/radio/src/translations/cz.h.txt @@ -51,9 +51,6 @@ #define LEN_VBEEPMODE TR("\005","\012") #define TR_VBEEPMODE TR("Tichý""Alarm""BezKl""Vše\0", "Tichý\0 ""Jen alarm\0""Bez kláves""Vše\0 ") -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "Ne REaREb" - #define LEN_VBLMODE TR("\005", "\007") #define TR_VBLMODE TR("Vyp\0 ""Kláv.""Páky\0""Vše\0 ""Zap\0 ", "Vypnuto""Klávesy""Páky\0 ""Vše\0 ""Zapnuto") @@ -117,7 +114,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "SVPK12345LR" + #define TR_RETA123 "SVPK13245LR" #elif defined(PCBX9E) #define TR_RETA123 "SVPK1234LRLR" #elif defined(PCBTARANIS) || defined(REVX) @@ -356,7 +353,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Učitel/SBUS Modul\0" #define TR_VTRAINER_MASTER_CPPM_MODULE "Učitel/CPPM Modul\0" #define TR_VTRAINER_MASTER_BATTERY "Učitel/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\012" #define TR_VFAILSAFE "Nenastaven""Držet\0 ""Vlastní\0 ""Bez pulzů\0""Přijímač\0" @@ -517,7 +515,6 @@ #define TR_MODEL_STILL_POWERED "Model stále spuštěn" #define TR_MODEL_SHUTDOWN "Vypnout ?" #define TR_PRESS_ENTER_TO_CONFIRM "Zmáčkni enter pro potvrzení" -#define TR_RENAVIG "Navig. RotEnc" #define TR_THROTTLE_LABEL "Plyn" #define TR_THROTTLEREVERSE TR("ReversPlyn", INDENT"Revers plynu") #define TR_MINUTEBEEP TR("Minuta", "Oznamovat minuty") @@ -567,10 +564,9 @@ #define OFS_RX 4 #define TR_ACCEL "Acc:" #define TR_NODATA CENTER "NO DATA" -#define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" -#define TR_TMIXMAXMS "Tmix max" -#define TR_FREE_STACK "Free stack" +#define TR_US "us" +#define TR_TMIXMAXMS "Tmix max" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET TR_ENTER" >> Reset" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" @@ -723,6 +719,9 @@ #define TR_SPECTRUM_ANALYSER_EXT "Spektální an. (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spektální an. (INT)" #define TR_SDCARD_FULL "Plná SD karta" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Nekompatibilní" #define TR_WARNING "KONTROLA" #define TR_EEPROMWARN "EEPROM" @@ -736,6 +735,7 @@ #define TR_NIGHTLY_NOTSAFE "Verze není bezpečná k létání" #define TR_WRONG_SDCARDVERSION "Očekávaná ver.: " #define TR_WARN_RTC_BATTERY_LOW "Slabá RTC baterie" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATERIE" #define TR_WRONG_PCBREV "Jiná verze PCB/firmware" #define TR_EMERGENCY_MODE "NOUZOVÝ REŽIM" @@ -788,9 +788,9 @@ #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Hledat" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Vzdál. addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Lokál. addr" -#define TR_BLUETOOTH_PIN_CODE TR(INDENT "PIN kód", "PIN kód") +#define TR_BLUETOOTH_DIST_ADDR "Vzdál. addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Lokál. addr" +#define TR_BLUETOOTH_PIN_CODE TR("PIN kód", "PIN kód") #define TR_BAUDRATE "Baudrate BT" #define LEN_BLUETOOTH_MODES "\012" #if defined(PCBX9E) @@ -823,7 +823,9 @@ #define TR_FLASH_POWER_MANAGEMENT_UNIT TR("Flash řízení spotř.", "Flash jednotky řízení spotřeby") #define TR_CURRENT_VERSION TR("Současná ver. ", "Současná verze: ") #define TR_FLASH_INTERNAL_MODULE TR("Flash vnitř. modulu", "Flash vnitřního modulu") +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. modulu", "Flash externího zařízení") +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("Chyba zápisu FW", "Chyba zápisu firmware") #define TR_FIRMWARE_UPDATE_SUCCESS "Úspěšný zápis FW" #define TR_WRITING TR3("\14Zapisuji..", "\032Zapisuji..", "Zapisuji..") @@ -1153,6 +1155,8 @@ #define TR_MENU_OTHER "Ostatní" #define TR_MENU_INVERT "Invertovat" #define TR_JITTER_FILTER "ADC Filtr" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1165,6 +1169,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/de.h.txt b/radio/src/translations/de.h.txt index 7029f8599..60b84916c 100644 --- a/radio/src/translations/de.h.txt +++ b/radio/src/translations/de.h.txt @@ -52,9 +52,6 @@ #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Stumm""Alarm""NoKey""Alle\0" -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "AUSDGaDGb" - #define LEN_VBLMODE "\005" #define TR_VBLMODE "AUS\0 ""Taste""Stks\0""Beide""EIN\0 " // Anpassung @@ -121,7 +118,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "SHGQ12345LR" + #define TR_RETA123 "SHGQ13245LR" #elif defined(PCBX9E) #define TR_RETA123 "SHGQ1234LRLR" #elif defined(PCBTARANIS) || defined(REVX) @@ -362,7 +359,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Lehrer/SBUS Modul\0" #define TR_VTRAINER_MASTER_CPPM_MODULE "Lehrer/CPPM Modul\0" #define TR_VTRAINER_MASTER_BATTERY "Lehrer/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\015" // "\013" original #define TR_VFAILSAFE "Kein Failsafe""Halte Pos.\0 ""Kanäle\0 ""Kein Signal\0 ""Empfänger\0 " @@ -501,7 +499,7 @@ #define TR_ALARM TR("Alarme ", "Aufleuchten bei Alarm") // 9XR-Pro #define TR_USRDATA "Daten berechnen aus" #define TR_BLADES TR("Prop", "Prop-Blätter") // 9XR-Pro -#define TR_SCREEN "TelmBild " +#define TR_SCREEN "Seite: " #define TR_SOUND_LABEL "Töne" #define TR_LENGTH "Dauer" #define TR_BEEP_LENGTH "Beep-Länge" @@ -523,7 +521,6 @@ #define TR_MODEL_STILL_POWERED "Model still powered" #define TR_MODEL_SHUTDOWN "Shutdown ?" #define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG TR ("Rol", "Drehgeb. Navig.") #define TR_THROTTLE_LABEL "Gas-Kontrolle" #define TR_THROTTLEREVERSE TR("Gas invers", INDENT "Vollgas hinten?") //Änderung wg TH9x, Taranis #define TR_MINUTEBEEP TR("Min-Alarm", "Minuten-Alarm") @@ -578,7 +575,6 @@ #define TR_ACCEL "Acc:" #define TR_NODATA CENTER"Keine Daten" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" #define TR_FREE_STACK "Freier Stack" #define TR_MENUTORESET TR_ENTER " für Reset" @@ -729,7 +725,10 @@ #define TR_POWER_METER_INT "Power Meter (INT)" #define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" -#define TR_SDCARD_FULL "SD-Karte voll" +#define TR_SDCARD_FULL "SD-Karte voll" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Nicht kompatibel" #define TR_WARNING "WARNUNG" #define TR_EEPROMWARN "EEPROM" @@ -743,6 +742,7 @@ #define TR_NIGHTLY_NOTSAFE "Nicht für Flug geeignet" #define TR_WRONG_SDCARDVERSION TR("Erw. Version: ","Erwartete Version: ") #define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATTERY" #define TR_WRONG_PCBREV "Falsche PCB erkannt" #define TR_EMERGENCY_MODE "NOTFALL MODUS" @@ -795,9 +795,9 @@ #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" -#define TR_BLUETOOTH_PIN_CODE TR(INDENT "PIN code", "PIN code") +#define TR_BLUETOOTH_DIST_ADDR "Dist addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Local addr" +#define TR_BLUETOOTH_PIN_CODE "PIN code" #define TR_BAUDRATE "BT Baudrate" #define LEN_BLUETOOTH_MODES "\011" #if defined(PCBX9E) @@ -830,7 +830,9 @@ #define TR_FLASH_POWER_MANAGEMENT_UNIT TR("Flash pwr mngt unit", "Flash power management unit") #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE TR("Flash int. XJT","Flash internes XJT-Modul") +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. mod","Flash extern module") +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Writing..." @@ -1161,10 +1163,13 @@ #define TR_MENU_CHANNELS "\320Kanäle" #define TR_MENU_GVARS "\311Glob. Vars" #define TR_MENU_TELEMETRY "\321Telemetrie" -#define TR_MENU_DISPLAY "DISPLAY" +#define TR_MENU_DISPLAY "TELM-SEITEN" #define TR_MENU_OTHER "Weitere" #define TR_MENU_INVERT "Invertieren" #define TR_JITTER_FILTER "ADC Filter" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" + // ---------------------------------------------------------------- #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1177,6 +1182,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/en.h.txt b/radio/src/translations/en.h.txt index c8ad462d8..6ad2d16fd 100644 --- a/radio/src/translations/en.h.txt +++ b/radio/src/translations/en.h.txt @@ -52,9 +52,6 @@ #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Quiet""Alarm""NoKey""All\0 " -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "No REaREb" - #define LEN_VBLMODE TR("\004", "\010") #define TR_VBLMODE TR("OFF\0""Keys""Ctrl""Both""ON\0 ", "OFF\0 ""Keys\0 ""Controls""Both\0 ""ON\0 ") @@ -121,7 +118,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "RETA12345LR" + #define TR_RETA123 "RETA13245LR" #elif defined(PCBX9E) #define TR_RETA123 "RETA1234LRLR" #elif defined(PCBTARANIS) || defined(REVX) @@ -362,7 +359,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Not set\0 ""Hold\0 ""Custom\0 ""No pulses""Receiver\0" @@ -411,7 +409,6 @@ #if defined(PCBTARANIS) #define TR_POPUPS_ENTER_EXIT TR(TR_EXIT "\010" TR_ENTER, TR_EXIT "\010" "\010" "\010" "\010" TR_ENTER) - #else #define TR_POPUPS_ENTER_EXIT TR_ENTER "\010" TR_EXIT #endif @@ -519,9 +516,8 @@ #define TR_ALARMWARNING "Sound off" #define TR_RSSI_SHUTDOWN_ALARM TR("RSSI shutdown", "Check RSSI on shutdown") #define TR_MODEL_STILL_POWERED "Model still powered" -#define TR_MODEL_SHUTDOWN "Shutdown ?" +#define TR_MODEL_SHUTDOWN "Shutdown?" #define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG "RotEnc Navig" #define TR_THROTTLE_LABEL "Throttle" #define TR_THROTTLEREVERSE TR("T-Reverse", INDENT "Reverse") #define TR_MINUTEBEEP TR("Minute", "Minute call") @@ -575,7 +571,6 @@ #define TR_ACCEL "Acc:" #define TR_NODATA CENTER "NO DATA" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" #define TR_FREE_STACK "Free stack" #define TR_MENUTORESET TR_ENTER " to reset" @@ -728,6 +723,9 @@ #define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" #define TR_SDCARD_FULL "SD card full" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Incompatible" #define TR_WARNING "WARNING" #define TR_EEPROMWARN "EEPROM" @@ -741,6 +739,7 @@ #define TR_NIGHTLY_NOTSAFE "Version not safe to fly" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ", "Expected version: ") #define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATTERY" #define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_EMERGENCY_MODE "EMERGENCY MODE" @@ -792,8 +791,8 @@ #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" +#define TR_BLUETOOTH_DIST_ADDR "Dist addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Local addr" #define TR_BLUETOOTH_PIN_CODE "PIN code" #define TR_BAUDRATE "BT Baudrate" #define LEN_BLUETOOTH_MODES "\011" @@ -828,7 +827,9 @@ #define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" #define TR_CURRENT_VERSION TR("Curr Vers: ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE TR("Flash int. module", "Flash internal module") +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE TR("Flash ext. module", "Flash external module") +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update error", "Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Writing..." @@ -1164,6 +1165,8 @@ #define TR_MENU_OTHER "Other" #define TR_MENU_INVERT "Invert" #define TR_JITTER_FILTER "ADC filter" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1176,6 +1179,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/es.h.txt b/radio/src/translations/es.h.txt index cbe0ef8cc..ef4b98907 100644 --- a/radio/src/translations/es.h.txt +++ b/radio/src/translations/es.h.txt @@ -52,9 +52,6 @@ #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Mudo ""Alarm""NoKey""Todo " -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "No REaREb" - #define LEN_VBLMODE "\004" #define TR_VBLMODE "OFF ""Keys""Stks""Both""ON\0" @@ -121,7 +118,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "RETA12345LR" + #define TR_RETA123 "RETA13245LR" #elif defined(PCBX9E) #define TR_RETA123 "RETA1234LRLR" #elif defined(PCBTARANIS) || defined(REVX) @@ -377,7 +374,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Not set\0 ""Guardar\0 ""Adaptar\0 ""Sin pulso""Receiver\0" @@ -542,7 +540,6 @@ #define TR_MODEL_STILL_POWERED "Model still powered" #define TR_MODEL_SHUTDOWN "Shutdown ?" #define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG "RotEnc Navig" #define TR_THROTTLE_LABEL "Throttle" #define TR_THROTTLEREVERSE TR("Invert_Acel", INDENT "Invertir Acel.") #define TR_MINUTEBEEP TR("Minuto", "Cada Minuto") @@ -591,7 +588,6 @@ #define TR_ACCEL "Acc:" #define TR_NODATA CENTER "SIN DATOS" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" #define TR_FREE_STACK "Free stack" #define TR_MENUTORESET TR_ENTER "Resetear" @@ -752,7 +748,10 @@ #define TR_POWER_METER_INT "Power Meter (INT)" #define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" -#define TR_SDCARD_FULL "SD Card Full" +#define TR_SDCARD_FULL "SD Card Full" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Incompatible" #define TR_WARNING "AVISO" #define TR_EEPROMWARN "EEPROM" @@ -766,6 +765,7 @@ #define TR_NIGHTLY_NOTSAFE "Version not safe to fly" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ") #define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATTERY" #define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_EMERGENCY_MODE "EMERGENCY MODE" @@ -818,8 +818,8 @@ #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" +#define TR_BLUETOOTH_DIST_ADDR "Dist addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Local addr" #define TR_BLUETOOTH_PIN_CODE "PIN code" #define TR_BAUDRATE "BT Baudrate" #define LEN_BLUETOOTH_MODES "\011" @@ -853,7 +853,9 @@ #define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Writing..." @@ -1188,6 +1190,8 @@ #define TR_MENU_OTHER "Other" #define TR_MENU_INVERT "Invert" #define TR_JITTER_FILTER "ADC Filter" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1200,6 +1204,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/fi.h.txt b/radio/src/translations/fi.h.txt index 37887689f..14cf934f9 100644 --- a/radio/src/translations/fi.h.txt +++ b/radio/src/translations/fi.h.txt @@ -52,9 +52,6 @@ #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Äänet""Hälyt""EiNap""Kaikk" -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "No REaREb" - #define LEN_VBLMODE TR("\004", "\010") #define TR_VBLMODE TR("OFF\0""Keys""Ctrl""Both""ON\0 ", "OFF\0 ""Keys\0 ""Controls""Both\0 ""ON\0 ") @@ -121,7 +118,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "RETA12345LR" + #define TR_RETA123 "RETA13245LR" #elif defined(PCBX9E) #define TR_RETA123 "RETA1234LRLR" #elif defined(PCBTARANIS) || defined(REVX) @@ -377,7 +374,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Not set\0 ""Hold\0 ""Custom\0 ""No pulses""Receiver\0" @@ -534,7 +532,6 @@ #define TR_MODEL_STILL_POWERED "Model still powered" #define TR_MODEL_SHUTDOWN "Shutdown ?" #define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG "RotEnc Navig" #define TR_THROTTLE_LABEL "Throttle" #define TR_THROTTLEREVERSE TR("T-Reverse", INDENT "Throttle reverse") #define TR_MINUTEBEEP TR("Minute", "Minute call") @@ -583,7 +580,6 @@ #define TR_ACCEL "Acc:" #define TR_NODATA CENTER "NO DATA" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" #define TR_FREE_STACK "Free stack" @@ -746,7 +742,10 @@ #define TR_POWER_METER_INT "Power Meter (INT)" #define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" -#define TR_SDCARD_FULL "SD Card Full" +#define TR_SDCARD_FULL "SD Card Full" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Incompatible" #define TR_WARNING "WARNING" #define TR_EEPROMWARN "FINSKA" @@ -760,6 +759,7 @@ #define TR_NIGHTLY_NOTSAFE "Version not safe to fly" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ") #define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATTERY" #define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_EMERGENCY_MODE "EMERGENCY MODE" @@ -812,8 +812,8 @@ #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" +#define TR_BLUETOOTH_DIST_ADDR "Dist addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Local addr" #define TR_BLUETOOTH_PIN_CODE "PIN code" #define TR_BAUDRATE "BT Baudrate" #define LEN_BLUETOOTH_MODES "\011" @@ -847,7 +847,9 @@ #define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Writing..." @@ -1176,6 +1178,8 @@ #define TR_MENU_OTHER "Other" #define TR_MENU_INVERT "Invert" #define TR_JITTER_FILTER "ADC Filter" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1188,6 +1192,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/fr.h.txt b/radio/src/translations/fr.h.txt index 23b867cba..02066d245 100644 --- a/radio/src/translations/fr.h.txt +++ b/radio/src/translations/fr.h.txt @@ -52,11 +52,8 @@ #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Aucun""Alarm""NoKey""Tout\0" -#define LEN_COUNTDOWNVALUES "\003" -#define TR_COUNTDOWNVALUES "5s\0""10s""20s""30s" - -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "NonREaREb" +#define LEN_COUNTDOWNVALUES "\003" +#define TR_COUNTDOWNVALUES "5s\0""10s""20s""30s" #define LEN_VBLMODE TR("\004", "\011") #define TR_VBLMODE TR("OFF\0""Btns""Ctrl""Tous""ON\0","OFF\0 ""Touches\0 ""Controles""Tous\0 ""ON\0 ") @@ -121,7 +118,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "DPGA12345LR" + #define TR_RETA123 "DPGA13245LR" #elif defined(PCBX9E) #define TR_RETA123 "DPGA1234LRLR" #elif defined(PCBTARANIS) || defined(REVX) @@ -379,7 +376,8 @@ #define TR_VTRAINER_MASTER_SBUS_MODULE "Maître/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Maître/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Maître/Série\0 " -#define TR_VTRAINER_BLUETOOTH TR("Maître/BT\0 ""Elève/BT\0", "Maître/Bluetooth\0 ""Elève/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Maître/BT\0 ""Elève/BT\0 ", "Maître/Bluetooth\0 ""Elève/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE TR("Pas déf.\0""Maintien\0""Prédéf.\0 ""Pas d'imp""Récepteur", "Pas déf.\0""Maintien\0""Prédéfini""Pas d'imp""Récepteur") @@ -462,10 +460,10 @@ #endif #define TR_PROTO TR(INDENT "Proto.", INDENT "Protocole") #define TR_PPMFRAME INDENT "Trame PPM" -#define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") -#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") +#define TR_REFRESHRATE INDENT "Période" +#define STR_WARN_BATTVOLTAGE TR(INDENT "Signal est VBAT: ", INDENT "ATTENTION: signal est à VBAT: ") #define TR_MS "ms" -#define TR_FREQUENCY INDENT "Frequency" +#define TR_FREQUENCY INDENT "Fréquence" #define TR_SWITCH TR("Inter", "Interrupteur") #define TR_TRIMS "Trims" #define TR_FADEIN "Fondu ON" @@ -485,12 +483,12 @@ #define TR_SUBTYPE INDENT "Sous-type" #define TR_NOFREEEXPO "Max expos atteint!" #define TR_NOFREEMIXER "Max mixages atteint!" -#define TR_SOURCE "Source" +#define TR_SOURCE "Source" #define TR_WEIGHT "Ratio" #define TR_EXPO TR("Expo", "Exponentiel") #define TR_SIDE "Coté" #define TR_DIFFERENTIAL "Différentiel" -#define TR_OFFSET "Décalage" +#define TR_OFFSET "Décalage" #define TR_TRIM "Trim" #define TR_DREX "DRex" #define DREX_CHBOX_OFFSET 30 @@ -498,8 +496,8 @@ #define TR_FLMODE TR("Phase", "Phases") #define TR_MIXWARNING "Alerte" #define TR_OFF "OFF" -#define TR_ANTENNA "Antenna" -#define TR_NO_INFORMATION TR("No info", "No information") +#define TR_ANTENNA "Antenne" +#define TR_NO_INFORMATION TR("Pas d'info", "Pas d'information") #define TR_MULTPX "Opération" #define TR_DELAYDOWN "Retard bas" #define TR_DELAYUP "Retard haut" @@ -527,7 +525,7 @@ #define TR_HAPTIC_LABEL "Vibreur" #define TR_STRENGTH "Force" #define TR_GYRO_LABEL "Gyro" -#define TR_GYRO_OFFSET "Offset" +#define TR_GYRO_OFFSET "Décalage" #define TR_GYRO_MAX "Max" #define TR_CONTRAST "Contraste" #define TR_ALARMS_LABEL "Alarmes" @@ -541,7 +539,6 @@ #define TR_MODEL_STILL_POWERED TR("Modèle allumé", "Modèle encore allumé") #define TR_MODEL_SHUTDOWN "Eteindre ?" #define TR_PRESS_ENTER_TO_CONFIRM "Presser [Enter] pour confirmer" -#define TR_RENAVIG "Navig EncRot" #define TR_THROTTLE_LABEL "Gaz" #define TR_THROTTLEREVERSE TR("Inv. gaz", INDENT "Inversion gaz") #define TR_MINUTEBEEP TR("Bip min.", "Annonces minutes") @@ -552,8 +549,8 @@ #define TR_BLOFFBRIGHTNESS "Luminosité OFF" #define TR_BLCOLOR "Couleur" #define TR_SPLASHSCREEN "Logo d'accueil" -#define TR_PWR_ON_DELAY "Pwr On delay" -#define TR_PWR_OFF_DELAY "Pwr Off delay" +#define TR_PWR_ON_DELAY "Délai btn ON" +#define TR_PWR_OFF_DELAY "Délai btn OFF" #define TR_THROTTLE_WARNING TR(INDENT "Alerte gaz", INDENT "Alerte gaz") #define TR_SWITCHWARNING TR(INDENT "Alerte int", INDENT "Pos. interrupteurs") #define TR_POTWARNINGSTATE TR(INDENT "Pot&Slid.", INDENT "Pots & sliders") @@ -593,12 +590,11 @@ #define OFS_RX 4 #define TR_ACCEL "Acc:" #define TR_NODATA CENTER "NO DATA" -#define TR_US "us" +#define TR_US "us" #define TR_TMR1LATMINUS "Tmr1Lat min\037\124us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" - #define TR_TMIXMAXMS "Tmix max" - #define TR_FREE_STACK "Free stack" +#define TR_TMIXMAXMS "Tmix max" +#define TR_FREE_STACK "Free stack" #define TR_MENUTORESET TR_ENTER" pour reset" #define TR_PPM_TRAINER "TR" @@ -662,8 +658,8 @@ #define TR_MULTI_RFTUNE TR(INDENT "Ajust.fréq", INDENT "Ajustement fréq.") #define TR_MULTI_TELEMETRY "Télémétrie" #define TR_MULTI_VIDFREQ TR(INDENT "Fréq. vidéo", INDENT "Fréquence vidéo") -#define TR_RF_POWER TR(INDENT "Puiss. RF", INDENT "Puissance RF") -#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") +#define TR_RF_POWER TR(INDENT "Puiss. RF", INDENT "Puissance RF") +#define TR_MULTI_FIXEDID "ID fixe" #define TR_MULTI_OPTION TR(INDENT "Option", INDENT "Option perso") #define TR_MULTI_AUTOBIND TR(INDENT "Bind auto", INDENT "Bind automatique") #define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodét.", INDENT "Autodétection") @@ -718,38 +714,41 @@ #define TR_CAT_NOT_EMPTY "Categorie non vide" #define TR_SDCARD_ERROR "Erreur carte SD" #define TR_NO_SDCARD "Carte SD indisponible" -#define TR_WAITING_FOR_RX "Waiting for RX..." -#define TR_WAITING_FOR_TX "Waiting for TX..." -#define TR_NO_TOOLS "No tools available" +#define TR_WAITING_FOR_RX "Attente du RX..." +#define TR_WAITING_FOR_TX "Attente du TX..." +#define TR_NO_TOOLS "Pas d'outils dispo" #define TR_NORMAL "Normal" -#define TR_NOT_INVERTED "Not inv" -#define TR_NOT_CONNECTED "!Connected" -#define TR_CONNECTED "Connected" +#define TR_NOT_INVERTED "Non inv" +#define TR_NOT_CONNECTED "!Connecté" +#define TR_CONNECTED "Connecté" #define TR_FLEX_915 "Flex 915MHz" #define TR_FLEX_868 "Flex 868MHz" -#define TR_16CH_WITHOUT_TELEMETRY TR("16CH without telem.", "16CH without telemetry") -#define TR_16CH_WITH_TELEMETRY TR("16CH with telem.", "16CH with telemetry") -#define TR_8CH_WITH_TELEMETRY TR("8CH with telem.", "8CH with telemetry") -#define TR_EXT_ANTENNA "Ext. antenna" +#define TR_16CH_WITHOUT_TELEMETRY TR("16CH sans télém.", "16CH sans télémétrie") +#define TR_16CH_WITH_TELEMETRY TR("16CH avec télém.", "16CH avec télémétrie") +#define TR_8CH_WITH_TELEMETRY TR("8CH avec télém.", "8CH avec télémétrie") +#define TR_EXT_ANTENNA "Antenne externe" #define TR_PIN "Pin" -#define TR_UPDATE_RX_OPTIONS "Update RX options?" -#define TR_UPDATE_TX_OPTIONS "Update TX options?" -#define TR_MODULES_RX_VERSION "Modules / RX version" -#define TR_MENU_MODULES_RX_VERSION "MODULES / RX VERSION" -#define TR_MENU_FIRM_OPTIONS "FIRMWARE OPTIONS" +#define TR_UPDATE_RX_OPTIONS "Sauver options RX?" +#define TR_UPDATE_TX_OPTIONS "Sauver options TX?" +#define TR_MODULES_RX_VERSION "Versions modules / RX" +#define TR_MENU_MODULES_RX_VERSION "VERSIONS MODULES / RX " +#define TR_MENU_FIRM_OPTIONS "OPTIONS FIRMWARE" #define TR_GYRO "Gyro" -#define TR_STICKS_POTS_SLIDERS "Sticks/Pots/Sliders" -#define TR_PWM_STICKS_POTS_SLIDERS "PWM Sticks/Pots/Sliders" -#define TR_RF_PROTOCOL "RF Protocol" -#define TR_MODULE_OPTIONS "Module options" -#define TR_POWER "Power" -#define TR_NO_TX_OPTIONS "No TX options" -#define TR_RTC_BATT "RTC Batt" -#define TR_POWER_METER_EXT "Power Meter (EXT)" -#define TR_POWER_METER_INT "Power Meter (INT)" -#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" -#define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" +#define TR_STICKS_POTS_SLIDERS "Manches/Pots/leviers" +#define TR_PWM_STICKS_POTS_SLIDERS "Manches PWM/Pots/leviers" +#define TR_RF_PROTOCOL "Protocole RF" +#define TR_MODULE_OPTIONS "Options module" +#define TR_POWER "Puissance" +#define TR_NO_TX_OPTIONS "Pas d'options TX" +#define TR_RTC_BATT "Pile RTC" +#define TR_POWER_METER_EXT "Puissancemètre (EXT)" +#define TR_POWER_METER_INT "Puissancemètre (INT)" +#define TR_SPECTRUM_ANALYSER_EXT TR("Spectre (EXT)", "Analyseur spectre (EXT)") +#define TR_SPECTRUM_ANALYSER_INT TR("Spectre (INT)", "Analyseur spectre (INT)") #define TR_SDCARD_FULL "Carte SD pleine" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Incompatible" #define TR_WARNING "ALERTE" #define TR_EEPROMWARN "EEPROM" @@ -762,8 +761,9 @@ #define TR_NIGHTLY_WARNING TR("NIGHTLY", "NIGHTLY BUILD") #define TR_NIGHTLY_NOTSAFE "Version de test uniq." #define TR_WRONG_SDCARDVERSION "Version requise: " -#define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" -#define TR_BATTERY "BATTERY" +#define TR_WARN_RTC_BATTERY_LOW "Batterie RTC faible" +#define TR_WARN_MULTI_LOWPOWER "Mode basse puis." +#define TR_BATTERY "BATTERIE" #define TR_WRONG_PCBREV "PCB incorrect détecté" #define TR_EMERGENCY_MODE "MODE SECOURS" #define TR_PCBREV_ERROR "Erreur PCB" @@ -812,11 +812,11 @@ #define TR_TIME "Heure" #define TR_MAXBAUDRATE "Max bauds" #define TR_BLUETOOTH "Bluetooth" -#define TR_BLUETOOTH_DISC "Discover" +#define TR_BLUETOOTH_DISC "Découvrir" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" -#define TR_BLUETOOTH_PIN_CODE "PIN code" +#define TR_BLUETOOTH_DIST_ADDR "Addr dist." +#define TR_BLUETOOTH_LOCAL_ADDR "Addr locale" +#define TR_BLUETOOTH_PIN_CODE "Code PIN" #define TR_BAUDRATE "Baudrate BT" #define LEN_BLUETOOTH_MODES "\012" #if defined(PCBX9E) @@ -844,27 +844,29 @@ #define TR_VIEW_TEXT "Voir texte" #define TR_FLASH_BOOTLOADER "Flasher BootLoader" #define TR_FLASH_EXTERNAL_DEVICE TR("Flasher S.Port", "Flasher S.Port externe") -#define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" -#define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") -#define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" +#define TR_FLASH_RECEIVER_OTA "Flasher RX OTA" +#define TR_FLASH_BLUETOOTH_MODULE TR("Flash module BT", "Flash module Bluetooth") +#define TR_FLASH_POWER_MANAGEMENT_UNIT "Flasher pwr mngt unit" #define TR_CURRENT_VERSION "Version courante :" #define TR_FLASH_INTERNAL_MODULE TR("Flasher module int.", "Flasher module interne") +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE TR("Flasher module ext.", "Flasher module externe") +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("Erreur màj FW","Erreur de mise à jour") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash ok" #define TR_WRITING TR("\14Ecriture...", "\032Ecriture...") #define TR_CONFIRM_FORMAT "Confirmer Formatage?" #define TR_INTERNALRF "HF interne" -#define TR_INTERNAL_MODULE TR("Int. module","Internal module") -#define TR_EXTERNAL_MODULE TR("Ext. module","External module") -#define TR_OPENTX_UPGRADE_REQUIRED "OpenTX upgrade required" -#define TR_TELEMETRY_DISABLED "Telem. disabled" -#define TR_MORE_OPTIONS_AVAILABLE "More options available" -#define TR_NO_MODULE_INFORMATION "No module information" +#define TR_INTERNAL_MODULE TR("Module int.","Module interne") +#define TR_EXTERNAL_MODULE TR("Module ext.","Module externe") +#define TR_OPENTX_UPGRADE_REQUIRED "Màj OpenTX nécessaire" +#define TR_TELEMETRY_DISABLED "Télém. désactivée" +#define TR_MORE_OPTIONS_AVAILABLE "Autres options disponibles" +#define TR_NO_MODULE_INFORMATION "Pas d'info module" #define TR_EXTERNALRF "HF externe" #define TR_FAILSAFE TR(INDENT "Failsafe", INDENT "Type failsafe") #define TR_FAILSAFESET "REGLAGES FAILSAFE" -#define TR_REG_ID TR("ID Enr.", "ID Enregisrement") +#define TR_REG_ID TR("ID Enr.", "ID Enregistr.") #define TR_OWNER_ID "ID Radio" #define TR_PINMAPSET "PINMAP" #define TR_HOLD "Hold" @@ -920,7 +922,7 @@ #define TR_PXX2_SELECT_RX "Sélect RX..." #define TR_PXX2_DEFAULT "" #define TR_BT_SELECT_DEVICE "Sélect appareil..." -#define TR_DISCOVER "Découvrir" +#define TR_DISCOVER "Découvrir" #define TR_BUTTON_INIT BUTTON("Init") #define TR_WAITING "Attente..." #define TR_RECEIVER_DELETE "Suppr récept.?" @@ -929,8 +931,8 @@ #define TR_BIND "Bind" #define TR_REGISTER TR("Enr", "Enregistr.") #define TR_MODULE_RANGE BUTTON(TR("Prt", "Port.")) -#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") -#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) +#define TR_RECEIVER_OPTIONS TR("OPTIONS REC.", "OPTIONS RECEPTEUR") +#define TR_DEL_BUTTON BUTTON(TR("Eff", "Effacer")) #define TR_RESET_BTN BUTTON("RAZ") #define TR_DEBUG "Debug" #define TR_KEYS_BTN BUTTON(TR("Btns","Inters")) @@ -953,18 +955,18 @@ #define TR_ANTENNACONFIRM1 "Vraiment changer?" #if defined(PCBX12S) #define LEN_ANTENNA_MODES "\021" -#define TR_ANTENNA_MODES "Interne\0 ""Ask\0 ""Par modèle\0 ""Interne + Externe" +#define TR_ANTENNA_MODES "Interne\0 ""Demander\0 ""Par modèle\0 ""Interne + Externe" #else -#define LEN_ANTENNA_MODES "\011" -#define TR_ANTENNA_MODES "Internal\0""Ask\0 ""Per model""External" +#define LEN_ANTENNA_MODES "\012" +#define TR_ANTENNA_MODES "Interne\0 ""Demander\0 ""Par modèle""Externe\0 " #endif -#define TR_USE_INTERNAL_ANTENNA TR("Use int. antenna", "Use internal antenna") -#define TR_USE_EXTERNAL_ANTENNA TR("Use ext. antenna", "Use external antenna") +#define TR_USE_INTERNAL_ANTENNA TR("Util antenne int", "Utiliser antenne interne") +#define TR_USE_EXTERNAL_ANTENNA TR("Util antenne ext", "Utiliser antenne externe") #define TR_ANTENNACONFIRM2 TR("Vérif antenne", "Installer l'antenne d'abord!") -#define TR_MODULE_PROTOCOL_FLEX_WARN_LINE1 "Nécessite firm." -#define TR_MODULE_PROTOCOL_FCC_WARN_LINE1 "Requires FCC" -#define TR_MODULE_PROTOCOL_EU_WARN_LINE1 "Requires EU" -#define TR_MODULE_PROTOCOL_WARN_LINE2 "R9M non certifié" +#define TR_MODULE_PROTOCOL_FLEX_WARN_LINE1 "Nécessite firm." +#define TR_MODULE_PROTOCOL_FCC_WARN_LINE1 "Nécessite FCC" +#define TR_MODULE_PROTOCOL_EU_WARN_LINE1 "Nécessite EU" +#define TR_MODULE_PROTOCOL_WARN_LINE2 "R9M non certifié" #define TR_LOWALARM INDENT "Alarme basse" #define TR_CRITICALALARM INDENT "Alarme critique" #define TR_RSSIALARM_WARN TR("RSSI", "TELEMETRIE") @@ -995,7 +997,7 @@ #define TR_PREFLIGHT "Vérifications avant vol" #define TR_CHECKLIST TR(INDENT "Notes", INDENT "Afficher notes") #define TR_FAS_OFFSET TR(INDENT "Corr FAS", INDENT "Correction FAS") -#define TR_AUX_SERIAL_MODE "Port série" +#define TR_AUX_SERIAL_MODE "Port série" #define TR_SCRIPT "Script" #define TR_INPUTS "Entrées" #define TR_OUTPUTS "Sorties" @@ -1189,6 +1191,8 @@ #define TR_MENU_OTHER "Autres" #define TR_MENU_INVERT "Inverser" #define TR_JITTER_FILTER "Filtre ADC" +#define TR_RTC_CHECK TR("Vérif. RTC", "Vérif. pile RTC") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1201,6 +1205,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/it.h.txt b/radio/src/translations/it.h.txt index 1f3ec0059..6462392fc 100644 --- a/radio/src/translations/it.h.txt +++ b/radio/src/translations/it.h.txt @@ -20,6 +20,7 @@ */ // IT translations author: Romolo Manfredini +// IT integrations for OpenTX V2.3.x author: Marco Robustini /* * !!!!! DO NOT EDIT it.h - EDIT it.h.txt INSTEAD !!!!!!! @@ -52,9 +53,6 @@ #define LEN_VBEEPMODE TR("\005", "\010") #define TR_VBEEPMODE TR("Silen""Avvis""Notst""Tutti","Silente ""Avvisi\0 ""No Tasti""Tutti\0 ") -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "No REaREb" - #define LEN_VBLMODE TR("\005", "\006") #define TR_VBLMODE TR("OFF\0 ""Tasti""Stks\0""Tutti""ON\0 ", "Spenta""Tasti\0""Sticks""Tutti\0""Accesa") @@ -72,13 +70,13 @@ #endif #define LEN_SWTYPES "\006" -#define TR_SWTYPES "None\0 ""Toggle""2POS\0 ""3POS\0" +#define TR_SWTYPES "Dis.\0 ""Toggle""2POS\0 ""3POS\0" #define LEN_POTTYPES TR("\013","\017") -#define TR_POTTYPES TR("None\0 ""Pot w. det\0""Multipos\0 ""Pot\0 ", "None\0 ""Pot. con centro""Inter. Multipos""Potenziometro\0 ") +#define TR_POTTYPES TR("Dis.\0 ""Pot c. fer\0""Multipos\0 ""Pot\0 ", "Dis.\0 ""Pot. con centro""Inter. Multipos""Potenziometro\0 ") #define LEN_SLIDERTYPES "\006" -#define TR_SLIDERTYPES "Niente""Slider" +#define TR_SLIDERTYPES "Disat.""Slider" #define LEN_VLCD "\006" #define TR_VLCD "NormalOptrex" @@ -90,18 +88,18 @@ #define TR_COUNTRY_CODES TR("US""JP""EU", "America""Japan\0 ""Europa\0") #define LEN_USBMODES TR("\006", "\010") -#define TR_USBMODES TR("Ask\0 ""Joyst\0""SDCard""Serial", "Ask\0 ""Joystick""Storage\0""Serial\0 ") +#define TR_USBMODES TR("Chied\0""Joyst\0""SDCard""Serial", "Chiedi\0 ""Joystick""Storage\0""Seriale\0 ") #define LEN_MODULE_PROTOCOLS "\004" #define TR_MODULE_PROTOCOLS "OFF\0""PPM\0""XJT\0""XJT2""DSM2""CRSF""MULT""R9M\0""R9M2""SBUS" #define LEN_JACK_MODES "\007" -#define TR_JACK_MODES "Ask\0 ""Audio\0 ""Trainer" +#define TR_JACK_MODES "Chiedi\0 ""Audio\0 ""Trainer" #define LEN_TELEMETRY_PROTOCOLS "\017" #define TR_TELEMETRY_PROTOCOLS "FrSky S.PORT\0 ""FrSky D\0 ""FrSky D (cable)""TBS Crossfire\0 ""Spektrum\0 ""AFHDS2A IBUS\0 ""Multi Telemetry" -#define TR_MULTI_CUSTOM "Custom" +#define TR_MULTI_CUSTOM "Person." #define LEN_VTRIMINC "\006" #define TR_VTRIMINC "Exp ""ExFine""Fine ""Medio ""Ampio " @@ -116,7 +114,7 @@ #define TR_COUNTDOWNVALUES "5s\0""10s""20s""30s" #define LEN_VVARIOCENTER "\006" -#define TR_VVARIOCENTER "Tono\0 ""Silent" +#define TR_VVARIOCENTER "Tono\0 ""Silenz." #define LEN_CURVE_TYPES "\010" #define TR_CURVE_TYPES "Fisso\0 ""Modific." @@ -124,7 +122,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "DEMA12345LR" + #define TR_RETA123 "DEMA13245LR" #elif defined(PCBX9E) #define TR_RETA123 "DEMA123SDSD" #elif defined(PCBTARANIS) || defined(REVX) @@ -211,9 +209,9 @@ #define TR_SF_BG_MUSIC "Musica Sf\0 ""Musica Sf ||\0" #if defined(SDCARD) - #define TR_SDCLOGS "SDCARD Logs\0 " + #define TR_SDCLOGS "Logs SDCard\0 " #else - #define TR_SDCLOGS "[SDCARD Logs]\0" + #define TR_SDCLOGS "[Logs SDCard]\0" #endif #if defined(GVARS) @@ -382,8 +380,9 @@ #define TR_VTRAINER_SLAVE_JACK "Allievo/Jack\0 " #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/Modulo SBUS" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/Modulo CPPM" -#define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MASTER_BATTERY "Master/Seriale\0 " +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\013" #define TR_VFAILSAFE "Non settato""Mantieni\0 ""Personali\0 ""No impulsi\0""Ricevente\0 " @@ -439,54 +438,54 @@ #endif #define TR_MENUWHENDONE CENTER "\007" TR_ENTER " Conferma" -#define TR_FREE "disp" -#define TR_DELETEMODEL "Elimina modello?" +#define TR_FREE "Disp." +#define TR_DELETEMODEL "CANCELLA" BREAKSPACE "MODELLO" #define TR_COPYINGMODEL "Copia in corso.." #define TR_MOVINGMODEL "Spostamento..." #define TR_LOADINGMODEL "Caricamento..." #define STR_NAME "Nome" -#define TR_MODELNAME "Nome modello" +#define TR_MODELNAME TR("Nome Mode.", "Nome Modello") #define TR_PHASENAME "Nome fase" #define TR_MIXNAME "Nome mix" #define TR_INPUTNAME "Nome Ingr." #define TR_EXPONAME "Nome expo" #define TR_BITMAP "Immagine" -#define TR_TIMER TR("Timer","Timer ") +#define TR_TIMER TR("Timer", "Timer ") #define TR_START "Start" -#define TR_ELIMITS TR("Limiti.E","Limiti Estesi") -#define TR_ETRIMS TR("Trim Ext","Trim Estesi") +#define TR_ELIMITS TR("Limiti.E", "Limiti Estesi") +#define TR_ETRIMS TR("Trim Ext", "Trim Estesi") #define TR_TRIMINC "Passo Trim" -#define TR_DISPLAY_TRIMS "Mostra Trims" -#define TR_TTRACE TR("T-Source", INDENT "Sorgente Motore") -#define TR_TTRIM TR("T-Trim", INDENT "Trim Motore") -#define TR_BEEPCTR TR("Ctr Beep","Beep al centro") -#define TR_USE_GLOBAL_FUNCS "Usa Funz Globali" +#define TR_DISPLAY_TRIMS TR("Mos. Trims", "Mostra Trims") +#define TR_TTRACE TR("So. motore", INDENT "Sorgente Motore") +#define TR_TTRIM TR("Trim Mot.", INDENT "Trim Motore") +#define TR_BEEPCTR TR("Beep al c.", "Beep al centro") +#define TR_USE_GLOBAL_FUNCS "Usa Funz. Globali" #if defined(PCBSKY9X) && defined(REVX) - #define TR_OUTPUT_TYPE INDENT "Output" + #define TR_OUTPUT_TYPE INDENT "Uscita" #endif -#define TR_PROTO TR(INDENT "Proto", INDENT "Protocollo") - #define TR_PPMFRAME INDENT "PPM frame" +#define TR_PROTO TR(INDENT "Protoc.", INDENT "Protocollo") + #define TR_PPMFRAME INDENT "Frame PPM" #define TR_REFRESHRATE TR(INDENT "Refresh", INDENT "Refresh rate") -#define STR_WARN_BATTVOLTAGE TR(INDENT "Output is VBAT: ", INDENT "Warning: output level is VBAT: ") +#define STR_WARN_BATTVOLTAGE TR(INDENT "Uscita VBAT: ", INDENT "Att.: livel. uscita VBAT: ") #define TR_MS "ms" -#define TR_FREQUENCY INDENT "Frequency" +#define TR_FREQUENCY INDENT "Frequenza" #define TR_SWITCH "Inter." #define TR_TRIMS "Trims" #define TR_FADEIN "Diss.In" #define TR_FADEOUT "Diss.Out" #define TR_DEFAULT "(Predefinita)" -#define TR_CHECKTRIMS CENTER "\006Check\012Trims" +#define TR_CHECKTRIMS CENTER "\006Contr.\012Trims" #define OFS_CHECKTRIMS CENTER_OFS+(9*FW) #define TR_SWASHTYPE "Tipo Ciclico" -#define TR_COLLECTIVE TR("Collettivo","Origine Collettivo") -#define TR_AILERON TR("Lateral cyc.", "Lateral cyc. source") -#define TR_ELEVATOR TR("Long. cyc.", "Long. cyc. source") +#define TR_COLLECTIVE TR("Collettivo", "Origine Collettivo") +#define TR_AILERON TR("Cic. later.", "Sorg. cic. later.") +#define TR_ELEVATOR TR("Cic. long.", "Sorg. cic. long.") #define TR_SWASHRING "Anello Ciclico" -#define TR_ELEDIRECTION TR("Direzione ELE","Direzione Long. cyc.") -#define TR_AILDIRECTION TR("Direzione AIL","Direzione Lateral cyc.") -#define TR_COLDIRECTION TR("Direzione PIT","Direzione Coll. Passo") +#define TR_ELEDIRECTION TR("Direzione ELE", "Direzione cic. long.") +#define TR_AILDIRECTION TR("Direzione AIL", "Direzione cic. lat.") +#define TR_COLDIRECTION TR("Direzione PIT", "Direzione passo coll.") #define TR_MODE "Modo" -#define TR_SUBTYPE INDENT "Subtype" +#define TR_SUBTYPE INDENT "Sottotipo" #define TR_NOFREEEXPO "Expo pieni!" #define TR_NOFREEMIXER "Mixer pieni!" #define TR_SOURCE "Sorg." @@ -499,16 +498,16 @@ #define TR_DREX "DRex" #define DREX_CHBOX_OFFSET 30 #define TR_CURVE "Curva" -#define TR_FLMODE "Fase" +#define TR_FLMODE TR("Fase", "Fasi") #define TR_MIXWARNING "Avviso" #define TR_OFF "OFF" -#define TR_ANTENNA "Antenna" -#define TR_NO_INFORMATION TR("No info", "No information") +#define TR_ANTENNA "Antenna" +#define TR_NO_INFORMATION TR("No info", "No informazione") #define TR_MULTPX "MultPx" #define TR_DELAYDOWN "Post.Giù " -#define TR_DELAYUP "Post.Sù" +#define TR_DELAYUP "Post.Su" #define TR_SLOWDOWN "Rall.Giù " -#define TR_SLOWUP "Rall.Sù" +#define TR_SLOWUP "Rall.Su" #define TR_MIXER "MIXER" #define TR_CV "CV" #if defined(PCBNV14) @@ -517,59 +516,58 @@ #define TR_GV TR("G", "GV") #endif #define TR_ACHANNEL "A\002ingresso" -#define TR_RANGE TR(INDENT"Inter.", INDENT"Intervallo") +#define TR_RANGE TR(INDENT "Inter.", INDENT "Intervallo") #define TR_CENTER INDENT "Centro" #define TR_BAR "Barra" -#define TR_ALARM TR("Allar.", "Allarme") +#define TR_ALARM TR( "Allar.", "Allarme") #define TR_USRDATA "Dati" -#define TR_BLADES "Pale" -#define TR_SCREEN "Schermo " +#define TR_BLADES "Pale" +#define TR_SCREEN "Schermo\001" #define TR_SOUND_LABEL "Suono" -#define TR_LENGTH "Durata" +#define TR_LENGTH "Durata" #define TR_BEEP_LENGTH "Lung. Beep" #define TR_BEEP_PITCH "Tono" -#define TR_HAPTIC_LABEL "Vibraz" +#define TR_HAPTIC_LABEL "Vibrazione" #define TR_STRENGTH "Forza" #define TR_GYRO_LABEL "Gyro" #define TR_GYRO_OFFSET "Offset" #define TR_GYRO_MAX "Max" #define TR_CONTRAST "Contrasto" #define TR_ALARMS_LABEL "Allarmi" -#define TR_BATTERY_RANGE TR("Interv. Batt", "Intervallo batteria") -#define TR_BATTERYWARNING "Avviso batteria" -#define TR_INACTIVITYALARM "Inattivita'" -#define TR_MEMORYWARNING "Avviso memoria" -#define TR_ALARMWARNING "Spegni suono" -#define TR_RSSI_SHUTDOWN_ALARM TR("Rssi Shutdown", "Check Rssi on Shutdown") -#define TR_MODEL_STILL_POWERED "Model still powered" -#define TR_MODEL_SHUTDOWN "Shutdown ?" -#define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG "Navig EncRot " +#define TR_BATTERY_RANGE TR("Int. Batt.", "Intervallo batteria") +#define TR_BATTERYWARNING TR(INDENT "Avv. Batt.", INDENT "Avviso Batteria") +#define TR_INACTIVITYALARM INDENT "Inattività" +#define TR_MEMORYWARNING TR(INDENT "Avv. Mem.", INDENT "Avviso Memoria") +#define TR_ALARMWARNING INDENT "Spegni suono" +#define TR_RSSISHUTDOWNALARM TR(INDENT "RSSI Shut.", INDENT "Control. RSSI al Shutdown") +#define TR_MODEL_STILL_POWERED "Ricevente ancora connessa" +#define TR_MODEL_SHUTDOWN "Shutdown?" +#define TR_PRESS_ENTER_TO_CONFIRM "Premi [ENT] per confermare" #define TR_THROTTLE_LABEL "Motore" -#define TR_THROTTLEREVERSE TR("Mot inv.", INDENT "Motore Inverso") +#define TR_THROTTLEREVERSE TR("Mot inv.", "Motore Inverso") #define TR_MINUTEBEEP "Minuto" -#define TR_BEEPCOUNTDOWN TR(INDENT"Conto rov", INDENT"Conto rovescia") -#define TR_PERSISTENT TR(INDENT"Persist.", INDENT"Persistente") -#define TR_BACKLIGHT_LABEL TR("Retroillum.", "Retroilluminazione") -#define TR_BLONBRIGHTNESS TR("Lumin. ON", "Luminosità ON") -#define TR_BLOFFBRIGHTNESS TR("Lumin. OFF", "Luminosità OFF") +#define TR_BEEPCOUNTDOWN TR(INDENT "Conto rov", INDENT "Conto rovescia") +#define TR_PERSISTENT TR(INDENT "Persist.", INDENT "Persistente") +#define TR_BACKLIGHT_LABEL TR("Retroillu.", "Retroilluminazione") +#define TR_BLONBRIGHTNESS TR("Lumin. ON", "Luminosità ON") +#define TR_BLOFFBRIGHTNESS TR("Lumin. OFF", "Luminosità OFF") #define TR_BLCOLOR "Colore" -#define TR_SPLASHSCREEN TR("Schermo avvio", "Schermata di avvio") -#define TR_PWR_ON_DELAY "Pwr On delay" -#define TR_PWR_OFF_DELAY "Pwr Off delay" -#define TR_THROTTLE_WARNING TR("All. Mot.", INDENT "Allarme Motore") -#define TR_SWITCHWARNING TR("Avv. Int.", INDENT "Avviso Interr.") +#define TR_SPLASHSCREEN TR("Sch. avvio", "Schermata d'avvio") +#define TR_PWR_ON_DELAY "Rit. accens." +#define TR_PWR_OFF_DELAY "Rit. spegni." +#define TR_THROTTLE_WARNING TR(INDENT "All. Mot.", INDENT "Allarme Motore") +#define TR_SWITCHWARNING TR(INDENT "Avv. Int.", INDENT "Avviso Interr.") #define TR_POTWARNINGSTATE TR(INDENT "Pot&Slid.", INDENT "Pots & sliders") -#define TR_SLIDERWARNING TR(INDENT "Slid. pos.", INDENT "Slider positions") -#define TR_POTWARNING TR("Avv. Pot.", INDENT "Avviso Pot.") +#define TR_SLIDERWARNING TR(INDENT "Pos. slid.", INDENT "Posizione slider") +#define TR_POTWARNING TR(INDENT "Avv. Pot.", INDENT "Avviso Pot.") #define TR_TIMEZONE "Ora locale" -#define TR_ADJUST_RTC TR("Aggiusta RTC", "Aggiusta RTC") +#define TR_ADJUST_RTC TR(INDENT "Agg. RTC", "Aggiusta RTC") #define TR_GPS "GPS" -#define TR_RXCHANNELORD "Ordine ch RX" +#define TR_RXCHANNELORD "Ordine CH RX" #define TR_STICKS "Sticks" #define TR_POTS "Pot." #define TR_SWITCHES "Interutt." -#define TR_SWITCHES_DELAY "Ritardo voce FV" +#define TR_SWITCHES_DELAY TR("Rit. V. FV", "Ritardo Voce FV") #define TR_SLAVE "Allievo" #define TR_MODESRC "Modo\006% Origine" #define TR_MULTIPLIER "Moltiplica" @@ -579,11 +577,11 @@ #define TR_BG "BG:" #define TR_CALIB_DONE "Calibration completed" #if defined(PCBHORUS) - #define TR_MENUTOSTART "Press [Enter] to start" - #define TR_SETMIDPOINT "Center sticks/pots/sliders and press [Enter]" - #define TR_MOVESTICKSPOTS "Move sticks, pots and sliders and press [Enter]" + #define TR_MENUTOSTART "Premi [ENT] per partire" + #define TR_SETMIDPOINT "Centra sticks/pots/sliders e premi [ENT]" + #define TR_MOVESTICKSPOTS "Muovi sticks/pots/sliders e premi [ENT]" #elif defined(COLORLCD) - #define TR_MENUTOSTART TR_ENTER " TO START" + #define TR_MENUTOSTART TR_ENTER " PER PART." #define TR_SETMIDPOINT "CENTRA STICKS/SLIDERS" #define TR_MOVESTICKSPOTS "MUOVI STICKS/POTS" #else @@ -597,10 +595,9 @@ #define TR_ACCEL "Acc:" #define TR_NODATA CENTER"DATI ASSENTI" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" #define TR_FREE_STACK "Free stack" -#define TR_MENUTORESET TR_ENTER" x Azzerare" +#define TR_MENUTORESET TR_ENTER" per azzerare" #define TR_PPM_TRAINER "TR" #define TR_CH "CH" #define TR_MODEL "MODELLO" @@ -608,16 +605,16 @@ #define TR_MIX "MIX" #define TR_EEPROMLOWMEM "EEPROM quasi piena!" #define TR_PRESS_ANY_KEY_TO_SKIP "\010Premi un tasto" -#define TR_THROTTLE_NOT_IDLE TR("Motore non in posiz.","Motore non in posizione") +#define TR_THROTTLE_NOT_IDLE TR("Motore non in posiz.", "Motore non in posizione") #define TR_ALARMSDISABLED "Avvisi Disattivati!" #define TR_PRESSANYKEY "\010Premi un tasto" #define TR_BADEEPROMDATA "Dati corrotti!" -#define TR_BAD_RADIO_DATA "Bad Radio Data" +#define TR_BAD_RADIO_DATA "Dati radio errati" #define TR_EEPROMFORMATTING "Formatto EEPROM..." -#define TR_STORAGE_FORMAT "Storage Preparation" +#define TR_STORAGE_FORMAT "Preparazione storage" #define TR_EEPROMOVERFLOW "EEPROM Piena" -#define TR_RADIO_SETUP "CONFIGURATX" -#define TR_MENUDATEANDTIME "DATA E ORA" +#define TR_RADIO_SETUP "CONFIGURA TX" +#define TR_MENUDATEANDTIME "DATA ED ORA" #define TR_MENUTRAINER "MAESTRO/ALLIEVO" #define TR_MENUSPECIALFUNCS "FUNZIONI GLOBALI" #define TR_MENUVERSION "VERSIONE" @@ -627,10 +624,10 @@ #if defined(COLORLCD) #define TR_TRIMS2OFFSETS "Trims => Subtrims" #else - #define TR_TRIMS2OFFSETS "\006Trim => Offset " + #define TR_TRIMS2OFFSETS "\006Trims => Offset " #endif -#define TR_CHANNELS2FAILSAFE "Channels=>Failsafe" -#define TR_CHANNEL2FAILSAFE "Channel=>Failsafe" +#define TR_CHANNELS2FAILSAFE "Canali => Failsafe" +#define TR_CHANNEL2FAILSAFE "Canale => Failsafe" #define TR_MENUMODELSEL "MODELLI" #define TR_MENU_MODEL_SETUP "CONFIGURA" #define TR_MENUFLIGHTMODE "FASE DI VOLO" @@ -643,53 +640,53 @@ #define TR_MENUCURVES "CURVE" #define TR_MENUCURVE "CURVA" #define TR_MENULOGICALSWITCH "INTER. PERSON." -#define TR_MENULOGICALSWITCHES TR("INTER. LOGICI","INTERRUTTORI LOGICI") -#define TR_MENUCUSTOMFUNC TR("FUNZ. SPECIALI","FUNZIONI SPECIALI") +#define TR_MENULOGICALSWITCHES TR("INTER. LOGICI", "INTERRUTTORI LOGICI") +#define TR_MENUCUSTOMFUNC TR("FUNZ. SPECIALI", "FUNZIONI SPECIALI") #define TR_MENUCUSTOMSCRIPTS "SCRIPTS UTENTE" #define TR_MENUTELEMETRY "TELEMETRIA" #define TR_MENUTEMPLATES "ESEMPI GUIDA" #define TR_MENUSTAT "STATO" #define TR_MENUDEBUG "DEBUG" -#define TR_MONITOR_CHANNELS1 "CHANNELS MONITOR 1/8" -#define TR_MONITOR_CHANNELS2 "CHANNELS MONITOR 9/16" -#define TR_MONITOR_SWITCHES "LOGICAL SWITCHES MONITOR" -#define TR_MONITOR_CHANNELS3 "CHANNELS MONITOR 17/24" -#define TR_MONITOR_CHANNELS4 "CHANNELS MONITOR 25/32" -#define TR_MONITOR_OUTPUT_DESC "Outputs" +#define TR_MONITOR_CHANNELS1 "MONITOR CANALI 1/8" +#define TR_MONITOR_CHANNELS2 "MONITOR CANALI 9/16" +#define TR_MONITOR_SWITCHES "MONITOR INTERRUTTORI LOGICI" +#define TR_MONITOR_CHANNELS3 "MONITOR CANALI 17/24" +#define TR_MONITOR_CHANNELS4 "MONITOR CANALI 25/32" +#define TR_MONITOR_OUTPUT_DESC "Uscite" #define TR_MONITOR_MIXER_DESC "Mixers" -#define TR_RECEIVER_NUM TR("RxNum", "Ricevente No.") -#define TR_RECEIVER "Receiver" -#define TR_MULTI_RFTUNE TR("Freq tune", "RF Freq. fine tune") -#define TR_MULTI_TELEMETRY "Telemetry" -#define TR_MULTI_VIDFREQ TR("Vid. freq.", "Video frequency") -#define TR_RF_POWER "RF Power" -#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") -#define TR_MULTI_OPTION TR("Option", "Option value") -#define TR_MULTI_AUTOBIND TR(INDENT "Autobind",INDENT "Bind on channel") -#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Autodetect", INDENT "Autodetect format") -#define TR_MULTI_LOWPOWER TR(INDENT "Low power", INDENT "Low power mode") -#define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "S.Port link") -#define TR_MODULE_TELEM_ON TR("ON", "Enabled") -#define TR_DISABLE_INTERNAL TR("Disable int. RF", "Disable internal RF") -#define TR_MODULE_NO_SERIAL_MODE TR("!serial mode", "Not in serial mode") -#define TR_MODULE_NO_INPUT TR("No input", "No serial input") -#define TR_MODULE_NO_TELEMETRY TR3( "No telmetry", "No MULTI_TELEMETRY", "No telemetry (enable MULTI_TELEMETRY)") -#define TR_MODULE_WAITFORBIND "Bind to load protocol" -#define TR_MODULE_BINDING "Binding" -#define TR_REBIND "Rebinding required" -#define TR_REG_OK "Registration ok" -#define TR_BIND_OK "Bind successful" +#define TR_RECEIVER_NUM TR("RxNum", "Ricevente N.") +#define TR_RECEIVER "Ricevente" +#define TR_MULTI_RFTUNE TR("Tune RF", "Tune fine Freq. RF") +#define TR_MULTI_TELEMETRY "Telemetria" +#define TR_MULTI_VIDFREQ TR("Freq. video", "Frequenza video") +#define TR_RF_POWER "Potenza RF" +#define TR_MULTI_FIXEDID TR("FixedID", "Fixed ID") +#define TR_MULTI_OPTION TR("Opzione", "Opzione valore") +#define TR_MULTI_AUTOBIND TR(INDENT "Autoassoc.",INDENT "Associa automat.") +#define TR_MULTI_DSM_AUTODTECT TR(INDENT "Trova autom.", INDENT "Autoril. il formato") +#define TR_MULTI_LOWPOWER TR(INDENT "Bassa pot.", INDENT "Modo bassa potenza") +#define TR_MODULE_TELEMETRY TR(INDENT "S.Port", INDENT "Link S.Port") +#define TR_MODULE_TELEM_ON TR("ON", "Abilitato") +#define TR_DISABLE_INTERNAL TR("Disatt. RF int.", "Disattiva RF interna") +#define TR_MODULE_NO_SERIAL_MODE TR("!modo seriale", "Non in modo seriale") +#define TR_MODULE_NO_INPUT TR("Nessun input", "Nessun input seriale") +#define TR_MODULE_NO_TELEMETRY TR3("No telemetria", "MULTI_TELEMETRY disattivato", "Nessuna telem. (abilita MULTI_TELEMETRY)") +#define TR_MODULE_WAITFORBIND "Associa per caricare il protocollo" +#define TR_MODULE_BINDING "Associa" +#define TR_REBIND "Richiede associazione" +#define TR_REG_OK "Registrazione ok" +#define TR_BIND_OK "Associazione riuscita" #define TR_BINDING_CH1_8_TELEM_ON "Ch1-8 Telem ON" #define TR_BINDING_CH1_8_TELEM_OFF "Ch1-8 Telem OFF" #define TR_BINDING_CH9_16_TELEM_ON "Ch9-16 Telem ON" #define TR_BINDING_CH9_16_TELEM_OFF "Ch9-16 Telem OFF" -#define TR_PROTOCOL_INVALID TR("Prot. invalid", "Protocol invalid") -#define TR_MODULE_STATUS TR(INDENT "Status", INDENT "Module Status") -#define TR_MODULE_SYNC TR(INDENT "Sync", INDENT "Module Sync") -#define TR_MULTI_SERVOFREQ TR("Servo rate", "Servo update rate") +#define TR_PROTOCOL_INVALID TR("Prot. invalido", "Protocollo invalido") +#define TR_MODULE_STATUS TR(INDENT "Stato", INDENT "Stato del modulo") +#define TR_MODULE_SYNC TR(INDENT "Sinc.", INDENT "Sinc. del modulo") +#define TR_MULTI_SERVOFREQ TR("Servo rate", "Aggiorna servo rate") #define TR_SYNCMENU "[Sync]" #define TR_LIMIT INDENT "Limiti" -#define TR_MINRSSI "Min Rssi" +#define TR_MINRSSI "Min. RSSI" #define TR_FLYSKY_TELEMETRY TR("FlySky RSSI #", "Use FlySky RSSI value without rescalling") #define TR_LATITUDE "Latitud." #define TR_LONGITUDE "Longitud." @@ -700,57 +697,60 @@ #define TR_REPEAT_AT_ZERO "Ripeti a Zero" #define TR_SHUTDOWN "ARRESTO.." #define TR_SAVE_MODEL "Salvataggio dati modello" -#define TR_BATT_CALIB "Calibra batt." +#define TR_BATT_CALIB TR("Calibra batt.", "Calibr. batteria") #define TR_CURRENT_CALIB "Calibra corr." #define TR_VOLTAGE TR(INDENT "Voltagg.",INDENT "Voltaggio") #define TR_CURRENT TR(INDENT "Corrente",INDENT "Corrente") -#define TR_SELECT_MODEL "Scegli Memo." -#define TR_CREATE_CATEGORY "Create Category" -#define TR_RENAME_CATEGORY "Rename Category" -#define TR_DELETE_CATEGORY "Delete Category" +#define TR_SELECT_MODEL TR("Scegli mod.", "Scegli Modello") +#define TR_CREATE_CATEGORY "Crea Categoria" +#define TR_RENAME_CATEGORY "Rinomina Categoria" +#define TR_DELETE_CATEGORY "Cancella Categoria" #define TR_CREATE_MODEL "Crea Modello" -#define TR_DUPLICATE_MODEL "Duplicate Model" +#define TR_DUPLICATE_MODEL "Duplica Modello" #define TR_COPY_MODEL "Copia Modello" #define TR_MOVE_MODEL "Sposta Modello" #define TR_BACKUP_MODEL "Salva Modello" -#define TR_DELETE_MODEL TR("Elim. Modello","Elimina Modello") // TODO merged into DELETEMODEL? -#define TR_RESTORE_MODEL TR("Ripr. Modello","Ripristina Modello") -#define TR_DELETE_ERROR "Delete error" -#define TR_CAT_NOT_EMPTY "Category is not empty" -#define TR_SDCARD_ERROR "Errore SD" -#define TR_NO_SDCARD "No SDCARD" -#define TR_WAITING_FOR_RX "Waiting for RX..." -#define TR_WAITING_FOR_TX "Waiting for TX..." -#define TR_NO_TOOLS "No tools available" -#define TR_NORMAL "Normal" -#define TR_NOT_INVERTED "Not inv" -#define TR_NOT_CONNECTED "!Connected" -#define TR_CONNECTED "Connected" +#define TR_DELETE_MODEL TR("Elim. Modello", "Elimina Modello") +#define TR_RESTORE_MODEL TR("Ripr. Modello", "Ripristina Modello") +#define TR_DELETE_ERROR "Errore cancell." +#define TR_CAT_NOT_EMPTY "Categoria non vuota" +#define TR_SDCARD_ERROR TR("Errore SD", "Errore SDCard") +#define TR_NO_SDCARD "No SDCard" +#define TR_WAITING_FOR_RX "Attendo la RX..." +#define TR_WAITING_FOR_TX "Attendo la TX..." +#define TR_NO_TOOLS "Tools non disp." +#define TR_NORMAL "Normale" +#define TR_NOT_INVERTED "No inv." +#define TR_NOT_CONNECTED "!Connesso" +#define TR_CONNECTED "Connesso" #define TR_FLEX_915 "Flex 915MHz" #define TR_FLEX_868 "Flex 868MHz" -#define TR_16CH_WITHOUT_TELEMETRY TR("16CH without telem.", "16CH without telemetry") -#define TR_16CH_WITH_TELEMETRY TR("16CH with telem.", "16CH with telemetry") -#define TR_8CH_WITH_TELEMETRY TR("8CH with telem.", "8CH with telemetry") -#define TR_EXT_ANTENNA "Ext. antenna" +#define TR_16CH_WITHOUT_TELEMETRY TR("16CH senza telem.", "16CH senza telemetria") +#define TR_16CH_WITH_TELEMETRY TR("16CH con telem.", "16CH con telemetria") +#define TR_8CH_WITH_TELEMETRY TR("8CH con telem.", "8CH con telemetria") +#define TR_EXT_ANTENNA "Antenna Ext." #define TR_PIN "Pin" -#define TR_UPDATE_RX_OPTIONS "Update RX options?" -#define TR_UPDATE_TX_OPTIONS "Update TX options?" -#define TR_MODULES_RX_VERSION "Modules / RX version" -#define TR_MENU_MODULES_RX_VERSION "MODULES / RX VERSION" -#define TR_MENU_FIRM_OPTIONS "FIRMWARE OPTIONS" +#define TR_UPDATE_RX_OPTIONS "Agg. opzioni RX?" +#define TR_UPDATE_TX_OPTIONS "Agg. opzioni TX?" +#define TR_MODULES_RX_VERSION "Versioni Moduli / RX" +#define TR_MENU_MODULES_RX_VERSION "VERSIONI MODULI / RX" +#define TR_MENU_FIRM_OPTIONS "OPZIONI FIRMWARE" #define TR_GYRO "Gyro" -#define TR_STICKS_POTS_SLIDERS "Sticks/Pots/Sliders" -#define TR_PWM_STICKS_POTS_SLIDERS "PWM Sticks/Pots/Sliders" -#define TR_RF_PROTOCOL "RF Protocol" -#define TR_MODULE_OPTIONS "Module options" -#define TR_POWER "Power" -#define TR_NO_TX_OPTIONS "No TX options" +#define TR_STICKS_POTS_SLIDERS "Interruttori/Pots/Sliders" +#define TR_PWM_STICKS_POTS_SLIDERS "PWM Interruttori/Pots/Sliders" +#define TR_RF_PROTOCOL "Protocollo RF" +#define TR_MODULE_OPTIONS "Optioni modulo" +#define TR_POWER "Potenza" +#define TR_NO_TX_OPTIONS "No Opzioni TX" #define TR_RTC_BATT "RTC Batt" -#define TR_POWER_METER_EXT "Power Meter (EXT)" +#define TR_POWER_METER_EXT "Power Meter (EST)" #define TR_POWER_METER_INT "Power Meter (INT)" -#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" +#define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EST)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" -#define TR_SDCARD_FULL "SD Card Piena" +#define TR_SDCARD_FULL "SDCard Piena" +#define TR_NEEDS_FILE "RICHIEDE FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Incompatibile" #define TR_WARNING "AVVISO" #define TR_EEPROMWARN "EEPROM" @@ -761,14 +761,15 @@ #define TR_SWITCHWARN "CONTROLLI" #define TR_FAILSAFEWARN "FAILSAFE" #define TR_NIGHTLY_WARNING TR("NIGHTLY", "NIGHTLY BUILD") -#define TR_NIGHTLY_NOTSAFE "Version not safe to fly" -#define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ") -#define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" -#define TR_BATTERY "BATTERY" -#define TR_WRONG_PCBREV "Wrong PCB detected" -#define TR_EMERGENCY_MODE "EMERGENCY MODE" -#define TR_PCBREV_ERROR "PCB error" -#define TR_NO_FAILSAFE "Failsafe non settato" +#define TR_NIGHTLY_NOTSAFE "Versione non sicura per volare" +#define TR_WRONG_SDCARDVERSION TR("Richiede ver: ", "Richiede versione: ") +#define TR_WARN_RTC_BATTERY_LOW "Batteria RTC scarica" +#define TR_WARN_MULTI_LOWPOWER "Modalità bassa pot." +#define TR_BATTERY "BATTERIA" +#define TR_WRONG_PCBREV "PCB sbagliato" +#define TR_EMERGENCY_MODE "MODALITA' EMERGENZA" +#define TR_PCBREV_ERROR "Errore PCB" +#define TR_NO_FAILSAFE "Failsafe" BREAKSPACE "non settato" #define TR_KEYSTUCK "Tasto bloccato" #define TR_INVERT_THR "Inverti Mot?" #define TR_VOLUME "Volume Audio" @@ -788,10 +789,10 @@ #define TR_DELAY "Ritardo" #define TR_SD_CARD "SD Card" #define TR_SDHC_CARD "SD-HC Card" -#define TR_NO_SOUNDS_ON_SD "No Suoni su SD" -#define TR_NO_MODELS_ON_SD "No Model. su SD" -#define TR_NO_BITMAPS_ON_SD "No Immag. su SD" -#define TR_NO_SCRIPTS_ON_SD "No Scripts su SD" +#define TR_NO_SOUNDS_ON_SD "No Suoni" BREAKSPACE "su SD" +#define TR_NO_MODELS_ON_SD "No Model." BREAKSPACE "su SD" +#define TR_NO_BITMAPS_ON_SD "No Immag." BREAKSPACE "su SD" +#define TR_NO_SCRIPTS_ON_SD "No Scripts" BREAKSPACE "su SD" #define TR_SCRIPT_SYNTAX_ERROR "Script errore sintassi" #define TR_SCRIPT_PANIC "Script panic" #define TR_SCRIPT_KILLED "Script fermato" @@ -799,8 +800,8 @@ #define TR_PLAY_FILE "Suona" #define TR_DELETE_FILE "Elimina" #define TR_COPY_FILE "Copia" -#define TR_RENAME_FILE "Rinomomina" -#define TR_ASSIGN_BITMAP "Assegna Immagine" +#define TR_RENAME_FILE "Rinomina" +#define TR_ASSIGN_BITMAP "Assegna immagine" #define TR_ASSIGN_SPLASH "Splash screen" #define TR_EXECUTE_FILE "Esegui" #define TR_REMOVED " rimosso" @@ -808,25 +809,25 @@ #define TR_SD_FORMAT "Format" #define TR_NA "N/A" #define TR_HARDWARE "HARDWARE" -#define TR_FORMATTING "Formattazione." -#define TR_TEMP_CALIB "Temp. Calib" +#define TR_FORMATTING "Formattazione" +#define TR_TEMP_CALIB "Temp. Calib." #define TR_TIME "Ora" -#define TR_MAXBAUDRATE "Max bauds" +#define TR_MAXBAUDRATE "Bauds Max" #define TR_BLUETOOTH "Bluetooth" -#define TR_BLUETOOTH_DISC "Discover" -#define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" -#define TR_BLUETOOTH_PIN_CODE "PIN code" -#define TR_BAUDRATE "BT Baudrate" +#define TR_BLUETOOTH_DISC "Cerca" +#define TR_BLUETOOTH_INIT "Iniz." +#define TR_BLUETOOTH_DIST_ADDR "Ind. Dist." +#define TR_BLUETOOTH_LOCAL_ADDR "Ind. Loc." +#define TR_BLUETOOTH_PIN_CODE "Codice PIN" +#define TR_BAUDRATE "Baudrate BT" #define LEN_BLUETOOTH_MODES "\011" #if defined(PCBX9E) -#define TR_BLUETOOTH_MODES "---\0 ""Enabled\0 " +#define TR_BLUETOOTH_MODES "---\0 ""Attivo\0 " #else -#define TR_BLUETOOTH_MODES "---\0 ""Telemetry""Trainer\0" +#define TR_BLUETOOTH_MODES "---\0 ""Telemetr.""Trainer\0" #endif -#define TR_SD_INFO_TITLE "SD INFO" +#define TR_SD_INFO_TITLE "INFO SD" #define TR_SD_TYPE "Tipo:" #define TR_SD_SPEED "Veloc.:" #define TR_SD_SECTORS "Settori:" @@ -838,34 +839,36 @@ #define TR_MENUGLOBALVARS "VARIABILI GLOBALI" #define TR_OWN "Fase" #define TR_DATE "Data" -#define TR_MONTHS { "Jan", "Fev", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" } +#define TR_MONTHS { "Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Auo", "Set", "Ott", "Nov", "Dic" } #define TR_ROTARY_ENCODER "R.E." #define TR_CHANNELS_MONITOR "MONITOR CANALI" #define TR_MIXERS_MONITOR "MONITOR MIXER" #define TR_PATH_TOO_LONG "Path troppo lungo" #define TR_VIEW_TEXT "Vedi testo" -#define TR_FLASH_BOOTLOADER "Flash bootloader" -#define TR_FLASH_EXTERNAL_DEVICE "Progr. Dispositivo Esterno" -#define TR_FLASH_RECEIVER_OTA "Flash receiver OTA" -#define TR_FLASH_BLUETOOTH_MODULE TR("Flash BT module", "Flash Bluetooth module") -#define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" -#define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") -#define TR_FLASH_INTERNAL_MODULE "Progr. Modulo Interno" -#define TR_FLASH_EXTERNAL_MODULE "Flash external module" -#define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") -#define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" -#define TR_WRITING "\032Scrivendo..." -#define TR_CONFIRM_FORMAT "Confermi Format?" +#define TR_FLASH_BOOTLOADER "Prog. bootloader" +#define TR_FLASH_EXTERNAL_DEVICE "Progr. dispositivo Esterno" +#define TR_FLASH_RECEIVER_OTA TR("Prog. RX OTA", INDENT "Prog. ricevente OTA") +#define TR_FLASH_BLUETOOTH_MODULE TR("Prog. mod. BT", INDENT "Prog. modulo Bluetooth") +#define TR_FLASH_POWER_MANAGEMENT_UNIT TR("Prog. PMU", "Program. PMU") +#define TR_CURRENT_VERSION TR("Vers. currente ", "Versione corrente: ") +#define TR_FLASH_INTERNAL_MODULE "Progr. modulo int." +#define TR_FLASH_EXTERNAL_MODULE "Progr. modulo est." +#define TR_FLASH_INTERNAL_MULTI "Prog. Multi int." +#define TR_FLASH_EXTERNAL_MULTI "Prog. Multi est." +#define TR_FIRMWARE_UPDATE_ERROR TR(INDENT "Errore agg. FW",INDENT "Errore aggiornamento firmware") +#define TR_FIRMWARE_UPDATE_SUCCESS "Aggiornamento" BREAKSPACE "riuscito" +#define TR_WRITING "Scrittura..." +#define TR_CONFIRM_FORMAT "Confermi Formattazione?" #define TR_INTERNALRF "Modulo Interno" -#define TR_INTERNAL_MODULE TR("Int. module","Internal module") -#define TR_EXTERNAL_MODULE TR("Ext. module","External module") -#define TR_OPENTX_UPGRADE_REQUIRED "OpenTX upgrade required" -#define TR_TELEMETRY_DISABLED "Telem. disabled" -#define TR_MORE_OPTIONS_AVAILABLE "More options available" -#define TR_NO_MODULE_INFORMATION "No module information" +#define TR_INTERNAL_MODULE TR("Modulo int.", "Modulo interno") +#define TR_EXTERNAL_MODULE TR("Modulo est.", "Modulo esterno") +#define TR_OPENTX_UPGRADE_REQUIRED "OpenTX richiede aggiornamento" +#define TR_TELEMETRY_DISABLED "Telem. disabilitata" +#define TR_MORE_OPTIONS_AVAILABLE "Altre opzioni assenti" +#define TR_NO_MODULE_INFORMATION "Nessuna info del modulo" #define TR_EXTERNALRF "Modulo esterno" #define TR_FAILSAFE "Modo failsafe" -#define TR_FAILSAFESET TR("FAILSAFE","IMPOSTAZIONI FAILSAFE") +#define TR_FAILSAFESET TR(INDENT "FAILSAFE", INDENT "IMPOSTAZIONI FAILSAFE") #define TR_REG_ID "Reg. ID" #define TR_OWNER_ID "Owner ID" #define TR_PINMAPSET "PINMAP" @@ -875,18 +878,18 @@ #define TR_NONE_UPPERCASE "NONE" #define TR_MENUSENSOR "SENSOR" #define TR_POWERMETER_PEAK "Peak" -#define TR_POWERMETER_POWER "Power" -#define TR_POWERMETER_ATTN "Attn" +#define TR_POWERMETER_POWER "Potenza" +#define TR_POWERMETER_ATTN "Att." #define TR_POWERMETER_FREQ "Freq." #define TR_MENUTOOLS "TOOLS" -#define TR_TURN_OFF_RECEIVER "Turn off receiver" -#define TR_STOPPING "Stopping..." -#define TR_MENU_SPECTRUM_ANALYSER "SPECTRUM ANALYSER" -#define TR_MENU_POWER_METER "POWER METER" -#define TR_SENSOR "SENSOR" -#define TR_COUNTRY_CODE TR("Codice Paese","Standard 2.4Ghz") -#define TR_USBMODE "USB Mode" -#define TR_JACK_MODE "Jack Mode" +#define TR_TURN_OFF_RECEIVER "Spegni la RX" +#define TR_STOPPING "Fermando..." +#define TR_MENU_SPECTRUM_ANALYSER "ANALIZZATORE SPETTRO" +#define TR_MENU_POWER_METER "MISURATORE POTENZA" +#define TR_SENSOR "SENSORE" +#define TR_COUNTRY_CODE TR("Cod. Paese", "Codice del Paese") +#define TR_USBMODE "Modo USB" +#define TR_JACK_MODE "Modo JACK" #define TR_VOICE_LANGUAGE "Lingua Voce" #define TR_UNITS_SYSTEM "Unità" #define TR_EDIT "Modifica" @@ -906,44 +909,44 @@ #define TR_RESET_TELEMETRY "Azzera Telemetria" #define TR_STATISTICS "Statistiche" #define TR_ABOUT_US "Info su" -#define TR_USB_JOYSTICK "USB Joystick (HID)" -#define TR_USB_MASS_STORAGE "USB Storage (SD)" -#define TR_USB_SERIAL "USB Serial (Debug)" -#define TR_SETUP_SCREENS "Setup screens" +#define TR_USB_JOYSTICK "Joystick USB (HID)" +#define TR_USB_MASS_STORAGE "Storage USB (SD)" +#define TR_USB_SERIAL "Seriale USB (Debug)" +#define TR_SETUP_SCREENS "Schermate conf." #define TR_MONITOR_SCREENS "Monitors" #define TR_AND_SWITCH "Inter. AND" #define TR_SF "CF" #define TR_GF "GF" -#define TR_SPEAKER INDENT"Speaker" -#define TR_BUZZER INDENT"Buzzer" +#define TR_SPEAKER INDENT "Speaker" +#define TR_BUZZER INDENT "Buzzer" #define TR_BYTES "Bytes" #define TR_MODULE_BIND "[Bind]" -#define TR_POWERMETER_ATTN_NEEDED "Attenuator needed" -#define TR_PXX2_SELECT_RX "Select RX..." +#define TR_POWERMETER_ATTN_NEEDED "Attenuatore necessario" +#define TR_PXX2_SELECT_RX "Seleziona RX..." #define TR_PXX2_DEFAULT "" -#define TR_BT_SELECT_DEVICE "Select device..." -#define TR_DISCOVER "Discover" +#define TR_BT_SELECT_DEVICE "Seleziona dispositivo" +#define TR_DISCOVER "Cerca" #define TR_BUTTON_INIT BUTTON("Init") -#define TR_WAITING "Waiting..." -#define TR_RECEIVER_DELETE "Delete receiver?" -#define TR_RECEIVER_RESET "Reset receiver?" -#define TR_SHARE "Share" +#define TR_WAITING "In attesa..." +#define TR_RECEIVER_DELETE "Cancello RX?" +#define TR_RECEIVER_RESET "Resetto RX?" +#define TR_SHARE "Condividere" #define TR_BIND "Bind" -#define TR_REGISTER TR("Reg", "Register") +#define TR_REGISTER TR("Reg", "Registrare") #define TR_MODULE_RANGE "[Range]" -#define TR_RECEIVER_OPTIONS TR("REC. OPTIONS", "RECEIVER OPTIONS") -#define TR_DEL_BUTTON BUTTON(TR("Del", "Delete")) +#define TR_RECEIVER_OPTIONS TR("OPZIONI RX", "OPZIONI RICEVENTE") +#define TR_DEL_BUTTON BUTTON(TR("Canc.", "Cancella")) #define TR_RESET_BTN "[Reset]" #define TR_DEBUG "Debug" -#define TR_KEYS_BTN BUTTON(TR("SW","Switches")) -#define TR_ANALOGS_BTN BUTTON(TR("Analog","Analogs")) -#define TR_CALIBRATION "Calibration" +#define TR_KEYS_BTN BUTTON(TR("SW","Interruttori")) +#define TR_ANALOGS_BTN BUTTON(TR("Analogico","Analogici")) +#define TR_CALIBRATION TR("Calibraz.", "Calibrazione") #define TR_SET "[Set]" -#define TR_TRAINER TR("Trainer","Maestro/Allievo") +#define TR_TRAINER TR("Trainer", "Maestro/Allievo") #define TR_ANTENNAPROBLEM CENTER "Problemi antenna TX!" -#define TR_MODELIDUSED TR("ID già usato","ID Modello già usato") +#define TR_MODELIDUSED TR("ID già usato", "ID Modello già usato") #define TR_MODULE "Modulo" -#define TR_RX_NAME "Rx Name" +#define TR_RX_NAME "Nome RX" #define TR_TELEMETRY_TYPE "Tipo Telemetria" #define TR_TELEMETRY_SENSORS "Sensori" #define TR_VALUE "Valore" @@ -951,29 +954,29 @@ #define TR_ENABLE "Enable" #define TR_TOPLCDTIMER "Timer LCD Sup." #define TR_UNIT "Unita" -#define TR_TELEMETRY_NEWSENSOR INDENT "Aggiungi nuovo sensore..." +#define TR_TELEMETRY_NEWSENSOR INDENT "Aggiungi nuovo sensore" #define TR_CHANNELRANGE INDENT "Numero Canali" #define TR_RXFREQUENCY TR("Rx Freqency", "Rx Servo Frequency") -#define TR_ANTENNACONFIRM1 "EXT. ANTENNA" +#define TR_ANTENNACONFIRM1 "ANTENNA EST." #if defined(PCBX12S) #define LEN_ANTENNA_MODES "\023" -#define TR_ANTENNA_MODES "Internal\0 ""Ask\0 ""Per model\0 ""Internal + External" +#define TR_ANTENNA_MODES "Interna\0 ""Chiedi\0 ""Per modello\0 ""Interna + esterna" #else #define LEN_ANTENNA_MODES "\011" -#define TR_ANTENNA_MODES "Internal\0""Ask\0 ""Per model""External" +#define TR_ANTENNA_MODES "Interna\0 ""Chiedi\0 ""Per model""Esterna" #endif -#define TR_USE_INTERNAL_ANTENNA TR("Use int. antenna", "Use internal antenna") -#define TR_USE_EXTERNAL_ANTENNA TR("Use ext. antenna", "Use external antenna") -#define TR_ANTENNACONFIRM2 TR("Check antenna", "Make sure antenna is installed!") -#define TR_MODULE_PROTOCOL_FLEX_WARN_LINE1 "Requires non" -#define TR_MODULE_PROTOCOL_FCC_WARN_LINE1 "Requires FCC" -#define TR_MODULE_PROTOCOL_EU_WARN_LINE1 "Requires EU" -#define TR_MODULE_PROTOCOL_WARN_LINE2 "certified firmware" +#define TR_USE_INTERNAL_ANTENNA TR("Usa ant. int.", "Usa antenna interna") +#define TR_USE_EXTERNAL_ANTENNA TR("Usa ant. est.", "Usa antenna esterna") +#define TR_ANTENNACONFIRM2 TR("Controlla instal.", "Controlla prima se installata!") +#define TR_MODULE_PROTOCOL_FLEX_WARN_LINE1 "Non richiede" +#define TR_MODULE_PROTOCOL_FCC_WARN_LINE1 "Richiede FCC" +#define TR_MODULE_PROTOCOL_EU_WARN_LINE1 "Richiede EU" +#define TR_MODULE_PROTOCOL_WARN_LINE2 "firmware certificato" #define TR_LOWALARM INDENT "Allarme Basso" #define TR_CRITICALALARM INDENT "Allarme Critico" -#define TR_RSSIALARM_WARN TR("RSSI","TELEMETRY RSSI") -#define TR_NO_RSSIALARM TR(INDENT "Alarms disabled", INDENT "Telemetry alarms disabled") -#define TR_DISABLE_ALARM TR(INDENT "Disable alarms", INDENT "Disable telemetry alarms") +#define TR_RSSIALARM_WARN TR(INDENT "Tel. RSSI", "TELEMETRIA RSSI") +#define TR_NO_RSSIALARM TR("Allarmi disab.", "Allarmi telemetrici disabilitati") +#define TR_DISABLE_ALARM TR(INDENT "Allarmi disab.", INDENT "Allarmi telemetrici disabilitati") #define TR_ENABLE_POPUP "Abilita Popup" #define TR_DISABLE_POPUP "Disabilita Popup" #define TR_POPUP "Popup" @@ -989,8 +992,8 @@ #define TR_PT "pt" #define TR_PTS "pti" #define TR_SMOOTH "Smussa" -#define TR_COPY_STICKS_TO_OFS TR("Cpy stick->subtrim", "Copia Stick su Offset") -#define TR_COPY_TRIMS_TO_OFS TR("Cpy trim->subtrim", "Copia Trim in Subtrim") +#define TR_COPY_STICKS_TO_OFS TR(INDENT "Cp. stick->subtrim", INDENT "Copia Sticks su Subtrim") +#define TR_COPY_TRIMS_TO_OFS TR(INDENT "Cp. trim->subtrim", INDENT "Copia Trims su Subtrim") #define TR_INCDEC "Inc/Decrementa" #define TR_GLOBALVAR "Var Globale" #define TR_MIXSOURCE "Sorgente Mixer" @@ -1003,7 +1006,7 @@ #define TR_SCRIPT "Script" #define TR_INPUTS "Ingresso" #define TR_OUTPUTS "Uscita" -#define STR_EEBACKUP "Copiare la EEPROM" +#define STR_EEBACKUP "Copiare l'EEPROM" #define STR_FACTORYRESET "Inizializza dati" #define TR_CONFIRMRESET "Resettare TUTTI i dati?" #define TR_TOO_MANY_LUA_SCRIPTS "Troppi Scripts Lua!" @@ -1013,12 +1016,12 @@ #define TR_PHASES_HEADERS_NAME "Nome" #define TR_PHASES_HEADERS_SW "Inter" #define TR_PHASES_HEADERS_RUD_TRIM "Trim Deriva" -#define TR_PHASES_HEADERS_ELE_TRIM "Trim Elevator" +#define TR_PHASES_HEADERS_ELE_TRIM "Trim Elevatore" #define TR_PHASES_HEADERS_THT_TRIM "Trim Motore" #define TR_PHASES_HEADERS_AIL_TRIM "Trim Alettoni" #define TR_PHASES_HEADERS_CH5_TRIM "Trim 5" #define TR_PHASES_HEADERS_CH6_TRIM "Trim 6" -#define TR_PHASES_HEADERS_FAD_IN "Disolv. In" +#define TR_PHASES_HEADERS_FAD_IN "Dissolv. In" #define TR_PHASES_HEADERS_FAD_OUT "Dissolv. Out" #define TR_LIMITS_HEADERS_NAME "Nome" @@ -1037,19 +1040,19 @@ #define TR_LSW_HEADERS_DURATION "Durata" #define TR_LSW_HEADERS_DELAY "Ritardo" -#define TR_GVAR_HEADERS_NAME "Name" -#define TR_GVAR_HEADERS_FM0 "Value on FM0" -#define TR_GVAR_HEADERS_FM1 "Value on FM1" -#define TR_GVAR_HEADERS_FM2 "Value on FM2" -#define TR_GVAR_HEADERS_FM3 "Value on FM3" -#define TR_GVAR_HEADERS_FM4 "Value on FM4" -#define TR_GVAR_HEADERS_FM5 "Value on FM5" -#define TR_GVAR_HEADERS_FM6 "Value on FM6" -#define TR_GVAR_HEADERS_FM7 "Value on FM7" -#define TR_GVAR_HEADERS_FM8 "Value on FM8" +#define TR_GVAR_HEADERS_NAME "Nome" +#define TR_GVAR_HEADERS_FM0 "Valore su FM0" +#define TR_GVAR_HEADERS_FM1 "Valore su FM1" +#define TR_GVAR_HEADERS_FM2 "Valore su FM2" +#define TR_GVAR_HEADERS_FM3 "Valore su FM3" +#define TR_GVAR_HEADERS_FM4 "Valore su FM4" +#define TR_GVAR_HEADERS_FM5 "Valore su FM5" +#define TR_GVAR_HEADERS_FM6 "Valore su FM6" +#define TR_GVAR_HEADERS_FM7 "Valore su FM7" +#define TR_GVAR_HEADERS_FM8 "Valore su FM8" // Horus footer descriptions -#define TR_LSW_DESCRIPTIONS { "Comparison type or function", "First variable", "Second variable or constant", "Second variable or constant", "Additional condition for line to be enabled", "Minimum ON duration of the logical switch", "Minimum TRUE duration for the switch to become ON" } +#define TR_LSW_DESCRIPTIONS { "Tipo o funzione di confronto", "Prima variabile", "Seconda variabile o costante", "Seconda variabile o costante", "Condizione aggiuntiva da abilitare linea", "Durata minima ON dell'interruttore logico", "Durata minima TRUE affinché l'interruttore si accenda" } // About screen #define TR_ABOUTUS TR(" INFO ", "INFO SU") @@ -1114,19 +1117,19 @@ #define TR_BG_VOLUME "Volume Sf" #define TR_TOP_BAR "Barra sup." -#define TR_FLASH_ERASE "Flash erase..." -#define TR_FLASH_WRITE "Flash write..." -#define TR_OTA_UPDATE "OTA update..." -#define TR_MODULE_RESET "Module reset..." -#define TR_UNKNOWN_RX "Unknown RX" -#define TR_UNSUPPORTED_RX "Unsupported RX" -#define TR_OTA_UPDATE_ERROR "OTA update error" -#define TR_DEVICE_RESET "Device reset..." +#define TR_FLASH_ERASE "Cancello flash..." +#define TR_FLASH_WRITE "Scrivo flash..." +#define TR_OTA_UPDATE "Aggiorn. OTA..." +#define TR_MODULE_RESET "Reset modulo..." +#define TR_UNKNOWN_RX "RX sconociuta" +#define TR_UNSUPPORTED_RX "RX non compatibile" +#define TR_OTA_UPDATE_ERROR "Errore agg. OTA" +#define TR_DEVICE_RESET "Resetto dispositivo..." #define TR_ALTITUDE INDENT "Altitudine" #define TR_SCALE "Scala" #define TR_VIEW_CHANNELS "Vedi Canali" #define TR_VIEW_NOTES "Vedi Note" -#define TR_MODEL_SELECT "Model Select" +#define TR_MODEL_SELECT "Seleziona Modello" #define TR_MODS_FORBIDDEN "Modifica proibita!" #define TR_UNLOCKED "Sbloccato" #define TR_ID "ID" @@ -1136,39 +1139,39 @@ #define TR_CELLINDEX "Indice cella" #define TR_LOGS "Logs" #define TR_OPTIONS "Opzioni" -#define TR_FIRMWARE_OPTIONS "Firmware options" +#define TR_FIRMWARE_OPTIONS "Opzioni firmware" #define TR_ALTSENSOR "Sensore Alt" #define TR_CELLSENSOR "Sensore Cell" #define TR_GPSSENSOR "Sensore GPS" #define TR_CURRENTSENSOR "Sensore" -#define TR_AUTOOFFSET "Auto Offset" +#define TR_AUTOOFFSET "Offset Auto" #define TR_ONLYPOSITIVE "Positivo" #define TR_FILTER "Filtro" #define TR_TELEMETRYFULL "Tutti gli slot sono pieni!" -#define TR_SERVOS_OK "Servos OK" -#define TR_SERVOS_KO "Servos KO" +#define TR_SERVOS_OK "Servi OK" +#define TR_SERVOS_KO "Servi KO" //TODO: translation -#define TR_INVERTED_SERIAL INDENT "Invert" -#define TR_IGNORE_INSTANCE TR(INDENT "No inst.","Ignora instanza") +#define TR_INVERTED_SERIAL INDENT "Invert." +#define TR_IGNORE_INSTANCE TR(INDENT "No inst.", INDENT "Ignora instanza") #define TR_DISCOVER_SENSORS "Cerca nuovi sensori" -#define TR_STOP_DISCOVER_SENSORS "Ferma ricerca.." +#define TR_STOP_DISCOVER_SENSORS "Ferma ricerca" #define TR_DELETE_ALL_SENSORS "Elimina tutti i sensori" -#define TR_CONFIRMDELETE "Confermi " LCDW_128_480_LINEBREAK "eliminazione ?" -#define TR_SELECT_WIDGET "Select widget" -#define TR_REMOVE_WIDGET "Remove widget" -#define TR_WIDGET_SETTINGS "Widget settings" -#define TR_REMOVE_SCREEN "Remove screen" -#define TR_SETUP_WIDGETS "Setup widgets" -#define TR_USER_INTERFACE "User interface" -#define TR_THEME "Theme" -#define TR_SETUP "Setup" -#define TR_MAINVIEWX "Main view X" +#define TR_CONFIRMDELETE "Confermi " LCDW_128_480_LINEBREAK "eliminazione?" +#define TR_SELECT_WIDGET "Seleziona widget" +#define TR_REMOVE_WIDGET "Rimuovi widget" +#define TR_WIDGET_SETTINGS "Settaggio widget" +#define TR_REMOVE_SCREEN "Rimuovi schermo" +#define TR_SETUP_WIDGETS "Setta widgets" +#define TR_USER_INTERFACE "Interfaccia utente" +#define TR_THEME "Tema" +#define TR_SETUP "Imposta" +#define TR_MAINVIEWX "Vista princ. X" #define TR_LAYOUT "Layout" -#define TR_ADD_MAIN_VIEW "Add main view" -#define TR_BACKGROUND_COLOR "Background color" -#define TR_MAIN_COLOR "Main color" -#define TR_TEXT_VIEWER "Text Viewer" +#define TR_ADD_MAIN_VIEW "Aggiungi vista princ." +#define TR_BACKGROUND_COLOR "Colore background" +#define TR_MAIN_COLOR "Colore principale" +#define TR_TEXT_VIEWER "Visualizzatore testi" #define TR_MENU_INPUTS "\314Ingressi" #define TR_MENU_LUA "\322Lua scripts" @@ -1186,7 +1189,9 @@ #define TR_MENU_DISPLAY "DISPLAY" #define TR_MENU_OTHER "Altro" #define TR_MENU_INVERT "Inverti" -#define TR_JITTER_FILTER "ADC Filter" +#define TR_JITTER_FILTER "Filtro ADC" +#define TR_RTC_CHECK TR("Controllo RTC", "Controllo voltaggio RTC") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1199,6 +1204,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/nl.h.txt b/radio/src/translations/nl.h.txt index 43a741867..677b246ef 100644 --- a/radio/src/translations/nl.h.txt +++ b/radio/src/translations/nl.h.txt @@ -52,9 +52,6 @@ #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Stil\0""Alarm""NoKey""Alles" -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "UITREaREb" - #define LEN_VBLMODE TR("\005", "\010") #define TR_VBLMODE TR("UIT\0 ""Keys\0""Stick""Beide""AAN\0 ", "UIT\0 ""Toetsen\0""Sticks\0 ""Beide\0 ""AAN\0 ") @@ -122,7 +119,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "RETA12345LR" + #define TR_RETA123 "RETA13245LR" #elif defined(PCBX9E) #define TR_RETA123 "RETA1234LRLR" #elif defined(PCBTARANIS) || defined(REVX) @@ -341,7 +338,6 @@ #else #define TR_GYR_VSRCRAW #endif -TR_GYR_VSRCRAW #if defined(HELI) #define TR_CYC_VSRCRAW "CYC1""CYC2""CYC3" #else @@ -360,7 +356,8 @@ TR_GYR_VSRCRAW #define TR_VTRAINER_MASTER_SBUS_MODULE "Master/SBUS Module" #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " -#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0 ", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE TR("\013","\011") #define TR_VFAILSAFE TR("Niet Gezet\0""Vasthouden\0""Custom\0 ""Geen Pulsen""Ontvanger\0 ","Not Set\0 ""Hold\0 ""Custom\0 ""No Pulses""Receiver\0") @@ -524,7 +521,6 @@ TR_GYR_VSRCRAW #define TR_MODEL_STILL_POWERED "Model still powered" #define TR_MODEL_SHUTDOWN "Shutdown ?" #define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG "Stappenschakelaar" #define TR_THROTTLE_LABEL "Gas" #define TR_THROTTLEREVERSE TR("Reverse", INDENT "Omgekeerd") #define TR_MINUTEBEEP TR("Min-Alarm", "Minuten-Alarm") @@ -579,7 +575,6 @@ TR_GYR_VSRCRAW #define TR_ACCEL "Acc:" #define TR_NODATA CENTER"Geen Data" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" #define TR_FREE_STACK "Free stack" #define TR_MENUTORESET TR_ENTER" voor Reset" @@ -735,7 +730,10 @@ TR_GYR_VSRCRAW #define TR_POWER_METER_INT "Power Meter (INT)" #define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" -#define TR_SDCARD_FULL "SD-Kaart vol" +#define TR_SDCARD_FULL "SD-Kaart vol" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Niet compatibel" #define TR_WARNING "MELDING" #define TR_EEPROMWARN "EEPROM" @@ -749,6 +747,7 @@ TR_GYR_VSRCRAW #define TR_NIGHTLY_NOTSAFE "Version not safe to fly" #define TR_WRONG_SDCARDVERSION TR("Verwachte ver: ","Verwachte versie: ") #define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATTERY" #define TR_WRONG_PCBREV "Verkeerde PCB gedetecteerd" #define TR_EMERGENCY_MODE "EMERGENCY MODE" @@ -801,8 +800,8 @@ TR_GYR_VSRCRAW #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" +#define TR_BLUETOOTH_DIST_ADDR "Dist addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Local addr" #define TR_BLUETOOTH_PIN_CODE "PIN code" #define TR_BAUDRATE "BT Baudrate" #define LEN_BLUETOOTH_MODES "\011" @@ -836,7 +835,9 @@ TR_GYR_VSRCRAW #define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash interne XJT-Module" +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "\032Schrijven..." @@ -1177,6 +1178,8 @@ TR_GYR_VSRCRAW #define TR_MENU_OTHER "Verdere" #define TR_MENU_INVERT "Inverteer" #define TR_JITTER_FILTER "ADC Filter" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1189,6 +1192,21 @@ TR_GYR_VSRCRAW #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/pl.h.txt b/radio/src/translations/pl.h.txt index 6f4298905..933725759 100644 --- a/radio/src/translations/pl.h.txt +++ b/radio/src/translations/pl.h.txt @@ -52,9 +52,6 @@ #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Cichy""Alarm""BezPr""Wsz.\0" -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "No REaREb" - #define LEN_VBLMODE TR("\004", "\010") #define TR_VBLMODE TR("Wył\0""Przy""Drąż""Oba\0""Zał\0", "Wyłącz ""Przycisk""Drązki\0 ""Oba\0 ""Włącz ") @@ -122,7 +119,7 @@ #define LEN_RETA123 "\001" #if defined(PCBHORUS) - #define TR_RETA123 "KWGL12345LR" + #define TR_RETA123 "KWGL13245LR" #elif defined(PCBX9E) #define TR_RETA123 "KWGL1234LRLR" #elif defined(PCBTARANIS) || defined(REVX) @@ -381,6 +378,7 @@ #define TR_VTRAINER_MASTER_CPPM_MODULE "Trener/CPPM Moduł " #define TR_VTRAINER_MASTER_BATTERY "Trener/Serial\0 " #define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" /*9 decimal*/ #define TR_VFAILSAFE "Brak \0 ""Utrzymuj\0""Własne \0""0 sygnału""Odbiornik" @@ -541,7 +539,6 @@ #define TR_MODEL_STILL_POWERED "Model still powered" #define TR_MODEL_SHUTDOWN "Shutdown ?" #define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG "Nawigacja potencjometrem" #define TR_THROTTLE_LABEL "Gaz " #define TR_THROTTLEREVERSE TR("OdwrGaz", INDENT "OdwrGaz") #define TR_MINUTEBEEP TR("Minuta", "PikCoMinutę") @@ -594,7 +591,6 @@ #define TR_ACCEL "Acc:" #define TR_NODATA CENTER "BrakDAN" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "TmixMaks" #define TR_FREE_STACK "Wolny stos" #define TR_MENUTORESET TR_ENTER " >> Reset" @@ -747,7 +743,10 @@ #define TR_POWER_METER_INT "Power Meter (INT)" #define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" -#define TR_SDCARD_FULL "Karta Pełna " +#define TR_SDCARD_FULL "Karta Pełna " +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Niekompatybilne" #define TR_WARNING "UWAGA" #define TR_EEPROMWARN "EEPROM" @@ -761,6 +760,7 @@ #define TR_NIGHTLY_NOTSAFE "Version not safe to fly" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ") #define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATTERY" #define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_EMERGENCY_MODE "EMERGENCY MODE" @@ -813,8 +813,8 @@ #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" +#define TR_BLUETOOTH_DIST_ADDR "Dist addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Local addr" #define TR_BLUETOOTH_PIN_CODE "PIN code" #define TR_BAUDRATE "Prędkość BT" #define LEN_BLUETOOTH_MODES "\011" @@ -848,7 +848,9 @@ #define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Sflashuj Moduł Wewnętrzny" +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "\032Zapis... " @@ -1184,6 +1186,8 @@ #define TR_MENU_OTHER "Inny " #define TR_MENU_INVERT "Odwróć" #define TR_JITTER_FILTER "ADC Filter" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1196,6 +1200,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/pt.h.txt b/radio/src/translations/pt.h.txt index 10ad8266d..14d7db55a 100644 --- a/radio/src/translations/pt.h.txt +++ b/radio/src/translations/pt.h.txt @@ -52,9 +52,6 @@ #define LEN_VBEEPMODE "\005" #define TR_VBEEPMODE "Mudo ""Alarm""NoKey""Todo " -#define LEN_VRENAVIG "\003" -#define TR_VRENAVIG "No REaREb" - #define LEN_VBLMODE "\004" #define TR_VBLMODE "OFF ""Chav""Stks""Tudo""ON\0" @@ -363,6 +360,7 @@ #define TR_VTRAINER_MASTER_CPPM_MODULE "Master/CPPM Module" #define TR_VTRAINER_MASTER_BATTERY "Master/Serial\0 " #define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Not set\0 ""Hold\0 ""Custom\0 ""No pulses""Receiver\0" @@ -527,7 +525,6 @@ #define TR_MODEL_STILL_POWERED "Model still powered" #define TR_MODEL_SHUTDOWN "Shutdown ?" #define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG "RotEnc Navig" #define TR_THROTTLE_LABEL "Throttle" #define TR_THROTTLEREVERSE TR("Inverte Acel.", INDENT "Inverte Acel.") #define TR_MINUTEBEEP "Beep Minuto" @@ -576,7 +573,6 @@ #define TR_ACCEL "Acc:" #define TR_NODATA CENTER"SEM DADOS" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" #define TR_FREE_STACK "Free stack" #define TR_MENUTORESET TR_ENTER" Reinicia" @@ -737,7 +733,10 @@ #define TR_POWER_METER_INT "Power Meter (INT)" #define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" -#define TR_SDCARD_FULL "SD Card Full" +#define TR_SDCARD_FULL "SD Card Full" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Incompativel" #define TR_WARNING "AVISO" #define TR_EEPROMWARN "EEPROM" @@ -751,6 +750,7 @@ #define TR_NIGHTLY_NOTSAFE "Version not safe to fly" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ") #define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATTERY" #define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_EMERGENCY_MODE "EMERGENCY MODE" @@ -803,8 +803,8 @@ #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" +#define TR_BLUETOOTH_DIST_ADDR "Dist addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Local addr" #define TR_BLUETOOTH_PIN_CODE "PIN code" #define TR_BAUDRATE "BT Baudrate" #define LEN_BLUETOOTH_MODES "\011" @@ -838,7 +838,9 @@ #define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "Writing..." @@ -1173,6 +1175,8 @@ #define TR_MENU_OTHER "Other" #define TR_MENU_INVERT "Invert" #define TR_JITTER_FILTER "ADC Filter" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1185,6 +1189,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/se.h.txt b/radio/src/translations/se.h.txt index 149501b80..191865a71 100644 --- a/radio/src/translations/se.h.txt +++ b/radio/src/translations/se.h.txt @@ -376,6 +376,7 @@ #define TR_VTRAINER_MASTER_CPPM_MODULE "Lärare/CPPM-Modul\0" #define TR_VTRAINER_MASTER_BATTERY "Lärare/Serial\0 " #define TR_VTRAINER_BLUETOOTH TR("Master/BT\0 ""Slave/BT\0", "Master/Bluetooth\0 ""Slave/Bluetooth\0 ") +#define TR_VTRAINER_MULTI "Master/Multi" #define LEN_VFAILSAFE "\011" #define TR_VFAILSAFE "Ej givet\0""Lås Servo""Anpassat\0""Pulsfritt""Mottagare" @@ -540,7 +541,6 @@ #define TR_MODEL_STILL_POWERED "Model still powered" #define TR_MODEL_SHUTDOWN "Shutdown ?" #define TR_PRESS_ENTER_TO_CONFIRM "Press enter to confirm" -#define TR_RENAVIG "RotEnk Navig" #define TR_THROTTLE_LABEL "Gas" #define TR_THROTTLEREVERSE TR("Inv.Gas", INDENT "Inverterad Gas") #define TR_MINUTEBEEP "Minutpip" @@ -593,7 +593,6 @@ #define TR_ACCEL "Acc:" #define TR_NODATA CENTER "DATA SAKNAS" #define TR_US "us" -#define TR_TMR1JITTERUS "Tmr1 Jitter\037\124us" #define TR_TMIXMAXMS "Tmix max" #define TR_FREE_STACK "Free stack" #define TR_MENUTORESET TR_ENTER " Nollar" @@ -746,7 +745,10 @@ #define TR_POWER_METER_INT "Power Meter (INT)" #define TR_SPECTRUM_ANALYSER_EXT "Spectrum (EXT)" #define TR_SPECTRUM_ANALYSER_INT "Spectrum (INT)" -#define TR_SDCARD_FULL "SD-kort Fullt" +#define TR_SDCARD_FULL "SD-kort Fullt" +#define TR_NEEDS_FILE "NEEDS FILE" +#define TR_EXT_MULTI_SPEC "opentx-inv" +#define TR_INT_MULTI_SPEC "stm-opentx-noinv" #define TR_INCOMPATIBLE "Inkompatibel" #define TR_WARNING "VARNING" #define TR_EEPROMWARN "EEPROM" @@ -761,6 +763,7 @@ #define TR_SDCARDVERSIONWARN "SD Card Check" #define TR_WRONG_SDCARDVERSION TR("Expected ver: ","Expected version: ") #define TR_WARN_RTC_BATTERY_LOW "RTC Battery low" +#define TR_WARN_MULTI_LOWPOWER "Low power mode" #define TR_BATTERY "BATTERY" #define TR_WRONG_PCBREV "Wrong PCB detected" #define TR_EMERGENCY_MODE "EMERGENCY MODE" @@ -813,8 +816,8 @@ #define TR_BLUETOOTH "Bluetooth" #define TR_BLUETOOTH_DISC "Discover" #define TR_BLUETOOTH_INIT "Init" -#define TR_BLUETOOTH_DIST_ADDR INDENT "Dist addr" -#define TR_BLUETOOTH_LOCAL_ADDR INDENT "Local addr" +#define TR_BLUETOOTH_DIST_ADDR "Dist addr" +#define TR_BLUETOOTH_LOCAL_ADDR "Local addr" #define TR_BLUETOOTH_PIN_CODE "PIN code" #define TR_BAUDRATE "BT Baudrate" #define LEN_BLUETOOTH_MODES "\011" @@ -848,7 +851,9 @@ #define TR_FLASH_POWER_MANAGEMENT_UNIT "Flash pwr mngt unit" #define TR_CURRENT_VERSION TR("Current vers. ", "Current version: ") #define TR_FLASH_INTERNAL_MODULE "Flash Internal Module" +#define TR_FLASH_INTERNAL_MULTI TR("Flash Int. Multi", "Flash Internal Multi") #define TR_FLASH_EXTERNAL_MODULE "Flash external module" +#define TR_FLASH_EXTERNAL_MULTI TR("Flash Ext. Multi", "Flash External Multi") #define TR_FIRMWARE_UPDATE_ERROR TR("FW update Error","Firmware update error") #define TR_FIRMWARE_UPDATE_SUCCESS "Flash successful" #define TR_WRITING "\032Skriver..." @@ -1184,6 +1189,8 @@ #define TR_MENU_OTHER "Annat" #define TR_MENU_INVERT "Invertera" #define TR_JITTER_FILTER "ADC Filter" +#define TR_RTC_CHECK TR("Check RTC", "Check RTC voltage") +#define TR_AUTH_FAILURE "Auth-failure" #define ZSTR_RSSI "RSSI" #define ZSTR_R9PW "R9PW" @@ -1196,6 +1203,21 @@ #define ZSTR_ALT "Alt" #define ZSTR_TEMP1 "Tmp1" #define ZSTR_TEMP2 "Tmp2" +#define ZSTR_TEMP3 "Tmp3" +#define ZSTR_TEMP4 "Tmp4" +#define ZSTR_RPM2 "RPM2" +#define ZSTR_PRES "Pres" +#define ZSTR_ODO1 "Odo1" +#define ZSTR_ODO2 "Odo2" +#define ZSTR_TXV "TX_V" +#define ZSTR_CURR_SERVO1 "CSv1" +#define ZSTR_CURR_SERVO2 "CSv2" +#define ZSTR_CURR_SERVO3 "CSv3" +#define ZSTR_CURR_SERVO4 "CSv4" +#define ZSTR_DIST "Dist" +#define ZSTR_ARM "Arm" +#define ZSTR_C50 "C50" +#define ZSTR_C200 "C200" #define ZSTR_RPM "RPM" #define ZSTR_FUEL "Fuel" #define ZSTR_VSPD "VSpd" diff --git a/radio/src/translations/untranslated.h b/radio/src/translations/untranslated.h index 61c8540f7..bc072fe5a 100644 --- a/radio/src/translations/untranslated.h +++ b/radio/src/translations/untranslated.h @@ -36,29 +36,26 @@ #define TR_POTS_VSRCRAW "\210S1\0""\2106P\0""\210S2\0""\210EX1""\210EX2""\211LS\0""\211RS\0""\210JSx""\210JSy" #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\212SE\0""\212SF\0""\212SG\0""\212SH\0""\212SI\0""\212SJ\0" #elif defined(PCBX9E) - #define TR_POTS_VSRCRAW "\210F1\0""\210F2\0""\210F3\0""\210F4\0""\211S1\0""\211S2\0""\211LS\0""\211RS\0" - #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\212SE\0""\212SF\0""\212SG\0""\212SH\0""\212SI\0""\212SJ\0""\212SK\0""\212SL\0""\212SM\0""\212SN\0""\212SO\0""\212SP\0""\212SQ\0""\212SR\0" -#elif defined(PCBXLITES) - #define TR_POTS_VSRCRAW "\210S1\0""\210S2\0" - #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\212SE\0""\212SF\0" + #define TR_POTS_VSRCRAW "\310F1\0""\310F2\0""\310F3\0""\310F4\0""\311S1\0""\311S2\0""\311LS\0""\311RS\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0""\312SG\0""\312SH\0""\312SI\0""\312SJ\0""\312SK\0""\312SL\0""\312SM\0""\312SN\0""\312SO\0""\312SP\0""\312SQ\0""\312SR\0" #elif defined(PCBXLITE) #define TR_POTS_VSRCRAW "\210S1\0""\210S2\0" - #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0" + #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\312SE\0""\312SF\0" #elif defined(RADIO_X7) #define TR_POTS_VSRCRAW "\210S1\0""\210S2\0" #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\212SF\0""\212SH\0""\212SI\0""\212SJ\0" #elif defined(RADIO_T12) #define TR_POTS_VSRCRAW "\210S1\0""\210S2\0" #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\212SG\0""\212SH\0""\212SI\0""\212SJ\0" +#elif defined(PCBX9LITES) + #define TR_POTS_VSRCRAW "\310S1\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0""\312SG\0" #elif defined(PCBX9LITE) - #define TR_POTS_VSRCRAW "\210S1\0" - #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\212SE\0" -#elif defined(PCBX9DP) && PCBREV >= 2019 - #define TR_POTS_VSRCRAW "\210S1\0""\210S2\0""\210S3\0""\211LS\0""\211RS\0" - #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\212SE\0""\212SF\0""\212SG\0""\212SH\0""\212SI\0" + #define TR_POTS_VSRCRAW "\310S1\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0" #elif defined(PCBTARANIS) - #define TR_POTS_VSRCRAW "\210S1\0""\210S2\0""\210S3\0""\211LS\0""\211RS\0" - #define TR_SW_VSRCRAW "\212SA\0""\212SB\0""\212SC\0""\212SD\0""\212SE\0""\212SF\0""\212SG\0""\212SH\0" + #define TR_POTS_VSRCRAW "\310S1\0""\310S2\0""\310S3\0""\311LS\0""\311RS\0" + #define TR_SW_VSRCRAW "\312SA\0""\312SB\0""\312SC\0""\312SD\0""\312SE\0""\312SF\0""\312SG\0""\312SH\0""\312SI\0" #elif defined(PCBSKY9X) #define TR_POTS_VSRCRAW "P1\0 ""P2\0 ""P3\0 " #define TR_SW_VSRCRAW "3POS" "THR\0""RUD\0""ELE\0""AIL\0""GEA\0""TRN\0" @@ -74,14 +71,16 @@ #define TR_VSWITCHES "---" "ID0""ID1""ID2" "THR""RUD""ELE""AIL""GEA""TRN" TR_TRIMS_SWITCHES TR_ROTENC_SWITCHES TR_ON_ONE_SWITCHES #endif -#if defined(PCBHORUS) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_BLUETOOTH +#if defined(PCBHORUS) && !defined(BLUETOOTH) + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MULTI +#elif defined(PCBHORUS) + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #elif defined(PCBX9E) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #elif defined(PCBTARANIS) && defined(BLUETOOTH) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_BLUETOOTH TR_VTRAINER_MULTI #elif defined(PCBTARANIS) - #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY + #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_SBUS_MODULE TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY TR_VTRAINER_MULTI #else #define TR_VTRAINERMODES TR_VTRAINER_MASTER_JACK TR_VTRAINER_SLAVE_JACK TR_VTRAINER_MASTER_CPPM_MODULE TR_VTRAINER_MASTER_BATTERY #endif @@ -136,4 +135,4 @@ #define TR_DSM_PROTOCOLS "LP45""DSM2""DSMX" #define LEN_MULTI_PROTOCOLS "\007" -#define TR_MULTI_PROTOCOLS "FlySky\0""Hubsan\0""FrSky\0 ""Hisky\0 ""V2x2\0 ""DSM\0 ""Devo\0 ""YD717\0 ""KN\0 ""SymaX\0 ""SLT\0 ""CX10\0 ""CG023\0 ""Bayang\0""ESky\0 ""MT99XX\0""MJXq\0 ""Shenqi\0""FY326\0 ""SFHSS\0 ""J6 Pro\0""FQ777\0 ""Assan\0 ""Hontai\0""OpenLrs""FSky 2A""Q2x2\0 ""Walkera""Q303\0 ""GW008\0 ""DM002\0 ""Cabell\0""Esky150""H8 3D\0 ""Corona\0""CFlie\0 ""Hitec\0 ""WFly\0 ""Bugs\0 ""BugMini""Traxxas""NCC1701""E01X\0 ""V911S\0 ""GD00X\0 ""V761\0 ""KF606\0 ""Redpine""Potensi""ZSX\0 ""FlyZone" \ No newline at end of file +#define TR_MULTI_PROTOCOLS "FlySky\0""Hubsan\0""FrSky\0 ""Hisky\0 ""V2x2\0 ""DSM\0 ""Devo\0 ""YD717\0 ""KN\0 ""SymaX\0 ""SLT\0 ""CX10\0 ""CG023\0 ""Bayang\0""ESky\0 ""MT99XX\0""MJXq\0 ""Shenqi\0""FY326\0 ""SFHSS\0 ""J6 Pro\0""FQ777\0 ""Assan\0 ""Hontai\0""OpenLrs""FSky 2A""Q2x2\0 ""Walkera""Q303\0 ""GW008\0 ""DM002\0 ""Cabell\0""Esky150""H8 3D\0 ""Corona\0""CFlie\0 ""Hitec\0 ""WFly\0 ""Bugs\0 ""BugMini""Traxxas""NCC1701""E01X\0 ""V911S\0 ""GD00X\0 ""V761\0 ""KF606\0 ""Redpine""Potensi""ZSX\0 ""FlyZone""Scanner""FrSkyRX""FS2A_RX" diff --git a/radio/util/build-firmware.py b/radio/util/build-firmware.py index 41be5705a..630751a64 100755 --- a/radio/util/build-firmware.py +++ b/radio/util/build-firmware.py @@ -88,7 +88,11 @@ def main(): cmake_options["PCB"] = "X9LITE" firmware_options = options_taranis_x9lite maxsize = 65536 * 8 - elif board_name == "x7": + elif board_name == "x9lites": + cmake_options["PCB"] = "X9LITES" + firmware_options = options_taranis_x9lite + maxsize = 65536 * 8 + elif options[optcount] == "x7": cmake_options["PCB"] = "X7" firmware_options = options_taranis_x9dp maxsize = 65536 * 8 @@ -135,6 +139,11 @@ def main(): cmake_options["PCBREV"] = "T12" firmware_options = options_taranis_x9dp maxsize = 65536 * 8 + elif board_name == "t16": + cmake_options["PCB"] = "X10" + cmake_options["PCBREV"] = "T16" + firmware_options = options_jumper_t16 + maxsize = 2 * 1024 * 1024 else: exit(INVALID_BOARD) diff --git a/radio/util/fwoptions.py b/radio/util/fwoptions.py index e9dea65e3..104452561 100755 --- a/radio/util/fwoptions.py +++ b/radio/util/fwoptions.py @@ -198,3 +198,17 @@ options_horus_x10express = { "eu": ("MODULE_PROTOCOL_D8", "NO", "YES"), "flexr9m": ("MODULE_PROTOCOL_FLEX", "YES", None) } + +options_jumper_t16 = { + "noheli": ("HELI", "NO", "YES"), + "ppmus": ("PPM_UNIT", "US", "PERCENT_PREC1"), + "lua": ("LUA", "YES", "NO_MODEL_SCRIPTS"), + "nogvars": ("GVARS", "NO", "YES"), + "faimode": ("FAI", "YES", None), + "faichoice": ("FAI", "CHOICE", None), + "nooverridech": ("OVERRIDE_CHANNEL_FUNCTION", "NO", "YES"), + "eu": ("MODULE_PROTOCOL_D8", "NO", "YES"), + "flexr9m": ("MODULE_PROTOCOL_FLEX", "YES", None), + "internalmulti": ("INTERNAL_MODULE_MULTI", "YES", "NO"), + "bluetooth": ("BLUETOOTH", "YES", "NO"), +} \ No newline at end of file diff --git a/radio/util/lua/lua_event_test.lua b/radio/util/lua/lua_event_test.lua new file mode 100644 index 000000000..3a883b7cb --- /dev/null +++ b/radio/util/lua/lua_event_test.lua @@ -0,0 +1,92 @@ +local toolName = "TNS|LUA event tests|TNE" +---- ######################################################################### +---- # # +---- # Copyright (C) OpenTX # +-----# # +---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html # +---- # # +---- # This program is free software; you can redistribute it and/or modify # +---- # it under the terms of the GNU General Public License version 2 as # +---- # published by the Free Software Foundation. # +---- # # +---- # This program is distributed in the hope that it will be useful # +---- # but WITHOUT ANY WARRANTY; without even the implied warranty of # +---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +---- # GNU General Public License for more details. # +---- # # +---- ######################################################################### + +local virtual_next = 0 +local virtual_prev = 0 +local virtual_inc = 0 +local virtual_dec = 0 +local virtual_next_rept = 0 +local virtual_prev_rept = 0 +local virtual_page_next = 0 +local virtual_page_prev = 0 +local virtual_enter = 0 +local virtual_enter_long = 0 +local virtual_menu = 0 +local virtual_menu_long = 0 + +-- Init +local function init() + +end + +-- Main +local function run(event) + if event == nil then + error("Cannot be run as a model script!") + return 2 + end + if event == EVT_VIRTUAL_EXIT then + return 2 + end + if event == EVT_VIRTUAL_NEXT then + virtual_next = virtual_next + 1 + end + if event == EVT_VIRTUAL_PREV then + virtual_prev = virtual_prev + 1 + end + if event == EVT_VIRTUAL_INC then + virtual_inc = virtual_inc + 1 + end + if event == EVT_VIRTUAL_DEC then + virtual_dec = virtual_dec + 1 + end + if event == EVT_VIRTUAL_NEXT_REPT then + virtual_next_rept = virtual_next_rept + 1 + end + if event == EVT_VIRTUAL_PREV_REPT then + virtual_prev_rept = virtual_prev_rept + 1 + end + if event == EVT_VIRTUAL_NEXT_PAGE then + virtual_page_next = virtual_page_next +1 + end + if event == EVT_VIRTUAL_PREV_PAGE then + virtual_page_prev = virtual_page_prev + 1 + killEvents(event); + end + if event == EVT_VIRTUAL_ENTER then + virtual_enter = virtual_enter + 1 + end + if event == EVT_VIRTUAL_MENU then + virtual_menu = virtual_menu + 1 + end + + lcd.clear() + lcd.drawScreenTitle("LUA EVENT TEST", 0, 0) + lcd.drawText(1, 10, "PREV:"..virtual_prev) + lcd.drawText(LCD_W/2, 10, "NEXT: "..virtual_next) + lcd.drawText(1, 20, "DEC:"..virtual_dec) + lcd.drawText(LCD_W/2, 20, "INC:"..virtual_inc) + lcd.drawText(1, 30, "NXT PAGE: "..virtual_page_next) + lcd.drawText(LCD_W/2, 30, "PRV PAGE: "..virtual_page_prev) + lcd.drawText(1, 50, "ENTER: "..virtual_enter) + lcd.drawText(LCD_W/2, 50, "MENU: "..virtual_menu) + return 0 +end + +return { init=init, run=run } + diff --git a/radio/util/lua/lua_old_event_check.lua b/radio/util/lua/lua_old_event_check.lua new file mode 100755 index 000000000..6a74a3c0f --- /dev/null +++ b/radio/util/lua/lua_old_event_check.lua @@ -0,0 +1,74 @@ +local toolName = "TNS|LUA event tests|TNE" +---- ######################################################################### +---- # # +---- # Copyright (C) OpenTX # +-----# # +---- # License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html # +---- # # +---- # This program is free software; you can redistribute it and/or modify # +---- # it under the terms of the GNU General Public License version 2 as # +---- # published by the Free Software Foundation. # +---- # # +---- # This program is distributed in the hope that it will be useful # +---- # but WITHOUT ANY WARRANTY; without even the implied warranty of # +---- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # +---- # GNU General Public License for more details. # +---- # # +---- ######################################################################### + +local virtual_next = 0 +local virtual_previous = 0 +local virtual_next_rept = 0 +local virtual_previous_rept = 0 +local virtual_page_next = 0 +local virtual_page_previous = 0 +local virtual_enter = 0 +local virtual_enter_long = 0 +local virtual_menu = 0 +local virtual_menu_long = 0 + +-- Init +local function init() + +end + +-- Main +local function run(event) + if event == nil then + error("Cannot be run as a model script!") + return 2 + elseif event == EVT_VIRTUAL_EXIT then + return 2 + elseif event == EVT_PLUS_FIRST then + virtual_next = virtual_next + 1 + elseif event == EVT_MINUS_FIRST then + virtual_previous = virtual_previous + 1 + elseif event == EVT_PLUS_REPT then + virtual_next_rept = virtual_next_rept + 1 + elseif event == EVT_MINUS_REPT then + virtual_previous_rept = virtual_previous_rept + 1 + elseif event == EVT_PAGE_BREAK then + virtual_page_next = virtual_page_next +1 + elseif event == EVT_PAGE_LONG then + virtual_page_previous = virtual_page_previous + 1 + killEvents(event); + elseif event == EVT_ENTER_BREAK then + virtual_enter = virtual_enter + 1 + elseif event == EVT_MENU_BREAK then + virtual_menu = virtual_menu + 1 + end + + lcd.clear() + lcd.drawScreenTitle("LUA EVENT TEST", 0, 0) + lcd.drawText(1, 10, "PLUS: "..virtual_next) + lcd.drawText(1, 20, "MINUS: "..virtual_previous) + lcd.drawText(1, 40, "PLUS_REPT: "..virtual_next_rept) + lcd.drawText(1, 50, "MINUS_REPT: "..virtual_previous_rept) + lcd.drawText(LCD_W/2, 10, "ENTER: "..virtual_enter) + lcd.drawText(LCD_W/2, 20, "MENU: "..virtual_menu) + lcd.drawText(LCD_W/2, 40, "NEXT_PAGE: "..virtual_page_next) + lcd.drawText(LCD_W/2, 50, "PREVIOUS_PAGE: "..virtual_page_previous) + return 0 +end + +return { init=init, run=run } diff --git a/radio/util/tts_it.py b/radio/util/tts_it.py index 91a796e9c..52ba120a8 100755 --- a/radio/util/tts_it.py +++ b/radio/util/tts_it.py @@ -37,12 +37,12 @@ for i, (s, f) in enumerate([("volt", "volt0"), ("radiante", "rad0"), ("radianti", "rad1"), ("millilitro", "m10"), ("millilitri", "m11"), ("oncia fluida", "founce0"), ("once fluide", "founce1"), - ("milliliter per minute", "mlpm0"), ("milliliters per minute", "mlpm1"), + ("millilitro per minuto", "mlpm0"), ("millilitri per minuto", "mlpm1"), ("ora", "hour0"), ("ore", "hour1"), ("minuto", "minute0"), ("minuti", "minute1"), ("secondo", "second0"), ("secondi", "second1"), ]): - systemSounds.append((s, filename(f, PROMPT_SYSTEM_BASE + 113 + i))) + systemSounds.append((s, filename(f, PROMPT_SYSTEM_BASE + 116 + i))) for s, f, a in [("radio inattiva controllare", "inactiv", 486), ("batteria della radio scarica", "lowbatt", 485), ("controllo motore non in posizione, verificare", "thralert", 481), @@ -71,6 +71,9 @@ for s, f, a in [("radio inattiva controllare", "inactiv", 486), ("Problema all'antenna della radio", "swr_red", NO_ALTERNATE), ("Telemetria assente", "telemko", NO_ALTERNATE), ("Telemetria disponibile", "telemok", NO_ALTERNATE), + ("Segnale trainer perso", "trainko", NO_ALTERNATE), + ("Segnale trainer disponibile", "trainok", NO_ALTERNATE), + ("Sensore perso", "sensorko", NO_ALTERNATE), ("sovraccarico servo", "servoko", NO_ALTERNATE), ("sovraccarico di alimentazione", "rxko", NO_ALTERNATE), ("ricevente ancora connessa", "modelpwr", NO_ALTERNATE), @@ -80,11 +83,13 @@ for i, s in enumerate(["timer", "", "tensione", "tensione", "trasmissione", "ric "carburante", "temperatura", "temperatura", "velocità", "distanza", "altitudine", "cella lipo", "totale lipo", "tensione", "corrente", "consumo", "potenza", "accelerazione X", "accelerazione Y", "accelerazione Z", "direzione", "variometro", "minimo", "massimo"]): - systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 135 + i))) + systemSounds.append((s, filename(PROMPT_SYSTEM_BASE + 155 + i))) for i, (s, f) in enumerate([("carrello chiuso", "gearup"), ("carrello aperto", "geardn"), ("flap rientrati", "flapup"), ("flap estesi", "flapdn"), + ("spoiler su", "splrup"), + ("spoiler giù", "splrdn"), ("atterraggio", "attero"), ("modalità maestro attiva", "trnon"), ("modalità maestro disattiva", "trnoff"), @@ -92,11 +97,15 @@ for i, (s, f) in enumerate([("carrello chiuso", "gearup"), ("troppo alto", "tohigh"), ("troppo basso", "tolow"), ("batteria scarica", "lowbat"), - ("crow on", "crowon"), - ("crow off", "crowof"), + ("crow attivato", "crowon"), + ("crow disattivato", "crowof"), + ("segnale radio basso", "siglow"), + ("segnale radio critico", "sigcrt"), ("modo velocità", "spdmod"), ("modo termica", "thmmod"), ("modo volo normale", "nrmmod"), + ("modo atterraggio", "lnding"), + ("modo acro", "acro"), ("fase di volo 1", "fltmd1"), ("fase di volo 2", "fltmd2"), ("fase di volo 3", "fltmd3"), @@ -104,7 +113,21 @@ for i, (s, f) in enumerate([("carrello chiuso", "gearup"), ("fase di volo 5", "fltmd5"), ("fase di volo 6", "fltmd6"), ("fase di volo 7", "fltmd7"), - ("fase di volo 8", "fltmd8"), - ("fase di volo 9", "fltmd9"), + ("variometro attivato", "vrion"), + ("variometro disabilitato", "vrioff"), + ("fase di volo power", "fm-pwr"), + ("fase di volo land", "fm-lnd"), + ("fase di volo planata", "fm-flt"), + ("fase di volo velocità", "fm-spd"), + ("fase di volo veloce", "fm-fst"), + ("fase di volo normale", "fm-nrm"), + ("fase di volo cruise", "fm-crs"), + ("fase di volo acro", "fm-acr"), + ("fase di volo race", "fm-rce"), + ("fase di volo lancio", "fm-lch"), + ("fase di volo ping", "fm-png"), + ("fase di volo termica", "fm-thm"), + ("fase di volo termica sinistra", "fm-thl"), + ("fase di volo termica destra", "fm-thr"), ]): sounds.append((s, filename(f, PROMPT_CUSTOM_BASE + i))) diff --git a/tools/build-companion-nightly.sh b/tools/build-companion-nightly.sh index c0cf47bd1..ac2004b16 100755 --- a/tools/build-companion-nightly.sh +++ b/tools/build-companion-nightly.sh @@ -40,45 +40,67 @@ cd build cmake ${COMMON_OPTIONS} -DPCB=AR9X ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=SKY9X ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=9XRPRO ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X9LITE ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt + +cmake ${COMMON_OPTIONS} -DPCB=X9LITES ${SRCDIR} +make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X7 ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X7 -DPCBREV=T12 ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X9D ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X9D+ ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DPCBREV=2019 ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=XLITE ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=XLITES ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X9E ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X10 ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt + +cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=T16 ${SRCDIR} +make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X10 -DPCBREV=EXPRESS ${SRCDIR} make -j${JOBS} libsimulator +rm CMakeCache.txt cmake ${COMMON_OPTIONS} -DPCB=X12S ${SRCDIR} make -j${JOBS} libsimulator diff --git a/tools/build-companion-release.sh b/tools/build-companion-release.sh index 14bda21bf..81a20b6cd 100755 --- a/tools/build-companion-release.sh +++ b/tools/build-companion-release.sh @@ -50,6 +50,9 @@ make -j${JOBS} libsimulator cmake ${COMMON_OPTIONS} -DPCB=X9LITE ${SRCDIR} make -j${JOBS} libsimulator +cmake ${COMMON_OPTIONS} -DPCB=X9LITES ${SRCDIR} +make -j${JOBS} libsimulator + cmake ${COMMON_OPTIONS} -DPCB=X7 ${SRCDIR} make -j${JOBS} libsimulator diff --git a/tools/build-frsky.py b/tools/build-frsky.py index 03beec3e3..9e538bc4a 100755 --- a/tools/build-frsky.py +++ b/tools/build-frsky.py @@ -61,6 +61,21 @@ boards = { "SBUS": "NO", "DEFAULT_MODE": "2", }, + "X9LITES": { + "PCB": "X9LITES", + "LUA": "NO_MODEL_SCRIPTS", + "GVARS": "YES", + "AUTOUPDATE": "YES", + "PXX1": "YES", + "XJT": "NO", + "MODULE_SIZE_STD": "NO", + "PPM": "NO", + "DSM2": "NO", + "MULTIMODULE": "NO", + "CROSSFIRE": "NO", + "SBUS": "NO", + "DEFAULT_MODE": "2", + }, "X9D+": { "PCB": "X9D+", "PCBREV": "2019", diff --git a/tools/build-jumper.py b/tools/build-jumper.py new file mode 100755 index 000000000..0a2db17f3 --- /dev/null +++ b/tools/build-jumper.py @@ -0,0 +1,78 @@ +#!/usr/bin/python3 + +import argparse +import datetime +import os +from builtins import NotADirectoryError +import shutil +import tempfile + + +boards = { + "T12": { + "PCB": "X7", + "PCBREV": "T12", + "DEFAULT_MODE": "2", + }, + "T16": { + "PCB": "X10", + "PCBREV": "T16", + "INTERNAL_MODULE_MULTI": "YES", + "DEFAULT_MODE": "2", + } +} + +translations = [ + "EN", +] + + +def timestamp(): + return datetime.datetime.now().strftime("%y%m%d") + + +def build(board, translation, srcdir): + cmake_options = " ".join(["-D%s=%s" % (key, value) for key, value in boards[board].items()]) + cwd = os.getcwd() + if not os.path.exists("output"): + os.mkdir("output") + path = tempfile.mkdtemp() + os.chdir(path) + command = "cmake %s -DTRANSLATIONS=%s -DJUMPER_RELEASE=YES %s" % (cmake_options, translation, srcdir) + print(command) + os.system(command) + os.system("make firmware -j6") + os.chdir(cwd) + index = 0 + while 1: + suffix = "" if index == 0 else "_%d" % index + filename = "output/firmware_%s_%s_%s%s.bin" % (board.lower(), translation.lower(), timestamp(), suffix) + if not os.path.exists(filename): + shutil.copy("%s/firmware.bin" % path, filename) + break + index += 1 + shutil.rmtree(path) + + +def dir_path(string): + if os.path.isdir(string): + return string + else: + raise NotADirectoryError(string) + + +def main(): + parser = argparse.ArgumentParser(description="Build JumperRC firmware") + parser.add_argument("-b", "--boards", action="append", help="Destination boards", required=True) + parser.add_argument("-t", "--translations", action="append", help="Translations", required=True) + parser.add_argument("srcdir", type=dir_path) + + args = parser.parse_args() + + for board in (boards.keys() if "ALL" in args.boards else args.boards): + for translation in (translations if "ALL" in args.translations else args.translations): + build(board, translation, args.srcdir) + + +if __name__ == "__main__": + main() diff --git a/tools/commit-tests.sh b/tools/commit-tests.sh index 73c7a2775..61b1bc5c3 100755 --- a/tools/commit-tests.sh +++ b/tools/commit-tests.sh @@ -64,7 +64,7 @@ if [[ " SKY9X ARM9X ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=SKY9X -DHELI=YES DLUA=YES -DTELEMETRY=FRSKY -DPPM_LIMITS_SYMETRICAL=YES -DVARIO=YES -DAUTOSWITCH=YES -DAUTOSOURCE=YES -DAUDIO=YES -DGPS=YES -DPPM_CENTER_ADJUSTABLE=YES -DFLIGHT_MODES=YES -DOVERRIDE_CHANNEL_FUNCTION=YES -DFRSKY_STICKS=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " AR9X ARM9X ALL " =~ " ${FLAVOR} " ]] ; then @@ -73,7 +73,7 @@ if [[ " AR9X ARM9X ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=AR9X -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " 9XRPRO ARM9X ALL " =~ " ${FLAVOR} " ]] ; then @@ -82,7 +82,7 @@ if [[ " 9XRPRO ARM9X ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=9XRPRO -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " X9LITE ALL " =~ " ${FLAVOR} " ]] ; then @@ -91,6 +91,15 @@ if [[ " X9LITE ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9LITE -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator + make -j${CORES} tests-radio +fi + +if [[ " X9LITES ALL " =~ " ${FLAVOR} " ]] ; then + # OpenTX on X9LITES + rm -rf * + cmake ${COMMON_OPTIONS} -DPCB=X9LITES -DHELI=YES -DGVARS=YES ${SRCDIR} + make -j${CORES} ${FIRMARE_TARGET} + make -j${CORES} libsimulator make -j${CORES} tests fi @@ -100,7 +109,7 @@ if [[ " X7 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X7 -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " XLITE ALL " =~ " ${FLAVOR} " ]] ; then @@ -109,7 +118,7 @@ if [[ " XLITE ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=XLITE -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " XLITES ALL " =~ " ${FLAVOR} " ]] ; then @@ -118,7 +127,7 @@ if [[ " XLITES ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=XLITES -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " X9D X9 ALL " =~ " ${FLAVOR} " ]] ; then @@ -127,7 +136,7 @@ if [[ " X9D X9 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9D -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " X9D+ X9 ALL " =~ " ${FLAVOR} " ]] ; then @@ -136,7 +145,7 @@ if [[ " X9D+ X9 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " X9D+2019 X9 ALL " =~ " ${FLAVOR} " ]] ; then @@ -145,7 +154,7 @@ if [[ " X9D+2019 X9 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9D+ -DPCBREV=2019 -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " X9E X9 ALL " =~ " ${FLAVOR} " ]] ; then @@ -154,7 +163,7 @@ if [[ " X9E X9 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X9E -DHELI=YES -DLUA=YES -DGVARS=YES -DPPM_UNIT=PERCENT_PREC1 ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " X10 HORUS ALL " =~ " ${FLAVOR} " ]] ; then @@ -163,7 +172,7 @@ if [[ " X10 HORUS ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X10 -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " X12S HORUS ALL " =~ " ${FLAVOR} " ]] ; then @@ -172,7 +181,7 @@ if [[ " X12S HORUS ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X12S -DHELI=YES -DLUA=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " T12 ALL " =~ " ${FLAVOR} " ]] ; then @@ -181,7 +190,7 @@ if [[ " T12 ALL " =~ " ${FLAVOR} " ]] ; then cmake ${COMMON_OPTIONS} -DPCB=X7 -DPCBREV=T12 -DHELI=YES -DGVARS=YES ${SRCDIR} make -j${CORES} ${FIRMARE_TARGET} make -j${CORES} libsimulator - make -j${CORES} tests + make -j${CORES} tests-radio fi if [[ " DEFAULT ALL " =~ " ${FLAVOR} " ]] ; then @@ -189,4 +198,5 @@ if [[ " DEFAULT ALL " =~ " ${FLAVOR} " ]] ; then rm -rf * cmake ${COMMON_OPTIONS} ${SRCDIR} make -j${CORES} + make -j${CORES} tests fi diff --git a/tools/release23/build-sdcard.sh b/tools/release23/build-sdcard.sh new file mode 100755 index 000000000..97a4799b7 --- /dev/null +++ b/tools/release23/build-sdcard.sh @@ -0,0 +1,77 @@ +#!/bin/bash + +set -e +set -x + +workdir=/home/opentx/release23 +output=/var/www/html/2.3/release + +# Handle opentx.sdcard.version +sdcard_version="2.3V"$(grep 'set(SDCARD_REVISION' ${workdir}/code/CMakeLists.txt | grep -o '".*"' | sed 's/"//g') +echo ${sdcard_version} > ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version +echo ${sdcard_version} > ${workdir}/code/radio/sdcard/taranis-x9/opentx.sdcard.version +echo ${sdcard_version} > ${workdir}/code/radio/sdcard/taranis-x7/opentx.sdcard.version + + +if cmp --silent ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version ${workdir}/opentx.sdcard.version +then + exit +else + cd ${workdir} + + # Copy git sdcard data + rm -Rf ${workdir}/sdcard + cp -r ${workdir}/code/radio/sdcard . + + # Get images for Horus + mkdir -p ${workdir}/sdcard/horus/IMAGES + cp /home/opentx/horus-bitmaps/* ${workdir}/sdcard/horus/IMAGES/ + + + # Request sound pack generation + if [[ ! -d /tmp/SOUNDS/fr ]];then + ${workdir}/code/tools/release23/tts.py en csv files + fi + if [[ ! -d /tmp/SOUNDS/es ]];then + ${workdir}/code/tools/release23/tts.py fr csv files + fi + if [[ ! -d /tmp/SOUNDS/it ]];then + ${workdir}/code/tools/release23/tts.py es csv files + fi + if [[ ! -d /tmp/SOUNDS/de ]];then + ${workdir}/code/tools/release23/tts.py it csv files + fi + if [[ ! -d /tmp/SOUNDS/cz ]];then + ${workdir}/code/tools/release23/tts.py de csv files + fi + if [[ ! -d /tmp/SOUNDS/pl ]];then + ${workdir}/code/tools/release23/tts.py cz csv files + fi + if [[ ! -d /tmp/SOUNDS/ru ]];then + ${workdir}/code/tools/release23/tts.py pt csv files + fi + ${workdir}/code/tools/release23/tts.py ru csv psv files + + # Create sdcards.zips for supported platforms + mv /tmp/SOUNDS ${workdir}/sdcard/horus/ + mkdir ${workdir}/sdcard/taranis-x9/SOUNDS + mkdir ${workdir}/sdcard/taranis-x7/SOUNDS + cp -r ${workdir}/sdcard/horus/SOUNDS ${workdir}/sdcard/taranis-x9/ + cp -r ${workdir}/sdcard/horus/SOUNDS ${workdir}/sdcard/taranis-x7/ + cd ${workdir}/sdcard/horus && zip -r ${output}/sdcard/sdcard-horus-${sdcard_version}.zip * + cd ${workdir}/sdcard/taranis-x9 && zip -r ${output}/sdcard/sdcard-taranis-x9-${sdcard_version}.zip * + cd ${workdir}/sdcard/taranis-x7 && zip -r ${output}/sdcard/sdcard-taranis-x7-${sdcard_version}.zip * + + # Create symlinks for other radios + ln -s ${output}/sdcard/sdcard-taranis-x7-${sdcard_version}.zip ${output}/sdcard/sdcard-taranis-xlite-${sdcard_version}.zip + ln -s ${output}/sdcard/sdcard-taranis-x7-${sdcard_version}.zip ${output}/sdcard/sdcard-taranis-x9lite-${sdcard_version}.zip + ln -s ${output}/sdcard/sdcard-taranis-x7-${sdcard_version}.zip ${output}/sdcard/sdcard-jumper-t12-${sdcard_version}.zip + + # remove LUA stuff for 9x platform + rm -Rf ${workdir}/sdcard/taranis-x7/SCRIPTS + rm -Rf ${workdir}/sdcard/taranis-x7/FrSky-utilities + cd ${workdir}/sdcard/taranis-x7 && zip -r ${output}/sdcard/sdcard-9xarm-${sdcard_version}.zip * + + rm -Rf ${workdir}/sdcard + cp -r ${workdir}/code/radio/sdcard/horus/opentx.sdcard.version ${workdir} +fi diff --git a/tools/release23/tts.py b/tools/release23/tts.py new file mode 100755 index 000000000..fc42cfeb6 --- /dev/null +++ b/tools/release23/tts.py @@ -0,0 +1,152 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- + + +# This script is a modified version to support Linux TTS fiel genration using PicoTTS + +# Sound pack maintainers (incomplete list) by language alphabetical order +# Czech : Martin Hotar +# French : Bertrand Songis & André Bernet +# English : Rob Thompson & Martin Hotar +# German : Romolo Manfredini (Some corrections by Peer) +# Italian : Romolo Manfredini +# Portuguese : Romolo Manfredini +# Spanish : Romolo Manfredini (With the help of Jose Moreno) + +# from __future__ import print_function + +import os +import sys +import subprocess +import zipfile +from gtts import gTTS +from tts_common import * +board = "taranis" + +reload(sys) +sys.setdefaultencoding('utf8') + +SOURCE_DIRECTORY = os.path.dirname(os.path.realpath(__file__)) +lib_path = os.path.abspath(os.path.join(SOURCE_DIRECTORY, '..', '..', 'radio', 'util')) +sys.path.append(lib_path) + +def generate(str, filename): + if 0: + output = "output.wav" + command = 'pico2wave -l=%s -w=%s "%s"' % (voice, output, str) + os.system(command.encode('utf-8')) + command = "sox %s -r 32000 %s reverse silence 1 0.1 0.1%% reverse" % (output, filename) + os.system(command.encode('utf-8')) + else: + output = u"output.mp3" + tts = gTTS(text=str, lang=voice[:2]) + tts.save(output) + command = "sox --norm %s -r 32000 %s tempo 1.2" % (output, filename) + os.system(command.encode('utf-8')) + command = "rm -f output.mp3" + os.system(command.encode('utf-8')) + +################################################################ + +if __name__ == "__main__": + if "en" in sys.argv: + from tts_en import systemSounds, sounds + + directory = "en" + voice = "en-US" + + elif "fr" in sys.argv: + from tts_fr import systemSounds, sounds + + directory = "fr" + voice = "fr-FR" + + elif "it" in sys.argv: + from tts_it import systemSounds, sounds + + directory = "it" + voice = "it-IT" + + elif "de" in sys.argv: + from tts_de import systemSounds, sounds + + directory = "de" + voice = "de-DE" + + elif "es" in sys.argv: + from tts_es import systemSounds, sounds + + directory = "es" + voice = "es-ES" + + elif "cz" in sys.argv: + from tts_cz import systemSounds, sounds + + directory = "cz" + voice = "cs-CZ" + + elif "ru" in sys.argv: + from tts_ru import systemSounds, sounds + + directory = "ru" + voice = "ru-RU" + + elif "pt" in sys.argv: + from tts_pt import systemSounds, sounds + + directory = "pt" + voice = "pt-PT" + + else: + print("which language?") + exit() + + if "csv" in sys.argv: + path = "/tmp/SOUNDS/" + directory + "/SYSTEM/" + if not os.path.exists(path): + os.makedirs(path) + os.chdir(path) + with open("%s-%s.csv" % (voice, board), "wb") as csvFile: + for s, f in systemSounds: + if s and f: + l = u"" + if board in ("sky9x", "taranis"): + l += u"SOUNDS/%s/SYSTEM;" % directory + l += f + u";" + s + u"\n" + csvFile.write(l.encode("utf-8")) + for s, f in sounds: + if s and f: + l = u"" + if board in ("sky9x", "taranis"): + l += u"SOUNDS/%s;" % directory + l += f + u";" + s + u"\n" + csvFile.write(l.encode("utf-8")) + + if "psv" in sys.argv: + path = "/tmp/SOUNDS/" + directory + "/" + if not os.path.exists(path): + os.makedirs(path) + os.chdir(path) + with open("%s-%s.psv" % (voice, board), "wb") as csvFile: + for s, f in systemSounds: + if s and f: + l = u"SYSTEM|" + f.replace(".wav", "") + u"|" + s + u"\r\n" + csvFile.write(l.encode("windows-1251")) + for s, f in sounds: + if s and f: + l = u"|" + f.replace(".wav", "") + u"|" + s + u"\r\n" + csvFile.write(l.encode("windows-1251")) + + + if "files" in sys.argv: + path = "/tmp/SOUNDS/" + directory + "/SYSTEM/" + if not os.path.exists(path): + os.makedirs(path) + os.chdir(path) + for s, f in systemSounds: + if s and f: + generate(s, f) + os.chdir("..") + for s, f in sounds: + if s and f: + generate(s, f) diff --git a/tools/release23/tts_common.py b/tools/release23/tts_common.py new file mode 100644 index 000000000..25623b005 --- /dev/null +++ b/tools/release23/tts_common.py @@ -0,0 +1,14 @@ +NO_ALTERNATE = 1024 +PROMPT_CUSTOM_BASE = 256 +PROMPT_SYSTEM_BASE = 0 +board = "taranis" + +import sys + +def filename(idx, alternate=0): + ext = ".wav" + if isinstance(idx, int): + result = "%04d%s" % (idx, ext) + elif board in ('sky9x', 'taranis'): + result = idx + ext + return result